import { useState } from 'react' import { IconLoader2, IconPlus, IconTrash } from '@tabler/icons-react' import { Button } from '@/client/components/ui/button' import { Input } from '@/client/components/ui/input' import { Switch } from '@/client/components/ui/switch' import { useWorkspaceLayoutCtx } from '@/client/features/workspace/WorkspaceLayoutContext' import { cn } from '@/client/lib/cn' import type { WorkspaceEnvVar } from '@/lib/types' import { SettingsPage, SettingsRow, SettingsSection } from './SettingsLayout' import { useEnvVars } from './useEnvVars' const SOURCE_LABEL: Record = { dotenv: '.env', custom: 'secret', both: 'override' } const ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/ export function EnvironmentSettings() { const { workspaceId } = useWorkspaceLayoutCtx() const { env, update } = useEnvVars(workspaceId) const [draftKey, setDraftKey] = useState('') const [draftValue, setDraftValue] = useState('') const keyValid = ENV_KEY_RE.test(draftKey) const canAdd = keyValid && draftValue.length > 0 && !update.isPending const addVariable = () => { if (!canAdd) return update.mutate( { set: { [draftKey]: draftValue } }, { onSuccess: () => { setDraftKey('') setDraftValue('') } } ) } const variables = env.data?.vars ?? [] const fileCount = env.data?.files.reduce((count, file) => count + file.count, 0) ?? 0 const dotenvFiles = env.data?.files.length ?? 0 return ( {env.isLoading ? (
) : variables.length === 0 ? (

No variables yet.

) : ( variables.map(variable => { const editable = variable.source !== 'dotenv' return (
{variable.key} •••••• {SOURCE_LABEL[variable.source]} {!editable && ( from file )}
) }) )}
setDraftKey(event.target.value)} placeholder="NEW_KEY" aria-invalid={draftKey.length > 0 && !keyValid} className="h-7 w-40 font-mono text-xs" /> setDraftValue(event.target.value)} onKeyDown={event => { if (event.key === 'Enter') addVariable() }} type="password" placeholder="value" className="h-7 flex-1 text-xs" />
0 ? `Discovered ${fileCount} ${fileCount === 1 ? 'key' : 'keys'} across ${dotenvFiles} ${dotenvFiles === 1 ? 'file' : 'files'} in this space.` : 'No .env files found in this space.' } control={ update.mutate({ inheritDotenv: checked })} /> } />
) }