This repository has been archived on 2025-03-19. You can view files and clone it, but cannot push or open issues or pull requests.
feishin/src/renderer/features/servers/components/edit-server-form.tsx
Jeff 9f2e873366
Redesign sidebar / header and other misc. improvements (#24)
* Remove 1920px max width

* Fix position of list controls menu

* Match size and color of search input

* Adjust library header sizing

* Move app menu to sidebar

* Increase row buffer on play queue list

* Fix query builder styles

* Fix playerbar slider track bg

* Adjust titlebar styles

* Fix invalid modal prop

* Various adjustments to detail pages

* Fix sidebar height calculation

* Fix list null indicators, add filter indicator

* Adjust playqueue styles

* Fix jellyfin releaseYear normalization

* Suppress browser context menu on ag-grid

* Add radius to drawer queue -- normalize layout

* Add modal styles to provider theme

* Fix playlist song list pagination

* Add disc number to albums with more than one disc

* Fix query builder boolean values

* Adjust input placeholder color

* Properly handle rating/favorite from context menu on table

* Conform dropdown menu styles to context menu

* Increase sort type select width

* Fix drawer queue radius

* Change primary color

* Prevent volume wheel from invalid values

* Add icons to query builder dropdowns

* Update notification styles

* Update scrollbar thumb styles

* Remove "add to playlist" on smart playlists

* Fix "add to playlist" from context menu
2023-02-07 22:47:23 -08:00

137 lines
4 KiB
TypeScript

import { useState } from 'react';
import { Checkbox, Stack, Group } from '@mantine/core';
import { Button, PasswordInput, TextInput, toast } from '/@/renderer/components';
import { useForm } from '@mantine/form';
import { closeAllModals } from '@mantine/modals';
import { nanoid } from 'nanoid/non-secure';
import { RiInformationLine } from 'react-icons/ri';
import { jellyfinApi } from '/@/renderer/api/jellyfin.api';
import { navidromeApi } from '/@/renderer/api/navidrome.api';
import { subsonicApi } from '/@/renderer/api/subsonic.api';
import { AuthenticationResponse } from '/@/renderer/api/types';
import { useAuthStoreActions } from '/@/renderer/store';
import { ServerListItem, ServerType } from '/@/renderer/types';
interface EditServerFormProps {
isUpdate?: boolean;
onCancel: () => void;
server: ServerListItem;
}
const AUTH_FUNCTIONS = {
[ServerType.JELLYFIN]: jellyfinApi.authenticate,
[ServerType.NAVIDROME]: navidromeApi.authenticate,
[ServerType.SUBSONIC]: subsonicApi.authenticate,
};
export const EditServerForm = ({ isUpdate, server, onCancel }: EditServerFormProps) => {
const { updateServer, setCurrentServer } = useAuthStoreActions();
const [isLoading, setIsLoading] = useState(false);
const form = useForm({
initialValues: {
legacyAuth: false,
name: server?.name,
password: '',
type: server?.type,
url: server?.url,
username: server?.username,
},
});
const isSubsonic = form.values.type === ServerType.SUBSONIC;
const isSubmitDisabled =
!form.values.name || !form.values.url || !form.values.username || !form.values.password;
const handleSubmit = form.onSubmit(async (values) => {
const authFunction = AUTH_FUNCTIONS[values.type];
if (!authFunction) {
return toast.error({ message: 'Selected server type is invalid' });
}
try {
setIsLoading(true);
const data: AuthenticationResponse = await authFunction(values.url, {
legacy: values.legacyAuth,
password: values.password,
username: values.username,
});
const serverItem = {
credential: data.credential,
id: nanoid(),
name: values.name,
ndCredential: data.ndCredential,
type: values.type,
url: values.url,
userId: data.userId,
username: data.username,
};
updateServer(server.id, serverItem);
setCurrentServer(serverItem);
toast.success({ message: 'Server has been updated' });
} catch (err: any) {
setIsLoading(false);
return toast.error({ message: err?.message });
}
if (isUpdate) closeAllModals();
return setIsLoading(false);
});
return (
<form onSubmit={handleSubmit}>
<Stack>
<TextInput
required
label="Name"
rightSection={form.isDirty('name') && <RiInformationLine color="red" />}
{...form.getInputProps('name')}
/>
<TextInput
required
label="Url"
rightSection={form.isDirty('url') && <RiInformationLine color="red" />}
{...form.getInputProps('url')}
/>
<TextInput
label="Username"
rightSection={form.isDirty('username') && <RiInformationLine color="red" />}
{...form.getInputProps('username')}
/>
<PasswordInput
label="Password"
{...form.getInputProps('password')}
/>
{isSubsonic && (
<Checkbox
label="Enable legacy authentication"
{...form.getInputProps('legacyAuth', {
type: 'checkbox',
})}
/>
)}
<Group position="right">
<Button
variant="subtle"
onClick={onCancel}
>
Cancel
</Button>
<Button
disabled={isSubmitDisabled}
loading={isLoading}
type="submit"
variant="filled"
>
Save
</Button>
</Group>
</Stack>
</form>
);
};