feat(i18n): deploy 模块(Pipeline/Credential)国际化增量迁移 — 翻译键 deploy 命名空间(455键) + CredentialManager 补全 3 处 UI 文案
- PipelineManager.tsx: 流水线全量翻译(标题/搜索/CRUD/阶段/任务/运行/横幅) - CredentialManager.tsx: 操作按钮 title 属性补全(编辑/禁用启用/删除) - zh-CN.json + en-US.json: deploy 命名空间 455 键完全对齐 - 总翻译键: 1019(zh) = 1019(en) - tsc -b 零错误, npm build 成功(17.42s)
This commit is contained in:
1 parent
ed7a5c07a7
commit
01967bc52b
4 files changed
+1053
-67
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
Plus, Pencil, Trash2, RefreshCw, Key, Shield, Search,
|
||||
Clock, CheckCircle2, XCircle, Zap,
|
||||
@@ -17,6 +18,7 @@ import { CredFormDialog } from './credential-manager/CredFormDialog';
|
||||
|
||||
// 凭据管理页编排器 // Logan.Li
|
||||
export default function CredentialManager() {
|
||||
const { t } = useTranslation();
|
||||
const confirm = useConfirm();
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [editing, setEditing] = useState<Credential | null>(null);
|
||||
@@ -38,28 +40,28 @@ export default function CredentialManager() {
|
||||
|
||||
const handleDelete = async (cred: Credential) => {
|
||||
const ok = await confirm({
|
||||
title: '删除凭据',
|
||||
description: `确定删除凭据「${cred.name}」?此操作不可撤销。`,
|
||||
confirmText: '删除',
|
||||
title: t('deploy.cred.deleteCred'),
|
||||
description: t('deploy.pipeline.deleteConfirm', { name: cred.name }),
|
||||
confirmText: t('common.delete'),
|
||||
variant: 'destructive',
|
||||
});
|
||||
if (!ok) return;
|
||||
try {
|
||||
await deleteMutation.mutateAsync(cred.id);
|
||||
toast.success('已删除');
|
||||
} catch { toast.error('删除失败'); }
|
||||
toast.success(t('deploy.toast.deleted'));
|
||||
} catch { toast.error(t('deploy.toast.deleteFailed')); }
|
||||
};
|
||||
|
||||
const handleToggleActive = async (cred: Credential) => {
|
||||
try {
|
||||
await toggleActiveMutation.mutateAsync({ id: cred.id, isActive: !cred.is_active });
|
||||
toast.success(cred.is_active ? '已禁用' : '已启用');
|
||||
} catch { toast.error('操作失败'); }
|
||||
toast.success(cred.is_active ? t('deploy.toast.disabled') : t('deploy.toast.enabled'));
|
||||
} catch { toast.error(t('deploy.toast.operationFailed')); }
|
||||
};
|
||||
|
||||
const handleCopyPrefix = (prefix: string) => {
|
||||
navigator.clipboard.writeText(prefix);
|
||||
toast.success('引用 ID 已复制');
|
||||
toast.success(t('deploy.cred.refIdCopied'));
|
||||
};
|
||||
|
||||
const typeOptions = Object.entries(TYPE_CONFIG) as [SecretType, typeof TYPE_CONFIG[SecretType]][];
|
||||
@@ -68,17 +70,17 @@ export default function CredentialManager() {
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 className="text-lg font-semibold text-[var(--dg-text-primary)]">凭据管理</h2>
|
||||
<h2 className="text-lg font-semibold text-[var(--dg-text-primary)]">{t('deploy.cred.title')}</h2>
|
||||
<p className="text-sm text-[var(--dg-text-muted)] mt-0.5">
|
||||
统一管理 SSH 密钥、Docker 密码、AKSK、数据库等敏感凭据(AES 加密存储)
|
||||
{t('deploy.cred.subtitle')}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button variant="outline" size="sm" onClick={() => refetch()}>
|
||||
<RefreshCw className="w-4 h-4 mr-1" />刷新
|
||||
<RefreshCw className="w-4 h-4 mr-1" />{t('common.refresh')}
|
||||
</Button>
|
||||
<Button size="sm" onClick={() => { setEditing(null); setDialogOpen(true); }}>
|
||||
<Plus className="w-4 h-4 mr-1" />新增凭据
|
||||
<Plus className="w-4 h-4 mr-1" />{t('deploy.cred.addCredential')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -87,10 +89,10 @@ export default function CredentialManager() {
|
||||
<div className="flex items-center gap-3 flex-wrap">
|
||||
<Select value={filterType} onValueChange={setFilterType}>
|
||||
<SelectTrigger className="w-[140px] bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)] h-9 text-sm">
|
||||
<SelectValue placeholder="全部类型" />
|
||||
<SelectValue placeholder={t('deploy.label.allType')} />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">全部类型</SelectItem>
|
||||
<SelectItem value="all">{t('deploy.label.allType')}</SelectItem>
|
||||
{typeOptions.map(([k, v]) => (
|
||||
<SelectItem key={k} value={k}>
|
||||
<span className="flex items-center gap-2"><v.icon className="h-3.5 w-3.5" />{v.label}</span>
|
||||
@@ -101,23 +103,23 @@ export default function CredentialManager() {
|
||||
<div className="relative flex-1 max-w-xs">
|
||||
<Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-4 w-4 text-[var(--dg-text-muted)]" />
|
||||
<Input value={filterSearch} onChange={e => setFilterSearch(e.target.value)}
|
||||
placeholder="搜索名称、描述..."
|
||||
placeholder={t('deploy.label.searchPlaceholder')}
|
||||
className="pl-8 bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)] text-[var(--dg-text-primary)] h-9 text-sm" />
|
||||
</div>
|
||||
<span className="text-xs text-[var(--dg-text-muted)]">{credentials.length} 个凭据</span>
|
||||
<span className="text-xs text-[var(--dg-text-muted)]">{t('deploy.cred.credCount', { count: credentials.length })}</span>
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
<div className="text-center py-16 text-[var(--dg-text-secondary)]">
|
||||
<Zap className="w-6 h-6 animate-spin mx-auto mb-2 text-[var(--dg-blue)]" />加载中...
|
||||
<Zap className="w-6 h-6 animate-spin mx-auto mb-2 text-[var(--dg-blue)]" />{t('deploy.label.loading')}
|
||||
</div>
|
||||
) : credentials.length === 0 ? (
|
||||
<div className="text-center py-16 border border-dashed border-[var(--dg-border)] rounded-lg">
|
||||
<Shield className="w-12 h-12 mx-auto mb-3 text-[var(--dg-text-muted)]" />
|
||||
<p className="text-[var(--dg-text-secondary)] mb-2">暂无凭据</p>
|
||||
<p className="text-xs text-[var(--dg-text-muted)] mb-4">创建 SSH、Docker、AKSK 等类型的凭据,供流水线和服务器使用</p>
|
||||
<p className="text-[var(--dg-text-secondary)] mb-2">{t('deploy.cred.noCredentials')}</p>
|
||||
<p className="text-xs text-[var(--dg-text-muted)] mb-4">{t('deploy.cred.subtitle')}</p>
|
||||
<Button onClick={() => { setEditing(null); setDialogOpen(true); }}>
|
||||
<Plus className="w-4 h-4 mr-1" />创建第一个凭据
|
||||
<Plus className="w-4 h-4 mr-1" />{t('deploy.cred.createFirst')}
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
@@ -125,13 +127,13 @@ export default function CredentialManager() {
|
||||
<table className="w-full text-sm">
|
||||
<thead className="bg-[var(--dg-bg-tertiary)] border-b border-[var(--dg-border)]">
|
||||
<tr>
|
||||
<th className="px-3 py-2.5 text-left font-medium text-[var(--dg-text-secondary)]">名称</th>
|
||||
<th className="px-3 py-2.5 text-left font-medium text-[var(--dg-text-secondary)]">类型</th>
|
||||
<th className="px-3 py-2.5 text-left font-medium text-[var(--dg-text-secondary)] hidden md:table-cell">摘要</th>
|
||||
<th className="px-3 py-2.5 text-left font-medium text-[var(--dg-text-secondary)] hidden lg:table-cell">标签</th>
|
||||
<th className="px-3 py-2.5 text-left font-medium text-[var(--dg-text-secondary)] hidden xl:table-cell">引用ID</th>
|
||||
<th className="px-3 py-2.5 text-left font-medium text-[var(--dg-text-secondary)]">状态</th>
|
||||
<th className="px-3 py-2.5 text-right font-medium text-[var(--dg-text-secondary)]">操作</th>
|
||||
<th className="px-3 py-2.5 text-left font-medium text-[var(--dg-text-secondary)]">{t('deploy.table.name')}</th>
|
||||
<th className="px-3 py-2.5 text-left font-medium text-[var(--dg-text-secondary)]">{t('deploy.table.type')}</th>
|
||||
<th className="px-3 py-2.5 text-left font-medium text-[var(--dg-text-secondary)] hidden md:table-cell">{t('deploy.table.repoUrl')}</th>
|
||||
<th className="px-3 py-2.5 text-left font-medium text-[var(--dg-text-secondary)] hidden lg:table-cell">{t('deploy.table.tagLabel')}</th>
|
||||
<th className="px-3 py-2.5 text-left font-medium text-[var(--dg-text-secondary)] hidden xl:table-cell">{t('deploy.cred.refId')}</th>
|
||||
<th className="px-3 py-2.5 text-left font-medium text-[var(--dg-text-secondary)]">{t('deploy.table.status')}</th>
|
||||
<th className="px-3 py-2.5 text-right font-medium text-[var(--dg-text-secondary)]">{t('deploy.table.actions')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -181,28 +183,28 @@ export default function CredentialManager() {
|
||||
<td className="px-3 py-2.5">
|
||||
<div className="flex items-center gap-1">
|
||||
{cred.is_active ? (
|
||||
<Badge className="bg-green-500/20 text-green-400 text-xs border-0">启用</Badge>
|
||||
<Badge className="bg-green-500/20 text-green-400 text-xs border-0">{t('common.enable')}</Badge>
|
||||
) : (
|
||||
<Badge className="bg-red-500/20 text-red-400 text-xs border-0">禁用</Badge>
|
||||
<Badge className="bg-red-500/20 text-red-400 text-xs border-0">{t('common.disable')}</Badge>
|
||||
)}
|
||||
{isExpired && (
|
||||
<Badge className="bg-yellow-500/20 text-yellow-400 text-xs border-0"><Clock className="h-2.5 w-2.5 mr-0.5" />过期</Badge>
|
||||
<Badge className="bg-yellow-500/20 text-yellow-400 text-xs border-0"><Clock className="h-2.5 w-2.5 mr-0.5" />{t('deploy.status.expired')}</Badge>
|
||||
)}
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-3 py-2.5 text-right" onClick={(e) => e.stopPropagation()}>
|
||||
<div className="flex justify-end gap-1">
|
||||
<Button variant="ghost" size="icon" className="h-7 w-7"
|
||||
onClick={() => { setEditing(cred as Credential); setDialogOpen(true); }} title="编辑">
|
||||
onClick={() => { setEditing(cred as Credential); setDialogOpen(true); }} title={t('common.edit')}>
|
||||
<Pencil className="w-3.5 h-3.5" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="icon" className="h-7 w-7"
|
||||
onClick={() => handleToggleActive(cred as Credential)}
|
||||
title={cred.is_active ? '禁用' : '启用'}>
|
||||
title={cred.is_active ? t('common.disable') : t('common.enable')}>
|
||||
{cred.is_active ? <XCircle className="w-3.5 h-3.5 text-yellow-500" /> : <CheckCircle2 className="w-3.5 h-3.5 text-green-500" />}
|
||||
</Button>
|
||||
<Button variant="ghost" size="icon" className="h-7 w-7 text-red-500"
|
||||
onClick={() => handleDelete(cred as Credential)} title="删除">
|
||||
onClick={() => handleDelete(cred as Credential)} title={t('common.delete')}>
|
||||
<Trash2 className="w-3.5 h-3.5" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import {
|
||||
@@ -28,6 +29,7 @@ import { PipelineCreateDialog } from './pipeline-manager/PipelineCreateDialog';
|
||||
|
||||
// 流水线列表页编排器 // Logan.Li
|
||||
export function PipelineManager() {
|
||||
const { t } = useTranslation();
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const { data: pipelines = [], isLoading: loading, refetch: refetchPipelines } = usePipelines();
|
||||
const { triggerMutation, deleteMutation, stopRunMutation } = usePipelineMutations();
|
||||
@@ -41,11 +43,11 @@ export function PipelineManager() {
|
||||
const confirm = useConfirm();
|
||||
|
||||
const ENV_TYPES = [
|
||||
{ key: 'all', label: '全部', icon: Layers, color: '#6B7280' },
|
||||
{ key: 'production', label: '生产', icon: ShieldCheck, color: '#EF4444' },
|
||||
{ key: 'testing', label: '测试', icon: CheckCircle, color: '#F59E0B' },
|
||||
{ key: 'staging', label: '预发布', icon: Globe, color: '#8B5CF6' },
|
||||
{ key: 'development', label: '开发', icon: Code, color: '#3B82F6' },
|
||||
{ key: 'all', label: t('deploy.env.all'), icon: Layers, color: '#6B7280' },
|
||||
{ key: 'production', label: t('deploy.env.production'), icon: ShieldCheck, color: '#EF4444' },
|
||||
{ key: 'testing', label: t('deploy.env.testing'), icon: CheckCircle, color: '#F59E0B' },
|
||||
{ key: 'staging', label: t('deploy.env.staging'), icon: Globe, color: '#8B5CF6' },
|
||||
{ key: 'development', label: t('deploy.env.development'), icon: Code, color: '#3B82F6' },
|
||||
];
|
||||
|
||||
// 同步运行中的任务 ID // Logan.Li
|
||||
@@ -86,20 +88,20 @@ export function PipelineManager() {
|
||||
const handleTrigger = async (pipelineId: number, code: string) => {
|
||||
try {
|
||||
await triggerMutation.mutateAsync(code);
|
||||
toast.success('已触发');
|
||||
toast.success(t('deploy.toast.triggered'));
|
||||
loadRuns(pipelineId, code);
|
||||
refetchPipelines();
|
||||
} catch {
|
||||
toast.error('触发失败');
|
||||
toast.error(t('deploy.toast.triggerFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
const handleStop = async (pipelineId: number, code: string, runId: number | string) => {
|
||||
const ok = await confirm({ title: '停止运行', description: '确定要停止此运行吗?', variant: 'destructive' });
|
||||
const ok = await confirm({ title: t('deploy.run.stopRun'), description: t('deploy.run.stopConfirm'), variant: 'destructive' });
|
||||
if (!ok) return;
|
||||
try {
|
||||
await stopRunMutation.mutateAsync({ code, runId });
|
||||
toast.success('已停止');
|
||||
toast.success(t('deploy.toast.stopped'));
|
||||
loadRuns(pipelineId, code);
|
||||
setRunningRunMap((prev) => {
|
||||
const n = { ...prev };
|
||||
@@ -107,7 +109,7 @@ export function PipelineManager() {
|
||||
return n;
|
||||
});
|
||||
} catch {
|
||||
toast.error('停止失败');
|
||||
toast.error(t('deploy.toast.stopFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -120,9 +122,9 @@ export function PipelineManager() {
|
||||
(r) => r.status === 'running' || r.status === 'pending',
|
||||
);
|
||||
if (running) await handleStop(pipelineId, code, running.id as number | string);
|
||||
else toast.error('未找到运行中的任务');
|
||||
else toast.error(t('deploy.pipeline.noRunningTask'));
|
||||
} catch {
|
||||
toast.error('停止失败');
|
||||
toast.error(t('deploy.toast.stopFailed'));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -131,17 +133,17 @@ export function PipelineManager() {
|
||||
|
||||
const handleDelete = async (pipeline: Record<string, unknown>) => {
|
||||
const ok = await confirm({
|
||||
title: '删除流水线',
|
||||
description: `确定删除「${pipeline.name}」?`,
|
||||
title: t('deploy.pipeline.deletePipeline'),
|
||||
description: t('deploy.pipeline.deleteConfirm', { name: pipeline.name }),
|
||||
variant: 'destructive',
|
||||
});
|
||||
if (!ok) return;
|
||||
try {
|
||||
await deleteMutation.mutateAsync(pipeline.id as number | string);
|
||||
toast.success('已删除');
|
||||
toast.success(t('deploy.toast.deleted'));
|
||||
refetchPipelines();
|
||||
} catch {
|
||||
toast.error('删除失败');
|
||||
toast.error(t('deploy.toast.deleteFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -157,14 +159,14 @@ export function PipelineManager() {
|
||||
<div className="space-y-5">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-[var(--dg-text-primary)]">流水线</h1>
|
||||
<p className="text-sm text-[var(--dg-text-secondary)] mt-1">CI/CD 构建 · 部署 · 发布一体化</p>
|
||||
<h1 className="text-2xl font-bold text-[var(--dg-text-primary)]">{t('deploy.pipeline.title')}</h1>
|
||||
<p className="text-sm text-[var(--dg-text-secondary)] mt-1">{t('deploy.pipeline.subtitle')}</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button variant="outline" className="border-[var(--dg-border)] text-[var(--dg-text-secondary)]" onClick={() => refetchPipelines()}>
|
||||
<Clock className={`h-4 w-4 mr-2 ${loading ? 'animate-spin' : ''}`} />刷新
|
||||
<Clock className={`h-4 w-4 mr-2 ${loading ? 'animate-spin' : ''}`} />{t('common.refresh')}
|
||||
</Button>
|
||||
<Button onClick={() => setNewOpen(true)}><Plus className="h-4 w-4 mr-2" />新建流水线</Button>
|
||||
<Button onClick={() => setNewOpen(true)}><Plus className="h-4 w-4 mr-2" />{t('deploy.pipeline.newPipeline')}</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -173,45 +175,45 @@ export function PipelineManager() {
|
||||
<div className="flex-1 space-y-1.5">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<GitBranch className="h-3 w-3 text-indigo-400" />
|
||||
<span className="text-[10px] font-semibold text-indigo-400">构建</span>
|
||||
<span className="text-[10px] font-semibold text-indigo-400">{t('deploy.banner.build')}</span>
|
||||
<ArrowRight className="h-2.5 w-2.5 text-[var(--dg-text-secondary)] opacity-30" />
|
||||
<Rocket className="h-3 w-3 text-red-400" />
|
||||
<span className="text-[10px] font-semibold text-red-400">部署</span>
|
||||
<span className="text-[10px] font-semibold text-red-400">{t('deploy.banner.deploy')}</span>
|
||||
<ArrowRight className="h-2.5 w-2.5 text-[var(--dg-text-secondary)] opacity-30" />
|
||||
<div className="flex items-center gap-1 px-2 py-0.5 rounded bg-blue-400/10 border border-blue-400/20">
|
||||
<Server className="h-3 w-3 text-blue-400" />
|
||||
<span className="text-[10px] font-medium text-blue-400">SSH 主机</span>
|
||||
<span className="text-[10px] font-medium text-blue-400">{t('deploy.banner.sshHost')}</span>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-[9px] text-[var(--dg-text-secondary)] opacity-40 pl-1">传统主机 SCP 部署 · 无需镜像仓库</p>
|
||||
<p className="text-[9px] text-[var(--dg-text-secondary)] opacity-40 pl-1">{t('deploy.banner.sshDesc')}</p>
|
||||
</div>
|
||||
<div className="w-px bg-[var(--dg-border)]" />
|
||||
<div className="flex-1 space-y-1.5">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<GitBranch className="h-3 w-3 text-indigo-400" />
|
||||
<span className="text-[10px] font-semibold text-indigo-400">构建</span>
|
||||
<span className="text-[10px] font-semibold text-indigo-400">{t('deploy.banner.build')}</span>
|
||||
<ArrowRight className="h-2.5 w-2.5 text-[var(--dg-text-secondary)] opacity-30" />
|
||||
<Container className="h-3 w-3 text-cyan-400" />
|
||||
<span className="text-[10px] font-semibold text-cyan-400">镜像仓库</span>
|
||||
<span className="text-[10px] font-semibold text-cyan-400">{t('deploy.banner.imageRegistry')}</span>
|
||||
<ArrowRight className="h-2.5 w-2.5 text-[var(--dg-text-secondary)] opacity-30" />
|
||||
<Rocket className="h-3 w-3 text-red-400" />
|
||||
<span className="text-[10px] font-semibold text-red-400">部署</span>
|
||||
<span className="text-[10px] font-semibold text-red-400">{t('deploy.banner.deploy')}</span>
|
||||
<ArrowRight className="h-2.5 w-2.5 text-[var(--dg-text-secondary)] opacity-30" />
|
||||
<div className="flex items-center gap-1 px-2 py-0.5 rounded bg-emerald-400/10 border border-emerald-400/20">
|
||||
<Network className="h-3 w-3 text-emerald-400" />
|
||||
<span className="text-[10px] font-medium text-emerald-400">Kubernetes</span>
|
||||
<span className="text-[10px] font-medium text-emerald-400">{t('deploy.banner.kubernetes')}</span>
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-[9px] text-[var(--dg-text-secondary)] opacity-40 pl-1">容器化部署 · 需镜像仓库推送</p>
|
||||
<p className="text-[9px] text-[var(--dg-text-secondary)] opacity-40 pl-1">{t('deploy.banner.k8sDesc')}</p>
|
||||
</div>
|
||||
<span className="self-center ml-2 text-[10px] text-[var(--dg-text-secondary)] opacity-30 tracking-wide whitespace-nowrap">全流程可视化</span>
|
||||
<span className="self-center ml-2 text-[10px] text-[var(--dg-text-secondary)] opacity-30 tracking-wide whitespace-nowrap">{t('deploy.banner.fullFlow')}</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
<div className="relative max-w-md flex-1">
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-[var(--dg-text-secondary)]" />
|
||||
<Input
|
||||
placeholder="搜索流水线..."
|
||||
placeholder={t('deploy.pipeline.searchPlaceholder')}
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="pl-10 bg-[var(--dg-bg-secondary)] border-[var(--dg-border)] text-[var(--dg-text-primary)]"
|
||||
@@ -244,9 +246,9 @@ export function PipelineManager() {
|
||||
) : filtered.length === 0 ? (
|
||||
<div className="text-center py-16 text-[var(--dg-text-secondary)]">
|
||||
<Workflow className="h-10 w-10 mx-auto mb-3 opacity-30" />
|
||||
<p className="text-sm">暂无流水线</p>
|
||||
<p className="text-sm">{t('deploy.pipeline.noData')}</p>
|
||||
<Button variant="outline" className="mt-4" onClick={() => setNewOpen(true)}>
|
||||
<Plus className="h-4 w-4 mr-1" />创建第一个流水线
|
||||
<Plus className="h-4 w-4 mr-1" />{t('deploy.pipeline.createFirst')}
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
@@ -275,4 +277,4 @@ export function PipelineManager() {
|
||||
<PipelineCreateDialog open={newOpen} onOpenChange={setNewOpen} onCreated={refetchPipelines} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -654,5 +654,496 @@
|
||||
"closed": "Closed"
|
||||
}
|
||||
}
|
||||
},
|
||||
"deploy": {
|
||||
"pipeline": {
|
||||
"title": "Pipelines",
|
||||
"subtitle": "CI/CD Build · Deploy · Release All-in-One",
|
||||
"newPipeline": "New Pipeline",
|
||||
"createFirst": "Create your first pipeline",
|
||||
"searchPlaceholder": "Search pipelines...",
|
||||
"noData": "No pipelines",
|
||||
"triggered": "Triggered",
|
||||
"triggerFailed": "Trigger failed",
|
||||
"stopRun": "Stop Run",
|
||||
"stopConfirm": "Are you sure you want to stop this run?",
|
||||
"stopped": "Stopped",
|
||||
"stopFailed": "Stop failed",
|
||||
"noRunningTask": "No running task found",
|
||||
"deletePipeline": "Delete Pipeline",
|
||||
"deleteConfirm": "Delete \"{{name}}\"?",
|
||||
"deleted": "Deleted",
|
||||
"deleteFailed": "Delete failed",
|
||||
"detail": "Pipeline Detail",
|
||||
"notExist": "Pipeline does not exist",
|
||||
"config": "Pipeline Config",
|
||||
"name": "Pipeline Name",
|
||||
"namePlaceholder": "Enter pipeline name",
|
||||
"type": "Pipeline Type",
|
||||
"stages": "Pipeline Stages ({{count}})",
|
||||
"allStages": "All Stages",
|
||||
"noStages": "No stage configuration",
|
||||
"clickToAddStage": "Click \"Add Stage\" to start",
|
||||
"addStage": "Add Stage",
|
||||
"newStage": "New Stage",
|
||||
"addTask": "Add Task",
|
||||
"newTask": "New Task",
|
||||
"taskEdit": "Task Editor",
|
||||
"selectTaskHint": "Select a task to start editing",
|
||||
"matchPreview": "Pipeline Match Preview",
|
||||
"created": "Pipeline created",
|
||||
"createFailed": "Create failed",
|
||||
"saving": "Saving...",
|
||||
"save": "Save",
|
||||
"editPipeline": "Edit Pipeline",
|
||||
"modifyConfig": "Modify Pipeline Config",
|
||||
"configureNew": "Configure new CI/CD pipeline",
|
||||
"editMode": "Save Changes",
|
||||
"createMode": "Create Pipeline",
|
||||
"desc": "No description",
|
||||
"buildNumber": "Build",
|
||||
"runs": "Run Count",
|
||||
"neverRun": "Never run",
|
||||
"runNow": "Run Now",
|
||||
"executing": "Executing...",
|
||||
"logOutput": "No log output",
|
||||
"noLogStage": "No log output for this stage",
|
||||
"realtimeOutput": "Pipeline running, real-time output...",
|
||||
"buildDir": "Pipeline Build Directory Terminal",
|
||||
"fileBrowser": "File Browser #{{buildNumber}}",
|
||||
"buildDirFiles": "Pipeline Build Directory File Browser",
|
||||
"workspaceTerminal": "Workspace Terminal #{{buildNumber}}",
|
||||
"execLog": "Execution Log #{{number}}",
|
||||
"release": "Release #{{number}}",
|
||||
"all": "All ({{count}})"
|
||||
},
|
||||
"stage": {
|
||||
"checkout": "Checkout",
|
||||
"build": "Build",
|
||||
"image": "Image Build",
|
||||
"deploy": "Deploy",
|
||||
"test": "Test",
|
||||
"custom": "Custom",
|
||||
"tasks": "{{count}} tasks",
|
||||
"selectOrder": "Select stages in order",
|
||||
"checkoutDesc": "Pull code",
|
||||
"buildDesc": "Build & package",
|
||||
"imageDesc": "Push image",
|
||||
"deployDesc": "Deploy to Kubernetes",
|
||||
"testDesc": "Code inspection",
|
||||
"checkoutNeedGit": "Checkout stage requires Git URL",
|
||||
"imageNeedDocker": "Image build stage requires Docker credential",
|
||||
"suggestDocker": "Recommended credential",
|
||||
"needDocker": "Docker credential required"
|
||||
},
|
||||
"env": {
|
||||
"all": "All",
|
||||
"production": "Production",
|
||||
"testing": "Testing",
|
||||
"staging": "Staging",
|
||||
"development": "Development",
|
||||
"prodEnv": "Production",
|
||||
"testEnv": "Testing",
|
||||
"stagingEnv": "Staging",
|
||||
"devEnv": "Development",
|
||||
"selectEnv": "Select Environment",
|
||||
"envType": "Environment Type",
|
||||
"envGroup": "Environment Group",
|
||||
"envLabel": "Environment ID",
|
||||
"selectEnvHint": "Pipeline runs will be linked to the selected environment",
|
||||
"addEnv": "Add Environment",
|
||||
"editEnv": "Edit Environment",
|
||||
"envManage": "Environments ({{count}})",
|
||||
"noEnvConfig": "No environment config, click \"Add Environment\" to create"
|
||||
},
|
||||
"trigger": {
|
||||
"manual": "Manual",
|
||||
"manualTrigger": "Manual Trigger",
|
||||
"manualExec": "Manual Execution",
|
||||
"gitPush": "Git Push Trigger",
|
||||
"gitPushAuto": "Git Push Auto Trigger",
|
||||
"cron": "Cron Schedule",
|
||||
"webhook": "Webhook Trigger",
|
||||
"externalWebhook": "External Webhook Call",
|
||||
"method": "Trigger Method",
|
||||
"triggerBuild": "Trigger Build",
|
||||
"settings": "Trigger Settings",
|
||||
"listenBranch": "Listen Branch",
|
||||
"excludeBranch": "Exclude Branch",
|
||||
"cronExpr": "Cron Expression",
|
||||
"every5min": "Every 5 minutes",
|
||||
"everyHour": "Every hour",
|
||||
"everyDay2": "Daily at 2:00",
|
||||
"everySunday": "Every Sunday",
|
||||
"tagRelease": "Tag Release",
|
||||
"branchTag": "Branch / Tag",
|
||||
"noTriggerMode": "Manual"
|
||||
},
|
||||
"run": {
|
||||
"status": "Status",
|
||||
"triggeredBy": "Triggered By",
|
||||
"triggerMode": "Trigger Method",
|
||||
"duration": "Duration",
|
||||
"startTime": "Start Time",
|
||||
"branch": "Branch",
|
||||
"commit": "Code",
|
||||
"noRecords": "No execution records",
|
||||
"noRecordsHint": "No execution records, click \"Run Now\" to trigger a build",
|
||||
"stopRun": "Stop Run",
|
||||
"stopConfirm": "Are you sure you want to stop this run?",
|
||||
"buildStatus": "Build Status",
|
||||
"buildLog": "Build Log",
|
||||
"execStage": "Execution Stage",
|
||||
"fullFlowVisual": "Full-flow Visualization"
|
||||
},
|
||||
"status": {
|
||||
"pending": "Pending",
|
||||
"running": "Running",
|
||||
"success": "Success",
|
||||
"failed": "Failed",
|
||||
"stopped": "Stopped",
|
||||
"building": "Building",
|
||||
"deploying": "Deploying",
|
||||
"succeeded": "Succeeded",
|
||||
"failed_deploy": "Deploy Failed",
|
||||
"rolledBack": "Rolled Back",
|
||||
"pendingRelease": "Pending Release",
|
||||
"pendingApproval": "Pending Approval",
|
||||
"approved": "Approved",
|
||||
"rejected": "Rejected",
|
||||
"cancelled": "Cancelled",
|
||||
"expired": "Expired",
|
||||
"created": "Created",
|
||||
"updated": "Updated",
|
||||
"deleted": "Deleted",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"installed": "Installed",
|
||||
"notInstalled": "Not Installed",
|
||||
"installing": "Installing"
|
||||
},
|
||||
"cred": {
|
||||
"title": "Credentials",
|
||||
"subtitle": "Manage SSH keys, Docker passwords, AKSK, database and other sensitive credentials (AES encrypted)",
|
||||
"addCredential": "Add Credential",
|
||||
"createFirst": "Create your first credential",
|
||||
"searchPlaceholder": "Search credentials...",
|
||||
"credName": "Credential Name",
|
||||
"nameRequired": "Please enter credential name",
|
||||
"credType": "Type",
|
||||
"authMethod": "Auth Method",
|
||||
"noCredentials": "No credentials",
|
||||
"credCount": "{{count}} credentials",
|
||||
"editCred": "Edit Credential",
|
||||
"newCred": "New Credential",
|
||||
"deleteCred": "Delete Credential",
|
||||
"credData": "Secret Data",
|
||||
"noCredData": "Credential data not found",
|
||||
"refId": "Reference ID",
|
||||
"refIdCopied": "Reference ID copied",
|
||||
"refHint": "Reference this credential in pipelines/scripts:",
|
||||
"credDetail": "Credential Detail",
|
||||
"refIdLabel": "Reference ID:",
|
||||
"descDefault": "Manage sensitive credentials",
|
||||
"suggestLink": "Recommended credential",
|
||||
"notLinked": "Not linked",
|
||||
"notLinkedCred": "No credential",
|
||||
"selectDocker": "Select Docker credential",
|
||||
"selectDockerPwd": "Select Docker password credential",
|
||||
"selectApiCred": "Select credential (API/password etc.)",
|
||||
"selectCred": "Select credential",
|
||||
"linkedCred": "Linked Credential"
|
||||
},
|
||||
"release": {
|
||||
"title": "Application Release",
|
||||
"subtitle": "Manage application version releases and approval workflows",
|
||||
"newRelease": "New Release",
|
||||
"searchApp": "Search app name or version...",
|
||||
"noRecords": "No release records",
|
||||
"appName": "App Name",
|
||||
"version": "Version",
|
||||
"versionNo": "Version Number",
|
||||
"releaseDesc": "Release Notes",
|
||||
"releaseProgress": "Release Progress",
|
||||
"releaseDetail": "Release Detail",
|
||||
"approve": "Approve Release",
|
||||
"approveFail": "Approval failed",
|
||||
"approveHint": "After approval, it will enter the ready-to-deploy state",
|
||||
"reject": "Reject",
|
||||
"rejectFail": "Reject failed",
|
||||
"deploy": "Deploy",
|
||||
"deployStarted": "Deployment started",
|
||||
"deployFail": "Deploy failed",
|
||||
"confirmDeploy": "Confirm Deploy",
|
||||
"rollback": "Rollback",
|
||||
"rollbackSuccess": "Rollback succeeded",
|
||||
"rollbackFail": "Rollback failed",
|
||||
"confirmRollback": "Confirm Rollback",
|
||||
"redeploy": "Redeploy",
|
||||
"redeployFail": "Redeploy failed",
|
||||
"redeployed": "Redeployment triggered",
|
||||
"submitApp": "Submit Request",
|
||||
"submitFail": "Release request submitted",
|
||||
"createNew": "Create new application version release request",
|
||||
"appPlaceholder": "e.g., demo-jar backend deployment",
|
||||
"nameVerRequired": "Please enter app name and version",
|
||||
"getReleaseFail": "Failed to get release list",
|
||||
"deployEnv": "Deploy Environment:",
|
||||
"targetEnv": "Target Environment",
|
||||
"releaseConfig": "Release Config Management",
|
||||
"releaseRecords": "Release Records ({{count}})",
|
||||
"releaseFlow": "Release Flow",
|
||||
"releasePerson": "Released By",
|
||||
"releaseManage": "Release Management"
|
||||
},
|
||||
"tool": {
|
||||
"title": "Tool Config",
|
||||
"subtitle": "Manage DevOps tool installation strategy: pre-installed, lazy-load on first use, or disabled",
|
||||
"installMethod": "Install Method",
|
||||
"preinstall": "Pre-install",
|
||||
"lazyLoad": "Lazy Load",
|
||||
"selectVersion": "Select Version",
|
||||
"versionPrompt": "{{name}} — Please select a version to install",
|
||||
"noConfig": "No tool config, please check backend seed data",
|
||||
"getToolFail": "Failed to get tool config",
|
||||
"installed": "Installed",
|
||||
"notInstalled": "Not installed",
|
||||
"installing": "Installing",
|
||||
"test": "Test",
|
||||
"install": "Install"
|
||||
},
|
||||
"rbac": {
|
||||
"title": "Deploy Permissions",
|
||||
"subtitle": "Jenkins-style Role Strategy — Assign roles by pipeline code regex matching",
|
||||
"newRole": "New Item Role",
|
||||
"newGroup": "New User Group",
|
||||
"assignToUser": "Assign roles to users",
|
||||
"userGroupManage": "User Group Management",
|
||||
"groupDesc": "Create user groups, authorize groups to pipelines, group members automatically inherit permissions",
|
||||
"noRoles": "No Item Roles",
|
||||
"noGroups": "No user groups, click \"New User Group\" to create",
|
||||
"noDirectUsers": "No direct users",
|
||||
"noGroupAuth": "No group authorization — Create a group in \"",
|
||||
"noGroupAuthSuffix": "\" page, then authorize here",
|
||||
"directUsers": "👤 Direct User Authorization ({{count}})",
|
||||
"groupAssignments": "👥 Group Authorization ({{count}})",
|
||||
"rolePattern": "Regex Match Pattern",
|
||||
"regexEmpty": "Regex cannot be empty",
|
||||
"noMatch": "No match — please adjust the regex",
|
||||
"regexError": "❌ Invalid regex syntax",
|
||||
"matchCount": "{{count}} matches",
|
||||
"matchPreview": "Pipeline Match Preview",
|
||||
"roleHint": "— Select a role to see which pipelines match",
|
||||
"owner": "Owner",
|
||||
"editor": "Editor",
|
||||
"viewer": "Viewer",
|
||||
"ownerRole": "Owner",
|
||||
"editorRole": "Editor",
|
||||
"viewerRole": "Viewer",
|
||||
"assigned": "Assigned",
|
||||
"assignedRoles": "Assigned roles:",
|
||||
"addUser": "Add User",
|
||||
"selectUser": "Select User",
|
||||
"selectUserPlaceholder": "Select user...",
|
||||
"selectRole": "Select Role",
|
||||
"assign": "Assign",
|
||||
"assignFail": "Assign failed",
|
||||
"memberManage": "Members ({{count}})",
|
||||
"addMember": "Add User",
|
||||
"removeMember": "Remove Member",
|
||||
"removeConfirm": "Are you sure you want to remove this member?",
|
||||
"removeFail": "Remove failed",
|
||||
"noMembers": "No members",
|
||||
"addedMember": "Member added",
|
||||
"removed": "Removed",
|
||||
"groupNewTitle": "New User Group",
|
||||
"groupEditTitle": "Edit User Group",
|
||||
"groupName": "Group Name",
|
||||
"groupPlaceholder": "Enter group name",
|
||||
"createGroup": "Create",
|
||||
"creating": "Creating...",
|
||||
"deleteGroup": "Delete User Group",
|
||||
"deleteRole": "Delete Role",
|
||||
"userCol": "User",
|
||||
"noUserRole": "This user has not been assigned any Item Role"
|
||||
},
|
||||
"banner": {
|
||||
"build": "Build",
|
||||
"deploy": "Deploy",
|
||||
"sshHost": "SSH Host",
|
||||
"kubernetes": "Kubernetes",
|
||||
"imageRegistry": "Image Registry",
|
||||
"sshDesc": "Traditional host SCP deployment · No registry needed",
|
||||
"k8sDesc": "Containerized deployment · Requires registry push",
|
||||
"fullFlow": "Full-flow Visualization"
|
||||
},
|
||||
"template": {
|
||||
"go": "Go Project",
|
||||
"goDesc": "For Go backend projects",
|
||||
"java": "Java Project",
|
||||
"javaDesc": "For Java Spring Boot projects",
|
||||
"nodejs": "Node.js Project",
|
||||
"nodejsDesc": "For Node.js frontend projects",
|
||||
"python": "Python Project",
|
||||
"pythonDesc": "For Python projects",
|
||||
"selectTemplate": "Select Template",
|
||||
"mavenBuild": "Maven Build",
|
||||
"dependencyInstall": "Dependency Install",
|
||||
"unitTest": "Unit Test",
|
||||
"healthCheck": "Health Check",
|
||||
"package": "Package",
|
||||
"verify": "Verify",
|
||||
"detect": "Detect"
|
||||
},
|
||||
"var": {
|
||||
"title": "Variables",
|
||||
"addVar": "Add Variable",
|
||||
"varName": "Variable Name",
|
||||
"varValue": "Variable Value",
|
||||
"varAlias": "Variable Alias",
|
||||
"noVars": "No variables, click \"Add Variable\" to create",
|
||||
"envVar": "Environment Variables",
|
||||
"envVarOptional": "Environment Variables (optional)"
|
||||
},
|
||||
"table": {
|
||||
"name": "Name",
|
||||
"code": "Code",
|
||||
"codeCol": "Repository",
|
||||
"type": "Type",
|
||||
"status": "Status",
|
||||
"env": "Environment",
|
||||
"duration": "Duration",
|
||||
"trigger": "Trigger",
|
||||
"triggerBy": "Triggered By",
|
||||
"startTime": "Start Time",
|
||||
"actions": "Actions",
|
||||
"sortOrder": "Sort",
|
||||
"modifyTime": "Modified",
|
||||
"size": "Size",
|
||||
"color": "Color",
|
||||
"icon": "Icon",
|
||||
"displayName": "Display Name",
|
||||
"envId": "Env ID",
|
||||
"successRate": "Success Rate",
|
||||
"todayRelease": "Today's Releases",
|
||||
"defaultBranch": "Default Branch",
|
||||
"repoUrl": "Repository URL",
|
||||
"tagLabel": "Tag",
|
||||
"version": "Version",
|
||||
"user": "User",
|
||||
"category": "Category"
|
||||
},
|
||||
"form": {
|
||||
"name": "Name",
|
||||
"nameStar": "Name *",
|
||||
"nameRequired": "Please enter a name",
|
||||
"code": "Code (unique identifier)",
|
||||
"desc": "Description",
|
||||
"descOptional": "Description (optional)",
|
||||
"repoUrlStar": "Repository URL *",
|
||||
"registryUrlStar": "Registry URL *",
|
||||
"nameAddrRequired": "Please enter name and address",
|
||||
"concurrent": "Concurrent Executors",
|
||||
"concurrentHint": "Set to 1 for sequential execution, default 2 allows parallel builds",
|
||||
"serial": "1 — Sequential",
|
||||
"gitCred": "Git Credential",
|
||||
"jobName": "Job Name",
|
||||
"envVars": "Environment Variables",
|
||||
"deployMode": "Deploy Mode",
|
||||
"deployTarget": "Deploy Target",
|
||||
"commitId": "Commit ID (optional)",
|
||||
"dockerfilePath": "Dockerfile Path",
|
||||
"buildCache": "Build Cache",
|
||||
"cachePaths": "Separate multiple paths with commas, same Key will hit existing cache",
|
||||
"registryAddr": "Registry Address",
|
||||
"imageName": "Image Name:",
|
||||
"varRef": "(${'{VAR_NAME}'} reference)",
|
||||
"scriptType": "Script Type",
|
||||
"scriptContent": "Script Content",
|
||||
"buildQueue": "Build Queue",
|
||||
"defaultNamespace": "Default Namespace",
|
||||
"defaultEnabled": "Enabled by default",
|
||||
"notSpecified": "Not specified",
|
||||
"save": "Save",
|
||||
"cancel": "Cancel",
|
||||
"create": "Create",
|
||||
"update": "Update"
|
||||
},
|
||||
"toast": {
|
||||
"saved": "Saved",
|
||||
"updated": "Updated",
|
||||
"deleted": "Deleted",
|
||||
"created": "Created",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"installed": "Installed",
|
||||
"triggered": "Triggered",
|
||||
"stopped": "Stopped",
|
||||
"added": "Added",
|
||||
"removed": "Removed",
|
||||
"revoked": "Revoked",
|
||||
"approved": "Approved",
|
||||
"rejected": "Rejected",
|
||||
"cancelled": "Cancelled",
|
||||
"expired": "Expired",
|
||||
"rolledBack": "Rolled back",
|
||||
"redeployed": "Redeployment triggered",
|
||||
"assigned": "Assigned",
|
||||
"createdPipeline": "Pipeline created",
|
||||
"releaseSubmitted": "Release request submitted",
|
||||
"deployStarted": "Deployment started",
|
||||
"saveFailed": "Save failed",
|
||||
"updateFailed": "Update failed",
|
||||
"deleteFailed": "Delete failed",
|
||||
"createFailed": "Create failed",
|
||||
"triggerFailed": "Trigger failed",
|
||||
"stopFailed": "Stop failed",
|
||||
"addFailed": "Add failed",
|
||||
"removeFailed": "Remove failed",
|
||||
"revokeFailed": "Revoke failed",
|
||||
"approveFailed": "Approve failed",
|
||||
"rejectFailed": "Reject failed",
|
||||
"deployFailed": "Deploy failed",
|
||||
"rollbackFailed": "Rollback failed",
|
||||
"redeployFailed": "Redeploy failed",
|
||||
"assignFailed": "Assign failed",
|
||||
"batchDeleteFailed": "Batch delete failed",
|
||||
"cancelFailed": "Cancel failed",
|
||||
"operationFailed": "Operation failed",
|
||||
"getDataFailed": "Failed to get data",
|
||||
"loadFailed": "Load failed",
|
||||
"saveSuccess": "Saved successfully"
|
||||
},
|
||||
"label": {
|
||||
"basicInfo": "Basic Info",
|
||||
"flowConfig": "Flow Config",
|
||||
"triggerSettings": "Trigger Settings",
|
||||
"variables": "Variables",
|
||||
"credentials": "Credentials",
|
||||
"environments": "Environments",
|
||||
"toolConfig": "Tool Config",
|
||||
"releaseConfig": "Release Config",
|
||||
"releaseRecords": "Release Records",
|
||||
"permission": "Permissions",
|
||||
"userGroups": "User Groups",
|
||||
"roles": "Roles",
|
||||
"gitRepo": "Git Repos ({{count}})",
|
||||
"registry": "Registries ({{count}})",
|
||||
"envManage": "Environments ({{count}})",
|
||||
"advanced": "Advanced",
|
||||
"loading": "Loading...",
|
||||
"emptyDir": "Directory is empty",
|
||||
"browse": "Browse",
|
||||
"record": "Record",
|
||||
"log": "Log",
|
||||
"run": "Run",
|
||||
"execute": "Execute",
|
||||
"download": "Download",
|
||||
"searchPlaceholder": "Search name, description...",
|
||||
"allStatus": "All Status",
|
||||
"allEnv": "All Environments",
|
||||
"allType": "All Types",
|
||||
"pagination": "{{n}}/page"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -654,5 +654,496 @@
|
||||
"closed": "已关闭"
|
||||
}
|
||||
}
|
||||
},
|
||||
"deploy": {
|
||||
"pipeline": {
|
||||
"title": "流水线",
|
||||
"subtitle": "CI/CD 构建 · 部署 · 发布一体化",
|
||||
"newPipeline": "新建流水线",
|
||||
"createFirst": "创建第一个流水线",
|
||||
"searchPlaceholder": "搜索流水线...",
|
||||
"noData": "暂无流水线",
|
||||
"triggered": "已触发",
|
||||
"triggerFailed": "触发失败",
|
||||
"stopRun": "停止运行",
|
||||
"stopConfirm": "确定要停止此运行吗?",
|
||||
"stopped": "已停止",
|
||||
"stopFailed": "停止失败",
|
||||
"noRunningTask": "未找到运行中的任务",
|
||||
"deletePipeline": "删除流水线",
|
||||
"deleteConfirm": "确定删除「{{name}}」?",
|
||||
"deleted": "已删除",
|
||||
"deleteFailed": "删除失败",
|
||||
"detail": "流水线详情",
|
||||
"notExist": "流水线不存在",
|
||||
"config": "流水线配置",
|
||||
"name": "流水线名称",
|
||||
"namePlaceholder": "请输入流水线名称",
|
||||
"type": "流水线类型",
|
||||
"stages": "流水线阶段 ({{count}})",
|
||||
"allStages": "全阶段",
|
||||
"noStages": "暂无阶段配置",
|
||||
"clickToAddStage": "点击「添加阶段」开始",
|
||||
"addStage": "添加阶段",
|
||||
"newStage": "新阶段",
|
||||
"addTask": "添加任务",
|
||||
"newTask": "新任务",
|
||||
"taskEdit": "任务编辑",
|
||||
"selectTaskHint": "选择一个任务开始编辑",
|
||||
"matchPreview": "流水线命中预览",
|
||||
"created": "流水线已创建",
|
||||
"createFailed": "创建失败",
|
||||
"saving": "保存中...",
|
||||
"save": "保存",
|
||||
"editPipeline": "编辑流水线",
|
||||
"modifyConfig": "修改流水线配置",
|
||||
"configureNew": "配置新的 CI/CD 流水线",
|
||||
"editMode": "保存修改",
|
||||
"createMode": "创建流水线",
|
||||
"desc": "暂无描述",
|
||||
"buildNumber": "构建",
|
||||
"runs": "运行次数",
|
||||
"neverRun": "从未运行",
|
||||
"runNow": "立即执行",
|
||||
"executing": "执行中...",
|
||||
"logOutput": "暂无日志输出",
|
||||
"noLogStage": "该阶段暂无日志输出",
|
||||
"realtimeOutput": "流水线执行中,实时输出...",
|
||||
"buildDir": "流水线构建目录终端",
|
||||
"fileBrowser": "文件浏览器 #{{buildNumber}}",
|
||||
"buildDirFiles": "流水线构建目录文件浏览",
|
||||
"workspaceTerminal": "Workspace 终端 #{{buildNumber}}",
|
||||
"execLog": "执行日志 #{{number}}",
|
||||
"release": "发布 #{{number}}",
|
||||
"all": "全部 ({{count}})"
|
||||
},
|
||||
"stage": {
|
||||
"checkout": "代码检出",
|
||||
"build": "构建",
|
||||
"image": "镜像打包",
|
||||
"deploy": "部署",
|
||||
"test": "测试",
|
||||
"custom": "自定义",
|
||||
"tasks": "{{count}} 任务",
|
||||
"selectOrder": "按顺序选择阶段",
|
||||
"checkoutDesc": "拉取代码",
|
||||
"buildDesc": "构建打包",
|
||||
"imageDesc": "推送镜像",
|
||||
"deployDesc": "部署到Kubernetes",
|
||||
"testDesc": "代码检查",
|
||||
"checkoutNeedGit": "代码检出阶段需要填写 Git URL",
|
||||
"imageNeedDocker": "镜像打包阶段需要关联 Docker 凭证",
|
||||
"suggestDocker": "建议关联凭证",
|
||||
"needDocker": "需要关联 Docker 凭证"
|
||||
},
|
||||
"env": {
|
||||
"all": "全部",
|
||||
"production": "生产",
|
||||
"testing": "测试",
|
||||
"staging": "预发布",
|
||||
"development": "开发",
|
||||
"prodEnv": "生产环境",
|
||||
"testEnv": "测试环境",
|
||||
"stagingEnv": "预发环境",
|
||||
"devEnv": "开发环境",
|
||||
"selectEnv": "选择环境",
|
||||
"envType": "环境类型",
|
||||
"envGroup": "环境分组",
|
||||
"envLabel": "环境标识",
|
||||
"selectEnvHint": "选择后流水线执行记录会关联到对应环境",
|
||||
"addEnv": "新增环境",
|
||||
"editEnv": "编辑环境",
|
||||
"envManage": "环境管理 ({{count}})",
|
||||
"noEnvConfig": "暂无环境配置,点击\"新增环境\"创建"
|
||||
},
|
||||
"trigger": {
|
||||
"manual": "手动",
|
||||
"manualTrigger": "手动触发",
|
||||
"manualExec": "手动触发执行",
|
||||
"gitPush": "Git Push 触发",
|
||||
"gitPushAuto": "Git Push 自动触发",
|
||||
"cron": "Cron 定时执行",
|
||||
"webhook": "Webhook 触发",
|
||||
"externalWebhook": "外部 Webhook 调用",
|
||||
"method": "触发方式",
|
||||
"triggerBuild": "触发构建",
|
||||
"settings": "触发设置",
|
||||
"listenBranch": "监听分支",
|
||||
"excludeBranch": "排除分支",
|
||||
"cronExpr": "Cron 表达式",
|
||||
"every5min": "每5分钟",
|
||||
"everyHour": "每小时",
|
||||
"everyDay2": "每天2点",
|
||||
"everySunday": "每周日",
|
||||
"tagRelease": "Tag 发版",
|
||||
"branchTag": "分支 / Tag",
|
||||
"noTriggerMode": "手动"
|
||||
},
|
||||
"run": {
|
||||
"status": "状态",
|
||||
"triggeredBy": "触发人",
|
||||
"triggerMode": "触发方式",
|
||||
"duration": "耗时",
|
||||
"startTime": "开始时间",
|
||||
"branch": "分支",
|
||||
"commit": "代码",
|
||||
"noRecords": "暂无执行记录",
|
||||
"noRecordsHint": "暂无执行记录,点击\"立即执行\"触发构建",
|
||||
"stopRun": "停止运行",
|
||||
"stopConfirm": "确定要停止此运行吗?",
|
||||
"buildStatus": "构建执行状态",
|
||||
"buildLog": "构建日志",
|
||||
"execStage": "执行阶段",
|
||||
"fullFlowVisual": "全流程可视化"
|
||||
},
|
||||
"status": {
|
||||
"pending": "待执行",
|
||||
"running": "运行中",
|
||||
"success": "成功",
|
||||
"failed": "失败",
|
||||
"stopped": "已停止",
|
||||
"building": "构建中",
|
||||
"deploying": "发布中",
|
||||
"succeeded": "发布成功",
|
||||
"failed_deploy": "发布失败",
|
||||
"rolledBack": "已回滚",
|
||||
"pendingRelease": "待发布",
|
||||
"pendingApproval": "待审批",
|
||||
"approved": "已审批",
|
||||
"rejected": "已驳回",
|
||||
"cancelled": "已取消",
|
||||
"expired": "已过期",
|
||||
"created": "已创建",
|
||||
"updated": "已更新",
|
||||
"deleted": "已删除",
|
||||
"enabled": "已启用",
|
||||
"disabled": "已禁用",
|
||||
"installed": "已安装",
|
||||
"notInstalled": "未安装",
|
||||
"installing": "安装中"
|
||||
},
|
||||
"cred": {
|
||||
"title": "凭据管理",
|
||||
"subtitle": "统一管理 SSH 密钥、Docker 密码、AKSK、数据库等敏感凭据(AES 加密存储)",
|
||||
"addCredential": "新增凭据",
|
||||
"createFirst": "创建第一个凭据",
|
||||
"searchPlaceholder": "搜索凭据...",
|
||||
"credName": "凭据名称",
|
||||
"nameRequired": "请填写凭据名称",
|
||||
"credType": "类型",
|
||||
"authMethod": "认证方式",
|
||||
"noCredentials": "暂无凭据",
|
||||
"credCount": "{{count}} 个凭据",
|
||||
"editCred": "编辑凭据",
|
||||
"newCred": "新增凭据",
|
||||
"deleteCred": "删除凭据",
|
||||
"credData": "密钥数据",
|
||||
"noCredData": "未找到凭据数据",
|
||||
"refId": "引用ID",
|
||||
"refIdCopied": "引用 ID 已复制",
|
||||
"refHint": "在流水线/脚本中引用此凭据:",
|
||||
"credDetail": "凭据详情",
|
||||
"refIdLabel": "引用ID:",
|
||||
"descDefault": "管理敏感凭据信息",
|
||||
"suggestLink": "建议关联凭证",
|
||||
"notLinked": "不关联",
|
||||
"notLinkedCred": "不关联凭证",
|
||||
"selectDocker": "选择 Docker 凭证",
|
||||
"selectDockerPwd": "选择 Docker 密码凭据",
|
||||
"selectApiCred": "选择凭据(API/密码等)",
|
||||
"selectCred": "选择凭证",
|
||||
"linkedCred": "关联凭证"
|
||||
},
|
||||
"release": {
|
||||
"title": "应用发布",
|
||||
"subtitle": "管理应用版本发布与审批流程",
|
||||
"newRelease": "新建发布",
|
||||
"searchApp": "搜索应用名称或版本...",
|
||||
"noRecords": "暂无发布记录",
|
||||
"appName": "应用名称",
|
||||
"version": "版本",
|
||||
"versionNo": "版本号",
|
||||
"releaseDesc": "发布说明",
|
||||
"releaseProgress": "发布进度",
|
||||
"releaseDetail": "发布详情",
|
||||
"approve": "审批发布",
|
||||
"approveFail": "审批失败",
|
||||
"approveHint": "确认审批后将进入部署就绪状态",
|
||||
"reject": "驳回",
|
||||
"rejectFail": "驳回失败",
|
||||
"deploy": "部署",
|
||||
"deployStarted": "部署已启动",
|
||||
"deployFail": "部署失败",
|
||||
"confirmDeploy": "确认部署",
|
||||
"rollback": "回滚",
|
||||
"rollbackSuccess": "回滚成功",
|
||||
"rollbackFail": "回滚失败",
|
||||
"confirmRollback": "确认回滚",
|
||||
"redeploy": "重新部署",
|
||||
"redeployFail": "重新部署失败",
|
||||
"redeployed": "已重新触发部署",
|
||||
"submitApp": "提交申请",
|
||||
"submitFail": "发布申请已提交",
|
||||
"createNew": "创建新的应用版本发布申请",
|
||||
"appPlaceholder": "例如: demo-jar 后端部署",
|
||||
"nameVerRequired": "请填写应用名称和版本号",
|
||||
"getReleaseFail": "获取发布列表失败",
|
||||
"deployEnv": "部署环境:",
|
||||
"targetEnv": "目标环境",
|
||||
"releaseConfig": "发布配置管理",
|
||||
"releaseRecords": "发布记录 ({{count}})",
|
||||
"releaseFlow": "发布流程",
|
||||
"releasePerson": "发布人",
|
||||
"releaseManage": "发布管理"
|
||||
},
|
||||
"tool": {
|
||||
"title": "工具配置",
|
||||
"subtitle": "管理 DevOps 工具的安装策略:预装在镜像中、首次使用自动下载(懒加载)、或禁用不安装",
|
||||
"installMethod": "安装方式",
|
||||
"preinstall": "预装",
|
||||
"lazyLoad": "懒加载",
|
||||
"selectVersion": "选择安装版本",
|
||||
"versionPrompt": "{{name}} — 请选择要安装的版本",
|
||||
"noConfig": "暂无工具配置,请检查后端种子数据",
|
||||
"getToolFail": "获取工具配置失败",
|
||||
"installed": "已安装",
|
||||
"notInstalled": "未安装",
|
||||
"installing": "安装中",
|
||||
"test": "测试",
|
||||
"install": "安装"
|
||||
},
|
||||
"rbac": {
|
||||
"title": "发布权限",
|
||||
"subtitle": "Jenkins-style Role Strategy — 按流水线 code 正则匹配分配角色",
|
||||
"newRole": "新建 Item Role",
|
||||
"newGroup": "新建用户组",
|
||||
"assignToUser": "分配角色给用户",
|
||||
"userGroupManage": "用户组管理",
|
||||
"groupDesc": "创建用户组,将组授权给流水线,组内成员自动获得流水线权限",
|
||||
"noRoles": "暂无 Item Role",
|
||||
"noGroups": "暂无用户组,点击「新建用户组」创建",
|
||||
"noDirectUsers": "暂无直接用户",
|
||||
"noGroupAuth": "暂无组授权 — 在「",
|
||||
"noGroupAuthSuffix": "」页面创建组后,可在此授权",
|
||||
"directUsers": "👤 直接用户授权 ({{count}})",
|
||||
"groupAssignments": "👥 用户组授权 ({{count}})",
|
||||
"rolePattern": "正则匹配 Pattern",
|
||||
"regexEmpty": "正则不能为空",
|
||||
"noMatch": "无匹配 — 请调整正则表达式",
|
||||
"regexError": "❌ 正则语法错误",
|
||||
"matchCount": "{{count}} 条",
|
||||
"matchPreview": "流水线命中预览",
|
||||
"roleHint": "— 选择一个角色查看哪些流水线会被匹配",
|
||||
"owner": "拥有者",
|
||||
"editor": "编辑者",
|
||||
"viewer": "查看者",
|
||||
"ownerRole": "拥有者 (owner)",
|
||||
"editorRole": "编辑者 (editor)",
|
||||
"viewerRole": "查看者 (viewer)",
|
||||
"assigned": "已分配",
|
||||
"assignedRoles": "已分配角色:",
|
||||
"addUser": "添加用户",
|
||||
"selectUser": "选择用户",
|
||||
"selectUserPlaceholder": "选择用户...",
|
||||
"selectRole": "选择角色",
|
||||
"assign": "分配",
|
||||
"assignFail": "分配失败",
|
||||
"memberManage": "成员管理 ({{count}})",
|
||||
"addMember": "添加用户",
|
||||
"removeMember": "移除成员",
|
||||
"removeConfirm": "确定要移除此成员吗?",
|
||||
"removeFail": "移除失败",
|
||||
"noMembers": "暂无成员",
|
||||
"addedMember": "已添加成员",
|
||||
"removed": "已移除",
|
||||
"groupNewTitle": "新建用户组",
|
||||
"groupEditTitle": "编辑用户组",
|
||||
"groupName": "组名",
|
||||
"groupPlaceholder": "请输入组名",
|
||||
"createGroup": "创建",
|
||||
"creating": "创建中...",
|
||||
"deleteGroup": "删除用户组",
|
||||
"deleteRole": "删除角色",
|
||||
"userCol": "用户",
|
||||
"noUserRole": "该用户尚未分配任何 Item Role"
|
||||
},
|
||||
"banner": {
|
||||
"build": "构建",
|
||||
"deploy": "部署",
|
||||
"sshHost": "SSH 主机",
|
||||
"kubernetes": "Kubernetes",
|
||||
"imageRegistry": "镜像仓库",
|
||||
"sshDesc": "传统主机 SCP 部署 · 无需镜像仓库",
|
||||
"k8sDesc": "容器化部署 · 需镜像仓库推送",
|
||||
"fullFlow": "全流程可视化"
|
||||
},
|
||||
"template": {
|
||||
"go": "Go 项目",
|
||||
"goDesc": "适用于 Go 后端项目",
|
||||
"java": "Java 项目",
|
||||
"javaDesc": "适用于 Java Spring Boot 项目",
|
||||
"nodejs": "Node.js 项目",
|
||||
"nodejsDesc": "适用于 Node.js 前端项目",
|
||||
"python": "Python 项目",
|
||||
"pythonDesc": "适用于 Python 项目",
|
||||
"selectTemplate": "选择模板",
|
||||
"mavenBuild": "Maven构建",
|
||||
"dependencyInstall": "依赖安装",
|
||||
"unitTest": "单元测试",
|
||||
"healthCheck": "健康检查",
|
||||
"package": "打包",
|
||||
"verify": "验证",
|
||||
"detect": "检测"
|
||||
},
|
||||
"var": {
|
||||
"title": "变量",
|
||||
"addVar": "添加变量",
|
||||
"varName": "变量名",
|
||||
"varValue": "变量值",
|
||||
"varAlias": "变量别名",
|
||||
"noVars": "暂无变量,点击\"添加变量\"新增",
|
||||
"envVar": "环境变量",
|
||||
"envVarOptional": "环境变量 (可选)"
|
||||
},
|
||||
"table": {
|
||||
"name": "名称",
|
||||
"code": "代码",
|
||||
"codeCol": "代码仓库",
|
||||
"type": "类型",
|
||||
"status": "状态",
|
||||
"env": "环境",
|
||||
"duration": "耗时",
|
||||
"trigger": "触发方式",
|
||||
"triggerBy": "触发人",
|
||||
"startTime": "开始时间",
|
||||
"actions": "操作",
|
||||
"sortOrder": "排序",
|
||||
"modifyTime": "修改时间",
|
||||
"size": "大小",
|
||||
"color": "颜色",
|
||||
"icon": "图标",
|
||||
"displayName": "显示名称",
|
||||
"envId": "环境标识",
|
||||
"successRate": "成功率",
|
||||
"todayRelease": "今日发布",
|
||||
"defaultBranch": "默认分支",
|
||||
"repoUrl": "仓库 URL",
|
||||
"tagLabel": "标签",
|
||||
"version": "版本",
|
||||
"user": "用户",
|
||||
"category": "分类"
|
||||
},
|
||||
"form": {
|
||||
"name": "名称",
|
||||
"nameStar": "名称 *",
|
||||
"nameRequired": "请填写名称",
|
||||
"code": "代码 (唯一标识)",
|
||||
"desc": "描述",
|
||||
"descOptional": "描述 (可选)",
|
||||
"repoUrlStar": "仓库 URL *",
|
||||
"registryUrlStar": "Registry URL *",
|
||||
"nameAddrRequired": "请填写名称和地址",
|
||||
"concurrent": "并发执行数",
|
||||
"concurrentHint": "设为 1 则按顺序串行执行,默认 2 可并发构建",
|
||||
"serial": "1 — 串行",
|
||||
"gitCred": "Git 凭证",
|
||||
"jobName": "Job 名称",
|
||||
"envVars": "环境变量",
|
||||
"deployMode": "部署模式",
|
||||
"deployTarget": "部署目标",
|
||||
"commitId": "Commit ID (可选)",
|
||||
"dockerfilePath": "Dockerfile 路径",
|
||||
"buildCache": "构建缓存",
|
||||
"cachePaths": "多个路径用逗号分隔,相同的 Key 会命中已有缓存",
|
||||
"registryAddr": "Registry 地址",
|
||||
"imageName": "镜像命名:",
|
||||
"varRef": "(${'{VAR_NAME}'} 引用)",
|
||||
"scriptType": "脚本类型",
|
||||
"scriptContent": "脚本内容",
|
||||
"buildQueue": "构建队列",
|
||||
"defaultNamespace": "默认命名空间",
|
||||
"defaultEnabled": "默认启用",
|
||||
"notSpecified": "不指定",
|
||||
"save": "保存",
|
||||
"cancel": "取消",
|
||||
"create": "创建",
|
||||
"update": "更新"
|
||||
},
|
||||
"toast": {
|
||||
"saved": "已保存",
|
||||
"updated": "已更新",
|
||||
"deleted": "已删除",
|
||||
"created": "已创建",
|
||||
"enabled": "已启用",
|
||||
"disabled": "已禁用",
|
||||
"installed": "已安装",
|
||||
"triggered": "已触发",
|
||||
"stopped": "已停止",
|
||||
"added": "已添加",
|
||||
"removed": "已移除",
|
||||
"revoked": "已撤销",
|
||||
"approved": "已审批",
|
||||
"rejected": "已驳回",
|
||||
"cancelled": "已取消",
|
||||
"expired": "已过期",
|
||||
"rolledBack": "已回滚",
|
||||
"redeployed": "已重新触发部署",
|
||||
"assigned": "已分配",
|
||||
"createdPipeline": "流水线已创建",
|
||||
"releaseSubmitted": "发布申请已提交",
|
||||
"deployStarted": "部署已启动",
|
||||
"saveFailed": "保存失败",
|
||||
"updateFailed": "更新失败",
|
||||
"deleteFailed": "删除失败",
|
||||
"createFailed": "创建失败",
|
||||
"triggerFailed": "触发失败",
|
||||
"stopFailed": "停止失败",
|
||||
"addFailed": "添加失败",
|
||||
"removeFailed": "移除失败",
|
||||
"revokeFailed": "撤销失败",
|
||||
"approveFailed": "审批失败",
|
||||
"rejectFailed": "驳回失败",
|
||||
"deployFailed": "部署失败",
|
||||
"rollbackFailed": "回滚失败",
|
||||
"redeployFailed": "重新部署失败",
|
||||
"assignFailed": "分配失败",
|
||||
"batchDeleteFailed": "批量删除失败",
|
||||
"cancelFailed": "取消失败",
|
||||
"operationFailed": "操作失败",
|
||||
"getDataFailed": "获取数据失败",
|
||||
"loadFailed": "加载失败",
|
||||
"saveSuccess": "保存成功"
|
||||
},
|
||||
"label": {
|
||||
"basicInfo": "基本信息",
|
||||
"flowConfig": "流程配置",
|
||||
"triggerSettings": "触发设置",
|
||||
"variables": "变量",
|
||||
"credentials": "凭据",
|
||||
"environments": "环境",
|
||||
"toolConfig": "工具配置",
|
||||
"releaseConfig": "发布配置",
|
||||
"releaseRecords": "发布记录",
|
||||
"permission": "发布权限",
|
||||
"userGroups": "用户组",
|
||||
"roles": "角色",
|
||||
"gitRepo": "Git 仓库 ({{count}})",
|
||||
"registry": "镜像仓库 ({{count}})",
|
||||
"envManage": "环境管理 ({{count}})",
|
||||
"advanced": "高级",
|
||||
"loading": "加载中...",
|
||||
"emptyDir": "目录为空",
|
||||
"browse": "浏览",
|
||||
"record": "记录",
|
||||
"log": "日志",
|
||||
"run": "运行",
|
||||
"execute": "执行",
|
||||
"download": "下载",
|
||||
"searchPlaceholder": "搜索名称、描述...",
|
||||
"allStatus": "全部状态",
|
||||
"allEnv": "全部环境",
|
||||
"allType": "全部类型",
|
||||
"pagination": "{{n}}条/页"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user