refactor(i18n): U42 残余硬编码中文彻底清零 — 33文件54处→0, zh/en 7847→7898对齐
全量 JSX children + toast/confirm + sr-only 描述硬编码中文清零: - Kubernetes模块: UpdateStrategyCard maxSurge/maxUnavailable说明 + IngressCreateForm host域名/Service端口 + ServiceCreateForm 端口配置/selector + DeploymentEditService 无selector/个关联/暂无Service/Ingress + ClusterOverviewPage 核 + KubernetesClusterDialog 已配置 + KubectlTerminal/ResourceVisualEditor/CreateHPADialog/DeploymentEditContainers/Storage + PodInstancesTable/UpdateStrategySelectorCards - AI模块: PredictiveCapacityTab AI深度解读/紧急/警告/7天预测/预计N天 + PredictiveCostTab AI深度解读 + event-handler.ts 高危操作确认toast - Deploy模块: DeployCredentials 启用/禁用 + DeployRBAC 删除角色confirm + WorkspaceTermDialog + CredFormDialog Windows用户 - Monitor模块: AlertRulesTab 删除confirm/分钟 + PrometheusDatasourceManager/LogDatasourcePage 删除confirm + QueryHistoryPanel 条 - System模块: ServerFileBrowser/TerminalDialog/RdpAuditViewer sr-only + SystemManager/CredentialManager/TerminalSessionsTab 删除confirm + SecuritySettingsTab 30分钟/2小时 - Task模块: CronJobViewDialog 次 新增 61 翻译键 (k8s.editAdvanced 6 + k8s.editService 11 + k8s.cluster 2 + k8s.misc 9 + aiops.capacity 9 + aiops.cost 1 + aiops.cli 2 + deploy 4 + monitor 5 + system 10 + task 1 + common 2) tsc -b=0, npm build✓ (17.71s), ESLint=0/43/any=0, go build=0, 17/17 测试通过
This commit is contained in:
1 parent
a7838aaf65
commit
c6e0d6ca57
35 files changed
+217
-104
No files matched your search
@@ -529,6 +529,7 @@ services/api.ts (1324L)
|
|||||||
| U39 | 残余 JSX 属性/模板字面量中文清零(10 文件 14 处→0: DualLineChart subtitle 接收/发送 + NetworkTab 5处 unit="个" + FDUsageCard subtitle 当前 + NamespaceOverviewPage/NamespaceManagementPage subtitle + CreateHPADialog title+text 命名空间 + LogFieldSidebar title 个值 + LiveMonitorDialog title 全屏/退出全屏 + ExecutionHistoryDialog title 成功/失败 + LdapSettingsTab className 成功检查→ldapTestSuccess boolean 状态替代字符串匹配 — 新增 11 翻译键, zh/en 7751→7762 对齐;tsc -b=0, npm build✓ (16.94s), ESLint=0/0/any=0, go build=0, 17/17 测试通过) | P3 | **done** |
|
| U39 | 残余 JSX 属性/模板字面量中文清零(10 文件 14 处→0: DualLineChart subtitle 接收/发送 + NetworkTab 5处 unit="个" + FDUsageCard subtitle 当前 + NamespaceOverviewPage/NamespaceManagementPage subtitle + CreateHPADialog title+text 命名空间 + LogFieldSidebar title 个值 + LiveMonitorDialog title 全屏/退出全屏 + ExecutionHistoryDialog title 成功/失败 + LdapSettingsTab className 成功检查→ldapTestSuccess boolean 状态替代字符串匹配 — 新增 11 翻译键, zh/en 7751→7762 对齐;tsc -b=0, npm build✓ (16.94s), ESLint=0/0/any=0, go build=0, 17/17 测试通过) | P3 | **done** |
|
||||||
| U40 | Monitor + Agent 子组件残余硬编码中文 i18n 补全(14 文件 ~50 处→0: ContextSwitchCard CTX/IRQ/次 + ProcessTable agentWaitData/cpuUsagePercent + FDUsageCard fdHandles + PortMonitorTab 黑名单/白名单/策略配置/暂无端口数据 + PortPolicyDialog 白名单全量上报/黑名单仅上报选中/端口列表/逗号分隔/白名单无需配置/已输入端口 + HostTimeRangePicker 时间范围/自定义/取消/应用 + DualLineChart 接收/发送 (i18n.t→useTranslation hook) + ZoomableAreaChart 暂无数据 + SiteResultsPanel 选择任务/次/可用率/立即拨测/SSL证书预警/到期/剩余/阈值/天 + MiddlewareMonitor Redis单机集群/上次更新/添加平台默认/暂无实例 + SiteMonitor subtitle + SNMPMonitor 标题/采集间隔/IP地址/OID模板/SNMP版本/确认/暂无设备/采集指标/暂无指标 + HealthProbeSection TCP目标地址/TCP端口 + AgentAlerts Agent告警/刷新/未恢复/已恢复/恢复/新建规则/创建第一条规则 — 新增 monitor.lbl 46 语义化翻译键 + agent.alerts 6 键, zh/en 7762→7814 对齐;tsc -b=0, npm build✓ (16.88s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | **done** |
|
| U40 | Monitor + Agent 子组件残余硬编码中文 i18n 补全(14 文件 ~50 处→0: ContextSwitchCard CTX/IRQ/次 + ProcessTable agentWaitData/cpuUsagePercent + FDUsageCard fdHandles + PortMonitorTab 黑名单/白名单/策略配置/暂无端口数据 + PortPolicyDialog 白名单全量上报/黑名单仅上报选中/端口列表/逗号分隔/白名单无需配置/已输入端口 + HostTimeRangePicker 时间范围/自定义/取消/应用 + DualLineChart 接收/发送 (i18n.t→useTranslation hook) + ZoomableAreaChart 暂无数据 + SiteResultsPanel 选择任务/次/可用率/立即拨测/SSL证书预警/到期/剩余/阈值/天 + MiddlewareMonitor Redis单机集群/上次更新/添加平台默认/暂无实例 + SiteMonitor subtitle + SNMPMonitor 标题/采集间隔/IP地址/OID模板/SNMP版本/确认/暂无设备/采集指标/暂无指标 + HealthProbeSection TCP目标地址/TCP端口 + AgentAlerts Agent告警/刷新/未恢复/已恢复/恢复/新建规则/创建第一条规则 — 新增 monitor.lbl 46 语义化翻译键 + agent.alerts 6 键, zh/en 7762→7814 对齐;tsc -b=0, npm build✓ (16.88s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | **done** |
|
||||||
| U41 | i18n 残余硬编码中文清零 — 工具函数 + 审计RDP标签 + AIOps分析 + Monitor残余 + 审批选项(18 文件 ~35 处→0: agent-utils.ts timeAgo 秒前/分钟前/小时前 + utils.ts formatDistanceToNow 分钟前/小时前/天前 + request.ts 响应解析失败 + ActiveSessionsPanel RDP在线会话 + HistorySessionsPanel RDP历史会话/RDP会话共N条 + MetricsExplorer 清除/已选/最近1小时 + HostMonitor 当前主机 + AIAnalysisResult 证据链(useTranslation hook) + capacity-predict.ts 容量预测摘要模板 + ApprovalResourcePage 阿里云/腾讯云/华为云 + ApprovalPermissionPage 堡垒机 + site-monitor/helpers.ts 推荐频率/秒/分钟/小时/天 + site-monitor/analytics.ts 证书剩余/失败/延迟波动 + middleware-monitor/MwTargetChartsPanel 选择实例/已用/集群节点/慢查询 + MwTrendChart 暂无趋势数据 + middleware-monitor/helpers.ts 相对时间 + snmp-monitor/SnmpMetricTrendChart 暂无趋势数据等待采集 + SnmpDeviceChartsPanel 点击设备/可观测/刷新/暂无指标 + host-monitor/utils.ts 图表点数 + PortPolicyDialog 系统进程端口说明 — 新增 common.duration.secAgo/hourAgo/dayAgo + common.selected/responseParseError/rdpActiveSessions/rdpHistorySessions/rdpSessionCount/evidenceChain/last1Hour/currentHost + monitor.lbl 10键 + monitor.siteMonitor 8键 + approval.provider 3键 + approval.permType 1键 + monitor.portPolicyDialog.systemProcessDesc + aiops.capacity.summary 共 34 翻译键, zh/en 7813→7847 对齐;tsc -b=0, npm build✓ (17.31s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | **done** |
|
| U41 | i18n 残余硬编码中文清零 — 工具函数 + 审计RDP标签 + AIOps分析 + Monitor残余 + 审批选项(18 文件 ~35 处→0: agent-utils.ts timeAgo 秒前/分钟前/小时前 + utils.ts formatDistanceToNow 分钟前/小时前/天前 + request.ts 响应解析失败 + ActiveSessionsPanel RDP在线会话 + HistorySessionsPanel RDP历史会话/RDP会话共N条 + MetricsExplorer 清除/已选/最近1小时 + HostMonitor 当前主机 + AIAnalysisResult 证据链(useTranslation hook) + capacity-predict.ts 容量预测摘要模板 + ApprovalResourcePage 阿里云/腾讯云/华为云 + ApprovalPermissionPage 堡垒机 + site-monitor/helpers.ts 推荐频率/秒/分钟/小时/天 + site-monitor/analytics.ts 证书剩余/失败/延迟波动 + middleware-monitor/MwTargetChartsPanel 选择实例/已用/集群节点/慢查询 + MwTrendChart 暂无趋势数据 + middleware-monitor/helpers.ts 相对时间 + snmp-monitor/SnmpMetricTrendChart 暂无趋势数据等待采集 + SnmpDeviceChartsPanel 点击设备/可观测/刷新/暂无指标 + host-monitor/utils.ts 图表点数 + PortPolicyDialog 系统进程端口说明 — 新增 common.duration.secAgo/hourAgo/dayAgo + common.selected/responseParseError/rdpActiveSessions/rdpHistorySessions/rdpSessionCount/evidenceChain/last1Hour/currentHost + monitor.lbl 10键 + monitor.siteMonitor 8键 + approval.provider 3键 + approval.permType 1键 + monitor.portPolicyDialog.systemProcessDesc + aiops.capacity.summary 共 34 翻译键, zh/en 7813→7847 对齐;tsc -b=0, npm build✓ (17.31s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | **done** |
|
||||||
|
| U42 | i18n 残余硬编码中文彻底清零 — 全量 JSX children + toast/confirm + sr-only 描述(33 文件 54 处→0: PredictiveCapacityTab AI深度解读/紧急/警告/7天使用率预测/预计N天/后达到阈值/AI建议 + PredictiveCostTab AI深度解读 + event-handler.ts 高危操作确认 toast + DeployCredentials 启用/禁用 + DeployRBAC 删除角色 confirm + WorkspaceTermDialog 标题 + CredFormDialog Windows用户 + ClusterOverviewPage 核 + DeploymentEditContainers Pod级别 + DeploymentEditService 无selector/个关联/Ingresses应用路由/暂无Service/暂无Ingress/自动高亮 + DeploymentEditStorage 无容器 + KubectlTerminal sr-only + KubernetesClusterDialog 已配置 + ResourceVisualEditor YAML编辑 + CreateHPADialog CPU目标 + UpdateStrategyCard maxSurge/maxUnavailable/revisionHistoryLimit/progressDeadlineSeconds 说明 + IngressCreateForm host域名/Service端口 + ServiceCreateForm 端口配置/个端口/selector自动检测 + PodInstancesTable Pod名称 + UpdateStrategySelectorCards Pod管理策略 + AlertRulesTab 删除confirm/分钟 + PrometheusDatasourceManager 删除confirm + LogDatasourcePage 删除confirm + QueryHistoryPanel 条 + ServerFileBrowser sr-only + TerminalDialog sr-only + CredentialManager 删除confirm + RdpAuditViewer sr-only + SystemManager 删除用户/批量删除 confirm + TerminalSessionsTab 删除confirm + SecuritySettingsTab 30分钟/2小时 + CronJobViewDialog 次 — 新增 k8s.editAdvanced 6键+k8s.editService 11键+k8s.cluster 2键+k8s.clusterDialog 1键+k8s.kubectlTerminalDesc/k8s.rve.yamlEditBtn/k8s.hpa.cpuTarget/k8s.podLevel/k8s.podNameLabel/k8s.podManagePolicy 共 28键 + aiops.capacity 8键+aiops.cost 1键+aiops.cli 2键 + deploy.cred.windowsUser/deploy.workspaceTerminalTitle/deploy.rbac.deleteRoleDesc/deploy.cred.badgeDefault 4键 + monitor.deleteRulesConfirmDesc/deleteDatasourceConfirmDesc/deleteLogDsConfirmDesc/durationMinutes/queryHistory.count 5键 + system.rdpLiveAudit/rdpHistoryReplay/rdpAuditDesc/sshTerminalDesc/sftpFileDesc/sftpFileLabel/deleteUserConfirmDesc/batchDeleteUsersConfirmDesc/deleteCredConfirmDesc/deleteTermSessionsConfirmDesc 10键 + task.cronJob.runCount 1键 + common.minutes30/hours2 2键, zh/en 7847→7898 对齐;tsc -b=0, npm build✓ (17.71s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | **done** |
|
||||||
| U37 | 全量 JSX 文本节点硬编码中文清零(65 文件 151 处→0: MiddlewareMonitor/SiteMonitor/SNMPMonitor/HealthProbeSection/ContextSwitchCard/ProcessTable/PortMonitorTab/MwTargetChartsPanel/MiddlewareDialog/ChartRangeHint/SnmpDeviceChartsPanel/AlertRulesTab/LogClusterPanel/LogDatasourcePage/LogQueryToolbar/LogAlertsPanel/PrometheusDatasourceManager/PodMetricsPage/CapacityPage/NamespaceManagementPage/NamespaceResourcePage/DeploymentEditService/EventsPage/DeploymentDetail/ClusterOverviewPage/DeploymentEditContainers/DeploymentEditStorage/WorkloadViewPage/BottomStatusBar/UpdateStrategySelectorCards/PodInstancesTable/shared-components/UpdateStrategyCard/TolerationsCard/HostSettingsCard/IngressListItem/ServiceListItem/ServiceCreateForm/IngressCreateForm/CreateHPADialog/DeployCredentials/DeployRBAC/UserGroupsManager/BuildNodesManager/DeployTargetFields/PipelineCreateDialog/CredFormDialog/WorkspaceTermDialog/AgentAlerts/AgentRuleDialog/LiveMonitorDialog/RoleFormDialog/CronJobViewDialog/TerminalOutput/AIAnalysisResult/AIPredictiveAnalytics/PredictiveCostTab/PredictiveCapacityTab/ActiveSessionsPanel/HistorySessionsPanel/TerminalDialog/ServerFileBrowser/PodFileBrowser/SiteResultsPanel/SiteProtocolPieChart — 151 JSX 文本节点中文全部替换为 t()/i18n.t() 调用;新增 common.* 98 翻译键 (selectedCount/itemsCount/newValue/namespaceLabel/containerLabel/replicasLabel/minReplicas/maxReplicas/createNamespace/noNamespace/unknownResource/exportYaml/loadTrend/loadCapacity/predicted/threshold/hostSettings/addVolume/addMount/createService/createIngress/editAction/updateStrategy/selectAndLabel/historyVersion/fileBrowser/scale/back/createHpa/allNamespaces/certLabel/observable/deviceList/addDevice/addMonitor/collectNow/addTask/addProbe/restoreFull/contextSwitch/processTop/listenPorts/terminalRealtime/auditWebssh/buildTerminal/fileBrowse/newDir/loadDeployment/notLinked/selectedPerms/none/hasLabel/deleteNamespace/deleteNamespaceWarn/allResources/notFoundDeploy/nodeList/fileLabel/addCustom/newInstanceService/newInstanceIngress/totalContainers/workContainers/loadingEllipsis/volumeClaimTemplates/containerTemplate/passwordOptional/updated/page/perPage/clusterMode/totalLogs/countLabel/percentage/queryTime/addDatasource/newPermission/newEnv/envLabel/displayName/newUserGroup/auditTrace/predictValue/confidence/predictMonthEnd/noCapacityData/securityMode/standardRdp/domainLabel/noRdpActive/noRdpHistory/buffer/matched/podLogs/createHpaTitle/password/events/total);37 文件已有 import i18n→i18n.t() 模式, 2 文件新增 import i18n;zh/en 7640→3526 namespace-flat +98 键对齐;tsc -b=0, npm build✓ (17.96s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | **done** |
|
| U37 | 全量 JSX 文本节点硬编码中文清零(65 文件 151 处→0: MiddlewareMonitor/SiteMonitor/SNMPMonitor/HealthProbeSection/ContextSwitchCard/ProcessTable/PortMonitorTab/MwTargetChartsPanel/MiddlewareDialog/ChartRangeHint/SnmpDeviceChartsPanel/AlertRulesTab/LogClusterPanel/LogDatasourcePage/LogQueryToolbar/LogAlertsPanel/PrometheusDatasourceManager/PodMetricsPage/CapacityPage/NamespaceManagementPage/NamespaceResourcePage/DeploymentEditService/EventsPage/DeploymentDetail/ClusterOverviewPage/DeploymentEditContainers/DeploymentEditStorage/WorkloadViewPage/BottomStatusBar/UpdateStrategySelectorCards/PodInstancesTable/shared-components/UpdateStrategyCard/TolerationsCard/HostSettingsCard/IngressListItem/ServiceListItem/ServiceCreateForm/IngressCreateForm/CreateHPADialog/DeployCredentials/DeployRBAC/UserGroupsManager/BuildNodesManager/DeployTargetFields/PipelineCreateDialog/CredFormDialog/WorkspaceTermDialog/AgentAlerts/AgentRuleDialog/LiveMonitorDialog/RoleFormDialog/CronJobViewDialog/TerminalOutput/AIAnalysisResult/AIPredictiveAnalytics/PredictiveCostTab/PredictiveCapacityTab/ActiveSessionsPanel/HistorySessionsPanel/TerminalDialog/ServerFileBrowser/PodFileBrowser/SiteResultsPanel/SiteProtocolPieChart — 151 JSX 文本节点中文全部替换为 t()/i18n.t() 调用;新增 common.* 98 翻译键 (selectedCount/itemsCount/newValue/namespaceLabel/containerLabel/replicasLabel/minReplicas/maxReplicas/createNamespace/noNamespace/unknownResource/exportYaml/loadTrend/loadCapacity/predicted/threshold/hostSettings/addVolume/addMount/createService/createIngress/editAction/updateStrategy/selectAndLabel/historyVersion/fileBrowser/scale/back/createHpa/allNamespaces/certLabel/observable/deviceList/addDevice/addMonitor/collectNow/addTask/addProbe/restoreFull/contextSwitch/processTop/listenPorts/terminalRealtime/auditWebssh/buildTerminal/fileBrowse/newDir/loadDeployment/notLinked/selectedPerms/none/hasLabel/deleteNamespace/deleteNamespaceWarn/allResources/notFoundDeploy/nodeList/fileLabel/addCustom/newInstanceService/newInstanceIngress/totalContainers/workContainers/loadingEllipsis/volumeClaimTemplates/containerTemplate/passwordOptional/updated/page/perPage/clusterMode/totalLogs/countLabel/percentage/queryTime/addDatasource/newPermission/newEnv/envLabel/displayName/newUserGroup/auditTrace/predictValue/confidence/predictMonthEnd/noCapacityData/securityMode/standardRdp/domainLabel/noRdpActive/noRdpHistory/buffer/matched/podLogs/createHpaTitle/password/events/total);37 文件已有 import i18n→i18n.t() 模式, 2 文件新增 import i18n;zh/en 7640→3526 namespace-flat +98 键对齐;tsc -b=0, npm build✓ (17.96s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | **done** |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ export function PredictiveCapacityTab({
|
|||||||
<div className="p-4 rounded-lg border border-purple-500/30 bg-purple-500/5">
|
<div className="p-4 rounded-lg border border-purple-500/30 bg-purple-500/5">
|
||||||
<div className="flex items-center gap-2 mb-2">
|
<div className="flex items-center gap-2 mb-2">
|
||||||
<Sparkles className="h-4 w-4 dg-text-purple" />
|
<Sparkles className="h-4 w-4 dg-text-purple" />
|
||||||
<span className="text-sm font-medium text-purple-300">AI 深度解读</span>
|
<span className="text-sm font-medium text-purple-300">{t('aiops.capacity.aiInsight')}</span>
|
||||||
</div>
|
</div>
|
||||||
{looksLikeMarkdown(insight) ? (
|
{looksLikeMarkdown(insight) ? (
|
||||||
<AgentMarkdown content={insight} />
|
<AgentMarkdown content={insight} />
|
||||||
@@ -103,24 +103,24 @@ export function PredictiveCapacityTab({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
{forecast.daysUntilThreshold <= 7
|
{forecast.daysUntilThreshold <= 7
|
||||||
? '紧急'
|
? t('aiops.capacity.urgency')
|
||||||
: forecast.daysUntilThreshold <= 14
|
: forecast.daysUntilThreshold <= 14
|
||||||
? '警告'
|
? t('aiops.capacity.warning')
|
||||||
: '正常'}
|
: t('common.normal')}
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<div className="flex items-center justify-between text-sm mb-1">
|
<div className="flex items-center justify-between text-sm mb-1">
|
||||||
<span className="dg-text-secondary">7天使用率预测</span>
|
<span className="dg-text-secondary">{t('aiops.capacity.sevenDayForecast')}</span>
|
||||||
<span className="dg-text-secondary">
|
<span className="dg-text-secondary">
|
||||||
{forecast.daysUntilThreshold >= 999 ? (
|
{forecast.daysUntilThreshold >= 999 ? (
|
||||||
'增长平缓,暂无触顶风险'
|
t('aiops.capacity.noRisk')
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
预计{' '}
|
{t('aiops.capacity.expectedToReach')}{' '}
|
||||||
<span className="dg-text-yellow font-medium">{forecast.daysUntilThreshold}天</span>{' '}
|
<span className="dg-text-yellow font-medium">{forecast.daysUntilThreshold}{t('aiops.capacity.days')}</span>{' '}
|
||||||
后达到阈值
|
{t('aiops.capacity.afterReachThreshold')}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
@@ -147,7 +147,7 @@ export function PredictiveCapacityTab({
|
|||||||
<div className="flex items-start gap-2">
|
<div className="flex items-start gap-2">
|
||||||
<Zap className="h-4 w-4 dg-text-green mt-0.5" />
|
<Zap className="h-4 w-4 dg-text-green mt-0.5" />
|
||||||
<div>
|
<div>
|
||||||
<span className="text-sm dg-text-secondary">AI建议:</span>
|
<span className="text-sm dg-text-secondary">{t('aiops.capacity.aiSuggestion')}:</span>
|
||||||
<p className="text-sm text-[var(--dg-text-secondary)] mt-1">{forecast.recommendation}</p>
|
<p className="text-sm text-[var(--dg-text-secondary)] mt-1">{forecast.recommendation}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ export function PredictiveCostTab({
|
|||||||
<div className="p-4 rounded-lg border border-purple-500/30 bg-purple-500/5">
|
<div className="p-4 rounded-lg border border-purple-500/30 bg-purple-500/5">
|
||||||
<div className="flex items-center gap-2 mb-2">
|
<div className="flex items-center gap-2 mb-2">
|
||||||
<Sparkles className="h-4 w-4 dg-text-purple" />
|
<Sparkles className="h-4 w-4 dg-text-purple" />
|
||||||
<span className="text-sm font-medium text-purple-300">AI 深度解读</span>
|
<span className="text-sm font-medium text-purple-300">{t('aiops.cost.aiInsight')}</span>
|
||||||
</div>
|
</div>
|
||||||
{looksLikeMarkdown(insight) ? (
|
{looksLikeMarkdown(insight) ? (
|
||||||
<AgentMarkdown content={insight} />
|
<AgentMarkdown content={insight} />
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import type { Dispatch, SetStateAction, RefObject } from 'react';
|
|||||||
import type { ChatItem } from '../AgentCLIMessages';
|
import type { ChatItem } from '../AgentCLIMessages';
|
||||||
import type { WsEvent } from '../agent-cli-constants';
|
import type { WsEvent } from '../agent-cli-constants';
|
||||||
import type { ConfirmOptions } from '@/components/ui/confirm-dialog';
|
import type { ConfirmOptions } from '@/components/ui/confirm-dialog';
|
||||||
|
import i18n from '@/i18n';
|
||||||
|
|
||||||
export interface WsEventHandlerDeps {
|
export interface WsEventHandlerDeps {
|
||||||
push: (it: Omit<ChatItem, 'id'>) => void;
|
push: (it: Omit<ChatItem, 'id'>) => void;
|
||||||
@@ -31,10 +32,10 @@ export function createWsEventHandler(deps: WsEventHandlerDeps) {
|
|||||||
// 高危命令确认(后端驱动 → 弹框 → 回传)
|
// 高危命令确认(后端驱动 → 弹框 → 回传)
|
||||||
async function handleConfirm(ev: WsEvent) {
|
async function handleConfirm(ev: WsEvent) {
|
||||||
const ok = await confirm({
|
const ok = await confirm({
|
||||||
title: '⚠️ 确认执行高危操作',
|
title: i18n.t('aiops.cli.confirmHighRiskTitle'),
|
||||||
description: `工具:${ev.tool_name}\n风险:${ev.risk}\n命令:${ev.command || '(无)'}`,
|
description: i18n.t('aiops.cli.confirmHighRiskDesc', { tool: ev.tool_name, risk: ev.risk, command: ev.command || '(无)' }),
|
||||||
confirmText: '确认执行',
|
confirmText: i18n.t('common.confirm'),
|
||||||
cancelText: '拒绝',
|
cancelText: i18n.t('common.cancel'),
|
||||||
variant: 'destructive',
|
variant: 'destructive',
|
||||||
});
|
});
|
||||||
wsRef.current?.send(JSON.stringify({ type: ok ? 'confirm' : 'deny', confirm_id: ev.confirm_id }));
|
wsRef.current?.send(JSON.stringify({ type: ok ? 'confirm' : 'deny', confirm_id: ev.confirm_id }));
|
||||||
|
|||||||
@@ -312,7 +312,7 @@ export default function DeployCredentials() {
|
|||||||
<td className="px-3 py-2"><div className="w-6 h-6 rounded border" style={{ backgroundColor: env.color }} /></td>
|
<td className="px-3 py-2"><div className="w-6 h-6 rounded border" style={{ backgroundColor: env.color }} /></td>
|
||||||
<td className="px-3 py-2 text-[var(--dg-text-secondary)]">{env.sort_order}</td>
|
<td className="px-3 py-2 text-[var(--dg-text-secondary)]">{env.sort_order}</td>
|
||||||
<td className="px-3 py-2">
|
<td className="px-3 py-2">
|
||||||
<Badge className={env.enabled ? 'bg-emerald-500/20 dg-text-green border-emerald-500/30' : 'bg-[var(--dg-bg-active)]/20 dg-text-secondary border-[var(--dg-border)]'}>{env.enabled ? '启用' : '禁用'}</Badge>
|
<Badge className={env.enabled ? 'bg-emerald-500/20 dg-text-green border-emerald-500/30' : 'bg-[var(--dg-bg-active)]/20 dg-text-secondary border-[var(--dg-border)]'}>{env.enabled ? t('common.enable') : t('common.disable')}</Badge>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2 text-right">
|
<td className="px-3 py-2 text-right">
|
||||||
<div className="flex justify-end gap-1">
|
<div className="flex justify-end gap-1">
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ export default function DeployRBAC() {
|
|||||||
const handleDelete = async (role: ItemRole) => {
|
const handleDelete = async (role: ItemRole) => {
|
||||||
const ok = await _confirm({
|
const ok = await _confirm({
|
||||||
title: i18n.t('deploy.rbac.policy.deletePolicy'),
|
title: i18n.t('deploy.rbac.policy.deletePolicy'),
|
||||||
description: `确定删除「${role.name}」?将影响 ${matchCount[role.id]?.length || 0} 个发布任务`,
|
description: i18n.t("deploy.rbac.deleteRoleDesc", { name: role.name, count: matchCount[role.id]?.length || 0 }),
|
||||||
variant: 'destructive',
|
variant: 'destructive',
|
||||||
});
|
});
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ export function WorkspaceTermDialog({
|
|||||||
)}
|
)}
|
||||||
style={fullscreen ? { maxWidth: '100vw', width: '100vw', height: '100vh' } : { maxWidth: '900px', width: '90vw' }}
|
style={fullscreen ? { maxWidth: '100vw', width: '100vw', height: '100vh' } : { maxWidth: '900px', width: '90vw' }}
|
||||||
>
|
>
|
||||||
<DialogTitle className="sr-only">Workspace 终端 #{buildNumber}</DialogTitle>
|
<DialogTitle className="sr-only">{t("deploy.workspaceTerminalTitle", { num: buildNumber })}</DialogTitle>
|
||||||
<DialogDescription className="sr-only">{t("common.buildTerminal")}</DialogDescription>
|
<DialogDescription className="sr-only">{t("common.buildTerminal")}</DialogDescription>
|
||||||
<div className="flex items-center justify-between px-4 py-2 border-b border-[var(--dg-border)]">
|
<div className="flex items-center justify-between px-4 py-2 border-b border-[var(--dg-border)]">
|
||||||
<div className="flex items-center gap-2 text-sm min-w-0">
|
<div className="flex items-center gap-2 text-sm min-w-0">
|
||||||
|
|||||||
@@ -292,7 +292,7 @@ export function CredFormDialog({ open, onClose, onSaved, editData }: CredFormDia
|
|||||||
{secretType === 'rdp' && (
|
{secretType === 'rdp' && (
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<Label className="text-[var(--dg-text-secondary)] text-xs">Windows 用户 <span className="dg-text-red">*</span></Label>
|
<Label className="text-[var(--dg-text-secondary)] text-xs">{t("deploy.cred.windowsUser")} <span className="dg-text-red">*</span></Label>
|
||||||
<Input value={rdpUsername} onChange={e => setRdpUsername(e.target.value)} placeholder="Administrator"
|
<Input value={rdpUsername} onChange={e => setRdpUsername(e.target.value)} placeholder="Administrator"
|
||||||
className="bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]" />
|
className="bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ export default function ClusterOverviewPage() {
|
|||||||
<span className="text-[var(--dg-text-secondary)]">{cpuPct.toFixed(0)}%</span>
|
<span className="text-[var(--dg-text-secondary)]">{cpuPct.toFixed(0)}%</span>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<span className="text-[var(--dg-text-muted)]">{cpuCores} 核</span>
|
<span className="text-[var(--dg-text-muted)]">{cpuCores} {i18n.t("k8s.cluster.cpuCores", { count: cpuCores })}</span>
|
||||||
)}
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="text-xs">
|
<TableCell className="text-xs">
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ export function DeploymentEditContainers({ clusterCode, namespace, deploymentNam
|
|||||||
<CardTitle className="text-sm text-[var(--dg-text-primary)] flex items-center gap-2">
|
<CardTitle className="text-sm text-[var(--dg-text-primary)] flex items-center gap-2">
|
||||||
<KeyRound className="h-4 w-4 dg-text-yellow" />
|
<KeyRound className="h-4 w-4 dg-text-yellow" />
|
||||||
镜像拉取凭证 (imagePullSecrets)
|
镜像拉取凭证 (imagePullSecrets)
|
||||||
<Badge variant="outline" className="border-[var(--dg-border)] dg-text-muted text-[10px]">Pod 级别</Badge>
|
<Badge variant="outline" className="border-[var(--dg-border)] dg-text-muted text-[10px]">{i18n.t('k8s.podLevel')}</Badge>
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="pt-0 space-y-2">
|
<CardContent className="pt-0 space-y-2">
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ export function DeploymentEditService({ clusterCode, namespace, deploymentName,
|
|||||||
<code key={k} className="bg-[var(--dg-bg-tertiary)] px-1.5 py-0.5 rounded text-[var(--dg-text-secondary)] text-[11px]">{k}={v}</code>
|
<code key={k} className="bg-[var(--dg-bg-tertiary)] px-1.5 py-0.5 rounded text-[var(--dg-text-secondary)] text-[11px]">{k}={v}</code>
|
||||||
))}
|
))}
|
||||||
{Object.keys(selectorLabels).length === 0 && (
|
{Object.keys(selectorLabels).length === 0 && (
|
||||||
<span className="dg-text-muted italic">(无 selector)</span>
|
<span className="dg-text-muted italic">{i18n.t('k8s.editService.noSelector')}</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Button size="sm" variant="ghost" className="h-6 ml-auto text-xs dg-text-secondary" onClick={load}>
|
<Button size="sm" variant="ghost" className="h-6 ml-auto text-xs dg-text-secondary" onClick={load}>
|
||||||
@@ -279,7 +279,7 @@ export function DeploymentEditService({ clusterCode, namespace, deploymentName,
|
|||||||
<CardTitle className="text-sm text-[var(--dg-text-primary)] flex items-center gap-2">
|
<CardTitle className="text-sm text-[var(--dg-text-primary)] flex items-center gap-2">
|
||||||
<Network className="h-4 w-4 dg-text-blue" />
|
<Network className="h-4 w-4 dg-text-blue" />
|
||||||
Services
|
Services
|
||||||
<Badge variant="outline" className="border-[var(--dg-border)] dg-text-secondary">{matchedSvcs.length} 个关联</Badge>
|
<Badge variant="outline" className="border-[var(--dg-border)] dg-text-secondary">{i18n.t('k8s.editService.svcLinked', { count: matchedSvcs.length })}</Badge>
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
<Button size="sm" variant="outline" className="h-7 border-[var(--dg-border)] text-[var(--dg-text-secondary)] text-xs"
|
<Button size="sm" variant="outline" className="h-7 border-[var(--dg-border)] text-[var(--dg-text-secondary)] text-xs"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@@ -295,7 +295,7 @@ export function DeploymentEditService({ clusterCode, namespace, deploymentName,
|
|||||||
{matchedSvcs.length === 0 && showCreate !== 'service' ? (
|
{matchedSvcs.length === 0 && showCreate !== 'service' ? (
|
||||||
<div className="text-center py-6 dg-text-muted text-sm border border-dashed border-[var(--dg-border)] rounded-lg">
|
<div className="text-center py-6 dg-text-muted text-sm border border-dashed border-[var(--dg-border)] rounded-lg">
|
||||||
<Network className="h-8 w-8 mx-auto mb-2 dg-text-muted" />
|
<Network className="h-8 w-8 mx-auto mb-2 dg-text-muted" />
|
||||||
当前命名空间暂无关联 Service
|
{i18n.t('k8s.editService.noSvcInNs')}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
@@ -330,7 +330,7 @@ export function DeploymentEditService({ clusterCode, namespace, deploymentName,
|
|||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<CardTitle className="text-sm text-[var(--dg-text-primary)] flex items-center gap-2">
|
<CardTitle className="text-sm text-[var(--dg-text-primary)] flex items-center gap-2">
|
||||||
<GitBranch className="h-4 w-4 dg-text-purple" />
|
<GitBranch className="h-4 w-4 dg-text-purple" />
|
||||||
Ingresses (应用路由)
|
{i18n.t('k8s.editService.ingressesLabel')}
|
||||||
<Badge variant="outline" className="border-[var(--dg-border)] dg-text-secondary">{matchedIngs.length}/{ingresses.length}</Badge>
|
<Badge variant="outline" className="border-[var(--dg-border)] dg-text-secondary">{matchedIngs.length}/{ingresses.length}</Badge>
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
<Button size="sm" variant="outline" className="h-7 border-[var(--dg-border)] text-[var(--dg-text-secondary)] text-xs"
|
<Button size="sm" variant="outline" className="h-7 border-[var(--dg-border)] text-[var(--dg-text-secondary)] text-xs"
|
||||||
@@ -341,13 +341,13 @@ export function DeploymentEditService({ clusterCode, namespace, deploymentName,
|
|||||||
<Plus className="h-3 w-3 mr-1" />{i18n.t("common.createIngress")}
|
<Plus className="h-3 w-3 mr-1" />{i18n.t("common.createIngress")}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-xs dg-text-muted mt-1">backend 指向关联 Service 的 Ingress 自动高亮</p>
|
<p className="text-xs dg-text-muted mt-1">{i18n.t('k8s.editService.ingressAutoHighlight')}</p>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="pt-0">
|
<CardContent className="pt-0">
|
||||||
{ingresses.length === 0 ? (
|
{ingresses.length === 0 ? (
|
||||||
<div className="text-center py-6 dg-text-muted text-sm border border-dashed border-[var(--dg-border)] rounded-lg">
|
<div className="text-center py-6 dg-text-muted text-sm border border-dashed border-[var(--dg-border)] rounded-lg">
|
||||||
<GitBranch className="h-8 w-8 mx-auto mb-2 dg-text-muted" />
|
<GitBranch className="h-8 w-8 mx-auto mb-2 dg-text-muted" />
|
||||||
当前命名空间暂无 Ingress
|
{i18n.t('k8s.editService.noIngInNs')}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ export function DeploymentEditStorage({ clusterCode, namespace, deploymentName,
|
|||||||
onChange={(e) => updateMount(i, mi, { containerName: e.target.value })}
|
onChange={(e) => updateMount(i, mi, { containerName: e.target.value })}
|
||||||
className="h-8 min-w-[140px] max-w-[280px] bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-md text-sm text-[var(--dg-text-primary)] px-2 font-medium truncate"
|
className="h-8 min-w-[140px] max-w-[280px] bg-[var(--dg-bg-tertiary)] border border-[var(--dg-border)] rounded-md text-sm text-[var(--dg-text-primary)] px-2 font-medium truncate"
|
||||||
>
|
>
|
||||||
{containers.length === 0 && <option value="">(无容器)</option>}
|
{containers.length === 0 && <option value="">{i18n.t('k8s.cluster.noContainer')}</option>}
|
||||||
{containers.map((cn) => <option key={cn} value={cn}>{cn}</option>)}
|
{containers.map((cn) => <option key={cn} value={cn}>{cn}</option>)}
|
||||||
</select>
|
</select>
|
||||||
<div className="flex items-center gap-1 bg-[var(--dg-bg-tertiary)] rounded-lg p-0.5 border border-[var(--dg-border)]">
|
<div className="flex items-center gap-1 bg-[var(--dg-bg-tertiary)] rounded-lg p-0.5 border border-[var(--dg-border)]">
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ export function KubectlTerminal({ open, onOpenChange, clusterId, clusterName }:
|
|||||||
style={fullscreen ? { maxWidth: '100vw', width: '100vw', height: '100vh' } : { maxWidth: '900px', width: '90vw' }}
|
style={fullscreen ? { maxWidth: '100vw', width: '100vw', height: '100vh' } : { maxWidth: '900px', width: '90vw' }}
|
||||||
>
|
>
|
||||||
<DialogTitle className="sr-only">kubectl — {clusterName}</DialogTitle>
|
<DialogTitle className="sr-only">kubectl — {clusterName}</DialogTitle>
|
||||||
<DialogDescription className="sr-only">Kubernetes 集群命令行终端</DialogDescription>
|
<DialogDescription className="sr-only">{i18n.t('k8s.kubectlTerminalDesc')}</DialogDescription>
|
||||||
|
|
||||||
{/* 头部 */}
|
{/* 头部 */}
|
||||||
<div className="flex items-center justify-between px-4 py-2 border-b border-[var(--dg-border)]">
|
<div className="flex items-center justify-between px-4 py-2 border-b border-[var(--dg-border)]">
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ export function KubernetesClusterDialog({
|
|||||||
{formData.config_type === 0 ? (
|
{formData.config_type === 0 ? (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label className="text-[var(--dg-text-secondary)]">
|
<Label className="text-[var(--dg-text-secondary)]">
|
||||||
Token {hasToken && <span className="dg-text-green text-xs ml-1">✓ 已配置(留空不修改)</span>}
|
Token {hasToken && <span className="dg-text-green text-xs ml-1">{i18n.t('k8s.clusterDialog.configured')}</span>}
|
||||||
</Label>
|
</Label>
|
||||||
<Textarea
|
<Textarea
|
||||||
value={formData.token}
|
value={formData.token}
|
||||||
@@ -232,7 +232,7 @@ export function KubernetesClusterDialog({
|
|||||||
) : (
|
) : (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label className="text-[var(--dg-text-secondary)]">
|
<Label className="text-[var(--dg-text-secondary)]">
|
||||||
Kubeconfig {hasKubeConfig && <span className="dg-text-green text-xs ml-1">✓ 已配置(留空不修改)</span>}
|
Kubeconfig {hasKubeConfig && <span className="dg-text-green text-xs ml-1">{i18n.t('k8s.clusterDialog.configured')}</span>}
|
||||||
</Label>
|
</Label>
|
||||||
<Textarea
|
<Textarea
|
||||||
value={formData.kube_config}
|
value={formData.kube_config}
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ export function ResourceVisualEditor({ clusterCode, namespace, resource, name, o
|
|||||||
<button
|
<button
|
||||||
className={`px-3 py-1.5 text-xs font-medium transition-colors ${mode === 'yaml' ? 'bg-blue-600 text-white' : 'bg-transparent text-[var(--dg-text-secondary)] hover:bg-[var(--dg-bg-tertiary)]'}`}
|
className={`px-3 py-1.5 text-xs font-medium transition-colors ${mode === 'yaml' ? 'bg-blue-600 text-white' : 'bg-transparent text-[var(--dg-text-secondary)] hover:bg-[var(--dg-bg-tertiary)]'}`}
|
||||||
onClick={() => { if (mode === 'visual') switchToYaml(); else setMode('yaml'); }}
|
onClick={() => { if (mode === 'visual') switchToYaml(); else setMode('yaml'); }}
|
||||||
>YAML 编辑</button>
|
>YAML {i18n.t('k8s.rve.yamlEditBtn')}</button>
|
||||||
</div>
|
</div>
|
||||||
<Button variant="ghost" size="icon" className="h-8 w-8 text-[var(--dg-text-secondary)]" onClick={onClose}><X className="h-4 w-4" /></Button>
|
<Button variant="ghost" size="icon" className="h-8 w-8 text-[var(--dg-text-secondary)]" onClick={onClose}><X className="h-4 w-4" /></Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ export function CreateHPADialog({ clusterCode, namespace, deploymentName, onCrea
|
|||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<Label className="dg-text-secondary text-sm">CPU 目标 (%)</Label>
|
<Label className="dg-text-secondary text-sm">{i18n.t('k8s.hpa.cpuTarget')}</Label>
|
||||||
<Input type="number" value={form.cpuPercent} min={0} max={100}
|
<Input type="number" value={form.cpuPercent} min={0} max={100}
|
||||||
onChange={(e) => setForm({ ...form, cpuPercent: Number(e.target.value) })}
|
onChange={(e) => setForm({ ...form, cpuPercent: Number(e.target.value) })}
|
||||||
className="dg-input mt-1" />
|
className="dg-input mt-1" />
|
||||||
|
|||||||
@@ -40,23 +40,23 @@ export function UpdateStrategyCard({
|
|||||||
<label className="flex items-center gap-1.5 text-xs text-[var(--dg-text-secondary)] cursor-pointer">
|
<label className="flex items-center gap-1.5 text-xs text-[var(--dg-text-secondary)] cursor-pointer">
|
||||||
<input type="radio" checked={strategyType === 'RollingUpdate'} onChange={() => onStrategyTypeChange('RollingUpdate')}
|
<input type="radio" checked={strategyType === 'RollingUpdate'} onChange={() => onStrategyTypeChange('RollingUpdate')}
|
||||||
className="accent-blue-500" />
|
className="accent-blue-500" />
|
||||||
RollingUpdate(滚动更新)
|
{i18n.t('k8s.editAdvanced.rollingUpdateDesc')}
|
||||||
</label>
|
</label>
|
||||||
<label className="flex items-center gap-1.5 text-xs text-[var(--dg-text-secondary)] cursor-pointer">
|
<label className="flex items-center gap-1.5 text-xs text-[var(--dg-text-secondary)] cursor-pointer">
|
||||||
<input type="radio" checked={strategyType === 'Recreate'} onChange={() => onStrategyTypeChange('Recreate')}
|
<input type="radio" checked={strategyType === 'Recreate'} onChange={() => onStrategyTypeChange('Recreate')}
|
||||||
className="accent-blue-500" />
|
className="accent-blue-500" />
|
||||||
Recreate(重建)
|
{i18n.t('k8s.editAdvanced.recreateDesc')}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{strategyType === 'RollingUpdate' && (
|
{strategyType === 'RollingUpdate' && (
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<Label className="dg-text-muted text-xs">maxSurge(整数或百分比,超出期望副本数)</Label>
|
<Label className="dg-text-muted text-xs">{i18n.t('k8s.editAdvanced.maxSurgeHint')}</Label>
|
||||||
<Input value={maxSurge} onChange={e => onMaxSurgeChange(e.target.value)}
|
<Input value={maxSurge} onChange={e => onMaxSurgeChange(e.target.value)}
|
||||||
placeholder="25%" className="h-8 mt-1 dg-input text-sm font-mono" />
|
placeholder="25%" className="h-8 mt-1 dg-input text-sm font-mono" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label className="dg-text-muted text-xs">maxUnavailable(整数或百分比,不可用上限)</Label>
|
<Label className="dg-text-muted text-xs">{i18n.t('k8s.editAdvanced.maxUnavailableHint')}</Label>
|
||||||
<Input value={maxUnavailable} onChange={e => onMaxUnavailableChange(e.target.value)}
|
<Input value={maxUnavailable} onChange={e => onMaxUnavailableChange(e.target.value)}
|
||||||
placeholder="25%" className="h-8 mt-1 dg-input text-sm font-mono" />
|
placeholder="25%" className="h-8 mt-1 dg-input text-sm font-mono" />
|
||||||
</div>
|
</div>
|
||||||
@@ -74,12 +74,12 @@ export function UpdateStrategyCard({
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="pt-0 grid grid-cols-2 gap-3">
|
<CardContent className="pt-0 grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<Label className="dg-text-muted text-xs">revisionHistoryLimit(保留 RS 历史)</Label>
|
<Label className="dg-text-muted text-xs">{i18n.t('k8s.editAdvanced.revisionHistoryLimitHint')}</Label>
|
||||||
<Input type="number" value={revisionHistoryLimit} onChange={e => onRevisionHistoryLimitChange(e.target.value)}
|
<Input type="number" value={revisionHistoryLimit} onChange={e => onRevisionHistoryLimitChange(e.target.value)}
|
||||||
className="h-8 mt-1 dg-input text-sm font-mono" />
|
className="h-8 mt-1 dg-input text-sm font-mono" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label className="dg-text-muted text-xs">progressDeadlineSeconds(升级超时秒数)</Label>
|
<Label className="dg-text-muted text-xs">{i18n.t('k8s.editAdvanced.progressDeadlineSecondsHint')}</Label>
|
||||||
<Input type="number" value={progressDeadlineSeconds} onChange={e => onProgressDeadlineSecondsChange(e.target.value)}
|
<Input type="number" value={progressDeadlineSeconds} onChange={e => onProgressDeadlineSecondsChange(e.target.value)}
|
||||||
className="h-8 mt-1 dg-input text-sm font-mono" />
|
className="h-8 mt-1 dg-input text-sm font-mono" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export function IngressCreateForm({ ingForm, setIngForm, deploymentName, onCance
|
|||||||
className="h-7 mt-0.5 dg-input text-[var(--dg-text-secondary)] text-xs font-mono" />
|
className="h-7 mt-0.5 dg-input text-[var(--dg-text-secondary)] text-xs font-mono" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label className="dg-text-muted text-[11px]">host (域名)</Label>
|
<Label className="dg-text-muted text-[11px]">{i18n.t('k8s.editService.hostDomain')}</Label>
|
||||||
<Input value={ingForm.host} onChange={e => setIngForm(s => ({ ...s, host: e.target.value }))}
|
<Input value={ingForm.host} onChange={e => setIngForm(s => ({ ...s, host: e.target.value }))}
|
||||||
placeholder="app.example.com"
|
placeholder="app.example.com"
|
||||||
className="h-7 mt-0.5 dg-input text-[var(--dg-text-secondary)] text-xs font-mono" />
|
className="h-7 mt-0.5 dg-input text-[var(--dg-text-secondary)] text-xs font-mono" />
|
||||||
@@ -47,7 +47,7 @@ export function IngressCreateForm({ ingForm, setIngForm, deploymentName, onCance
|
|||||||
className="h-7 mt-0.5 dg-input text-[var(--dg-text-secondary)] text-xs font-mono" />
|
className="h-7 mt-0.5 dg-input text-[var(--dg-text-secondary)] text-xs font-mono" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label className="dg-text-muted text-[11px]">Service 端口</Label>
|
<Label className="dg-text-muted text-[11px]">{i18n.t('k8s.editService.servicePortLabel')}</Label>
|
||||||
<Input type="number" value={ingForm.svcPort} onChange={e => setIngForm(s => ({ ...s, svcPort: e.target.value }))}
|
<Input type="number" value={ingForm.svcPort} onChange={e => setIngForm(s => ({ ...s, svcPort: e.target.value }))}
|
||||||
className="h-7 mt-0.5 dg-input text-[var(--dg-text-secondary)] text-xs font-mono" />
|
className="h-7 mt-0.5 dg-input text-[var(--dg-text-secondary)] text-xs font-mono" />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ export function ServiceCreateForm({ svcForm, setSvcForm, selectorLabels, deploym
|
|||||||
{/* 端口列表 */}
|
{/* 端口列表 */}
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label className="dg-text-muted text-[11px]">
|
<Label className="dg-text-muted text-[11px]">
|
||||||
端口配置 <span className="dg-text-muted">({svcForm.ports.length} 个端口)</span>
|
{i18n.t('k8s.editService.portConfig')} <span className="dg-text-muted">({i18n.t('k8s.editService.portCount', { count: svcForm.ports.length })})</span>
|
||||||
</Label>
|
</Label>
|
||||||
{svcForm.ports.map((p, i) => (
|
{svcForm.ports.map((p, i) => (
|
||||||
<div key={i} className="flex items-center gap-1.5 p-2 rounded bg-[var(--dg-bg-tertiary)]/50 border border-[var(--dg-border)]/50">
|
<div key={i} className="flex items-center gap-1.5 p-2 rounded bg-[var(--dg-bg-tertiary)]/50 border border-[var(--dg-border)]/50">
|
||||||
@@ -128,7 +128,7 @@ export function ServiceCreateForm({ svcForm, setSvcForm, selectorLabels, deploym
|
|||||||
|
|
||||||
{/* Selector 预览 */}
|
{/* Selector 预览 */}
|
||||||
<div className="text-[10px] dg-text-muted border-t border-[var(--dg-border)]/50 pt-2">
|
<div className="text-[10px] dg-text-muted border-t border-[var(--dg-border)]/50 pt-2">
|
||||||
<span className="dg-text-muted">selector (自动检测): </span>
|
<span className="dg-text-muted">{i18n.t('k8s.editService.selectorAutoDetect')} </span>
|
||||||
{Object.keys(selectorLabels).length > 0 ? (
|
{Object.keys(selectorLabels).length > 0 ? (
|
||||||
Object.entries(selectorLabels).map(([k, v]) => (
|
Object.entries(selectorLabels).map(([k, v]) => (
|
||||||
<code key={k} className="bg-[var(--dg-bg-tertiary)] px-1 py-0.5 rounded dg-text-secondary ml-1">{k}={v}</code>
|
<code key={k} className="bg-[var(--dg-bg-tertiary)] px-1 py-0.5 rounded dg-text-secondary ml-1">{k}={v}</code>
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import {
|
|||||||
} from '@/components/ui/table';
|
} from '@/components/ui/table';
|
||||||
import { Activity, Terminal, HardDrive } from 'lucide-react';
|
import { Activity, Terminal, HardDrive } from 'lucide-react';
|
||||||
import { statusColor } from '../k8s-yaml-utils';
|
import { statusColor } from '../k8s-yaml-utils';
|
||||||
import type { JsonData } from '@/types/common';
|
|
||||||
import i18n from '@/i18n';
|
import i18n from '@/i18n';
|
||||||
|
import type { JsonData } from '@/types/common';
|
||||||
|
|
||||||
export function PodInstancesTable({
|
export function PodInstancesTable({
|
||||||
pods,
|
pods,
|
||||||
@@ -30,7 +30,7 @@ export function PodInstancesTable({
|
|||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow className="border-[var(--dg-border)] hover:bg-transparent">
|
<TableRow className="border-[var(--dg-border)] hover:bg-transparent">
|
||||||
<TableHead className="text-[var(--dg-text-secondary)]">Pod 名称</TableHead>
|
<TableHead className="text-[var(--dg-text-secondary)]">{i18n.t('k8s.podNameLabel')}</TableHead>
|
||||||
<TableHead className="text-[var(--dg-text-secondary)]"> {i18n.t('system.terminalStatus')} </TableHead>
|
<TableHead className="text-[var(--dg-text-secondary)]"> {i18n.t('system.terminalStatus')} </TableHead>
|
||||||
<TableHead className="text-[var(--dg-text-secondary)]"> {i18n.t('kubernetes.pod.nodeName')} </TableHead>
|
<TableHead className="text-[var(--dg-text-secondary)]"> {i18n.t('kubernetes.pod.nodeName')} </TableHead>
|
||||||
<TableHead className="text-[var(--dg-text-secondary)]">Pod IP</TableHead>
|
<TableHead className="text-[var(--dg-text-secondary)]">Pod IP</TableHead>
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export function UpdateStrategySelectorCards({ stats }: { stats: WorkloadStats })
|
|||||||
)}
|
)}
|
||||||
{isSts && (
|
{isSts && (
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<span className="text-[var(--dg-text-muted)]">Pod 管理策略</span>
|
<span className="text-[var(--dg-text-muted)]">{i18n.t('k8s.podManagePolicy')}</span>
|
||||||
<span className="text-[var(--dg-text-secondary)] font-mono">{spec.podManagementPolicy || 'OrderedReady'}</span>
|
<span className="text-[var(--dg-text-secondary)] font-mono">{spec.podManagementPolicy || 'OrderedReady'}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ export function AlertRulesTab({
|
|||||||
if (selectedIds.length === 0) return;
|
if (selectedIds.length === 0) return;
|
||||||
const ok = await confirm({
|
const ok = await confirm({
|
||||||
title: i18n.t('monitor.alertRulesTab.deleteRule'),
|
title: i18n.t('monitor.alertRulesTab.deleteRule'),
|
||||||
description: `确定删除选中的 ${selectedIds.length} 条告警规则吗?此操作不可撤销。`,
|
description: i18n.t("monitor.deleteRulesConfirmDesc", { count: selectedIds.length }),
|
||||||
confirmText: i18n.t('system.terminalBatchDelete'),
|
confirmText: i18n.t('system.terminalBatchDelete'),
|
||||||
variant: 'destructive',
|
variant: 'destructive',
|
||||||
});
|
});
|
||||||
@@ -194,7 +194,7 @@ export function AlertRulesTab({
|
|||||||
)}
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<span className="text-sm text-[var(--dg-text-secondary)]">{(rule.duration || 0) / 60}分钟</span>
|
<span className="text-sm text-[var(--dg-text-secondary)]">{i18n.t("monitor.durationMinutes", { count: (rule.duration || 0) / 60 })}</span>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
{renderRuleChannels(rule, notifyChannels)}
|
{renderRuleChannels(rule, notifyChannels)}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export default function PrometheusDatasourceManager() {
|
|||||||
const handleDelete = async (ds: PromDS) => {
|
const handleDelete = async (ds: PromDS) => {
|
||||||
const ok = await _confirm({
|
const ok = await _confirm({
|
||||||
title: i18n.t('monitor.deleteDatasource'),
|
title: i18n.t('monitor.deleteDatasource'),
|
||||||
description: `确定删除数据源「${ds.name}」吗?此操作不可撤销。`,
|
description: i18n.t("monitor.deleteDatasourceConfirmDesc", { name: ds.name }),
|
||||||
variant: 'destructive',
|
variant: 'destructive',
|
||||||
});
|
});
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export function LogDatasourcePage() {
|
|||||||
const handleDelete = async (ds: LogDataSource) => {
|
const handleDelete = async (ds: LogDataSource) => {
|
||||||
const ok = await confirm({
|
const ok = await confirm({
|
||||||
title: i18n.t('monitor.deleteDatasource'),
|
title: i18n.t('monitor.deleteDatasource'),
|
||||||
description: `确认删除「${ds.name}」?`,
|
description: i18n.t("monitor.deleteLogDsConfirmDesc", { name: ds.name }),
|
||||||
variant: 'destructive',
|
variant: 'destructive',
|
||||||
confirmText: i18n.t('kubernetes.storage.delete2'),
|
confirmText: i18n.t('kubernetes.storage.delete2'),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ export function QueryHistoryPanel({ visible, onClose, onSelect, onCreateAlert }:
|
|||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="text-[10px]" style={{ color: 'var(--dg-text-muted)' }}>{item.timeRange}</span>
|
<span className="text-[10px]" style={{ color: 'var(--dg-text-muted)' }}>{item.timeRange}</span>
|
||||||
{item.resultCount !== undefined && (
|
{item.resultCount !== undefined && (
|
||||||
<span className="text-[10px]" style={{ color: 'var(--dg-text-muted)' }}>{item.resultCount} 条</span>
|
<span className="text-[10px]" style={{ color: 'var(--dg-text-muted)' }}>{i18n.t("monitor.queryHistory.count", { count: item.resultCount })}</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
|
<div className="flex items-center gap-1 opacity-0 group-hover:opacity-100 transition-opacity">
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ export function ServerFileBrowser({ open, onOpenChange, serverId, serverName }:
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<DialogTitle className="sr-only">{i18n.t("common.fileBrowse")} — {serverName}</DialogTitle>
|
<DialogTitle className="sr-only">{i18n.t("common.fileBrowse")} — {serverName}</DialogTitle>
|
||||||
<DialogDescription className="sr-only">SFTP 文件管理 · 上传 · 下载 · 删除</DialogDescription>
|
<DialogDescription className="sr-only">{i18n.t("system.sftpFileDesc")}</DialogDescription>
|
||||||
|
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="flex items-center justify-between px-4 py-2.5 border-b border-[var(--dg-border)] shrink-0">
|
<div className="flex items-center justify-between px-4 py-2.5 border-b border-[var(--dg-border)] shrink-0">
|
||||||
@@ -173,7 +173,7 @@ export function ServerFileBrowser({ open, onOpenChange, serverId, serverName }:
|
|||||||
<span className="text-[var(--dg-text-primary)] font-medium text-sm truncate">
|
<span className="text-[var(--dg-text-primary)] font-medium text-sm truncate">
|
||||||
{serverName}
|
{serverName}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-[var(--dg-text-muted)] text-xs">· SFTP 文件管理</span>
|
<span className="text-[var(--dg-text-muted)] text-xs">{i18n.t("system.sftpFileLabel")}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ export function TerminalDialog({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<DialogTitle className="sr-only">{t("common.podLogs")} - {serverName}</DialogTitle>
|
<DialogTitle className="sr-only">{t("common.podLogs")} - {serverName}</DialogTitle>
|
||||||
<DialogDescription className="sr-only">SSH 终端连接</DialogDescription>
|
<DialogDescription className="sr-only">{t("system.sshTerminalDesc")}</DialogDescription>
|
||||||
{/* 终端头部 */}
|
{/* 终端头部 */}
|
||||||
<div className="flex items-center justify-between px-4 py-2 border-b border-[var(--dg-border)]">
|
<div className="flex items-center justify-between px-4 py-2 border-b border-[var(--dg-border)]">
|
||||||
<div className="flex items-center gap-2 text-sm">
|
<div className="flex items-center gap-2 text-sm">
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export function CredentialManager() {
|
|||||||
const item = credentials.find(c => c.id === id);
|
const item = credentials.find(c => c.id === id);
|
||||||
const ok = await confirm({
|
const ok = await confirm({
|
||||||
title: t('pipeline.deleteCred'),
|
title: t('pipeline.deleteCred'),
|
||||||
description: `确定删除「${item?.name || id}」吗?删除后无法恢复,关联的服务器将无法使用此凭据连接。`,
|
description: i18n.t("system.deleteCredConfirmDesc", { name: item?.name || id }),
|
||||||
confirmText: t('common.delete'),
|
confirmText: t('common.delete'),
|
||||||
variant: 'destructive',
|
variant: 'destructive',
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { cn } from '@/lib/utils';
|
|||||||
import { getAuthToken, getWsBase } from '@/utils/request';
|
import { getAuthToken, getWsBase } from '@/utils/request';
|
||||||
import { rdpSessionApi } from '@/api';
|
import { rdpSessionApi } from '@/api';
|
||||||
import { Loader2, Maximize2, Minimize2, Pause, Play, RotateCcw, X } from 'lucide-react';
|
import { Loader2, Maximize2, Minimize2, Pause, Play, RotateCcw, X } from 'lucide-react';
|
||||||
|
import i18n from '@/i18n';
|
||||||
|
|
||||||
interface RdpAuditViewerProps {
|
interface RdpAuditViewerProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -237,8 +238,8 @@ export function RdpAuditViewer({ open, onOpenChange, sessionId, mode }: RdpAudit
|
|||||||
)}
|
)}
|
||||||
style={fullscreen ? { maxWidth: '100vw', width: '100vw', height: '100vh' } : { maxWidth: '1120px', width: '94vw' }}
|
style={fullscreen ? { maxWidth: '100vw', width: '100vw', height: '100vh' } : { maxWidth: '1120px', width: '94vw' }}
|
||||||
>
|
>
|
||||||
<DialogTitle className="sr-only">{mode === 'live' ? 'RDP 实时审计' : 'RDP 历史回放'}</DialogTitle>
|
<DialogTitle className="sr-only">{mode === 'live' ? i18n.t('system.rdpLiveAudit') : i18n.t('system.rdpHistoryReplay')}</DialogTitle>
|
||||||
<DialogDescription className="sr-only">Windows RDP 图形会话审计查看</DialogDescription>
|
<DialogDescription className="sr-only">{i18n.t("system.rdpAuditDesc")}</DialogDescription>
|
||||||
<div className="flex items-center justify-between px-4 py-2 border-b border-[var(--dg-border)]">
|
<div className="flex items-center justify-between px-4 py-2 border-b border-[var(--dg-border)]">
|
||||||
<div className="text-sm font-medium text-[var(--dg-text-primary)]">
|
<div className="text-sm font-medium text-[var(--dg-text-primary)]">
|
||||||
{mode === 'live' ? 'RDP 实时审计' : `RDP 历史回放 #${sessionId || ''}`}
|
{mode === 'live' ? 'RDP 实时审计' : `RDP 历史回放 #${sessionId || ''}`}
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ export function SystemManager() {
|
|||||||
const handleDelete = async (user: any) => {
|
const handleDelete = async (user: any) => {
|
||||||
const ok = await confirm({
|
const ok = await confirm({
|
||||||
title: t("system.deleteUser"),
|
title: t("system.deleteUser"),
|
||||||
description: `确认删除用户「${user.nickname || user.username}」吗?`,
|
description: t('system.deleteUserConfirmDesc', { name: user.nickname || user.username }),
|
||||||
confirmText: t("common.delete"),
|
confirmText: t("common.delete"),
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
});
|
});
|
||||||
@@ -228,7 +228,7 @@ export function SystemManager() {
|
|||||||
if (selectedUserIds.length === 0) return;
|
if (selectedUserIds.length === 0) return;
|
||||||
const ok = await confirm({
|
const ok = await confirm({
|
||||||
title: t("system.batchDeleteUsers"),
|
title: t("system.batchDeleteUsers"),
|
||||||
description: `确定删除选中的 ${selectedUserIds.length} 个用户吗?此操作不可恢复。`,
|
description: t("system.batchDeleteUsersConfirmDesc", { count: selectedUserIds.length }),
|
||||||
confirmText: t("system.terminalBatchDelete"),
|
confirmText: t("system.terminalBatchDelete"),
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ export function TerminalSessionsTab() {
|
|||||||
if (selected.size === 0) return;
|
if (selected.size === 0) return;
|
||||||
const ok = await confirm({
|
const ok = await confirm({
|
||||||
title: t('system.terminalBatchDelete'),
|
title: t('system.terminalBatchDelete'),
|
||||||
description: `确认删除选中的 ${selected.size} 条终端会话记录?`,
|
description: t("system.deleteTermSessionsConfirmDesc", { count: selected.size }),
|
||||||
confirmText: t('common.delete'),
|
confirmText: t('common.delete'),
|
||||||
variant: 'destructive',
|
variant: 'destructive',
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -266,11 +266,11 @@ export function SecuritySettingsTab(props: SecuritySettingsTabProps) {
|
|||||||
<SelectItem value="15">
|
<SelectItem value="15">
|
||||||
{t("monitor.traceMgr.min15")}
|
{t("monitor.traceMgr.min15")}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="30">30分钟</SelectItem>
|
<SelectItem value="30">{t("common.minutes30")}</SelectItem>
|
||||||
<SelectItem value="60">
|
<SelectItem value="60">
|
||||||
{t("monitor.traceMgr.hour1")}
|
{t("monitor.traceMgr.hour1")}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
<SelectItem value="120">2小时</SelectItem>
|
<SelectItem value="120">{t("common.hours2")}</SelectItem>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export function CronJobViewDialog({ open, onOpenChange, job }: Props) {
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div className="dg-text-muted mb-0.5">{t("common.totalRun")}</div>
|
<div className="dg-text-muted mb-0.5">{t("common.totalRun")}</div>
|
||||||
<div className="text-[var(--dg-text-primary)] tabular-nums">{job.run_count ?? 0} 次</div>
|
<div className="text-[var(--dg-text-primary)] tabular-nums">{t("task.cronJob.runCount", { count: job.run_count ?? 0 })}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div className="dg-text-muted mb-0.5">{t("common.successFail")}</div>
|
<div className="dg-text-muted mb-0.5">{t("common.successFail")}</div>
|
||||||
|
|||||||
@@ -634,7 +634,9 @@
|
|||||||
"rdpSessionCount": "RDP sessions: {{count}}",
|
"rdpSessionCount": "RDP sessions: {{count}}",
|
||||||
"evidenceChain": "Evidence Chain",
|
"evidenceChain": "Evidence Chain",
|
||||||
"last1Hour": "Last 1 hour",
|
"last1Hour": "Last 1 hour",
|
||||||
"currentHost": "Current host: {{host}}"
|
"currentHost": "Current host: {{host}}",
|
||||||
|
"minutes30": "30 min",
|
||||||
|
"hours2": "2 hours"
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"aiAgentCli": "Agent CLI",
|
"aiAgentCli": "Agent CLI",
|
||||||
@@ -1801,7 +1803,9 @@
|
|||||||
"operationFailed": "Operation failed",
|
"operationFailed": "Operation failed",
|
||||||
"tagsLabel": "Tags"
|
"tagsLabel": "Tags"
|
||||||
},
|
},
|
||||||
"sensitiveWarn": "Please keep sensitive information safe"
|
"sensitiveWarn": "Please keep sensitive information safe",
|
||||||
|
"windowsUser": "Windows User",
|
||||||
|
"badgeDefault": "Default"
|
||||||
},
|
},
|
||||||
"credCol": {
|
"credCol": {
|
||||||
"name": "Credential Name",
|
"name": "Credential Name",
|
||||||
@@ -2162,7 +2166,8 @@
|
|||||||
"noPolicy": "No job permission policies",
|
"noPolicy": "No job permission policies",
|
||||||
"createHint": "After creating a policy, users will automatically get access to matching pipelines via regex"
|
"createHint": "After creating a policy, users will automatically get access to matching pipelines via regex"
|
||||||
},
|
},
|
||||||
"deleteGroupDesc": "Delete \"{{name}}\"? All members and pipeline grants will be removed."
|
"deleteGroupDesc": "Delete \"{{name}}\"? All members and pipeline grants will be removed.",
|
||||||
|
"deleteRoleDesc": "Delete \"{{name}}\"? This will affect {{count}} release tasks"
|
||||||
},
|
},
|
||||||
"rdpPassword": "Windows Password",
|
"rdpPassword": "Windows Password",
|
||||||
"rdpPasswordPlaceholder": "Windows login password",
|
"rdpPasswordPlaceholder": "Windows login password",
|
||||||
@@ -2550,7 +2555,8 @@
|
|||||||
"noVars": "No variables, click \"Add Variable\" to create",
|
"noVars": "No variables, click \"Add Variable\" to create",
|
||||||
"envVar": "Environment Variables",
|
"envVar": "Environment Variables",
|
||||||
"envVarOptional": "Environment Variables (optional)"
|
"envVarOptional": "Environment Variables (optional)"
|
||||||
}
|
},
|
||||||
|
"workspaceTerminalTitle": "Workspace Terminal #{{num}}"
|
||||||
},
|
},
|
||||||
"k8s": {
|
"k8s": {
|
||||||
"actionModal": {
|
"actionModal": {
|
||||||
@@ -2606,11 +2612,13 @@
|
|||||||
"now": "Now",
|
"now": "Now",
|
||||||
"allNamespaces": "All Namespaces",
|
"allNamespaces": "All Namespaces",
|
||||||
"provider": "Provider",
|
"provider": "Provider",
|
||||||
"region": "Region"
|
"region": "Region",
|
||||||
|
"cpuCores": "{{count}} cores",
|
||||||
|
"noContainer": "(no containers)"
|
||||||
},
|
},
|
||||||
"clusterDialog": {
|
"clusterDialog": {
|
||||||
"nameHint": "Only English letters, numbers and hyphens (-) allowed. Cannot start or end with hyphen. Name will be the cluster unique identifier.",
|
"nameHint": "Only English letters, numbers and hyphens (-) allowed. Cannot start or end with hyphen. Name will be the cluster unique identifier.",
|
||||||
"configured": "Configured (leave empty to keep)",
|
"configured": "✓ Configured (leave blank to keep)",
|
||||||
"kubeconfigHint": "API Server address will be auto-parsed after pasting kubeconfig content",
|
"kubeconfigHint": "API Server address will be auto-parsed after pasting kubeconfig content",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"nameRule": "Only letters, digits, and hyphens (-) allowed; cannot start or end with a hyphen",
|
"nameRule": "Only letters, digits, and hyphens (-) allowed; cannot start or end with a hyphen",
|
||||||
@@ -2857,8 +2865,8 @@
|
|||||||
"updateStrategy": "Update Strategy",
|
"updateStrategy": "Update Strategy",
|
||||||
"rollingUpdate": "Rolling Update",
|
"rollingUpdate": "Rolling Update",
|
||||||
"recreate": "Recreate",
|
"recreate": "Recreate",
|
||||||
"maxSurgeHint": "Integer or percentage, exceeds desired replicas",
|
"maxSurgeHint": "maxSurge (integer or percentage, surge above desired)",
|
||||||
"maxUnavailableHint": "Integer or percentage, max unavailable",
|
"maxUnavailableHint": "maxUnavailable (integer or percentage, max unavailable)",
|
||||||
"historyVersions": "History Versions & Progress",
|
"historyVersions": "History Versions & Progress",
|
||||||
"rsHistory": "Retain RS History",
|
"rsHistory": "Retain RS History",
|
||||||
"upgradeTimeout": "Upgrade timeout (seconds)",
|
"upgradeTimeout": "Upgrade timeout (seconds)",
|
||||||
@@ -2879,7 +2887,11 @@
|
|||||||
"secondsPlaceholder": "seconds",
|
"secondsPlaceholder": "seconds",
|
||||||
"maxSurge": "Max Surge",
|
"maxSurge": "Max Surge",
|
||||||
"maxUnavailable": "Max Unavailable",
|
"maxUnavailable": "Max Unavailable",
|
||||||
"strategyLabel": "Update Strategy"
|
"strategyLabel": "Update Strategy",
|
||||||
|
"rollingUpdateDesc": "RollingUpdate (Rolling)",
|
||||||
|
"recreateDesc": "Recreate (Recreate)",
|
||||||
|
"revisionHistoryLimitHint": "revisionHistoryLimit (RS history to retain)",
|
||||||
|
"progressDeadlineSecondsHint": "progressDeadlineSeconds (upgrade timeout seconds)"
|
||||||
},
|
},
|
||||||
"editBasic": {
|
"editBasic": {
|
||||||
"synced": "Synced",
|
"synced": "Synced",
|
||||||
@@ -2960,7 +2972,7 @@
|
|||||||
"edit": "Edit",
|
"edit": "Edit",
|
||||||
"createNew": "Create New Service",
|
"createNew": "Create New Service",
|
||||||
"portConfig": "Port Configuration",
|
"portConfig": "Port Configuration",
|
||||||
"portCount": "ports",
|
"portCount": "{{count}} ports",
|
||||||
"addCustomPort": "Add Custom Port",
|
"addCustomPort": "Add Custom Port",
|
||||||
"autoDetect": "Auto Detect",
|
"autoDetect": "Auto Detect",
|
||||||
"ingresses": "Ingresses (App Routes)",
|
"ingresses": "Ingresses (App Routes)",
|
||||||
@@ -2968,15 +2980,22 @@
|
|||||||
"autoHighlight": "Ingress whose backend points to related Service is auto-highlighted",
|
"autoHighlight": "Ingress whose backend points to related Service is auto-highlighted",
|
||||||
"noRelatedIngress": "No Ingress in current namespace",
|
"noRelatedIngress": "No Ingress in current namespace",
|
||||||
"createNewIngress": "Create New Ingress",
|
"createNewIngress": "Create New Ingress",
|
||||||
"hostDomain": "Host (Domain)",
|
"hostDomain": "host (domain)",
|
||||||
"servicePort": "Service Port",
|
"servicePort": "Service Port",
|
||||||
"noSelector": "(No selector)",
|
"noSelector": "(no selector)",
|
||||||
"confirmDelete": "Confirm Delete",
|
"confirmDelete": "Confirm Delete",
|
||||||
"deleteDesc": "This operation cannot be undone",
|
"deleteDesc": "This operation cannot be undone",
|
||||||
"portName": "Port Name",
|
"portName": "Port Name",
|
||||||
"targetPort": "Target Port",
|
"targetPort": "Target Port",
|
||||||
"protocol": "Protocol",
|
"protocol": "Protocol",
|
||||||
"serviceCreated": "Service created"
|
"serviceCreated": "Service created",
|
||||||
|
"servicePortLabel": "Service Port",
|
||||||
|
"selectorAutoDetect": "selector (auto-detected):",
|
||||||
|
"svcLinked": "{{count}} linked",
|
||||||
|
"ingressAutoHighlight": "Ingresses pointing to linked Services are auto-highlighted",
|
||||||
|
"noSvcInNs": "No linked Services in current namespace",
|
||||||
|
"noIngInNs": "No Ingresses in current namespace",
|
||||||
|
"ingressesLabel": "Ingresses (App Routes)"
|
||||||
},
|
},
|
||||||
"editStorage": {
|
"editStorage": {
|
||||||
"volumes": "Volumes",
|
"volumes": "Volumes",
|
||||||
@@ -3420,7 +3439,8 @@
|
|||||||
"commonExamples": "Common:",
|
"commonExamples": "Common:",
|
||||||
"accessModeRWO": "ReadWriteOnce (Single node read-write)",
|
"accessModeRWO": "ReadWriteOnce (Single node read-write)",
|
||||||
"accessModeROX": "ReadOnlyMany (Multi-node read-only)",
|
"accessModeROX": "ReadOnlyMany (Multi-node read-only)",
|
||||||
"accessModeRWX": "ReadWriteMany (Multi-node read-write)"
|
"accessModeRWX": "ReadWriteMany (Multi-node read-write)",
|
||||||
|
"yamlEditBtn": "YAML Edit"
|
||||||
},
|
},
|
||||||
"scheduling": {
|
"scheduling": {
|
||||||
"mode": {
|
"mode": {
|
||||||
@@ -3689,7 +3709,11 @@
|
|||||||
"download": "Download",
|
"download": "Download",
|
||||||
"copied": "Copied",
|
"copied": "Copied",
|
||||||
"fetchFailed": "Failed to fetch YAML"
|
"fetchFailed": "Failed to fetch YAML"
|
||||||
}
|
},
|
||||||
|
"kubectlTerminalDesc": "Kubernetes cluster command-line terminal",
|
||||||
|
"podLevel": "Pod Level",
|
||||||
|
"podNameLabel": "Pod Name",
|
||||||
|
"podManagePolicy": "Pod Management Policy"
|
||||||
},
|
},
|
||||||
"monitor": {
|
"monitor": {
|
||||||
"acknowledge": "Acknowledge",
|
"acknowledge": "Acknowledge",
|
||||||
@@ -5294,7 +5318,14 @@
|
|||||||
"nextPage": "Next"
|
"nextPage": "Next"
|
||||||
},
|
},
|
||||||
"zookeeper": "ZooKeeper",
|
"zookeeper": "ZooKeeper",
|
||||||
"deleteRuleConfirmDesc": "Delete \"{{name}}\"?"
|
"deleteRuleConfirmDesc": "Delete \"{{name}}\"?",
|
||||||
|
"deleteRulesConfirmDesc": "Delete {{count}} selected alert rules? This action cannot be undone.",
|
||||||
|
"deleteDatasourceConfirmDesc": "Delete datasource \"{{name}}\"? This action cannot be undone.",
|
||||||
|
"deleteLogDsConfirmDesc": "Delete \"{{name}}\"?",
|
||||||
|
"durationMinutes": "{{count}} min",
|
||||||
|
"queryHistory": {
|
||||||
|
"count": "{{count}} entries"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"task": {
|
"task": {
|
||||||
"cronJob": {
|
"cronJob": {
|
||||||
@@ -5372,7 +5403,8 @@
|
|||||||
"batchDeleteConfirm": "Delete {{count}} selected jobs? This cannot be undone.",
|
"batchDeleteConfirm": "Delete {{count}} selected jobs? This cannot be undone.",
|
||||||
"confirmDelete": "Delete \"{{name}}\"? This cannot be undone.",
|
"confirmDelete": "Delete \"{{name}}\"? This cannot be undone.",
|
||||||
"execDuration": "Duration: {{ms}}ms"
|
"execDuration": "Duration: {{ms}}ms"
|
||||||
}
|
},
|
||||||
|
"runCount": "{{count}} times"
|
||||||
},
|
},
|
||||||
"cronJobCol": {
|
"cronJobCol": {
|
||||||
"task": "Task",
|
"task": "Task",
|
||||||
@@ -7763,7 +7795,17 @@
|
|||||||
"liveMonitor": {
|
"liveMonitor": {
|
||||||
"exitFullscreen": "Exit Fullscreen",
|
"exitFullscreen": "Exit Fullscreen",
|
||||||
"fullscreen": "Fullscreen"
|
"fullscreen": "Fullscreen"
|
||||||
}
|
},
|
||||||
|
"rdpLiveAudit": "RDP Live Audit",
|
||||||
|
"rdpHistoryReplay": "RDP History Replay",
|
||||||
|
"rdpAuditDesc": "Windows RDP graphical session audit viewer",
|
||||||
|
"sshTerminalDesc": "SSH terminal connection",
|
||||||
|
"sftpFileDesc": "SFTP file management · upload · download · delete",
|
||||||
|
"sftpFileLabel": "· SFTP file management",
|
||||||
|
"deleteUserConfirmDesc": "Delete user \"{{name}}\"?",
|
||||||
|
"batchDeleteUsersConfirmDesc": "Delete {{count}} selected users? This action cannot be undone.",
|
||||||
|
"deleteCredConfirmDesc": "Delete \"{{name}}\"? This cannot be undone. Servers using this credential will lose connection.",
|
||||||
|
"deleteTermSessionsConfirmDesc": "Delete {{count}} selected terminal session records?"
|
||||||
},
|
},
|
||||||
"aiops": {
|
"aiops": {
|
||||||
"activeCount": "{{count}} active",
|
"activeCount": "{{count}} active",
|
||||||
@@ -7966,12 +8008,20 @@
|
|||||||
"recDisk": "Disk space is running low. Consider expanding storage or cleaning up historical data and logs.",
|
"recDisk": "Disk space is running low. Consider expanding storage or cleaning up historical data and logs.",
|
||||||
"recMonitor": "Recommend continued monitoring of resource usage trends.",
|
"recMonitor": "Recommend continued monitoring of resource usage trends.",
|
||||||
"in24Hours": "In 24 hours",
|
"in24Hours": "In 24 hours",
|
||||||
"noRisk": "Growth is gradual, no threshold breach risk",
|
"noRisk": "Growth is gradual, no threshold risk",
|
||||||
"expertPrompt": "You are an AIOps capacity planning expert. Based on the following server resource capacity forecast data, provide a comprehensive risk assessment and actionable operations recommendations:",
|
"expertPrompt": "You are an AIOps capacity planning expert. Based on the following server resource capacity forecast data, provide a comprehensive risk assessment and actionable operations recommendations:",
|
||||||
"resCpu": "Server CPU Compute",
|
"resCpu": "Server CPU Compute",
|
||||||
"resMemory": "Server Memory",
|
"resMemory": "Server Memory",
|
||||||
"resDisk": "Storage Disk Space",
|
"resDisk": "Storage Disk Space",
|
||||||
"summary": "- {{resource}}: Current {{current}}% → 7-day forecast {{predicted}}% (threshold {{threshold}}%), {{risk}}"
|
"summary": "- {{resource}}: Current {{current}}% → 7-day forecast {{predicted}}% (threshold {{threshold}}%), {{risk}}",
|
||||||
|
"aiInsight": "AI Deep Insight",
|
||||||
|
"urgency": "Critical",
|
||||||
|
"warning": "Warning",
|
||||||
|
"sevenDayForecast": "7-Day Usage Forecast",
|
||||||
|
"expectedToReach": "Expected to",
|
||||||
|
"days": "days",
|
||||||
|
"afterReachThreshold": "until threshold reached",
|
||||||
|
"aiSuggestion": "AI Suggestion"
|
||||||
},
|
},
|
||||||
"capacityPlanPrompt": "Based on the following host resource usage, provide cost optimization and capacity planning advice (identify idle/overloaded hosts; suggest scale-down/scale-up)",
|
"capacityPlanPrompt": "Based on the following host resource usage, provide cost optimization and capacity planning advice (identify idle/overloaded hosts; suggest scale-down/scale-up)",
|
||||||
"capacityPlanning": "Capacity Planning",
|
"capacityPlanning": "Capacity Planning",
|
||||||
@@ -8108,7 +8158,9 @@
|
|||||||
"hint": "Shift+Enter for new line / Enter to send",
|
"hint": "Shift+Enter for new line / Enter to send",
|
||||||
"stop": "Stop",
|
"stop": "Stop",
|
||||||
"execute": "Run"
|
"execute": "Run"
|
||||||
}
|
},
|
||||||
|
"confirmHighRiskTitle": "⚠️ Confirm High-Risk Operation",
|
||||||
|
"confirmHighRiskDesc": "Tool: {{tool}}\nRisk: {{risk}}\nCommand: {{command}}"
|
||||||
},
|
},
|
||||||
"cloudService": "Cloud Services",
|
"cloudService": "Cloud Services",
|
||||||
"codingPlan": "Coding Plan",
|
"codingPlan": "Coding Plan",
|
||||||
@@ -8474,7 +8526,10 @@
|
|||||||
"zhipuGeneral": "Zhipu GLM (General)",
|
"zhipuGeneral": "Zhipu GLM (General)",
|
||||||
"zhipuGetKey": "Register a Zhipu account and enable model services to get an API Key",
|
"zhipuGetKey": "Register a Zhipu account and enable model services to get an API Key",
|
||||||
"zhipuOpenPlatform": "Zhipu Open Platform",
|
"zhipuOpenPlatform": "Zhipu Open Platform",
|
||||||
"reachable": "reachable"
|
"reachable": "reachable",
|
||||||
|
"cost": {
|
||||||
|
"aiInsight": "AI Deep Insight"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"breadcrumb": {
|
"breadcrumb": {
|
||||||
"aiAlertAnalyzer": "Alert Analysis",
|
"aiAlertAnalyzer": "Alert Analysis",
|
||||||
|
|||||||
@@ -634,7 +634,9 @@
|
|||||||
"rdpSessionCount": "RDP 会话共 {{count}} 条",
|
"rdpSessionCount": "RDP 会话共 {{count}} 条",
|
||||||
"evidenceChain": "证据链",
|
"evidenceChain": "证据链",
|
||||||
"last1Hour": "最近 1 小时",
|
"last1Hour": "最近 1 小时",
|
||||||
"currentHost": "当前主机: {{host}}"
|
"currentHost": "当前主机: {{host}}",
|
||||||
|
"minutes30": "30分钟",
|
||||||
|
"hours2": "2小时"
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"aiAgentCli": "Agent CLI",
|
"aiAgentCli": "Agent CLI",
|
||||||
@@ -1801,7 +1803,9 @@
|
|||||||
"operationFailed": "操作失败",
|
"operationFailed": "操作失败",
|
||||||
"tagsLabel": "标签"
|
"tagsLabel": "标签"
|
||||||
},
|
},
|
||||||
"sensitiveWarn": "敏感信息请妥善保管"
|
"sensitiveWarn": "敏感信息请妥善保管",
|
||||||
|
"windowsUser": "Windows 用户",
|
||||||
|
"badgeDefault": "默认"
|
||||||
},
|
},
|
||||||
"credCol": {
|
"credCol": {
|
||||||
"name": "凭据名称",
|
"name": "凭据名称",
|
||||||
@@ -2162,7 +2166,8 @@
|
|||||||
"noPolicy": "暂无 Job 权限策略",
|
"noPolicy": "暂无 Job 权限策略",
|
||||||
"createHint": "创建策略后,用户将按正则自动获得匹配流水线的访问权限"
|
"createHint": "创建策略后,用户将按正则自动获得匹配流水线的访问权限"
|
||||||
},
|
},
|
||||||
"deleteGroupDesc": "确定删除「{{name}}」?所有成员和流水线授权将同时移除。"
|
"deleteGroupDesc": "确定删除「{{name}}」?所有成员和流水线授权将同时移除。",
|
||||||
|
"deleteRoleDesc": "确定删除「{{name}}」?将影响 {{count}} 个发布任务"
|
||||||
},
|
},
|
||||||
"rdpPassword": "Windows 密码",
|
"rdpPassword": "Windows 密码",
|
||||||
"rdpPasswordPlaceholder": "Windows 登录密码",
|
"rdpPasswordPlaceholder": "Windows 登录密码",
|
||||||
@@ -2550,7 +2555,8 @@
|
|||||||
"noVars": "暂无变量,点击\"添加变量\"新增",
|
"noVars": "暂无变量,点击\"添加变量\"新增",
|
||||||
"envVar": "环境变量",
|
"envVar": "环境变量",
|
||||||
"envVarOptional": "环境变量 (可选)"
|
"envVarOptional": "环境变量 (可选)"
|
||||||
}
|
},
|
||||||
|
"workspaceTerminalTitle": "Workspace 终端 #{{num}}"
|
||||||
},
|
},
|
||||||
"k8s": {
|
"k8s": {
|
||||||
"actionModal": {
|
"actionModal": {
|
||||||
@@ -2606,11 +2612,13 @@
|
|||||||
"now": "现在",
|
"now": "现在",
|
||||||
"allNamespaces": "全部命名空间",
|
"allNamespaces": "全部命名空间",
|
||||||
"provider": "提供商",
|
"provider": "提供商",
|
||||||
"region": "区域"
|
"region": "区域",
|
||||||
|
"cpuCores": "{{count}} 核",
|
||||||
|
"noContainer": "(无容器)"
|
||||||
},
|
},
|
||||||
"clusterDialog": {
|
"clusterDialog": {
|
||||||
"nameHint": "只允许英文、数字和连字符(-),首尾不能是连字符。名称将作为集群唯一标识。",
|
"nameHint": "只允许英文、数字和连字符(-),首尾不能是连字符。名称将作为集群唯一标识。",
|
||||||
"configured": "已配置(留空不修改)",
|
"configured": "✓ 已配置(留空不修改)",
|
||||||
"kubeconfigHint": "粘贴 kubeconfig 内容后将自动解析 API Server 地址",
|
"kubeconfigHint": "粘贴 kubeconfig 内容后将自动解析 API Server 地址",
|
||||||
"cancel": "取消",
|
"cancel": "取消",
|
||||||
"nameRule": "只允许英文、数字和连字符(-),首尾不能是连字符",
|
"nameRule": "只允许英文、数字和连字符(-),首尾不能是连字符",
|
||||||
@@ -2857,8 +2865,8 @@
|
|||||||
"updateStrategy": "更新策略 (Strategy)",
|
"updateStrategy": "更新策略 (Strategy)",
|
||||||
"rollingUpdate": "滚动更新",
|
"rollingUpdate": "滚动更新",
|
||||||
"recreate": "重建",
|
"recreate": "重建",
|
||||||
"maxSurgeHint": "整数或百分比,超出期望副本数",
|
"maxSurgeHint": "maxSurge(整数或百分比,超出期望副本数)",
|
||||||
"maxUnavailableHint": "整数或百分比,不可用上限",
|
"maxUnavailableHint": "maxUnavailable(整数或百分比,不可用上限)",
|
||||||
"historyVersions": "历史版本 & 进度",
|
"historyVersions": "历史版本 & 进度",
|
||||||
"rsHistory": "保留 RS 历史",
|
"rsHistory": "保留 RS 历史",
|
||||||
"upgradeTimeout": "升级超时秒数",
|
"upgradeTimeout": "升级超时秒数",
|
||||||
@@ -2879,7 +2887,11 @@
|
|||||||
"secondsPlaceholder": "秒",
|
"secondsPlaceholder": "秒",
|
||||||
"maxSurge": "最大超出",
|
"maxSurge": "最大超出",
|
||||||
"maxUnavailable": "最大不可用",
|
"maxUnavailable": "最大不可用",
|
||||||
"strategyLabel": "更新策略"
|
"strategyLabel": "更新策略",
|
||||||
|
"rollingUpdateDesc": "RollingUpdate(滚动更新)",
|
||||||
|
"recreateDesc": "Recreate(重建)",
|
||||||
|
"revisionHistoryLimitHint": "revisionHistoryLimit(保留 RS 历史)",
|
||||||
|
"progressDeadlineSecondsHint": "progressDeadlineSeconds(升级超时秒数)"
|
||||||
},
|
},
|
||||||
"editBasic": {
|
"editBasic": {
|
||||||
"synced": "已同步",
|
"synced": "已同步",
|
||||||
@@ -2960,7 +2972,7 @@
|
|||||||
"edit": "编辑",
|
"edit": "编辑",
|
||||||
"createNew": "创建新 Service",
|
"createNew": "创建新 Service",
|
||||||
"portConfig": "端口配置",
|
"portConfig": "端口配置",
|
||||||
"portCount": "个端口",
|
"portCount": "{{count}} 个端口",
|
||||||
"addCustomPort": "添加自定义端口",
|
"addCustomPort": "添加自定义端口",
|
||||||
"autoDetect": "自动检测",
|
"autoDetect": "自动检测",
|
||||||
"ingresses": "Ingresses (应用路由)",
|
"ingresses": "Ingresses (应用路由)",
|
||||||
@@ -2976,7 +2988,14 @@
|
|||||||
"portName": "端口名称",
|
"portName": "端口名称",
|
||||||
"targetPort": "目标端口",
|
"targetPort": "目标端口",
|
||||||
"protocol": "协议",
|
"protocol": "协议",
|
||||||
"serviceCreated": "Service 已创建"
|
"serviceCreated": "Service 已创建",
|
||||||
|
"servicePortLabel": "Service 端口",
|
||||||
|
"selectorAutoDetect": "selector (自动检测):",
|
||||||
|
"svcLinked": "{{count}} 个关联",
|
||||||
|
"ingressAutoHighlight": "backend 指向关联 Service 的 Ingress 自动高亮",
|
||||||
|
"noSvcInNs": "当前命名空间暂无关联 Service",
|
||||||
|
"noIngInNs": "当前命名空间暂无 Ingress",
|
||||||
|
"ingressesLabel": "Ingresses (应用路由)"
|
||||||
},
|
},
|
||||||
"editStorage": {
|
"editStorage": {
|
||||||
"volumes": "数据卷",
|
"volumes": "数据卷",
|
||||||
@@ -3420,7 +3439,8 @@
|
|||||||
"commonExamples": "常见:",
|
"commonExamples": "常见:",
|
||||||
"accessModeRWO": "ReadWriteOnce (单节点读写)",
|
"accessModeRWO": "ReadWriteOnce (单节点读写)",
|
||||||
"accessModeROX": "ReadOnlyMany (多节点只读)",
|
"accessModeROX": "ReadOnlyMany (多节点只读)",
|
||||||
"accessModeRWX": "ReadWriteMany (多节点读写)"
|
"accessModeRWX": "ReadWriteMany (多节点读写)",
|
||||||
|
"yamlEditBtn": "YAML 编辑"
|
||||||
},
|
},
|
||||||
"scheduling": {
|
"scheduling": {
|
||||||
"mode": {
|
"mode": {
|
||||||
@@ -3689,7 +3709,11 @@
|
|||||||
"download": "下载",
|
"download": "下载",
|
||||||
"copied": "已复制",
|
"copied": "已复制",
|
||||||
"fetchFailed": "获取YAML失败"
|
"fetchFailed": "获取YAML失败"
|
||||||
}
|
},
|
||||||
|
"kubectlTerminalDesc": "Kubernetes 集群命令行终端",
|
||||||
|
"podLevel": "Pod 级别",
|
||||||
|
"podNameLabel": "Pod 名称",
|
||||||
|
"podManagePolicy": "Pod 管理策略"
|
||||||
},
|
},
|
||||||
"monitor": {
|
"monitor": {
|
||||||
"acknowledge": "确认告警",
|
"acknowledge": "确认告警",
|
||||||
@@ -5294,7 +5318,14 @@
|
|||||||
"nextPage": "下一页"
|
"nextPage": "下一页"
|
||||||
},
|
},
|
||||||
"zookeeper": "ZooKeeper",
|
"zookeeper": "ZooKeeper",
|
||||||
"deleteRuleConfirmDesc": "删除「{{name}}」?"
|
"deleteRuleConfirmDesc": "删除「{{name}}」?",
|
||||||
|
"deleteRulesConfirmDesc": "确定删除选中的 {{count}} 条告警规则吗?此操作不可撤销。",
|
||||||
|
"deleteDatasourceConfirmDesc": "确定删除数据源「{{name}}」吗?此操作不可撤销。",
|
||||||
|
"deleteLogDsConfirmDesc": "确认删除「{{name}}」?",
|
||||||
|
"durationMinutes": "{{count}}分钟",
|
||||||
|
"queryHistory": {
|
||||||
|
"count": "{{count}} 条"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"task": {
|
"task": {
|
||||||
"cronJob": {
|
"cronJob": {
|
||||||
@@ -5372,7 +5403,8 @@
|
|||||||
"batchDeleteConfirm": "确定删除选中的 {{count}} 个任务吗?此操作不可恢复。",
|
"batchDeleteConfirm": "确定删除选中的 {{count}} 个任务吗?此操作不可恢复。",
|
||||||
"confirmDelete": "确定删除「{{name}}」吗?此操作不可恢复。",
|
"confirmDelete": "确定删除「{{name}}」吗?此操作不可恢复。",
|
||||||
"execDuration": "耗时 {{ms}}ms"
|
"execDuration": "耗时 {{ms}}ms"
|
||||||
}
|
},
|
||||||
|
"runCount": "{{count}} 次"
|
||||||
},
|
},
|
||||||
"cronJobCol": {
|
"cronJobCol": {
|
||||||
"task": "任务",
|
"task": "任务",
|
||||||
@@ -7763,7 +7795,17 @@
|
|||||||
"liveMonitor": {
|
"liveMonitor": {
|
||||||
"exitFullscreen": "退出全屏",
|
"exitFullscreen": "退出全屏",
|
||||||
"fullscreen": "全屏"
|
"fullscreen": "全屏"
|
||||||
}
|
},
|
||||||
|
"rdpLiveAudit": "RDP 实时审计",
|
||||||
|
"rdpHistoryReplay": "RDP 历史回放",
|
||||||
|
"rdpAuditDesc": "Windows RDP 图形会话审计查看",
|
||||||
|
"sshTerminalDesc": "SSH 终端连接",
|
||||||
|
"sftpFileDesc": "SFTP 文件管理 · 上传 · 下载 · 删除",
|
||||||
|
"sftpFileLabel": "· SFTP 文件管理",
|
||||||
|
"deleteUserConfirmDesc": "确认删除用户「{{name}}」吗?",
|
||||||
|
"batchDeleteUsersConfirmDesc": "确定删除选中的 {{count}} 个用户吗?此操作不可恢复。",
|
||||||
|
"deleteCredConfirmDesc": "确定删除「{{name}}」吗?删除后无法恢复,关联的服务器将无法使用此凭据连接。",
|
||||||
|
"deleteTermSessionsConfirmDesc": "确认删除选中的 {{count}} 条终端会话记录?"
|
||||||
},
|
},
|
||||||
"aiops": {
|
"aiops": {
|
||||||
"activeCount": "{{count}} 个活跃",
|
"activeCount": "{{count}} 个活跃",
|
||||||
@@ -7971,7 +8013,15 @@
|
|||||||
"resCpu": "服务器CPU算力",
|
"resCpu": "服务器CPU算力",
|
||||||
"resMemory": "服务器内存",
|
"resMemory": "服务器内存",
|
||||||
"resDisk": "存储磁盘空间",
|
"resDisk": "存储磁盘空间",
|
||||||
"summary": "- {{resource}}:当前 {{current}}% → 7天后预测 {{predicted}}%(阈值 {{threshold}}%),{{risk}}"
|
"summary": "- {{resource}}:当前 {{current}}% → 7天后预测 {{predicted}}%(阈值 {{threshold}}%),{{risk}}",
|
||||||
|
"aiInsight": "AI 深度解读",
|
||||||
|
"urgency": "紧急",
|
||||||
|
"warning": "警告",
|
||||||
|
"sevenDayForecast": "7天使用率预测",
|
||||||
|
"expectedToReach": "预计",
|
||||||
|
"days": "天",
|
||||||
|
"afterReachThreshold": "后达到阈值",
|
||||||
|
"aiSuggestion": "AI建议"
|
||||||
},
|
},
|
||||||
"capacityPlanPrompt": "根据以下主机资源使用数据,提供成本优化和容量规划建议(识别闲置/过载主机,给出缩容/扩容建议)",
|
"capacityPlanPrompt": "根据以下主机资源使用数据,提供成本优化和容量规划建议(识别闲置/过载主机,给出缩容/扩容建议)",
|
||||||
"capacityPlanning": "容量规划",
|
"capacityPlanning": "容量规划",
|
||||||
@@ -8108,7 +8158,9 @@
|
|||||||
"hint": "Shift+回车换行 · 回车发送",
|
"hint": "Shift+回车换行 · 回车发送",
|
||||||
"stop": "停止",
|
"stop": "停止",
|
||||||
"execute": "执行"
|
"execute": "执行"
|
||||||
}
|
},
|
||||||
|
"confirmHighRiskTitle": "⚠️ 确认执行高危操作",
|
||||||
|
"confirmHighRiskDesc": "工具:{{tool}}\n风险:{{risk}}\n命令:{{command}}"
|
||||||
},
|
},
|
||||||
"cloudService": "云服务",
|
"cloudService": "云服务",
|
||||||
"codingPlan": "编码套餐 Coding Plan",
|
"codingPlan": "编码套餐 Coding Plan",
|
||||||
@@ -8474,7 +8526,10 @@
|
|||||||
"zhipuGeneral": "智谱 GLM (通用)",
|
"zhipuGeneral": "智谱 GLM (通用)",
|
||||||
"zhipuGetKey": "注册智谱账号并开通模型服务后获取 API Key",
|
"zhipuGetKey": "注册智谱账号并开通模型服务后获取 API Key",
|
||||||
"zhipuOpenPlatform": "智谱开放平台",
|
"zhipuOpenPlatform": "智谱开放平台",
|
||||||
"reachable": "可达"
|
"reachable": "可达",
|
||||||
|
"cost": {
|
||||||
|
"aiInsight": "AI 深度解读"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"breadcrumb": {
|
"breadcrumb": {
|
||||||
"aiAlertAnalyzer": "告警分析",
|
"aiAlertAnalyzer": "告警分析",
|
||||||
|
|||||||
Reference in new issue
Block a user