/* Copyright 2026 Marimo. All rights reserved. */ import { CheckIcon, CopyIcon, KeyIcon, PlusIcon } from "lucide-react"; import React from "react"; import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels"; import { Spinner } from "@/components/icons/spinner"; import { useImperativeModal } from "@/components/modal/ImperativeModal"; import { Badge } from "@/components/ui/badge"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { toast } from "@/components/ui/use-toast"; import { SECRETS_REGISTRY } from "@/core/secrets/request-registry"; import { useAsyncData } from "@/hooks/useAsyncData"; import { ErrorBanner } from "@/plugins/impl/common/error-banner"; import { cn } from "@/utils/cn"; import { copyToClipboard } from "@/utils/copy"; import { PanelEmptyState } from "./empty-state"; import { sortProviders, WriteSecretModal } from "./write-secret-modal"; const SecretsPanel: React.FC = () => { const { openModal, closeModal } = useImperativeModal(); const { data: secretKeyProviders, isPending, error, refetch, } = useAsyncData(async () => { const result = await SECRETS_REGISTRY.request({}); return sortProviders(result.secrets); }, []); // Only show on the first load if (isPending) { return ; } if (error) { return ; } // Provider names without 'env' provider const providerNames = secretKeyProviders .filter((provider) => provider.provider !== "env") .map((provider) => provider.name); if (secretKeyProviders.length === 0) { return ( } /> ); } return (
Environment Variable Source {secretKeyProviders.map((provider) => { return provider.keys.map((key) => ( {key} {provider.provider !== "env" && ( {provider.name} )} { await copyToClipboard(`os.environ["${key}"]`); toast({ title: "Copied to clipboard", description: `os.environ["${key}"] has been copied to your clipboard.`, }); }} className={cn( "float-right px-2 h-full text-xs text-muted-foreground hover:text-foreground", "invisible group-hover:visible", )} /> )); })}
); }; export default SecretsPanel; const CopyButton: React.FC<{ className?: string; ariaLabel: string; onCopy: () => void; }> = ({ className, ariaLabel, onCopy }) => { const [copied, setCopied] = React.useState(false); const handleCopy = () => { onCopy(); setCopied(true); setTimeout(() => setCopied(false), 1000); }; return ( ); };