Files
NetMesh/components/keychain/GenerateStandardPanel.tsx
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

140 lines
5.6 KiB
TypeScript

/**
* Generate Key Panel - Standard SSH Key generation form
*/
import { Eye, EyeOff } from 'lucide-react';
import React from 'react';
import { useI18n } from '../../application/i18n/I18nProvider';
import { cn } from '../../lib/utils';
import { KeyType, SSHKey } from '../../types';
import { Button } from '../ui/button';
import { Input } from '../ui/input';
import { Label } from '../ui/label';
interface GenerateStandardPanelProps {
draftKey: Partial<SSHKey>;
setDraftKey: (key: Partial<SSHKey>) => void;
showPassphrase: boolean;
setShowPassphrase: (show: boolean) => void;
isGenerating: boolean;
onGenerate: () => void;
}
export const GenerateStandardPanel: React.FC<GenerateStandardPanelProps> = ({
draftKey,
setDraftKey,
showPassphrase,
setShowPassphrase,
isGenerating,
onGenerate,
}) => {
const { t } = useI18n();
return (
<>
<div className="space-y-2">
<Label>{t('keychain.field.label')}</Label>
<Input
value={draftKey.label || ''}
onChange={e => setDraftKey({ ...draftKey, label: e.target.value })}
placeholder={t('keychain.generate.labelPlaceholder')}
/>
</div>
<div className="space-y-2">
<Label>{t('keychain.generate.keyType')}</Label>
<div className="flex gap-2">
{(['ED25519', 'ECDSA', 'RSA'] as KeyType[]).map((t) => (
<Button
key={t}
variant={draftKey.type === t ? 'secondary' : 'ghost'}
className={cn(
"flex-1 h-10",
draftKey.type === t && "bg-primary/15 text-primary"
)}
onClick={() => {
// Set default keySize based on type
const defaultSize = t === 'ED25519' ? undefined : (t === 'RSA' ? 4096 : 256);
setDraftKey({ ...draftKey, type: t, keySize: defaultSize });
}}
>
{t}
</Button>
))}
</div>
</div>
{/* Key Size selector - only for RSA and ECDSA */}
{(draftKey.type === 'RSA' || draftKey.type === 'ECDSA') && (
<div className="space-y-2">
<Label>{t('keychain.generate.keySize')}</Label>
<div className="flex gap-2">
{(draftKey.type === 'RSA'
? [4096, 2048, 1024]
: [256, 384, 521]
).map((size) => (
<Button
key={size}
variant={draftKey.keySize === size ? 'secondary' : 'ghost'}
className={cn(
"flex-1 h-10",
draftKey.keySize === size && "bg-primary/15 text-primary"
)}
onClick={() => setDraftKey({ ...draftKey, keySize: size })}
>
{draftKey.type === 'RSA' ? `${size} bits` : `P-${size}`}
</Button>
))}
</div>
</div>
)}
<div className="space-y-2">
<Label>{t('terminal.auth.passphrase')}</Label>
<div className="relative">
<Input
type={showPassphrase ? 'text' : 'password'}
value={draftKey.passphrase || ''}
onChange={e => setDraftKey({ ...draftKey, passphrase: e.target.value })}
placeholder={t('keychain.generate.passphrasePlaceholder')}
className="pr-10"
/>
<Button
type="button"
variant="ghost"
size="icon"
className="absolute right-1 top-1/2 -translate-y-1/2 h-8 w-8"
onClick={() => setShowPassphrase(!showPassphrase)}
>
{showPassphrase ? <EyeOff size={14} /> : <Eye size={14} />}
</Button>
</div>
</div>
<div className="flex items-center gap-2">
<input
type="checkbox"
id="savePassphrase"
checked={draftKey.savePassphrase || false}
onChange={e => setDraftKey({ ...draftKey, savePassphrase: e.target.checked })}
className="h-4 w-4 rounded border-border"
/>
<Label htmlFor="savePassphrase" className="text-sm font-normal cursor-pointer">
{t('keychain.generate.savePassphrase')}
</Label>
</div>
<Button
className="w-full h-11"
onClick={onGenerate}
disabled={isGenerating || !draftKey.label?.trim()}
>
{isGenerating ? (
<div className="h-4 w-4 border-2 border-primary-foreground/30 border-t-primary-foreground rounded-full animate-spin" />
) : (
t('keychain.generate.generateSave')
)}
</Button>
</>
);
};