import type * as React from 'react' import { type ActionItemSpec, ActionsContextMenu, ActionsMenu, type MenuKit, renderActionItem } from '@/components/ui/actions-menu' import { Button } from '@/components/ui/button' import { Codicon } from '@/components/ui/codicon' import { useI18n } from '@/i18n' import { triggerHaptic } from '@/lib/haptics' import { ExternalLink, Eye, EyeOff, KeyRound, Trash2 } from '@/lib/icons' import { cn } from '@/lib/utils' interface EnvVarActions { clearDisabled?: boolean docsUrl?: string | null isRevealed?: boolean isSet: boolean label: string onClear?: () => void onEdit: () => void /** Internal navigation to Settings → API Keys with this key highlighted. * Rendered only when provided AND the key is set (an unset key is managed * right here via Set). */ onManageKeys?: () => void onReveal?: () => void showReveal?: boolean } // The shared action rows, rendered identically by the kebab dropdown and the // row's right-click menu so the two never drift. function useEnvVarItems({ clearDisabled = false, docsUrl, isRevealed = false, isSet, onClear, onEdit, onManageKeys, onReveal, showReveal = true }: EnvVarActions) { const { t } = useI18n() const copy = t.settings.envActions const hasClear = isSet && onClear const hasReveal = isSet && showReveal && onReveal const hasManageKeys = isSet && onManageKeys const hasDocs = Boolean(docsUrl?.trim()) return (kit: MenuKit) => { const rows: ActionItemSpec[] = [] if (hasDocs) { rows.push({ iconNode: , key: 'docs', label: copy.docs, onSelect: event => { event.preventDefault() triggerHaptic('selection') window.open(docsUrl!, '_blank', 'noopener,noreferrer') } }) } if (hasReveal) { rows.push({ iconNode: isRevealed ? : , key: 'reveal', label: isRevealed ? copy.hideValue : copy.revealValue, onSelect: () => { triggerHaptic('selection') onReveal() } }) } rows.push({ icon: 'edit', key: 'edit', label: isSet ? copy.replace : copy.set, onSelect: () => { triggerHaptic('selection') onEdit() } }) if (hasManageKeys) { rows.push({ iconNode: , key: 'manage-keys', label: copy.manageInKeys, onSelect: () => { triggerHaptic('selection') onManageKeys() } }) } return ( <> {rows.map(row => renderActionItem(kit, row))} {hasClear && ( <> {renderActionItem(kit, { disabled: clearDisabled, iconNode: , key: 'clear', label: copy.clear, onSelect: () => { triggerHaptic('warning') onClear() }, variant: 'destructive' })} )} ) } } interface EnvVarActionsMenuProps extends EnvVarActions, Pick, 'align' | 'sideOffset'> { children: React.ReactNode } export function EnvVarActionsMenu({ align = 'end', children, sideOffset = 6, ...actions }: EnvVarActionsMenuProps) { const { t } = useI18n() const copy = t.settings.envActions const items = useEnvVarItems(actions) return ( {children} ) } interface EnvVarContextMenuProps extends EnvVarActions { children: React.ReactNode } /** Wrap an env-var row so right-clicking it opens the same menu as its kebab. */ export function EnvVarContextMenu({ children, ...actions }: EnvVarContextMenuProps) { const { t } = useI18n() const copy = t.settings.envActions const items = useEnvVarItems(actions) return ( {children} ) } export function EnvVarActionsTrigger({ className, ...props }: Omit, 'size' | 'variant'>) { const { t } = useI18n() const copy = t.settings.envActions return ( ) }