129 lines · 4.0 KB · TypeScript
RawDownload
import type { EnvironmentId, UnifiedSettings } from "@t3tools/contracts";import { PlusIcon } from "lucide-react";import { useState } from "react"; import { useUpdateEnvironmentSettings } from "../../hooks/useSettings";import {  AlertDialog,  AlertDialogClose,  AlertDialogDescription,  AlertDialogFooter,  AlertDialogHeader,  AlertDialogPopup,  AlertDialogTitle,} from "../ui/alert-dialog";import { Button } from "../ui/button";import { AddUsageLimitSourceDialog } from "./AddUsageLimitSourceDialog";import { searchableSetting } from "./settingsSearch";import { SettingsRow, SettingsSection } from "./settingsLayout"; /** Hub management follows the selected device and access rules of provider settings. */export function UsageProviderSettings({  environmentId,  environmentLabel,  sources,  readOnly,}: {  readonly environmentId: EnvironmentId;  readonly environmentLabel: string;  readonly sources: UnifiedSettings["usageLimitSources"];  readonly readOnly: boolean;}) {  const updateSettings = useUpdateEnvironmentSettings(environmentId);  const [adding, setAdding] = useState(false);  const entries = Object.entries(sources);   return (    <>      <SettingsSection        {...searchableSetting("usage-providers")}        headerAction={          !readOnly ? (            <Button size="xs" variant="outline" onClick={() => setAdding(true)}>              <PlusIcon className="size-3" aria-hidden />              Add hub            </Button>          ) : null        }      >        {entries.length === 0 ? (          <SettingsRow title="No usage providers configured." />        ) : (          entries.map(([id, source]) => {            const label = source.label?.trim() || source.url;            return (              <SettingsRow                key={id}                title={label}                description={                  <span className="break-all">                    CLI Proxy{source.enabled ? "" : " · Disabled"}                    {label !== source.url ? ` · ${source.url}` : ""}                  </span>                }                control={                  !readOnly ? (                    <RemoveUsageProviderButton                      label={label}                      onConfirm={() => updateSettings({ usageLimitSources: { [id]: null } })}                    />                  ) : null                }              />            );          })        )}      </SettingsSection>      {adding && !readOnly ? (        <AddUsageLimitSourceDialog          open          onOpenChange={setAdding}          environmentId={environmentId}          environmentLabel={environmentLabel}        />      ) : null}    </>  );} /** Removing a hub deletes its stored management key, so it requires confirmation. */function RemoveUsageProviderButton({  label,  onConfirm,}: {  readonly label: string;  readonly onConfirm: () => void;}) {  const [open, setOpen] = useState(false);  return (    <>      <Button size="xs" variant="ghost" onClick={() => setOpen(true)}>        Remove      </Button>      <AlertDialog open={open} onOpenChange={setOpen}>        <AlertDialogPopup>          <AlertDialogHeader>            <AlertDialogTitle>Remove {label}?</AlertDialogTitle>            <AlertDialogDescription>              The hub's management key is deleted from this server. Its accounts leave the Limits              view; the hub itself is untouched. Add it again with the URL and key to bring them              back.            </AlertDialogDescription>          </AlertDialogHeader>          <AlertDialogFooter>            <AlertDialogClose render={<Button variant="outline" />}>Cancel</AlertDialogClose>            <Button              variant="destructive"              onClick={() => {                setOpen(false);                onConfirm();              }}            >              Remove hub            </Button>          </AlertDialogFooter>        </AlertDialogPopup>      </AlertDialog>    </>  );}