日志过大,更多日志请下载查看
+ {{ $t('logViewer.moreLog') }}
{{ idx + 1 }}
diff --git a/ui/src/components/data/text-copy/index.vue b/ui/src/components/data/text-copy/index.vue
index 094367fe533b3673e558e198ee2b695e16b4ad2e..2bec495c2d03217c75a8dc8a7a861325c2ad5f04 100644
--- a/ui/src/components/data/text-copy/index.vue
+++ b/ui/src/components/data/text-copy/index.vue
@@ -2,9 +2,9 @@
-
+
-
+
@@ -12,6 +12,7 @@
-
\ No newline at end of file
+
diff --git a/ui/src/components/workflow/workflow-viewer/toolbar.vue b/ui/src/components/workflow/workflow-viewer/toolbar.vue
index 3727393a9164960f19bbdf706b04080b3ab2a4cf..022db8a2d0658e0e3445711be5dd7bba2e8c13cb 100644
--- a/ui/src/components/workflow/workflow-viewer/toolbar.vue
+++ b/ui/src/components/workflow/workflow-viewer/toolbar.vue
@@ -2,53 +2,61 @@
能会导致一些已知问题或有更好的节点可替代它)', + sync: '同步', + delete: '删除', + nameRequired: '名称不能为空', + dslRequired: 'DSL不能为空', + createSuccess: '新增成功', + deleteNodeTitle: '删除节点', + deleteConfirm: '确定要删除节点吗?', + deleteSuccess: '删除成功', + syncTitle: '同步DSL', + syncConfirm: '确定要同步吗?', + syncSuccess: '同步成功', + }, + editor: { + cancel: '取消', + previousStep: '上一步', + saveAndBack: '保存并返回', + save: '保存', + selectProjectGroup: '选择项目组', + pleaseSelectProjectGroup: '请选择项目组', + dslMode: 'DSL模式', + validationProjectGroup: '请选择项目组', + dslEmptyError: 'DSL不能为空', + saveSuccess: '保存成功', + createSuccess: '新增成功', + }, + importStepOne: { + cancel: '取消', + next: '下一步', + subgroups: '分组', + selectGroup: '请选择项目组', + enterUrl: '请输入URL,例如:https://gitee.com/jianmu-dev/jianmu.git', + branch: '分支', + enterBranch: '请输入分支', + auth: '认证:', + type: '类型', + selectType: '请选择类型', + username: '用户名', + selectUsername: '请选择用户名', + password: '密码', + selectPassword: '请选择密码', + selectUsernameAgain: '请选择用户名', + privateKey: '私钥', + selectPrivateKey: '请选择私钥', + uriRequired: 'URI不能为空', + groupRequired: '项目分组不能为空', + branchRequired: '分支不能为空', + mustSelectType: '请选择类型', + mustSelectUsername: '请选择用户名', + mustSelectPassword: '请选择密码', + }, + importStepTwo: { + cancel: '取消', + previous: '上一步', + save: '保存', + selectDsl: '请选择DSL文件', + importSuccess: '导入成功', + }, + importer: { + cloneGitRepo: '克隆Git仓库', + selectDSL: '选择DSL文件', + }, + pipelineEditor: { + unnamedProject: '未命名项目', + createSuccess: '新增成功', + saveSuccess: '保存成功', + }, + projectGroupManager: { + close: '关闭', + newGroup: '新建分组', + projectGroup: '项目分组', + totalGroups: '(共有 { total } 个组)', + closeSorting: '关闭排序', + sorting: '排序', + none: '无', + lastModified: '最后修改时间:', + total: '共', + items: '条项目', + homeShow: '首页展示', + confirmDeleteGroup: '确定要删除分组吗?', + name: '名称:', + deleteGroup: '删除分组', + confirm: '确定', + cancel: '取消', + deleteSuccess: '项目分组删除成功', + }, + projectGroupEditor: { + title: '编辑项目分组', + name: '分组名称', + namePlaceholder: '请输入分组名称', + isShow: '首页展示', + description: '描述', + descriptionPlaceholder: '请输入描述', + descriptionTips: '描述信息不超过 256个字符', + cancel: '取消', + save: '保存', + nameRequired: '分组名称不能为空', + success: '项目分组修改成功', + }, + projectGroupDetail: { + close: '关闭', + totalProjects: '(共有 { count } 个项目)', + none: '无', + addProject: '添加项目', + projectList: '项目列表', + closeSorting: '关闭排序', + sorting: '排序', + }, + projectGroupCreator: { + title: '新建项目分组', + name: '分组名称', + namePlaceholder: '请输入分组名称', + isShow: '首页展示', + description: '描述', + descriptionPlaceholder: '请输入描述', + descriptionTips: '描述信息不超过 256个字符', + cancel: '取消', + confirm: '确定', + nameRequired: '分组名称不能为空', + success: '项目分组创建成功', + }, + projectAdder: { + title: '添加项目', + selectGroup: '选择项目组', + selectGroupPlaceholder: '请选择项目组', + selectedProject: '已选项目', + inputPlaceholder: '请输入项目名称或描述', + none: '无', + cancel: '取消', + confirm: '确定', + selectGroupRequired: '请选择项目组', + addProjectRequired: '请添加项目', + success: '项目添加成功', + }, + skManager: { + close: '关闭', + title: '密钥列表', + total: '(共有 { keys } 个密钥)', + add: '新增密钥', + none: '无', + confirmDelete: '确定要删除密钥吗?', + name: '名称:', + delete: '删除密钥', + confirm: '确定', + cancel: '取消', + success: '删除成功', + }, + skEditor: { + title: '新增密钥', + name: '名称', + namePlaceholder: '请输入名称', + value: '值', + valuePlaceholder: '请输入值', + cancel: '取消', + confirm: '确定', + nameRequired: '名称不能为空', + valueRequired: '值不能为空', + success: '新增成功', + }, + nsManager: { + close: '关闭', + add: '新增命名空间', + title: '命名空间', + total: '(共有 { length } 个命名空间)', + none: '无', + lastModified: '最后修改时间:', + confirmDelete: '确定要删除命名空间吗?', + nameLabel: '名称:', + deleteTitle: '删除命名空间', + confirm: '确定', + cancel: '取消', + success: '删除成功', + }, + nsEditor: { + title: '新增密钥命名空间', + name: '命名空间', + namePlaceholder: '请输入命名空间', + description: '描述', + descriptionPlaceholder: '请输入描述', + cancel: '取消', + confirm: '确定', + nameRequired: '命名空间不能为空', + success: '新增成功', + }, + workersManager: { + close: '关闭', + title: 'Worker列表', + total: '(共有 { length } 个Worker)', + name: '名称:', + label: '标签:', + none: '无', + os: '操作系统:', + arch: '架构:', + type: '类型:', + time: '注册时间:', + confirmDeleteMsg: '确定要删除Worker吗?', + confirmDeleteTitle: '删除Worker', + confirm: '确定', + cancel: '取消', + success: '删除成功', + }, + detail: { + terminateAll: '终止全部', + trigger: '触发', + notClickable: '暂无法点击', + startTime: '启动时间', + endTime: '完成时间', + suspendedDuration: '挂起时长', + executionDuration: '执行时长', + none: '无', + instanceId: '流程实例ID', + version: '流程版本号', + terminate: '终止', + success: '操作成功', + confirmTrigger: '确定要触发吗?', + triggerExecution: '触发项目执行', + confirm: '确定', + cancel: '取消', + terminatingSuccess: '操作成功,正在终止,请稍后', + confirmTerminateAll: '确定要终止执行中/挂起的全部实例吗?', + terminateExecution: '终止项目执行', + confirmTerminate: '确定要终止吗?', + terminateSuccess: '终止成功', + }, + processLog: { + processName: '流程名称', + startTime: '启动时间', + endTime: '完成时间', + suspendedDuration: '挂起时长', + executionDuration: '执行时长', + instanceId: '流程实例ID', + version: '流程版本号', + loading: '加载中...', + }, + taskLog: { + processName: '流程名称', + executionCount: '执行次数', + nodeName: '节点名称', + successCount: '成功次数', + nodeDefinition: '节点定义', + failureCount: '失败次数', + startTime: '启动时间', + skipCount: '跳过次数', + executionDuration: '执行时长', + suspendedCount: '挂起次数', + executionStatus: '执行状态', + ignoreCount: '忽略次数', + log: '日志', + loading: '加载中...', + businessParams: '业务参数', + inputParams: '输入参数', + paramKey: '参数唯一标识', + paramType: '参数类型', + requiredOrNot: '是/否必填', + yes: '是', + no: '否', + paramValue: '参数值', + outputParams: '输出参数', + cache: '缓存', + mountPath: '挂载目录', + status: '状态', + unavailableTipLine1: '对于不可用的缓存,可到项目卡片-', + unavailableTipLine2: '更多-缓存中清理或项目编辑页删除', + available: '可用', + unavailable: '不可用', + requiredField: '必填项', + }, + webhookLog: { + processName: '流程名称:', + nodeName: '节点名称:', + startTime: '启动时间:', + log: '日志', + businessParams: '业务参数', + paramKey: '参数唯一标识', + paramType: '参数类型', + paramValue: '参数值', + notTriggered: '尚未触发', + manualTriggerLog: '此次为手动触发,无webhook日志', + }, + workflow: { + taskLogTitle: '查看任务执行日志', + processLogTitle: '查看流程日志', + webhookLogTitle: '查看Webhook日志', + }, + index: { + graphProject: '图形项目', + codeProject: '代码项目', + workerManager: 'Worker管理', + localNode: '本地节点', + groupManager: '分组管理', + secretKeyManager: '密钥管理', + }, + main: { + componentLib: '组件库', + loginPage: '登录页', + errorPage: '错误页:', + browserVersion: '浏览器版本', + network: '网络', + }, + login: { + welcome: '欢迎登录', + usernamePlaceholder: '请输入用户名', + passwordPlaceholder: '请输入密码', + remember: '记住用户名', + login: '登录', + loginProblem: '登录遇到问题,请尝试重新登录', + cancel: '取消', + reLogin: '重新登录', + loggingInWith: '{type} 账号登录中…', + loginWith: '使用 {type} 账号登录', + usernameEmpty: '用户名不能为空', + passwordEmpty: '密码不能为空', + success: '登录成功', + }, + projectGroup: { + viewMore: '查看更多', + noProjects: '没有项目', + noResult: '没有找到相关结果', + totalProjects: '共有 { count } 个项目', + }, + cacheDrawerItem: { + unavailable: '不可用', + clear: '清理', + viewMount: '查看挂载点', + noMount: '未设置挂载点', + node: '节点', + mountDir: '挂载目录', + confirmClearTitle: '确定清理当前缓存?', + confirmClearTip: '旧的缓存数据将被清空', + cancel: '取消', + confirm: '确定', + clearSuccess: '清理成功', + }, + cacheDrawer: { + viewCache: '查看缓存', + }, + projectItem: { + concurrent: '可并发', + tipInit: + '前序流程正在执行或已挂起,待执行完毕或手动终止后,本次流程将开始执行。 或开启并发执行,开启后,多次可同时执行。', + tipSuspended: '当前流程中某个节点执行失败,流程处于暂停状态,需要手动 重试/忽略 挂起节点。', + terminate: '终止', + nextTime: '距离下次执行还有', + suspended: '挂起', + running: '执行', + duration: '时长', + disabled: '已禁用,不可', + trigger: '触发', + edit: '编辑', + sync: '同步DSL', + openGit: '打开git仓库', + previewWorkflow: '预览流程', + previewPipeline: '预览管道', + disable: '禁用', + enable: '启用', + delete: '删除', + cache: '缓存', + + project: '项目', + failed: '失败', + Running: '执行中', + succeeded: '成功', + notStarted: '未启动', + pending: '待启动', + nextTimeTip: '定时项目:下次执行时间', + confirmTerminate: '确定要终止吗?', + terminateTitle: '终止项目执行', + confirm: '确定', + cancel: '取消', + terminateSuccess: '终止成功', + operationSuccess: '操作成功', + confirmTrigger: '确定要触发吗?', + triggerTitle: '触发项目执行', + confirmGeneric: '确定要', + enabled: '已启用', + Disabled: '已禁用', + notModifiable: '不可修改', + dslUpdateTip: '若要修改,请通过DSL更新', + close: '关闭', + disableProject: '禁用项目', + enableProject: '启用项目', + confirmSync: '确定要同步吗?', + syncTitle: '同步DSL', + syncSuccess: '同步成功', + confirmDelete: '确定要删除项目吗?', + deleteTitle: '删除项目', + name: '名称:', + deleteSuccess: '删除成功', + }, + webhookDrawer: { + triggerTip: '可以通过调用以下Webhook地址来触发流程执行', + copyLink: '复制链接', + requestList: '请求列表', + noRecordLine1: '若无对应的触发记录,可到上游webhook管理中,', + noRecordLine2: '查看请求是否发送成功', + refresh: '刷新', + source: '来源', + requestTime: '请求时间', + status: '状态', + success: '成功', + failure: '失败', + errorMessage: '错误信息', + action: '操作', + retry: '重试', + details: '详情', + viewDetails: '查看详情', + trigger: '触发器', + paramList: '参数列表', + paramName: '参数唯一标识', + paramType: '参数类型', + paramValue: '参数值', + authRule: '认证规则', + noData: '暂无数据', + jsonPath: 'Json路径:', + copySuccess: '复制成功', + copyFailed: '复制失败,请手动复制', + retrySuccess: '重试成功', + confirmRetry: '确定要重试吗?', + confirm: '确认', + cancel: '取消', + }, + webhookSettingDialog: { + title: '触发执行', + tip: '项目已配置webhook,手动触发请填写参数', + importLast: '填入上次参数', + clear: '清空表单', + paramName: '参数名', + type: '类型', + paramValue: '参数值', + placeholder: '请输入参数值', + authRule: '认证规则', + cancel: '取消', + confirm: '确认', + selectPlaceholder: '请选择参数值', + }, + nodeToolbar: { + confirmRetry: '确定要重试吗?', + confirmIgnore: '确定要忽略吗?', + confirm: '确认', + cancel: '取消', + retry: '重试', + ignore: '忽略', + log: '日志', + param: '参数', + cache: '缓存', + }, + taskState: { + INIT: '待启动', + WAITING: '排队中', + RUNNING: '执行中', + SKIPPED: '已跳过', + FAILED: '执行失败', + SUCCEEDED: '执行成功', + SUSPENDED: '已挂起', + IGNORED: '已忽略', + }, + toolbar: { + exitFullScreen: '退出全屏', + fullScreen: '全屏', + originalSize: '原始大小', + fitToScreen: '适屏', + rotate: '旋转', + zoomOut: '缩小', + zoomIn: '放大', + workflowLog: '流程日志', + viewDsl: '查看DSL', + return: '返回', + workflow: '流程', + pipeline: '管道', + }, + projectPanel: { + title: '编辑项目信息', + name: '项目名称', + namePlaceholder: '请输入项目名称', + group: '项目分组', + groupPlaceholder: '请选择项目分组', + description: '项目描述', + descriptionPlaceholder: '请输入项目描述', + cancel: '取消', + confirm: '确定', + nameRequired: '请输入项目名称', + groupRequired: '请选择项目分组', + }, + topToolbar: { + zoomOut: '缩小', + zoomIn: '放大', + center: '居中', + cache: '缓存', + maxConcurrent: '最大并发数', + concurrentTip: '单个流程中可同时执行/挂起的实例数', + saveAndBack: '保存并返回', + save: '保存', + saveModification: '保存此次修改', + noSave: '不保存', + }, + nodeGroup: { + networkError: '网络开小差啦', + reload: '重新加载', + trigger: '触发器', + builtIn: '内置节点', + local: '本地节点', + official: '官方节点', + community: '社区节点', + }, + nodePanel: { + search: '搜索', + noResult: '没有搜到相关结果', + submitRequest: '欢迎提交节点需求', + }, + cacheEditor: { + placeholder: '请输入缓存唯一标识', + }, + cacheSelector: { + empty: '暂无缓存,请先到顶部缓存模块添加缓存', + placeholder: '请输入缓存要挂载的目录,以/开头', + }, + shellEnv: { + name: '变量名称', + placeholderName: '请输入变量名称', + value: '变量值', + placeholderValue: '请输入变量值', + }, + webhookParam: { + name: '名称', + namePlaceholder: '请输入参数名称', + nameRule: '以英文字母或下划线开头,支持下划线、数字、英文字母', + type: '类型', + typePlaceholder: '请选择参数类型', + expression: '表达式', + expressionTip: '详见', + extractionRule: '提取规则', + expressionPlaceholder: '请输入参数表达式', + required: '是否必填', + no: '否', + yes: '是', + default: '默认值', + defaultPlaceholder: '请输入默认值', + }, + asyncTaskPanel: { + name: '节点名称', + version: '节点版本', + versionPlaceholder: '请选择节点版本', + inputParam: '输入参数', + outputParam: '输出参数', + select: '请选择', + enter: '请输入', + cacheMount: '缓存挂载', + cacheMountTip: '在顶部缓存模块中添加缓存后,在此挂载', + add: '添加', + failureMode: '执行失败时', + suspend: '挂起', + ignore: '忽略', + type: '类型:', + description: '描述:', + noDescription: '暂无描述', + noOutput: '无输出参数', + }, + cachePanel: { + title: '缓存', + description: '添加缓存后可在节点中挂载,避免下次执行节点时重复下载依赖,提高执行速度。', + unique: '唯一标识', + uniqueRule: '以英文字母或下划线开头,支持下划线、数字、英文字母', + addCache: '添加缓存', + deleteTitle: '确定删除当前缓存?', + deleteTip: '删除后已引用该缓存的节点将会报错', + cancel: '取消', + confirm: '确认', + }, + cronPanel: { + placeholder: '请输入cron表达式', + meaningTitle: 'Cron表达式的7个部分从左到右代表的含义如下:', + meaningContent: '秒 分 时 日 月 周 年(可选,留空)', + exampleTitle: '常见表达式例子:', + example1: '0 0 12 * * ? 每天中午12点触发', + example2: '0 15 10 * * ? 每天上午10:15触发', + example3: '0 0 1 ? * SAT 每周六凌晨1点触发', + example4: '0 15 10 ? * MON-FRI 周一至周五的上午10:15触发', + example5: '0 * 10 * * ? 每天上午10点到10:59期间,每分钟触发一次', + }, + nodeConfigPanel: { + title: '节点配置面板', + }, + shellPanel: { + name: '节点名称', + image: 'docker镜像', + imagePlaceholder: '请选择或输入镜像', + env: '环境变量', + envTooltip1: '可以使用表达式,引用全局参数、事件参数', + envTooltip2: '或上游节点的输出参数,详见', + envTooltipLink: '参数章节', + addEnv: '添加环境变量', + script: '脚本', + scriptPlaceholder: '请输入shell脚本', + cache: '缓存挂载', + cacheTooltip: '在顶部缓存模块中添加缓存后,在此挂载', + addCache: '添加', + failureMode: '执行失败时', + suspend: '挂起', + ignore: '忽略', + }, + webhookPanel: { + triggerParam: '触发器参数', + triggerParamTip: '引用触发器参数参考', + paramSection: '参数章节', + addTriggerParam: '添加触发器参数', + advancedSetting: '高级设置', + authRule: '认证规则', + authRuleTip1: '若关闭认证规则,任何人皆可通过', + authRuleTip2: 'webhook触发此流程', + tokenTip: 'Webhook请求携带的认证鉴权数据', + tokenPlaceholder: '请输入token值', + valueTip1: '用于校验token值,相同则验证成功', + valueTip2: '必须是密钥类型', + valuePlaceholder: '请选择value值', + onlyRule: '匹配规则,结果为 true 时触发流程,当', + onlyTip: '前只可引用触发器参数。详见', + onlyLink: '运算表达式', + onlyPlaceholder: '请输入匹配规则', + }, + paramButton: { + label: '参数', + }, + workflowNodeToolbar: { + confirmDelete: '你确认要删除吗?', + name: '名称: ', + delete: '删除', + node: '节点', + trigger: '触发器', + confirm: '确认', + cancel: '取消', + }, + loadMore: { + show: '显示更多', + noMore: '没有更多了', + }, + breadcrumb: { + home: '首页', + worker: 'Worker管理', + localNode: '本地节点库', + group: '分组管理', + secretKey: '密钥管理', + addProject: '新增项目', + Details: '详情', + }, + workflowValidator: { + noNodes: '未存在任何节点', + atLeastOneShellOrTaskNode: '至少有一个shell或任务节点', + nodeNotConnected: '节点:尚未连接任何其他节点', + node: '节点:', + onlyOneTrigger: '只能有一个触发器', + }, + shell: { + enterVariableName: '请输入变量名', + enterVariableValue: '请输入变量值', + selectCache: '请选择缓存', + enterDirectory: '请输入目录', + enterDirectoryBeginningWithSlash: '请输入以/开头的目录', + selectOrEnterMirrorImage: '请选择或输入镜像', + }, + webhook: { + enterParamName: '请输入参数名称', + paramNamePattern: '以英文字母或下划线开头,支持下划线、数字、英文字母', + selectParamType: '请选择参数类型', + enterParamExpression: '请输入参数表达式', + selectParamDefaultValue: '请选择参数默认值', + enterParamDefaultValue: '请输入参数默认值', + triggerParamNotExist: '触发器参数不存在', + enterTokenValue: '请输入token值', + selectKey: '请选择密钥', + }, + cron: { + scheduleNotEmpty: 'schedule不能为空', + invalidCronExpression: '请输入正确的cron表达式', + }, + logViewer: { + downloading: '下载中,请稍后...', + download: '下载', + moreLog: '日志过大,更多日志请下载查看', + }, + textCopy: { + copy: '复制', + valueEmpty: '值为空', + copied: '已复制', + copyFailed: '复制失败', + cause: '原因:', + }, + }, + + en: { + top: { + logout: 'Logout', + language: 'Language', + LogoutSuccessful: 'Logout Successful', + }, + bottom: { + project: 'Mulan Incubator', + about: 'About Jianmu', + manual: 'Documentation', + contact: 'Contact Us', + }, + dialog: { + needLoginTip: 'The contents of the operation will be lost if you are not logged in', + }, + allProject: { + projectList: 'Project List', + inputPlaceholder: 'Please enter project name', + empty: 'No Projects', + default: 'Default Sort', + lastExecute: 'Recently triggered', + lastModify: 'Recent changes', + }, + searchProject: { + selectGroup: 'Please select a project group', + inputName: 'Please enter project name', + }, + network: { + title: 'Your device is not connected to the internet', + desc: 'This page cannot be displayed because your computer is currently offline', + backHome: 'Back to Home', + }, + browserVersion: { + unsupported: 'Sorry, this browser is not supported', + backHome: 'Back to Home', + }, + httpStatus: { + backHome: 'Back to Home', + noPermission: 'No permission to access this page', + pageNotFound: 'Page not found', + serverError: 'Server Error', + }, + nodeLibrary: { + addLocalNode: 'Add Local Node', + name: 'Name', + inputName: 'Please enter name', + description: 'Description', + inputDescription: 'Please enter description', + note: 'Note: When ref is xxx/xxx or xxx, it is uniformly handled as local/xxx and referenced as local/xxx:xxx in the process or pipeline dsl.', + cancel: 'Cancel', + confirm: 'Confirm', + close: 'Close', + nodeLibraryTitle: 'Jianmu Node Library', + nodeLibraryCount: '(Total { count } node definitions)', + tooltipDeprecated: 'This node is not recommended due to known issues or a better alternative', + sync: 'Sync', + delete: 'Delete', + nameRequired: 'Name cannot be empty', + dslRequired: 'DSL cannot be empty', + createSuccess: 'Created successfully', + deleteNodeTitle: 'Delete Node', + deleteConfirm: 'Are you sure you want to delete the node?', + deleteSuccess: 'Deleted successfully', + syncTitle: 'Sync DSL', + syncConfirm: 'Are you sure you want to sync?', + syncSuccess: 'Synced successfully', + }, + editor: { + cancel: 'Cancel', + previousStep: 'Previous Step', + saveAndBack: 'Save and Return', + save: 'Save', + selectProjectGroup: 'Select Project Group', + pleaseSelectProjectGroup: 'Please select a project group', + dslMode: 'DSL Mode', + validationProjectGroup: 'Please select a project group', + dslEmptyError: 'DSL cannot be empty', + saveSuccess: 'Saved successfully', + createSuccess: 'Created successfully', + }, + importStepOne: { + cancel: 'Cancel', + next: 'Next', + subgroups: 'Subgroups', + selectGroup: 'Please select the project group', + enterUrl: 'Please enter the URL, e.g. https://gitee.com/jianmu-dev/jianmu.git', + branch: 'Branch', + enterBranch: 'Please enter the branch', + auth: 'Authentication:', + type: 'Type', + selectType: 'Please select the type', + username: 'Username', + selectUsername: 'Please select the username', + password: 'Password', + selectPassword: 'Please select the password', + selectUsernameAgain: 'Please select the username', + privateKey: 'Private Key', + selectPrivateKey: 'Please select the private key', + uriRequired: 'URI can\'t be null', + groupRequired: 'Project grouping can\'t be null', + branchRequired: 'Branching can\'t be null', + mustSelectType: 'Please Select type', + mustSelectUsername: 'Please select username', + mustSelectPassword: 'Please select password', + }, + importStepTwo: { + cancel: 'Cancel', + previous: 'Previous Step', + save: 'Save', + selectDsl: 'Please select DSL file', + importSuccess: 'Import Successful', + }, + importer: { + cloneGitRepo: 'Clone Git Repository', + selectDSL: 'Select DSL File', + }, + pipelineEditor: { + unnamedProject: 'Untitled Project', + createSuccess: 'Created successfully', + saveSuccess: 'Saved successfully', + }, + projectGroupManager: { + close: 'Close', + newGroup: 'New Group', + projectGroup: 'Project Group', + totalGroups: '(Total { total } groups)', + closeSorting: 'Close Sorting', + sorting: 'Sorting', + none: 'None', + lastModified: 'Last Modified: ', + total: 'Total ', + items: ' items', + homeShow: 'Home Show', + confirmDeleteGroup: 'Sure you want to delete the group?', + name: 'Name: ', + deleteGroup: 'Delete Group', + confirm: 'Confirm', + cancel: 'Cancel', + deleteSuccess: 'Project Group Delete Successful', + }, + projectGroupEditor: { + title: 'Edit project grouping', + name: 'Grouping name', + namePlaceholder: 'Please enter the name of the grouping', + isShow: 'Home display', + description: 'Description', + descriptionPlaceholder: 'Please enter the description', + descriptionTips: 'The description information is not more than 256 characters', + cancel: 'Cancel', + save: 'Save', + nameRequired: 'The grouping name can not be empty', + success: 'Project grouping modification successful', + }, + projectGroupDetail: { + close: 'Close', + totalProjects: '(Total { count } projects)', + none: 'None', + addProject: 'add project', + projectList: 'project list', + closeSorting: 'close sorting', + sorting: 'sorting', + }, + projectGroupCreator: { + title: 'New project grouping', + name: 'Grouping name', + namePlaceholder: 'Please enter the name of the grouping', + isShow: 'Home display', + description: 'Description', + descriptionPlaceholder: 'Please enter the description', + descriptionTips: 'The description information is not more than 256 characters', + cancel: 'Cancel', + confirm: 'Confirm', + nameRequired: 'The grouping name must not be empty', + success: 'The project grouping was created successfully', + }, + projectAdder: { + title: 'Add project', + selectGroup: 'Select project group', + selectGroupPlaceholder: 'Please select project group', + selectedProject: 'Selected project', + inputPlaceholder: 'Please enter project name or description', + none: 'None', + cancel: 'Cancel', + confirm: 'Confirm', + selectGroupRequired: 'Please select project group', + addProjectRequired: 'Please add project', + success: 'Project added successfully', + }, + skManager: { + close: 'Close', + title: 'Secret Key List', + total: '(Total { keys } Secret Keys)', + add: 'New Secret Key', + none: 'None', + confirmDelete: 'Are you sure you want to delete the secret key?', + name: 'Name: ', + delete: 'Delete Secret Key', + confirm: 'Confirm', + cancel: 'Cancel', + success: 'Delete Successful', + }, + skEditor: { + title: 'Add Secret Key', + name: 'Name', + namePlaceholder: 'Please enter a name', + value: 'Value', + valuePlaceholder: 'Please enter a value', + cancel: 'Cancel', + confirm: 'Confirm', + nameRequired: 'Name can\'t be empty', + valueRequired: 'Value can\'t be empty', + success: 'Add success', + }, + nsManager: { + close: 'Close', + add: 'New Namespace', + title: 'Namespaces', + total: '(Total { length } namespaces)', + none: 'None', + lastModified: 'Last modified: ', + confirmDelete: 'Sure you want to delete namespace?', + nameLabel: 'Name: ', + deleteTitle: 'Delete Namespace', + confirm: 'Confirm', + cancel: 'Cancel', + success: 'Delete Successful', + }, + nsEditor: { + title: 'Add Secret Key Namespace', + name: 'Namespace', + namePlaceholder: 'Please enter the namespace', + description: 'Description', + descriptionPlaceholder: 'Please enter the description', + cancel: 'Cancel', + confirm: 'Confirm', + nameRequired: 'Namespace can\'t be empty', + success: 'New Successful', + }, + workersManager: { + close: 'Close', + title: 'Worker list', + total: '(Total { length } Workers)', + name: 'Name: ', + label: 'Label: ', + none: 'None', + os: 'Operating System: ', + arch: 'Architecture: ', + type: 'Type: ', + time: 'Registered: ', + confirmDeleteMsg: 'Sure you want to delete a Worker?', + confirmDeleteTitle: 'Delete Worker', + confirm: 'Confirm', + cancel: 'Cancel', + success: 'Delete Successful', + }, + detail: { + terminateAll: 'Terminate all', + trigger: 'Trigger', + notClickable: 'Not clickable at this time', + startTime: 'Start time', + endTime: 'Completion time', + suspendedDuration: 'Suspended Duration', + executionDuration: 'Execution Duration', + none: 'None', + instanceId: 'Process instance ID', + version: 'Process version number', + terminate: 'Terminate', + success: 'Operation successful', + confirmTrigger: 'Sure you want to trigger?', + triggerExecution: 'Trigger Project Execution', + confirm: 'Confirm', + cancel: 'Cancel', + terminatingSuccess: 'Operation Successful, terminating, please wait', + confirmTerminateAll: 'Sure you want to terminate all instances in execution/pending?', + terminateExecution: 'Terminate Project Execution', + confirmTerminate: 'Sure you want to terminate?', + terminateSuccess: 'Terminate Successful', + }, + processLog: { + processName: 'Process name', + startTime: 'Start time', + endTime: 'Completion time', + suspendedDuration: 'Suspended Duration', + executionDuration: 'Execution Duration', + instanceId: 'Process instance ID', + version: 'Process version number', + loading: 'Loading...', + }, + taskLog: { + processName: 'Process Name', + executionCount: 'Execution Count', + nodeName: 'Node Name', + successCount: 'Success Count', + nodeDefinition: 'Node Definition', + failureCount: 'Failure Count', + startTime: 'Start Time', + skipCount: 'Skip Count', + executionDuration: 'Execution Duration', + suspendedCount: 'Suspended Count', + executionStatus: 'Execution Status', + ignoreCount: 'Ignore Count', + log: 'Log', + loading: 'Loading...', + businessParams: 'Business Parameters', + inputParams: 'Input Parameters', + paramKey: 'Parameter Unique Identifier', + paramType: 'Parameter Type', + requiredOrNot: 'Yes/No Required', + yes: 'Yes', + no: 'No', + paramValue: 'Parameter Value', + outputParams: 'Output Parameters', + cache: 'Cache', + mountPath: 'Mounted Directory', + status: 'Status', + unavailableTipLine1: 'For unavailable caches, you can go to Project Cards -', + unavailableTipLine2: 'More - Cleanup in Cache or the Project Edit Page to delete', + available: 'Available', + unavailable: 'Unavailable', + requiredField: 'Required fields', + }, + webhookLog: { + processName: 'Process Name: ', + nodeName: 'Node Name: ', + startTime: 'Start Time: ', + log: 'Log', + businessParams: 'Business Parameters', + paramKey: 'Parameter Unique Identifier', + paramType: 'Parameter Type', + paramValue: 'Parameter Value', + notTriggered: 'Not Triggered Yet', + manualTriggerLog: 'This time manually triggered, no webhook logs', + }, + workflow: { + taskLogTitle: 'View Task Execution Log', + processLogTitle: 'View Process Log', + webhookLogTitle: 'View Webhook Log', + }, + index: { + graphProject: 'Graphics Projects', + codeProject: 'Code Projects', + workerManager: 'Worker Management', + localNode: 'Local Nodes', + groupManager: 'Group Management', + secretKeyManager: 'Secret Key Management', + }, + main: { + componentLib: 'Component Library', + loginPage: 'Login Page', + errorPage: 'Error Page: ', + browserVersion: 'Browser Version', + network: 'Web', + }, + login: { + welcome: 'Welcome to login', + usernamePlaceholder: 'Please enter your username', + passwordPlaceholder: 'Please enter your password', + remember: 'Remember username', + login: 'Login', + loginProblem: 'Problems logging in, please try to log in again', + cancel: 'Cancel', + reLogin: 'Re-login', + loggingInWith: 'Account login in progress with {type}…', + loginWith: 'Use {type} account to login', + usernameEmpty: 'Username can\'t be empty', + passwordEmpty: 'Password can\'t be empty', + success: 'Login successful', + }, + projectGroup: { + viewMore: 'View More', + noProjects: 'No Projects', + noResult: 'No related results were found', + totalProjects: '(Total { count } projects)', + }, + cacheDrawerItem: { + unavailable: 'Unavailable', + clear: 'Clear', + viewMount: 'View mount point', + noMount: 'Mount point not set', + node: 'Node', + mountDir: 'Mount directory', + confirmClearTitle: 'Make sure to clear the current cache?', + confirmClearTip: 'Old cached data will be cleared', + cancel: 'Cancel', + confirm: 'Confirm', + clearSuccess: 'Clear Successful', + }, + cacheDrawer: { + viewCache: 'View Cache', + }, + projectItem: { + concurrent: 'Can be concurrent', + tipInit: + 'The prequel process is executing or has hung, and the current process will start executing when it finishes or is manually terminated. Or enable concurrent execution, when enabled, multiple times can be executed at the same time.', + tipSuspended: + 'If a node in the current process fails to execute, the process is suspended and you need to manually retry/ignore the pending node.', + terminate: 'Terminate', + nextTime: 'Until next execution', + suspended: 'Suspend', + running: 'Execution', + duration: 'Duration', + disabled: 'Disabled, not available', + trigger: 'Trigger', + edit: 'Edit', + sync: 'Sync DSL', + openGit: 'Open git repository', + previewWorkflow: 'Preview process', + previewPipeline: 'Preview pipeline', + disable: 'Disable', + enable: 'Enable', + delete: 'Delete', + cache: 'Cache', + + project: 'project', + failed: 'Failed', + Running: 'Executing', + succeeded: 'Successful', + notStarted: 'Not started', + pending: 'Pending start', + nextTimeTip: 'Timed item: next execution time', + confirmTerminate: 'Sure to terminate?', + terminateTitle: 'Terminate project execution', + confirm: 'OK', + cancel: 'Cancel', + terminateSuccess: 'Terminate Successful', + operationSuccess: 'Operation Successful', + confirmTrigger: 'Are you sure you want to trigger?', + triggerTitle: 'Trigger item execution', + confirmGeneric: 'Are you sure you want to?', + enabled: 'Enabled', + Disabled: 'Disabled', + notModifiable: 'Not modifiable', + dslUpdateTip: 'To modify, update via DSL', + close: 'Close', + disableProject: 'Disable project', + enableProject: 'Enable project', + confirmSync: 'Sure to synchronise?', + syncTitle: 'Synchronise DSL', + syncSuccess: 'Synchronise Successful', + confirmDelete: 'Are you sure you want to delete the project?', + deleteTitle: 'Delete project', + name: 'Name:', + deleteSuccess: 'Delete Successful', + }, + webhookDrawer: { + triggerTip: 'You can trigger the process execution by calling the following webhook address', + copyLink: 'Copy Link', + requestList: 'Request List', + noRecordLine1: 'If there is no corresponding trigger record, you can go to the upstream webhook management,', + noRecordLine2: 'to see if the request was sent successfully', + refresh: 'Refresh', + source: 'Source', + requestTime: 'Request Time', + status: 'Status', + success: 'Success', + failure: 'Failure', + errorMessage: 'Error Message', + action: 'Action', + retry: 'Retry', + details: 'Details', + viewDetails: 'View Details', + trigger: 'Trigger', + paramList: 'Parameter List', + paramName: 'Parameter Unique Identifier', + paramType: 'Parameter Type', + paramValue: 'Parameter Value', + authRule: 'Authentication Rule', + noData: 'No data available at this time', + jsonPath: 'Json Path:', + copySuccess: 'Copy Successful', + copyFailed: 'Copy Failed, please copy manually', + retrySuccess: 'Retry Successful', + confirmRetry: 'Are you sure you want to retry?', + confirm: 'Confirm', + cancel: 'Cancel', + }, + webhookSettingDialog: { + title: 'Trigger execution', + tip: 'The project has been configured with a webhook, for manual triggering please fill in the parameters', + importLast: 'Fill in the last parameters', + clear: 'Clear the form', + paramName: 'Parameter name', + type: 'Type', + paramValue: 'Parameter value', + placeholder: 'Please enter the parameter value', + authRule: 'Authentication rules', + cancel: 'Cancel', + confirm: 'Confirm', + selectPlaceholder: 'Please select the parameter value', + }, + nodeToolbar: { + confirmRetry: 'Sure you want to retry?', + confirmIgnore: 'Sure you want to ignore?', + confirm: 'Confirm', + cancel: 'Cancel', + retry: 'Retry', + ignore: 'Ignore', + log: 'Log', + param: 'Parameters', + cache: 'Cache', + }, + taskState: { + INIT: 'Pending startup', + WAITING: 'In queue', + RUNNING: 'Executing', + SKIPPED: 'Skipped', + FAILED: 'Failed to execute', + SUCCEEDED: 'Successful', + SUSPENDED: 'Pending', + IGNORED: 'Ignored', + }, + toolbar: { + exitFullScreen: 'Exit Full Screen', + fullScreen: 'Full Screen', + originalSize: 'Original Size', + fitToScreen: 'Fit to Screen', + rotate: 'Rotate', + zoomOut: 'Zoom Out', + zoomIn: 'Zoom In', + workflowLog: 'WorkFlow Log', + viewDsl: 'View DSL', + return: 'Return', + workflow: 'WorkFlow', + pipeline: 'Pipeline', + }, + projectPanel: { + title: 'Edit project information', + name: 'Project name', + namePlaceholder: 'Please enter the project name', + group: 'Project grouping', + groupPlaceholder: 'Please select the project grouping', + description: 'Project description', + descriptionPlaceholder: 'Please enter the project description', + cancel: 'Cancel', + confirm: 'Confirm', + nameRequired: 'Please enter the project name', + groupRequired: 'Please select the project grouping', + }, + topToolbar: { + zoomOut: 'Zoom out', + zoomIn: 'Zoom in', + center: 'Center', + cache: 'Cache', + maxConcurrent: 'Maximum number of concurrency', + concurrentTip: 'Number of instances that can Execute/Suspend simultaneously in a single process', + saveAndBack: 'Save and return', + save: 'Save', + saveModification: 'Save this modification', + noSave: 'Do not save', + }, + nodeGroup: { + networkError: 'Network Error', + reload: 'Reload', + trigger: 'Trigger', + builtIn: 'Built-in nodes', + local: 'Local nodes', + official: 'Official nodes', + community: 'Community nodes', + }, + nodePanel: { + search: 'Search', + noResult: 'Did not yield any relevant results', + submitRequest: 'Welcome to submit node requests', + }, + cacheEditor: { + placeholder: 'Please enter a unique cache ID', + }, + cacheSelector: { + empty: 'There is no cache at the moment, please go to the top of the cache module to add a cache', + placeholder: 'Mount directory, start with /', + }, + shellEnv: { + name: 'Variable name', + placeholderName: 'Please enter variable name', + value: 'Variable value', + placeholderValue: 'Please enter variable value', + }, + webhookParam: { + name: 'Name', + namePlaceholder: 'Please enter the name of the parameter', + nameRule: 'Begin with an English letter or underscore, underscore, numbers, English letters are supported', + type: 'Type', + typePlaceholder: 'Please select the type of the parameter', + expression: 'Expression', + expressionTip: 'See details ', + extractionRule: 'Extraction rules', + expressionPlaceholder: 'Please enter the parameter expression', + required: 'Required', + no: 'No', + yes: 'Yes', + default: 'Default value', + defaultPlaceholder: 'Please enter the default value', + }, + asyncTaskPanel: { + name: 'Node name', + version: 'Node version', + versionPlaceholder: 'Please select the node version', + inputParam: 'Input parameter', + outputParam: 'Output parameter', + select: 'Please select', + enter: 'Please enter', + cacheMount: 'Cache mount', + cacheMountTip: 'Mount here after adding a cache in the top cache module', + add: 'Add', + failureMode: 'When execution fails', + suspend: 'Mount', + ignore: 'Ignore', + type: 'Type:', + description: 'Description:', + noDescription: 'No description', + noOutput: 'No output parameter', + }, + cachePanel: { + title: 'Cache', + description: + 'Add cache can be mounted in the node to avoid downloading the dependency repeatedly in the next execution of the node and improve the execution speed.', + unique: 'Unique identifier', + uniqueRule: 'Begin with an English letter or underscore, underscore, numbers, English letters are supported', + addCache: 'Add Cache', + deleteTitle: 'Sure to delete the current cache?', + deleteTip: 'Nodes that already refer to this cache will report an error after deletion', + cancel: 'Cancel', + confirm: 'Confirm', + }, + cronPanel: { + placeholder: 'Please enter a cron expression', + meaningTitle: 'The 7 parts of a Cron expression are represented from left to right as follows:', + meaningContent: 'Seconds Minutes Hours Days Months Weeks Years (optional, leave blank)', + exampleTitle: 'Examples of common expressions:', + example1: '0 0 12 * * ? Triggered at 12:00 noon every day', + example2: '0 15 10 * * ? Triggered every day at 10:15 a.m.', + example3: '0 0 1 ? * SAT Triggered at 1am every Saturday', + example4: '0 15 10 ? * MON-FRI Triggered at 10:15am Monday to Friday', + example5: '0 * 10 * * ? Triggered every minute between 10:00 a.m. and 10:59 a.m. every day', + }, + nodeConfigPanel: { + title: 'Node Configuration Panel', + }, + shellPanel: { + name: 'Node Name', + image: 'Docker Image', + imagePlaceholder: 'Please select or enter the image', + env: 'Environment variables', + envTooltip1: 'You can use expressions, refer to global parameters, event parameters or output ', + envTooltip2: 'parameters of the upstream node, see the ', + envTooltipLink: 'Parameters section for more details', + addEnv: 'Adding environment variables', + script: 'Scripts', + scriptPlaceholder: 'Please enter a shell script', + cache: 'Cache mounts', + cacheTooltip: 'Mounts here after adding a cache to the top cache module', + addCache: 'Add', + failureMode: 'Mounts when execution fails', + suspend: 'Suspend', + ignore: 'Ignore', + }, + webhookPanel: { + triggerParam: 'Trigger Parameters', + triggerParamTip: 'Reference to Trigger Parameters ', + paramSection: 'Parameters Section', + addTriggerParam: 'Add Trigger Parameters', + advancedSetting: 'Advanced Settings', + authRule: 'Authentication Rules', + authRuleTip1: 'If you turn off the Authentication Rules, anyone can pass through', + authRuleTip2: 'webhook triggers the process', + tokenTip: 'Webhook Requests for Carrying Authentication Authentication Data', + tokenPlaceholder: 'Please enter a token value', + valueTip1: 'Used to verify the token value, the same authentication succeeds', + valueTip2: 'Must be a secret key type', + valuePlaceholder: 'Please select value', + onlyRule: 'Match the rule, trigger the process when the result is true,', + onlyTip: 'can currently only refer to the trigger parameter. See ', + onlyLink: 'Arithmetic Expressions', + onlyPlaceholder: 'Please enter a matching rule', + }, + paramButton: { + label: 'parameter', + }, + workflowNodeToolbar: { + confirmDelete: 'Are you sure you want to delete?', + name: 'Name: ', + delete: 'Delete ', + node: 'Node', + trigger: 'Trigger', + confirm: 'Confirm', + cancel: 'Cancel', + }, + loadMore: { + show: 'Show More', + noMore: 'No More', + }, + breadcrumb: { + home: 'Home', + worker: 'Worker Management', + localNode: 'Local Node Library', + group: 'Group Management', + secretKey: 'Secret Key Management', + addProject: 'Add New Project', + Details: 'Details', + }, + workflowValidator: { + noNodes: 'No nodes exist', + atLeastOneShellOrTaskNode: 'There is at least one shell or task node', + nodeNotConnected: 'Node: no other nodes connected yet', + node: 'Node: ', + onlyOneTrigger: 'There can only be one trigger', + }, + shell: { + enterVariableName: 'Please enter a variable name', + enterVariableValue: 'Please enter a variable value', + selectCache: 'Please select a cache ', + enterDirectory: 'Please enter a directory ', + enterDirectoryBeginningWithSlash: 'Please enter a directory beginning with /', + selectOrEnterMirrorImage: 'Please select or enter a mirror image', + }, + webhook: { + enterParamName: 'Please enter the parameter name', + paramNamePattern: 'Start with an English letter or underscore, support underscore, numbers, English letters', + selectParamType: 'Please select the parameter type', + enterParamExpression: 'Please enter the parameter expression', + selectParamDefaultValue: 'Please select the parameter default value', + enterParamDefaultValue: 'Please enter the parameter default value', + triggerParamNotExist: 'Trigger parameter does not exist', + enterTokenValue: 'Please enter the token value', + selectKey: 'Please select the key', + }, + cron: { + scheduleNotEmpty: 'schedule cannot be empty', + invalidCronExpression: 'Please enter the correct cron expression', + }, + logViewer: { + downloading: 'Downloading, please wait...', + download: 'Download', + moreLog: 'log is too large, more logs please download to view', + }, + textCopy: { + copy: 'Copy', + valueEmpty: 'value is null', + copied: 'copied', + copyFailed: 'copy failed', + cause: 'cause: ', + }, + }, +}; + +const getDefaultLocale = () => { + const saved = localStorage.getItem('JianmuLang'); + if (saved) return saved; + + const browserLang = navigator.language.split('-')[0]; + const supportedLangs = ['zh', 'en']; + const lang = supportedLangs.includes(browserLang) ? browserLang : 'zh'; + localStorage.setItem('JianmuLang', lang); + return lang; +}; + +const i18n = createI18n({ + locale: getDefaultLocale(), + fallbackLocale: 'zh', + messages, +}); + +export default i18n; +export const globalT = i18n.global.t; diff --git a/ui/src/main.ts b/ui/src/main.ts index 1474429893fad1c02b0d12279e1c3cb901f17b4f..2f37b32986fba4ce935f51c9a7894124ae7756ae 100644 --- a/ui/src/main.ts +++ b/ui/src/main.ts @@ -9,7 +9,7 @@ import { globalErrorHandler } from './utils/global-error-handler'; import './utils/operation-btn-position.ts'; // 安装百度统计 import './utils/baidu-tongji.ts'; - +import i18n from './locales'; // 打印环境变量,用于调试 console.debug(import.meta.env); const app = createApp(App); @@ -21,10 +21,9 @@ app.use(components); app.use(router); // 安装vuex app.use(store); - +app.use(i18n); // 注册全局异常处理方法 -app.config.errorHandler = (err, instance, info) => - globalErrorHandler(err as Error, instance, info, router, store); +app.config.errorHandler = (err, instance, info) => globalErrorHandler(err as Error, instance, info, router, store); app.config.globalProperties.$throw = (err: Error, instance: ComponentPublicInstance | null) => globalErrorHandler(err, instance, null, router, store); diff --git a/ui/src/router/index.ts b/ui/src/router/index.ts index d8d7f9079f3e231bea5f85796c68e5bc86ef5076..cd2403cb0c3ac182147d10a31a0e17de0175afa4 100644 --- a/ui/src/router/index.ts +++ b/ui/src/router/index.ts @@ -5,7 +5,7 @@ import { namespace as sessionNs } from '@/store/modules/session'; import { IState as ISessionState } from '@/model/modules/session'; import LoginVerify from '@/views/login/dialog.vue'; import { AppContext } from 'vue'; - +import { globalT as t } from '@/utils/i18n'; /** * 加载业务模块路由 * @param path @@ -66,7 +66,7 @@ export default (appContext: AppContext) => { // platform模块 loadModuleRoute( PLATFORM_INDEX, - '首页', + t('breadcrumb.home'), false, import('@/layout/platform.vue'), import.meta.globEager('./modules/platform.ts'), diff --git a/ui/src/router/modules/platform.ts b/ui/src/router/modules/platform.ts index 411c2b1a85a790c3214e51eff2ff9712437a14e2..954756f956242d4d78256d877a58f0ce17211117 100644 --- a/ui/src/router/modules/platform.ts +++ b/ui/src/router/modules/platform.ts @@ -1,5 +1,5 @@ import { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router'; - +import { globalT as t } from '@/utils/i18n'; export default [ // 首页 { @@ -28,7 +28,7 @@ export default [ path: 'worker-manager', component: () => import('@/views/workers/workers-manager.vue'), meta: { - title: 'Worker管理', + title: t('breadcrumb.worker'), }, }, // 节点库路由 @@ -37,7 +37,7 @@ export default [ path: 'node-library', component: () => import('@/views/node-library/node-library-manager.vue'), meta: { - title: '本地节点库', + title: t('breadcrumb.localNode'), }, }, { @@ -45,7 +45,7 @@ export default [ path: 'project-group', component: () => import('@/views/project-group/project-group-manager.vue'), meta: { - title: '分组管理', + title: t('breadcrumb.group'), }, children: [ { @@ -66,7 +66,7 @@ export default [ path: 'secret-key', component: () => import('@/views/secret-key/ns-manager.vue'), meta: { - title: '密钥管理', + title: t('breadcrumb.secretKey'), }, children: [ { @@ -77,7 +77,7 @@ export default [ ns: namespace, }), meta: { - title: '详情', + title: t('breadcrumb.Details'), }, }, ], @@ -95,7 +95,7 @@ export default [ path: 'project/editor', component: () => import('@/views/project/editor.vue'), meta: { - title: '新增项目', + title: t('breadcrumb.addProject'), }, }, { diff --git a/ui/src/utils/i18n.ts b/ui/src/utils/i18n.ts new file mode 100644 index 0000000000000000000000000000000000000000..cb48463e4d40b55b81c0db0eb848e5aa5910748e --- /dev/null +++ b/ui/src/utils/i18n.ts @@ -0,0 +1,18 @@ +import { useI18n } from 'vue-i18n'; +import { globalT } from '@/locales'; + +export function useLocale() { + const { locale, t } = useI18n(); + + const handleLocaleChange = (lang: string) => { + locale.value = lang; + localStorage.setItem('JianmuLang', lang); + }; + + return { + t, + locale, + handleLocaleChange, + }; +} +export { globalT }; diff --git a/ui/src/views/common/cache-drawer-item.vue b/ui/src/views/common/cache-drawer-item.vue index 863b8d4f56d538a8037ac1d92f6dbd8e505c1e30..7a1678c1aa8b703856af5ce68895ed3845163a44 100644 --- a/ui/src/views/common/cache-drawer-item.vue +++ b/ui/src/views/common/cache-drawer-item.vue @@ -3,12 +3,14 @@
-
-
-
+
+
-
+
-
+
-
+
-
-
+
+
-
+
+
{{ zoom }}%
-
-
-
+
+
-
-
-
+
@@ -170,14 +178,14 @@ export default defineComponent({
padding: 10px 15px;
box-shadow: 0 0 4px 0 rgba(194, 194, 194, 0.5);
border-radius: 2px;
- border: 1px solid #CAD6EE;
+ border: 1px solid #cad6ee;
background-color: rgba(255, 255, 255, 0.6);
display: flex;
align-items: center;
&.dsl {
background-color: #818894;
- border: 1px solid #767F91;
+ border: 1px solid #767f91;
box-shadow: 0 0 4px 0 rgba(194, 194, 194, 0.5);
}
@@ -253,7 +261,7 @@ export default defineComponent({
margin: 0 16px;
width: 1px;
height: 15px;
- background-color: #CDD1E3;
+ background-color: #cdd1e3;
overflow: hidden;
}
@@ -279,9 +287,9 @@ export default defineComponent({
line-height: 20px;
font-size: 14px;
font-weight: 500;
- color: #4A4A4A;
+ color: #4a4a4a;
text-align: center;
}
}
}
-
\ No newline at end of file
+
diff --git a/ui/src/locales/index.ts b/ui/src/locales/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..42af6907ef9ba03b7fbe8939b48768e684b819cf
--- /dev/null
+++ b/ui/src/locales/index.ts
@@ -0,0 +1,1512 @@
+import httpStatusVue from '@/views/error/http-status.vue';
+import { createI18n } from 'vue-i18n';
+
+const messages = {
+ zh: {
+ noData: 'No data',
+ top: {
+ logout: '退出',
+ language: '语言设置',
+ LogoutSuccessful: '退出成功',
+ },
+ bottom: {
+ project: '木兰社区孵化项目',
+ about: '关于建木',
+ manual: '使用手册',
+ contact: '联系我们',
+ },
+ dialog: {
+ needLoginTip: '未登录状态下,操作内容将会丢失',
+ },
+ allProject: {
+ projectList: '项目列表',
+ inputPlaceholder: '请输入项目名称',
+ empty: '暂无项目',
+ default: '默认排序',
+ lastExecute: '最近触发',
+ lastModify: '最近修改',
+ },
+ searchProject: {
+ selectGroup: '请选择项目组',
+ inputName: '请输入项目名称',
+ },
+ network: {
+ title: '你的设备没有接入互联网',
+ desc: '无法显示此页面,因为你的电脑目前已离线',
+ backHome: '返回首页',
+ },
+ browserVersion: {
+ unsupported: '抱歉,不支持此浏览器',
+ backHome: '返回首页',
+ },
+ httpStatus: {
+ backHome: '返回首页',
+ noPermission: '没有权限访问该页面',
+ pageNotFound: '找不到页面',
+ serverError: '服务器出错',
+ },
+ nodeLibrary: {
+ addLocalNode: '新增本地节点',
+ name: '名称',
+ inputName: '请输入名称',
+ description: '描述',
+ inputDescription: '请输入描述',
+ note: '注意事项:ref为xxx/xxx或xxx时,统一处理成local/xxx,在流程或管道dsl中以local/xxx:xxx方式引用。',
+ cancel: '取消',
+ confirm: '确定',
+ close: '关闭',
+ nodeLibraryTitle: '建木节点库',
+ nodeLibraryCount: '(共有 { count } 个节点定义)',
+ tooltipDeprecated:
+ '由于某些原因,该节点不被推荐使用(如该节点可
+
+
-
{{ `返回${isWorkflow ? '流程' : '管道'}` }}
+
+ {{ $t('toolbar.return') }}{{ isWorkflow ? $t('toolbar.workflow') : $t('toolbar.pipeline') }}
+
-
+
能会导致一些已知问题或有更好的节点可替代它)', + sync: '同步', + delete: '删除', + nameRequired: '名称不能为空', + dslRequired: 'DSL不能为空', + createSuccess: '新增成功', + deleteNodeTitle: '删除节点', + deleteConfirm: '确定要删除节点吗?', + deleteSuccess: '删除成功', + syncTitle: '同步DSL', + syncConfirm: '确定要同步吗?', + syncSuccess: '同步成功', + }, + editor: { + cancel: '取消', + previousStep: '上一步', + saveAndBack: '保存并返回', + save: '保存', + selectProjectGroup: '选择项目组', + pleaseSelectProjectGroup: '请选择项目组', + dslMode: 'DSL模式', + validationProjectGroup: '请选择项目组', + dslEmptyError: 'DSL不能为空', + saveSuccess: '保存成功', + createSuccess: '新增成功', + }, + importStepOne: { + cancel: '取消', + next: '下一步', + subgroups: '分组', + selectGroup: '请选择项目组', + enterUrl: '请输入URL,例如:https://gitee.com/jianmu-dev/jianmu.git', + branch: '分支', + enterBranch: '请输入分支', + auth: '认证:', + type: '类型', + selectType: '请选择类型', + username: '用户名', + selectUsername: '请选择用户名', + password: '密码', + selectPassword: '请选择密码', + selectUsernameAgain: '请选择用户名', + privateKey: '私钥', + selectPrivateKey: '请选择私钥', + uriRequired: 'URI不能为空', + groupRequired: '项目分组不能为空', + branchRequired: '分支不能为空', + mustSelectType: '请选择类型', + mustSelectUsername: '请选择用户名', + mustSelectPassword: '请选择密码', + }, + importStepTwo: { + cancel: '取消', + previous: '上一步', + save: '保存', + selectDsl: '请选择DSL文件', + importSuccess: '导入成功', + }, + importer: { + cloneGitRepo: '克隆Git仓库', + selectDSL: '选择DSL文件', + }, + pipelineEditor: { + unnamedProject: '未命名项目', + createSuccess: '新增成功', + saveSuccess: '保存成功', + }, + projectGroupManager: { + close: '关闭', + newGroup: '新建分组', + projectGroup: '项目分组', + totalGroups: '(共有 { total } 个组)', + closeSorting: '关闭排序', + sorting: '排序', + none: '无', + lastModified: '最后修改时间:', + total: '共', + items: '条项目', + homeShow: '首页展示', + confirmDeleteGroup: '确定要删除分组吗?', + name: '名称:', + deleteGroup: '删除分组', + confirm: '确定', + cancel: '取消', + deleteSuccess: '项目分组删除成功', + }, + projectGroupEditor: { + title: '编辑项目分组', + name: '分组名称', + namePlaceholder: '请输入分组名称', + isShow: '首页展示', + description: '描述', + descriptionPlaceholder: '请输入描述', + descriptionTips: '描述信息不超过 256个字符', + cancel: '取消', + save: '保存', + nameRequired: '分组名称不能为空', + success: '项目分组修改成功', + }, + projectGroupDetail: { + close: '关闭', + totalProjects: '(共有 { count } 个项目)', + none: '无', + addProject: '添加项目', + projectList: '项目列表', + closeSorting: '关闭排序', + sorting: '排序', + }, + projectGroupCreator: { + title: '新建项目分组', + name: '分组名称', + namePlaceholder: '请输入分组名称', + isShow: '首页展示', + description: '描述', + descriptionPlaceholder: '请输入描述', + descriptionTips: '描述信息不超过 256个字符', + cancel: '取消', + confirm: '确定', + nameRequired: '分组名称不能为空', + success: '项目分组创建成功', + }, + projectAdder: { + title: '添加项目', + selectGroup: '选择项目组', + selectGroupPlaceholder: '请选择项目组', + selectedProject: '已选项目', + inputPlaceholder: '请输入项目名称或描述', + none: '无', + cancel: '取消', + confirm: '确定', + selectGroupRequired: '请选择项目组', + addProjectRequired: '请添加项目', + success: '项目添加成功', + }, + skManager: { + close: '关闭', + title: '密钥列表', + total: '(共有 { keys } 个密钥)', + add: '新增密钥', + none: '无', + confirmDelete: '确定要删除密钥吗?', + name: '名称:', + delete: '删除密钥', + confirm: '确定', + cancel: '取消', + success: '删除成功', + }, + skEditor: { + title: '新增密钥', + name: '名称', + namePlaceholder: '请输入名称', + value: '值', + valuePlaceholder: '请输入值', + cancel: '取消', + confirm: '确定', + nameRequired: '名称不能为空', + valueRequired: '值不能为空', + success: '新增成功', + }, + nsManager: { + close: '关闭', + add: '新增命名空间', + title: '命名空间', + total: '(共有 { length } 个命名空间)', + none: '无', + lastModified: '最后修改时间:', + confirmDelete: '确定要删除命名空间吗?', + nameLabel: '名称:', + deleteTitle: '删除命名空间', + confirm: '确定', + cancel: '取消', + success: '删除成功', + }, + nsEditor: { + title: '新增密钥命名空间', + name: '命名空间', + namePlaceholder: '请输入命名空间', + description: '描述', + descriptionPlaceholder: '请输入描述', + cancel: '取消', + confirm: '确定', + nameRequired: '命名空间不能为空', + success: '新增成功', + }, + workersManager: { + close: '关闭', + title: 'Worker列表', + total: '(共有 { length } 个Worker)', + name: '名称:', + label: '标签:', + none: '无', + os: '操作系统:', + arch: '架构:', + type: '类型:', + time: '注册时间:', + confirmDeleteMsg: '确定要删除Worker吗?', + confirmDeleteTitle: '删除Worker', + confirm: '确定', + cancel: '取消', + success: '删除成功', + }, + detail: { + terminateAll: '终止全部', + trigger: '触发', + notClickable: '暂无法点击', + startTime: '启动时间', + endTime: '完成时间', + suspendedDuration: '挂起时长', + executionDuration: '执行时长', + none: '无', + instanceId: '流程实例ID', + version: '流程版本号', + terminate: '终止', + success: '操作成功', + confirmTrigger: '确定要触发吗?', + triggerExecution: '触发项目执行', + confirm: '确定', + cancel: '取消', + terminatingSuccess: '操作成功,正在终止,请稍后', + confirmTerminateAll: '确定要终止执行中/挂起的全部实例吗?', + terminateExecution: '终止项目执行', + confirmTerminate: '确定要终止吗?', + terminateSuccess: '终止成功', + }, + processLog: { + processName: '流程名称', + startTime: '启动时间', + endTime: '完成时间', + suspendedDuration: '挂起时长', + executionDuration: '执行时长', + instanceId: '流程实例ID', + version: '流程版本号', + loading: '加载中...', + }, + taskLog: { + processName: '流程名称', + executionCount: '执行次数', + nodeName: '节点名称', + successCount: '成功次数', + nodeDefinition: '节点定义', + failureCount: '失败次数', + startTime: '启动时间', + skipCount: '跳过次数', + executionDuration: '执行时长', + suspendedCount: '挂起次数', + executionStatus: '执行状态', + ignoreCount: '忽略次数', + log: '日志', + loading: '加载中...', + businessParams: '业务参数', + inputParams: '输入参数', + paramKey: '参数唯一标识', + paramType: '参数类型', + requiredOrNot: '是/否必填', + yes: '是', + no: '否', + paramValue: '参数值', + outputParams: '输出参数', + cache: '缓存', + mountPath: '挂载目录', + status: '状态', + unavailableTipLine1: '对于不可用的缓存,可到项目卡片-', + unavailableTipLine2: '更多-缓存中清理或项目编辑页删除', + available: '可用', + unavailable: '不可用', + requiredField: '必填项', + }, + webhookLog: { + processName: '流程名称:', + nodeName: '节点名称:', + startTime: '启动时间:', + log: '日志', + businessParams: '业务参数', + paramKey: '参数唯一标识', + paramType: '参数类型', + paramValue: '参数值', + notTriggered: '尚未触发', + manualTriggerLog: '此次为手动触发,无webhook日志', + }, + workflow: { + taskLogTitle: '查看任务执行日志', + processLogTitle: '查看流程日志', + webhookLogTitle: '查看Webhook日志', + }, + index: { + graphProject: '图形项目', + codeProject: '代码项目', + workerManager: 'Worker管理', + localNode: '本地节点', + groupManager: '分组管理', + secretKeyManager: '密钥管理', + }, + main: { + componentLib: '组件库', + loginPage: '登录页', + errorPage: '错误页:', + browserVersion: '浏览器版本', + network: '网络', + }, + login: { + welcome: '欢迎登录', + usernamePlaceholder: '请输入用户名', + passwordPlaceholder: '请输入密码', + remember: '记住用户名', + login: '登录', + loginProblem: '登录遇到问题,请尝试重新登录', + cancel: '取消', + reLogin: '重新登录', + loggingInWith: '{type} 账号登录中…', + loginWith: '使用 {type} 账号登录', + usernameEmpty: '用户名不能为空', + passwordEmpty: '密码不能为空', + success: '登录成功', + }, + projectGroup: { + viewMore: '查看更多', + noProjects: '没有项目', + noResult: '没有找到相关结果', + totalProjects: '共有 { count } 个项目', + }, + cacheDrawerItem: { + unavailable: '不可用', + clear: '清理', + viewMount: '查看挂载点', + noMount: '未设置挂载点', + node: '节点', + mountDir: '挂载目录', + confirmClearTitle: '确定清理当前缓存?', + confirmClearTip: '旧的缓存数据将被清空', + cancel: '取消', + confirm: '确定', + clearSuccess: '清理成功', + }, + cacheDrawer: { + viewCache: '查看缓存', + }, + projectItem: { + concurrent: '可并发', + tipInit: + '前序流程正在执行或已挂起,待执行完毕或手动终止后,本次流程将开始执行。 或开启并发执行,开启后,多次可同时执行。', + tipSuspended: '当前流程中某个节点执行失败,流程处于暂停状态,需要手动 重试/忽略 挂起节点。', + terminate: '终止', + nextTime: '距离下次执行还有', + suspended: '挂起', + running: '执行', + duration: '时长', + disabled: '已禁用,不可', + trigger: '触发', + edit: '编辑', + sync: '同步DSL', + openGit: '打开git仓库', + previewWorkflow: '预览流程', + previewPipeline: '预览管道', + disable: '禁用', + enable: '启用', + delete: '删除', + cache: '缓存', + + project: '项目', + failed: '失败', + Running: '执行中', + succeeded: '成功', + notStarted: '未启动', + pending: '待启动', + nextTimeTip: '定时项目:下次执行时间', + confirmTerminate: '确定要终止吗?', + terminateTitle: '终止项目执行', + confirm: '确定', + cancel: '取消', + terminateSuccess: '终止成功', + operationSuccess: '操作成功', + confirmTrigger: '确定要触发吗?', + triggerTitle: '触发项目执行', + confirmGeneric: '确定要', + enabled: '已启用', + Disabled: '已禁用', + notModifiable: '不可修改', + dslUpdateTip: '若要修改,请通过DSL更新', + close: '关闭', + disableProject: '禁用项目', + enableProject: '启用项目', + confirmSync: '确定要同步吗?', + syncTitle: '同步DSL', + syncSuccess: '同步成功', + confirmDelete: '确定要删除项目吗?', + deleteTitle: '删除项目', + name: '名称:', + deleteSuccess: '删除成功', + }, + webhookDrawer: { + triggerTip: '可以通过调用以下Webhook地址来触发流程执行', + copyLink: '复制链接', + requestList: '请求列表', + noRecordLine1: '若无对应的触发记录,可到上游webhook管理中,', + noRecordLine2: '查看请求是否发送成功', + refresh: '刷新', + source: '来源', + requestTime: '请求时间', + status: '状态', + success: '成功', + failure: '失败', + errorMessage: '错误信息', + action: '操作', + retry: '重试', + details: '详情', + viewDetails: '查看详情', + trigger: '触发器', + paramList: '参数列表', + paramName: '参数唯一标识', + paramType: '参数类型', + paramValue: '参数值', + authRule: '认证规则', + noData: '暂无数据', + jsonPath: 'Json路径:', + copySuccess: '复制成功', + copyFailed: '复制失败,请手动复制', + retrySuccess: '重试成功', + confirmRetry: '确定要重试吗?', + confirm: '确认', + cancel: '取消', + }, + webhookSettingDialog: { + title: '触发执行', + tip: '项目已配置webhook,手动触发请填写参数', + importLast: '填入上次参数', + clear: '清空表单', + paramName: '参数名', + type: '类型', + paramValue: '参数值', + placeholder: '请输入参数值', + authRule: '认证规则', + cancel: '取消', + confirm: '确认', + selectPlaceholder: '请选择参数值', + }, + nodeToolbar: { + confirmRetry: '确定要重试吗?', + confirmIgnore: '确定要忽略吗?', + confirm: '确认', + cancel: '取消', + retry: '重试', + ignore: '忽略', + log: '日志', + param: '参数', + cache: '缓存', + }, + taskState: { + INIT: '待启动', + WAITING: '排队中', + RUNNING: '执行中', + SKIPPED: '已跳过', + FAILED: '执行失败', + SUCCEEDED: '执行成功', + SUSPENDED: '已挂起', + IGNORED: '已忽略', + }, + toolbar: { + exitFullScreen: '退出全屏', + fullScreen: '全屏', + originalSize: '原始大小', + fitToScreen: '适屏', + rotate: '旋转', + zoomOut: '缩小', + zoomIn: '放大', + workflowLog: '流程日志', + viewDsl: '查看DSL', + return: '返回', + workflow: '流程', + pipeline: '管道', + }, + projectPanel: { + title: '编辑项目信息', + name: '项目名称', + namePlaceholder: '请输入项目名称', + group: '项目分组', + groupPlaceholder: '请选择项目分组', + description: '项目描述', + descriptionPlaceholder: '请输入项目描述', + cancel: '取消', + confirm: '确定', + nameRequired: '请输入项目名称', + groupRequired: '请选择项目分组', + }, + topToolbar: { + zoomOut: '缩小', + zoomIn: '放大', + center: '居中', + cache: '缓存', + maxConcurrent: '最大并发数', + concurrentTip: '单个流程中可同时执行/挂起的实例数', + saveAndBack: '保存并返回', + save: '保存', + saveModification: '保存此次修改', + noSave: '不保存', + }, + nodeGroup: { + networkError: '网络开小差啦', + reload: '重新加载', + trigger: '触发器', + builtIn: '内置节点', + local: '本地节点', + official: '官方节点', + community: '社区节点', + }, + nodePanel: { + search: '搜索', + noResult: '没有搜到相关结果', + submitRequest: '欢迎提交节点需求', + }, + cacheEditor: { + placeholder: '请输入缓存唯一标识', + }, + cacheSelector: { + empty: '暂无缓存,请先到顶部缓存模块添加缓存', + placeholder: '请输入缓存要挂载的目录,以/开头', + }, + shellEnv: { + name: '变量名称', + placeholderName: '请输入变量名称', + value: '变量值', + placeholderValue: '请输入变量值', + }, + webhookParam: { + name: '名称', + namePlaceholder: '请输入参数名称', + nameRule: '以英文字母或下划线开头,支持下划线、数字、英文字母', + type: '类型', + typePlaceholder: '请选择参数类型', + expression: '表达式', + expressionTip: '详见', + extractionRule: '提取规则', + expressionPlaceholder: '请输入参数表达式', + required: '是否必填', + no: '否', + yes: '是', + default: '默认值', + defaultPlaceholder: '请输入默认值', + }, + asyncTaskPanel: { + name: '节点名称', + version: '节点版本', + versionPlaceholder: '请选择节点版本', + inputParam: '输入参数', + outputParam: '输出参数', + select: '请选择', + enter: '请输入', + cacheMount: '缓存挂载', + cacheMountTip: '在顶部缓存模块中添加缓存后,在此挂载', + add: '添加', + failureMode: '执行失败时', + suspend: '挂起', + ignore: '忽略', + type: '类型:', + description: '描述:', + noDescription: '暂无描述', + noOutput: '无输出参数', + }, + cachePanel: { + title: '缓存', + description: '添加缓存后可在节点中挂载,避免下次执行节点时重复下载依赖,提高执行速度。', + unique: '唯一标识', + uniqueRule: '以英文字母或下划线开头,支持下划线、数字、英文字母', + addCache: '添加缓存', + deleteTitle: '确定删除当前缓存?', + deleteTip: '删除后已引用该缓存的节点将会报错', + cancel: '取消', + confirm: '确认', + }, + cronPanel: { + placeholder: '请输入cron表达式', + meaningTitle: 'Cron表达式的7个部分从左到右代表的含义如下:', + meaningContent: '秒 分 时 日 月 周 年(可选,留空)', + exampleTitle: '常见表达式例子:', + example1: '0 0 12 * * ? 每天中午12点触发', + example2: '0 15 10 * * ? 每天上午10:15触发', + example3: '0 0 1 ? * SAT 每周六凌晨1点触发', + example4: '0 15 10 ? * MON-FRI 周一至周五的上午10:15触发', + example5: '0 * 10 * * ? 每天上午10点到10:59期间,每分钟触发一次', + }, + nodeConfigPanel: { + title: '节点配置面板', + }, + shellPanel: { + name: '节点名称', + image: 'docker镜像', + imagePlaceholder: '请选择或输入镜像', + env: '环境变量', + envTooltip1: '可以使用表达式,引用全局参数、事件参数', + envTooltip2: '或上游节点的输出参数,详见', + envTooltipLink: '参数章节', + addEnv: '添加环境变量', + script: '脚本', + scriptPlaceholder: '请输入shell脚本', + cache: '缓存挂载', + cacheTooltip: '在顶部缓存模块中添加缓存后,在此挂载', + addCache: '添加', + failureMode: '执行失败时', + suspend: '挂起', + ignore: '忽略', + }, + webhookPanel: { + triggerParam: '触发器参数', + triggerParamTip: '引用触发器参数参考', + paramSection: '参数章节', + addTriggerParam: '添加触发器参数', + advancedSetting: '高级设置', + authRule: '认证规则', + authRuleTip1: '若关闭认证规则,任何人皆可通过', + authRuleTip2: 'webhook触发此流程', + tokenTip: 'Webhook请求携带的认证鉴权数据', + tokenPlaceholder: '请输入token值', + valueTip1: '用于校验token值,相同则验证成功', + valueTip2: '必须是密钥类型', + valuePlaceholder: '请选择value值', + onlyRule: '匹配规则,结果为 true 时触发流程,当', + onlyTip: '前只可引用触发器参数。详见', + onlyLink: '运算表达式', + onlyPlaceholder: '请输入匹配规则', + }, + paramButton: { + label: '参数', + }, + workflowNodeToolbar: { + confirmDelete: '你确认要删除吗?', + name: '名称: ', + delete: '删除', + node: '节点', + trigger: '触发器', + confirm: '确认', + cancel: '取消', + }, + loadMore: { + show: '显示更多', + noMore: '没有更多了', + }, + breadcrumb: { + home: '首页', + worker: 'Worker管理', + localNode: '本地节点库', + group: '分组管理', + secretKey: '密钥管理', + addProject: '新增项目', + Details: '详情', + }, + workflowValidator: { + noNodes: '未存在任何节点', + atLeastOneShellOrTaskNode: '至少有一个shell或任务节点', + nodeNotConnected: '节点:尚未连接任何其他节点', + node: '节点:', + onlyOneTrigger: '只能有一个触发器', + }, + shell: { + enterVariableName: '请输入变量名', + enterVariableValue: '请输入变量值', + selectCache: '请选择缓存', + enterDirectory: '请输入目录', + enterDirectoryBeginningWithSlash: '请输入以/开头的目录', + selectOrEnterMirrorImage: '请选择或输入镜像', + }, + webhook: { + enterParamName: '请输入参数名称', + paramNamePattern: '以英文字母或下划线开头,支持下划线、数字、英文字母', + selectParamType: '请选择参数类型', + enterParamExpression: '请输入参数表达式', + selectParamDefaultValue: '请选择参数默认值', + enterParamDefaultValue: '请输入参数默认值', + triggerParamNotExist: '触发器参数不存在', + enterTokenValue: '请输入token值', + selectKey: '请选择密钥', + }, + cron: { + scheduleNotEmpty: 'schedule不能为空', + invalidCronExpression: '请输入正确的cron表达式', + }, + logViewer: { + downloading: '下载中,请稍后...', + download: '下载', + moreLog: '日志过大,更多日志请下载查看', + }, + textCopy: { + copy: '复制', + valueEmpty: '值为空', + copied: '已复制', + copyFailed: '复制失败', + cause: '原因:', + }, + }, + + en: { + top: { + logout: 'Logout', + language: 'Language', + LogoutSuccessful: 'Logout Successful', + }, + bottom: { + project: 'Mulan Incubator', + about: 'About Jianmu', + manual: 'Documentation', + contact: 'Contact Us', + }, + dialog: { + needLoginTip: 'The contents of the operation will be lost if you are not logged in', + }, + allProject: { + projectList: 'Project List', + inputPlaceholder: 'Please enter project name', + empty: 'No Projects', + default: 'Default Sort', + lastExecute: 'Recently triggered', + lastModify: 'Recent changes', + }, + searchProject: { + selectGroup: 'Please select a project group', + inputName: 'Please enter project name', + }, + network: { + title: 'Your device is not connected to the internet', + desc: 'This page cannot be displayed because your computer is currently offline', + backHome: 'Back to Home', + }, + browserVersion: { + unsupported: 'Sorry, this browser is not supported', + backHome: 'Back to Home', + }, + httpStatus: { + backHome: 'Back to Home', + noPermission: 'No permission to access this page', + pageNotFound: 'Page not found', + serverError: 'Server Error', + }, + nodeLibrary: { + addLocalNode: 'Add Local Node', + name: 'Name', + inputName: 'Please enter name', + description: 'Description', + inputDescription: 'Please enter description', + note: 'Note: When ref is xxx/xxx or xxx, it is uniformly handled as local/xxx and referenced as local/xxx:xxx in the process or pipeline dsl.', + cancel: 'Cancel', + confirm: 'Confirm', + close: 'Close', + nodeLibraryTitle: 'Jianmu Node Library', + nodeLibraryCount: '(Total { count } node definitions)', + tooltipDeprecated: 'This node is not recommended due to known issues or a better alternative', + sync: 'Sync', + delete: 'Delete', + nameRequired: 'Name cannot be empty', + dslRequired: 'DSL cannot be empty', + createSuccess: 'Created successfully', + deleteNodeTitle: 'Delete Node', + deleteConfirm: 'Are you sure you want to delete the node?', + deleteSuccess: 'Deleted successfully', + syncTitle: 'Sync DSL', + syncConfirm: 'Are you sure you want to sync?', + syncSuccess: 'Synced successfully', + }, + editor: { + cancel: 'Cancel', + previousStep: 'Previous Step', + saveAndBack: 'Save and Return', + save: 'Save', + selectProjectGroup: 'Select Project Group', + pleaseSelectProjectGroup: 'Please select a project group', + dslMode: 'DSL Mode', + validationProjectGroup: 'Please select a project group', + dslEmptyError: 'DSL cannot be empty', + saveSuccess: 'Saved successfully', + createSuccess: 'Created successfully', + }, + importStepOne: { + cancel: 'Cancel', + next: 'Next', + subgroups: 'Subgroups', + selectGroup: 'Please select the project group', + enterUrl: 'Please enter the URL, e.g. https://gitee.com/jianmu-dev/jianmu.git', + branch: 'Branch', + enterBranch: 'Please enter the branch', + auth: 'Authentication:', + type: 'Type', + selectType: 'Please select the type', + username: 'Username', + selectUsername: 'Please select the username', + password: 'Password', + selectPassword: 'Please select the password', + selectUsernameAgain: 'Please select the username', + privateKey: 'Private Key', + selectPrivateKey: 'Please select the private key', + uriRequired: 'URI can\'t be null', + groupRequired: 'Project grouping can\'t be null', + branchRequired: 'Branching can\'t be null', + mustSelectType: 'Please Select type', + mustSelectUsername: 'Please select username', + mustSelectPassword: 'Please select password', + }, + importStepTwo: { + cancel: 'Cancel', + previous: 'Previous Step', + save: 'Save', + selectDsl: 'Please select DSL file', + importSuccess: 'Import Successful', + }, + importer: { + cloneGitRepo: 'Clone Git Repository', + selectDSL: 'Select DSL File', + }, + pipelineEditor: { + unnamedProject: 'Untitled Project', + createSuccess: 'Created successfully', + saveSuccess: 'Saved successfully', + }, + projectGroupManager: { + close: 'Close', + newGroup: 'New Group', + projectGroup: 'Project Group', + totalGroups: '(Total { total } groups)', + closeSorting: 'Close Sorting', + sorting: 'Sorting', + none: 'None', + lastModified: 'Last Modified: ', + total: 'Total ', + items: ' items', + homeShow: 'Home Show', + confirmDeleteGroup: 'Sure you want to delete the group?', + name: 'Name: ', + deleteGroup: 'Delete Group', + confirm: 'Confirm', + cancel: 'Cancel', + deleteSuccess: 'Project Group Delete Successful', + }, + projectGroupEditor: { + title: 'Edit project grouping', + name: 'Grouping name', + namePlaceholder: 'Please enter the name of the grouping', + isShow: 'Home display', + description: 'Description', + descriptionPlaceholder: 'Please enter the description', + descriptionTips: 'The description information is not more than 256 characters', + cancel: 'Cancel', + save: 'Save', + nameRequired: 'The grouping name can not be empty', + success: 'Project grouping modification successful', + }, + projectGroupDetail: { + close: 'Close', + totalProjects: '(Total { count } projects)', + none: 'None', + addProject: 'add project', + projectList: 'project list', + closeSorting: 'close sorting', + sorting: 'sorting', + }, + projectGroupCreator: { + title: 'New project grouping', + name: 'Grouping name', + namePlaceholder: 'Please enter the name of the grouping', + isShow: 'Home display', + description: 'Description', + descriptionPlaceholder: 'Please enter the description', + descriptionTips: 'The description information is not more than 256 characters', + cancel: 'Cancel', + confirm: 'Confirm', + nameRequired: 'The grouping name must not be empty', + success: 'The project grouping was created successfully', + }, + projectAdder: { + title: 'Add project', + selectGroup: 'Select project group', + selectGroupPlaceholder: 'Please select project group', + selectedProject: 'Selected project', + inputPlaceholder: 'Please enter project name or description', + none: 'None', + cancel: 'Cancel', + confirm: 'Confirm', + selectGroupRequired: 'Please select project group', + addProjectRequired: 'Please add project', + success: 'Project added successfully', + }, + skManager: { + close: 'Close', + title: 'Secret Key List', + total: '(Total { keys } Secret Keys)', + add: 'New Secret Key', + none: 'None', + confirmDelete: 'Are you sure you want to delete the secret key?', + name: 'Name: ', + delete: 'Delete Secret Key', + confirm: 'Confirm', + cancel: 'Cancel', + success: 'Delete Successful', + }, + skEditor: { + title: 'Add Secret Key', + name: 'Name', + namePlaceholder: 'Please enter a name', + value: 'Value', + valuePlaceholder: 'Please enter a value', + cancel: 'Cancel', + confirm: 'Confirm', + nameRequired: 'Name can\'t be empty', + valueRequired: 'Value can\'t be empty', + success: 'Add success', + }, + nsManager: { + close: 'Close', + add: 'New Namespace', + title: 'Namespaces', + total: '(Total { length } namespaces)', + none: 'None', + lastModified: 'Last modified: ', + confirmDelete: 'Sure you want to delete namespace?', + nameLabel: 'Name: ', + deleteTitle: 'Delete Namespace', + confirm: 'Confirm', + cancel: 'Cancel', + success: 'Delete Successful', + }, + nsEditor: { + title: 'Add Secret Key Namespace', + name: 'Namespace', + namePlaceholder: 'Please enter the namespace', + description: 'Description', + descriptionPlaceholder: 'Please enter the description', + cancel: 'Cancel', + confirm: 'Confirm', + nameRequired: 'Namespace can\'t be empty', + success: 'New Successful', + }, + workersManager: { + close: 'Close', + title: 'Worker list', + total: '(Total { length } Workers)', + name: 'Name: ', + label: 'Label: ', + none: 'None', + os: 'Operating System: ', + arch: 'Architecture: ', + type: 'Type: ', + time: 'Registered: ', + confirmDeleteMsg: 'Sure you want to delete a Worker?', + confirmDeleteTitle: 'Delete Worker', + confirm: 'Confirm', + cancel: 'Cancel', + success: 'Delete Successful', + }, + detail: { + terminateAll: 'Terminate all', + trigger: 'Trigger', + notClickable: 'Not clickable at this time', + startTime: 'Start time', + endTime: 'Completion time', + suspendedDuration: 'Suspended Duration', + executionDuration: 'Execution Duration', + none: 'None', + instanceId: 'Process instance ID', + version: 'Process version number', + terminate: 'Terminate', + success: 'Operation successful', + confirmTrigger: 'Sure you want to trigger?', + triggerExecution: 'Trigger Project Execution', + confirm: 'Confirm', + cancel: 'Cancel', + terminatingSuccess: 'Operation Successful, terminating, please wait', + confirmTerminateAll: 'Sure you want to terminate all instances in execution/pending?', + terminateExecution: 'Terminate Project Execution', + confirmTerminate: 'Sure you want to terminate?', + terminateSuccess: 'Terminate Successful', + }, + processLog: { + processName: 'Process name', + startTime: 'Start time', + endTime: 'Completion time', + suspendedDuration: 'Suspended Duration', + executionDuration: 'Execution Duration', + instanceId: 'Process instance ID', + version: 'Process version number', + loading: 'Loading...', + }, + taskLog: { + processName: 'Process Name', + executionCount: 'Execution Count', + nodeName: 'Node Name', + successCount: 'Success Count', + nodeDefinition: 'Node Definition', + failureCount: 'Failure Count', + startTime: 'Start Time', + skipCount: 'Skip Count', + executionDuration: 'Execution Duration', + suspendedCount: 'Suspended Count', + executionStatus: 'Execution Status', + ignoreCount: 'Ignore Count', + log: 'Log', + loading: 'Loading...', + businessParams: 'Business Parameters', + inputParams: 'Input Parameters', + paramKey: 'Parameter Unique Identifier', + paramType: 'Parameter Type', + requiredOrNot: 'Yes/No Required', + yes: 'Yes', + no: 'No', + paramValue: 'Parameter Value', + outputParams: 'Output Parameters', + cache: 'Cache', + mountPath: 'Mounted Directory', + status: 'Status', + unavailableTipLine1: 'For unavailable caches, you can go to Project Cards -', + unavailableTipLine2: 'More - Cleanup in Cache or the Project Edit Page to delete', + available: 'Available', + unavailable: 'Unavailable', + requiredField: 'Required fields', + }, + webhookLog: { + processName: 'Process Name: ', + nodeName: 'Node Name: ', + startTime: 'Start Time: ', + log: 'Log', + businessParams: 'Business Parameters', + paramKey: 'Parameter Unique Identifier', + paramType: 'Parameter Type', + paramValue: 'Parameter Value', + notTriggered: 'Not Triggered Yet', + manualTriggerLog: 'This time manually triggered, no webhook logs', + }, + workflow: { + taskLogTitle: 'View Task Execution Log', + processLogTitle: 'View Process Log', + webhookLogTitle: 'View Webhook Log', + }, + index: { + graphProject: 'Graphics Projects', + codeProject: 'Code Projects', + workerManager: 'Worker Management', + localNode: 'Local Nodes', + groupManager: 'Group Management', + secretKeyManager: 'Secret Key Management', + }, + main: { + componentLib: 'Component Library', + loginPage: 'Login Page', + errorPage: 'Error Page: ', + browserVersion: 'Browser Version', + network: 'Web', + }, + login: { + welcome: 'Welcome to login', + usernamePlaceholder: 'Please enter your username', + passwordPlaceholder: 'Please enter your password', + remember: 'Remember username', + login: 'Login', + loginProblem: 'Problems logging in, please try to log in again', + cancel: 'Cancel', + reLogin: 'Re-login', + loggingInWith: 'Account login in progress with {type}…', + loginWith: 'Use {type} account to login', + usernameEmpty: 'Username can\'t be empty', + passwordEmpty: 'Password can\'t be empty', + success: 'Login successful', + }, + projectGroup: { + viewMore: 'View More', + noProjects: 'No Projects', + noResult: 'No related results were found', + totalProjects: '(Total { count } projects)', + }, + cacheDrawerItem: { + unavailable: 'Unavailable', + clear: 'Clear', + viewMount: 'View mount point', + noMount: 'Mount point not set', + node: 'Node', + mountDir: 'Mount directory', + confirmClearTitle: 'Make sure to clear the current cache?', + confirmClearTip: 'Old cached data will be cleared', + cancel: 'Cancel', + confirm: 'Confirm', + clearSuccess: 'Clear Successful', + }, + cacheDrawer: { + viewCache: 'View Cache', + }, + projectItem: { + concurrent: 'Can be concurrent', + tipInit: + 'The prequel process is executing or has hung, and the current process will start executing when it finishes or is manually terminated. Or enable concurrent execution, when enabled, multiple times can be executed at the same time.', + tipSuspended: + 'If a node in the current process fails to execute, the process is suspended and you need to manually retry/ignore the pending node.', + terminate: 'Terminate', + nextTime: 'Until next execution', + suspended: 'Suspend', + running: 'Execution', + duration: 'Duration', + disabled: 'Disabled, not available', + trigger: 'Trigger', + edit: 'Edit', + sync: 'Sync DSL', + openGit: 'Open git repository', + previewWorkflow: 'Preview process', + previewPipeline: 'Preview pipeline', + disable: 'Disable', + enable: 'Enable', + delete: 'Delete', + cache: 'Cache', + + project: 'project', + failed: 'Failed', + Running: 'Executing', + succeeded: 'Successful', + notStarted: 'Not started', + pending: 'Pending start', + nextTimeTip: 'Timed item: next execution time', + confirmTerminate: 'Sure to terminate?', + terminateTitle: 'Terminate project execution', + confirm: 'OK', + cancel: 'Cancel', + terminateSuccess: 'Terminate Successful', + operationSuccess: 'Operation Successful', + confirmTrigger: 'Are you sure you want to trigger?', + triggerTitle: 'Trigger item execution', + confirmGeneric: 'Are you sure you want to?', + enabled: 'Enabled', + Disabled: 'Disabled', + notModifiable: 'Not modifiable', + dslUpdateTip: 'To modify, update via DSL', + close: 'Close', + disableProject: 'Disable project', + enableProject: 'Enable project', + confirmSync: 'Sure to synchronise?', + syncTitle: 'Synchronise DSL', + syncSuccess: 'Synchronise Successful', + confirmDelete: 'Are you sure you want to delete the project?', + deleteTitle: 'Delete project', + name: 'Name:', + deleteSuccess: 'Delete Successful', + }, + webhookDrawer: { + triggerTip: 'You can trigger the process execution by calling the following webhook address', + copyLink: 'Copy Link', + requestList: 'Request List', + noRecordLine1: 'If there is no corresponding trigger record, you can go to the upstream webhook management,', + noRecordLine2: 'to see if the request was sent successfully', + refresh: 'Refresh', + source: 'Source', + requestTime: 'Request Time', + status: 'Status', + success: 'Success', + failure: 'Failure', + errorMessage: 'Error Message', + action: 'Action', + retry: 'Retry', + details: 'Details', + viewDetails: 'View Details', + trigger: 'Trigger', + paramList: 'Parameter List', + paramName: 'Parameter Unique Identifier', + paramType: 'Parameter Type', + paramValue: 'Parameter Value', + authRule: 'Authentication Rule', + noData: 'No data available at this time', + jsonPath: 'Json Path:', + copySuccess: 'Copy Successful', + copyFailed: 'Copy Failed, please copy manually', + retrySuccess: 'Retry Successful', + confirmRetry: 'Are you sure you want to retry?', + confirm: 'Confirm', + cancel: 'Cancel', + }, + webhookSettingDialog: { + title: 'Trigger execution', + tip: 'The project has been configured with a webhook, for manual triggering please fill in the parameters', + importLast: 'Fill in the last parameters', + clear: 'Clear the form', + paramName: 'Parameter name', + type: 'Type', + paramValue: 'Parameter value', + placeholder: 'Please enter the parameter value', + authRule: 'Authentication rules', + cancel: 'Cancel', + confirm: 'Confirm', + selectPlaceholder: 'Please select the parameter value', + }, + nodeToolbar: { + confirmRetry: 'Sure you want to retry?', + confirmIgnore: 'Sure you want to ignore?', + confirm: 'Confirm', + cancel: 'Cancel', + retry: 'Retry', + ignore: 'Ignore', + log: 'Log', + param: 'Parameters', + cache: 'Cache', + }, + taskState: { + INIT: 'Pending startup', + WAITING: 'In queue', + RUNNING: 'Executing', + SKIPPED: 'Skipped', + FAILED: 'Failed to execute', + SUCCEEDED: 'Successful', + SUSPENDED: 'Pending', + IGNORED: 'Ignored', + }, + toolbar: { + exitFullScreen: 'Exit Full Screen', + fullScreen: 'Full Screen', + originalSize: 'Original Size', + fitToScreen: 'Fit to Screen', + rotate: 'Rotate', + zoomOut: 'Zoom Out', + zoomIn: 'Zoom In', + workflowLog: 'WorkFlow Log', + viewDsl: 'View DSL', + return: 'Return', + workflow: 'WorkFlow', + pipeline: 'Pipeline', + }, + projectPanel: { + title: 'Edit project information', + name: 'Project name', + namePlaceholder: 'Please enter the project name', + group: 'Project grouping', + groupPlaceholder: 'Please select the project grouping', + description: 'Project description', + descriptionPlaceholder: 'Please enter the project description', + cancel: 'Cancel', + confirm: 'Confirm', + nameRequired: 'Please enter the project name', + groupRequired: 'Please select the project grouping', + }, + topToolbar: { + zoomOut: 'Zoom out', + zoomIn: 'Zoom in', + center: 'Center', + cache: 'Cache', + maxConcurrent: 'Maximum number of concurrency', + concurrentTip: 'Number of instances that can Execute/Suspend simultaneously in a single process', + saveAndBack: 'Save and return', + save: 'Save', + saveModification: 'Save this modification', + noSave: 'Do not save', + }, + nodeGroup: { + networkError: 'Network Error', + reload: 'Reload', + trigger: 'Trigger', + builtIn: 'Built-in nodes', + local: 'Local nodes', + official: 'Official nodes', + community: 'Community nodes', + }, + nodePanel: { + search: 'Search', + noResult: 'Did not yield any relevant results', + submitRequest: 'Welcome to submit node requests', + }, + cacheEditor: { + placeholder: 'Please enter a unique cache ID', + }, + cacheSelector: { + empty: 'There is no cache at the moment, please go to the top of the cache module to add a cache', + placeholder: 'Mount directory, start with /', + }, + shellEnv: { + name: 'Variable name', + placeholderName: 'Please enter variable name', + value: 'Variable value', + placeholderValue: 'Please enter variable value', + }, + webhookParam: { + name: 'Name', + namePlaceholder: 'Please enter the name of the parameter', + nameRule: 'Begin with an English letter or underscore, underscore, numbers, English letters are supported', + type: 'Type', + typePlaceholder: 'Please select the type of the parameter', + expression: 'Expression', + expressionTip: 'See details ', + extractionRule: 'Extraction rules', + expressionPlaceholder: 'Please enter the parameter expression', + required: 'Required', + no: 'No', + yes: 'Yes', + default: 'Default value', + defaultPlaceholder: 'Please enter the default value', + }, + asyncTaskPanel: { + name: 'Node name', + version: 'Node version', + versionPlaceholder: 'Please select the node version', + inputParam: 'Input parameter', + outputParam: 'Output parameter', + select: 'Please select', + enter: 'Please enter', + cacheMount: 'Cache mount', + cacheMountTip: 'Mount here after adding a cache in the top cache module', + add: 'Add', + failureMode: 'When execution fails', + suspend: 'Mount', + ignore: 'Ignore', + type: 'Type:', + description: 'Description:', + noDescription: 'No description', + noOutput: 'No output parameter', + }, + cachePanel: { + title: 'Cache', + description: + 'Add cache can be mounted in the node to avoid downloading the dependency repeatedly in the next execution of the node and improve the execution speed.', + unique: 'Unique identifier', + uniqueRule: 'Begin with an English letter or underscore, underscore, numbers, English letters are supported', + addCache: 'Add Cache', + deleteTitle: 'Sure to delete the current cache?', + deleteTip: 'Nodes that already refer to this cache will report an error after deletion', + cancel: 'Cancel', + confirm: 'Confirm', + }, + cronPanel: { + placeholder: 'Please enter a cron expression', + meaningTitle: 'The 7 parts of a Cron expression are represented from left to right as follows:', + meaningContent: 'Seconds Minutes Hours Days Months Weeks Years (optional, leave blank)', + exampleTitle: 'Examples of common expressions:', + example1: '0 0 12 * * ? Triggered at 12:00 noon every day', + example2: '0 15 10 * * ? Triggered every day at 10:15 a.m.', + example3: '0 0 1 ? * SAT Triggered at 1am every Saturday', + example4: '0 15 10 ? * MON-FRI Triggered at 10:15am Monday to Friday', + example5: '0 * 10 * * ? Triggered every minute between 10:00 a.m. and 10:59 a.m. every day', + }, + nodeConfigPanel: { + title: 'Node Configuration Panel', + }, + shellPanel: { + name: 'Node Name', + image: 'Docker Image', + imagePlaceholder: 'Please select or enter the image', + env: 'Environment variables', + envTooltip1: 'You can use expressions, refer to global parameters, event parameters or output ', + envTooltip2: 'parameters of the upstream node, see the ', + envTooltipLink: 'Parameters section for more details', + addEnv: 'Adding environment variables', + script: 'Scripts', + scriptPlaceholder: 'Please enter a shell script', + cache: 'Cache mounts', + cacheTooltip: 'Mounts here after adding a cache to the top cache module', + addCache: 'Add', + failureMode: 'Mounts when execution fails', + suspend: 'Suspend', + ignore: 'Ignore', + }, + webhookPanel: { + triggerParam: 'Trigger Parameters', + triggerParamTip: 'Reference to Trigger Parameters ', + paramSection: 'Parameters Section', + addTriggerParam: 'Add Trigger Parameters', + advancedSetting: 'Advanced Settings', + authRule: 'Authentication Rules', + authRuleTip1: 'If you turn off the Authentication Rules, anyone can pass through', + authRuleTip2: 'webhook triggers the process', + tokenTip: 'Webhook Requests for Carrying Authentication Authentication Data', + tokenPlaceholder: 'Please enter a token value', + valueTip1: 'Used to verify the token value, the same authentication succeeds', + valueTip2: 'Must be a secret key type', + valuePlaceholder: 'Please select value', + onlyRule: 'Match the rule, trigger the process when the result is true,', + onlyTip: 'can currently only refer to the trigger parameter. See ', + onlyLink: 'Arithmetic Expressions', + onlyPlaceholder: 'Please enter a matching rule', + }, + paramButton: { + label: 'parameter', + }, + workflowNodeToolbar: { + confirmDelete: 'Are you sure you want to delete?', + name: 'Name: ', + delete: 'Delete ', + node: 'Node', + trigger: 'Trigger', + confirm: 'Confirm', + cancel: 'Cancel', + }, + loadMore: { + show: 'Show More', + noMore: 'No More', + }, + breadcrumb: { + home: 'Home', + worker: 'Worker Management', + localNode: 'Local Node Library', + group: 'Group Management', + secretKey: 'Secret Key Management', + addProject: 'Add New Project', + Details: 'Details', + }, + workflowValidator: { + noNodes: 'No nodes exist', + atLeastOneShellOrTaskNode: 'There is at least one shell or task node', + nodeNotConnected: 'Node: no other nodes connected yet', + node: 'Node: ', + onlyOneTrigger: 'There can only be one trigger', + }, + shell: { + enterVariableName: 'Please enter a variable name', + enterVariableValue: 'Please enter a variable value', + selectCache: 'Please select a cache ', + enterDirectory: 'Please enter a directory ', + enterDirectoryBeginningWithSlash: 'Please enter a directory beginning with /', + selectOrEnterMirrorImage: 'Please select or enter a mirror image', + }, + webhook: { + enterParamName: 'Please enter the parameter name', + paramNamePattern: 'Start with an English letter or underscore, support underscore, numbers, English letters', + selectParamType: 'Please select the parameter type', + enterParamExpression: 'Please enter the parameter expression', + selectParamDefaultValue: 'Please select the parameter default value', + enterParamDefaultValue: 'Please enter the parameter default value', + triggerParamNotExist: 'Trigger parameter does not exist', + enterTokenValue: 'Please enter the token value', + selectKey: 'Please select the key', + }, + cron: { + scheduleNotEmpty: 'schedule cannot be empty', + invalidCronExpression: 'Please enter the correct cron expression', + }, + logViewer: { + downloading: 'Downloading, please wait...', + download: 'Download', + moreLog: 'log is too large, more logs please download to view', + }, + textCopy: { + copy: 'Copy', + valueEmpty: 'value is null', + copied: 'copied', + copyFailed: 'copy failed', + cause: 'cause: ', + }, + }, +}; + +const getDefaultLocale = () => { + const saved = localStorage.getItem('JianmuLang'); + if (saved) return saved; + + const browserLang = navigator.language.split('-')[0]; + const supportedLangs = ['zh', 'en']; + const lang = supportedLangs.includes(browserLang) ? browserLang : 'zh'; + localStorage.setItem('JianmuLang', lang); + return lang; +}; + +const i18n = createI18n({ + locale: getDefaultLocale(), + fallbackLocale: 'zh', + messages, +}); + +export default i18n; +export const globalT = i18n.global.t; diff --git a/ui/src/main.ts b/ui/src/main.ts index 1474429893fad1c02b0d12279e1c3cb901f17b4f..2f37b32986fba4ce935f51c9a7894124ae7756ae 100644 --- a/ui/src/main.ts +++ b/ui/src/main.ts @@ -9,7 +9,7 @@ import { globalErrorHandler } from './utils/global-error-handler'; import './utils/operation-btn-position.ts'; // 安装百度统计 import './utils/baidu-tongji.ts'; - +import i18n from './locales'; // 打印环境变量,用于调试 console.debug(import.meta.env); const app = createApp(App); @@ -21,10 +21,9 @@ app.use(components); app.use(router); // 安装vuex app.use(store); - +app.use(i18n); // 注册全局异常处理方法 -app.config.errorHandler = (err, instance, info) => - globalErrorHandler(err as Error, instance, info, router, store); +app.config.errorHandler = (err, instance, info) => globalErrorHandler(err as Error, instance, info, router, store); app.config.globalProperties.$throw = (err: Error, instance: ComponentPublicInstance | null) => globalErrorHandler(err, instance, null, router, store); diff --git a/ui/src/router/index.ts b/ui/src/router/index.ts index d8d7f9079f3e231bea5f85796c68e5bc86ef5076..cd2403cb0c3ac182147d10a31a0e17de0175afa4 100644 --- a/ui/src/router/index.ts +++ b/ui/src/router/index.ts @@ -5,7 +5,7 @@ import { namespace as sessionNs } from '@/store/modules/session'; import { IState as ISessionState } from '@/model/modules/session'; import LoginVerify from '@/views/login/dialog.vue'; import { AppContext } from 'vue'; - +import { globalT as t } from '@/utils/i18n'; /** * 加载业务模块路由 * @param path @@ -66,7 +66,7 @@ export default (appContext: AppContext) => { // platform模块 loadModuleRoute( PLATFORM_INDEX, - '首页', + t('breadcrumb.home'), false, import('@/layout/platform.vue'), import.meta.globEager('./modules/platform.ts'), diff --git a/ui/src/router/modules/platform.ts b/ui/src/router/modules/platform.ts index 411c2b1a85a790c3214e51eff2ff9712437a14e2..954756f956242d4d78256d877a58f0ce17211117 100644 --- a/ui/src/router/modules/platform.ts +++ b/ui/src/router/modules/platform.ts @@ -1,5 +1,5 @@ import { RouteLocationNormalizedLoaded, RouteRecordRaw } from 'vue-router'; - +import { globalT as t } from '@/utils/i18n'; export default [ // 首页 { @@ -28,7 +28,7 @@ export default [ path: 'worker-manager', component: () => import('@/views/workers/workers-manager.vue'), meta: { - title: 'Worker管理', + title: t('breadcrumb.worker'), }, }, // 节点库路由 @@ -37,7 +37,7 @@ export default [ path: 'node-library', component: () => import('@/views/node-library/node-library-manager.vue'), meta: { - title: '本地节点库', + title: t('breadcrumb.localNode'), }, }, { @@ -45,7 +45,7 @@ export default [ path: 'project-group', component: () => import('@/views/project-group/project-group-manager.vue'), meta: { - title: '分组管理', + title: t('breadcrumb.group'), }, children: [ { @@ -66,7 +66,7 @@ export default [ path: 'secret-key', component: () => import('@/views/secret-key/ns-manager.vue'), meta: { - title: '密钥管理', + title: t('breadcrumb.secretKey'), }, children: [ { @@ -77,7 +77,7 @@ export default [ ns: namespace, }), meta: { - title: '详情', + title: t('breadcrumb.Details'), }, }, ], @@ -95,7 +95,7 @@ export default [ path: 'project/editor', component: () => import('@/views/project/editor.vue'), meta: { - title: '新增项目', + title: t('breadcrumb.addProject'), }, }, { diff --git a/ui/src/utils/i18n.ts b/ui/src/utils/i18n.ts new file mode 100644 index 0000000000000000000000000000000000000000..cb48463e4d40b55b81c0db0eb848e5aa5910748e --- /dev/null +++ b/ui/src/utils/i18n.ts @@ -0,0 +1,18 @@ +import { useI18n } from 'vue-i18n'; +import { globalT } from '@/locales'; + +export function useLocale() { + const { locale, t } = useI18n(); + + const handleLocaleChange = (lang: string) => { + locale.value = lang; + localStorage.setItem('JianmuLang', lang); + }; + + return { + t, + locale, + handleLocaleChange, + }; +} +export { globalT }; diff --git a/ui/src/views/common/cache-drawer-item.vue b/ui/src/views/common/cache-drawer-item.vue index 863b8d4f56d538a8037ac1d92f6dbd8e505c1e30..7a1678c1aa8b703856af5ce68895ed3845163a44 100644 --- a/ui/src/views/common/cache-drawer-item.vue +++ b/ui/src/views/common/cache-drawer-item.vue @@ -3,12 +3,14 @@
- 不可用
+ {{ t('cacheDrawerItem.unavailable') }}
清理
+
+ {{ t('cacheDrawerItem.clear') }}
+
{{ originData.workerId }}
@@ -16,16 +18,16 @@
-
- 旧的缓存数据将被清空
+
+ {{ t('cacheDrawerItem.confirmClearTip') }}
- 取消
- 确定
+ {{ t('cacheDrawerItem.cancel') }}
+ {{
+ t('cacheDrawerItem.confirm')
+ }}
@@ -61,6 +71,7 @@ import yaml from 'yaml';
import { clearCache } from '@/api/cache';
import defaultIcon from '@/components/workflow/workflow-editor/svgs/shape/async-task.svg';
import shellIcon from '@/components/workflow/workflow-editor/svgs/shape/shell.svg';
+import { useLocale } from '@/utils/i18n';
export default defineComponent({
props: {
@@ -70,6 +81,7 @@ export default defineComponent({
},
},
setup(props) {
+ const { t } = useLocale();
const { proxy } = getCurrentInstance() as any;
const toggle = ref(false);
const dialogVisible = ref(false);
@@ -94,7 +106,7 @@ export default defineComponent({
try {
loading.value = true;
await clearCache(originData.value.id);
- proxy.$success('清理成功');
+ proxy.$success(t('cacheDrawerItem.clearSuccess'));
dialogVisible.value = false;
} catch (err) {
proxy.$throw(err, proxy);
@@ -103,6 +115,7 @@ export default defineComponent({
}
};
return {
+ t,
loading,
toggle,
dialogVisible,
diff --git a/ui/src/views/common/cache-drawer.vue b/ui/src/views/common/cache-drawer.vue
index f39a191d256342039969732690923161410d9a1b..03b16eaa7f2e0bd2165b1e9f9ef1cc0cbf576580 100644
--- a/ui/src/views/common/cache-drawer.vue
+++ b/ui/src/views/common/cache-drawer.vue
@@ -11,7 +11,7 @@
diff --git a/ui/src/views/common/login.vue b/ui/src/views/common/login.vue
index ec59ef05a4736ef75b30ac2cb223caa3a6818ac4..d838f3112d09b8c7535e0ad2c307b8a8a2992c95 100644
--- a/ui/src/views/common/login.vue
+++ b/ui/src/views/common/login.vue
@@ -2,7 +2,7 @@
- 记住用户名
+ {{ t('login.remember') }}
@@ -46,10 +46,10 @@
-
@@ -71,6 +73,7 @@ import { useRoute, useRouter } from 'vue-router';
import { AUTHORIZE_INDEX, PLATFORM_INDEX } from '@/router/path-def';
import { fetchAuthUrl } from '@/api/session';
import { getRedirectUri } from '@/utils/redirect-uri';
+import { useLocale } from '@/utils/i18n';
const { mapActions: mapSessionActions, mapMutations } = createNamespacedHelpers(namespace);
@@ -87,6 +90,7 @@ export default defineComponent({
},
},
setup(props: any, { emit }) {
+ const { t } = useLocale();
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const route = useRoute();
@@ -149,7 +153,7 @@ export default defineComponent({
// 登录成功
loading.value = false;
authError.value = false;
- proxy.$success('登录成功');
+ proxy.$success(t('login.success'));
setTimeout(() => {
emit('logined');
}, 500);
@@ -210,6 +214,7 @@ export default defineComponent({
window.onstorage = null;
});
return {
+ t,
authError,
loginType,
Type,
@@ -218,8 +223,8 @@ export default defineComponent({
loginFormRef,
loginForm,
loginRule: ref>({
- username: [{ required: true, message: '用户名不能为空', trigger: 'blur' }],
- password: [{ required: true, message: '密码不能为空', trigger: 'blur' }],
+ username: [{ required: true, message: t('login.usernameEmpty'), trigger: 'blur' }],
+ password: [{ required: true, message: t('login.passwordEmpty'), trigger: 'blur' }],
}),
login: () => {
// 开启loading
diff --git a/ui/src/views/common/project-group.vue b/ui/src/views/common/project-group.vue
index 2245fbb6d84d0e181426cc217b9d89b1fede48dd..fa0d3d0de8e3859a2b27f79e52fb827eb22250f5 100644
--- a/ui/src/views/common/project-group.vue
+++ b/ui/src/views/common/project-group.vue
@@ -16,11 +16,13 @@
{{ projectGroup?.name }}
- (共有 {{ projectPage.total >= 0 ? projectPage.total : 0 }} 个项目)
+ {{
+ $t('projectGroup.totalProjects', { count: projectPage.total >= 0 ? projectPage.total : 0 })
+ }}
- 查看更多
+ {{ $t('projectGroup.viewMore') }}
@@ -29,10 +31,14 @@
- 终止
+ {{
+ t('projectItem.terminate')
+ }}
- 查看挂载点
+ {{ t('cacheDrawerItem.viewMount') }}
- 未设置挂载点
+ {{ t('cacheDrawerItem.noMount') }}
-
节点
- 挂载目录
+ {{ t('cacheDrawerItem.node') }}
+ {{ t('cacheDrawerItem.mountDir') }}
@@ -42,12 +44,20 @@
- 查看缓存
+ {{ $t('cacheDrawer.viewCache') }}
- 欢迎登录
+ {{ t('login.welcome') }}
@@ -14,7 +14,7 @@
v-model="loginForm.username"
prefix-icon="jm-icon-input-user"
clearable
- placeholder="请输入用户名"
+ :placeholder="t('login.usernamePlaceholder')"
@keyup.enter="login"
/>
@@ -27,18 +27,18 @@
type="password"
clearable
show-password
- placeholder="请输入密码"
+ :placeholder="t('login.passwordPlaceholder')"
@keyup.enter="login"
/>
- 登录
+ {{ t('login.login') }}
登录遇到问题,请尝试重新登录
+ {{ t('login.loginProblem') }}
- 取消
- 重新登录
+ {{ t('login.cancel') }}
+ {{ t('login.reLogin') }}
@@ -57,7 +57,9 @@
- {{ loading ? `${Type} 账号登录中…` : `使用 ${Type} 账号登录` }}
+ {{
+ loading ? t('login.loggingInWith', { type: Type }) : t('login.loginWith', { type: Type })
+ }}
-
+
diff --git a/ui/src/views/common/project-item.vue b/ui/src/views/common/project-item.vue
index 54f569caadcf79afb5e37a3401a9c16a8ffe40ab..266daafe7ce2e9739721b7f639220afa2e5f1e80 100644
--- a/ui/src/views/common/project-item.vue
+++ b/ui/src/views/common/project-item.vue
@@ -8,7 +8,7 @@
>
- 可并发
+ {{ t('projectItem.concurrent') }}
#{{ executeCount }}
- 距离下次执行还有
+ {{ t('projectItem.nextTime') }}
@@ -63,7 +63,13 @@
- {{ project.status === ProjectStatusEnum.SUSPENDED ? '挂起' : '执行' }}时长
+ {{
+ project.status === ProjectStatusEnum.SUSPENDED
+ ? t('projectItem.suspended')
+ : t('projectItem.running')
+ }}{{ t('projectItem.duration') }}
- 终止
+ {{
+ t('projectItem.terminate')
+ }}
-
+
-
+
-
+
-
+
-
+
-
+
@@ -135,12 +156,15 @@
href="javascript: void(0)"
:class="enabled ? 'jm-icon-button-disable' : 'jm-icon-button-off'"
style="width: 90px; display: inline-block"
- >{{ enabled ? '禁用' : '启用' }}{{ enabled ? t('projectItem.disable') : t('projectItem.enable') }}
- 删除{{ t('projectItem.delete') }}
@@ -167,7 +191,7 @@
>
- 可并发
+ {{ t('projectItem.concurrent') }}
#{{ executeCount }}
- 距离下次执行还有
+ {{ t('projectItem.nextTime') }}
@@ -222,7 +246,13 @@
- {{ project.status === ProjectStatusEnum.SUSPENDED ? '挂起' : '执行' }}时长
+ {{
+ project.status === ProjectStatusEnum.SUSPENDED
+ ? t('projectItem.suspended')
+ : t('projectItem.running')
+ }}{{ t('projectItem.duration') }}
-
+
-
+
-
+
-
+
-
+
-
+
@@ -294,7 +339,7 @@
href="javascript: void(0)"
class="jm-icon-workflow-cache"
style="width: 90px; display: inline-block"
- >缓存{{ t('projectItem.cache') }}
@@ -302,12 +347,15 @@
href="javascript: void(0)"
:class="enabled ? 'jm-icon-button-disable' : 'jm-icon-button-off'"
style="width: 90px; display: inline-block"
- >{{ enabled ? '禁用' : '启用' }}{{ enabled ? t('projectItem.disable') : t('projectItem.enable') }}
- 删除{{ t('projectItem.delete') }}
@@ -352,6 +400,7 @@ import { useRouter } from 'vue-router';
import { terminate } from '@/api/workflow-execution-record';
import dayjs from 'dayjs';
import WebhookSettingDialog from '@/views/common/webhook-setting-dialog.vue';
+import { useLocale } from '@/utils/i18n';
export default defineComponent({
components: { WebhookSettingDialog, ProjectPreviewDialog, WebhookDrawer, CacheDrawer },
@@ -378,6 +427,7 @@ export default defineComponent({
},
emits: ['triggered', 'synchronized', 'deleted', 'terminated'],
setup(props: any, { emit }: SetupContext) {
+ const { t } = useLocale();
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const isMove = computed(() => props.move);
@@ -408,20 +458,20 @@ export default defineComponent({
const statusDesc = computed(() => {
switch (props.project.status) {
case ProjectStatusEnum.SUSPENDED:
- return '挂起';
+ return t('projectItem.suspended');
case ProjectStatusEnum.FAILED:
- return '失败';
+ return t('projectItem.failed');
case ProjectStatusEnum.RUNNING:
- return '执行中';
+ return t('projectItem.Running');
case ProjectStatusEnum.SUCCEEDED:
- return '成功';
+ return t('projectItem.succeeded');
default:
- return props.project.serialNo === 0 ? '未启动' : '待启动';
+ return props.project.serialNo === 0 ? t('projectItem.notStarted') : t('projectItem.pending');
}
});
// alarm 提示
const alarmTip = computed(
- () => `定时项目:下次执行时间 ${dayjs(props.project.nextTime).format('MM-DD HH:mm')}`,
+ () => `${t('projectItem.nextTimeTip')} ${dayjs(props.project.nextTime).format('MM-DD HH:mm')}`,
);
// 控制是否显示下一次执行时间
const isShowNextTime = computed(() => {
@@ -435,15 +485,15 @@ export default defineComponent({
});
const stopProcess = (id: string) => {
proxy
- .$confirm('确定要终止吗?', '终止项目执行', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
+ .$confirm(t('projectItem.confirmTerminate'), t('projectItem.terminateTitle'), {
+ confirmButtonText: t('projectItem.confirm'),
+ cancelButtonText: t('projectItem.cancel'),
type: 'info',
})
.then(() => {
terminate(id)
.then(() => {
- proxy.$success('终止成功');
+ proxy.$success(t('projectItem.terminateSuccess'));
// 终止项目
emit('terminated', id);
})
@@ -459,7 +509,7 @@ export default defineComponent({
try {
executing.value = true;
await executeImmediately(props.project.id, payload);
- proxy.$success('操作成功');
+ proxy.$success(t('projectItem.operationSuccess'));
visible.value = false;
emit('triggered', props.project.id);
} catch (err) {
@@ -469,6 +519,7 @@ export default defineComponent({
}
};
return {
+ t,
visible,
webhookDefinition,
executeCount,
@@ -503,16 +554,16 @@ export default defineComponent({
const { triggerType } = props.project;
const isWarning = triggerType === TriggerTypeEnum.WEBHOOK;
- const msg = '
+
-
-
+
+
-
+
-
-
+
-
+
@@ -94,14 +96,16 @@
+
-
+
{{ scope.row.type }}
-
+
@@ -53,13 +62,17 @@
-
+
@@ -85,7 +98,7 @@
取消
- 确定
+ {{ t('webhookSettingDialog.cancel') }}
+ {{ t('webhookSettingDialog.confirm') }}
@@ -114,6 +127,7 @@ import { IProjectTriggeringDto, ITriggerDefinitionVo, IWebhookAuth, IWebhookPara
import { ParamTypeEnum } from '@/components/workflow/workflow-editor/model/data/enumeration';
import { IWebhookParameterVo, IWebRequestVo } from '@/api/dto/trigger';
import { getWebhookList, getWebhookParams } from '@/api/trigger';
+import { useLocale } from '@/utils/i18n';
export default defineComponent({
emits: ['update:model-value', 'submit'],
@@ -132,6 +146,7 @@ export default defineComponent({
},
},
setup(props, { emit }) {
+ const { t } = useLocale();
const { proxy } = getCurrentInstance() as any;
const dialogVisible = computed(() => props.modelValue);
const formRef = ref>();
@@ -176,7 +191,9 @@ export default defineComponent({
const rule = [
{
required: true,
- message: isBoolean ? '请选择参数值' : '请输入参数值',
+ message: isBoolean
+ ? t('webhookSettingDialog.selectPlaceholder')
+ : t('webhookSettingDialog.placeholder'),
trigger: isBoolean ? 'change' : 'blur',
},
];
@@ -257,6 +274,7 @@ export default defineComponent({
});
};
return {
+ t,
paramTableRef,
paramsTableHeight,
ruleForm,
diff --git a/ui/src/views/error/browser-version.vue b/ui/src/views/error/browser-version.vue
index 80e09dce794f5bc3b0f2fbe949b8eba23aa74027..c251187b636d061b9abd0a3c540abd91015a5ab4 100644
--- a/ui/src/views/error/browser-version.vue
+++ b/ui/src/views/error/browser-version.vue
@@ -1,17 +1,19 @@
确定要触发吗?
';
+ const msg = `${t('projectItem.confirmTrigger')}
`;
if (isWarning) {
// 获取webhook触发器定义
webhookDefinition.value = await fetchWebhookDefinition(id);
// 如果没有webhook触发器参数定义则可直接触发
if (!webhookDefinition.value.params) {
proxy
- .$confirm(msg, '触发项目执行', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
+ .$confirm(msg, t('projectItem.triggerTitle'), {
+ confirmButtonText: t('projectItem.confirm'),
+ cancelButtonText: t('projectItem.cancel'),
type: 'info',
dangerouslyUseHTMLString: true,
})
@@ -521,7 +572,7 @@ export default defineComponent({
executeImmediately(id)
.then(() => {
- proxy.$success('操作成功');
+ proxy.$success(t('projectItem.operationSuccess'));
executing.value = false;
emit('triggered', id);
})
@@ -536,9 +587,9 @@ export default defineComponent({
}
} else {
proxy
- .$confirm(msg, '触发项目执行', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
+ .$confirm(msg, t('projectItem.triggerTitle'), {
+ confirmButtonText: t('projectItem.confirm'),
+ cancelButtonText: t('projectItem.cancel'),
type: isWarning ? 'warning' : 'info',
dangerouslyUseHTMLString: true,
})
@@ -547,7 +598,7 @@ export default defineComponent({
executeImmediately(id)
.then(() => {
- proxy.$success('操作成功');
+ proxy.$success(t('projectItem.operationSuccess'));
executing.value = false;
emit('triggered', id);
})
@@ -563,27 +614,31 @@ export default defineComponent({
return;
}
- const str = enabled.value ? '禁用' : '启用';
+ const str = enabled.value ? t('projectItem.disable') : t('projectItem.enable');
const msg = props.project.mutable
? `
`
: `
- ${enabled.value ? '已启用' : '已禁用'},不可修改
+ ${enabled.value ? t('projectItem.enabled') : t('projectItem.Disabled')},${t(
+ 'projectItem.notModifiable',
+)}
- 若要修改,请通过DSL更新
+ ${t(
+ 'projectItem.dslUpdateTip',
+ )}
`;
proxy
- .$confirm(msg, `${str}项目`, {
+ .$confirm(msg, `${str}${t('projectItem.project')}`, {
showConfirmButton: props.project.mutable,
- confirmButtonText: '确定',
- cancelButtonText: props.project.mutable ? '取消' : '关闭',
+ confirmButtonText: t('projectItem.confirm'),
+ cancelButtonText: props.project.mutable ? t('projectItem.cancel') : t('projectItem.close'),
type: 'info',
dangerouslyUseHTMLString: true,
})
@@ -593,7 +648,7 @@ export default defineComponent({
await active(id, !enabled.value);
enabled.value = !enabled.value;
- proxy.$success(enabled.value ? '已启用' : '已禁用');
+ proxy.$success(enabled.value ? t('projectItem.enabled') : t('projectItem.Disabled'));
} catch (err) {
proxy.$throw(err, proxy);
} finally {
@@ -610,9 +665,9 @@ export default defineComponent({
}
proxy
- .$confirm('确定要同步吗?', '同步DSL', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
+ .$confirm(t('projectItem.confirmSync'), t('projectItem.syncTitle'), {
+ confirmButtonText: t('projectItem.confirm'),
+ cancelButtonText: t('projectItem.cancel'),
type: 'info',
})
.then(() => {
@@ -620,7 +675,7 @@ export default defineComponent({
synchronize(id)
.then(() => {
- proxy.$success('同步成功');
+ proxy.$success(t('projectItem.syncSuccess'));
synchronizing.value = false;
emit('synchronized', id);
@@ -638,13 +693,12 @@ export default defineComponent({
const { name } = props.project;
- let msg = '确定要删除项目吗?
';
- msg += `名称:${name}
`;
-
+ let msg = `${t('projectItem.confirmDelete')}
`;
+ msg += `${t('projectItem.name')}${name}
`;
proxy
- .$confirm(msg, '删除项目', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
+ .$confirm(msg, t('projectItem.deleteTitle'), {
+ confirmButtonText: t('projectItem.confirm'),
+ cancelButtonText: t('projectItem.cancel'),
type: 'warning',
dangerouslyUseHTMLString: true,
})
@@ -653,7 +707,7 @@ export default defineComponent({
del(id)
.then(() => {
- proxy.$success('删除成功');
+ proxy.$success(t('projectItem.deleteSuccess'));
deleting.value = false;
emit('deleted', id);
diff --git a/ui/src/views/common/webhook-drawer.vue b/ui/src/views/common/webhook-drawer.vue
index f88a5b63013c22b878092c0c73526ca9485f17e9..9f5d70b0a85210923707ea9d3b09631ebab6e044 100644
--- a/ui/src/views/common/webhook-drawer.vue
+++ b/ui/src/views/common/webhook-drawer.vue
@@ -12,7 +12,7 @@
{{ currentProject }}
-
可以通过调用以下Webhook地址来触发流程执行
+ {{ t('webhookDrawer.triggerTip') }}
@@ -21,22 +21,22 @@
- 复制链接
+ {{ t('webhookDrawer.copyLink') }}
-
- 若无对应的触发记录,可到上游webhook管理中,
- 查看请求是否发送成功 + {{ t('webhookDrawer.noRecordLine1') }}
+ {{ t('webhookDrawer.noRecordLine2') }}
- 请求列表
+ {{ t('webhookDrawer.requestList') }}
- 查看请求是否发送成功 + {{ t('webhookDrawer.noRecordLine1') }}
+ {{ t('webhookDrawer.noRecordLine2') }}
{{ datetimeFormatter(scope.row.requestTime) }}
成功
- 失败
+
+ {{ t('webhookDrawer.success') }}
+
+ {{ t('webhookDrawer.failure') }}
-
重试
- 详情
+ {{ t('webhookDrawer.retry') }}
+ {{ t('webhookDrawer.details') }}
-
@@ -111,7 +115,7 @@
触发器
+
+ {{ t('webhookDrawer.trigger') }}
+
Payload
JsonView
-
@@ -123,15 +127,15 @@
Json路径:
+ {{ t('webhookDrawer.jsonPath') }}
-
-
+
-
-
+
+
@@ -204,6 +208,7 @@ import { StateEnum } from '@/components/load-more/enumeration';
import { ParamTypeEnum } from '@/api/dto/enumeration';
import JmTextViewer from '@/components/text-viewer/index.vue';
import ParamValue from '@/views/common/param-value.vue';
+import { useLocale } from '@/utils/i18n';
enum TabState {
TRIGGER = 'TRIGGER',
@@ -226,6 +231,7 @@ export default defineComponent({
},
emits: ['update:webhookVisible'],
setup(props, { emit }) {
+ const { t } = useLocale();
const { proxy } = getCurrentInstance() as any;
const { toClipboard } = useClipboard();
@@ -378,9 +384,9 @@ export default defineComponent({
}
try {
await toClipboard(link.value);
- proxy.$success('复制成功');
+ proxy.$success(t('webhookDrawer.copySuccess'));
} catch (err) {
- proxy.$error('复制失败,请手动复制');
+ proxy.$error(t('webhookDrawer.copyFailed'));
console.error(err);
}
};
@@ -397,7 +403,7 @@ export default defineComponent({
try {
webhookRequestParams.value.pageNum = START_PAGE_NUM;
await retryWebRequest(id);
- proxy.$success('重试成功');
+ proxy.$success(t('webhookDrawer.retrySuccess'));
// 旧数据覆盖新数据
await getWebhookRequestList('cover');
} catch (err) {
@@ -405,12 +411,13 @@ export default defineComponent({
}
};
// 重试
- let msg = '参数列表
+ {{ t('webhookDrawer.paramList') }}
@@ -171,7 +175,7 @@
-
@@ -181,7 +185,7 @@
认证规则
+ {{ t('webhookDrawer.authRule') }}
{{ webhookParamsDetail?.only }}
- 暂无数据
+ {{ t('webhookDrawer.noData') }}
确定要重试吗?
';
+ let msg = `${t('webhookDrawer.confirmRetry')}
`;
const retry = (id: string) => {
+ proxy;
proxy
- .$confirm(msg, '重试', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
+ .$confirm(msg, t('webhookDrawer.retry'), {
+ confirmButtonText: t('webhookDrawer.confirm'),
+ cancelButtonText: t('webhookDrawer.cancel'),
type: 'info',
dangerouslyUseHTMLString: true,
})
@@ -498,9 +505,9 @@ export default defineComponent({
}
try {
await toClipboard(value);
- proxy.$success('复制成功');
+ proxy.$success(t('webhookDrawer.copySuccess'));
} catch (err) {
- proxy.$error('复制失败,请手动复制');
+ proxy.$error(t('webhookDrawer.copyFailed'));
console.error(err);
}
};
@@ -516,6 +523,7 @@ export default defineComponent({
refreshFlag.value = false;
};
return {
+ t,
loadState,
height,
scrollableEl,
diff --git a/ui/src/views/common/webhook-setting-dialog.vue b/ui/src/views/common/webhook-setting-dialog.vue
index ea68b82e706a5559e1441c1da99dcd30d4d3d589..f0b3d5872673d5e56da915a685d5de058613f8fb 100644
--- a/ui/src/views/common/webhook-setting-dialog.vue
+++ b/ui/src/views/common/webhook-setting-dialog.vue
@@ -7,18 +7,18 @@
:destroy-on-close="true"
@close="closeDialog"
>
- 触发执行
+ {{ t('webhookSettingDialog.title') }}
- 项目已配置webhook,手动触发请填写参数
+ {{ t('webhookSettingDialog.tip') }}
@@ -31,7 +31,12 @@
:height="paramsTableHeight"
class="params-table"
>
-
- 填入上次参数
+ {{ t('webhookSettingDialog.importLast') }}
- 清空表单
+ {{ t('webhookSettingDialog.clear') }}
@@ -39,12 +44,16 @@
-
@@ -99,8 +112,8 @@
- 认证规则
+ {{ t('webhookSettingDialog.authRule') }}
-
- 返回首页
+ {{
+ $t('browserVersion.backHome')
+ }}
抱歉,不支持此浏览器
+ {{ $t('browserVersion.unsupported') }}
-
+
+
-
{{ minVersion }}
@@ -27,22 +29,28 @@ import BottomNav from '@/views/nav/bottom.vue';
const browsers: {
name: string;
minVersion: string;
-}[] = [{
- name: 'chrome',
- minVersion: '26.0',
-}, {
- name: 'edge',
- minVersion: '45.0',
-}, {
- name: 'firefox',
- minVersion: '16.0',
-}, {
- name: 'safari',
- minVersion: '6.1',
-}, {
- name: 'opera',
- minVersion: '12.1',
-}];
+}[] = [
+ {
+ name: 'chrome',
+ minVersion: '26.0',
+ },
+ {
+ name: 'edge',
+ minVersion: '45.0',
+ },
+ {
+ name: 'firefox',
+ minVersion: '16.0',
+ },
+ {
+ name: 'safari',
+ minVersion: '6.1',
+ },
+ {
+ name: 'opera',
+ minVersion: '12.1',
+ },
+];
export default defineComponent({
components: { BottomNav },
@@ -91,7 +99,7 @@ export default defineComponent({
width: 150px;
text-align: center;
font-size: 14px;
- color: #FFFFFF;
+ color: #ffffff;
background-repeat: no-repeat;
background-position: center top;
@@ -129,7 +137,7 @@ export default defineComponent({
width: 500px;
height: 280px;
position: absolute;
- background-color: #D9EBFF;
+ background-color: #d9ebff;
border-top-left-radius: 111px;
opacity: 0.14;
transform: rotate(23deg);
diff --git a/ui/src/views/error/http-status.vue b/ui/src/views/error/http-status.vue
index c33e3b6cb61bf97d3528165d1d974cedcf491fb7..224995cdc013f3cad75143bee1653431e2f1af6e 100644
--- a/ui/src/views/error/http-status.vue
+++ b/ui/src/views/error/http-status.vue
@@ -1,12 +1,12 @@
-
+
- 返回首页
+ {{ $t('httpStatus.backHome') }}
-
+
{{ message }}
@@ -16,7 +16,7 @@
\ No newline at end of file
+
diff --git a/ui/src/views/nav/bottom.vue b/ui/src/views/nav/bottom.vue
index 9e4c67836686ed2f619691b75e3cc782420fabd6..37114caa3d5fd98e3a9239082b2804b3b1e12c06 100644
--- a/ui/src/views/nav/bottom.vue
+++ b/ui/src/views/nav/bottom.vue
@@ -1,12 +1,10 @@
- 退出
+
+
+
+ {{ t('top.language') }}
+ {{ locale === 'zh' ? '简体中文' : 'English' }}
+
+
+
+
+
+ 简体中文
+ English
+
+
+
+ {{ t('top.logout') }}
@@ -56,7 +79,7 @@
- 木兰社区孵化项目
- 关于建木
- 使用手册
- 联系我们
+ {{ $t('bottom.project') }}
+ {{ $t('bottom.about') }}
+ {{ $t('bottom.manual') }}
+ {{ $t('bottom.contact') }}
diff --git a/ui/src/views/nav/bottom2.vue b/ui/src/views/nav/bottom2.vue
index 3dfb3053da038a18430e7464e35bec12f49443aa..be4c003b0304334d8e1ceab12be87526a9fc154b 100644
--- a/ui/src/views/nav/bottom2.vue
+++ b/ui/src/views/nav/bottom2.vue
@@ -1,14 +1,12 @@
- 木兰社区孵化项目
+ {{ $t('bottom.project') }}
- 关于建木
+ {{ $t('bottom.about') }}
- 使用手册
+ {{ $t('bottom.manual') }}
- 联系我们
+ {{ $t('bottom.contact') }}
@@ -45,7 +43,7 @@ export default defineComponent({
.line {
width: 1px;
height: 14px;
- background: #B9CFE6;
+ background: #b9cfe6;
}
.mulan {
diff --git a/ui/src/views/nav/top.vue b/ui/src/views/nav/top.vue
index 64a061a0074ec3a8950a918b23cb4ea8be45a6fd..566c9a9252308116078abb5353db6acff13414b6 100644
--- a/ui/src/views/nav/top.vue
+++ b/ui/src/views/nav/top.vue
@@ -47,7 +47,30 @@