/* * Copyright (c) 2021 - 2023, Ludvig Lundgren and the autobrr contributors. * SPDX-License-Identifier: GPL-2.0-or-later */ import { useState, useMemo } from "react"; import { Switch } from "@headlessui/react"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import toast from "react-hot-toast"; import { useToggle } from "@hooks/hooks"; import { classNames } from "@utils"; import { DownloadClientAddForm, DownloadClientUpdateForm } from "@forms"; import { EmptySimple } from "@components/emptystates"; import { APIClient } from "@api/APIClient"; import { DownloadClientTypeNameMap } from "@domain/constants"; import Toast from "@components/notifications/Toast"; export const clientKeys = { all: ["download_clients"] as const, lists: () => [...clientKeys.all, "list"] as const, // list: (indexers: string[], sortOrder: string) => [...clientKeys.lists(), { indexers, sortOrder }] as const, details: () => [...clientKeys.all, "detail"] as const, detail: (id: number) => [...clientKeys.details(), id] as const }; interface DLSettingsItemProps { client: DownloadClient; idx: number; } interface ListItemProps { clients: DownloadClient; } interface SortConfig { key: keyof ListItemProps["clients"] | "enabled"; direction: "ascending" | "descending"; } function useSort(items: ListItemProps["clients"][], config?: SortConfig) { const [sortConfig, setSortConfig] = useState(config); const sortedItems = useMemo(() => { if (!sortConfig) { return items; } const sortableItems = [...items]; sortableItems.sort((a, b) => { const aValue = sortConfig.key === "enabled" ? (a[sortConfig.key] ?? false) as number | boolean | string : a[sortConfig.key] as number | boolean | string; const bValue = sortConfig.key === "enabled" ? (b[sortConfig.key] ?? false) as number | boolean | string : b[sortConfig.key] as number | boolean | string; if (aValue < bValue) { return sortConfig.direction === "ascending" ? -1 : 1; } if (aValue > bValue) { return sortConfig.direction === "ascending" ? 1 : -1; } return 0; }); return sortableItems; }, [items, sortConfig]); const requestSort = (key: keyof ListItemProps["clients"]) => { let direction: "ascending" | "descending" = "ascending"; if ( sortConfig && sortConfig.key === key && sortConfig.direction === "ascending" ) { direction = "descending"; } setSortConfig({ key, direction }); }; const getSortIndicator = (key: keyof ListItemProps["clients"]) => { if (!sortConfig || sortConfig.key !== key) { return ""; } return sortConfig.direction === "ascending" ? "↑" : "↓"; }; return { items: sortedItems, requestSort, sortConfig, getSortIndicator }; } function DownloadClientSettingsListItem({ client }: DLSettingsItemProps) { const [updateClientIsOpen, toggleUpdateClient] = useToggle(false); const queryClient = useQueryClient(); const mutation = useMutation({ mutationFn: (client: DownloadClient) => APIClient.download_clients.update(client).then(() => client), onSuccess: (client: DownloadClient) => { toast.custom(t => ); queryClient.invalidateQueries({ queryKey: clientKeys.lists() }); } }); const onToggleMutation = (newState: boolean) => { mutation.mutate({ ...client, enabled: newState }); }; return (
  • Use setting
    {client.name}
    {client.host}
    {DownloadClientTypeNameMap[client.type]}
    Edit
  • ); } function DownloadClientSettings() { const [addClientIsOpen, toggleAddClient] = useToggle(false); const { error, data } = useQuery({ queryKey: clientKeys.lists(), queryFn: APIClient.download_clients.getAll, refetchOnWindowFocus: false }); const sortedClients = useSort(data || []); if (error) { return

    Failed to fetch download clients

    ; } return (

    Clients

    Manage download clients.

    {sortedClients.items.length > 0 ?
    1. sortedClients.requestSort("enabled")}> Enabled {sortedClients.getSortIndicator("enabled")}
      sortedClients.requestSort("name")} > Name {sortedClients.getSortIndicator("name")}
      sortedClients.requestSort("host")} > Host {sortedClients.getSortIndicator("host")}
      sortedClients.requestSort("type")} > Type {sortedClients.getSortIndicator("type")}
    2. {sortedClients.items.map((client, idx) => ( ))}
    : }
    ); } export default DownloadClientSettings;