refactor(i18n): U38 phantom CTK 清理 — 13 文件 16 处模板字面量/JSX 属性残余中文→i18n.t() 调用

13 文件 16 处 UI-facing phantom CTK (i18n.t() 模板字面量中的中文片段) 全部替换为语义化 i18n.t() 调用:
- LogsHeader: '行'suffix→common.lineSuffix
- analyzerHelpers: '当前值'→common.currentValue
- DeploymentEditStorage: 2 toast description→k8s.editStorage.*Desc (插值)
- WorkloadViewPage: 2 toast description→k8s.workloadView.restartSentDesc + k8s.workloads.scaleSuccessDesc (插值)
- ServerFileBrowser: confirm→common.confirmDeleteType (插值)
- LogDatasourcePage: toast '可达'→aiops.reachable
- LogAlertsPanel: confirm→monitor.deleteRuleConfirmDesc (插值)
- DeployTargetFields: JSX '(多容器时填写)'→common.fillIfMultiContainer
- UserGroupsManager: 3 处 confirm/desc→deploy.rbac.deleteGroupDesc + pipeline.removeMemberDesc + common.memberCount (插值)
- BuildNodesManager: JSX '(可选)'→common.optional (已有键复用)
- useLdapManagement: confirm→system.ldapMgmt.deleteEntryDesc (插值)

新增 14 语义化翻译键 (5 common + 2 k8s.editStorage + 1 k8s.workloadView + 1 k8s.workloads + 1 aiops + 1 monitor + 1 deploy.rbac + 1 pipeline + 1 system.ldapMgmt), zh/en 7737→7751 +14 对齐
tsc -b=0, npm build✓ (16.86s), ESLint=0/43/any=0, go build=0, 17/17 测试通过
This commit is contained in:
attacker committed 2026-07-13 08:55:28 +08:00
1 parent 7c80e35411
commit a1d82574a7
14 files changed
+64 -35

No files matched your search

@@ -184,7 +184,7 @@ export function mapAlertEvent(event: JsonData): AlertItem {
startedAt,
description: event.message && event.message !== `告警事件 ${event.id}`
? event.message
: event.rule?.description || `${event.rule_name || i18n.t('monitor.hostDashboard.alert')}: ${event.target} 当前值 ${currentValue}`,
: event.rule?.description || `${event.rule_name || i18n.t('monitor.hostDashboard.alert')}: ${event.target} ${i18n.t('common.currentValue')} ${currentValue}`,
};
}
@@ -317,7 +317,7 @@ export default function BuildNodesManager({ embedded = false }: { embedded?: boo
</div>
</div>
<div className="space-y-1">
<Label className="text-xs"> {i18n.t('kubernetes.namespace.labels')} <span className="text-[var(--dg-text-muted)]">(可选)</span></Label>
<Label className="text-xs"> {i18n.t('kubernetes.namespace.labels')} <span className="text-[var(--dg-text-muted)]">{i18n.t('common.optional')}</span></Label>
<Input value={labels} onChange={(e) => setLabels(e.target.value)} className="h-8 text-xs dg-input" placeholder="linux,docker,high-mem" />
</div>
<div className="space-y-1">
@@ -61,7 +61,7 @@ export default function UserGroupsManager({ embedded = false }: { embedded?: boo
};
const handleDelete = async (g: Group) => {
const ok = await _confirm({ title: i18n.t('deploy.rbac.deleteGroup'), description: `确定删除「${g.name}」?所有成员和流水线授权将同时移除。`, variant: 'destructive' });
const ok = await _confirm({ title: i18n.t('deploy.rbac.deleteGroup'), description: i18n.t('deploy.rbac.deleteGroupDesc', { name: g.name }), variant: 'destructive' });
if (!ok) return;
try { await deployApi.deleteGroup(g.id); toast.success(i18n.t('monitor.silenceRules.deleted')); loadGroups(); }
catch { toast.error(i18n.t('kubernetes.msg.deleteFailed2')); }
@@ -75,7 +75,7 @@ export default function UserGroupsManager({ embedded = false }: { embedded?: boo
};
const handleRemoveMember = async (groupId: number, memberId: number, username: string) => {
const ok = await _confirm({ title: i18n.t('pipeline.removeMember'), description: `确定从组中移除「${username}」?` });
const ok = await _confirm({ title: i18n.t('pipeline.removeMember'), description: i18n.t('pipeline.removeMemberDesc', { username }) });
if (!ok) return;
try { await deployApi.removeGroupMember(groupId, memberId); toast.success(i18n.t('deploy.toast.removed')); loadGroups(); }
catch { toast.error(i18n.t('deploy.toast.removeFailed')); }
@@ -116,7 +116,7 @@ export default function UserGroupsManager({ embedded = false }: { embedded?: boo
<Shield className="w-5 h-5 dg-text-blue" />
<div>
<div className="font-medium text-[var(--dg-text-primary)]">{g.name}</div>
<div className="text-xs text-[var(--dg-text-secondary)]">{g.description || i18n.t('system.roleDescFallback')} · {(g.members || []).length} 位成员</div>
<div className="text-xs text-[var(--dg-text-secondary)]">{g.description || i18n.t('system.roleDescFallback')} · {i18n.t('common.memberCount', { count: (g.members || []).length })}</div>
</div>
</div>
<div className="flex items-center gap-2">
@@ -349,7 +349,7 @@ export function DeployTargetFields({ value, onChange, requireTarget = true }: De
)}
</ScrollArea>
<div className="space-y-1">
<Label className="text-xs"> {i18n.t('kubernetes.container.containerName')} <span className="text-[var(--dg-text-muted)]">(多容器时填写)</span></Label>
<Label className="text-xs"> {i18n.t('kubernetes.container.containerName')} <span className="text-[var(--dg-text-muted)]">{i18n.t('common.fillIfMultiContainer')}</span></Label>
<Input
value={value.k8sContainerName}
onChange={(e) => onChange({ k8sContainerName: e.target.value })}
@@ -137,12 +137,12 @@ export function DeploymentEditStorage({ clusterCode, namespace, deploymentName,
: entry.volume.type === 'secret' ? i18n.t('k8s.editStorage.selectSecret')
: entry.volume.type === 'persistentVolumeClaim' ? i18n.t('k8s.editStorage.selectPVC')
: i18n.t('k8s.editStorage.typeRequiredHint');
toast({ title: i18n.t('k8s.editStorage.incompleteConfig'), description: `请为「${entry.volume.name}」${hint}`, variant: 'destructive' });
toast({ title: i18n.t('k8s.editStorage.incompleteConfig'), description: i18n.t('k8s.editStorage.incompleteConfigDesc', { name: entry.volume.name, hint }), variant: 'destructive' });
return;
}
const validMounts = entry.mounts.filter((m) => m.mountPath.trim());
if (validMounts.length === 0) {
toast({ title: i18n.t('k8s.editStorage.mountPathRequired'), description: `数据卷「${entry.volume.name}」需至少挂载到一个容器`, variant: 'destructive' });
toast({ title: i18n.t('k8s.editStorage.mountPathRequired'), description: i18n.t('k8s.editStorage.mountPathRequiredDesc', { name: entry.volume.name }), variant: 'destructive' });
return;
}
}
@@ -107,7 +107,7 @@ export default function WorkloadViewPage() {
} else {
await kubernetesApi.restartDaemonSet(clusterCode, namespace, name);
}
toast({ title: i18n.t('k8s.workloadView.restartSent'), description: `${kind} 滚动重启已触发` });
toast({ title: i18n.t('k8s.workloadView.restartSent'), description: i18n.t('k8s.workloadView.restartSentDesc', { kind }) });
setTimeout(loadData, 1000);
} catch (e) {
toast({ title: i18n.t('kubernetes.deployment.restartFailed'), description: e instanceof Error ? e.message : String(e), variant: 'destructive' });
@@ -118,7 +118,7 @@ export default function WorkloadViewPage() {
setActionLoading(true);
try {
await kubernetesApi.scaleStatefulSet(clusterCode, namespace, name, scaleValue);
toast({ title: i18n.t('k8s.workloads.scaleSuccess'), description: `StatefulSet 副本数已更新为 ${scaleValue}` });
toast({ title: i18n.t('k8s.workloads.scaleSuccess'), description: i18n.t('k8s.workloads.scaleSuccessDesc', { count: scaleValue }) });
setScaleModal(false);
setTimeout(loadData, 1000);
} catch (e) {
@@ -40,7 +40,7 @@ export function LogsHeader({
<span className="text-[var(--dg-text-primary)] font-medium truncate">{i18n.t('k8s.podLogs.logTitle', { name: podName })}</span>
{loading && <Loader2 className="h-3 w-3 animate-spin text-[var(--dg-text-muted)]" />}
<span className="text-xs text-[var(--dg-text-muted)]">
{streaming ? (paused ? i18n.t('kubernetes.deployment.paused') : i18n.t('kubernetes.podLogsViewer.liveTail')) : i18n.t('agent.agentServiceStopped')} · {matchedCount}{keyword ? `/${lineCount}` : ''} 行
{streaming ? (paused ? i18n.t('kubernetes.deployment.paused') : i18n.t('kubernetes.podLogsViewer.liveTail')) : i18n.t('agent.agentServiceStopped')} · {matchedCount}{keyword ? `/${lineCount}` : ''} {i18n.t('common.lineSuffix')}
{lineCount >= RING_BUFFER_MAX && i18n.t('kubernetes.podLogsViewer.bufferFull')}
</span>
</div>
@@ -38,7 +38,7 @@ export function LogAlertsPanel() {
useEffect(() => { load(); }, [load]);
const handleDelete = async (rule: any) => {
const ok = await confirm({ title: i18n.t('monitor.deleteRule'), description: `删除「${rule.name}」?`, variant: 'destructive', confirmText: i18n.t('kubernetes.storage.delete2') });
const ok = await confirm({ title: i18n.t('monitor.deleteRule'), description: i18n.t('monitor.deleteRuleConfirmDesc', { name: rule.name }), variant: 'destructive', confirmText: i18n.t('kubernetes.storage.delete2') });
if (!ok) return;
try {
await alertApi.deleteRule(rule.id);
@@ -67,7 +67,7 @@ export function LogDatasourcePage() {
// 已保存数据源通过 datasource_id 测试,避免密码丢失或前端暴露密码。// Logan.Li
const result: TestConnectionResult = await logCenterApi.testDatasource({ datasource_id: ds.id });
if (result.status === 'ok') {
toast({ title: i18n.t('aiops.llmTestSuccess'), description: `${ds.name} 可达` });
toast({ title: i18n.t('aiops.llmTestSuccess'), description: `${ds.name} ${i18n.t('aiops.reachable')}` });
} else {
toast({ title: i18n.t('aiops.llmTestFailed'), description: result.error || i18n.t('monitor.dashboard.agent.toast.unknownError'), variant: 'destructive' });
}
@@ -117,7 +117,7 @@ export function ServerFileBrowser({ open, onOpenChange, serverId, serverName }:
};
const handleDelete = async (filePath: string, isDir: boolean) => {
if (!serverId || !confirm(`确认删除 ${isDir ? i18n.t('server.fileBrowser2.directory') : i18n.t('k8s.pods.action.file')} "${filePath}"?`)) return;
if (!serverId || !confirm(i18n.t('common.confirmDeleteType', { type: isDir ? i18n.t('server.fileBrowser2.directory') : i18n.t('k8s.pods.action.file'), name: filePath }))) return;
try {
await serverApi.deleteFile(serverId, filePath);
await fetchDir(currentPath);
@@ -168,7 +168,7 @@ export function useLdapManagement(onUsersChanged: () => Promise<void> | void) {
/** 删除 LDAP 条目 // Logan.Li */
const handleDeleteLDAPEntry = async (dn: string, silent = false) => {
if (!silent) {
const ok = await confirm({ title: i18n.t('system.ldapMgmt.deleteEntry'), description: `确定删除 ${dn}?`, confirmText: i18n.t('kubernetes.storage.delete2'), variant: 'destructive' });
const ok = await confirm({ title: i18n.t('system.ldapMgmt.deleteEntry'), description: i18n.t('system.ldapMgmt.deleteEntryDesc', { dn }), confirmText: i18n.t('kubernetes.storage.delete2'), variant: 'destructive' });
if (!ok) return;
}
try {