refactor(i18n): U36 全量 JSX 属性 + toast 硬编码中文清零 — 20 文件 30 处 → 0
清理 23 处 JSX 属性 (title/placeholder/label/description) + 7 处 toast 调用硬编码中文: - Deploy 模块 (AppRelease/DeployCredentials/PipelineManager/WorkspaceTermDialog/CredFormDialog/JobRoleCreateDialog/PipelineCreateDialog/AdvancedSettingsPanel) - Server 模块 (ServerForm) - System 模块 (LdapManagementSection/LiveMonitorDialog/SystemManager) - Audit 模块 (ActiveSessionsPanel/HistorySessionsPanel) - Monitor 模块 (AlertRulesTab/PrometheusDatasourceManager/SNMPMonitor) - AIOps 模块 (PredictiveCapacityTab) - Common/UI (TerminalLoadingOverlay/copy-button) 新增 25 翻译键 (common.connectingEllipsis/enteringWorkspace/connectingMonitor + deploy.* 11键 + server.jsonFormatPlaceholder + system.* 3键 + audit.* 2键 + monitor.* 3键 + aiops.aiAnalysisFailedToast + pipeline.subtitle) copy-button.tsx 从 import i18n → useTranslation() hook 3 组件新增 useTranslation hook (TerminalLoadingOverlay/WorkspaceTermDialog/LiveMonitorDialog/PredictiveCapacityTab) zh/en 7616→7640 +24 对齐, tsc -b=0, npm build✓ (17.25s), ESLint=0/43/0, go build=0, 17/17 测试通过
This commit is contained in:
1 parent
8d64936caf
commit
09b7fd4ad5
22 files changed
+114
-55
No files matched your search
@@ -100,7 +100,7 @@ export function AppReleaseManager() {
|
||||
</div>
|
||||
<Select value={envFilter} onValueChange={setEnvFilter}>
|
||||
<SelectTrigger className="w-32 h-9 dg-input">
|
||||
<SelectValue placeholder="环境" />
|
||||
<SelectValue placeholder={t('deploy.placeholderEnv')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="dg-input">
|
||||
<SelectItem value="all">{t('deploy.filterAllEnv')}</SelectItem>
|
||||
@@ -112,7 +112,7 @@ export function AppReleaseManager() {
|
||||
</Select>
|
||||
<Select value={statusFilter} onValueChange={setStatusFilter}>
|
||||
<SelectTrigger className="w-32 h-9 dg-input">
|
||||
<SelectValue placeholder="状态" />
|
||||
<SelectValue placeholder={t('deploy.placeholderStatus')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="dg-input">
|
||||
<SelectItem value="all">{t('deploy.filterAllStatus')}</SelectItem>
|
||||
|
||||
@@ -275,8 +275,8 @@ export default function DeployCredentials() {
|
||||
{environments.length === 0 ? (
|
||||
<PageEmpty
|
||||
icon={<Globe className="h-10 w-10" />}
|
||||
title="暂无环境配置"
|
||||
description='点击"新增环境"创建'
|
||||
title={t('deploy.noEnvConfig')}
|
||||
description={t('deploy.clickEnvConfigHint')}
|
||||
action={(
|
||||
<Button size="sm" onClick={() => { setEditEnv(null); setEnvDialogOpen(true); }}>
|
||||
<Plus className="w-4 h-4 mr-1" />新增环境
|
||||
|
||||
@@ -214,8 +214,8 @@ export function PipelineManager() {
|
||||
return (
|
||||
<PageShell
|
||||
variant="list"
|
||||
title="流水线"
|
||||
subtitle="CI/CD 构建、镜像打包与双通道部署"
|
||||
title={t('pipeline.title')}
|
||||
subtitle={t('pipeline.subtitle')}
|
||||
icon={<Workflow className="h-5 w-5" />}
|
||||
loading={loading}
|
||||
toolbar={toolbar}
|
||||
|
||||
@@ -13,6 +13,7 @@ import { cn } from '@/lib/utils';
|
||||
import { attachTerminalResize, mountXterm } from '@/lib/xterm-utils';
|
||||
import { useUserStore } from '@/store';
|
||||
import { pipelineApi } from '@/api';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { TerminalLoadingOverlay } from '@/components/common/TerminalLoadingOverlay';
|
||||
import type { JsonData } from '@/types/common';
|
||||
|
||||
@@ -32,6 +33,7 @@ export function WorkspaceTermDialog({
|
||||
runId,
|
||||
buildNumber,
|
||||
}: WorkspaceTermDialogProps) {
|
||||
const { t } = useTranslation();
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const termRef = useRef<XTerm | null>(null);
|
||||
const wsRef = useRef<WebSocket | null>(null);
|
||||
@@ -186,7 +188,7 @@ export function WorkspaceTermDialog({
|
||||
</div>
|
||||
<div className="relative bg-[#0a0e14]" style={{ height: fullscreen ? 'calc(100vh - 49px)' : '480px' }}>
|
||||
<div ref={containerRef} className="xterm-terminal-host h-full" />
|
||||
<TerminalLoadingOverlay show={!hasOutput} label="正在进入工作区..." />
|
||||
<TerminalLoadingOverlay show={!hasOutput} label={t('common.enteringWorkspace')} />
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
@@ -123,8 +123,8 @@ export function CredFormDialog({ open, onClose, onSaved, editData }: CredFormDia
|
||||
if (sshPrivateKey.trim()) payload.ssh_private_key = sshPrivateKey.trim();
|
||||
if (sshPublicKey.trim()) payload.ssh_public_key = sshPublicKey.trim();
|
||||
} else if (secretType === 'rdp') {
|
||||
if (!rdpUsername.trim()) { toast.error('请填写 RDP 用户'); return; }
|
||||
if (!isEdit && !rdpPassword.trim()) { toast.error('请填写 RDP 密码'); return; }
|
||||
if (!rdpUsername.trim()) { toast.error(t('deploy.rdpUserRequired')); return; }
|
||||
if (!isEdit && !rdpPassword.trim()) { toast.error(t('deploy.rdpPasswordRequired')); return; }
|
||||
if (rdpUsername.trim()) payload.rdp_username = rdpUsername.trim();
|
||||
if (rdpPassword.trim()) payload.rdp_password = rdpPassword.trim();
|
||||
if (rdpDomain.trim()) payload.rdp_domain = rdpDomain.trim();
|
||||
@@ -310,11 +310,11 @@ export function CredFormDialog({ open, onClose, onSaved, editData }: CredFormDia
|
||||
</Select>
|
||||
</div>
|
||||
{/* 用户名(左上)与密码(左下)同列上下行,安全模式/域归右列 // Logan.Li */}
|
||||
<div><FieldWithToggle label="Windows 密码" value={rdpPassword} onChange={setRdpPassword}
|
||||
placeholder="Windows 登录密码" fieldKey="rdp_pwd" required /></div>
|
||||
<div><FieldWithToggle label={t('deploy.rdpPassword')} value={rdpPassword} onChange={setRdpPassword}
|
||||
placeholder={t('deploy.rdpPasswordPlaceholder')} fieldKey="rdp_pwd" required /></div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-[var(--dg-text-secondary)] text-xs">域</Label>
|
||||
<Input value={rdpDomain} onChange={e => setRdpDomain(e.target.value)} placeholder="可选"
|
||||
<Input value={rdpDomain} onChange={e => setRdpDomain(e.target.value)} placeholder={t('common.optional')}
|
||||
className="bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -89,7 +89,7 @@ export function JobRoleCreateDialog({
|
||||
<Input
|
||||
value={pattern}
|
||||
onChange={(e) => onPatternChange(e.target.value)}
|
||||
placeholder="^cex-.* 或 ^api-server$"
|
||||
placeholder={t('deploy.jobNamePatternHint')}
|
||||
className="h-8 text-sm font-mono dg-input"
|
||||
/>
|
||||
<p className="text-[10px] text-[var(--dg-text-muted)]">{patternHint}</p>
|
||||
|
||||
@@ -371,7 +371,7 @@ export function PipelineCreateDialog({ open, onOpenChange, onCreated }: Pipeline
|
||||
onValueChange={(v) => setNewGitCredentialId(v === '__none' ? '' : v)}
|
||||
>
|
||||
<SelectTrigger className="h-8 text-xs dg-input">
|
||||
<SelectValue placeholder="选择凭证" />
|
||||
<SelectValue placeholder={t('deploy.selectCredentialPlaceholder')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="__none">{t('deploy.notLinked')}</SelectItem>
|
||||
@@ -396,7 +396,7 @@ export function PipelineCreateDialog({ open, onOpenChange, onCreated }: Pipeline
|
||||
onValueChange={(v) => setNewRegistryCredentialId(v === '__none' ? '' : v)}
|
||||
>
|
||||
<SelectTrigger className="h-8 text-xs dg-input">
|
||||
<SelectValue placeholder="Docker 凭证" />
|
||||
<SelectValue placeholder={t('deploy.dockerCredPlaceholder')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="__none">不关联</SelectItem>
|
||||
|
||||
+1
-1
@@ -106,7 +106,7 @@ export function AdvancedSettingsPanel({
|
||||
<Input
|
||||
value={watchBranches}
|
||||
onChange={(e) => onWatchBranchesChange(e.target.value)}
|
||||
placeholder="监听分支,如 main, release/*"
|
||||
placeholder={t('deploy.branchListenPlaceholder')}
|
||||
className="h-8 text-xs font-mono dg-input"
|
||||
/>
|
||||
)}
|
||||
|
||||
Reference in new issue
Block a user