feishin/src/renderer/features/playlists/components/save-as-playlist-form.tsx

120 lines
4.1 KiB
TypeScript
Raw Normal View History

2023-01-04 18:37:25 -08:00
import { useForm } from '@mantine/form';
import { useTranslation } from 'react-i18next';
2023-01-04 18:37:25 -08:00
import { useCreatePlaylist } from '/@/renderer/features/playlists/mutations/create-playlist-mutation';
import { useCurrentServer } from '/@/renderer/store';
2025-05-20 19:23:36 -07:00
import { hasFeature } from '/@/shared/api/utils';
import { Group } from '/@/shared/components/group/group';
import { ModalButton } from '/@/shared/components/modal/model-shared';
import { Stack } from '/@/shared/components/stack/stack';
import { Switch } from '/@/shared/components/switch/switch';
import { TextInput } from '/@/shared/components/text-input/text-input';
import { toast } from '/@/shared/components/toast/toast';
2025-05-20 19:23:36 -07:00
import {
CreatePlaylistBody,
CreatePlaylistResponse,
ServerType,
} from '/@/shared/types/domain-types';
import { ServerFeature } from '/@/shared/types/features-types';
2023-01-04 18:37:25 -08:00
interface SaveAsPlaylistFormProps {
2023-07-01 19:10:05 -07:00
body: Partial<CreatePlaylistBody>;
onCancel: () => void;
onSuccess: (data: CreatePlaylistResponse) => void;
serverId: string | undefined;
2023-01-04 18:37:25 -08:00
}
2023-05-21 18:20:46 -07:00
export const SaveAsPlaylistForm = ({
2023-07-01 19:10:05 -07:00
body,
onCancel,
onSuccess,
serverId,
2023-05-21 18:20:46 -07:00
}: SaveAsPlaylistFormProps) => {
const { t } = useTranslation();
2023-07-01 19:10:05 -07:00
const mutation = useCreatePlaylist({});
const server = useCurrentServer();
2023-01-04 18:37:25 -08:00
2023-07-01 19:10:05 -07:00
const form = useForm<CreatePlaylistBody>({
initialValues: {
_custom: {
navidrome: {
rules: undefined,
...body?._custom?.navidrome,
},
},
comment: body.comment || '',
name: body.name || '',
2024-09-01 09:37:37 -07:00
public: body.public,
},
2023-07-01 19:10:05 -07:00
});
2023-01-04 18:37:25 -08:00
2023-07-01 19:10:05 -07:00
const handleSubmit = form.onSubmit((values) => {
mutation.mutate(
{ body: values, serverId },
{
onError: (err) => {
toast.error({
message: err.message,
title: t('error.genericError', { postProcess: 'sentenceCase' }),
});
2023-07-01 19:10:05 -07:00
},
onSuccess: (data) => {
toast.success({
message: t('form.createPlaylist.success', { postProcess: 'sentenceCase' }),
});
2023-07-01 19:10:05 -07:00
onSuccess(data);
onCancel();
},
},
);
});
2023-01-04 18:37:25 -08:00
2024-09-01 09:37:37 -07:00
const isPublicDisplayed = hasFeature(server, ServerFeature.PUBLIC_PLAYLIST);
const isSubmitDisabled = !form.values.name || mutation.isPending;
2023-01-04 18:37:25 -08:00
2023-07-01 19:10:05 -07:00
return (
<form onSubmit={handleSubmit}>
<Stack>
<TextInput
data-autofocus
label={t('form.createPlaylist.input', {
context: 'name',
postProcess: 'titleCase',
})}
required
2023-07-01 19:10:05 -07:00
{...form.getInputProps('name')}
/>
2024-09-01 09:37:37 -07:00
{server?.type === ServerType.NAVIDROME && (
<TextInput
label={t('form.createPlaylist.input', {
context: 'description',
postProcess: 'titleCase',
})}
{...form.getInputProps('comment')}
/>
)}
2023-07-01 19:10:05 -07:00
{isPublicDisplayed && (
<Switch
label={t('form.createPlaylist.input', {
context: 'public',
postProcess: 'titleCase',
})}
2024-09-01 09:37:37 -07:00
{...form.getInputProps('public', { type: 'checkbox' })}
2023-07-01 19:10:05 -07:00
/>
)}
<Group justify="flex-end">
<ModalButton onClick={onCancel}>{t('common.cancel')}</ModalButton>
<ModalButton
2023-07-01 19:10:05 -07:00
disabled={isSubmitDisabled}
loading={mutation.isPending}
2023-07-01 19:10:05 -07:00
type="submit"
variant="filled"
>
{t('common.save')}
</ModalButton>
2023-07-01 19:10:05 -07:00
</Group>
</Stack>
</form>
);
2023-01-04 18:37:25 -08:00
};