import { Button } from "@/src/components/ui/button"; import { api } from "@/src/utils/api"; import { useState } from "react"; import { PlusIcon } from "lucide-react"; import { Dialog, DialogBody, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/src/components/ui/dialog"; import { CodeView } from "@/src/components/ui/CodeJsonViewer"; import { useHasProjectAccess } from "@/src/features/rbac/utils/checkProjectAccess"; import { useHasOrganizationAccess } from "@/src/features/rbac/utils/checkOrganizationAccess"; import { usePostHogClientCapture } from "@/src/features/posthog-analytics/usePostHogClientCapture"; import { Input } from "@/src/components/ui/input"; import { useLangfuseEnvCode } from "@/src/features/public-api/hooks/useLangfuseEnvCode"; import { Label } from "@/src/components/ui/label"; import { cn } from "@/src/utils/tailwind"; import { SubHeader } from "@/src/components/layouts/header"; type ApiKeyScope = "project" | "organization"; export function CreateApiKeyButton(props: { entityId: string; scope: ApiKeyScope; }) { const utils = api.useUtils(); const capture = usePostHogClientCapture(); const hasProjectAccess = useHasProjectAccess({ projectId: props.entityId, scope: "apiKeys:CUD", }); const hasOrganizationAccess = useHasOrganizationAccess({ organizationId: props.entityId, scope: "organization:CRUD_apiKeys", }); const hasAccess = props.scope === "project" ? hasProjectAccess : hasOrganizationAccess; const mutCreateProjectApiKey = api.projectApiKeys.create.useMutation({ onSuccess: () => utils.projectApiKeys.invalidate(), }); const mutCreateOrgApiKey = api.organizationApiKeys.create.useMutation({ onSuccess: () => utils.organizationApiKeys.invalidate(), }); const [open, setOpen] = useState(false); const [note, setNote] = useState(""); const [generatedKeys, setGeneratedKeys] = useState<{ secretKey: string; publicKey: string; } | null>(null); const handleOpenChange = (newOpen: boolean) => { setOpen(newOpen); if (!newOpen) { // Reset state when closing setGeneratedKeys(null); setNote(""); } }; const createApiKey = () => { if (props.scope === "project") { mutCreateProjectApiKey .mutateAsync({ projectId: props.entityId, note: note || undefined, }) .then(({ secretKey, publicKey }) => { setGeneratedKeys({ secretKey, publicKey, }); capture(`${props.scope}_settings:api_key_create`); }) .catch((error) => { console.error(error); }); } else { mutCreateOrgApiKey .mutateAsync({ orgId: props.entityId, note: note || undefined, }) .then(({ secretKey, publicKey }) => { setGeneratedKeys({ secretKey, publicKey, }); capture(`${props.scope}_settings:api_key_create`); }) .catch((error) => { console.error(error); }); } }; if (!hasAccess) return null; return ( ); } export const ApiKeyRender = ({ scope, generatedKeys, className, }: { scope: ApiKeyScope; generatedKeys?: { secretKey: string; publicKey: string }; className?: string; }) => { const envCode = useLangfuseEnvCode(generatedKeys); return (