refactor(i18n): U35 Deploy + Task 模块残余 JSX 硬编码中文清理 — PipelineRunPanel 12处 + CronJobTable 12处 + ExecutionHistoryDialog 10处 + ScrollButtons 2处, 新增 54 翻译键(deploy.runStatus/task.cronJobCol/task.execHistory/deploy.credCol/common.*), zh/en 7565→7616 对齐, tsc -b=0, npm build✓ (17.02s), ESLint=0/43/0, go build=0, 17/17 测试通过
This commit is contained in:
1 parent
0dbb85f5b8
commit
8d64936caf
7 files changed
+163
-43
No files matched your search
+2
-1
@@ -522,7 +522,8 @@ services/api.ts (1324L)
|
||||
| U31 | AIOps Agent CLI 组件 i18n 修复(AgentCLI + AgentCLIToolbar + AgentCLIHistory + AgentCLIEmptyState + ChatInputArea + agent-cli-constants.ts 6 文件 — Q7/Q35 拆分后丢失的 i18n 集成全部修复,新增 `aiops.cli.*` 命名空间 100 翻译键(8 子分类: toolbar/safety/tips/error/info/viewMode/placeholder/history/empty/input),SAFETY_MODES+TIPS_HOST+TIPS_KUBERNETES 常量数组改为 `getSafetyModes(t)`/`getTipsHost(t)`/`getTipsKubernetes(t)` 接收 TFunction 参数的工厂函数,全部 UI 硬编码中文清零,zh/en 7381→7481 +100 键对齐,tsc -b=0,npm build✓ (18.21s),ESLint=0/53/0,go build=0,17/17 测试通过) | P3 | **done** |
|
||||
| U32 | 全量 hash key 清理 + React Hooks 警告修复(151 个 hash-style flat key (s+hex 后缀) 全部重命名为语义化 nested key — monitor 58/kubernetes 42/aiops 17/agent 12/cloud 13/pipeline 6/system 3;58 个源文件 147 处 t()/i18n.t() 调用更新;3 个命名空间冲突修复(monitor.hostMonitor/agent.agentMonitor/aiops.aiAnalysisResult 原 string → .title 子键);React Hooks 警告 53→43 (-10): exhaustive-deps 4→0 + preserve-manual-memoization 5→0 + 变量遮蔽修复(filter(t)→filter(tg));zh/en 7480=7480 完全对齐 0 hash key 残留;tsc -b=0,npm build✓ (17.59s),ESLint=0/43/any=0,go build=0,17/17 测试通过) | P3 | **done** |
|
||||
| U33 | K8s 资源编辑器 + Pod 日志/Metrics i18n 补全(resource-visual-editors/ 5 文件: ConfigMap/Secret/Service/Ingress/PvcEditor 按钮文案+帮助文本+访问模式+IngressClass 提示全部 i18n;pod-logs-viewer/ 3 文件: ControlBar 导出/刷新/实时/停止+LogContentArea 加载中+LogsHeader 标题;PodLogsViewer 6 处错误消息+DialogTitle/Description;PodMetricsPage subtitle+表头+所有命名空间;17 处 toast description 模板字面量中文→i18n.t() 插值 (DeploymentEditAdvanced/Containers/Storage/View/Detail/Service/ResourceVisualEditor/NamespaceResourcePage/ClusterOverviewPage);5 处 confirm description (DeploymentView/EditService/Detail/WorkloadViewPage/MiddlewareMonitor/SiteMonitor/HealthProbeSection);5 处 subtitle 模板字面量 (PodMetricsPage/CapacityPage/EventsPage/KubernetesNodes/ClusterOverviewPage);新增 k8s.rve 14键+k8s.toast 18键+k8s.podMetrics 4键+k8s.podLogs 13键 共 49 翻译键;zh/en 7481→7524 +43 对齐;tsc -b=0,npm build✓ (17.76s),ESLint=0/43/any=0,go build=0,17/17 测试通过) | P3 | **done** |
|
||||
| U34 | System & User 模块 i18n 清理(ProfilePage + ResetPasswordDialog + SystemRolesTab + LdapManagementSection 4 文件 — ProfilePage 从零接入 useTranslation + ResetPasswordDialog 从零接入 useTranslation + SystemRolesTab 权限分组标签(云资源/自动化/审批/审计)+toast+confirm description+角色计数+空状态+权限列表计数+编码标签+尾部文案全部 i18n + LdapManagementSection 验证按钮+根OU标签+创建按钮+导入按钮+编辑用户描述全部 i18n;新增 user.profile.* 14键+user.resetPwd.* 11键+system.* 16键 共 41 翻译键;UI 硬编码中文 ProfilePage 15→0 + ResetPasswordDialog 11→0 + SystemRolesTab 12→0 + LdapManagementSection 8→0;zh/en 7524→7565 +41 对齐;tsc -b=0,npm build✓ (16.05s),ESLint=0/43/any=0,go build=0,17/17 测试通过) | P3 | **done** |
|
||||
| U34 | System & User 模块 i18n 清理(ProfilePage + ResetPasswordDialog + SystemRolesTab + LdapManagementSection 4 文件 — ProfilePage 从零接入 useTranslation + ResetPasswordDialog 从零接入 useTranslation + SystemRolesTab 权限分组标签(云资源/自动化/审批/审计)+toast+confirm description+角色计数+空状态+权限列表计数+编码标签+尾部文案全部 i18n + LdapManagementSection 验证按钮+根OU标签+创建按钮+导入按钮+编辑用户描述全部 i18n;新增 user.profile.* 14键+user.resetPwd.* 11键+system.* 16键 共 41 翻译键;UI 硬编码中文 ProfilePage 15→0 + ResetPasswordDialog 11→0 + SystemRolesTab 12→0 + LdapManagementSection 8→0;zh/en 7524→7565 +41 对齐;tsc -b=0, npm build✓ (16.05s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | **done** |
|
||||
| U35 | Deploy + Task 模块残余 JSX 硬编码中文清理(PipelineRunPanel 12处 + CronJobTable 12处 + ExecutionHistoryDialog 10处 + ScrollButtons 2处 — 新增 deploy.runStatus.* 12键 + task.cronJobCol.* 14键 + task.execHistory.* 14键 + deploy.credCol.* 9键 + common.scrollToTop/scrollToBottom/success/failed/total 5键 共 54 翻译键;zh/en 7565→7616 +51 对齐;tsc -b=0, npm build✓ (17.02s), ESLint=0/43/any=0, go build=0, 17/17 测试通过) | P3 | **done** |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// ScrollButtons.tsx — 浮动滚动按钮(回到顶部/底部),AgentCLI 对话区复用
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { ChevronUp, ChevronDown } from 'lucide-react';
|
||||
import i18n from '@/i18n';
|
||||
|
||||
export interface ScrollButtonsProps {
|
||||
show: boolean;
|
||||
@@ -21,7 +22,7 @@ export default function ScrollButtons({ show, atTop, atBottom, onScrollTop, onSc
|
||||
size="icon"
|
||||
className="h-8 w-8 rounded-full shadow-md border border-[var(--dg-border)] bg-[var(--surface-raised)]/95 opacity-90 hover:opacity-100"
|
||||
onClick={onScrollTop}
|
||||
title="回到顶部"
|
||||
title={i18n.t('common.scrollToTop')}
|
||||
>
|
||||
<ChevronUp className="h-4 w-4" />
|
||||
</Button>
|
||||
@@ -33,7 +34,7 @@ export default function ScrollButtons({ show, atTop, atBottom, onScrollTop, onSc
|
||||
size="icon"
|
||||
className="h-8 w-8 rounded-full shadow-md border border-[var(--dg-border)] bg-[var(--surface-raised)]/95 opacity-90 hover:opacity-100"
|
||||
onClick={onScrollBottom}
|
||||
title="回到底部"
|
||||
title={i18n.t('common.scrollToBottom')}
|
||||
>
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
</Button>
|
||||
|
||||
@@ -74,7 +74,7 @@ function PipelineQueuePanel({ pipeline }: { pipeline: Record<string, unknown> })
|
||||
<span className="font-bold text-[var(--dg-text-primary)]">{running}/{max}</span>
|
||||
{queued > 0 && (
|
||||
<span className="text-[var(--dg-text-secondary)] ml-2">
|
||||
构建队列 <span className="font-bold dg-text-yellow">({queued})</span>
|
||||
{i18n.t('deploy.runStatus.buildQueue')} <span className="font-bold dg-text-yellow">({queued})</span>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
@@ -90,7 +90,7 @@ function PipelineQueuePanel({ pipeline }: { pipeline: Record<string, unknown> })
|
||||
<span className="text-[var(--dg-text-secondary)] opacity-50">{String(run.triggered_by || '-')}</span>
|
||||
</div>
|
||||
<Button variant="ghost" size="sm" className="h-6 text-xs dg-text-red hover:dg-text-red" onClick={() => handleCancel(run.id as number)}>
|
||||
<XCircle className="h-3 w-3 mr-1" />取消
|
||||
<XCircle className="h-3 w-3 mr-1" />{i18n.t('deploy.runStatus.cancel')}
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
@@ -106,7 +106,7 @@ function PipelineQueuePanel({ pipeline }: { pipeline: Record<string, unknown> })
|
||||
<span className="text-[var(--dg-text-muted)] font-mono">Run #{id}</span>
|
||||
</div>
|
||||
<Button variant="ghost" size="sm" className="h-6 text-xs dg-text-red hover:dg-text-red" onClick={() => handleCancel(id)}>
|
||||
<XCircle className="h-3 w-3 mr-1" />取消
|
||||
<XCircle className="h-3 w-3 mr-1" />{i18n.t('deploy.runStatus.cancel')}
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
@@ -163,19 +163,19 @@ export function PipelineRunPanel({ pipeline, pipelineRuns, isLoadingRuns, onStop
|
||||
<td className="px-4 py-2">
|
||||
{r.status === 'success' ? (
|
||||
<Badge className="bg-emerald-500/20 dg-text-green border-emerald-500/30 text-[11px]">
|
||||
<CheckCircle className="h-3 w-3 mr-0.5" />成功
|
||||
<CheckCircle className="h-3 w-3 mr-0.5" />{i18n.t('deploy.runStatus.success')}
|
||||
</Badge>
|
||||
) : r.status === 'failed' ? (
|
||||
<Badge className="bg-red-500/20 dg-text-red border-red-500/30 text-[11px]">
|
||||
<XCircle className="h-3 w-3 mr-0.5" />失败
|
||||
<XCircle className="h-3 w-3 mr-0.5" />{i18n.t('deploy.runStatus.failed')}
|
||||
</Badge>
|
||||
) : r.status === 'running' ? (
|
||||
<Badge className="bg-blue-500/20 dg-text-blue border-blue-500/30 text-[11px]">
|
||||
<Loader2 className="h-3 w-3 animate-spin mr-0.5" />执行中
|
||||
<Loader2 className="h-3 w-3 animate-spin mr-0.5" />{i18n.t('deploy.runStatus.running')}
|
||||
</Badge>
|
||||
) : r.status === 'cancelled' ? (
|
||||
<Badge className="bg-yellow-500/20 dg-text-yellow border-yellow-500/30 text-[11px]">
|
||||
<StopCircle className="h-3 w-3 mr-0.5" />已停止
|
||||
<StopCircle className="h-3 w-3 mr-0.5" />{i18n.t('deploy.runStatus.cancelled')}
|
||||
</Badge>
|
||||
) : (
|
||||
<Badge variant="secondary" className="text-[11px]">{String(r.status)}</Badge>
|
||||
@@ -189,11 +189,11 @@ export function PipelineRunPanel({ pipeline, pipelineRuns, isLoadingRuns, onStop
|
||||
<td className="px-4 py-2 text-right">
|
||||
<div className="flex items-center justify-end gap-1">
|
||||
<Button variant="ghost" size="sm" className="h-7 text-xs dg-text-blue hover:text-blue-300" onClick={() => handleViewLog(r)}>
|
||||
<FileText className="h-3.5 w-3.5 mr-1" />日志
|
||||
<FileText className="h-3.5 w-3.5 mr-1" />{i18n.t('deploy.runStatus.log')}
|
||||
</Button>
|
||||
{(r.status === 'running' || r.status === 'pending') && (
|
||||
<Button variant="ghost" size="sm" className="h-7 text-xs dg-text-red hover:dg-text-red" onClick={() => onStopRun(r.id as number | string)}>
|
||||
<StopCircle className="h-3.5 w-3.5 mr-1" />停止
|
||||
<StopCircle className="h-3.5 w-3.5 mr-1" />{i18n.t('deploy.runStatus.stop')}
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
@@ -208,14 +208,14 @@ export function PipelineRunPanel({ pipeline, pipelineRuns, isLoadingRuns, onStop
|
||||
<DialogContent className="max-w-3xl max-h-[85vh] overflow-y-auto bg-[var(--dg-bg-primary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="flex items-center gap-2">
|
||||
<FileText className="h-5 w-5" />执行日志 #{String(logRun?.build_number ?? logRun?.id ?? '')}
|
||||
<FileText className="h-5 w-5" />{i18n.t('deploy.runStatus.execLog', { number: String(logRun?.build_number ?? logRun?.id ?? '') })}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="space-y-3">
|
||||
<div className="flex flex-wrap gap-3 text-sm text-[var(--dg-text-secondary)]">
|
||||
<span>触发方式: {String(logRun?.triggered_by || 'manual')}</span>
|
||||
<span>分支: {String(logRun?.branch || '-')}</span>
|
||||
<span>耗时: {fmtDuration(logRun?.duration as number | undefined)}</span>
|
||||
<span>{i18n.t('deploy.runStatus.triggerMethod')} {String(logRun?.triggered_by || 'manual')}</span>
|
||||
<span>{i18n.t('deploy.runStatus.branch')} {String(logRun?.branch || '-')}</span>
|
||||
<span>{i18n.t('deploy.runStatus.duration')} {fmtDuration(logRun?.duration as number | undefined)}</span>
|
||||
</div>
|
||||
<div className="bg-[var(--dg-bg-primary)] rounded-md p-3 max-h-[50vh] overflow-y-auto font-mono text-xs">
|
||||
{logs.length === 0 ? (
|
||||
|
||||
@@ -48,14 +48,14 @@ export function CronJobTable({
|
||||
className="border-[var(--dg-border)]"
|
||||
/>
|
||||
</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs min-w-[140px]">任务</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs w-[120px] hidden lg:table-cell">调度</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs w-[88px]">类型</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs w-[72px] hidden sm:table-cell">开关</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs w-[72px]">最近</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs w-[100px] hidden md:table-cell">上次执行</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs w-[96px] hidden md:table-cell">成功率</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs w-[148px] text-right">操作</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs min-w-[140px]">{t('task.cronJobCol.task')}</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs w-[120px] hidden lg:table-cell">{t('task.cronJobCol.schedule')}</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs w-[88px]">{t('task.cronJobCol.type')}</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs w-[72px] hidden sm:table-cell">{t('task.cronJobCol.switch')}</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs w-[72px]">{t('task.cronJobCol.recent')}</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs w-[100px] hidden md:table-cell">{t('task.cronJobCol.lastExec')}</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs w-[96px] hidden md:table-cell">{t('task.cronJobCol.successRate')}</TableHead>
|
||||
<TableHead className="dg-text-secondary text-xs w-[148px] text-right">{t('task.cronJobCol.actions')}</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
@@ -122,7 +122,7 @@ export function CronJobTable({
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-7 w-7 dg-text-green hover:bg-emerald-500/10"
|
||||
title="立即执行"
|
||||
title={t('task.cronJobCol.execNow')}
|
||||
disabled={isExecuting}
|
||||
onClick={() => onExecute(job.id)}
|
||||
>
|
||||
@@ -136,7 +136,7 @@ export function CronJobTable({
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-7 w-7"
|
||||
title="执行历史"
|
||||
title={t('task.cronJobCol.execHistory')}
|
||||
onClick={() => onHistory(job)}
|
||||
>
|
||||
<History className="h-3.5 w-3.5" />
|
||||
@@ -145,7 +145,7 @@ export function CronJobTable({
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-7 w-7"
|
||||
title={job.enabled ? '禁用' : '启用'}
|
||||
title={job.enabled ? t('task.cronJobCol.disable') : t('task.cronJobCol.enable')}
|
||||
onClick={() => onToggle(job.id)}
|
||||
>
|
||||
{job.enabled ? <Pause className="h-3.5 w-3.5" /> : <Play className="h-3.5 w-3.5" />}
|
||||
@@ -155,7 +155,7 @@ export function CronJobTable({
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-7 w-7"
|
||||
title="编辑"
|
||||
title={t('task.cronJobCol.edit')}
|
||||
onClick={() => onEdit(job)}
|
||||
>
|
||||
<Edit className="h-3.5 w-3.5" />
|
||||
@@ -166,7 +166,7 @@ export function CronJobTable({
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-7 w-7"
|
||||
title="删除"
|
||||
title={t('task.cronJobCol.delete')}
|
||||
onClick={() => onDelete(job)}
|
||||
>
|
||||
<Trash2 className="h-3.5 w-3.5 dg-text-red" />
|
||||
|
||||
@@ -118,7 +118,7 @@ export function ExecutionHistoryDialog({
|
||||
[executions, viewingExecId],
|
||||
);
|
||||
|
||||
const title = taskName ? `执行历史 — ${taskName}` : '全部执行历史';
|
||||
const title = taskName ? `${t('task.execHistory.title')} — ${taskName}` : t('task.execHistory.title');
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
@@ -126,7 +126,7 @@ export function ExecutionHistoryDialog({
|
||||
<DialogHeader className="shrink-0">
|
||||
<DialogTitle>{title}</DialogTitle>
|
||||
<DialogDescription className="text-[var(--dg-text-secondary)]">
|
||||
近 7 天趋势与执行日志(最近 100 条)
|
||||
{t('task.execHistory.recentTrend', { defaultValue: '近 7 天趋势与执行日志(最近 100 条)' })}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
@@ -137,7 +137,7 @@ export function ExecutionHistoryDialog({
|
||||
) : executions.length === 0 ? (
|
||||
<div className="flex flex-col items-center justify-center py-16 text-[var(--dg-text-secondary)]">
|
||||
<History className="h-10 w-10 mb-3 opacity-40" />
|
||||
<p className="text-sm">暂无执行记录</p>
|
||||
<p className="text-sm">{t('task.execHistory.noRecords', { defaultValue: '暂无执行记录' })}</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex flex-col gap-4 min-h-0 flex-1 overflow-y-auto mt-1">
|
||||
@@ -146,27 +146,27 @@ export function ExecutionHistoryDialog({
|
||||
<CheckCircle className="h-7 w-7 text-emerald-500 shrink-0" />
|
||||
<div>
|
||||
<div className="text-xl font-semibold text-emerald-500 tabular-nums">{stats.success}</div>
|
||||
<div className="text-[11px] dg-text-secondary">成功 · {stats.successRate}%</div>
|
||||
<div className="text-[11px] dg-text-secondary">{t('common.success', { defaultValue: '成功' })} · {stats.successRate}%</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-lg border border-red-500/20 bg-red-500/5 px-3 py-2.5 flex items-center gap-2.5">
|
||||
<XCircle className="h-7 w-7 text-red-500 shrink-0" />
|
||||
<div>
|
||||
<div className="text-xl font-semibold text-red-500 tabular-nums">{stats.failed}</div>
|
||||
<div className="text-[11px] dg-text-secondary">失败 · {stats.failedRate}%</div>
|
||||
<div className="text-[11px] dg-text-secondary">{t('common.failed', { defaultValue: '失败' })} · {stats.failedRate}%</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="rounded-lg border border-[var(--dg-border)] bg-[var(--dg-bg-secondary)] px-3 py-2.5 flex items-center gap-2.5">
|
||||
<BarChart3 className="h-7 w-7 dg-text-blue shrink-0" />
|
||||
<div>
|
||||
<div className="text-xl font-semibold tabular-nums">{stats.total}</div>
|
||||
<div className="text-[11px] dg-text-secondary">总计</div>
|
||||
<div className="text-[11px] dg-text-secondary">{t('common.total', { defaultValue: '总计' })}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg border border-[var(--dg-border)] bg-[var(--dg-bg-secondary)] px-3 py-3 shrink-0">
|
||||
<div className="text-xs font-medium mb-2 dg-text-secondary">最近 7 天</div>
|
||||
<div className="text-xs font-medium mb-2 dg-text-secondary">{t('task.execHistory.last7days', { defaultValue: '最近 7 天' })}</div>
|
||||
<div className="flex items-end justify-between gap-1.5 h-24">
|
||||
{trend.map((item) => {
|
||||
const heightPct = item.total > 0 ? Math.max((item.total / trendMax) * 100, 12) : 4;
|
||||
@@ -197,10 +197,10 @@ export function ExecutionHistoryDialog({
|
||||
<TableHeader>
|
||||
<TableRow className="border-[var(--dg-border)] bg-[var(--dg-bg-secondary)] hover:bg-[var(--dg-bg-secondary)]">
|
||||
<TableHead className="text-[var(--dg-text-secondary)] text-xs w-8" />
|
||||
{!taskId && <TableHead className="text-[var(--dg-text-secondary)] text-xs">任务</TableHead>}
|
||||
<TableHead className="text-[var(--dg-text-secondary)] text-xs w-[72px]">状态</TableHead>
|
||||
<TableHead className="text-[var(--dg-text-secondary)] text-xs w-[80px]">耗时</TableHead>
|
||||
<TableHead className="text-[var(--dg-text-secondary)] text-xs">执行时间</TableHead>
|
||||
{!taskId && <TableHead className="text-[var(--dg-text-secondary)] text-xs">{t('task.cronJobCol.task')}</TableHead>}
|
||||
<TableHead className="text-[var(--dg-text-secondary)] text-xs w-[72px]">{t('task.execHistory.status')}</TableHead>
|
||||
<TableHead className="text-[var(--dg-text-secondary)] text-xs w-[80px]">{t('task.execHistory.duration')}</TableHead>
|
||||
<TableHead className="text-[var(--dg-text-secondary)] text-xs">{t('task.execHistory.startTime')}</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
@@ -256,7 +256,7 @@ export function ExecutionHistoryDialog({
|
||||
</div>
|
||||
|
||||
{viewingExec && !viewingExec.output && (
|
||||
<p className="text-xs dg-text-muted text-center py-2">该记录无输出日志</p>
|
||||
<p className="text-xs dg-text-muted text-center py-2">{t('task.execHistory.noOutput')}</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -514,7 +514,9 @@
|
||||
"request.tokenExpired": "Session expired, please log in again",
|
||||
"days": "days",
|
||||
"seconds": "sec",
|
||||
"copyManually": "Please manually select and copy"
|
||||
"copyManually": "Please manually select and copy",
|
||||
"scrollToTop": "Scroll to top",
|
||||
"scrollToBottom": "Scroll to bottom"
|
||||
},
|
||||
"menu": {
|
||||
"dashboard": "Dashboard",
|
||||
@@ -2381,6 +2383,31 @@
|
||||
"namePlaceholder": "e.g., Backend Team",
|
||||
"subtitle": "User groups - batch authorize pipeline access",
|
||||
"memberCount": "Total Members"
|
||||
},
|
||||
"runStatus": {
|
||||
"success": "Success",
|
||||
"failed": "Failed",
|
||||
"running": "Running",
|
||||
"cancelled": "Stopped",
|
||||
"cancel": "Cancel",
|
||||
"log": "Log",
|
||||
"stop": "Stop",
|
||||
"execLog": "Execution Log #{{number}}",
|
||||
"triggerMethod": "Trigger:",
|
||||
"branch": "Branch:",
|
||||
"duration": "Duration:",
|
||||
"buildQueue": "Build Queue"
|
||||
},
|
||||
"credCol": {
|
||||
"name": "Credential Name",
|
||||
"type": "Type",
|
||||
"tags": "Tags",
|
||||
"actions": "Actions",
|
||||
"used": "Used",
|
||||
"unused": "Unused",
|
||||
"copyRef": "Copy Reference ID",
|
||||
"testConn": "Test Connection",
|
||||
"noTags": "No tags"
|
||||
}
|
||||
},
|
||||
"k8s": {
|
||||
@@ -5218,6 +5245,38 @@
|
||||
"toastExecConfirm": "Confirm batch execution",
|
||||
"toastExecConfirmDesc": "This will execute the command on {{count}} hosts. Please verify the command is safe:\n\n{{command}}",
|
||||
"noOutput": "(no output)"
|
||||
},
|
||||
"cronJobCol": {
|
||||
"task": "Task",
|
||||
"schedule": "Schedule",
|
||||
"type": "Type",
|
||||
"switch": "Toggle",
|
||||
"recent": "Recent",
|
||||
"lastExec": "Last Run",
|
||||
"successRate": "Success Rate",
|
||||
"actions": "Actions",
|
||||
"execNow": "Execute Now",
|
||||
"execHistory": "Run History",
|
||||
"disable": "Disable",
|
||||
"enable": "Enable",
|
||||
"edit": "Edit",
|
||||
"delete": "Delete"
|
||||
},
|
||||
"execHistory": {
|
||||
"title": "Execution History",
|
||||
"exitCode": "Exit Code",
|
||||
"output": "Output",
|
||||
"duration": "Duration",
|
||||
"startTime": "Start Time",
|
||||
"endTime": "End Time",
|
||||
"target": "Target",
|
||||
"status": "Status",
|
||||
"noOutput": "No output",
|
||||
"copyOutput": "Copy Output",
|
||||
"copied": "Copied to clipboard",
|
||||
"recentTrend": "Last 7 days trends and execution logs (latest 100)",
|
||||
"noRecords": "No execution records",
|
||||
"last7days": "Last 7 days"
|
||||
}
|
||||
},
|
||||
"rbac": {
|
||||
|
||||
@@ -514,7 +514,9 @@
|
||||
"request.tokenExpired": "登录已过期,请重新登录",
|
||||
"days": "天",
|
||||
"seconds": "秒",
|
||||
"copyManually": "请手动选中内容后复制"
|
||||
"copyManually": "请手动选中内容后复制",
|
||||
"scrollToTop": "回到顶部",
|
||||
"scrollToBottom": "回到底部"
|
||||
},
|
||||
"menu": {
|
||||
"dashboard": "仪表盘",
|
||||
@@ -2381,6 +2383,31 @@
|
||||
"namePlaceholder": "例如: 后端开发组",
|
||||
"subtitle": "用户组 — 批量授权流水线访问权限",
|
||||
"memberCount": "成员总数"
|
||||
},
|
||||
"runStatus": {
|
||||
"success": "成功",
|
||||
"failed": "失败",
|
||||
"running": "执行中",
|
||||
"cancelled": "已停止",
|
||||
"cancel": "取消",
|
||||
"log": "日志",
|
||||
"stop": "停止",
|
||||
"execLog": "执行日志 #{{number}}",
|
||||
"triggerMethod": "触发方式:",
|
||||
"branch": "分支:",
|
||||
"duration": "耗时:",
|
||||
"buildQueue": "构建队列"
|
||||
},
|
||||
"credCol": {
|
||||
"name": "凭据名称",
|
||||
"type": "类型",
|
||||
"tags": "标签",
|
||||
"actions": "操作",
|
||||
"used": "已使用",
|
||||
"unused": "未使用",
|
||||
"copyRef": "复制引用ID",
|
||||
"testConn": "测试连接",
|
||||
"noTags": "无标签"
|
||||
}
|
||||
},
|
||||
"k8s": {
|
||||
@@ -5218,6 +5245,38 @@
|
||||
"toastExecConfirm": "确认批量执行命令",
|
||||
"toastExecConfirmDesc": "将在 {{count}} 台主机上执行该命令,请确认命令安全:\n\n{{command}}",
|
||||
"noOutput": "(无输出)"
|
||||
},
|
||||
"cronJobCol": {
|
||||
"task": "任务",
|
||||
"schedule": "调度",
|
||||
"type": "类型",
|
||||
"switch": "开关",
|
||||
"recent": "最近",
|
||||
"lastExec": "上次执行",
|
||||
"successRate": "成功率",
|
||||
"actions": "操作",
|
||||
"execNow": "立即执行",
|
||||
"execHistory": "执行历史",
|
||||
"disable": "禁用",
|
||||
"enable": "启用",
|
||||
"edit": "编辑",
|
||||
"delete": "删除"
|
||||
},
|
||||
"execHistory": {
|
||||
"title": "执行历史",
|
||||
"exitCode": "退出码",
|
||||
"output": "输出",
|
||||
"duration": "耗时",
|
||||
"startTime": "开始时间",
|
||||
"endTime": "结束时间",
|
||||
"target": "目标",
|
||||
"status": "状态",
|
||||
"noOutput": "暂无输出",
|
||||
"copyOutput": "复制输出",
|
||||
"copied": "已复制到剪贴板",
|
||||
"recentTrend": "近 7 天趋势与执行日志(最近 100 条)",
|
||||
"noRecords": "暂无执行记录",
|
||||
"last7days": "最近 7 天"
|
||||
}
|
||||
},
|
||||
"rbac": {
|
||||
|
||||
Reference in new issue
Block a user