From b60e5f61c6423f4883246e6ded89742876785b18 Mon Sep 17 00:00:00 2001 From: stacksmash76 <98354295+stacksmash76@users.noreply.github.com> Date: Thu, 10 Feb 2022 17:47:05 +0100 Subject: [PATCH] refactor: web api client and cleanup (#128) refactor: refactored APIClient.ts with a new fetch wrapper and changed it into an explicit-import. chore: modified package.json not to start browser on "npm run start" chore: cleaned up code, deleted 2mo+ useless old comments. fix: fixed parameter collision in screens/filters/details.tsx fix: override react-select's Select component style to make it consistent. addresses #116 Co-authored-by: anonymous --- web/package.json | 2 +- web/src/api/APIClient.ts | 122 ++- web/src/forms/filters/FilterAddForm.tsx | 2 +- .../forms/settings/DownloadClientForms.tsx | 2 +- web/src/forms/settings/IndexerForms.tsx | 23 +- web/src/forms/settings/IrcForms.tsx | 2 +- web/src/screens/Dashboard.tsx | 896 +++++------------- web/src/screens/Logs.tsx | 2 +- web/src/screens/Releases.tsx | 8 +- web/src/screens/auth/login.tsx | 2 +- web/src/screens/auth/logout.tsx | 2 +- web/src/screens/filters/details.tsx | 39 +- web/src/screens/filters/list.tsx | 10 +- web/src/screens/settings/Application.tsx | 4 +- web/src/screens/settings/DownloadClient.tsx | 11 +- web/src/screens/settings/Indexer.tsx | 14 +- web/src/screens/settings/Irc.tsx | 33 +- 17 files changed, 381 insertions(+), 793 deletions(-) diff --git a/web/package.json b/web/package.json index cb419eb..0ac181e 100644 --- a/web/package.json +++ b/web/package.json @@ -23,7 +23,7 @@ "web-vitals": "^1.0.1" }, "scripts": { - "start": "react-scripts start", + "start": "BROWSER=none react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", diff --git a/web/src/api/APIClient.ts b/web/src/api/APIClient.ts index 846f3be..1249f4b 100644 --- a/web/src/api/APIClient.ts +++ b/web/src/api/APIClient.ts @@ -1,72 +1,55 @@ import {baseUrl, sseBaseUrl} from "../utils"; -function baseClient(endpoint: string, method: string, { body, ...customConfig}: any = {}) { - const baseURL = baseUrl() +interface ConfigType { + body?: BodyInit | Record | null; + headers?: Record; +} - const headers = {'content-type': 'application/json'} +export async function HttpClient( + endpoint: string, + method: string, + { body, ...customConfig }: ConfigType = {} +): Promise { const config = { method: method, - ...customConfig, + body: body ? JSON.stringify(body) : null, headers: { - ...headers, - ...customConfig.headers, + "Content-Type": "application/json" }, - } + // NOTE: customConfig can override the above defined settings + ...customConfig + } as RequestInit; - if (body) { - config.body = JSON.stringify(body) - } - - return window.fetch(`${baseURL}${endpoint}`, config) + return window.fetch(`${baseUrl()}${endpoint}`, config) .then(async response => { - if (response.status === 401) { - // unauthorized - // window.location.assign(window.location) + if ([401, 403, 404].includes(response.status)) + return Promise.reject(new Error(response.statusText)); - return Promise.reject(new Error(response.statusText)) - } - - if (response.status === 403) { - // window.location.assign("/login") - return Promise.reject(new Error(response.statusText)) - // return - } - - if (response.status === 404) { - return Promise.reject(new Error(response.statusText)) - } - - if (response.status === 201) { - return "" - } - - if (response.status === 204) { - return "" - } + if ([201, 204].includes(response.status)) + return Promise.resolve(response); if (response.ok) { - return await response.json() + return await response.json(); } else { - const errorMessage = await response.text() - - return Promise.reject(new Error(errorMessage)) + const errorMessage = await response.text(); + return Promise.reject(new Error(errorMessage)); } - }) + }); } const appClient = { - Get: (endpoint: string) => baseClient(endpoint, "GET"), - Post: (endpoint: string, data: any) => baseClient(endpoint, "POST", { body: data }), - Put: (endpoint: string, data: any) => baseClient(endpoint, "PUT", { body: data }), - Patch: (endpoint: string, data: any) => baseClient(endpoint, "PATCH", { body: data }), - Delete: (endpoint: string) => baseClient(endpoint, "DELETE"), + Get: (endpoint: string) => HttpClient(endpoint, "GET"), + Post: (endpoint: string, data: any) => HttpClient(endpoint, "POST", { body: data }), + Put: (endpoint: string, data: any) => HttpClient(endpoint, "PUT", { body: data }), + Patch: (endpoint: string, data: any) => HttpClient(endpoint, "PATCH", { body: data }), + Delete: (endpoint: string) => HttpClient(endpoint, "DELETE") } -const APIClient = { +export const APIClient = { auth: { - login: (username: string, password: string) => appClient.Post("api/auth/login", {username: username, password: password}), - logout: () => appClient.Post(`api/auth/logout`, null), - test: () => appClient.Get(`api/auth/test`), + login: (username: string, password: string) => appClient.Post("api/auth/login", { username: username, password: password }), + logout: () => appClient.Post("api/auth/logout", null), + test: () => appClient.Get("api/auth/test"), }, actions: { create: (action: Action) => appClient.Post("api/actions", action), @@ -75,34 +58,37 @@ const APIClient = { toggleEnable: (id: number) => appClient.Patch(`api/actions/${id}/toggleEnabled`, null), }, config: { - get: () => appClient.Get("api/config") + get: () => appClient.Get("api/config") }, download_clients: { - getAll: () => appClient.Get("api/download_clients"), - create: (dc: DownloadClient) => appClient.Post(`api/download_clients`, dc), - update: (dc: DownloadClient) => appClient.Put(`api/download_clients`, dc), + getAll: () => appClient.Get("api/download_clients"), + create: (dc: DownloadClient) => appClient.Post("api/download_clients", dc), + update: (dc: DownloadClient) => appClient.Put("api/download_clients", dc), delete: (id: number) => appClient.Delete(`api/download_clients/${id}`), - test: (dc: DownloadClient) => appClient.Post(`api/download_clients/test`, dc), + test: (dc: DownloadClient) => appClient.Post("api/download_clients/test", dc), }, filters: { - getAll: () => appClient.Get("api/filters"), - getByID: (id: number) => appClient.Get(`api/filters/${id}`), - create: (filter: Filter) => appClient.Post(`api/filters`, filter), + getAll: () => appClient.Get("api/filters"), + getByID: (id: number) => appClient.Get(`api/filters/${id}`), + create: (filter: Filter) => appClient.Post("api/filters", filter), update: (filter: Filter) => appClient.Put(`api/filters/${filter.id}`, filter), toggleEnable: (id: number, enabled: boolean) => appClient.Put(`api/filters/${id}/enabled`, { enabled }), delete: (id: number) => appClient.Delete(`api/filters/${id}`), }, indexers: { - getOptions: () => appClient.Get("api/indexer/options"), - getAll: () => appClient.Get("api/indexer"), - getSchema: () => appClient.Get("api/indexer/schema"), - create: (indexer: Indexer) => appClient.Post(`api/indexer`, indexer), - update: (indexer: Indexer) => appClient.Put(`api/indexer`, indexer), + // returns indexer options for all currently present/enabled indexers + getOptions: () => appClient.Get("api/indexer/options"), + // returns indexer definitions for all currently present/enabled indexers + getAll: () => appClient.Get("api/indexer"), + // returns all possible indexer definitions + getSchema: () => appClient.Get("api/indexer/schema"), + create: (indexer: Indexer) => appClient.Post("api/indexer", indexer), + update: (indexer: Indexer) => appClient.Put("api/indexer", indexer), delete: (id: number) => appClient.Delete(`api/indexer/${id}`), }, irc: { - getNetworks: () => appClient.Get("api/irc"), - createNetwork: (network: Network) => appClient.Post(`api/irc`, network), + getNetworks: () => appClient.Get("api/irc"), + createNetwork: (network: Network) => appClient.Post("api/irc", network), updateNetwork: (network: Network) => appClient.Put(`api/irc/network/${network.id}`, network), deleteNetwork: (id: number) => appClient.Delete(`api/irc/network/${id}`), }, @@ -110,9 +96,7 @@ const APIClient = { logs: () => new EventSource(`${sseBaseUrl()}api/events?stream=logs`, { withCredentials: true }) }, release: { - find: (query?: string) => appClient.Get(`api/release${query}`), - stats: () => appClient.Get(`api/release/stats`) + find: (query?: string) => appClient.Get(`api/release${query}`), + stats: () => appClient.Get("api/release/stats") } -} - -export default APIClient; \ No newline at end of file +}; \ No newline at end of file diff --git a/web/src/forms/filters/FilterAddForm.tsx b/web/src/forms/filters/FilterAddForm.tsx index 0e6ba30..d4f4e58 100644 --- a/web/src/forms/filters/FilterAddForm.tsx +++ b/web/src/forms/filters/FilterAddForm.tsx @@ -7,7 +7,7 @@ import { Field, Form, Formik } from "formik"; import type { FieldProps } from "formik"; import { queryClient } from "../../App"; -import APIClient from "../../api/APIClient"; +import { APIClient } from "../../api/APIClient"; import DEBUG from "../../components/debug"; import Toast from '../../components/notifications/Toast'; diff --git a/web/src/forms/settings/DownloadClientForms.tsx b/web/src/forms/settings/DownloadClientForms.tsx index 0b85bec..e2505e4 100644 --- a/web/src/forms/settings/DownloadClientForms.tsx +++ b/web/src/forms/settings/DownloadClientForms.tsx @@ -6,7 +6,7 @@ import { sleep, classNames } from "../../utils"; import { Form, Formik, useFormikContext } from "formik"; import DEBUG from "../../components/debug"; import { queryClient } from "../../App"; -import APIClient from "../../api/APIClient"; +import { APIClient } from "../../api/APIClient"; import { DownloadClientTypeOptions } from "../../domain/constants"; import { toast } from 'react-hot-toast' diff --git a/web/src/forms/settings/IndexerForms.tsx b/web/src/forms/settings/IndexerForms.tsx index 3833cf6..0ef126e 100644 --- a/web/src/forms/settings/IndexerForms.tsx +++ b/web/src/forms/settings/IndexerForms.tsx @@ -11,7 +11,7 @@ import { Dialog, Transition } from "@headlessui/react"; import { sleep } from "../../utils"; import { queryClient } from "../../App"; import DEBUG from "../../components/debug"; -import APIClient from "../../api/APIClient"; +import { APIClient } from "../../api/APIClient"; import { TextFieldWide, PasswordFieldWide, @@ -48,13 +48,22 @@ const Menu = (props: any) => { ); } +const Option = (props: any) => { + return ( + + ); +} + interface AddProps { isOpen: boolean; toggle: any; } export function IndexerAddForm({ isOpen, toggle }: AddProps) { - const { data } = useQuery('indexerDefinition', APIClient.indexers.getSchema, + const { data } = useQuery('indexerDefinition', APIClient.indexers.getSchema, { enabled: isOpen, refetchOnWindowFocus: false @@ -237,8 +246,14 @@ export function IndexerAddForm({ isOpen, toggle }: AddProps) { { - setValue(e.target.value); - onChange(e.target.value); - }} - placeholder={`${count} records...`} - /> - - ) -} */ + ) +} // This is a custom filter UI for selecting // a unique option from a list export function SelectColumnFilter({ - column: { filterValue, setFilter, preFilteredRows, id, render }, + column: { filterValue, setFilter, preFilteredRows, id, render }, }: any) { - // Calculate the options for filtering - // using the preFilteredRows - const options = React.useMemo(() => { - const options: any = new Set() - preFilteredRows.forEach((row: { values: { [x: string]: unknown } }) => { - options.add(row.values[id]) - }) - return [...options.values()] - }, [id, preFilteredRows]) + // Calculate the options for filtering + // using the preFilteredRows + const options = React.useMemo(() => { + const options: any = new Set() + preFilteredRows.forEach((row: { values: { [x: string]: unknown } }) => { + options.add(row.values[id]) + }) + return [...options.values()] + }, [id, preFilteredRows]) - // Render a multi-select box - return ( - - ) + // Render a multi-select box + return ( + + ) } -// export function StatusPill({ value }: any) { - -// const status = value ? value.toLowerCase() : "unknown"; - -// return ( -// -// {status} -// -// ); -// }; - export function StatusPill({ value }: any) { - const statusMap: any = { - "FILTER_APPROVED": Approved, - "FILTER_REJECTED": Rejected, - "PUSH_REJECTED": Rejected, - "PUSH_APPROVED": Approved, - "PENDING": PENDING, - "MIXED": MIXED, - } + const statusMap: any = { + "FILTER_APPROVED": Approved, + "FILTER_REJECTED": Rejected, + "PUSH_REJECTED": Rejected, + "PUSH_APPROVED": Approved, + "PENDING": PENDING, + "MIXED": MIXED, + } - return statusMap[value]; + return statusMap[value]; } export function AgeCell({ value }: any) { - const formatDate = formatDistanceToNowStrict( - new Date(value), - { addSuffix: true } - ) + const formatDate = formatDistanceToNowStrict( + new Date(value), + { addSuffix: true } + ) - return ( -
{formatDate}
- ) + return ( +
{formatDate}
+ ) } export function ReleaseCell({ value }: any) { - return ( -
{value}
- ) + return ( +
{value}
+ ) } export function IndexerCell({ value }: any) { @@ -409,307 +139,183 @@ export function IndexerCell({ value }: any) { } function Table({ columns, data }: any) { - // Use the state and functions returned from useTable to build your UI - const { - getTableProps, - getTableBodyProps, - headerGroups, - prepareRow, - page, // Instead of using 'rows', we'll use page, - // which has only the rows for the active page + // Use the state and functions returned from useTable to build your UI + const { + getTableProps, + getTableBodyProps, + headerGroups, + prepareRow, + page, // Instead of using 'rows', we'll use page, + // which has only the rows for the active page - // The rest of these things are super handy, too ;) - // canPreviousPage, - // canNextPage, - // pageOptions, - // pageCount, - // gotoPage, - // nextPage, - // previousPage, - // setPageSize, + // The rest of these things are super handy, too ;) + // canPreviousPage, + // canNextPage, + // pageOptions, + // pageCount, + // gotoPage, + // nextPage, + // previousPage, + // setPageSize, - // state, - // preGlobalFilteredRows, - // setGlobalFilter, - } = useTable({ - columns, - data, - }, - useFilters, // useFilters! - useGlobalFilter, - useSortBy, - usePagination, // new - ) - - // Render the UI for your table - return ( - <> -
- {/* */} - {/* {headerGroups.map((headerGroup: { headers: any[] }) => - headerGroup.headers.map((column) => - column.Filter ? ( -
- {column.render("Filter")} -
- ) : null - ) - )} */} -
- {page.length > 0 ? -
-
-
-
- - - {headerGroups.map((headerGroup) => { - const { key: rowKey, ...rowRest } = headerGroup.getHeaderGroupProps(); - return ( - - {headerGroup.headers.map((column) => { - const { key: columnKey, ...columnRest } = column.getHeaderProps(column.getSortByToggleProps()); - return ( - // Add the sorting props to control sorting. For this example - // we can add them into the header props - - ); - })} - - ); - })} - - - {page.map((row: any) => { - prepareRow(row); - const { key: bodyRowKey, ...bodyRowRest } = row.getRowProps(); - return ( - - {row.cells.map((cell: any) => { - const { key: cellRowKey, ...cellRowRest } = cell.getCellProps(); - return ( - - ) - })} - - ) - })} - -
-
- {column.render('Header')} - {/* Add a sort direction indicator */} - - {column.isSorted ? ( - column.isSortedDesc ? ( - - ) : ( - - ) - ) : ( - - )} - -
-
- {cell.column.Cell.name === "defaultRenderer" - ?
{cell.render('Cell')}
- : cell.render('Cell') - } -
- - - {/* Pagination */} - {/*
-
- - -
-
-
- - Page {state.pageIndex + 1} of {pageOptions.length} - - -
-
- -
-
-
*/} + // state, + // preGlobalFilteredRows, + // setGlobalFilter, + } = useTable({ + columns, + data, + }, + useFilters, // useFilters! + useGlobalFilter, + useSortBy, + usePagination, // new + ); + if (!page.length) + return ; + // Render the UI for your table + return ( +
+
+
+
+ + + {headerGroups.map((headerGroup) => { + const { key: rowKey, ...rowRest } = headerGroup.getHeaderGroupProps(); + return ( + + {headerGroup.headers.map((column) => { + const { key: columnKey, ...columnRest } = column.getHeaderProps(column.getSortByToggleProps()); + return ( + // Add the sorting props to control sorting. For this example + // we can add them into the header props + + ); + })} + + ); + })} + + + {page.map((row: any) => { + prepareRow(row); + const { key: bodyRowKey, ...bodyRowRest } = row.getRowProps(); + return ( + + {row.cells.map((cell: any) => { + const { key: cellRowKey, ...cellRowRest } = cell.getCellProps(); + return ( + + ) + })} + + ) + })} + +
+
+ {column.render('Header')} + {/* Add a sort direction indicator */} + + {column.isSorted ? ( + column.isSortedDesc ? ( + + ) : ( + + ) + ) : ( + + )} + +
+
+ {cell.column.Cell.name === "defaultRenderer" + ?
{cell.render('Cell')}
+ : cell.render('Cell') + } +
+
+
-
-
- : } - - ) + ); } function SortIcon({ className }: any) { - return ( - - ) + return ( + + ) } function SortUpIcon({ className }: any) { - return ( - - ) + return ( + + ) } function SortDownIcon({ className }: any) { - return ( - - ) + return ( + + ) } -/* function Button({ children, className, ...rest }: any) { - return ( - - ) -} - -function PageButton({ children, className, ...rest }: any) { - return ( - - ) -} */ - -function DataTablee() { - - const columns = React.useMemo(() => [ - { - Header: "Age", - accessor: 'timestamp', - Cell: AgeCell, - }, - { - Header: "Release", - accessor: 'torrent_name', - Cell: ReleaseCell, - }, - // { - // Header: "Filter Status", - // accessor: 'filter_status', - // Cell: StatusPill, - // }, - { - Header: "Actions", - accessor: 'action_status', - Cell: ReleaseStatusCell, - }, - { - Header: "Indexer", - accessor: 'indexer', - Cell: IndexerCell, - Filter: SelectColumnFilter, // new - filter: 'includes', - }, - ], []) - - // const data = React.useMemo(() => getData(), []) - - const { isLoading, data } = useQuery('dash_release', () => APIClient.release.find("?limit=10"), - { - refetchOnWindowFocus: false - } - ) - - if (isLoading) { - return null - } - - return ( -
-

Recent activity

- - - - ) +function DataTable() { + const columns = React.useMemo(() => [ + { + Header: "Age", + accessor: 'timestamp', + Cell: AgeCell, + }, + { + Header: "Release", + accessor: 'torrent_name', + Cell: ReleaseCell, + }, + { + Header: "Actions", + accessor: 'action_status', + Cell: ReleaseStatusCell, + }, + { + Header: "Indexer", + accessor: 'indexer', + Cell: IndexerCell, + Filter: SelectColumnFilter, // new + filter: 'includes', + }, + ], []) + + const { isLoading, data } = useQuery( + 'dash_release', + () => APIClient.release.find("?limit=10"), + { refetchOnWindowFocus: false } + ); + + if (isLoading) + return null; + + return ( +
+

+ Recent activity +

+ +
+ + ); } diff --git a/web/src/screens/Logs.tsx b/web/src/screens/Logs.tsx index b9d3436..973178b 100644 --- a/web/src/screens/Logs.tsx +++ b/web/src/screens/Logs.tsx @@ -1,5 +1,5 @@ import { useEffect, useRef, useState } from "react"; -import APIClient from "../api/APIClient"; +import { APIClient } from "../api/APIClient"; type LogEvent = { time: string; diff --git a/web/src/screens/Releases.tsx b/web/src/screens/Releases.tsx index 3ee3668..b731d9f 100644 --- a/web/src/screens/Releases.tsx +++ b/web/src/screens/Releases.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { useQuery } from "react-query"; import { formatDistanceToNowStrict } from "date-fns"; -import { useTable, useSortBy, usePagination } from "react-table"; +import { useTable, useSortBy, usePagination, Column } from "react-table"; import { ClockIcon, BanIcon, @@ -15,7 +15,7 @@ import { CheckIcon } from "@heroicons/react/solid"; -import APIClient from "../api/APIClient"; +import { APIClient } from "../api/APIClient"; import { EmptyListState } from "../components/emptystates"; import { classNames, simplifyDate } from "../utils"; @@ -222,7 +222,7 @@ function Table() { Filter: SelectColumnFilter, // new filter: 'includes', }, - ], []) + ] as Column[], []) const [{ queryPageIndex, queryPageSize, totalCount }, dispatch] = React.useReducer(reducer, initialState); @@ -260,7 +260,7 @@ function Table() { // setGlobalFilter, } = useTable({ columns, - data: isSuccess ? data.data : [], + data: data && isSuccess ? data.data : [], initialState: { pageIndex: queryPageIndex, pageSize: queryPageSize, diff --git a/web/src/screens/auth/login.tsx b/web/src/screens/auth/login.tsx index 7d1eec9..f6ed63f 100644 --- a/web/src/screens/auth/login.tsx +++ b/web/src/screens/auth/login.tsx @@ -2,7 +2,7 @@ import { useHistory } from "react-router-dom"; import { useMutation } from "react-query"; import { Form, Formik } from "formik"; -import APIClient from "../../api/APIClient"; +import { APIClient } from "../../api/APIClient"; import { TextField, PasswordField } from "../../components/inputs"; import logo from "../../logo.png"; diff --git a/web/src/screens/auth/logout.tsx b/web/src/screens/auth/logout.tsx index 1dc405f..e0e2cdd 100644 --- a/web/src/screens/auth/logout.tsx +++ b/web/src/screens/auth/logout.tsx @@ -2,7 +2,7 @@ import {useEffect} from "react"; import {useCookies} from "react-cookie"; import {useHistory} from "react-router-dom"; -import APIClient from "../../api/APIClient"; +import { APIClient } from "../../api/APIClient"; import { AuthContext } from "../../utils/Context"; function Logout() { diff --git a/web/src/screens/filters/details.tsx b/web/src/screens/filters/details.tsx index ecb7b59..149a307 100644 --- a/web/src/screens/filters/details.tsx +++ b/web/src/screens/filters/details.tsx @@ -29,7 +29,7 @@ import { RELEASE_TYPE_MUSIC_OPTIONS } from "../../domain/constants"; import { queryClient } from "../../App"; -import APIClient from "../../api/APIClient"; +import { APIClient } from "../../api/APIClient"; import { useToggle } from "../../hooks/hooks"; import { buildPath, classNames } from "../../utils"; @@ -134,7 +134,7 @@ export default function FilterDetails() { const { url } = useRouteMatch(); const { filterId } = useParams<{ filterId: string }>(); - const { isLoading, data: filter } = useQuery( + const { isLoading, data: filter } = useQuery( ['filter', +filterId], () => APIClient.filters.getByID(parseInt(filterId)), { @@ -144,14 +144,15 @@ export default function FilterDetails() { } ); - const updateMutation = useMutation((filter: Filter) => APIClient.filters.update(filter), { - onSuccess: (filter) => { - // queryClient.setQueryData(['filter', filter.id], data) - toast.custom((t) => ) - - queryClient.invalidateQueries(["filter", filter.id]); + const updateMutation = useMutation( + (filter: Filter) => APIClient.filters.update(filter), + { + onSuccess: () => { + toast.custom((t) => ) + queryClient.invalidateQueries(["filter", filter?.id]); + } } - }) + ); const deleteMutation = useMutation((id: number) => APIClient.filters.delete(id), { onSuccess: () => { @@ -315,11 +316,11 @@ export default function FilterDetails() { } function General() { - const { isLoading, data: indexers } = useQuery(["filter", "indexer_list"], APIClient.indexers.getOptions, - { - refetchOnWindowFocus: false - } - ) + const { isLoading, data: indexers } = useQuery( + ["filter", "indexer_list"], + APIClient.indexers.getOptions, + { refetchOnWindowFocus: false } + ); const opts = indexers && indexers.length > 0 ? indexers.map(v => ({ label: v.name, @@ -592,11 +593,11 @@ interface FilterActionsProps { } function FilterActions({ filter, values }: FilterActionsProps) { - const { data } = useQuery(['filter', 'download_clients'], APIClient.download_clients.getAll, - { - refetchOnWindowFocus: false - } - ) + const { data } = useQuery( + ['filter', 'download_clients'], + APIClient.download_clients.getAll, + { refetchOnWindowFocus: false } + ); const newAction = { name: "new action", diff --git a/web/src/screens/filters/list.tsx b/web/src/screens/filters/list.tsx index 9099f39..e1aab30 100644 --- a/web/src/screens/filters/list.tsx +++ b/web/src/screens/filters/list.tsx @@ -8,17 +8,17 @@ import { queryClient } from "../../App"; import { classNames } from "../../utils"; import { FilterAddForm } from "../../forms"; import { useToggle } from "../../hooks/hooks"; -import APIClient from "../../api/APIClient"; +import { APIClient } from "../../api/APIClient"; import Toast from "../../components/notifications/Toast"; import { EmptyListState } from "../../components/emptystates"; export default function Filters() { const [createFilterIsOpen, toggleCreateFilter] = useToggle(false) - const { isLoading, error, data } = useQuery('filter', APIClient.filters.getAll, - { - refetchOnWindowFocus: false - } + const { isLoading, error, data } = useQuery( + 'filter', + APIClient.filters.getAll, + { refetchOnWindowFocus: false } ); if (isLoading) { diff --git a/web/src/screens/settings/Application.tsx b/web/src/screens/settings/Application.tsx index bffe22c..dc2b3bb 100644 --- a/web/src/screens/settings/Application.tsx +++ b/web/src/screens/settings/Application.tsx @@ -1,6 +1,6 @@ import { useQuery } from "react-query"; -import APIClient from "../../api/APIClient"; +import { APIClient } from "../../api/APIClient"; import { Checkbox } from "../../components/Checkbox"; import { SettingsContext } from "../../utils/Context"; @@ -8,7 +8,7 @@ import { SettingsContext } from "../../utils/Context"; function ApplicationSettings() { const [settings, setSettings] = SettingsContext.use(); - const { isLoading, data } = useQuery( + const { isLoading, data } = useQuery( ['config'], () => APIClient.config.get(), { diff --git a/web/src/screens/settings/DownloadClient.tsx b/web/src/screens/settings/DownloadClient.tsx index d993cd5..7df1bf9 100644 --- a/web/src/screens/settings/DownloadClient.tsx +++ b/web/src/screens/settings/DownloadClient.tsx @@ -4,7 +4,7 @@ import { useQuery } from "react-query"; import { classNames } from "../../utils"; import { DownloadClientAddForm, DownloadClientUpdateForm } from "../../forms"; import { EmptySimple } from "../../components/emptystates"; -import APIClient from "../../api/APIClient"; +import { APIClient } from "../../api/APIClient"; import { DownloadClientTypeNameMap } from "../../domain/constants"; interface DLSettingsItemProps { @@ -53,10 +53,11 @@ function DownloadClientSettingsListItem({ client, idx }: DLSettingsItemProps) { function DownloadClientSettings() { const [addClientIsOpen, toggleAddClient] = useToggle(false) - const { error, data } = useQuery('downloadClients', APIClient.download_clients.getAll, - { - refetchOnWindowFocus: false - }) + const { error, data } = useQuery( + 'downloadClients', + APIClient.download_clients.getAll, + { refetchOnWindowFocus: false } + ); if (error) return (

An error has occurred:

); diff --git a/web/src/screens/settings/Indexer.tsx b/web/src/screens/settings/Indexer.tsx index acabe2a..691c025 100644 --- a/web/src/screens/settings/Indexer.tsx +++ b/web/src/screens/settings/Indexer.tsx @@ -4,7 +4,7 @@ import { IndexerAddForm, IndexerUpdateForm } from "../../forms"; import { Switch } from "@headlessui/react"; import { classNames } from "../../utils"; import { EmptySimple } from "../../components/emptystates"; -import APIClient from "../../api/APIClient"; +import { APIClient } from "../../api/APIClient"; const ListItem = ({ indexer }: any) => { const [updateIsOpen, toggleUpdate] = useToggle(false) @@ -45,11 +45,11 @@ const ListItem = ({ indexer }: any) => { function IndexerSettings() { const [addIndexerIsOpen, toggleAddIndexer] = useToggle(false) - const { error, data } = useQuery('indexer', APIClient.indexers.getAll, - { - refetchOnWindowFocus: false - } - ) + const { error, data } = useQuery( + 'indexer', + APIClient.indexers.getAll, + { refetchOnWindowFocus: false } + ); if (error) return (

An error has occurred

); @@ -104,7 +104,7 @@ function IndexerSettings() {
- {data && data.map((indexer: Indexer, idx: number) => ( + {data && data.map((indexer: IndexerDefinition, idx: number) => ( ))} diff --git a/web/src/screens/settings/Irc.tsx b/web/src/screens/settings/Irc.tsx index 4588954..84590ef 100644 --- a/web/src/screens/settings/Irc.tsx +++ b/web/src/screens/settings/Irc.tsx @@ -1,7 +1,7 @@ import { useQuery } from "react-query"; import { formatDistanceToNowStrict, formatISO9075 } from "date-fns"; -import APIClient from "../../api/APIClient"; +import { APIClient } from "../../api/APIClient"; import { useToggle } from "../../hooks/hooks"; import { EmptySimple } from "../../components/emptystates"; import { IrcNetworkAddForm, IrcNetworkUpdateForm } from "../../forms"; @@ -27,11 +27,11 @@ function simplifyDate(date: string) { function IrcSettings() { const [addNetworkIsOpen, toggleAddNetwork] = useToggle(false) - const { data } = useQuery('networks', APIClient.irc.getNetworks, - { - refetchOnWindowFocus: false - } - ) + const { data } = useQuery( + 'networks', + APIClient.irc.getNetworks, + { refetchOnWindowFocus: false } + ); return (
@@ -90,27 +90,8 @@ const LiItem = ({ idx, network }: LiItemProps) => {
  • - - {/*
    - - Enable - -
    */} +
    {