refactor(i18n): U39 残余 JSX 属性/模板字面量中文清零 — 14 处→0

10 文件修复:
- DualLineChart: subtitle 接收/发送→i18n.t(monitor.lbl.receiveSend)
- NetworkTab: 5处 unit="个"→t(common.unitCount)
- FDUsageCard: subtitle 当前→t(monitor.lbl.currentFDUsage)
- NamespaceOverviewPage: subtitle 命名空间概览→i18n.t(k8s.nsOverview.subtitle)
- NamespaceManagementPage: subtitle 资源配额→i18n.t(k8s.nsMgmt.quotaSubtitle)
- CreateHPADialog: title+text 命名空间→i18n.t(k8s.hpa.targetInfo)
- LogFieldSidebar: title 个值→i18n.t(common.fieldValues)
- LiveMonitorDialog: title 全屏/退出全屏→t(common.fullscreen/exitFullscreen)
- ExecutionHistoryDialog: title 成功/失败→t(task.execHistory.successFail)
- LdapSettingsTab: className 成功检查→ldapTestSuccess boolean 状态

新增 11 翻译键 (common.unitCount/fieldValues/exitFullscreen/fullscreen +
monitor.lbl.receiveSend/currentFDUsage + k8s.nsOverview.subtitle/nsMgmt.quotaSubtitle/hpa.targetInfo +
task.execHistory.successFail), zh/en 7751→7762 对齐

tsc -b=0, npm build✓ (16.94s), ESLint=0/0/any=0, go build=0, 17/17 测试通过
This commit is contained in:
attacker committed 2026-07-13 13:12:54 +08:00
1 parent a1d82574a7
commit 5205def47f
14 files changed
+67 -29

No files matched your search

@@ -121,7 +121,7 @@ export default function NamespaceManagementPage() {
<PageShell
variant="list"
title={i18n.t('k8s.nsMgmt.title')}
subtitle={`${clusterCode} · 资源配额与生命周期管理`}
subtitle={i18n.t('k8s.nsMgmt.quotaSubtitle', { code: clusterCode })}
icon={<Boxes className="h-5 w-5" />}
metrics={!loading ? (
<StatStrip
@@ -68,7 +68,7 @@ export default function NamespaceOverviewPage() {
<PageShell
variant="default"
title={namespace || i18n.t('kubernetes.namespace.title')}
subtitle={`${clusterCode} · 命名空间概览`}
subtitle={i18n.t('k8s.nsOverview.subtitle', { code: clusterCode })}
icon={<Cloud className="h-5 w-5" />}
loading={loading}
loadingLabel={i18n.t('k8s.nsOverview.loadingStats')}
@@ -72,8 +72,8 @@ export function CreateHPADialog({ clusterCode, namespace, deploymentName, onCrea
</div>
<div>
<Label className="dg-text-secondary text-sm">{i18n.t("common.target")}</Label>
<p className="text-[var(--dg-text-secondary)] text-sm mt-1 bg-[var(--dg-bg-tertiary)] rounded px-3 py-2 truncate" title={`Deployment: ${deploymentName} · 命名空间: ${namespace}`}>
Deployment: {deploymentName} · 命名空间: {namespace}
<p className="text-[var(--dg-text-secondary)] text-sm mt-1 bg-[var(--dg-bg-tertiary)] rounded px-3 py-2 truncate" title={i18n.t('k8s.hpa.targetInfo', { deploy: deploymentName, ns: namespace })}>
{i18n.t('k8s.hpa.targetInfo', { deploy: deploymentName, ns: namespace })}
</p>
</div>
<div className="grid grid-cols-2 gap-3">
@@ -92,7 +92,7 @@ export function LogFieldSidebar({
className="flex items-center gap-1.5 py-1 px-1.5 rounded cursor-pointer hover:opacity-80 transition-colors"
style={{ background: selectedFields.includes(f.name) ? 'var(--dg-bg-tertiary)' : 'transparent' }}
onClick={() => onFieldClick?.(f.name)}
title={`${f.name} (${f.type || 'text'})${f.count ? ` · ${f.count} 个值` : ''}`}
title={`${f.name} (${f.type || 'text'})${f.count ? ` · ${i18n.t('common.fieldValues', { count: f.count })}` : ''}`}
>
<input
type="checkbox"
@@ -232,7 +232,7 @@ export function LiveMonitorDialog({ open, onOpenChange, sessionId, sessionInfo }
type="button"
onClick={() => setFullscreen(!fullscreen)}
className="p-1.5 rounded hover:bg-[var(--dg-bg-hover)] text-[var(--dg-text-secondary)]"
title={fullscreen ? '退出全屏' : '全屏'}
title={fullscreen ? t('common.exitFullscreen') : t('common.fullscreen')}
>
{fullscreen ? <Minimize2 className="h-4 w-4" /> : <Maximize2 className="h-4 w-4" />}
</button>
@@ -57,6 +57,7 @@ export interface SystemSettingsTabProps {
ldapSaving: boolean;
ldapTesting: boolean;
ldapTestResult: string | null;
ldapTestSuccess: boolean;
handleLdapSave: () => void;
handleLdapTest: () => void;
// LDAP management - pass-through to LdapManagementSection
@@ -17,6 +17,7 @@ type LdapSettingsTabProps = Pick<
| "ldapSaving"
| "ldapTesting"
| "ldapTestResult"
| "ldapTestSuccess"
| "handleLdapSave"
| "handleLdapTest"
> &
@@ -75,6 +76,7 @@ export function LdapSettingsTab(props: LdapSettingsTabProps) {
ldapSaving,
ldapTesting,
ldapTestResult,
ldapTestSuccess,
handleLdapSave,
handleLdapTest,
} = props;
@@ -204,7 +206,7 @@ export function LdapSettingsTab(props: LdapSettingsTabProps) {
<div className="flex items-center gap-3 mt-4 pt-4 border-t border-[var(--dg-border)]">
{ldapTestResult && (
<span
className={`text-xs ${ldapTestResult.includes("成功") ? "dg-text-green" : "dg-text-red"}`}
className={`text-xs ${ldapTestSuccess ? "dg-text-green" : "dg-text-red"}`}
>
{ldapTestResult}
</span>
@@ -38,6 +38,7 @@ export function useLdapManagement(onUsersChanged: () => Promise<void> | void) {
const [ldapSaving, setLdapSaving] = useState(false);
const [ldapTesting, setLdapTesting] = useState(false);
const [ldapTestResult, setLdapTestResult] = useState<string | null>(null);
const [ldapTestSuccess, setLdapTestSuccess] = useState(false);
const [ldapMgmtOpen, setLdapMgmtOpen] = useState(false);
const [importFeedback, setImportFeedback] = useState<string | null>(null);
const [importResultOpen, setImportResultOpen] = useState(false);
@@ -101,11 +102,14 @@ export function useLdapManagement(onUsersChanged: () => Promise<void> | void) {
const handleLdapTest = async () => {
setLdapTesting(true);
setLdapTestResult(null);
setLdapTestSuccess(false);
try {
await ldapApi.updateConfig(ldapForm);
const res = await ldapApi.testConnection();
setLdapTestSuccess(!!res?.success);
setLdapTestResult(res?.message || (res?.success ? i18n.t('aiops.llmTestSuccess') : i18n.t('aiops.llmTestFailed')));
} catch (error) {
setLdapTestSuccess(false);
setLdapTestResult(error?.message || i18n.t('aiops.llmTestFailed'));
} finally {
setLdapTesting(false);
@@ -293,6 +297,7 @@ export function useLdapManagement(onUsersChanged: () => Promise<void> | void) {
ldapSaving,
ldapTesting,
ldapTestResult,
ldapTestSuccess,
handleLdapSave,
handleLdapTest,
ldapMgmtOpen,
@@ -182,7 +182,7 @@ export function ExecutionHistoryDialog({
? 'linear-gradient(to top, #ef4444 0%, #22c55e 100%)'
: item.total > 0 ? '#22c55e' : 'var(--dg-border)',
}}
title={`${item.label}: 成功 ${item.success} / 失败 ${item.failed}`}
title={t('task.execHistory.successFail', { label: item.label, success: item.success, failed: item.failed })}
/>
</div>
<span className="text-[10px] dg-text-muted">{item.label}</span>
+22 -7
View File
@@ -621,7 +621,9 @@
"currentValue": "current value",
"memberCount": "{{count}} members",
"fillIfMultiContainer": "(required for multi-container)",
"confirmDeleteType": "Delete {{type}} \"{{name}}\"?"
"confirmDeleteType": "Delete {{type}} \"{{name}}\"?",
"unitCount": "",
"fieldValues": "{{count}} values"
},
"menu": {
"aiAgentCli": "Agent CLI",
@@ -3031,7 +3033,8 @@
"maxReplicas": "Max Replicas",
"cpuTarget": "CPU Target (%)",
"memTarget": "Memory Target (%)",
"targetCPU": "Target CPU Utilization"
"targetCPU": "Target CPU Utilization",
"targetInfo": "Deployment: {{deploy}} · Namespace: {{ns}}"
},
"hpaCronHpa": {
"currentReplicas": "Current replicas:",
@@ -3148,7 +3151,8 @@
"searchPlaceholder": "Search namespaces...",
"title": "Namespace Management",
"quotaLimit": "Quota Limits",
"nameExample": "e.g. my-app"
"nameExample": "e.g. my-app",
"quotaSubtitle": "{{code}} · Resource Quotas & Lifecycle"
},
"nsOverview": {
"workloadReplicas": "Workload replica management",
@@ -3159,7 +3163,8 @@
"configMaps": "Configuration maps",
"secrets": "Secrets & credentials",
"hpaStrategy": "Horizontal autoscaling strategy",
"loadingStats": "Loading resource statistics..."
"loadingStats": "Loading resource statistics...",
"subtitle": "{{code}} · Namespace Overview"
},
"nsResource": {
"deployDesc": "Deployment workload status",
@@ -4370,7 +4375,9 @@
"siteRequestTimeout": "Request Timeout",
"siteConnFailed": "Connection Failed",
"noProbeHint": "No health probes. Click \"{{action}}\" to create one.",
"searchFields": "Search fields"
"searchFields": "Search fields",
"receiveSend": "RX {{rx}} · TX {{tx}}",
"currentFDUsage": "Current {{pct}}%"
},
"logAlertBell": {
"linked": "Alert Policy Linked",
@@ -5329,7 +5336,8 @@
"copied": "Copied to clipboard",
"recentTrend": "Last 7 days trends and execution logs (latest 100)",
"noRecords": "No execution records",
"last7days": "Last 7 days"
"last7days": "Last 7 days",
"successFail": "{{label}}: Success {{success}} / Failed {{failed}}"
},
"remoteExec": {
"subtitle": "Batch execute commands / upload files via native SSH",
@@ -7663,7 +7671,11 @@
"userTitle": "Title",
"userTitleField": "User Information",
"users": "Users",
"validUntil": "Valid Until"
"validUntil": "Valid Until",
"liveMonitor": {
"exitFullscreen": "Exit Fullscreen",
"fullscreen": "Fullscreen"
}
},
"aiops": {
"activeCount": "{{count}} active",
@@ -8541,5 +8553,8 @@
"oneDarkDesc": "Atom warm gray IDE, purple-green syntax",
"system": "Follow System",
"tokyoNightDesc": "Tokyo neon deep blue-purple, VS Code popular"
},
"monitor.hostMonitorPanel": {
"unitCount": ""
}
}
+22 -7
View File
@@ -621,7 +621,9 @@
"currentValue": "当前值",
"memberCount": "{{count}} 位成员",
"fillIfMultiContainer": "(多容器时填写)",
"confirmDeleteType": "确认删除 {{type}} \"{{name}}\"?"
"confirmDeleteType": "确认删除 {{type}} \"{{name}}\"?",
"unitCount": "个",
"fieldValues": "{{count}} 个值"
},
"menu": {
"aiAgentCli": "Agent CLI",
@@ -3031,7 +3033,8 @@
"maxReplicas": "最大副本数",
"cpuTarget": "CPU 目标 (%)",
"memTarget": "内存目标 (%)",
"targetCPU": "目标 CPU 使用率"
"targetCPU": "目标 CPU 使用率",
"targetInfo": "Deployment: {{deploy}} · 命名空间: {{ns}}"
},
"hpaCronHpa": {
"currentReplicas": "当前副本:",
@@ -3148,7 +3151,8 @@
"searchPlaceholder": "搜索命名空间...",
"title": "命名空间管理",
"quotaLimit": "配额限制",
"nameExample": "例如: my-app"
"nameExample": "例如: my-app",
"quotaSubtitle": "{{code}} · 资源配额与生命周期管理"
},
"nsOverview": {
"workloadReplicas": "工作负载副本管理",
@@ -3159,7 +3163,8 @@
"configMaps": "配置字典",
"secrets": "密钥与凭证",
"hpaStrategy": "水平自动伸缩策略",
"loadingStats": "加载资源统计..."
"loadingStats": "加载资源统计...",
"subtitle": "{{code}} · 命名空间概览"
},
"nsResource": {
"deployDesc": "Deployment 工作负载运行状态",
@@ -4370,7 +4375,9 @@
"siteRequestTimeout": "请求超时",
"siteConnFailed": "连接失败",
"noProbeHint": "暂无健康探针,点击「{{action}}」创建",
"searchFields": "搜索字段"
"searchFields": "搜索字段",
"receiveSend": "接收 {{rx}} · 发送 {{tx}}",
"currentFDUsage": "当前 {{pct}}%"
},
"logAlertBell": {
"linked": "已关联告警策略",
@@ -5329,7 +5336,8 @@
"copied": "已复制到剪贴板",
"recentTrend": "近 7 天趋势与执行日志(最近 100 条)",
"noRecords": "暂无执行记录",
"last7days": "最近 7 天"
"last7days": "最近 7 天",
"successFail": "{{label}}: 成功 {{success}} / 失败 {{failed}}"
},
"remoteExec": {
"subtitle": "关联主机后批量执行命令 / 上传文件(Go-native SSH)",
@@ -7663,7 +7671,11 @@
"userTitle": "职位",
"userTitleField": "用户信息",
"users": "用户管理",
"validUntil": "有效至"
"validUntil": "有效至",
"liveMonitor": {
"exitFullscreen": "退出全屏",
"fullscreen": "全屏"
}
},
"aiops": {
"activeCount": "{{count}} 个活跃",
@@ -8541,5 +8553,8 @@
"oneDarkDesc": "Atom 暖灰 IDE,紫绿语法渐变",
"system": "跟随系统",
"tokyoNightDesc": "东京霓虹深蓝紫,VS Code 热门"
},
"monitor.hostMonitorPanel": {
"unitCount": "个"
}
}
@@ -68,7 +68,7 @@ export function DualLineChart({
unit={unit}
chartId={`dual-${title.replace(/\s/g, '')}`}
title={title}
subtitle={`接收 ${currentRx} · 发送 ${currentTx}`}
subtitle={i18n.t('monitor.lbl.receiveSend', { rx: currentRx, tx: currentTx })}
height={208}
toolbarPlacement="header"
onZoomedChange={setZoomed}
@@ -63,7 +63,7 @@ export function FDUsageCard({ fdInfo, fdMetrics, aggType, fdChartRef, fdChartZoo
unit="%"
chartId="fd-usage"
title={t('monitor.lbl.nicBandwidth')}
subtitle={fdInfo?.usage_pct != null ? `当前 ${fdInfo.usage_pct.toFixed(1)}%` : undefined}
subtitle={fdInfo?.usage_pct != null ? t('monitor.lbl.currentFDUsage', { pct: fdInfo.usage_pct.toFixed(1) }) : undefined}
height={160}
toolbarPlacement="header"
onZoomedChange={setFdChartZoomed}
@@ -28,11 +28,11 @@ export function NetworkTab({ metrics, netInfo, currentVal, aggType }: NetworkTab
<MetricChartCard title="TCP EST" value={currentVal('tcp')} icon={<Network />} iconTone="purple"
data={metrics.tcpEst} color="#8b5cf6" unit={t('monitor.hostMonitorPanel.portUnit')} domain={[0, 'auto']} aggType={aggType} />
<MetricChartCard title="TCP TIME_WAIT" value={currentVal('tw')} icon={<Clock />} iconTone="yellow"
data={metrics.tcpTW} color="#f59e0b" unit="个" domain={[0, 'auto']} aggType={aggType} />
data={metrics.tcpTW} color="#f59e0b" unit={t('common.unitCount')} domain={[0, 'auto']} aggType={aggType} />
<MetricChartCard title="TCP CLOSE_WAIT" value={netInfo?.tcp_close_wait != null ? String(netInfo.tcp_close_wait) : '--'} icon={<Clock />} iconTone="red"
data={metrics.tcpCW} color="#ef4444" unit="个" domain={[0, 'auto']} aggType={aggType} />
data={metrics.tcpCW} color="#ef4444" unit={t('common.unitCount')} domain={[0, 'auto']} aggType={aggType} />
<MetricChartCard title={t('monitor.lbl.memUsage')} value={connTotal} icon={<Network />} iconTone="cyan"
data={metrics.connTotal} color="#22d3ee" unit="个" domain={[0, 'auto']} aggType={aggType} />
data={metrics.connTotal} color="#22d3ee" unit={t('common.unitCount')} domain={[0, 'auto']} aggType={aggType} />
</div>
<DualLineChart
title={t('monitor.lbl.hostMonitor')}
@@ -43,9 +43,9 @@ export function NetworkTab({ metrics, netInfo, currentVal, aggType }: NetworkTab
/>
<div className="grid grid-cols-1 md:grid-cols-2 gap-3 mt-3">
<MetricChartCard title={t('monitor.lbl.nicRxErrors')} value={netInfo?.net_rx_errors != null ? String(netInfo.net_rx_errors) : '--'} icon={<XCircle />} iconTone="red"
data={metrics.rxErr} color="#ef4444" unit="个" domain={[0, 'auto']} aggType={aggType} />
data={metrics.rxErr} color="#ef4444" unit={t('common.unitCount')} domain={[0, 'auto']} aggType={aggType} />
<MetricChartCard title={t('monitor.lbl.nicTxErrors')} value={netInfo?.net_tx_errors != null ? String(netInfo.net_tx_errors) : '--'} icon={<XCircle />} iconTone="orange"
data={metrics.txErr} color="#f97316" unit="个" domain={[0, 'auto']} aggType={aggType} />
data={metrics.txErr} color="#f97316" unit={t('common.unitCount')} domain={[0, 'auto']} aggType={aggType} />
</div>
</div>
);