mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-10 04:30:25 +02:00
Update server list
This commit is contained in:
@@ -3,7 +3,7 @@ import { useForm } from '@mantine/form';
|
|||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { RiInformationLine } from 'react-icons/ri';
|
import { RiInformationLine } from 'react-icons/ri';
|
||||||
import { Server, ServerType } from '@/renderer/api/types';
|
import { Server, ServerType } from '@/renderer/api/types';
|
||||||
import { Button, PasswordInput, TextInput } from '@/renderer/components';
|
import { Button, PasswordInput, TextInput, toast } from '@/renderer/components';
|
||||||
import { useUpdateServer } from '@/renderer/features/servers/mutations/use-update-server';
|
import { useUpdateServer } from '@/renderer/features/servers/mutations/use-update-server';
|
||||||
|
|
||||||
interface EditServerFormProps {
|
interface EditServerFormProps {
|
||||||
@@ -40,7 +40,15 @@ export const EditServerForm = ({ server, onCancel }: EditServerFormProps) => {
|
|||||||
},
|
},
|
||||||
query: { serverId: server.id },
|
query: { serverId: server.id },
|
||||||
},
|
},
|
||||||
{ onSuccess: onCancel }
|
{
|
||||||
|
onSuccess: (data) => {
|
||||||
|
toast.show({
|
||||||
|
message: `Server "${data.data.name}" updated`,
|
||||||
|
type: 'success',
|
||||||
|
});
|
||||||
|
onCancel();
|
||||||
|
},
|
||||||
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
import { Stack, Group } from '@mantine/core';
|
import { useMemo } from 'react';
|
||||||
|
import { Stack, Group, Divider } from '@mantine/core';
|
||||||
import { useDisclosure } from '@mantine/hooks';
|
import { useDisclosure } from '@mantine/hooks';
|
||||||
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
import { RiDeleteBin2Fill, RiEdit2Fill } from 'react-icons/ri';
|
import { RiDeleteBin2Fill, RiEdit2Fill } from 'react-icons/ri';
|
||||||
import { Server } from '@/renderer/api/types';
|
import { queryKeys } from '@/renderer/api/query-keys';
|
||||||
import { Button, Text } from '@/renderer/components';
|
import { Server, TaskType } from '@/renderer/api/types';
|
||||||
|
import { Button, Switch, Text, toast } from '@/renderer/components';
|
||||||
import { AddServerCredentialForm } from '@/renderer/features/servers/components/add-server-credential-form';
|
import { AddServerCredentialForm } from '@/renderer/features/servers/components/add-server-credential-form';
|
||||||
import { AddServerUrlForm } from '@/renderer/features/servers/components/add-server-url-form';
|
import { AddServerUrlForm } from '@/renderer/features/servers/components/add-server-url-form';
|
||||||
import { EditServerForm } from '@/renderer/features/servers/components/edit-server-form';
|
import { EditServerForm } from '@/renderer/features/servers/components/edit-server-form';
|
||||||
@@ -12,25 +15,77 @@ import { useDisableServerFolder } from '@/renderer/features/servers/mutations/us
|
|||||||
import { useDisableServerUrl } from '@/renderer/features/servers/mutations/use-disable-server-url';
|
import { useDisableServerUrl } from '@/renderer/features/servers/mutations/use-disable-server-url';
|
||||||
import { useEnableServerFolder } from '@/renderer/features/servers/mutations/use-enable-server-folder';
|
import { useEnableServerFolder } from '@/renderer/features/servers/mutations/use-enable-server-folder';
|
||||||
import { useEnableServerUrl } from '@/renderer/features/servers/mutations/use-enable-server-url';
|
import { useEnableServerUrl } from '@/renderer/features/servers/mutations/use-enable-server-url';
|
||||||
|
import { useFullScan } from '@/renderer/features/servers/mutations/use-full-scan';
|
||||||
|
import { useQuickScan } from '@/renderer/features/servers/mutations/use-quick-scan';
|
||||||
|
import { useUpdateServer } from '@/renderer/features/servers/mutations/use-update-server';
|
||||||
import { usePermissions } from '@/renderer/features/shared';
|
import { usePermissions } from '@/renderer/features/shared';
|
||||||
|
import { useTaskList } from '@/renderer/features/tasks';
|
||||||
import { useAuthStore } from '@/renderer/store';
|
import { useAuthStore } from '@/renderer/store';
|
||||||
|
import { Font } from '@/renderer/styles';
|
||||||
|
|
||||||
interface ServerListItemProps {
|
interface ServerListItemProps {
|
||||||
server: Server;
|
server: Server;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ServerListItem = ({ server }: ServerListItemProps) => {
|
export const ServerListItem = ({ server }: ServerListItemProps) => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
const [edit, editHandlers] = useDisclosure(false);
|
const [edit, editHandlers] = useDisclosure(false);
|
||||||
const [addUrl, addUrlHandlers] = useDisclosure(false);
|
const [addUrl, addUrlHandlers] = useDisclosure(false);
|
||||||
const [addCredential, addCredentialHandlers] = useDisclosure(false);
|
const [addCredential, addCredentialHandlers] = useDisclosure(false);
|
||||||
|
|
||||||
const permissions = usePermissions();
|
const permissions = usePermissions();
|
||||||
|
const updateServer = useUpdateServer();
|
||||||
const enableServerUrl = useEnableServerUrl();
|
const enableServerUrl = useEnableServerUrl();
|
||||||
const disableServerUrl = useDisableServerUrl();
|
const disableServerUrl = useDisableServerUrl();
|
||||||
const deleteServerUrl = useDeleteServerUrl();
|
const deleteServerUrl = useDeleteServerUrl();
|
||||||
const enableServerFolder = useEnableServerFolder();
|
const enableServerFolder = useEnableServerFolder();
|
||||||
const disableServerFolder = useDisableServerFolder();
|
const disableServerFolder = useDisableServerFolder();
|
||||||
const serverCredentials = useAuthStore((state) => state.serverCredentials);
|
const fullScan = useFullScan();
|
||||||
|
const quickScan = useQuickScan();
|
||||||
|
const { data: tasks } = useTaskList();
|
||||||
|
|
||||||
|
const isRunningTask = useMemo(() => {
|
||||||
|
return tasks?.data.some(
|
||||||
|
(task) =>
|
||||||
|
task.server?.id === server.id &&
|
||||||
|
(task.type === TaskType.FULL_SCAN || task.type === TaskType.QUICK_SCAN)
|
||||||
|
);
|
||||||
|
}, [server.id, tasks?.data]);
|
||||||
|
|
||||||
|
const serverCredentials = useAuthStore(
|
||||||
|
(state) => state.serverCredentials
|
||||||
|
).filter((credential) => credential.serverId === server.id);
|
||||||
|
|
||||||
|
const handleFullScan = () => {
|
||||||
|
fullScan.mutate(
|
||||||
|
{ body: {}, query: { serverId: server.id } },
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.show({ message: 'Full scan started', type: 'info' });
|
||||||
|
queryClient.invalidateQueries(queryKeys.tasks.root);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleQuickScan = () => {
|
||||||
|
quickScan.mutate(
|
||||||
|
{ body: {}, query: { serverId: server.id } },
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
toast.show({ message: 'Quick scan started', type: 'info' });
|
||||||
|
queryClient.invalidateQueries(queryKeys.tasks.root);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleRequiredCredential = (e: boolean) => {
|
||||||
|
updateServer.mutate({
|
||||||
|
body: { noCredential: e, type: server.type },
|
||||||
|
query: { serverId: server.id },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const enableServerCredential = useAuthStore(
|
const enableServerCredential = useAuthStore(
|
||||||
(state) => state.enableServerCredential
|
(state) => state.enableServerCredential
|
||||||
@@ -87,8 +142,33 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Stack spacing="xl">
|
<Stack mt="1rem" spacing="xl">
|
||||||
<ServerSection title="Server details">
|
<ServerSection
|
||||||
|
title={
|
||||||
|
<Group position="apart">
|
||||||
|
<Text font={Font.EPILOGUE}>Server details</Text>
|
||||||
|
<Group spacing="md">
|
||||||
|
<Button
|
||||||
|
compact
|
||||||
|
disabled={isRunningTask}
|
||||||
|
loading={fullScan.isLoading}
|
||||||
|
variant="subtle"
|
||||||
|
onClick={handleFullScan}
|
||||||
|
>
|
||||||
|
Full scan
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
compact
|
||||||
|
disabled={true || isRunningTask}
|
||||||
|
variant="filled"
|
||||||
|
onClick={handleQuickScan}
|
||||||
|
>
|
||||||
|
Quick scan
|
||||||
|
</Button>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
}
|
||||||
|
>
|
||||||
{edit ? (
|
{edit ? (
|
||||||
<EditServerForm
|
<EditServerForm
|
||||||
server={server}
|
server={server}
|
||||||
@@ -123,81 +203,25 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
|||||||
<ServerSection title="Music Folders">
|
<ServerSection title="Music Folders">
|
||||||
<Stack>
|
<Stack>
|
||||||
{server.serverFolders?.map((folder) => (
|
{server.serverFolders?.map((folder) => (
|
||||||
<Group position="apart">
|
<Group key={folder.id} position="apart">
|
||||||
|
<Text>{folder.name}</Text>
|
||||||
<Group>
|
<Group>
|
||||||
<Text>{folder.name}</Text>
|
|
||||||
</Group>
|
|
||||||
<Group>
|
|
||||||
<Button
|
|
||||||
compact
|
|
||||||
radius="lg"
|
|
||||||
variant={folder.enabled ? 'filled' : 'subtle'}
|
|
||||||
onClick={() =>
|
|
||||||
handleToggleFolder(folder.id, folder.enabled)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{folder.enabled ? 'Enabled' : 'Disabled'}
|
|
||||||
</Button>
|
|
||||||
{permissions.deleteServerFolder && (
|
{permissions.deleteServerFolder && (
|
||||||
<Button compact disabled radius="xl" variant="subtle">
|
<Button compact disabled radius="xl" variant="subtle">
|
||||||
<RiDeleteBin2Fill />
|
<RiDeleteBin2Fill />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
<Switch
|
||||||
|
checked={folder.enabled}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleToggleFolder(folder.id, !e.currentTarget.checked)
|
||||||
|
}
|
||||||
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
))}
|
))}
|
||||||
</Stack>
|
</Stack>
|
||||||
</ServerSection>
|
</ServerSection>
|
||||||
<ServerSection title="URLs">
|
|
||||||
{addUrl ? (
|
|
||||||
<AddServerUrlForm
|
|
||||||
serverId={server.id}
|
|
||||||
onCancel={() => addUrlHandlers.close()}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<Stack>
|
|
||||||
{server.serverUrls?.map((serverUrl) => (
|
|
||||||
<Group key={serverUrl.id} position="apart">
|
|
||||||
<Text>{serverUrl.url}</Text>
|
|
||||||
<Group>
|
|
||||||
<Button
|
|
||||||
compact
|
|
||||||
radius="lg"
|
|
||||||
variant={serverUrl.enabled ? 'filled' : 'subtle'}
|
|
||||||
onClick={() =>
|
|
||||||
handleToggleUrl(serverUrl.id, serverUrl.enabled)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{serverUrl.enabled ? 'Enabled' : 'Disabled'}
|
|
||||||
</Button>
|
|
||||||
{permissions.deleteServerUrl && (
|
|
||||||
<Button
|
|
||||||
compact
|
|
||||||
radius="xl"
|
|
||||||
variant="subtle"
|
|
||||||
onClick={() => handleDeleteUrl(serverUrl.id)}
|
|
||||||
>
|
|
||||||
<RiDeleteBin2Fill />
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
))}
|
|
||||||
</Stack>
|
|
||||||
{permissions.createServerUrl && (
|
|
||||||
<Button
|
|
||||||
compact
|
|
||||||
mt={10}
|
|
||||||
variant="default"
|
|
||||||
onClick={() => addUrlHandlers.open()}
|
|
||||||
>
|
|
||||||
Add URL
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</ServerSection>
|
|
||||||
<ServerSection title="Credentials">
|
<ServerSection title="Credentials">
|
||||||
{addCredential ? (
|
{addCredential ? (
|
||||||
<AddServerCredentialForm
|
<AddServerCredentialForm
|
||||||
@@ -211,19 +235,6 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
|||||||
<Group key={credential.id} position="apart">
|
<Group key={credential.id} position="apart">
|
||||||
<Text>{credential.username}</Text>
|
<Text>{credential.username}</Text>
|
||||||
<Group>
|
<Group>
|
||||||
<Button
|
|
||||||
compact
|
|
||||||
radius="lg"
|
|
||||||
variant={credential.enabled ? 'filled' : 'subtle'}
|
|
||||||
onClick={() =>
|
|
||||||
handleToggleCredential(
|
|
||||||
credential.id,
|
|
||||||
credential.enabled
|
|
||||||
)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{credential.enabled ? 'Disable' : 'Enable'}
|
|
||||||
</Button>
|
|
||||||
{permissions.deleteServerCredential && (
|
{permissions.deleteServerCredential && (
|
||||||
<Button
|
<Button
|
||||||
compact
|
compact
|
||||||
@@ -234,6 +245,15 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
|||||||
<RiDeleteBin2Fill />
|
<RiDeleteBin2Fill />
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
<Switch
|
||||||
|
checked={credential.enabled}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleToggleCredential(
|
||||||
|
credential.id,
|
||||||
|
!e.currentTarget.checked
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
</Group>
|
</Group>
|
||||||
</Group>
|
</Group>
|
||||||
))}
|
))}
|
||||||
@@ -251,7 +271,67 @@ export const ServerListItem = ({ server }: ServerListItemProps) => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</ServerSection>
|
</ServerSection>
|
||||||
|
<ServerSection title="URLs">
|
||||||
|
{addUrl ? (
|
||||||
|
<AddServerUrlForm
|
||||||
|
serverId={server.id}
|
||||||
|
onCancel={() => addUrlHandlers.close()}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Stack>
|
||||||
|
{server.serverUrls?.map((serverUrl) => (
|
||||||
|
<Group key={serverUrl.id} position="apart">
|
||||||
|
<Text>{serverUrl.url}</Text>
|
||||||
|
<Group>
|
||||||
|
{permissions.deleteServerUrl && (
|
||||||
|
<Button
|
||||||
|
compact
|
||||||
|
radius="xl"
|
||||||
|
variant="subtle"
|
||||||
|
onClick={() => handleDeleteUrl(serverUrl.id)}
|
||||||
|
>
|
||||||
|
<RiDeleteBin2Fill />
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
<Switch
|
||||||
|
checked={serverUrl.enabled}
|
||||||
|
onChange={(e) =>
|
||||||
|
handleToggleUrl(
|
||||||
|
serverUrl.id,
|
||||||
|
!e.currentTarget.checked
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
))}
|
||||||
|
</Stack>
|
||||||
|
{permissions.createServerUrl && (
|
||||||
|
<Button
|
||||||
|
compact
|
||||||
|
mt={10}
|
||||||
|
variant="default"
|
||||||
|
onClick={() => addUrlHandlers.open()}
|
||||||
|
>
|
||||||
|
Add URL
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</ServerSection>
|
||||||
|
|
||||||
<ServerSection title="Danger zone">
|
<ServerSection title="Danger zone">
|
||||||
|
<Group position="apart">
|
||||||
|
<Text>Require user credentials</Text>
|
||||||
|
<Switch
|
||||||
|
checked={server.noCredential}
|
||||||
|
onChange={(e) =>
|
||||||
|
toggleRequiredCredential(e.currentTarget.checked)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
|
<Divider my="xl" />
|
||||||
{permissions.deleteServer && (
|
{permissions.deleteServer && (
|
||||||
<Button compact color="red" leftIcon={<RiDeleteBin2Fill />}>
|
<Button compact color="red" leftIcon={<RiDeleteBin2Fill />}>
|
||||||
Delete server
|
Delete server
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Accordion, Group } from '@mantine/core';
|
import { Accordion, Group } from '@mantine/core';
|
||||||
import { RiRefreshLine, RiRestartLine, RiServerFill } from 'react-icons/ri';
|
import { RiServerFill } from 'react-icons/ri';
|
||||||
import { Button, Text } from '@/renderer/components';
|
import { Text } from '@/renderer/components';
|
||||||
import { ServerListItem } from '@/renderer/features/servers/components/server-list-item';
|
import { ServerListItem } from '@/renderer/features/servers/components/server-list-item';
|
||||||
import { useServerList } from '@/renderer/features/servers/queries/use-server-list';
|
import { useServerList } from '@/renderer/features/servers/queries/use-server-list';
|
||||||
import { Font } from '@/renderer/styles';
|
import { Font } from '@/renderer/styles';
|
||||||
@@ -9,18 +9,6 @@ import { titleCase } from '@/renderer/utils';
|
|||||||
export const ServerList = () => {
|
export const ServerList = () => {
|
||||||
const { data: servers } = useServerList();
|
const { data: servers } = useServerList();
|
||||||
|
|
||||||
const handleQuickScan = (
|
|
||||||
e: React.MouseEvent<HTMLButtonElement, MouseEvent>
|
|
||||||
) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFullScan = (
|
|
||||||
e: React.MouseEvent<HTMLButtonElement, MouseEvent>
|
|
||||||
) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Accordion variant="separated">
|
<Accordion variant="separated">
|
||||||
@@ -31,27 +19,6 @@ export const ServerList = () => {
|
|||||||
<Text font={Font.GOTHAM}>
|
<Text font={Font.GOTHAM}>
|
||||||
{titleCase(s.type)} - {s.name}
|
{titleCase(s.type)} - {s.name}
|
||||||
</Text>
|
</Text>
|
||||||
<Group spacing="xs">
|
|
||||||
<Button
|
|
||||||
component="div"
|
|
||||||
px={10}
|
|
||||||
role="button"
|
|
||||||
tabIndex={0}
|
|
||||||
tooltip={{ label: 'Full scan' }}
|
|
||||||
variant="subtle"
|
|
||||||
onClick={handleFullScan}
|
|
||||||
>
|
|
||||||
<RiRefreshLine color="white" size={20} />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
px={10}
|
|
||||||
tooltip={{ label: 'Quick scan' }}
|
|
||||||
variant="subtle"
|
|
||||||
onClick={handleQuickScan}
|
|
||||||
>
|
|
||||||
<RiRestartLine color="white" size={20} />
|
|
||||||
</Button>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
</Group>
|
||||||
</Accordion.Control>
|
</Accordion.Control>
|
||||||
<Accordion.Panel>
|
<Accordion.Panel>
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export const useDisableServerFolder = () => {
|
|||||||
return { previous };
|
return { previous };
|
||||||
},
|
},
|
||||||
onSettled: () => {
|
onSettled: () => {
|
||||||
queryClient.invalidateQueries(queryKeys.servers.list());
|
queryClient.invalidateQueries(queryKeys.servers.root);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export const useEnableServerFolder = () => {
|
|||||||
return { previous };
|
return { previous };
|
||||||
},
|
},
|
||||||
onSettled: () => {
|
onSettled: () => {
|
||||||
queryClient.invalidateQueries(queryKeys.servers.list());
|
queryClient.invalidateQueries(queryKeys.servers.root);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { AxiosError } from 'axios';
|
||||||
|
import { api } from '@/renderer/api';
|
||||||
|
import { queryKeys } from '@/renderer/api/query-keys';
|
||||||
|
import { ServerListResponse } from '@/renderer/api/servers.api';
|
||||||
|
import { ApiError, NullResponse } from '@/renderer/api/types';
|
||||||
|
|
||||||
|
export const useFullScan = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const mutation = useMutation<
|
||||||
|
NullResponse,
|
||||||
|
AxiosError<ApiError>,
|
||||||
|
{
|
||||||
|
body: { serverFolderId?: string[] };
|
||||||
|
query: { serverId: string };
|
||||||
|
},
|
||||||
|
{ previous: ServerListResponse | undefined }
|
||||||
|
>({
|
||||||
|
mutationFn: ({ body, query }) => api.servers.fullScan({ body, query }),
|
||||||
|
onError: (_err, _variables, context) => {
|
||||||
|
if (!context?.previous) return;
|
||||||
|
queryClient.setQueryData(queryKeys.servers.list(), context.previous);
|
||||||
|
},
|
||||||
|
onMutate: async () => {
|
||||||
|
const queryKey = queryKeys.servers.list();
|
||||||
|
|
||||||
|
await queryClient.cancelQueries(queryKey);
|
||||||
|
const previous = queryClient.getQueryData<ServerListResponse>(queryKey);
|
||||||
|
|
||||||
|
return { previous };
|
||||||
|
},
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries(queryKeys.servers.list());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return mutation;
|
||||||
|
};
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { AxiosError } from 'axios';
|
||||||
|
import { api } from '@/renderer/api';
|
||||||
|
import { queryKeys } from '@/renderer/api/query-keys';
|
||||||
|
import { ServerListResponse } from '@/renderer/api/servers.api';
|
||||||
|
import { ApiError, NullResponse } from '@/renderer/api/types';
|
||||||
|
|
||||||
|
export const useQuickScan = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const mutation = useMutation<
|
||||||
|
NullResponse,
|
||||||
|
AxiosError<ApiError>,
|
||||||
|
{
|
||||||
|
body: { serverFolderId?: string[] };
|
||||||
|
query: { serverId: string };
|
||||||
|
},
|
||||||
|
{ previous: ServerListResponse | undefined }
|
||||||
|
>({
|
||||||
|
mutationFn: ({ body, query }) => api.servers.quickScan({ body, query }),
|
||||||
|
onError: (_err, _variables, context) => {
|
||||||
|
if (!context?.previous) return;
|
||||||
|
queryClient.setQueryData(queryKeys.servers.list(), context.previous);
|
||||||
|
},
|
||||||
|
onMutate: async () => {
|
||||||
|
const queryKey = queryKeys.servers.list();
|
||||||
|
|
||||||
|
await queryClient.cancelQueries(queryKey);
|
||||||
|
const previous = queryClient.getQueryData<ServerListResponse>(queryKey);
|
||||||
|
|
||||||
|
return { previous };
|
||||||
|
},
|
||||||
|
onSettled: () => {
|
||||||
|
queryClient.invalidateQueries(queryKeys.servers.list());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return mutation;
|
||||||
|
};
|
||||||
@@ -39,10 +39,16 @@ export const useUpdateServer = () => {
|
|||||||
if (!previous) return undefined;
|
if (!previous) return undefined;
|
||||||
const data = previous.data.map((server) => {
|
const data = previous.data.map((server) => {
|
||||||
if (server.id === variables.query.serverId) {
|
if (server.id === variables.query.serverId) {
|
||||||
|
if (variables.body.name || variables.body.username) {
|
||||||
|
return {
|
||||||
|
...server,
|
||||||
|
name: variables.body.name,
|
||||||
|
username: variables.body?.username,
|
||||||
|
};
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
...server,
|
...server,
|
||||||
name: variables.body.name,
|
noCredential: variables.body.noCredential,
|
||||||
username: variables.body.username,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,13 +62,6 @@ export const useUpdateServer = () => {
|
|||||||
onSettled: () => {
|
onSettled: () => {
|
||||||
queryClient.invalidateQueries(queryKeys.servers.list());
|
queryClient.invalidateQueries(queryKeys.servers.list());
|
||||||
},
|
},
|
||||||
onSuccess: (data) => {
|
|
||||||
toast.show({
|
|
||||||
message: `Server "${data.data.name}" updated`,
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
queryClient.invalidateQueries(queryKeys.servers.list());
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return mutation;
|
return mutation;
|
||||||
|
|||||||
@@ -3,65 +3,29 @@ import { api } from '@/renderer/api';
|
|||||||
import { queryKeys } from '@/renderer/api/query-keys';
|
import { queryKeys } from '@/renderer/api/query-keys';
|
||||||
import { ServerListResponse } from '@/renderer/api/servers.api';
|
import { ServerListResponse } from '@/renderer/api/servers.api';
|
||||||
import { QueryOptions } from '@/renderer/lib/react-query';
|
import { QueryOptions } from '@/renderer/lib/react-query';
|
||||||
|
import { useAuthStore } from '@/renderer/store';
|
||||||
|
|
||||||
export const useServerList = (options?: QueryOptions<ServerListResponse>) => {
|
export const useServerList = (
|
||||||
// return useQuery({
|
params?: { enabled?: boolean },
|
||||||
// // onSuccess: (servers) => {
|
options?: QueryOptions<ServerListResponse>
|
||||||
// // const { serverUrl } = JSON.parse(
|
) => {
|
||||||
// // localStorage.getItem('authentication') || '{}'
|
const currentServer = useAuthStore((state) => state.currentServer);
|
||||||
// // );
|
const setCurrentServer = useAuthStore((state) => state.setCurrentServer);
|
||||||
// // const storedServersKey = `servers_${md5(serverUrl)}`;
|
|
||||||
// // const serversFromLocalStorage = localStorage.getItem(storedServersKey);
|
|
||||||
// // // If a custom account/token is set for a server, use that instead of the default one
|
|
||||||
// // if (serversFromLocalStorage) {
|
|
||||||
// // const existingServers = JSON.parse(serversFromLocalStorage);
|
|
||||||
// // // The 'locked' property determines whether or not to skip updating the server auth
|
|
||||||
// // const skipped = existingServers.filter(
|
|
||||||
// // (server: ServerFolderAuth) => server.locked
|
|
||||||
// // );
|
|
||||||
// // const store = servers?.data?.flatMap((server) =>
|
|
||||||
// // server.serverFolders?.map((serverFolder: ServerFolder) => {
|
|
||||||
// // if (skipped.includes(serverFolder.id)) {
|
|
||||||
// // return existingServers.find(
|
|
||||||
// // (s: ServerFolderAuth) => s.id === serverFolder.id
|
|
||||||
// // );
|
|
||||||
// // }
|
|
||||||
// // return {
|
|
||||||
// // id: serverFolder.id,
|
|
||||||
// // locked: false,
|
|
||||||
// // serverId: server.id,
|
|
||||||
// // token: server.token,
|
|
||||||
// // type: server.type,
|
|
||||||
// // url: server.url,
|
|
||||||
// // userId: server.remoteUserId,
|
|
||||||
// // username: server.username,
|
|
||||||
// // };
|
|
||||||
// // })
|
|
||||||
// // );
|
|
||||||
// // return localStorage.setItem(storedServersKey, JSON.stringify(store));
|
|
||||||
// // }
|
|
||||||
// // const store = servers?.data?.flatMap((server) =>
|
|
||||||
// // server.serverFolders?.map((serverFolder: ServerFolder) => ({
|
|
||||||
// // id: serverFolder.id,
|
|
||||||
// // locked: false,
|
|
||||||
// // serverId: server.id,
|
|
||||||
// // token: server.token,
|
|
||||||
// // type: server.type,
|
|
||||||
// // url: server.url,
|
|
||||||
// // userId: server.remoteUserId,
|
|
||||||
// // username: server.username,
|
|
||||||
// // }))
|
|
||||||
// // );
|
|
||||||
// // return localStorage.setItem(storedServersKey, JSON.stringify(store));
|
|
||||||
// // },
|
|
||||||
// queryFn: () => api.servers.getServerList(),
|
|
||||||
// queryKey: queryKeys.server.list,
|
|
||||||
// ...options,
|
|
||||||
// });
|
|
||||||
|
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryFn: () => api.servers.getServerList(),
|
onSuccess: (data) => {
|
||||||
queryKey: queryKeys.servers.list(),
|
const currentServerFromList = data.data.find(
|
||||||
|
(server) => server.id === currentServer?.id
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!currentServerFromList) {
|
||||||
|
return setCurrentServer(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return setCurrentServer(currentServerFromList);
|
||||||
|
},
|
||||||
|
queryFn: () => api.servers.getServerList(params),
|
||||||
|
queryKey: queryKeys.servers.list(params),
|
||||||
...options,
|
...options,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user