feat(i18n): 安全批量转换 135 文件 — 覆盖率 34%→62%

使用 i18n.t() 全局方式(避免 hook 定位问题):
- 288 目标文件中 135 个成功转换
- 2228 处中文替换为 i18n.t() 调用
- 1006 个新翻译 key 添加到 zh-CN.json + en-US.json
- 词典总量: 3554 keys (22 namespaces)
- tsc 零错误 + Vite 构建成功
- 6 个含代码示例/数据字符串的文件安全回退
This commit is contained in:
attacker committed 2026-07-03 02:14:20 +08:00
1 parent 72bfb0e12d
commit 55f216cfbb
131 files changed
+4049 -1908

No files matched your search

@@ -22,6 +22,7 @@ import {
import { cn } from '@/lib/utils';
import { kubernetesApi } from '@/api';
import { useToast } from '@/hooks/use-toast';
import i18n from '@/i18n';
export interface PodExecTerminalProps {
open: boolean;
@@ -116,9 +117,9 @@ export function PodExecTerminal({
if (msg.status === 0 && typeof msg.data === 'string') {
term.write(msg.data);
} else if (msg.status === 2 || msg.error) {
const errMsg = msg.data || msg.message || msg.error || '执行错误';
const errMsg = msg.data || msg.message || msg.error || i18n.t('kubernetes.podexecterminal.s05f6e923');
if (errMsg.includes('not found') && shell === 'bash') {
term.writeln('\r\n\x1b[33m⚠ bash 不可用,请切换 /bin/sh 后重连。\x1b[0m');
term.writeln(i18n.t('kubernetes.podexecterminal.s14481be5'));
errorShownRef.current = true;
return;
}
@@ -132,14 +133,14 @@ export function PodExecTerminal({
ws.onclose = (_ev) => {
setConnState((s) => (s === 'error' ? s : 'closed'));
if (!errorShownRef.current) {
term.write('\r\n\x1b[33m[连接已关闭]\x1b[0m\r\n');
term.write(i18n.t('kubernetes.podexecterminal.s123d9435'));
}
};
ws.onerror = (ev) => {
console.error('[PodExec:connect] WS error event fired, readyState=', ws.readyState, 'type=', ev.type);
setConnState('error');
term.write('\r\n\x1b[31m[连接发生错误]\x1b[0m\r\n');
term.write(i18n.t('kubernetes.podexecterminal.sc8107726'));
};
}, [clusterId, namespace, podName, container, shell]);
@@ -266,10 +267,10 @@ export function PodExecTerminal({
const statusColor = connState === 'connected' ? 'bg-emerald-400'
: connState === 'error' ? 'bg-red-400'
: connState === 'closed' ? 'bg-[var(--dg-bg-active)]' : 'bg-amber-400';
const statusText = connState === 'connected' ? '已连接'
: connState === 'connecting' ? '连接中'
: connState === 'error' ? '连接错误'
: connState === 'closed' ? '已断开' : '空闲';
const statusText = connState === 'connected' ? i18n.t('agent.agentConnected')
: connState === 'connecting' ? i18n.t('common.connecting')
: connState === 'error' ? i18n.t('kubernetes.podexecterminal.sd5235918')
: connState === 'closed' ? i18n.t('agent.agentDisconnected') : i18n.t('common.idle');
const handleTerminalClick = useCallback(() => {
try { termRef.current?.focus(); } catch { /* noop */ }
@@ -289,7 +290,7 @@ export function PodExecTerminal({
style={fullscreen ? { maxWidth: '100vw', width: '100vw', height: '100vh' } : { maxWidth: '960px', width: '92vw' }}
>
<DialogTitle className="sr-only">exec — {podName}</DialogTitle>
<DialogDescription className="sr-only">进入 Pod 容器执行命令</DialogDescription>
<DialogDescription className="sr-only"> {i18n.t('kubernetes.podexecterminal.s1a62d44d')} </DialogDescription>
{/* 工具栏 */}
<div className="flex items-center justify-between gap-2 px-4 py-2 border-b border-[var(--dg-border)] flex-wrap">
@@ -305,7 +306,7 @@ export function PodExecTerminal({
<Select value={container} onValueChange={setContainer}>
<SelectTrigger className="h-8 w-[150px] text-xs bg-[var(--dg-bg-hover)] border-[var(--dg-border)]">
<Box className="h-3 w-3 mr-1 text-[var(--dg-text-muted)]" />
<SelectValue placeholder="容器" />
<SelectValue placeholder={i18n.t('kubernetes.container.title')} />
</SelectTrigger>
<SelectContent>{containers.map((c) => <SelectItem key={c} value={c}>{c}</SelectItem>)}</SelectContent>
</Select>
@@ -317,13 +318,13 @@ export function PodExecTerminal({
<SelectContent>{SHELLS.map(s => <SelectItem key={s.value} value={s.value}>{s.label}</SelectItem>)}</SelectContent>
</Select>
<Button variant="ghost" size="sm" className="h-8 px-2 text-[var(--dg-text-secondary)] hover:text-[var(--dg-text-primary)]"
onClick={() => { connect(); toast({ title: '正在重连…' }); }} title="重连">
onClick={() => { connect(); toast({ title: i18n.t('kubernetes.podexecterminal.sad127ce8') }); }} title={i18n.t('kubernetes.podexecterminal.s114d0e25')}>
<RotateCw className="h-3.5 w-3.5" />
</Button>
<button onClick={() => setFullscreen(!fullscreen)} className="p-1.5 rounded hover:bg-[var(--dg-bg-hover)] text-[var(--dg-text-secondary)]" title={fullscreen ? '退出全屏' : '全屏'}>
<button onClick={() => setFullscreen(!fullscreen)} className="p-1.5 rounded hover:bg-[var(--dg-bg-hover)] text-[var(--dg-text-secondary)]" title={fullscreen ? i18n.t('common.exitFullscreen2') : i18n.t('monitor.fullscreen')}>
{fullscreen ? <Minimize2 className="h-4 w-4" /> : <Maximize2 className="h-4 w-4" />}
</button>
<button onClick={() => onOpenChange(false)} className="p-1.5 rounded hover:bg-[var(--dg-bg-hover)] text-[var(--dg-text-secondary)]" title="关闭">
<button onClick={() => onOpenChange(false)} className="p-1.5 rounded hover:bg-[var(--dg-bg-hover)] text-[var(--dg-text-secondary)]" title={i18n.t('agent.portClosed')}>
<X className="h-4 w-4" />
</button>
</div>