/** * Identity Panel - Create/Edit identity */ import { Eye,EyeOff,Key,Plus,Shield,User,X } from 'lucide-react'; import React,{ useMemo,useState } from 'react'; import { useI18n } from '../../application/i18n/I18nProvider'; import { Identity,SSHKey } from '../../types'; import { Button } from '../ui/button'; import { Combobox } from '../ui/combobox'; import { Input } from '../ui/input'; import { Label } from '../ui/label'; import { Popover,PopoverContent,PopoverTrigger } from '../ui/popover'; import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip'; interface IdentityPanelProps { draftIdentity: Partial; setDraftIdentity: (identity: Partial) => void; keys: SSHKey[]; showPassphrase: boolean; setShowPassphrase: (show: boolean) => void; isNew: boolean; onSave: () => void; } export const IdentityPanel: React.FC = ({ draftIdentity, setDraftIdentity, keys, showPassphrase, setShowPassphrase, isNew, onSave, }) => { const { t } = useI18n(); type CredentialType = 'key' | 'certificate' | null; const [credentialPopoverOpen, setCredentialPopoverOpen] = useState(false); const [selectedCredentialType, setSelectedCredentialType] = useState(null); const selectedKey = useMemo(() => { if (!draftIdentity.keyId) return undefined; return keys.find(k => k.id === draftIdentity.keyId); }, [draftIdentity.keyId, keys]); const keysByCategory = useMemo(() => { return { key: keys.filter(k => k.category === 'key' && !k.certificate), certificate: keys.filter(k => k.category === 'certificate' || !!k.certificate), }; }, [keys]); const clearSelectedKey = () => { setDraftIdentity({ ...draftIdentity, keyId: undefined, authMethod: 'password', }); setSelectedCredentialType(null); setCredentialPopoverOpen(false); }; const setSelectedKeyId = (keyId: string, kind: Exclude) => { setDraftIdentity({ ...draftIdentity, keyId: keyId || undefined, authMethod: kind === 'certificate' ? 'certificate' : 'key', }); setSelectedCredentialType(null); setCredentialPopoverOpen(false); }; return ( <>
setDraftIdentity({ ...draftIdentity, label: e.target.value })} placeholder={t('keychain.field.label')} className="flex-1" />
setDraftIdentity({ ...draftIdentity, username: e.target.value })} placeholder={t('terminal.auth.username')} className="pl-9" />
setDraftIdentity({ ...draftIdentity, password: e.target.value })} placeholder={t('terminal.auth.password.placeholder')} className="pr-10" />
{/* Selected credential display */} {draftIdentity.keyId && (
{draftIdentity.authMethod === 'certificate' ? ( ) : ( )} {selectedKey?.label || t('hostDetails.credential.missing')} {t('common.clear')}
)} {/* Credential type selection with inline popover */} {!draftIdentity.keyId && !selectedCredentialType && (
)} {/* Key selection combobox - appears after selecting "Key" type */} {selectedCredentialType === 'key' && !draftIdentity.keyId && (
({ value: k.id, label: k.label, sublabel: `${k.type}${k.keySize ? ` ${k.keySize}` : ''}`, icon: , }))} value={draftIdentity.keyId} onValueChange={(val) => setSelectedKeyId(val, 'key')} placeholder={t('hostDetails.keys.search')} emptyText={t('hostDetails.keys.empty')} icon={} className="flex-1" /> {t('common.cancel')}
)} {/* Certificate selection combobox */} {selectedCredentialType === 'certificate' && !draftIdentity.keyId && (
({ value: k.id, label: k.label, icon: , }))} value={draftIdentity.keyId} onValueChange={(val) => setSelectedKeyId(val, 'certificate')} placeholder={t('hostDetails.certs.search')} emptyText={t('hostDetails.certs.empty')} icon={} className="flex-1" /> {t('common.cancel')}
)} ); };