fix(k8s): 修复 shared-components.tsx JSX 结构错误致前端构建失败 + 补全残余 i18n 硬编码中文
- fix: shared-components.tsx ContainerInfo 端口区块多余 <div> 标签致 JSX 闭合错误 (TS17008) - i18n: EventsPage/DeploymentDetail/DeploymentEditAdvanced/Containers/Storage 等 K8s 组件残余硬编码中文→t() 调用 - i18n: zh/en 7987 键完全对齐, 新增 k8s.eventsPage/k8s.workload 等语义化键 - tsc -b=0, npm build✓ (17.48s), ESLint errors=0/warnings=43/any=0, go build=0 - 17/17 集成测试通过, Docker 部署 healthy
This commit is contained in:
1 parent
39a4432f79
commit
bd1ccefa7f
13 files changed
+172
-42
No files matched your search
@@ -176,7 +176,7 @@ export function DeploymentDetail({ clusterCode, namespace, deploymentName, onBac
|
|||||||
<Tabs defaultValue="pods">
|
<Tabs defaultValue="pods">
|
||||||
<TabsList className="bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)]">
|
<TabsList className="bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)]">
|
||||||
<TabsTrigger value="pods" className="data-[state=active]:bg-[var(--dg-bg-active)]">
|
<TabsTrigger value="pods" className="data-[state=active]:bg-[var(--dg-bg-active)]">
|
||||||
Pod 列表 ({pods.length})
|
{i18n.t('k8s.deploymentDetail.podList')} ({pods.length})
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
<TabsTrigger value="logs" className="data-[state=active]:bg-[var(--dg-bg-active)]">
|
<TabsTrigger value="logs" className="data-[state=active]:bg-[var(--dg-bg-active)]">
|
||||||
<FileText className="h-4 w-4 mr-1" />{i18n.t("common.podLogs")}
|
<FileText className="h-4 w-4 mr-1" />{i18n.t("common.podLogs")}
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ export function DeploymentEditAdvanced({ clusterCode, namespace, deploymentName,
|
|||||||
<Button variant="outline" className="border-[var(--dg-border)] dg-text-secondary" onClick={onCancel}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
<Button variant="outline" className="border-[var(--dg-border)] dg-text-secondary" onClick={onCancel}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
||||||
<Button className="bg-blue-600 hover:bg-blue-700" disabled={saving} onClick={save}>
|
<Button className="bg-blue-600 hover:bg-blue-700" disabled={saving} onClick={save}>
|
||||||
{saving ? <Loader2 className="h-4 w-4 animate-spin mr-1" /> : <Save className="h-4 w-4 mr-1" />}
|
{saving ? <Loader2 className="h-4 w-4 animate-spin mr-1" /> : <Save className="h-4 w-4 mr-1" />}
|
||||||
保存
|
{i18n.t('common.save')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ export function DeploymentEditContainers({ clusterCode, namespace, deploymentNam
|
|||||||
<Button variant="outline" className="border-[var(--dg-border)] dg-text-secondary" onClick={onCancel}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
<Button variant="outline" className="border-[var(--dg-border)] dg-text-secondary" onClick={onCancel}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
||||||
<Button className="bg-blue-600 hover:bg-blue-700" disabled={saving} onClick={save}>
|
<Button className="bg-blue-600 hover:bg-blue-700" disabled={saving} onClick={save}>
|
||||||
{saving ? <Loader2 className="h-4 w-4 animate-spin mr-1" /> : <Save className="h-4 w-4 mr-1" />}
|
{saving ? <Loader2 className="h-4 w-4 animate-spin mr-1" /> : <Save className="h-4 w-4 mr-1" />}
|
||||||
保存
|
{i18n.t('common.save')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ export function DeploymentEditStorage({ clusterCode, namespace, deploymentName,
|
|||||||
<Button variant="outline" className="border-[var(--dg-border)] dg-text-secondary" onClick={onCancel}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
<Button variant="outline" className="border-[var(--dg-border)] dg-text-secondary" onClick={onCancel}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
||||||
<Button className="bg-blue-600 hover:bg-blue-700" disabled={saving} onClick={save}>
|
<Button className="bg-blue-600 hover:bg-blue-700" disabled={saving} onClick={save}>
|
||||||
{saving ? <Loader2 className="h-4 w-4 animate-spin mr-1" /> : <Save className="h-4 w-4 mr-1" />}
|
{saving ? <Loader2 className="h-4 w-4 animate-spin mr-1" /> : <Save className="h-4 w-4 mr-1" />}
|
||||||
保存
|
{i18n.t('common.save')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -165,12 +165,12 @@ export default function EventsPage() {
|
|||||||
<span className="text-[var(--dg-text-muted)]"> {i18n.t('kubernetes.eventsPage.filterLabel')} </span>
|
<span className="text-[var(--dg-text-muted)]"> {i18n.t('kubernetes.eventsPage.filterLabel')} </span>
|
||||||
{selectedReason && (
|
{selectedReason && (
|
||||||
<button type="button" className="inline-flex items-center gap-1 rounded border border-[var(--dg-border)] px-2 py-0.5 text-[var(--dg-text-secondary)] hover:bg-[var(--dg-bg-tertiary)]" onClick={() => setSelectedReason('')}>
|
<button type="button" className="inline-flex items-center gap-1 rounded border border-[var(--dg-border)] px-2 py-0.5 text-[var(--dg-text-secondary)] hover:bg-[var(--dg-bg-tertiary)]" onClick={() => setSelectedReason('')}>
|
||||||
原因 {selectedReason} <X className="h-3 w-3" />
|
{i18n.t('k8s.eventsPage.reasonLabel')} {selectedReason} <X className="h-3 w-3" />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{selectedKind && (
|
{selectedKind && (
|
||||||
<button type="button" className="inline-flex items-center gap-1 rounded border border-[var(--dg-border)] px-2 py-0.5 text-[var(--dg-text-secondary)] hover:bg-[var(--dg-bg-tertiary)]" onClick={() => setSelectedKind('')}>
|
<button type="button" className="inline-flex items-center gap-1 rounded border border-[var(--dg-border)] px-2 py-0.5 text-[var(--dg-text-secondary)] hover:bg-[var(--dg-bg-tertiary)]" onClick={() => setSelectedKind('')}>
|
||||||
类型 {selectedKind} <X className="h-3 w-3" />
|
{i18n.t('k8s.eventsPage.kindLabel')} {selectedKind} <X className="h-3 w-3" />
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -240,7 +240,7 @@ export default function EventsPage() {
|
|||||||
<CardContent className="p-4">
|
<CardContent className="p-4">
|
||||||
<h3 className="text-sm font-medium text-[var(--dg-text-primary)] mb-3 flex items-center gap-1.5">
|
<h3 className="text-sm font-medium text-[var(--dg-text-primary)] mb-3 flex items-center gap-1.5">
|
||||||
<AlertTriangle className="h-4 w-4 text-[var(--dg-orange)]" />
|
<AlertTriangle className="h-4 w-4 text-[var(--dg-orange)]" />
|
||||||
最新告警 ({summary.recent_warnings.length})
|
{i18n.t('k8s.eventsPage.recentWarnings')} ({summary.recent_warnings.length})
|
||||||
</h3>
|
</h3>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
{summary.recent_warnings.map((w: JsonData, i: number) => (
|
{summary.recent_warnings.map((w: JsonData, i: number) => (
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ export function KubernetesClusterDialog({
|
|||||||
/>
|
/>
|
||||||
{nameError && <p className="text-xs dg-text-red">{nameError}</p>}
|
{nameError && <p className="text-xs dg-text-red">{nameError}</p>}
|
||||||
<p className="text-xs text-[var(--dg-text-muted)]">
|
<p className="text-xs text-[var(--dg-text-muted)]">
|
||||||
只允许英文、数字和连字符(-),首尾不能是连字符。名称将作为集群唯一标识。
|
{i18n.t('k8s.clusterDialog.codeRule')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
@@ -243,7 +243,7 @@ export function KubernetesClusterDialog({
|
|||||||
/>
|
/>
|
||||||
{!hasKubeConfig && (
|
{!hasKubeConfig && (
|
||||||
<p className="text-xs text-[var(--dg-text-muted)]">
|
<p className="text-xs text-[var(--dg-text-muted)]">
|
||||||
粘贴 kubeconfig 内容后将自动解析 API Server 地址
|
{i18n.t('k8s.clusterDialog.kubeconfigHint')}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -255,7 +255,7 @@ export function KubernetesClusterDialog({
|
|||||||
onClick={() => { onOpenChange(false); }}
|
onClick={() => { onOpenChange(false); }}
|
||||||
className="border-[var(--dg-border)] text-[var(--dg-text-secondary)] hover:text-[var(--dg-text-primary)] hover:bg-[var(--dg-bg-hover)]"
|
className="border-[var(--dg-border)] text-[var(--dg-text-secondary)] hover:text-[var(--dg-text-primary)] hover:bg-[var(--dg-bg-hover)]"
|
||||||
>
|
>
|
||||||
取消
|
{i18n.t('common.cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ export function KubernetesNodes() {
|
|||||||
<TableCell>{getRoleBadge(n.role)}</TableCell>
|
<TableCell>{getRoleBadge(n.role)}</TableCell>
|
||||||
<TableCell>{getStatusBadge(n.status)}</TableCell>
|
<TableCell>{getStatusBadge(n.status)}</TableCell>
|
||||||
<TableCell className="text-sm text-[var(--dg-text-secondary)]">
|
<TableCell className="text-sm text-[var(--dg-text-secondary)]">
|
||||||
{n.cpu ? `${n.cpu}核` : '-'} / {n.memory ? `${Math.round(n.memory / 1024)}GB` : '-'}
|
{n.cpu ? `${n.cpu}${i18n.t('k8s.nodes.cores')}` : '-'} / {n.memory ? `${Math.round(n.memory / 1024)}GB` : '-'}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
{(() => {
|
{(() => {
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ export default function NamespaceManagementPage() {
|
|||||||
onKeyDown={(e) => e.key === 'Enter' && handleCreate()}
|
onKeyDown={(e) => e.key === 'Enter' && handleCreate()}
|
||||||
/>
|
/>
|
||||||
<p className="text-xs text-[var(--dg-text-muted)]">
|
<p className="text-xs text-[var(--dg-text-muted)]">
|
||||||
名称需符合 DNS-1123 标准(小写字母/数字/连字符)
|
{i18n.t('k8s.nsMgmt.dnsHint')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -166,7 +166,7 @@ export default function NamespaceManagementPage() {
|
|||||||
<Button variant="outline" onClick={() => setCreateOpen(false)}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
<Button variant="outline" onClick={() => setCreateOpen(false)}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
||||||
<Button onClick={handleCreate} disabled={creating || !newName.trim()}>
|
<Button onClick={handleCreate} disabled={creating || !newName.trim()}>
|
||||||
{creating ? <Loader2 className="h-4 w-4 animate-spin mr-1" /> : null}
|
{creating ? <Loader2 className="h-4 w-4 animate-spin mr-1" /> : null}
|
||||||
创建
|
{i18n.t('common.create')}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
@@ -280,7 +280,7 @@ export default function NamespaceManagementPage() {
|
|||||||
{i18n.t('common.deleteNamespaceWarn')} <span className="font-bold">{deleteTarget}</span> {i18n.t('common.allResources')}
|
{i18n.t('common.deleteNamespaceWarn')} <span className="font-bold">{deleteTarget}</span> {i18n.t('common.allResources')}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-xs text-[var(--dg-red)]/70 mt-1">
|
<p className="text-xs text-[var(--dg-red)]/70 mt-1">
|
||||||
此操作不可逆,所有 Deployment/Pod/Service/ConfigMap 等资源将被永久删除。
|
{i18n.t('k8s.nsMgmt.confirmDeleteDesc')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -288,7 +288,7 @@ export default function NamespaceManagementPage() {
|
|||||||
<Button variant="outline" onClick={() => setDeleteTarget(null)}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
<Button variant="outline" onClick={() => setDeleteTarget(null)}> {i18n.t('rbac.jobRole.cancel')} </Button>
|
||||||
<Button variant="destructive" onClick={handleDelete} disabled={deleting}>
|
<Button variant="destructive" onClick={handleDelete} disabled={deleting}>
|
||||||
{deleting ? <Loader2 className="h-4 w-4 animate-spin mr-1" /> : null}
|
{deleting ? <Loader2 className="h-4 w-4 animate-spin mr-1" /> : null}
|
||||||
确认删除
|
{i18n.t('k8s.nsMgmt.confirmDelete')}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogFooter>
|
</DialogFooter>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ export function PodFileBrowser({
|
|||||||
const text = await kubernetesApi.readPodFileText(clusterCode, namespace, podName, filePath, container || undefined);
|
const text = await kubernetesApi.readPodFileText(clusterCode, namespace, podName, filePath, container || undefined);
|
||||||
setPreview({ file: fileName, content: text });
|
setPreview({ file: fileName, content: text });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setPreview({ file: fileName, content: `读取失败: ${(e as JsonData).message}` });
|
setPreview({ file: fileName, content: `${i18n.t('k8s.podFiles.readError')}: ${(e as JsonData).message}` });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ export function PodFileBrowser({
|
|||||||
await kubernetesApi.uploadPodFile(clusterCode, namespace, podName, currentPath, file, container || undefined);
|
await kubernetesApi.uploadPodFile(clusterCode, namespace, podName, currentPath, file, container || undefined);
|
||||||
loadFiles(currentPath);
|
loadFiles(currentPath);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(`上传失败: ${(err as JsonData).message}`);
|
setError(`${i18n.t('k8s.podFiles.uploadError')}: ${(err as JsonData).message}`);
|
||||||
} finally {
|
} finally {
|
||||||
setUploading(false);
|
setUploading(false);
|
||||||
if (fileInputRef.current) fileInputRef.current.value = '';
|
if (fileInputRef.current) fileInputRef.current.value = '';
|
||||||
@@ -211,7 +211,7 @@ export function PodFileBrowser({
|
|||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<input type="file" ref={fileInputRef} className="hidden" onChange={handleUpload} />
|
<input type="file" ref={fileInputRef} className="hidden" onChange={handleUpload} />
|
||||||
<Button size="sm" variant="outline" className="h-7 border-[var(--dg-border)] text-[var(--dg-text-secondary)] text-xs" onClick={() => fileInputRef.current?.click()} disabled={uploading}>
|
<Button size="sm" variant="outline" className="h-7 border-[var(--dg-border)] text-[var(--dg-text-secondary)] text-xs" onClick={() => fileInputRef.current?.click()} disabled={uploading}>
|
||||||
{uploading ? <Loader2 className="h-3 w-3 animate-spin mr-1" /> : <Upload className="h-3 w-3 mr-1" />}上传
|
{uploading ? <Loader2 className="h-3 w-3 animate-spin mr-1" /> : <Upload className="h-3 w-3 mr-1" />}{i18n.t('common.upload')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button size="sm" variant="outline" className="h-7 border-[var(--dg-border)] text-[var(--dg-text-secondary)] text-xs" onClick={() => loadFiles(currentPath)} disabled={loading}>
|
<Button size="sm" variant="outline" className="h-7 border-[var(--dg-border)] text-[var(--dg-text-secondary)] text-xs" onClick={() => loadFiles(currentPath)} disabled={loading}>
|
||||||
{loading ? <Loader2 className="h-3 w-3 animate-spin" /> : <RefreshCw className="h-3 w-3" />}
|
{loading ? <Loader2 className="h-3 w-3 animate-spin" /> : <RefreshCw className="h-3 w-3" />}
|
||||||
|
|||||||
@@ -97,6 +97,6 @@ export async function saveDeploymentBundleYaml(
|
|||||||
await kubernetesApi.applyYAML(clusterCode, docYaml);
|
await kubernetesApi.applyYAML(clusterCode, docYaml);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
throw new Error(`不支持的资源类型: ${manifest.kind}(仅支持 Deployment / Service)`);
|
throw new Error(i18n.t('k8s.bundleYaml.unsupportedType', { kind: manifest.kind }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ export function ContainerInfo({ c }: { c: JsonData }) {
|
|||||||
内存: <span className="text-[var(--dg-text-primary)] font-mono">{c.resources?.requests?.memory || '-'}/{c.resources?.limits?.memory || '-'}</span>
|
内存: <span className="text-[var(--dg-text-primary)] font-mono">{c.resources?.requests?.memory || '-'}/{c.resources?.limits?.memory || '-'}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-[var(--dg-text-secondary)]">
|
<div className="text-[var(--dg-text-secondary)]">
|
||||||
端口: <span className="text-[var(--dg-text-primary)] font-mono">
|
{i18n.t('k8s.workload.portsLabel')}: <span className="text-[var(--dg-text-primary)] font-mono">
|
||||||
{(c.ports || []).map((p: JsonData) => p.containerPort || p.port).join(', ') || '-'}
|
{(c.ports || []).map((p: JsonData) => p.containerPort || p.port).join(', ') || '-'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -662,7 +662,8 @@
|
|||||||
"readWrite": "Read Write",
|
"readWrite": "Read Write",
|
||||||
"manageAll": "Manage All",
|
"manageAll": "Manage All",
|
||||||
"createNew": "Create New",
|
"createNew": "Create New",
|
||||||
"saveSuccess": "Saved successfully"
|
"saveSuccess": "Saved successfully",
|
||||||
|
"daysSuffix": "days"
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"aiAgentCli": "Agent CLI",
|
"aiAgentCli": "Agent CLI",
|
||||||
@@ -2655,7 +2656,8 @@
|
|||||||
"tokenPlaceholder": "Paste Service Account Token...",
|
"tokenPlaceholder": "Paste Service Account Token...",
|
||||||
"tokenConfigured": "Configured, enter new value to override...",
|
"tokenConfigured": "Configured, enter new value to override...",
|
||||||
"addTitle": "Add Cluster",
|
"addTitle": "Add Cluster",
|
||||||
"editTitle": "Edit Cluster"
|
"editTitle": "Edit Cluster",
|
||||||
|
"codeRule": "Only English letters, numbers, and hyphens(-) allowed. Cannot start or end with a hyphen. Serves as cluster unique identifier."
|
||||||
},
|
},
|
||||||
"clusterOverview": {
|
"clusterOverview": {
|
||||||
"nodeCount": "Nodes",
|
"nodeCount": "Nodes",
|
||||||
@@ -3205,7 +3207,8 @@
|
|||||||
"notReady": "Not Ready",
|
"notReady": "Not Ready",
|
||||||
"selectCluster": "Select Cluster",
|
"selectCluster": "Select Cluster",
|
||||||
"subtitle": "Kubernetes cluster node status and resources",
|
"subtitle": "Kubernetes cluster node status and resources",
|
||||||
"noData": "No node data"
|
"noData": "No node data",
|
||||||
|
"cores": "cores"
|
||||||
},
|
},
|
||||||
"nsMgmt": {
|
"nsMgmt": {
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
@@ -3216,7 +3219,10 @@
|
|||||||
"title": "Namespace Management",
|
"title": "Namespace Management",
|
||||||
"quotaLimit": "Quota Limits",
|
"quotaLimit": "Quota Limits",
|
||||||
"nameExample": "e.g. my-app",
|
"nameExample": "e.g. my-app",
|
||||||
"quotaSubtitle": "{{code}} · Resource Quotas & Lifecycle"
|
"quotaSubtitle": "{{code}} · Resource Quotas & Lifecycle",
|
||||||
|
"dnsHint": "Name must comply with DNS-1123 (lowercase letters/numbers/hyphens)",
|
||||||
|
"confirmDeleteDesc": "This action is irreversible. All Deployments/Pods/Services/ConfigMaps will be permanently deleted.",
|
||||||
|
"confirmDelete": "Confirm Delete"
|
||||||
},
|
},
|
||||||
"nsOverview": {
|
"nsOverview": {
|
||||||
"workloadReplicas": "Workload replica management",
|
"workloadReplicas": "Workload replica management",
|
||||||
@@ -3688,7 +3694,9 @@
|
|||||||
"confirmDeletePod": "Confirm Delete Pod",
|
"confirmDeletePod": "Confirm Delete Pod",
|
||||||
"deletePodDesc": "This operation cannot be undone",
|
"deletePodDesc": "This operation cannot be undone",
|
||||||
"image": "Image",
|
"image": "Image",
|
||||||
"deployment": "Deployment"
|
"deployment": "Deployment",
|
||||||
|
"memoryLabel": "Memory",
|
||||||
|
"portsLabel": "Ports"
|
||||||
},
|
},
|
||||||
"workloadView": {
|
"workloadView": {
|
||||||
"restartSent": "Restart command sent",
|
"restartSent": "Restart command sent",
|
||||||
@@ -3740,7 +3748,19 @@
|
|||||||
"podLevel": "Pod Level",
|
"podLevel": "Pod Level",
|
||||||
"podNameLabel": "Pod Name",
|
"podNameLabel": "Pod Name",
|
||||||
"podManagePolicy": "Pod Management Policy",
|
"podManagePolicy": "Pod Management Policy",
|
||||||
"uploadFile": "Upload"
|
"uploadFile": "Upload",
|
||||||
|
"eventsPage": {
|
||||||
|
"reasonLabel": "Reason",
|
||||||
|
"kindLabel": "Kind",
|
||||||
|
"recentWarnings": "Recent Warnings"
|
||||||
|
},
|
||||||
|
"podFiles": {
|
||||||
|
"readError": "Read failed",
|
||||||
|
"uploadError": "Upload failed"
|
||||||
|
},
|
||||||
|
"bundleYaml": {
|
||||||
|
"unsupportedType": "Unsupported resource type: {{kind}} (only Deployment / Service supported)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"monitor": {
|
"monitor": {
|
||||||
"acknowledge": "Acknowledge",
|
"acknowledge": "Acknowledge",
|
||||||
@@ -3808,7 +3828,10 @@
|
|||||||
"alertChannelDialog": {
|
"alertChannelDialog": {
|
||||||
"notTested": "Not Tested",
|
"notTested": "Not Tested",
|
||||||
"title": "Notification Channel Configuration",
|
"title": "Notification Channel Configuration",
|
||||||
"enableChannel": "Enable this channel"
|
"enableChannel": "Enable this channel",
|
||||||
|
"desc": "Manage alert notification channels (DingTalk/WeChat/Email/SMS/Webhook). Reference in alert rules after configuration.",
|
||||||
|
"createNew": "New",
|
||||||
|
"emptyChannels": "No notification channels. Add on the right."
|
||||||
},
|
},
|
||||||
"alertChannelDialog2": {
|
"alertChannelDialog2": {
|
||||||
"editChannel": "Edit Channel",
|
"editChannel": "Edit Channel",
|
||||||
@@ -3901,7 +3924,9 @@
|
|||||||
"alertList": "Alerts",
|
"alertList": "Alerts",
|
||||||
"alertManager": {
|
"alertManager": {
|
||||||
"trendTitle": "Alert Trends",
|
"trendTitle": "Alert Trends",
|
||||||
"last24hStats": "Past 24 hours alert statistics"
|
"last24hStats": "Past 24 hours alert statistics",
|
||||||
|
"notifyConfig": "Notification Config",
|
||||||
|
"createRule": "Create Rule"
|
||||||
},
|
},
|
||||||
"alertMessage": "Message",
|
"alertMessage": "Message",
|
||||||
"alertMgr2": {
|
"alertMgr2": {
|
||||||
@@ -3948,7 +3973,12 @@
|
|||||||
"deleteRule": "Delete Alert Rule",
|
"deleteRule": "Delete Alert Rule",
|
||||||
"deleteConfirm": "Delete this alert rule?",
|
"deleteConfirm": "Delete this alert rule?",
|
||||||
"deleted": "Alert rule deleted",
|
"deleted": "Alert rule deleted",
|
||||||
"condition": "Trigger Condition"
|
"condition": "Trigger Condition",
|
||||||
|
"batchDelete": "Batch Delete",
|
||||||
|
"emptyRules": "No alert rules",
|
||||||
|
"severityCritical": "Critical",
|
||||||
|
"severityWarning": "Warning",
|
||||||
|
"severityInfo": "Info"
|
||||||
},
|
},
|
||||||
"alertSeverity": "Severity",
|
"alertSeverity": "Severity",
|
||||||
"alertSource": "Source",
|
"alertSource": "Source",
|
||||||
@@ -4502,7 +4532,22 @@
|
|||||||
"usedHint": "Used {{value}}",
|
"usedHint": "Used {{value}}",
|
||||||
"clusterNodesHint": "Cluster {{value}} nodes",
|
"clusterNodesHint": "Cluster {{value}} nodes",
|
||||||
"slowQueriesHint": "Slow queries {{value}}",
|
"slowQueriesHint": "Slow queries {{value}}",
|
||||||
"pointCount": "{{min}} — {{max}} · {{count}} pts"
|
"pointCount": "{{min}} — {{max}} · {{count}} pts",
|
||||||
|
"queryCount": "Log Count",
|
||||||
|
"totalCount": "Total",
|
||||||
|
"loadMore": "Load More",
|
||||||
|
"displayFields": "Display Fields",
|
||||||
|
"indexFields": "Indexed Fields",
|
||||||
|
"logQueryHint": "Log queries depend on datasource connections. Platform does not store log data.",
|
||||||
|
"labelBrowser": "Label Browser",
|
||||||
|
"selectedCount": "Selected",
|
||||||
|
"addAlertFromQuery": "Add current query as alert",
|
||||||
|
"emptyLogAlerts": "No log alerts. Click the bell icon in Loki/ES query page to create from current query.",
|
||||||
|
"useDefaultIndex": "Use datasource default",
|
||||||
|
"maxHistory": "Max 50 entries · Local storage",
|
||||||
|
"countSuffix": "entries",
|
||||||
|
"prometheusDs": "Prometheus Datasource",
|
||||||
|
"addDatasource": "Add Datasource"
|
||||||
},
|
},
|
||||||
"logAlertBell": {
|
"logAlertBell": {
|
||||||
"linked": "Alert Policy Linked",
|
"linked": "Alert Policy Linked",
|
||||||
@@ -7832,7 +7877,27 @@
|
|||||||
"deleteUserConfirmDesc": "Delete user \"{{name}}\"?",
|
"deleteUserConfirmDesc": "Delete user \"{{name}}\"?",
|
||||||
"batchDeleteUsersConfirmDesc": "Delete {{count}} selected users? This action cannot be undone.",
|
"batchDeleteUsersConfirmDesc": "Delete {{count}} selected users? This action cannot be undone.",
|
||||||
"deleteCredConfirmDesc": "Delete \"{{name}}\"? This cannot be undone. Servers using this credential will lose connection.",
|
"deleteCredConfirmDesc": "Delete \"{{name}}\"? This cannot be undone. Servers using this credential will lose connection.",
|
||||||
"deleteTermSessionsConfirmDesc": "Delete {{count}} selected terminal session records?"
|
"deleteTermSessionsConfirmDesc": "Delete {{count}} selected terminal session records?",
|
||||||
|
"newUser": "New User",
|
||||||
|
"password": "Password",
|
||||||
|
"local": "Local",
|
||||||
|
"batchImportCsv": "Batch Import Users (CSV)",
|
||||||
|
"csvImportDesc": "Upload a CSV file to batch create users. Download the template first, fill in and upload.",
|
||||||
|
"selectCsvFile": "Select CSV File",
|
||||||
|
"previewData": "Preview",
|
||||||
|
"moreEntries": "{{count}} more entries...",
|
||||||
|
"confirmImport": "Confirm Import ({{count}})",
|
||||||
|
"ldapImportTitle": "Import Users from LDAP",
|
||||||
|
"ldapImportDesc": "Retrieve user list from LDAP server, select users to import",
|
||||||
|
"foundUsers": "Found {{count}} users",
|
||||||
|
"noUserData": "No user data",
|
||||||
|
"selectedItems": "Selected {{selected}} / Total {{total}}",
|
||||||
|
"credentialEmpty": "No credentials. Click \"Add Credential\" to create",
|
||||||
|
"credentialSshKey": "SSH Private Key",
|
||||||
|
"credentialAkSk": "AK/SK (one pair per line, space or comma separated)",
|
||||||
|
"credentialEncryptedHint": "Credentials are encrypted with AES-256-GCM, decrypted only on server side",
|
||||||
|
"permissionAssign": "Permission Assignment",
|
||||||
|
"adminPassword": "Admin Password"
|
||||||
},
|
},
|
||||||
"aiops": {
|
"aiops": {
|
||||||
"activeCount": "{{count}} active",
|
"activeCount": "{{count}} active",
|
||||||
|
|||||||
@@ -662,7 +662,8 @@
|
|||||||
"readWrite": "读写",
|
"readWrite": "读写",
|
||||||
"manageAll": "管理全部",
|
"manageAll": "管理全部",
|
||||||
"createNew": "新建",
|
"createNew": "新建",
|
||||||
"saveSuccess": "保存成功"
|
"saveSuccess": "保存成功",
|
||||||
|
"daysSuffix": "天"
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"aiAgentCli": "Agent CLI",
|
"aiAgentCli": "Agent CLI",
|
||||||
@@ -2655,7 +2656,8 @@
|
|||||||
"tokenPlaceholder": "粘贴 Service Account Token...",
|
"tokenPlaceholder": "粘贴 Service Account Token...",
|
||||||
"tokenConfigured": "已配置,输入新值覆盖...",
|
"tokenConfigured": "已配置,输入新值覆盖...",
|
||||||
"addTitle": "添加集群",
|
"addTitle": "添加集群",
|
||||||
"editTitle": "编辑集群"
|
"editTitle": "编辑集群",
|
||||||
|
"codeRule": "只允许英文、数字和连字符(-),首尾不能是连字符。名称将作为集群唯一标识。"
|
||||||
},
|
},
|
||||||
"clusterOverview": {
|
"clusterOverview": {
|
||||||
"nodeCount": "节点数",
|
"nodeCount": "节点数",
|
||||||
@@ -3205,7 +3207,8 @@
|
|||||||
"notReady": "未就绪",
|
"notReady": "未就绪",
|
||||||
"selectCluster": "选择集群",
|
"selectCluster": "选择集群",
|
||||||
"subtitle": "Kubernetes 集群工作节点状态与资源",
|
"subtitle": "Kubernetes 集群工作节点状态与资源",
|
||||||
"noData": "暂无节点数据"
|
"noData": "暂无节点数据",
|
||||||
|
"cores": "核"
|
||||||
},
|
},
|
||||||
"nsMgmt": {
|
"nsMgmt": {
|
||||||
"status": "状态",
|
"status": "状态",
|
||||||
@@ -3216,7 +3219,10 @@
|
|||||||
"title": "命名空间管理",
|
"title": "命名空间管理",
|
||||||
"quotaLimit": "配额限制",
|
"quotaLimit": "配额限制",
|
||||||
"nameExample": "例如: my-app",
|
"nameExample": "例如: my-app",
|
||||||
"quotaSubtitle": "{{code}} · 资源配额与生命周期管理"
|
"quotaSubtitle": "{{code}} · 资源配额与生命周期管理",
|
||||||
|
"dnsHint": "名称需符合 DNS-1123 标准(小写字母/数字/连字符)",
|
||||||
|
"confirmDeleteDesc": "此操作不可逆,所有 Deployment/Pod/Service/ConfigMap 等资源将被永久删除。",
|
||||||
|
"confirmDelete": "确认删除"
|
||||||
},
|
},
|
||||||
"nsOverview": {
|
"nsOverview": {
|
||||||
"workloadReplicas": "工作负载副本管理",
|
"workloadReplicas": "工作负载副本管理",
|
||||||
@@ -3688,7 +3694,9 @@
|
|||||||
"confirmDeletePod": "确认删除 Pod",
|
"confirmDeletePod": "确认删除 Pod",
|
||||||
"deletePodDesc": "操作不可恢复",
|
"deletePodDesc": "操作不可恢复",
|
||||||
"image": "镜像",
|
"image": "镜像",
|
||||||
"deployment": "Deployment"
|
"deployment": "Deployment",
|
||||||
|
"memoryLabel": "内存",
|
||||||
|
"portsLabel": "端口"
|
||||||
},
|
},
|
||||||
"workloadView": {
|
"workloadView": {
|
||||||
"restartSent": "重启指令已下发",
|
"restartSent": "重启指令已下发",
|
||||||
@@ -3740,7 +3748,19 @@
|
|||||||
"podLevel": "Pod 级别",
|
"podLevel": "Pod 级别",
|
||||||
"podNameLabel": "Pod 名称",
|
"podNameLabel": "Pod 名称",
|
||||||
"podManagePolicy": "Pod 管理策略",
|
"podManagePolicy": "Pod 管理策略",
|
||||||
"uploadFile": "上传"
|
"uploadFile": "上传",
|
||||||
|
"eventsPage": {
|
||||||
|
"reasonLabel": "原因",
|
||||||
|
"kindLabel": "类型",
|
||||||
|
"recentWarnings": "最新告警"
|
||||||
|
},
|
||||||
|
"podFiles": {
|
||||||
|
"readError": "读取失败",
|
||||||
|
"uploadError": "上传失败"
|
||||||
|
},
|
||||||
|
"bundleYaml": {
|
||||||
|
"unsupportedType": "不支持的资源类型: {{kind}}(仅支持 Deployment / Service)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"monitor": {
|
"monitor": {
|
||||||
"acknowledge": "确认告警",
|
"acknowledge": "确认告警",
|
||||||
@@ -3808,7 +3828,10 @@
|
|||||||
"alertChannelDialog": {
|
"alertChannelDialog": {
|
||||||
"notTested": "未测试",
|
"notTested": "未测试",
|
||||||
"title": "通知渠道配置",
|
"title": "通知渠道配置",
|
||||||
"enableChannel": "启用此渠道"
|
"enableChannel": "启用此渠道",
|
||||||
|
"desc": "管理告警通知渠道(钉钉/企业微信/邮件/短信/Webhook),配置后可在告警规则中引用",
|
||||||
|
"createNew": "新建",
|
||||||
|
"emptyChannels": "暂无通知渠道,请在右侧添加"
|
||||||
},
|
},
|
||||||
"alertChannelDialog2": {
|
"alertChannelDialog2": {
|
||||||
"editChannel": "编辑渠道",
|
"editChannel": "编辑渠道",
|
||||||
@@ -3901,7 +3924,9 @@
|
|||||||
"alertList": "告警列表",
|
"alertList": "告警列表",
|
||||||
"alertManager": {
|
"alertManager": {
|
||||||
"trendTitle": "告警趋势",
|
"trendTitle": "告警趋势",
|
||||||
"last24hStats": "过去24小时告警统计"
|
"last24hStats": "过去24小时告警统计",
|
||||||
|
"notifyConfig": "通知配置",
|
||||||
|
"createRule": "新建规则"
|
||||||
},
|
},
|
||||||
"alertMessage": "告警信息",
|
"alertMessage": "告警信息",
|
||||||
"alertMgr2": {
|
"alertMgr2": {
|
||||||
@@ -3948,7 +3973,12 @@
|
|||||||
"deleteRule": "删除告警规则",
|
"deleteRule": "删除告警规则",
|
||||||
"deleteConfirm": "确定删除此告警规则?",
|
"deleteConfirm": "确定删除此告警规则?",
|
||||||
"deleted": "告警规则已删除",
|
"deleted": "告警规则已删除",
|
||||||
"condition": "触发条件"
|
"condition": "触发条件",
|
||||||
|
"batchDelete": "批量删除",
|
||||||
|
"emptyRules": "暂无告警规则",
|
||||||
|
"severityCritical": "严重",
|
||||||
|
"severityWarning": "警告",
|
||||||
|
"severityInfo": "提示"
|
||||||
},
|
},
|
||||||
"alertSeverity": "级别",
|
"alertSeverity": "级别",
|
||||||
"alertSource": "来源",
|
"alertSource": "来源",
|
||||||
@@ -4502,7 +4532,22 @@
|
|||||||
"usedHint": "已用 {{value}}",
|
"usedHint": "已用 {{value}}",
|
||||||
"clusterNodesHint": "集群 {{value}} 节点",
|
"clusterNodesHint": "集群 {{value}} 节点",
|
||||||
"slowQueriesHint": "慢查询 {{value}}",
|
"slowQueriesHint": "慢查询 {{value}}",
|
||||||
"pointCount": "{{min}} — {{max}} · {{count}} 点"
|
"pointCount": "{{min}} — {{max}} · {{count}} 点",
|
||||||
|
"queryCount": "日志条数",
|
||||||
|
"totalCount": "总数",
|
||||||
|
"loadMore": "加载更多",
|
||||||
|
"displayFields": "显示字段",
|
||||||
|
"indexFields": "索引字段",
|
||||||
|
"logQueryHint": "日志查询依赖数据源连接,平台不存储海量日志本体",
|
||||||
|
"labelBrowser": "Label 浏览器",
|
||||||
|
"selectedCount": "已选",
|
||||||
|
"addAlertFromQuery": "将当前查询添加为告警",
|
||||||
|
"emptyLogAlerts": "暂无日志告警。在 Loki/ES 查询页点击右下角「叮当」可从当前查询快速创建。",
|
||||||
|
"useDefaultIndex": "使用数据源默认",
|
||||||
|
"maxHistory": "最多保存 50 条 · 本地存储",
|
||||||
|
"countSuffix": "条",
|
||||||
|
"prometheusDs": "Prometheus 数据源",
|
||||||
|
"addDatasource": "添加数据源"
|
||||||
},
|
},
|
||||||
"logAlertBell": {
|
"logAlertBell": {
|
||||||
"linked": "已关联告警策略",
|
"linked": "已关联告警策略",
|
||||||
@@ -7832,7 +7877,27 @@
|
|||||||
"deleteUserConfirmDesc": "确认删除用户「{{name}}」吗?",
|
"deleteUserConfirmDesc": "确认删除用户「{{name}}」吗?",
|
||||||
"batchDeleteUsersConfirmDesc": "确定删除选中的 {{count}} 个用户吗?此操作不可恢复。",
|
"batchDeleteUsersConfirmDesc": "确定删除选中的 {{count}} 个用户吗?此操作不可恢复。",
|
||||||
"deleteCredConfirmDesc": "确定删除「{{name}}」吗?删除后无法恢复,关联的服务器将无法使用此凭据连接。",
|
"deleteCredConfirmDesc": "确定删除「{{name}}」吗?删除后无法恢复,关联的服务器将无法使用此凭据连接。",
|
||||||
"deleteTermSessionsConfirmDesc": "确认删除选中的 {{count}} 条终端会话记录?"
|
"deleteTermSessionsConfirmDesc": "确认删除选中的 {{count}} 条终端会话记录?",
|
||||||
|
"newUser": "新建用户",
|
||||||
|
"password": "密码",
|
||||||
|
"local": "本地",
|
||||||
|
"batchImportCsv": "批量导入用户(CSV)",
|
||||||
|
"csvImportDesc": "上传 CSV 文件批量创建用户。请先下载模板,按格式填写后上传。",
|
||||||
|
"selectCsvFile": "选择 CSV 文件",
|
||||||
|
"previewData": "预览",
|
||||||
|
"moreEntries": "还有 {{count}} 条...",
|
||||||
|
"confirmImport": "确认导入 ({{count}})",
|
||||||
|
"ldapImportTitle": "从 LDAP 导入用户",
|
||||||
|
"ldapImportDesc": "从 LDAP 服务器检索用户列表,选择需要导入的用户",
|
||||||
|
"foundUsers": "找到 {{count}} 个用户",
|
||||||
|
"noUserData": "暂无用户数据",
|
||||||
|
"selectedItems": "已选择 {{selected}} 项 / 共 {{total}} 项",
|
||||||
|
"credentialEmpty": "暂无凭据,点击「添加凭据」创建",
|
||||||
|
"credentialSshKey": "SSH 私钥",
|
||||||
|
"credentialAkSk": "AK/SK (每行一对,用空格或逗号分隔)",
|
||||||
|
"credentialEncryptedHint": "凭据内容使用 AES-256-GCM 加密存储,仅在服务器端解密使用",
|
||||||
|
"permissionAssign": "权限分配",
|
||||||
|
"adminPassword": "管理员密码"
|
||||||
},
|
},
|
||||||
"aiops": {
|
"aiops": {
|
||||||
"activeCount": "{{count}} 个活跃",
|
"activeCount": "{{count}} 个活跃",
|
||||||
|
|||||||
Reference in new issue
Block a user