/* eslint-disable @typescript-eslint/no-explicit-any */ // SecretEditor — Secret 键值对表格可视化编辑器 (Base64 编码/解码, 从 ResourceVisualEditor.tsx 拆分) import { useState } from 'react'; import { Plus, Trash2, Loader2, Save } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Textarea } from '@/components/ui/textarea'; import i18n from '@/i18n'; export interface SecretEditorProps { manifest: any; onSave: (m: any) => void; saving: boolean; isCreate?: boolean; } export function SecretEditor({ manifest, onSave, saving, isCreate }: SecretEditorProps) { const rawData = manifest?.data || {}; const [resName, setResName] = useState(manifest?.metadata?.name || ''); const [expandAll, setExpandAll] = useState(false); // Decode base64 values for editing const [entries, setEntries] = useState<{ key: string; value: string; encoded: boolean }[]>( Object.entries(rawData).map(([key, value]) => { const v = String(value); try { // Try to decode — if it's valid base64 const decoded = atob(v); return { key, value: decoded, encoded: true }; } catch { return { key, value: v, encoded: false }; } }) ); const update = (i: number, field: 'key' | 'value', val: string) => { const next = [...entries]; next[i] = { ...next[i], [field]: val }; setEntries(next); }; const addRow = () => setEntries([...entries, { key: '', value: '', encoded: true }]); const removeRow = (i: number) => setEntries(entries.filter((_, idx) => idx !== i)); const handleSave = () => { const newData: Record = {}; entries.forEach(e => { if (e.key.trim()) { // Re-encode if originally base64 newData[e.key.trim()] = e.encoded ? btoa(e.value) : e.value; } }); onSave({ ...manifest, metadata: { ...manifest.metadata, name: resName.trim() }, data: newData }); }; return (
setResName(e.target.value)} readOnly={!isCreate} className="mt-1 font-mono text-xs bg-[var(--dg-bg-tertiary)]" />
{entries.map((entry, i) => (
update(i, 'key', e.target.value)} placeholder={i18n.t('k8s.rve.keyPlaceholder')} className="flex-1 font-mono text-xs h-8 bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]" />