死键清理: 从 zh-CN.json 和 en-US.json 移除 866 个重构遗弃的 unreferenced
hash keys (filename.hash 格式)。这些键在组件迁移到语义化键后成为孤儿。
Live 键重命名 (21 个):
ui.datatable.s1a2b3c4d → selectedCount
ui.datatable.s2b3c4d5e → columns
ui.datatable.s3c4d5e6f → totalCount
aiops.predictive.s{1-3} → metricsTab/capacityTab/costTab
aiops.predictivecost.s{1-3} → aiFailed/overview/aiInsight
task.systemtaskspanel.s{1-3} → monitor/cleanup/finops
aiops.agentcli.s{1-3} → archLayer/archDesc/securityLayer
system.useldapmanageme.s{1-2} → ouExists/createOuFailed
common.requestts.sd3ab821c → common.request.tokenExpired
k8s.editAdvanced.s0c1fec65 → secondsPlaceholder
k8s.{kubectl,podExec}.sc8107726 → connectErrorAnsi
影响: zh/en 7597→6731 keys 对齐, 文件 328KB→276KB (-16%)
仍有 172 个 live hash keys 待后续重命名
tsc -b=0, npm build✓ (17.45s), ESLint=0/66/0, go build=0, 17/17 测试通过
62 lines
3.3 KiB
TypeScript
62 lines
3.3 KiB
TypeScript
// TolerationsCard.tsx — 容忍 (Tolerations) CRUD 卡片 (Q21 提取)
|
|
// 受控展示组件,接收 tolerations 数组 + 增删改回调。
|
|
import { Plus, Trash2 } from 'lucide-react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
|
import { Input } from '@/components/ui/input';
|
|
import i18n from '@/i18n';
|
|
import type { Toleration } from './types';
|
|
|
|
interface TolerationsCardProps {
|
|
tolerations: Toleration[];
|
|
onAdd: () => void;
|
|
onRemove: (index: number) => void;
|
|
onUpdate: (index: number, patch: Partial<Toleration>) => void;
|
|
}
|
|
|
|
export function TolerationsCard({ tolerations, onAdd, onRemove, onUpdate }: TolerationsCardProps) {
|
|
return (
|
|
<Card className="dg-card">
|
|
<CardHeader className="pb-3">
|
|
<div className="flex items-center justify-between">
|
|
<CardTitle className="text-sm text-[var(--dg-text-primary)]"> {i18n.t('kubernetes.deploymentedita.s13a8310b')} </CardTitle>
|
|
<Button size="sm" variant="outline" className="h-7 border-[var(--dg-border)] text-[var(--dg-text-secondary)] text-xs"
|
|
onClick={onAdd}>
|
|
<Plus className="h-3 w-3 mr-1" />添加
|
|
</Button>
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent className="pt-0 space-y-2">
|
|
{tolerations.length === 0 && <p className="text-xs dg-text-muted"> {i18n.t('kubernetes.deploymentedita.s8bc06bde')} </p>}
|
|
{tolerations.map((t, i) => (
|
|
<div key={i} className="grid grid-cols-[1fr_80px_1fr_100px_80px_auto] gap-2 items-center">
|
|
<Input value={t.key} placeholder="key" onChange={e => onUpdate(i, { key: e.target.value })}
|
|
className="h-7 dg-input text-xs font-mono" />
|
|
<select value={t.operator} onChange={e => onUpdate(i, { operator: e.target.value })}
|
|
className="h-7 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded text-xs text-[var(--dg-text-secondary)] px-1">
|
|
<option value="Equal">Equal</option>
|
|
<option value="Exists">Exists</option>
|
|
</select>
|
|
<Input value={t.value} placeholder="value" disabled={t.operator === 'Exists'}
|
|
onChange={e => onUpdate(i, { value: e.target.value })}
|
|
className="h-7 dg-input text-xs font-mono" />
|
|
<select value={t.effect} onChange={e => onUpdate(i, { effect: e.target.value })}
|
|
className="h-7 bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded text-xs text-[var(--dg-text-secondary)] px-1">
|
|
<option value=""> {i18n.t('kubernetes.deploymentedita.s2a6eb2dd')} </option>
|
|
<option value="NoSchedule">NoSchedule</option>
|
|
<option value="PreferNoSchedule">PreferNoSchedule</option>
|
|
<option value="NoExecute">NoExecute</option>
|
|
</select>
|
|
<Input value={t.tolerationSeconds} placeholder={i18n.t('k8s.editAdvanced.seconds')} disabled={t.effect !== 'NoExecute'}
|
|
onChange={e => onUpdate(i, { tolerationSeconds: e.target.value })}
|
|
className="h-7 dg-input text-xs font-mono" />
|
|
<Button variant="ghost" size="icon" className="h-7 w-7 dg-text-red" onClick={() => onRemove(i)}>
|
|
<Trash2 className="h-3 w-3" />
|
|
</Button>
|
|
</div>
|
|
))}
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|