"use client"; import CopyToClipboard from "@app/components/CopyToClipboard"; import { SettingsSection, SettingsSectionBody, SettingsSectionDescription, SettingsSectionHeader, SettingsSectionTitle, SettingsSubsectionDescription, SettingsSubsectionHeader, SettingsSubsectionTitle } from "@app/components/Settings"; import { Button } from "@app/components/ui/button"; import { createApiClient, formatAxiosError } from "@app/lib/api"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { toast } from "@app/hooks/useToast"; import { launcherQueries } from "@app/lib/queries"; import type { GetMyVirtualApiKeyResponse, VirtualApiKeyWithResources } from "@server/routers/virtualApiKey/types"; import { formatVirtualApiKeyCredential, formatVirtualApiKeyPreview } from "@app/lib/virtualApiKeyFormat"; import { useQuery } from "@tanstack/react-query"; import type { AxiosResponse } from "axios"; import { Loader2 } from "lucide-react"; import { useTranslations } from "next-intl"; import { useState } from "react"; type LauncherInferenceApiKeysSectionProps = { orgId: string; resourceGuid: string; }; function useRevealSecret(orgId: string, virtualApiKeyId: string) { const t = useTranslations(); const api = createApiClient(useEnvContext()); const [credential, setCredential] = useState(null); const [loading, setLoading] = useState(false); const revealSecret = () => { if (credential || loading) { return; } setLoading(true); api.get>( `/org/${orgId}/my-virtual-api-keys/${virtualApiKeyId}` ) .then((res) => { const secret = res.data.data.virtualApiKey.secret; if (secret) { setCredential( formatVirtualApiKeyCredential(virtualApiKeyId, secret) ); } else { toast({ variant: "destructive", title: t("virtualApiKeysErrorFetchSecret"), description: t( "virtualApiKeysErrorFetchSecretDescription" ) }); } }) .catch((e) => { toast({ variant: "destructive", title: t("virtualApiKeysErrorFetchSecret"), description: formatAxiosError( e, t("virtualApiKeysErrorFetchSecretDescription") ) }); }) .finally(() => { setLoading(false); }); }; return { credential, loading, revealSecret }; } function PanelKeySecret({ orgId, virtualApiKeyId, lastChars }: { orgId: string; virtualApiKeyId: string; lastChars: string; }) { const t = useTranslations(); const preview = formatVirtualApiKeyPreview(virtualApiKeyId, lastChars); const { credential, loading, revealSecret } = useRevealSecret( orgId, virtualApiKeyId ); const displayValue = credential ?? preview; return (
{!credential ? ( ) : null}
); } function ManualKeyRow({ orgId, keyRow }: { orgId: string; keyRow: VirtualApiKeyWithResources; }) { const t = useTranslations(); return (

{keyRow.name || t("myVirtualApiKeysUnnamed")}

{keyRow.description ? (

{keyRow.description}

) : null}
); } export function LauncherInferenceApiKeysSection({ orgId, resourceGuid }: LauncherInferenceApiKeysSectionProps) { const t = useTranslations(); const { data, isPending, isError } = useQuery( launcherQueries.myVirtualApiKeys(orgId, resourceGuid) ); return ( {t("resourceLauncherApiKeys")} {t("resourceLauncherApiKeysDescription")} {isPending ? (
) : null} {isError ? (

{t("resourceLauncherApiKeysError")}

) : null} {!isPending && !isError && data ? (

{t("resourceLauncherApiKeysIdentity")}

{data.manualKeys.length > 0 ? (
{t("resourceLauncherApiKeysManual")} {t( "myVirtualApiKeysManualResourceDescription" )}
{data.manualKeys.map((keyRow) => ( ))}
) : null}
) : null}
); }