autobrr/web/src/screens/settings/Application.tsx
KaiserBh db7ab7c99a
feat(web): migrate Tanstack Query to v5 (#1277)
* feat: migrate to v5

* refactor: Revise error handling in QueryClient for compatibility with React Query v5

The `useErrorBoundary` option has been renamed to `throwOnError` and suspense have been removed: more on suspense more on suspense.
https://tanstack.com/query/v5/docs/react/guides/migrating-to-v5#new-hooks-for-suspense

* refactor: Callbacks on useQuery (and QueryObserver) have been removed

onSuccess, onError and onSettled have been removed from Queries. They haven't been touched for Mutations. Please see this https://github.com/TanStack/query/discussions/5279 for motivations behind this change and what to do instead.

* refactor: change to isPending, isLoading have been renamed for mutations.

Also, they are using object now:
- useQuery(key, fn, options)
+ useQuery({ queryKey, queryFn, ...options })

* refactor: change to placeHolderData.

Removed keepPreviousData in favor of placeholderData identity function
https://tanstack.com/query/v5/docs/react/guides/migrating-to-v5#removed-keeppreviousdata-in-favor-of-placeholderdata-identity-function

* fix: useSuspenseQuery instead of useQuery.

* fix(web): more useSuspenseQuery substitutions

* whoops - nobody saw that okay?

* fix pnpm lockfile

* fix pnpm lockfile again

---------

Co-authored-by: martylukyy <35452459+martylukyy@users.noreply.github.com>
Co-authored-by: soup <soup@r4tio.dev>
2023-12-25 15:37:29 +01:00

172 lines
6 KiB
TypeScript

/*
* Copyright (c) 2021 - 2023, Ludvig Lundgren and the autobrr contributors.
* SPDX-License-Identifier: GPL-2.0-or-later
*/
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "react-hot-toast";
import { APIClient } from "@api/APIClient";
import { SettingsContext } from "@utils/Context";
import { Checkbox } from "@components/Checkbox";
import Toast from "@components/notifications/Toast";
import { ExternalLink } from "@components/ExternalLink";
import { Section, RowItem } from "./_components";
function ApplicationSettings() {
const [settings, setSettings] = SettingsContext.use();
const { isError:isConfigError, error: configError, data } = useQuery({
queryKey: ["config"],
queryFn: APIClient.config.get,
retry: false,
refetchOnWindowFocus: false
});
if (isConfigError) {
console.log(configError);
}
const { isError, error, data: updateData } = useQuery({
queryKey: ["updates"],
queryFn: APIClient.updates.getLatestRelease,
retry: false,
refetchOnWindowFocus: false,
enabled: data?.check_for_updates === true
});
if (isError) {
console.log(error);
}
const queryClient = useQueryClient();
const checkUpdateMutation = useMutation({
mutationFn: APIClient.updates.check,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["updates"] });
}
});
const toggleCheckUpdateMutation = useMutation({
mutationFn: (value: boolean) => APIClient.config.update({ check_for_updates: value }).then(() => value),
onSuccess: (_, value: boolean) => {
toast.custom(t => <Toast type="success" body={`${value ? "You will now be notified of new updates." : "You will no longer be notified of new updates."}`} t={t} />);
queryClient.invalidateQueries({ queryKey: ["config"] });
checkUpdateMutation.mutate();
}
});
return (
<Section
title="Application"
description="Application settings. Change in config.toml and restart to take effect."
>
<div className="-mx-4 divide-y divide-gray-150 dark:divide-gray-750">
<form className="mt-6 mb-4" action="#" method="POST">
{data && (
<div className="grid grid-cols-12 gap-2 sm:gap-6 px-4 sm:px-6">
<div className="col-span-12 sm:col-span-4">
<label htmlFor="host" className="block ml-px text-xs font-bold text-gray-700 dark:text-white uppercase tracking-wide">
Host
</label>
<input
type="text"
name="host"
id="host"
value={data.host}
disabled={true}
className="mt-1 block w-full sm:text-sm rounded-md border-gray-300 dark:border-gray-750 bg-gray-100 dark:bg-gray-825 dark:text-gray-100"
/>
</div>
<div className="col-span-12 sm:col-span-4">
<label htmlFor="port" className="block ml-px text-xs font-bold text-gray-700 dark:text-white uppercase tracking-wide">
Port
</label>
<input
type="text"
name="port"
id="port"
value={data.port}
disabled={true}
className="mt-1 block w-full sm:text-sm rounded-md border-gray-300 dark:border-gray-750 bg-gray-100 dark:bg-gray-825 dark:text-gray-100"
/>
</div>
<div className="col-span-12 sm:col-span-4">
<label htmlFor="base_url" className="block ml-px text-xs font-bold text-gray-700 dark:text-white uppercase tracking-wide">
Base url
</label>
<input
type="text"
name="base_url"
id="base_url"
value={data.base_url}
disabled={true}
className="mt-1 block w-full sm:text-sm rounded-md border-gray-300 dark:border-gray-750 bg-gray-100 dark:bg-gray-825 dark:text-gray-100"
/>
</div>
</div>
)}
</form>
<RowItem
label="Version"
value={data?.version}
rightSide={
updateData && updateData.html_url ? (
<ExternalLink
href={updateData.html_url}
className="ml-2 inline-flex items-center rounded-md bg-green-100 px-2.5 py-0.5 text-sm font-medium text-green-800"
>
{updateData.name} available!
</ExternalLink>
) : null
}
/>
{data?.commit && <RowItem label="Commit" value={data.commit} />}
{data?.date && <RowItem label="Build date" value={data.date} />}
<RowItem label="Application" value={data?.application} />
<RowItem label="Config path" value={data?.config_dir} />
<RowItem label="Database" value={data?.database} />
<div className="py-0.5">
<Checkbox
label="WebUI Debug mode"
value={settings.debug}
className="p-4 sm:px-6"
setValue={
(newValue: boolean) => setSettings((prevState) => ({
...prevState,
debug: newValue
}))
}
/>
</div>
<Checkbox
label="Check for updates"
description="Get notified of new updates."
value={data?.check_for_updates ?? true}
className="p-4 sm:px-6"
setValue={(newValue: boolean) => {
toggleCheckUpdateMutation.mutate(newValue);
}}
/>
<Checkbox
label="Dark theme"
description="Switch between dark and light theme."
value={settings.darkTheme}
className="p-4 sm:px-6"
setValue={
(newValue: boolean) => setSettings((prevState) => ({
...prevState,
darkTheme: newValue
}))
}
/>
</div>
</Section>
);
}
export default ApplicationSettings;