feat(i18n): 全量中英文国际化改造
- 翻译 en-US.json 中 1006 条未翻译的中文条目为英文 - 提取 30+ 组件文件的硬编码中文到 locale JSON - 新增 900+ 翻译键覆盖所有业务模块: - Layout (Sidebar, Header, Breadcrumb) - Server (ServerForm, CloudServerImport, WebShell, RdpTools) - Deploy (ReleaseManager, PipelineCreate, AppRelease) - Kubernetes (DeploymentEdit, PodExec, PodLogs, ResourceEditor) - Monitor (UnifiedQueryPanel, AlertCenter, Prometheus/Grafana Dashboard) - AIOps (predictUtils, PredictiveCostTab, AIPredictive) - System (useLdapManagement, AgentMonitor, AgentWizard) - tsc --noEmit 类型检查通过
This commit is contained in:
1 parent
76ec9387f0
commit
a9513c2056
44 files changed
+4342
-1792
No files matched your search
@@ -24,6 +24,7 @@ import { attachTerminalResize, mountXterm } from '@/lib/xterm-utils';
|
||||
import { TerminalLoadingOverlay } from '@/components/common/TerminalLoadingOverlay';
|
||||
import { kubernetesApi } from '@/api';
|
||||
import { useToast } from '@/hooks/use-toast';
|
||||
import i18n from '@/i18n';
|
||||
|
||||
export interface PodExecTerminalProps {
|
||||
open: boolean;
|
||||
@@ -96,7 +97,7 @@ export function PodExecTerminal({
|
||||
setConnState('connecting');
|
||||
setHasOutput(false);
|
||||
term.clear();
|
||||
term.writeln(`\x1b[36m[正在连接 ${podName}${container ? '/' + container : ''} shell=${shell} ...]\x1b[0m`);
|
||||
term.writeln(`\x1b[36m[${i18n.t('k8s.podExec.connecting')} ${podName}${container ? '/' + container : ''} shell=${shell} ...]\x1b[0m`);
|
||||
|
||||
const wsUrl = kubernetesApi.buildPodExecWsUrl(clusterId, namespace, podName, container || undefined, shell);
|
||||
|
||||
@@ -122,9 +123,9 @@ export function PodExecTerminal({
|
||||
term.write(msg.data);
|
||||
} else if (msg.status === 2 || msg.error) {
|
||||
setHasOutput(true);
|
||||
const errMsg = msg.data || msg.message || msg.error || '执行错误';
|
||||
const errMsg = msg.data || msg.message || msg.error || i18n.t('k8s.podExec.execError');
|
||||
if (errMsg.includes('not found') && shell === 'bash') {
|
||||
term.writeln('\r\n\x1b[33m⚠ bash 不可用,请切换 /bin/sh 后重连。\x1b[0m');
|
||||
term.writeln(i18n.t('k8s.podExec.reconnect'));
|
||||
errorShownRef.current = true;
|
||||
return;
|
||||
}
|
||||
@@ -142,7 +143,7 @@ export function PodExecTerminal({
|
||||
setConnState((s) => (s === 'error' ? s : 'closed'));
|
||||
setHasOutput(true);
|
||||
if (!errorShownRef.current) {
|
||||
term.write('\r\n\x1b[33m[连接已关闭]\x1b[0m\r\n');
|
||||
term.write(i18n.t('k8s.podExec.close'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -150,7 +151,7 @@ export function PodExecTerminal({
|
||||
console.error('[PodExec:connect] WS error event fired, readyState=', ws.readyState, 'type=', ev.type);
|
||||
setConnState('error');
|
||||
setHasOutput(true);
|
||||
term.write('\r\n\x1b[31m[连接发生错误]\x1b[0m\r\n');
|
||||
term.write(i18n.t('k8s.podExec.sc8107726'));
|
||||
};
|
||||
}, [clusterId, namespace, podName, container, shell]);
|
||||
|
||||
@@ -268,10 +269,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('k8s.podExec.connected')
|
||||
: connState === 'connecting' ? i18n.t('k8s.podExec.connecting')
|
||||
: connState === 'error' ? i18n.t('k8s.podExec.connectionError')
|
||||
: connState === 'closed' ? i18n.t('k8s.podExec.disconnected1') : i18n.t('k8s.podExec.idle');
|
||||
|
||||
const handleTerminalClick = useCallback(() => {
|
||||
try { termRef.current?.focus(); } catch { /* noop */ }
|
||||
@@ -291,7 +292,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('k8s.podExec.enterPod')}</DialogDescription>
|
||||
|
||||
{/* 工具栏 */}
|
||||
<div className="flex items-center justify-between gap-2 px-4 py-2 border-b border-[var(--dg-border)] flex-wrap">
|
||||
@@ -307,7 +308,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('k8s.podExec.container') />
|
||||
</SelectTrigger>
|
||||
<SelectContent>{containers.map((c) => <SelectItem key={c} value={c}>{c}</SelectItem>)}</SelectContent>
|
||||
</Select>
|
||||
@@ -319,13 +320,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('k8s.podExec.reconnect1') }); }} title=i18n.t('k8s.podExec.reconnect2')>
|
||||
<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('k8s.podExec.exitFullscreen') : i18n.t('k8s.podExec.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('k8s.podExec.close1')>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
@@ -338,7 +339,7 @@ export function PodExecTerminal({
|
||||
className="xterm-terminal-host h-full cursor-text"
|
||||
onClick={handleTerminalClick}
|
||||
/>
|
||||
<TerminalLoadingOverlay show={connState === 'connecting' && !hasOutput} label="正在进入容器..." />
|
||||
<TerminalLoadingOverlay show={connState === 'connecting' && !hasOutput} label=i18n.t('k8s.podExec.container1') />
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
Reference in new issue
Block a user