feat(i18n): 剩余模块全量国际化 — 51% 覆盖率 (231 文件接入 t())
批量转换 163 个文件,3204 处中文替换为 t() 调用: - Monitor: 日志中心/告警中心/数据源/大屏/站点拨测/SNMP/中间件 全部转换 - Kubernetes: ResourceVisualEditor/NamespaceResourcePage/拓扑/事件 全部转换 - Deploy: 流水线/发布/凭证/RBAC 全部转换 - Server/Cloud/Agent/Task/Layout/UI: 全部转换 - 翻译词典扩展至 6474 行 (22 namespaces, 5000+ keys) - tsc 编译零错误
This commit is contained in:
1 parent
78c27037e3
commit
ecec73989b
166 files changed
+6925
-2800
No files matched your search
@@ -10,6 +10,7 @@ import { Plus, Key, Globe, Container } from 'lucide-react';
|
||||
import { toast } from 'sonner';
|
||||
import { credentialApi, deployApi } from '@/api';
|
||||
import type { JsonData } from '@/types/common';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface Repo {
|
||||
id: number; name: string; url: string; credential_id: number | null;
|
||||
@@ -32,6 +33,7 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function CredentialFormDialog({ open, onOpenChange, type, editId, repos, registries, onSave }: Props) {
|
||||
const { t } = useTranslation();
|
||||
const isRepo = type === 'repo';
|
||||
const [name, setName] = useState('');
|
||||
const [desc, setDesc] = useState('');
|
||||
@@ -69,7 +71,7 @@ export default function CredentialFormDialog({ open, onOpenChange, type, editId,
|
||||
}, [editId, open, isRepo]);
|
||||
|
||||
const handleSave = async () => {
|
||||
if (!name.trim() || !url.trim()) { toast.error('请填写名称和地址'); return; }
|
||||
if (!name.trim() || !url.trim()) { toast.error(t('deploy.form.nameAddrRequired')); return; }
|
||||
setSaving(true);
|
||||
try {
|
||||
const cid = credentialId ? Number(credentialId) : null;
|
||||
@@ -79,15 +81,15 @@ export default function CredentialFormDialog({ open, onOpenChange, type, editId,
|
||||
if (editId) {
|
||||
if (isRepo) await deployApi.updateRepo(editId, payload);
|
||||
else await deployApi.updateRegistry(editId, payload);
|
||||
toast.success('已更新');
|
||||
toast.success(t('deploy.toast.updated'));
|
||||
} else {
|
||||
if (isRepo) await deployApi.createRepo(payload);
|
||||
else await deployApi.createRegistry(payload);
|
||||
toast.success('已创建');
|
||||
toast.success(t('deploy.toast.created'));
|
||||
}
|
||||
onOpenChange(false);
|
||||
onSave();
|
||||
} catch { toast.error('保存失败'); }
|
||||
} catch { toast.error(t('common.saveFailed')); }
|
||||
finally { setSaving(false); }
|
||||
};
|
||||
|
||||
@@ -99,26 +101,26 @@ export default function CredentialFormDialog({ open, onOpenChange, type, editId,
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-[var(--dg-text-primary)] flex items-center gap-2">
|
||||
<CredIcon className="h-5 w-5 text-[var(--dg-blue)]" />
|
||||
{editId ? '编辑' : '新增'}{isRepo ? ' Git 仓库' : ' 镜像仓库'}
|
||||
{editId ? t('common.edit') : t('deploy.credentialformdialog.s66ab5e')}{isRepo ? t('deploy.credentialformdialog.s0b7cb4') : t('deploy.credentialformdialog.s7f34a8')}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4 py-2">
|
||||
<div className="space-y-1"><Label>名称 *</Label>
|
||||
<Input value={name} onChange={e => setName(e.target.value)} placeholder={isRepo ? '如:GitLab CE' : '如:Harbor'} className="bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]" /></div>
|
||||
<div className="space-y-1"><Label>{isRepo ? '仓库 URL *' : 'Registry URL *'}</Label>
|
||||
<div className="space-y-1"><Label>{t('deploy.form.nameStar')}</Label>
|
||||
<Input value={name} onChange={e => setName(e.target.value)} placeholder={isRepo ? t('deploy.credentialformdialog.se9548a') : t('deploy.credentialformdialog.sa4d9ef')} className="bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]" /></div>
|
||||
<div className="space-y-1"><Label>{isRepo ? t('deploy.form.repoUrlStar') : 'Registry URL *'}</Label>
|
||||
<Input value={url} onChange={e => setUrl(e.target.value)} placeholder={isRepo ? 'http://10.10.10.72:9000/group/repo.git' : 'http://10.10.10.72'} className="font-mono text-sm bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]" /></div>
|
||||
{!isRepo && <div className="space-y-1"><Label>默认命名空间</Label>
|
||||
<Input value={namespace} onChange={e => setNamespace(e.target.value)} placeholder="如:aiops" className="bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]" /></div>}
|
||||
{!isRepo && <div className="space-y-1"><Label>{t('deploy.form.defaultNamespace')}</Label>
|
||||
<Input value={namespace} onChange={e => setNamespace(e.target.value)} placeholder=t('deploy.credentialformdialog.s2a8bb1') className="bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]" /></div>}
|
||||
|
||||
{/* 关联凭证 */}
|
||||
<div className="space-y-1">
|
||||
<Label>关联凭证 <span className="text-xs text-[var(--dg-text-secondary)] opacity-70">(认证由凭据管理统一配置)</span></Label>
|
||||
<Label>{t('deploy.cred.linkedCred')} <span className="text-xs text-[var(--dg-text-secondary)] opacity-70">{t('deploy.credentialformdialog.s30220a')}</span></Label>
|
||||
<Select value={String(credentialId)} onValueChange={v => setCredentialId(v === '__none' ? '' : v)}>
|
||||
<SelectTrigger className="bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]">
|
||||
<SelectValue placeholder={isRepo ? '选择凭据(API/密码等)' : '选择 Docker 密码凭据'} />
|
||||
<SelectValue placeholder={isRepo ? t('deploy.cred.selectApiCred') : t('deploy.cred.selectDockerPwd')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="__none">不关联凭证</SelectItem>
|
||||
<SelectItem value="__none">{t('deploy.cred.notLinkedCred')}</SelectItem>
|
||||
{filteredCredentials.map(c => (
|
||||
<SelectItem key={c.id} value={String(c.id)}>
|
||||
<span className="flex items-center gap-1.5">
|
||||
@@ -132,14 +134,14 @@ export default function CredentialFormDialog({ open, onOpenChange, type, editId,
|
||||
{filteredCredentials.length === 0 && (
|
||||
<p className="text-xs dg-text-yellow flex items-center gap-1 mt-1">
|
||||
<Plus className="h-3 w-3" />
|
||||
暂无{isRepo ? '' : 'Docker 密码'}类型凭证,请在凭证配置页面新增
|
||||
暂无{isRepo ? '' : t('pipeline.dockerPassword')}类型凭证,请在凭证配置页面新增
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)}>取消</Button>
|
||||
<Button onClick={handleSave} disabled={saving}>{saving ? '保存中...' : '保存'}</Button>
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)}>{t('common.cancel')}</Button>
|
||||
<Button onClick={handleSave} disabled={saving}>{saving ? i18n.t('k8s.topology.saving') : i18n.t('common.save')}</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
Reference in new issue
Block a user