From 2574ce1305b5794b987b4a939e10454dad6b6d59 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Tue, 21 Apr 2026 05:25:12 +0000 Subject: [PATCH 01/16] feat(workflow-template): add frontend API adaptation and i18n keys for data export workflow - DEV-022: Extend WorkFlowStepTemplateReqV1TypeEnum with export_review/export_execute; add WorkflowTemplateTypeEnum (workflow/data_export); add workflow_type field to IWorkflowTemplateDetailResV1 - DEV-023: Add optional workflow_type param to getWorkflowTemplateV1 and updateWorkflowTemplateV1; add new getWorkflowTemplateListV1 function calling GET /v1/projects/{name}/workflow_templates; add IGetWorkflowTemplateListResV1 type - DEV-029: Add zh-CN and en-US i18n keys in sqle workflowTemplate (list table columns, type tags, edit page titles, export review/execute step descriptions) and base dmsDataExport (approval process preview section) refs actiontech/dms-ee#784 (cherry picked from commit 4dd5e5c985fb49d2684609cf0530bfe86d686678) --- .../base/src/locale/en-US/dmsDataExport.ts | 7 +++++ .../base/src/locale/zh-CN/dmsDataExport.ts | 7 +++++ .../shared/lib/api/sqle/service/common.d.ts | 10 +++++++ .../lib/api/sqle/service/common.enum.ts | 12 ++++++++- .../lib/api/sqle/service/workflow/index.d.ts | 12 +++++++++ .../lib/api/sqle/service/workflow/index.ts | 26 ++++++++++++++++++- .../sqle/src/locale/en-US/workflowTemplate.ts | 23 ++++++++++++++-- .../sqle/src/locale/zh-CN/workflowTemplate.ts | 22 ++++++++++++++-- 8 files changed, 113 insertions(+), 6 deletions(-) diff --git a/packages/base/src/locale/en-US/dmsDataExport.ts b/packages/base/src/locale/en-US/dmsDataExport.ts index 10c6c50e3d..6d25445c00 100644 --- a/packages/base/src/locale/en-US/dmsDataExport.ts +++ b/packages/base/src/locale/en-US/dmsDataExport.ts @@ -56,6 +56,13 @@ export default { result: { success: 'Task created successfully', guide: 'View the newly created task' + }, + approvalProcess: { + title: 'Approval Process', + hint: 'Approval process can be modified in Project Configure > Approval Process', + stepLabel: 'Step {{number}}', + matchByPermission: 'Match by Permission', + loadFailed: 'Failed to load approval process' } }, batchClose: { diff --git a/packages/base/src/locale/zh-CN/dmsDataExport.ts b/packages/base/src/locale/zh-CN/dmsDataExport.ts index 28a2e382d7..80b18dd8d0 100644 --- a/packages/base/src/locale/zh-CN/dmsDataExport.ts +++ b/packages/base/src/locale/zh-CN/dmsDataExport.ts @@ -52,6 +52,13 @@ export default { hasExceptionRule: '当前存在审核规则未被校验,请排除问题后重新触发审核', continueSubmission: '仍要创建' }, + approvalProcess: { + title: '审批流程', + hint: '审批流程可在 Project Configure > Approval Process 中修改', + stepLabel: '步骤 {{number}}', + matchByPermission: '按权限匹配', + loadFailed: '加载审批流程失败' + }, update: { baseTitle: '工单基本信息', sourceTitle: '工单导出对象', diff --git a/packages/shared/lib/api/sqle/service/common.d.ts b/packages/shared/lib/api/sqle/service/common.d.ts index 993b7cdaf3..333f923789 100644 --- a/packages/shared/lib/api/sqle/service/common.d.ts +++ b/packages/shared/lib/api/sqle/service/common.d.ts @@ -2503,6 +2503,14 @@ export interface IGetWorkflowTemplateResV1 { message?: string; } +export interface IGetWorkflowTemplateListResV1 { + code?: number; + + data?: IWorkflowTemplateDetailResV1[]; + + message?: string; +} + export interface IGetWorkflowsResV1 { code?: number; @@ -4457,6 +4465,8 @@ export interface IWorkflowTemplateDetailResV1 { workflow_step_template_list?: IWorkFlowStepTemplateResV1[]; workflow_template_name?: string; + + workflow_type?: string; } export interface ICreatePipelineResData { diff --git a/packages/shared/lib/api/sqle/service/common.enum.ts b/packages/shared/lib/api/sqle/service/common.enum.ts index 0bdc064516..92982bee6a 100644 --- a/packages/shared/lib/api/sqle/service/common.enum.ts +++ b/packages/shared/lib/api/sqle/service/common.enum.ts @@ -829,7 +829,17 @@ export enum UpdateWorkflowTemplateReqV1AllowSubmitWhenLessAuditLevelEnum { export enum WorkFlowStepTemplateReqV1TypeEnum { 'sql_review' = 'sql_review', - 'sql_execute' = 'sql_execute' + 'sql_execute' = 'sql_execute', + + 'export_review' = 'export_review', + + 'export_execute' = 'export_execute' +} + +export enum WorkflowTemplateTypeEnum { + 'workflow' = 'workflow', + + 'data_export' = 'data_export' } export enum WorkflowDetailResV1CurrentStepTypeEnum { diff --git a/packages/shared/lib/api/sqle/service/workflow/index.d.ts b/packages/shared/lib/api/sqle/service/workflow/index.d.ts index c899fa201c..8883cbacab 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.d.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.d.ts @@ -3,6 +3,7 @@ import { IGetWorkflowsResV1, IGlobalWorkflowStatisticsResV1, IGetWorkflowTemplateResV1, + IGetWorkflowTemplateListResV1, IUpdateWorkflowTemplateReqV1, IBaseRes, ICreateWorkflowReqV1, @@ -129,14 +130,25 @@ export interface IGetGlobalWorkflowStatisticsReturn export interface IGetWorkflowTemplateV1Params { project_name: string; + + workflow_type?: string; } export interface IGetWorkflowTemplateV1Return extends IGetWorkflowTemplateResV1 {} +export interface IGetWorkflowTemplateListV1Params { + project_name: string; +} + +export interface IGetWorkflowTemplateListV1Return + extends IGetWorkflowTemplateListResV1 {} + export interface IUpdateWorkflowTemplateV1Params extends IUpdateWorkflowTemplateReqV1 { project_name: string; + + workflow_type?: string; } export interface IUpdateWorkflowTemplateV1Return extends IBaseRes {} diff --git a/packages/shared/lib/api/sqle/service/workflow/index.ts b/packages/shared/lib/api/sqle/service/workflow/index.ts index 13a5d63d3a..4d4a698fe1 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.ts @@ -18,6 +18,8 @@ import { IGetGlobalWorkflowStatisticsReturn, IGetWorkflowTemplateV1Params, IGetWorkflowTemplateV1Return, + IGetWorkflowTemplateListV1Params, + IGetWorkflowTemplateListV1Return, IUpdateWorkflowTemplateV1Params, IUpdateWorkflowTemplateV1Return, IGetWorkflowsV1Params, @@ -166,6 +168,21 @@ class WorkflowService extends ServiceBase { ); } + public getWorkflowTemplateListV1( + params: IGetWorkflowTemplateListV1Params, + options?: AxiosRequestConfig + ) { + const paramsData = this.cloneDeep(params); + const project_name = paramsData.project_name; + delete paramsData.project_name; + + return this.get( + `/v1/projects/${project_name}/workflow_templates`, + paramsData, + options + ); + } + public updateWorkflowTemplateV1( params: IUpdateWorkflowTemplateV1Params, options?: AxiosRequestConfig @@ -174,8 +191,15 @@ class WorkflowService extends ServiceBase { const project_name = paramsData.project_name; delete paramsData.project_name; + const workflow_type = paramsData.workflow_type; + delete paramsData.workflow_type; + + const queryString = workflow_type + ? `?workflow_type=${workflow_type}` + : ''; + return this.patch( - `/v1/projects/${project_name}/workflow_template`, + `/v1/projects/${project_name}/workflow_template${queryString}`, paramsData, options ); diff --git a/packages/sqle/src/locale/en-US/workflowTemplate.ts b/packages/sqle/src/locale/en-US/workflowTemplate.ts index eebcd5119d..59be44862f 100644 --- a/packages/sqle/src/locale/en-US/workflowTemplate.ts +++ b/packages/sqle/src/locale/en-US/workflowTemplate.ts @@ -10,7 +10,15 @@ export default { table: { workflowTemplateName: 'Approval workflow template name', - desc: 'Approval workflow template description' + desc: 'Approval workflow template description', + applicableType: 'Applicable Type', + approvalNodeDesc: 'Approval Node Description', + updateTime: 'Update Time' + }, + + type: { + workflow: 'SQL Exec Workflow', + dataExport: 'Data Export' }, operator: { @@ -33,7 +41,9 @@ export default { update: { title: { - wrapper: 'Update approval workflow template' + wrapper: 'Update approval workflow template', + workflow: 'Edit Approval Process - SQL Exec Workflow', + dataExport: 'Edit Approval Process - Data Export' }, result: { title: 'Update approval workflow template successfully', @@ -132,6 +142,15 @@ export default { matchExecute: 'Match members who have data source online permissions' } }, + exportReview: { + title: 'Export Review', + subTitle: + 'Reviewer checks the legitimacy of the export request' + }, + exportExecute: { + title: 'Export Execution Confirm', + subTitle: 'Confirm to execute the export operation' + }, operator: { remove: 'Remove this step', moveUp: 'Move this step up', diff --git a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts index 0e7ea1c556..0dd16070cd 100644 --- a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts +++ b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts @@ -10,7 +10,15 @@ export default { table: { workflowTemplateName: '审批流程模板名称', - desc: '审批流程模板描述' + desc: '审批流程模板描述', + applicableType: '适用类型', + approvalNodeDesc: '审批节点描述', + updateTime: '更新时间' + }, + + type: { + workflow: '上线工单', + dataExport: '数据导出' }, operator: { @@ -32,7 +40,9 @@ export default { update: { title: { - wrapper: '更新审批流程模板' + wrapper: '更新审批流程模板', + workflow: '编辑审批流程 - 上线工单', + dataExport: '编辑审批流程 - 数据导出' }, result: { title: '更新审批流程模板成功', @@ -124,6 +134,14 @@ export default { matchExecute: '匹配拥有数据源上线权限的成员' } }, + exportReview: { + title: '导出审批', + subTitle: '审批人在该步骤审核导出请求的合理性' + }, + exportExecute: { + title: '导出执行确认', + subTitle: '确认执行导出操作' + }, operator: { remove: '移除该步骤', moveUp: '上移该步骤', From 4aa4d845281f4cca9e514300e7ae5c7416a3724b Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Tue, 21 Apr 2026 05:47:35 +0000 Subject: [PATCH 02/16] feat(workflow-template): refactor approval process page from detail view to list view - DEV-024: Replace WorkflowTemplateStepInfo/AuthInfo with ActiontechTable - Add column.tsx with workflow_type tag, approval node description, update time columns - Refactor actions.tsx to use table row edit button with permission control - Edit button navigates with workflowType query parameter - Add getWorkflowTemplateList mock API and update test files - Remove old snapshots for updated page structure refs actiontech/dms-ee#784 (cherry picked from commit d6789673acb3de193e7cfa9119b8ac4f4b905d9e) --- .../mockApi/sqle/workflowTemplate/data.ts | 25 +- .../mockApi/sqle/workflowTemplate/index.ts | 16 +- .../__snapshots__/index.ce.test.tsx.snap | 544 ------ .../__snapshots__/index.test.tsx.snap | 1478 ----------------- .../WorkflowTemplateDetail/actions.tsx | 47 +- .../WorkflowTemplateDetail/column.tsx | 66 + .../WorkflowTemplateDetail/index.ce.test.tsx | 12 +- .../WorkflowTemplateDetail/index.test.tsx | 118 +- .../WorkflowTemplateDetail/index.tsx | 147 +- .../WorkflowTemplateDetail/style.ts | 10 - 10 files changed, 213 insertions(+), 2250 deletions(-) delete mode 100644 packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap delete mode 100644 packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap create mode 100644 packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx diff --git a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts index d7337181fc..3098e799a2 100644 --- a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts +++ b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts @@ -29,5 +29,28 @@ export const workflowTemplateData = { type: 'sql_execute' } ], - workflow_template_name: '700300-WorkflowTemplate' + workflow_template_name: '700300-WorkflowTemplate', + workflow_type: 'workflow' }; + +export const dataExportWorkflowTemplateData = { + allow_submit_when_less_audit_level: '', + desc: '', + update_time: '2024-01-15T10:30:00+08:00', + workflow_step_template_list: [ + { + approved_by_authorized: true, + assignee_user_id_list: [], + execute_by_authorized: false, + number: 1, + type: 'export_review' + } + ], + workflow_template_name: '700300-DataExportWorkflowTemplate', + workflow_type: 'data_export' +}; + +export const workflowTemplateListData = [ + workflowTemplateData, + dataExportWorkflowTemplateData +]; diff --git a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts index 9663d8174f..87a85ff092 100644 --- a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts +++ b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts @@ -1,12 +1,16 @@ import workflow from '../../../../api/sqle/service/workflow'; import { MockSpyApy, createSpySuccessResponse } from '../../common'; -import { workflowTemplateData } from './data'; +import { + workflowTemplateData, + workflowTemplateListData +} from './data'; import { cloneDeep } from 'lodash'; class MockWorkflowTemplateApi implements MockSpyApy { public mockAllApi(): void { this.updateWorkflowTemplate(); this.getWorkflowTemplate(); + this.getWorkflowTemplateList(); this.cancelWorkflow(); } @@ -26,6 +30,16 @@ class MockWorkflowTemplateApi implements MockSpyApy { return spy; } + public getWorkflowTemplateList() { + const spy = jest.spyOn(workflow, 'getWorkflowTemplateListV1'); + spy.mockImplementation(() => { + return createSpySuccessResponse({ + data: cloneDeep(workflowTemplateListData) + }); + }); + return spy; + } + public cancelWorkflow() { const spy = jest.spyOn(workflow, 'cancelWorkflowV2'); spy.mockImplementation(() => { diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap deleted file mode 100644 index fe53f498d2..0000000000 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap +++ /dev/null @@ -1,544 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`page/WorkflowTemplate CE render workflow template detail 1`] = ` - -
-
-
-
- 审批流程模板 -
-
-
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
- - 工单发起/工单更新SQL语句 - -
- 工单被创建,或者工单被驳回后等待修改SQL语句 -
-
-
-
-
-
-
- - - - - - -
-
-
- - - - - -
-
-
-
-
- - 审核节点 - - #1 - - -
- - -
-
-
- 审核人 -
-
- - - - - 匹配拥有数据源审核权限的成员 - -
-
-
-
-
-
-
-
- - - -
-
-
- - - - - -
-
-
-
-
- - 审核节点 - - #2 - - -
- step desc -
-
-
- 审核人 -
-
-
-
- - - T - - -
-
-
-
-
-
-
-
-
-
- - - - - - -
-
-
- - - - - -
-
-
-
-
- - 执行上线 - -
- - -
-
-
- 执行人 -
-
- - - - - 匹配拥有数据源上线权限的成员 - -
-
-
-
-
-
-
-
-
-
-
-
- - 允许创建工单的最高审核等级 - - - 告警(Warning) - -
-
-
-
-
-
-
-
-
-
- - 注意事项 - -
-
    -
  • - 若项目管理员对审批流程模板进行了修改,不会对已经在审批流程的工单造成影响; -
  • -
  • - 被驳回的工单,需要创建人更新SQL语句后重新发起,驳回记录可在 “工单进度-工单历史操作” 中查看; -
  • -
  • - 处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭; -
  • -
  • - 审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作; -
  • -
  • - 上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。 -
  • -
-
-
-
- - 审批流程模板更新时间 - -
- - - - - 2023-12-26 14:19:12 - -
-
-
-
-
-
-
-
-
- -`; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap deleted file mode 100644 index ac86d7daac..0000000000 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,1478 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`page/WorkflowTemplate/WorkflowTemplateDetail render workflow template detail 1`] = ` - -
-
- -
-
-
-
-
-
-
- - - - - -
-
-
-
-
- - 工单发起/工单更新SQL语句 - -
- 工单被创建,或者工单被驳回后等待修改SQL语句 -
-
-
-
-
-
-
- - - - - - -
-
-
- - - - - -
-
-
-
-
- - 审核节点 - - #1 - - -
- - -
-
-
- 审核人 -
-
- - - - - 匹配拥有数据源审核权限的成员 - -
-
-
-
-
-
-
-
- - - -
-
-
- - - - - -
-
-
-
-
- - 审核节点 - - #2 - - -
- step desc -
-
-
- 审核人 -
-
-
-
- - - T - - -
-
-
-
-
-
-
-
-
-
- - - - - - -
-
-
- - - - - -
-
-
-
-
- - 执行上线 - -
- - -
-
-
- 执行人 -
-
- - - - - 匹配拥有数据源上线权限的成员 - -
-
-
-
-
-
-
-
-
-
-
-
- - 允许创建工单的最高审核等级 - - - 告警(Warning) - -
-
-
-
-
-
-
-
-
-
- - 注意事项 - -
-
    -
  • - 若项目管理员对审批流程模板进行了修改,不会对已经在审批流程的工单造成影响; -
  • -
  • - 被驳回的工单,需要创建人更新SQL语句后重新发起,驳回记录可在 “工单进度-工单历史操作” 中查看; -
  • -
  • - 处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭; -
  • -
  • - 审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作; -
  • -
  • - 上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。 -
  • -
-
-
-
- - 审批流程模板更新时间 - -
- - - - - 2023-12-26 14:19:12 - -
-
-
-
-
-
-
-
-
- -`; - -exports[`page/WorkflowTemplate/WorkflowTemplateDetail render workflow template detail with no review step 1`] = ` - -
-
- -
-
-
-
-
-
-
- - - - - -
-
-
-
-
- - 工单发起/工单更新SQL语句 - -
- 工单被创建,或者工单被驳回后等待修改SQL语句 -
-
-
-
-
-
-
- - - - - - -
-
-
- - - - - -
-
-
-
-
- - 执行上线 - -
- - -
-
-
- 执行人 -
-
- - - - - 匹配拥有数据源上线权限的成员 - -
-
-
-
-
-
-
-
-
-
-
-
- - 允许创建工单的最高审核等级 - - - 告警(Warning) - -
-
-
-
-
-
-
-
-
-
- - 注意事项 - -
-
    -
  • - 若项目管理员对审批流程模板进行了修改,不会对已经在审批流程的工单造成影响; -
  • -
  • - 被驳回的工单,需要创建人更新SQL语句后重新发起,驳回记录可在 “工单进度-工单历史操作” 中查看; -
  • -
  • - 处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭; -
  • -
  • - 审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作; -
  • -
  • - 上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。 -
  • -
-
-
-
- - 审批流程模板更新时间 - -
- - - - - 2023-12-26 14:19:12 - -
-
-
-
-
-
-
-
-
- -`; - -exports[`page/WorkflowTemplate/WorkflowTemplateDetail render workflow template detail without permission 1`] = ` - -
-
-
-
- 审批流程模板 -
-
-
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
- - 工单发起/工单更新SQL语句 - -
- 工单被创建,或者工单被驳回后等待修改SQL语句 -
-
-
-
-
-
-
- - - - - - -
-
-
- - - - - -
-
-
-
-
- - 审核节点 - - #1 - - -
- - -
-
-
- 审核人 -
-
- - - - - 匹配拥有数据源审核权限的成员 - -
-
-
-
-
-
-
-
- - - -
-
-
- - - - - -
-
-
-
-
- - 审核节点 - - #2 - - -
- step desc -
-
-
- 审核人 -
-
-
-
- - - T - - -
-
-
-
-
-
-
-
-
-
- - - - - - -
-
-
- - - - - -
-
-
-
-
- - 执行上线 - -
- - -
-
-
- 执行人 -
-
- - - - - 匹配拥有数据源上线权限的成员 - -
-
-
-
-
-
-
-
-
-
-
-
- - 允许创建工单的最高审核等级 - - - 告警(Warning) - -
-
-
-
-
-
-
-
-
-
- - 注意事项 - -
-
    -
  • - 若项目管理员对审批流程模板进行了修改,不会对已经在审批流程的工单造成影响; -
  • -
  • - 被驳回的工单,需要创建人更新SQL语句后重新发起,驳回记录可在 “工单进度-工单历史操作” 中查看; -
  • -
  • - 处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭; -
  • -
  • - 审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作; -
  • -
  • - 上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。 -
  • -
-
-
-
- - 审批流程模板更新时间 - -
- - - - - 2023-12-26 14:19:12 - -
-
-
-
-
-
-
-
-
- -`; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx index 326a4d82c8..ef92f7b9ab 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx @@ -1,32 +1,23 @@ import { t } from '../../../locale'; import { - PERMISSIONS, - PermissionControl + ActiontechTableActionsWithPermissions, + PERMISSIONS } from '@actiontech/shared/lib/features'; -import { ActionButton } from '@actiontech/shared'; -import { EditOutlined } from '@ant-design/icons'; -import { ROUTE_PATHS } from '@actiontech/dms-kit'; -export const WorkflowTemplatePageHeaderActions = ( - projectID: string, - templateName?: string -): Record<'update-workflow-template', React.ReactNode> => ({ - 'update-workflow-template': ( - - } - text={t('workflowTemplate.detail.updateTemplate')} - actionType="navigate-link" - link={{ - to: ROUTE_PATHS.SQLE.PROGRESS.update, - params: { - projectID, - workflowName: templateName ?? '' - } - }} - /> - - ) +import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; + +export const WorkflowTemplateTableActions: ( + onEdit: (record: IWorkflowTemplateDetailResV1) => void +) => ActiontechTableActionsWithPermissions = ( + onEdit +) => ({ + buttons: [ + { + key: 'edit-workflow-template', + text: t('common.edit'), + buttonProps: (record) => ({ + onClick: () => onEdit(record ?? {}) + }), + permissions: PERMISSIONS.ACTIONS.SQLE.WORKFLOW_TEMPLATE.UPDATE + } + ] }); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx new file mode 100644 index 0000000000..4cfbfa1b88 --- /dev/null +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx @@ -0,0 +1,66 @@ +import { ActiontechTableColumn } from '@actiontech/dms-kit/es/components/ActiontechTable'; +import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; +import { WorkflowTemplateTypeEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; +import { BasicTag } from '@actiontech/dms-kit'; +import { formatTime } from '@actiontech/dms-kit'; +import { t } from '../../../locale'; + +const stepTypeNameMap: Record = { + sql_review: 'workflowTemplate.progressConfig.review.title', + sql_execute: 'workflowTemplate.progressConfig.exec.title', + export_review: 'workflowTemplate.progressConfig.exportReview.title', + export_execute: 'workflowTemplate.progressConfig.exportExecute.title' +}; + +const getStepTypeName = (stepType?: string): string => { + if (!stepType) return '-'; + const i18nKey = stepTypeNameMap[stepType]; + return i18nKey ? t(i18nKey) : stepType; +}; + +export const WorkflowTemplateListColumn = + (): ActiontechTableColumn => { + return [ + { + dataIndex: 'workflow_template_name', + title: () => t('workflowTemplate.list.table.workflowTemplateName') + }, + { + dataIndex: 'workflow_type', + title: () => t('workflowTemplate.list.table.applicableType'), + render: (workflowType) => { + if (workflowType === WorkflowTemplateTypeEnum.data_export) { + return ( + + {t('workflowTemplate.list.type.dataExport')} + + ); + } + return ( + + {t('workflowTemplate.list.type.workflow')} + + ); + } + }, + { + dataIndex: 'workflow_step_template_list', + title: () => t('workflowTemplate.list.table.approvalNodeDesc'), + render: (stepList) => { + if (!stepList || stepList.length === 0) return '-'; + return stepList + .map( + (step: { type?: string }) => getStepTypeName(step.type) + ) + .join(' -> '); + } + }, + { + dataIndex: 'update_time', + title: () => t('workflowTemplate.list.table.updateTime'), + render: (value) => { + return formatTime(value, '-'); + } + } + ]; + }; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx index 2557caa0f6..8672ba519b 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx @@ -8,12 +8,10 @@ import { act, cleanup, screen } from '@testing-library/react'; import workflowTemplate from '@actiontech/shared/lib/testUtil/mockApi/sqle/workflowTemplate'; import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentUser'; -import user from '@actiontech/shared/lib/testUtil/mockApi/sqle/user'; describe('page/WorkflowTemplate CE', () => { beforeEach(() => { workflowTemplate.mockAllApi(); - user.mockAllApi(); mockUseCurrentProject(); mockUseCurrentUser(); jest.useFakeTimers(); @@ -28,14 +26,12 @@ describe('page/WorkflowTemplate CE', () => { return sqleSuperRender(); }; - it('render workflow template detail', async () => { - const getInfoRequest = workflowTemplate.getWorkflowTemplate(); - const userInfoRequest = user.getUserTipList(); + it('render workflow template list without edit actions in CE', async () => { + const getListRequest = workflowTemplate.getWorkflowTemplateList(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); - expect(getInfoRequest).toHaveBeenCalled(); - expect(userInfoRequest).toHaveBeenCalled(); + expect(getListRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); - expect(screen.queryByText('修改当前审批流程模板')).not.toBeInTheDocument(); + expect(screen.getByText('审批流程模板')).toBeInTheDocument(); }); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx index 8c48e3e424..a3af58e417 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx @@ -1,19 +1,10 @@ import { sqleSuperRender } from '../../../testUtils/superRender'; import WorkflowTemplateDetail from '.'; -import { workflowTemplateData } from '@actiontech/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data'; import { act, cleanup, screen } from '@testing-library/react'; import workflowTemplate from '@actiontech/shared/lib/testUtil/mockApi/sqle/workflowTemplate'; import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentUser'; -import { getBySelector } from '@actiontech/shared/lib/testUtil/customQuery'; -import { - mockProjectInfo, - mockCurrentUserReturn -} from '@actiontech/shared/lib/testUtil/mockHook/data'; -import { createSpySuccessResponse } from '@actiontech/shared/lib/testUtil/mockApi'; -import user from '@actiontech/shared/lib/testUtil/mockApi/sqle/user'; import { mockUsePermission } from '@actiontech/shared/lib/testUtil/mockHook/mockUsePermission'; -import { SystemRole } from '@actiontech/dms-kit'; jest.mock('react-redux', () => { return { @@ -25,7 +16,6 @@ jest.mock('react-redux', () => { describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { beforeEach(() => { workflowTemplate.mockAllApi(); - user.mockAllApi(); mockUseCurrentProject(); mockUseCurrentUser(); jest.useFakeTimers(); @@ -43,108 +33,30 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { return sqleSuperRender(); }; - it('render workflow template detail', async () => { - const getInfoRequest = workflowTemplate.getWorkflowTemplate(); - const userInfoRequest = user.getUserTipList(); + it('render workflow template list', async () => { + const getListRequest = workflowTemplate.getWorkflowTemplateList(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); - expect(getInfoRequest).toHaveBeenCalled(); - expect(userInfoRequest).toHaveBeenCalled(); + expect(getListRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); expect(screen.getByText('审批流程模板')).toBeInTheDocument(); - expect(getBySelector('a')).toBeInTheDocument(); - expect(getBySelector('a')).toHaveAttribute( - 'href', - `/sqle/project/${mockProjectInfo.projectID}/progress/update/${workflowTemplateData.workflow_template_name}` - ); - - expect(screen.getByText('工单发起/工单更新SQL语句')).toBeInTheDocument(); - expect(screen.getAllByText('审核节点')?.[0]).toBeInTheDocument(); - expect(screen.getByText('执行上线')).toBeInTheDocument(); - - expect(screen.getByText('告警(Warning)')).toBeInTheDocument(); - expect(screen.getByText('2023-12-26 14:19:12')).toBeInTheDocument(); }); - it('render workflow template detail without permission', async () => { - // not admin or global manager or project manager - mockUseCurrentUser({ - ...mockCurrentUserReturn, - userRoles: { - ...mockCurrentUserReturn.userRoles, - [SystemRole.admin]: false, - [SystemRole.systemAdministrator]: false - } - }); - const getInfoRequest = workflowTemplate.getWorkflowTemplate(); - const userInfoRequest = user.getUserTipList(); - const { baseElement } = customRender(); - await act(async () => jest.advanceTimersByTime(3000)); - expect(getInfoRequest).toHaveBeenCalled(); - expect(userInfoRequest).toHaveBeenCalled(); - expect(baseElement).toMatchSnapshot(); - expect(screen.queryByText('修改当前审批流程模板')).not.toBeInTheDocument(); - - // project manager - cleanup(); - mockUseCurrentUser({ - ...mockCurrentUserReturn, - userRoles: { - ...mockCurrentUserReturn.userRoles, - [SystemRole.admin]: false, - [SystemRole.systemAdministrator]: false - }, - bindProjects: [ - { - is_manager: true, - project_name: mockProjectInfo.projectName, - project_id: mockProjectInfo.projectID, - archived: false - } - ] - }); + it('render workflow type tags correctly', async () => { + workflowTemplate.getWorkflowTemplateList(); customRender(); - expect(screen.getByText('修改当前审批流程模板')).toBeInTheDocument(); - - // project is archived - cleanup(); - mockUseCurrentUser({ - ...mockCurrentUserReturn, - userRoles: { - ...mockCurrentUserReturn.userRoles, - [SystemRole.admin]: false, - [SystemRole.systemAdministrator]: false - }, - bindProjects: [ - { - is_manager: true, - project_name: mockProjectInfo.projectName, - project_id: mockProjectInfo.projectID, - archived: true - } - ] - }); - customRender(); - expect(screen.queryByText('修改当前审批流程模板')).not.toBeInTheDocument(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(screen.getByText('上线工单')).toBeInTheDocument(); + expect(screen.getByText('数据导出')).toBeInTheDocument(); }); - it('render workflow template detail with no review step', async () => { - const getInfoRequest = workflowTemplate.getWorkflowTemplate(); - getInfoRequest.mockImplementation(() => { - const execStepData = - workflowTemplateData.workflow_step_template_list.pop(); - return createSpySuccessResponse({ - data: { - ...workflowTemplateData, - workflow_step_template_list: [execStepData] - } - }); - }); - const { baseElement } = customRender(); + it('render approval node description', async () => { + workflowTemplate.getWorkflowTemplateList(); + customRender(); await act(async () => jest.advanceTimersByTime(3000)); - expect(getInfoRequest).toHaveBeenCalled(); - expect(baseElement).toMatchSnapshot(); - expect(screen.getByText('审批流程模板')).toBeInTheDocument(); - expect(screen.getByText('执行上线')).toBeInTheDocument(); + expect( + screen.getByText('审核节点 -> 审核节点 -> 执行上线') + ).toBeInTheDocument(); + expect(screen.getByText('导出审批')).toBeInTheDocument(); }); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx index a7189e0f61..d0386ede54 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx @@ -1,88 +1,81 @@ -import { Col, Row, Spin } from 'antd'; -import React, { useState } from 'react'; -import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; +import { useMemo, useCallback } from 'react'; import { useRequest } from 'ahooks'; -import { useCurrentProject } from '@actiontech/shared/lib/features'; -import WorkflowTemplateAuthInfo from './components/WorkflowTemplateAuthInfo'; -import WorkflowTemplateStepInfo from './components/WorkflowTemplateStepInfo'; -import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; -import { PageHeader } from '@actiontech/dms-kit'; import { useTranslation } from 'react-i18next'; -import { WorkflowTemplateStyleWrapper } from './style'; -import useUsername from '../../../hooks/useUsername'; -import { WorkflowTemplatePageHeaderActions } from './actions'; +import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; +import { + useCurrentProject, + usePermission +} from '@actiontech/shared/lib/features'; +import { useTypedNavigate } from '@actiontech/shared'; +import { ROUTE_PATHS } from '@actiontech/dms-kit'; +import { PageHeader } from '@actiontech/dms-kit'; +import { + ActiontechTable, + ActiontechTableWrapper +} from '@actiontech/dms-kit/es/components/ActiontechTable'; +import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; +import { WorkflowTemplateListColumn } from './column'; +import { WorkflowTemplateTableActions } from './actions'; + const WorkflowTemplateDetail: React.FC = () => { const { t } = useTranslation(); const { projectName, projectID } = useCurrentProject(); - const { - updateUsernameList, - usernameList, - loading: getUsernameListLoading - } = useUsername(); - React.useEffect(() => { - updateUsernameList({ - filter_project: projectName - }); - }, [projectName, updateUsernameList]); - const [reviewSteps, setReviewSteps] = useState( - [] + const { parse2TableActionPermissions } = usePermission(); + const navigate = useTypedNavigate(); + + const columns = useMemo(() => WorkflowTemplateListColumn(), []); + + const { data: templateList, loading } = useRequest( + () => + workflow + .getWorkflowTemplateListV1({ + project_name: projectName + }) + .then((res) => res.data.data ?? []), + { + ready: !!projectName + } ); - const [execSteps, setExecSteps] = useState({ - assignee_user_id_list: [], - desc: '' - }); - const { data: workflowTemplate, loading: getWorkflowTemplateLoading } = - useRequest( - () => - workflow - .getWorkflowTemplateV1({ - project_name: projectName - }) - .then((res) => { - const stepList = res.data.data?.workflow_step_template_list ?? []; - if (stepList.length <= 1) { - setExecSteps(stepList[0]); - } else { - const execStep = stepList.pop(); - setReviewSteps(stepList); - if (execStep) setExecSteps(execStep); - } - return res.data.data; - }), - { - ready: !!projectName - } - ); - const pageHeaderActions = WorkflowTemplatePageHeaderActions( - projectID, - workflowTemplate?.workflow_template_name + + const onEditTemplate = useCallback( + (record: IWorkflowTemplateDetailResV1) => { + navigate(ROUTE_PATHS.SQLE.PROGRESS.update, { + params: { + projectID, + workflowName: record.workflow_template_name ?? '' + }, + queries: { + workflowType: record.workflow_type ?? '' + } + }); + }, + [navigate, projectID] ); + + const actions = useMemo(() => { + return parse2TableActionPermissions( + WorkflowTemplateTableActions(onEditTemplate) + ); + }, [parse2TableActionPermissions, onEditTemplate]); + return ( - - - - - - - - - - - - - + <> + + + + record?.workflow_template_name ?? '' + } + loading={loading} + columns={columns} + // #if [ee] + actions={actions} + // #endif + /> + + ); }; + export default WorkflowTemplateDetail; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts index 392f85f8bd..d63644aa9c 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts @@ -2,14 +2,4 @@ import { styled } from '@mui/material/styles'; export const WorkflowTemplateStyleWrapper = styled('div')` height: 100%; - - .workflow-template-wrapper { - height: 100%; - } - - .workflow-template-right-module { - border-left: ${({ theme }) => - theme.sqleTheme.workflowTemplate.workflowTemplateAuthInfo.borderBottom}; - height: auto; - } `; From 4a39b3b95546a3390a2a301941dfd48a464ebbba Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Tue, 21 Apr 2026 08:37:44 +0000 Subject: [PATCH 03/16] feat(workflow-template): differentiate edit page by workflow type - DEV-025: Read workflowType from URL query params, switch step type enums (export_review/export_execute vs sql_review/sql_execute) and page title based on workflow type, pass workflow_type to API calls - DEV-026: Hide AllowSubmitWhenLessAuditLevel field in BasicInfo component when editing data_export type template - Add query field to PROGRESS.update route definition for workflowType - Fix TS error in column.tsx stepTypeNameMap by using I18nKey type - Prettier formatting fixes refs actiontech/dms-ee#784 (cherry picked from commit 966319e09eb8dd6f0389c32118d9f9dbe28654c2) --- packages/dms-kit/src/data/routePaths.ts | 3 +- .../lib/api/sqle/service/workflow/index.ts | 4 +- .../mockApi/sqle/workflowTemplate/index.ts | 5 +- .../sqle/src/locale/en-US/workflowTemplate.ts | 3 +- .../components/BasicInfo/index.tsx | 50 ++++++++++--------- .../components/BasicInfo/index.type.ts | 1 + .../UpdateWorkflowTemplate/index.tsx | 38 +++++++++++--- .../WorkflowTemplateDetail/column.tsx | 8 ++- 8 files changed, 67 insertions(+), 45 deletions(-) diff --git a/packages/dms-kit/src/data/routePaths.ts b/packages/dms-kit/src/data/routePaths.ts index c5d8b7c504..4edda84e33 100644 --- a/packages/dms-kit/src/data/routePaths.ts +++ b/packages/dms-kit/src/data/routePaths.ts @@ -325,7 +325,8 @@ export const ROUTE_PATHS = { }, update: { prefix: '/sqle/project/:projectID/progress', - path: 'update/:workflowName' + path: 'update/:workflowName', + query: 'workflowType' } }, WHITELIST: { diff --git a/packages/shared/lib/api/sqle/service/workflow/index.ts b/packages/shared/lib/api/sqle/service/workflow/index.ts index 4d4a698fe1..2eed9af557 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.ts @@ -194,9 +194,7 @@ class WorkflowService extends ServiceBase { const workflow_type = paramsData.workflow_type; delete paramsData.workflow_type; - const queryString = workflow_type - ? `?workflow_type=${workflow_type}` - : ''; + const queryString = workflow_type ? `?workflow_type=${workflow_type}` : ''; return this.patch( `/v1/projects/${project_name}/workflow_template${queryString}`, diff --git a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts index 87a85ff092..819cf80a27 100644 --- a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts +++ b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts @@ -1,9 +1,6 @@ import workflow from '../../../../api/sqle/service/workflow'; import { MockSpyApy, createSpySuccessResponse } from '../../common'; -import { - workflowTemplateData, - workflowTemplateListData -} from './data'; +import { workflowTemplateData, workflowTemplateListData } from './data'; import { cloneDeep } from 'lodash'; class MockWorkflowTemplateApi implements MockSpyApy { diff --git a/packages/sqle/src/locale/en-US/workflowTemplate.ts b/packages/sqle/src/locale/en-US/workflowTemplate.ts index 59be44862f..c68a9b89ae 100644 --- a/packages/sqle/src/locale/en-US/workflowTemplate.ts +++ b/packages/sqle/src/locale/en-US/workflowTemplate.ts @@ -144,8 +144,7 @@ export default { }, exportReview: { title: 'Export Review', - subTitle: - 'Reviewer checks the legitimacy of the export request' + subTitle: 'Reviewer checks the legitimacy of the export request' }, exportExecute: { title: 'Export Execution Confirm', diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx index 3216bb5c4e..df97d96e7f 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx @@ -9,14 +9,16 @@ import StepButton from '../StepButton'; import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; const BasicInfo: React.FC = (props) => { const { t } = useTranslation(); - const { form } = props; + const { form, workflowType } = props; const { getAuditLevelStatusSelectOption } = useStaticStatus(); + const isDataExport = workflowType === 'data_export'; const nextStep = async () => { const value = await form.validateFields(); props.updateBaseInfo(value?.allowSubmitWhenLessAuditLevel); props.nextStep(); }; useEffect(() => { + if (isDataExport) return; if (!!props.defaultData) { form.setFieldsValue({ allowSubmitWhenLessAuditLevel: props.defaultData @@ -30,7 +32,7 @@ const BasicInfo: React.FC = (props) => { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum.warn }); } - }, [form, props.defaultData]); + }, [form, props.defaultData, isDataExport]); const handleChangeLevel = ( level: WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum ) => { @@ -49,28 +51,30 @@ const BasicInfo: React.FC = (props) => {
- - - {getAuditLevelStatusSelectOption()} - - + + {getAuditLevelStatusSelectOption()} + + + )} void; totalStep: number; + workflowType?: string; }; export type BaseFormFields = { diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx index 0154e97fd0..98e3c99726 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx @@ -1,5 +1,9 @@ import { BasicButton, BasicResult, PageHeader } from '@actiontech/dms-kit'; -import { ActionButton, useTypedParams } from '@actiontech/shared'; +import { + ActionButton, + useTypedParams, + useTypedQuery +} from '@actiontech/shared'; import { ArrowLeftOutlined } from '@ant-design/icons'; import { Col, Row, Space, Spin } from 'antd'; import React, { useState } from 'react'; @@ -41,6 +45,23 @@ const UpdateWorkflowTemplate: React.FC = () => { const [updateSuccess, setUpdateSuccess] = useState(false); const urlParams = useTypedParams(); const { projectName, projectID } = useCurrentProject(); + const extractQueries = useTypedQuery(); + const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.update); + const workflowType = searchParams?.workflowType || 'workflow'; + + const pageTitle = + workflowType === 'data_export' + ? t('workflowTemplate.update.title.dataExport') + : t('workflowTemplate.update.title.workflow'); + + const reviewType = + workflowType === 'data_export' + ? WorkFlowStepTemplateReqV1TypeEnum.export_review + : WorkFlowStepTemplateReqV1TypeEnum.sql_review; + const executeType = + workflowType === 'data_export' + ? WorkFlowStepTemplateReqV1TypeEnum.export_execute + : WorkFlowStepTemplateReqV1TypeEnum.sql_execute; const { loading: getUsernameListLoading, updateUsernameList, @@ -63,19 +84,20 @@ const UpdateWorkflowTemplate: React.FC = () => { await form?.validateFields(); const reviewTempData = reviewSteps.map((item) => ({ ...item, - type: WorkFlowStepTemplateReqV1TypeEnum.sql_review + type: reviewType })); const templateList: IWorkFlowStepTemplateReqV1[] = [ ...reviewTempData, { ...execSteps, - type: WorkFlowStepTemplateReqV1TypeEnum.sql_execute + type: executeType } ]; startSubmit(); return workflow .updateWorkflowTemplateV1({ project_name: projectName, + workflow_type: workflowType, workflow_step_template_list: templateList, allow_submit_when_less_audit_level: selectLevel as | UpdateWorkflowTemplateReqV1AllowSubmitWhenLessAuditLevelEnum @@ -92,7 +114,8 @@ const UpdateWorkflowTemplate: React.FC = () => { () => workflow .getWorkflowTemplateV1({ - project_name: projectName + project_name: projectName, + workflow_type: workflowType }) .then((res) => { const temp = res.data.data; @@ -150,6 +173,7 @@ const UpdateWorkflowTemplate: React.FC = () => { nextStep={nextStep} updateBaseInfo={updateBaseInfo} totalStep={reviewSteps.length + 2} + workflowType={workflowType} /> ); } @@ -184,7 +208,7 @@ const UpdateWorkflowTemplate: React.FC = () => { assignee_user_id_list: [], desc: '', approved_by_authorized: true, - type: WorkFlowStepTemplateReqV1TypeEnum.sql_review + type: reviewType } ]); setCurrentStep(reviewSteps.length + 1); @@ -204,7 +228,7 @@ const UpdateWorkflowTemplate: React.FC = () => { assignee_user_id_list: [], desc: '', execute_by_authorized: true, - type: WorkFlowStepTemplateReqV1TypeEnum.sql_execute + type: executeType }); }; const handleExchangeReviewNode = (from: number, to: number) => { @@ -232,7 +256,7 @@ const UpdateWorkflowTemplate: React.FC = () => { } - text={t('workflowTemplate.create.title.returnButton')} + text={pageTitle} actionType="navigate-link" link={{ to: ROUTE_PATHS.SQLE.PROGRESS.index, diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx index 4cfbfa1b88..633ae6ef0e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx @@ -3,9 +3,9 @@ import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/se import { WorkflowTemplateTypeEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; import { BasicTag } from '@actiontech/dms-kit'; import { formatTime } from '@actiontech/dms-kit'; -import { t } from '../../../locale'; +import { t, I18nKey } from '../../../locale'; -const stepTypeNameMap: Record = { +const stepTypeNameMap: Record = { sql_review: 'workflowTemplate.progressConfig.review.title', sql_execute: 'workflowTemplate.progressConfig.exec.title', export_review: 'workflowTemplate.progressConfig.exportReview.title', @@ -49,9 +49,7 @@ export const WorkflowTemplateListColumn = render: (stepList) => { if (!stepList || stepList.length === 0) return '-'; return stepList - .map( - (step: { type?: string }) => getStepTypeName(step.type) - ) + .map((step: { type?: string }) => getStepTypeName(step.type)) .join(' -> '); } }, From 29b817f5a1636f60ab806f6388e47e0873cf0316 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Tue, 21 Apr 2026 08:52:00 +0000 Subject: [PATCH 04/16] feat(data-export): add approval process preview component to data export creation page - DEV-027: New ApprovalProcessPreview component with read-only workflow step display - Calls getWorkflowTemplateV1 with workflow_type=data_export to fetch template - Renders step list with step number, step type name, and assignee info - Shows "match by permission" when approved_by_authorized/execute_by_authorized is true - Loading state with Spin, error state with Result fallback - Bottom hint guiding users to modify approval process in Project Configure - DEV-028: Integrate preview between BasicInfoWrapper and AuditResultList in SubmitWorkflow - Add step type name i18n keys (export_review/export_execute) to base package dmsDataExport refs actiontech/dms-ee#784 (cherry picked from commit 58397af27ee9914de241e531e8c146e3d613bdcc) --- .../base/src/locale/en-US/dmsDataExport.ts | 6 +- .../base/src/locale/zh-CN/dmsDataExport.ts | 6 +- .../ApprovalProcessPreview/index.tsx | 105 ++++++++++++++++++ .../ApprovalProcessPreview/style.ts | 46 ++++++++ .../components/SubmitWorkflow/index.tsx | 5 +- 5 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx create mode 100644 packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts diff --git a/packages/base/src/locale/en-US/dmsDataExport.ts b/packages/base/src/locale/en-US/dmsDataExport.ts index 6d25445c00..fba5efe8a6 100644 --- a/packages/base/src/locale/en-US/dmsDataExport.ts +++ b/packages/base/src/locale/en-US/dmsDataExport.ts @@ -62,7 +62,11 @@ export default { hint: 'Approval process can be modified in Project Configure > Approval Process', stepLabel: 'Step {{number}}', matchByPermission: 'Match by Permission', - loadFailed: 'Failed to load approval process' + loadFailed: 'Failed to load approval process', + stepType: { + export_review: 'Export Review', + export_execute: 'Export Execution Confirm' + } } }, batchClose: { diff --git a/packages/base/src/locale/zh-CN/dmsDataExport.ts b/packages/base/src/locale/zh-CN/dmsDataExport.ts index 80b18dd8d0..ed1601ef33 100644 --- a/packages/base/src/locale/zh-CN/dmsDataExport.ts +++ b/packages/base/src/locale/zh-CN/dmsDataExport.ts @@ -57,7 +57,11 @@ export default { hint: '审批流程可在 Project Configure > Approval Process 中修改', stepLabel: '步骤 {{number}}', matchByPermission: '按权限匹配', - loadFailed: '加载审批流程失败' + loadFailed: '加载审批流程失败', + stepType: { + export_review: '导出审批', + export_execute: '导出执行确认' + } }, update: { baseTitle: '工单基本信息', diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx new file mode 100644 index 0000000000..2b0b7f4658 --- /dev/null +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx @@ -0,0 +1,105 @@ +import { useTranslation } from 'react-i18next'; +import { useRequest } from 'ahooks'; +import { Spin, Space, Typography } from 'antd'; +import { Result } from 'antd'; +import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; +import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; +import { ApprovalProcessPreviewStyleWrapper } from './style'; + +interface ApprovalProcessPreviewProps { + projectName: string; +} + +const stepTypeNameMap: Record = { + export_review: 'dmsDataExport.create.approvalProcess.stepType.export_review', + export_execute: 'dmsDataExport.create.approvalProcess.stepType.export_execute' +}; + +const ApprovalProcessPreview: React.FC = ({ + projectName +}) => { + const { t } = useTranslation(); + + const { + data: templateData, + loading, + error + } = useRequest( + () => + workflow + .getWorkflowTemplateV1({ + project_name: projectName, + workflow_type: 'data_export' + }) + .then((res) => res.data.data), + { + ready: !!projectName + } + ); + + const renderAssigneeInfo = (step: IWorkFlowStepTemplateResV1) => { + if (step.approved_by_authorized || step.execute_by_authorized) { + return t('dmsDataExport.create.approvalProcess.matchByPermission'); + } + if (step.assignee_user_id_list && step.assignee_user_id_list.length > 0) { + return step.assignee_user_id_list.join(', '); + } + return '-'; + }; + + const renderStepTypeName = (type?: string) => { + if (type && stepTypeNameMap[type]) { + return t(stepTypeNameMap[type]); + } + return type ?? '-'; + }; + + if (error) { + return ( + + + + ); + } + + return ( + + +
+ {t('dmsDataExport.create.approvalProcess.title')} +
+ + {templateData?.workflow_step_template_list?.map( + (step: IWorkFlowStepTemplateResV1, index: number) => ( +
+
+ + + {t('dmsDataExport.create.approvalProcess.stepLabel', { + number: step.number ?? index + 1 + })} + + + {renderStepTypeName(step.type)} + + +
+
+ {renderAssigneeInfo(step)} +
+
+ ) + )} + +
+ {t('dmsDataExport.create.approvalProcess.hint')} +
+
+
+ ); +}; + +export default ApprovalProcessPreview; diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts new file mode 100644 index 0000000000..6423e16dda --- /dev/null +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts @@ -0,0 +1,46 @@ +import { styled } from '@mui/material/styles'; + +export const ApprovalProcessPreviewStyleWrapper = styled('div')` + padding: 24px 40px; + border-bottom: 1px solid + ${({ theme }) => theme.sharedTheme.basic.colorGrayLine}; + + .approval-process-title { + color: ${({ theme }) => theme.sharedTheme.uiToken.colorText}; + font-size: 16px; + font-weight: 500; + line-height: 24px; + margin-bottom: 16px; + } + + .approval-process-step { + padding: 12px 16px; + margin-bottom: 8px; + border-radius: 8px; + border: 1px solid ${({ theme }) => theme.sharedTheme.basic.colorGrayLine}; + background: ${({ theme }) => theme.sharedTheme.uiToken.colorFillQuaternary}; + + .approval-process-step-header { + margin-bottom: 4px; + + .step-number { + color: ${({ theme }) => theme.sharedTheme.uiToken.colorText}; + font-weight: 500; + font-size: 14px; + } + } + + .approval-process-step-assignee { + color: ${({ theme }) => theme.sharedTheme.uiToken.colorTextSecondary}; + font-size: 13px; + line-height: 20px; + } + } + + .approval-process-hint { + margin-top: 12px; + color: ${({ theme }) => theme.sharedTheme.uiToken.colorTextTertiary}; + font-size: 13px; + line-height: 20px; + } +`; diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx index 75e37bfff7..360857267e 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx @@ -15,6 +15,7 @@ import { CreateDataExportPageEnum } from '../../../../../store/dataExport'; import useCheckTaskAuditRuleExceptionStatus from '../../hooks/useCheckTaskAuditRuleExceptionStatus'; import { IListDataExportTaskSQL } from '@actiontech/shared/lib/api/base/service/common'; import SubmitWorkflowButton from './SubmitWorkflowButton'; +import ApprovalProcessPreview from './ApprovalProcessPreview'; const SubmitExportWorkflow: React.FC = () => { const { t } = useTranslation(); const { @@ -27,7 +28,7 @@ const SubmitExportWorkflow: React.FC = () => { updatePageState, updateWorkflowID } = useCreateDataExportReduxManage(); - const { projectID } = useCurrentProject(); + const { projectID, projectName } = useCurrentProject(); const [executeSQLsIsDQL, updateExecuteSQLsTypeIsDQL] = useState(true); const { hasExceptionAuditRule, @@ -105,6 +106,8 @@ const SubmitExportWorkflow: React.FC = () => { desc={formValues?.baseValues?.desc} /> + + Date: Tue, 21 Apr 2026 09:44:39 +0000 Subject: [PATCH 05/16] test(workflow-template): add/update unit tests for workflow template components - DEV-030: Update WorkflowTemplateDetail list page tests to cover edit button navigation with workflowType param, fix CE test missing usePermission mock - DEV-031: Update UpdateWorkflowTemplate edit page tests to mock useTypedQuery for workflowType, add data_export type title and step type tests, update BasicInfo test for hidden audit level field - DEV-032: Add ApprovalProcessPreview component tests covering loading state, success rendering, error fallback, step type name mapping, assignee display, and empty projectName guard refs actiontech/dms-ee#784 (cherry picked from commit 9b4a1b1ac6d301c2f4cc182503a934877c025d03) --- .../__snapshots__/index.test.tsx.snap | 165 ++++++++++++ .../__tests__/index.test.tsx | 135 ++++++++++ .../__snapshots__/index.test.tsx.snap | 20 +- .../__snapshots__/index.test.tsx.snap | 45 ++++ .../components/BasicInfo/index.test.tsx | 21 +- .../UpdateWorkflowTemplate/index.test.tsx | 55 +++- .../__snapshots__/index.ce.test.tsx.snap | 192 ++++++++++++++ .../__snapshots__/index.test.tsx.snap | 250 ++++++++++++++++++ .../WorkflowTemplateDetail/index.ce.test.tsx | 17 ++ .../WorkflowTemplateDetail/index.test.tsx | 46 +++- 10 files changed, 932 insertions(+), 14 deletions(-) create mode 100644 packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap create mode 100644 packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx create mode 100644 packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap create mode 100644 packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap new file mode 100644 index 0000000000..3d4d58f9a5 --- /dev/null +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap @@ -0,0 +1,165 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`base/DataExport/Create/ApprovalProcessPreview should render fallback error state when request fails 1`] = ` + +
+
+
+
+ + + +
+
+
+ 加载审批流程失败 +
+
+
+
+ +`; + +exports[`base/DataExport/Create/ApprovalProcessPreview should render loading state 1`] = ` + +
+
+
+
+
+ + + + + + +
+
+
+
+ 审批流程 +
+
+ 审批流程可在 Project Configure > Approval Process 中修改 +
+
+
+
+
+ +`; + +exports[`base/DataExport/Create/ApprovalProcessPreview should render step list when data loaded successfully 1`] = ` + +
+
+
+
+
+ 审批流程 +
+
+
+
+
+ + 步骤 1 + +
+
+ + 导出审批 + +
+
+
+
+ 按权限匹配 +
+
+
+ 审批流程可在 Project Configure > Approval Process 中修改 +
+
+
+
+
+ +`; diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx new file mode 100644 index 0000000000..285b4c9910 --- /dev/null +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx @@ -0,0 +1,135 @@ +import { act, screen } from '@testing-library/react'; +import { baseSuperRender } from '../../../../../../../testUtils/superRender'; +import ApprovalProcessPreview from '..'; +import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; +import { + createSpySuccessResponse, + createSpyErrorResponse +} from '@actiontech/shared/lib/testUtil/mockApi'; +import { dataExportWorkflowTemplateData } from '@actiontech/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data'; +import { cloneDeep } from 'lodash'; + +describe('base/DataExport/Create/ApprovalProcessPreview', () => { + beforeEach(() => { + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + jest.clearAllMocks(); + }); + + const customRender = (projectName = 'test-project') => { + return baseSuperRender( + + ); + }; + + it('should render loading state', () => { + jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation( + () => + new Promise(() => { + /* never resolves to keep loading */ + }) + ); + const { baseElement } = customRender(); + expect(baseElement).toMatchSnapshot(); + }); + + it('should render step list when data loaded successfully', async () => { + const getTemplateSpy = jest + .spyOn(workflow, 'getWorkflowTemplateV1') + .mockImplementation(() => + createSpySuccessResponse({ + data: cloneDeep(dataExportWorkflowTemplateData) + }) + ); + const { baseElement } = customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + + expect(getTemplateSpy).toHaveBeenCalledWith({ + project_name: 'test-project', + workflow_type: 'data_export' + }); + expect(screen.getByText('审批流程')).toBeInTheDocument(); + expect(screen.getByText('导出审批')).toBeInTheDocument(); + expect(screen.getByText('按权限匹配')).toBeInTheDocument(); + expect( + screen.getByText( + '审批流程可在 Project Configure > Approval Process 中修改' + ) + ).toBeInTheDocument(); + expect(baseElement).toMatchSnapshot(); + }); + + it('should render fallback error state when request fails', async () => { + jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation(() => + createSpyErrorResponse({}) + ); + const { baseElement } = customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + + expect(screen.getByText('加载审批流程失败')).toBeInTheDocument(); + expect(baseElement).toMatchSnapshot(); + }); + + it('should render correct step type names for export_review and export_execute', async () => { + const multiStepData = cloneDeep(dataExportWorkflowTemplateData); + multiStepData.workflow_step_template_list = [ + { + approved_by_authorized: true, + assignee_user_id_list: [], + execute_by_authorized: false, + number: 1, + type: 'export_review' + }, + { + approved_by_authorized: false, + assignee_user_id_list: [], + execute_by_authorized: true, + number: 2, + type: 'export_execute' + } + ]; + jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation(() => + createSpySuccessResponse({ + data: multiStepData + }) + ); + customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + + expect(screen.getByText('导出审批')).toBeInTheDocument(); + expect(screen.getByText('导出执行确认')).toBeInTheDocument(); + }); + + it('should render assignee user list when not matched by permission', async () => { + const customData = cloneDeep(dataExportWorkflowTemplateData); + customData.workflow_step_template_list = [ + { + approved_by_authorized: false, + assignee_user_id_list: ['user1', 'user2'], + execute_by_authorized: false, + number: 1, + type: 'export_review' + } + ]; + jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation(() => + createSpySuccessResponse({ + data: customData + }) + ); + customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + + expect(screen.getByText('user1, user2')).toBeInTheDocument(); + }); + + it('should not make API call when projectName is empty', () => { + const getTemplateSpy = jest + .spyOn(workflow, 'getWorkflowTemplateV1') + .mockImplementation(() => createSpySuccessResponse({ data: {} })); + customRender(''); + expect(getTemplateSpy).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap index fb864dc284..9ada633d8d 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap @@ -20,7 +20,7 @@ exports[`page/WorkflowTemplate/UpdateWorkflowTemplate change workflow template n />
- 返回审批流程模板 + 编辑审批流程 - 上线工单 @@ -712,7 +712,7 @@ exports[`page/WorkflowTemplate/UpdateWorkflowTemplate no review node in template />
- 返回审批流程模板 + 编辑审批流程 - 上线工单 @@ -1205,7 +1205,7 @@ exports[`page/WorkflowTemplate/UpdateWorkflowTemplate render update workflow tem
- 返回审批流程模板 + 编辑审批流程 - 上线工单 @@ -1881,7 +1881,7 @@ exports[`page/WorkflowTemplate/UpdateWorkflowTemplate render update workflow tem
- 返回审批流程模板 + 编辑审批流程 - 上线工单 @@ -2557,7 +2557,7 @@ exports[`page/WorkflowTemplate/UpdateWorkflowTemplate update workflow template i
- 返回审批流程模板 + 编辑审批流程 - 上线工单 diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/__snapshots__/index.test.tsx.snap index 38907a3002..eb20958d48 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/__snapshots__/index.test.tsx.snap @@ -278,3 +278,48 @@ exports[`page/WorkflowTemplate/BasicInfo render basic info without default data
`; + +exports[`page/WorkflowTemplate/BasicInfo should hide AllowSubmitWhenLessAuditLevel when workflowType is data_export 1`] = ` + +
+
+
+
+ 基本信息 +
+
+ 设定模板的基本信息 +
+
+
+ +
+ +
+ +
+
+
+ +`; diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.test.tsx index 26c8799069..95bfa5c4e5 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.test.tsx @@ -3,7 +3,8 @@ import BasicInfo from '.'; import { act, fireEvent, screen, renderHook } from '@testing-library/react'; import { getAllBySelector, - getBySelector + getBySelector, + queryBySelector } from '@actiontech/shared/lib/testUtil/customQuery'; import { workflowTemplateData } from '@actiontech/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data'; import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; @@ -24,7 +25,7 @@ describe('page/WorkflowTemplate/BasicInfo', () => { const updateMock = jest.fn(); const { result } = renderHook(() => Form.useForm()); - const customRender = (data?: { [key: string]: undefined }) => { + const customRender = (data?: Record) => { return sqleSuperRender( { expect(baseElement).toMatchSnapshot(); expect(screen.getByText('告警(Warning)')).toBeInTheDocument(); }); + + it('should hide AllowSubmitWhenLessAuditLevel when workflowType is data_export', async () => { + const { baseElement } = customRender({ workflowType: 'data_export' }); + expect(baseElement).toMatchSnapshot(); + expect(screen.getByText('基本信息')).toBeInTheDocument(); + expect( + screen.queryByText('允许创建工单的最高审核等级') + ).not.toBeInTheDocument(); + expect( + queryBySelector('.ant-select-selection-search-input') + ).not.toBeInTheDocument(); + + fireEvent.click(screen.getByText('下一步')); + await act(async () => jest.advanceTimersByTime(300)); + expect(nextStepMock).toHaveBeenCalled(); + }); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx index 3f572b005a..cdcadd0f4f 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx @@ -20,18 +20,25 @@ import { UtilsConsoleErrorStringsEnum } from '@actiontech/shared/lib/testUtil/common'; import user from '@actiontech/shared/lib/testUtil/mockApi/sqle/user'; +import { useTypedQuery } from '@actiontech/shared'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useParams: jest.fn() })); +jest.mock('@actiontech/shared', () => ({ + ...jest.requireActual('@actiontech/shared'), + useTypedQuery: jest.fn() +})); + describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { ignoreConsoleErrors([ UtilsConsoleErrorStringsEnum.UNCONNECTED_FORM_COMPONENT ]); const useParamsMock: jest.Mock = useParams as jest.Mock; + const extractQuerySpy = jest.fn(); const customRender = () => { return sqleSuperRender(); @@ -45,6 +52,8 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { mockUseCurrentUser(); jest.useFakeTimers(); workflowTemplate.mockAllApi(); + (useTypedQuery as jest.Mock).mockImplementation(() => extractQuerySpy); + extractQuerySpy.mockReturnValue({ workflowType: 'workflow' }); }); afterEach(() => { @@ -66,7 +75,9 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { expect(getInfoRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); await act(async () => jest.advanceTimersByTime(3000)); - expect(screen.getByText('返回审批流程模板')).toBeInTheDocument(); + expect( + screen.getByText('编辑审批流程 - 上线工单') + ).toBeInTheDocument(); expect(getBySelector('a')).toBeInTheDocument(); expect(getBySelector('a')).toHaveAttribute( 'href', @@ -81,6 +92,7 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { }); expect(updateInfoRequest).toHaveBeenCalledWith({ project_name: mockProjectInfo.projectName, + workflow_type: 'workflow', workflow_step_template_list: workflowTemplateData.workflow_step_template_list, allow_submit_when_less_audit_level: @@ -119,6 +131,7 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { }); expect(updateInfoRequest).toHaveBeenCalledWith({ project_name: mockProjectInfo.projectName, + workflow_type: 'workflow', workflow_step_template_list: workflowTemplateData.workflow_step_template_list, allow_submit_when_less_audit_level: @@ -176,6 +189,7 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { }); expect(updateInfoRequest).toHaveBeenCalledWith({ project_name: mockProjectInfo.projectName, + workflow_type: 'workflow', workflow_step_template_list: tempList, allow_submit_when_less_audit_level: UpdateWorkflowTemplateReqV1AllowSubmitWhenLessAuditLevelEnum.normal @@ -246,4 +260,43 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { await act(async () => jest.advanceTimersByTime(300)); }); }); + + describe('data_export workflow type', () => { + beforeEach(() => { + extractQuerySpy.mockReturnValue({ workflowType: 'data_export' }); + }); + + it('should render data export title when workflowType is data_export', async () => { + workflowTemplate.getWorkflowTemplate(); + user.getUserTipList(); + customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + await act(async () => jest.advanceTimersByTime(3000)); + expect( + screen.getByText('编辑审批流程 - 数据导出') + ).toBeInTheDocument(); + }); + + it('should use export step types when workflowType is data_export', async () => { + workflowTemplate.getWorkflowTemplate(); + const updateInfoRequest = workflowTemplate.updateWorkflowTemplate(); + user.getUserTipList(); + customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + await act(async () => jest.advanceTimersByTime(3000)); + + fireEvent.click(screen.getByText('下一步')); + await act(async () => jest.advanceTimersByTime(3000)); + + await act(async () => { + fireEvent.click(screen.getByText('保 存')); + await act(async () => jest.advanceTimersByTime(300)); + }); + expect(updateInfoRequest).toHaveBeenCalledWith( + expect.objectContaining({ + workflow_type: 'data_export' + }) + ); + }); + }); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap new file mode 100644 index 0000000000..eda47a95cf --- /dev/null +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap @@ -0,0 +1,192 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`page/WorkflowTemplate CE render workflow template list without edit actions in CE 1`] = ` + +
+
+
+ 审批流程模板 +
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 审批流程模板名称 + + 适用类型 + + 审批节点描述 + + 更新时间 +
+ 700300-WorkflowTemplate + + + 上线工单 + + + 审核节点 -> 审核节点 -> 执行上线 + + 2023-12-26 14:19:12 +
+ 700300-DataExportWorkflowTemplate + + + 数据导出 + + + 导出审批 + + 2024-01-15 10:30:00 +
+
+
+
+
+
+
+
+
+
+ +`; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap new file mode 100644 index 0000000000..4135a84379 --- /dev/null +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap @@ -0,0 +1,250 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`page/WorkflowTemplate/WorkflowTemplateDetail render workflow template list 1`] = ` + +
+
+
+ 审批流程模板 +
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 审批流程模板名称 + + 适用类型 + + 审批节点描述 + + 更新时间 + + 操作 +
+ 700300-WorkflowTemplate + + + 上线工单 + + + 审核节点 -> 审核节点 -> 执行上线 + + 2023-12-26 14:19:12 + +
+ +
+
+ 700300-DataExportWorkflowTemplate + + + 数据导出 + + + 导出审批 + + 2024-01-15 10:30:00 + +
+ +
+
+
+
+
+
+
+
+
+
+
+ +`; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx index 8672ba519b..acb09aebcb 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx @@ -9,12 +9,29 @@ import workflowTemplate from '@actiontech/shared/lib/testUtil/mockApi/sqle/workf import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentUser'; +jest.mock('react-redux', () => { + return { + ...jest.requireActual('react-redux'), + useSelector: jest.fn() + }; +}); + describe('page/WorkflowTemplate CE', () => { beforeEach(() => { workflowTemplate.mockAllApi(); mockUseCurrentProject(); mockUseCurrentUser(); jest.useFakeTimers(); + + const { useSelector } = require('react-redux'); + (useSelector as jest.Mock).mockImplementation((selector: Function) => + selector({ + permission: { + moduleFeatureSupport: {}, + userOperationPermissions: null + } + }) + ); }); afterEach(() => { diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx index a3af58e417..b94299593d 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx @@ -1,10 +1,11 @@ import { sqleSuperRender } from '../../../testUtils/superRender'; import WorkflowTemplateDetail from '.'; -import { act, cleanup, screen } from '@testing-library/react'; +import { act, cleanup, screen, fireEvent } from '@testing-library/react'; import workflowTemplate from '@actiontech/shared/lib/testUtil/mockApi/sqle/workflowTemplate'; import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentUser'; import { mockUsePermission } from '@actiontech/shared/lib/testUtil/mockHook/mockUsePermission'; +import { useTypedNavigate } from '@actiontech/shared'; jest.mock('react-redux', () => { return { @@ -13,7 +14,14 @@ jest.mock('react-redux', () => { }; }); +jest.mock('@actiontech/shared', () => ({ + ...jest.requireActual('@actiontech/shared'), + useTypedNavigate: jest.fn() +})); + describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { + const navigateSpy = jest.fn(); + beforeEach(() => { workflowTemplate.mockAllApi(); mockUseCurrentProject(); @@ -22,6 +30,7 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { mockUsePermission(undefined, { mockSelector: true }); + (useTypedNavigate as jest.Mock).mockImplementation(() => navigateSpy); }); afterEach(() => { @@ -59,4 +68,39 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { ).toBeInTheDocument(); expect(screen.getByText('导出审批')).toBeInTheDocument(); }); + + it('should navigate with workflowType param when clicking edit button', async () => { + workflowTemplate.getWorkflowTemplateList(); + customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + + const editButtons = screen.getAllByText('编 辑'); + expect(editButtons.length).toBe(2); + + fireEvent.click(editButtons[0]); + expect(navigateSpy).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + params: expect.objectContaining({ + workflowName: '700300-WorkflowTemplate' + }), + queries: expect.objectContaining({ + workflowType: 'workflow' + }) + }) + ); + + fireEvent.click(editButtons[1]); + expect(navigateSpy).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + params: expect.objectContaining({ + workflowName: '700300-DataExportWorkflowTemplate' + }), + queries: expect.objectContaining({ + workflowType: 'data_export' + }) + }) + ); + }); }); From 5cfffaf12b45e58e1464b8f9378a2a01a2e07c7b Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Tue, 21 Apr 2026 10:01:10 +0000 Subject: [PATCH 06/16] fix(test): add type annotation to dataExportWorkflowTemplateData and fix prettier formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为 dataExportWorkflowTemplateData 添加 IWorkflowTemplateDetailResV1 类型注解, 解决 assignee_user_id_list 空数组被推断为 never[] 导致的 TS2322 编译错误; 同时移除不合法的空字符串 allow_submit_when_less_audit_level 枚举值; 修复两个测试文件的 prettier 格式问题。 (cherry picked from commit 5b8b7238c1b9df63e1d3a6bb35a1b55b7fd5157d) --- .../ApprovalProcessPreview/__tests__/index.test.tsx | 6 +++--- .../lib/testUtil/mockApi/sqle/workflowTemplate/data.ts | 4 ++-- .../UpdateWorkflowTemplate/index.test.tsx | 8 ++------ 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx index 285b4c9910..061044e843 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx @@ -63,9 +63,9 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { }); it('should render fallback error state when request fails', async () => { - jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation(() => - createSpyErrorResponse({}) - ); + jest + .spyOn(workflow, 'getWorkflowTemplateV1') + .mockImplementation(() => createSpyErrorResponse({})); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); diff --git a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts index 3098e799a2..c51548fe7c 100644 --- a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts +++ b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts @@ -1,3 +1,4 @@ +import { IWorkflowTemplateDetailResV1 } from '../../../../api/sqle/service/common'; import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '../../../../api/sqle/service/common.enum'; export const workflowTemplateData = { @@ -33,8 +34,7 @@ export const workflowTemplateData = { workflow_type: 'workflow' }; -export const dataExportWorkflowTemplateData = { - allow_submit_when_less_audit_level: '', +export const dataExportWorkflowTemplateData: IWorkflowTemplateDetailResV1 = { desc: '', update_time: '2024-01-15T10:30:00+08:00', workflow_step_template_list: [ diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx index cdcadd0f4f..04b7acf416 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx @@ -75,9 +75,7 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { expect(getInfoRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); await act(async () => jest.advanceTimersByTime(3000)); - expect( - screen.getByText('编辑审批流程 - 上线工单') - ).toBeInTheDocument(); + expect(screen.getByText('编辑审批流程 - 上线工单')).toBeInTheDocument(); expect(getBySelector('a')).toBeInTheDocument(); expect(getBySelector('a')).toHaveAttribute( 'href', @@ -272,9 +270,7 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { customRender(); await act(async () => jest.advanceTimersByTime(3000)); await act(async () => jest.advanceTimersByTime(3000)); - expect( - screen.getByText('编辑审批流程 - 数据导出') - ).toBeInTheDocument(); + expect(screen.getByText('编辑审批流程 - 数据导出')).toBeInTheDocument(); }); it('should use export step types when workflowType is data_export', async () => { From 2307042c6c7013de43c6547a2e44d7abd2f5833b Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Wed, 22 Apr 2026 08:21:45 +0000 Subject: [PATCH 07/16] fix(#784): fix data export workflow template UI issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Issue 1: Change workflow template page from list to tab-based layout with separate tabs for SQL exec workflow and data export - Issue 2: Fix i18n text in template edit page for data export context (e.g. "执行上线" -> "执行导出", match permission text) - Issue 3: Fix description truncation in export order detail page by replacing BasicTypographyEllipsis with plain div - Issue 4: Restore polling logic for export status refresh in detail page - Issue 5: Fix workflow progress display to show dynamic approval nodes instead of hardcoded 3 steps - Issue 6: Fix approval flow i18n mixing in create export review page (Chinese text was mixed with English labels) (cherry picked from commit d5b3e259538d63bebb99871e945d3b9d5259a76c) --- .../base/src/locale/zh-CN/dmsDataExport.ts | 2 +- .../Common/BasicInfoWrapper/index.tsx | 7 +- .../WorkflowRecordInfo/WorkflowSteps.tsx | 85 ++++-- .../Detail/hooks/useInitDataWithRequest.ts | 48 +++- .../sqle/src/locale/en-US/workflowTemplate.ts | 21 +- .../sqle/src/locale/zh-CN/workflowTemplate.ts | 18 +- .../components/ReviewNodeInfo/index.tsx | 25 +- .../components/ReviewNodeInfo/index.type.ts | 1 + .../components/StepInfo/index.tsx | 4 +- .../UpdateWorkflowTemplate/index.tsx | 2 + .../WorkflowTemplateAuthInfo/index.tsx | 53 ++-- .../WorkflowTemplateAuthInfo/index.type.ts | 3 +- .../WorkflowTemplateStepInfo/index.tsx | 3 +- .../WorkflowTemplateStepInfo/index.type.ts | 1 + .../WorkflowTemplateDetail/index.tsx | 268 ++++++++++++++---- .../WorkflowTemplateDetail/style.ts | 18 ++ .../components/StepCard/index.type.ts | 2 + .../components/StepCard/stepInfo.tsx | 16 +- 18 files changed, 441 insertions(+), 136 deletions(-) diff --git a/packages/base/src/locale/zh-CN/dmsDataExport.ts b/packages/base/src/locale/zh-CN/dmsDataExport.ts index ed1601ef33..1bdebc0f3a 100644 --- a/packages/base/src/locale/zh-CN/dmsDataExport.ts +++ b/packages/base/src/locale/zh-CN/dmsDataExport.ts @@ -54,7 +54,7 @@ export default { }, approvalProcess: { title: '审批流程', - hint: '审批流程可在 Project Configure > Approval Process 中修改', + hint: '审批流程可在 项目配置 > 审批流程 中修改', stepLabel: '步骤 {{number}}', matchByPermission: '按权限匹配', loadFailed: '加载审批流程失败', diff --git a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx index 3db4fdf939..8a77c4c4ef 100644 --- a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx +++ b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx @@ -1,6 +1,6 @@ import classNames from 'classnames'; import { BasicInfoWrapperProps } from './index.type'; -import { BasicTypographyEllipsis, EmptyBox } from '@actiontech/dms-kit'; +import { EmptyBox } from '@actiontech/dms-kit'; import { DataExportStatusDictionary } from '../index.data'; import { BasicInfoStyleWrapper } from './style'; const BasicInfoWrapper: React.FC = ({ @@ -77,10 +77,7 @@ const BasicInfoWrapper: React.FC = ({
{title}
- +
{desc ?? '-'}
); }; diff --git a/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx b/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx index 38d4e26a9e..e6f436ea93 100644 --- a/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx +++ b/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx @@ -26,20 +26,38 @@ const WorkflowSteps: React.FC = ({ }) => { const { t } = useTranslation(); const { sharedTheme } = useThemeStyleData(); + + // Dynamic step number calculation based on workflow status and steps const stepNumber = useMemo(() => { - if (!workflowStatus) { + if (!workflowStatus || !workflowSteps) { return currentStepNumber; } - //本期后端没有流程模板,当前固定为:创建、审核、执行 三步,所以前端自己判断当前到第几步了 - if ( - workflowStatus === WorkflowRecordStatusEnum.wait_for_approve || - workflowStatus === WorkflowRecordStatusEnum.rejected - ) { + // Total steps: create(1) + N approval nodes + execute(1) + const totalApprovalSteps = workflowSteps.length; + + if (workflowStatus === WorkflowRecordStatusEnum.rejected) { + // Find which approval step was rejected + for (let i = 0; i < workflowSteps.length; i++) { + if (workflowSteps[i]?.state === 'rejected') { + return i + 2; // +1 for create step, +1 for 1-indexed + } + } return 2; } + + if (workflowStatus === WorkflowRecordStatusEnum.wait_for_approve) { + // Find the current step being awaited + if (currentStepNumber !== undefined && currentStepNumber !== null) { + // currentStepNumber from API represents which step we are on (1-indexed) + return (currentStepNumber as number) + 1; // +1 for create step + } + return 2; + } + if (workflowStatus === WorkflowRecordStatusEnum.wait_for_export) { - return 3; + return totalApprovalSteps + 2; // all approval done, at execute step } + if ( [ WorkflowRecordStatusEnum.exporting, @@ -48,19 +66,16 @@ const WorkflowSteps: React.FC = ({ WorkflowRecordStatusEnum.cancel ].includes(workflowStatus) ) { - return 4; + return totalApprovalSteps + 2; // at execute step } - }, [currentStepNumber, workflowStatus]); + }, [currentStepNumber, workflowStatus, workflowSteps]); + const renderTitle = useCallback( (type?: string) => { if (type === 'create') { return t('dmsDataExport.detail.record.steps.create'); } - // if (type === WorkflowStepResV2TypeEnum.update_workflow) { - // return t('dmsDataExport.detail.record.steps.update'); - // } - if (type === 'approve') { return t('dmsDataExport.detail.record.steps.approve'); } @@ -148,12 +163,14 @@ const WorkflowSteps: React.FC = ({ [renderOrderStepsItemContent] ); const renderOrderStepsItemIcon = useCallback( - (type?: string) => { + (type?: string, step?: any) => { if (type === 'create') { return ; } if (type === 'approve') { - const isRejected = workflowStatus === WorkflowRecordStatusEnum.rejected; + const isRejected = + workflowStatus === WorkflowRecordStatusEnum.rejected && + step?.state === 'rejected'; return ( = ({ }, [workflowStatus, sharedTheme.uiToken.colorWarning] ); + const stepsItems = useMemo(() => { if (!workflowSteps) { return []; } - // 没有流程模板,先固定这 3 步 - return [ + // Build dynamic steps: create + N approval nodes + execute + const allSteps: any[] = [ { type: 'create', number: 1, @@ -193,21 +211,30 @@ const WorkflowSteps: React.FC = ({ name: createUser }, operation_time: createTime - }, - { - ...workflowSteps[0], - type: 'approve', - number: 2 - }, - { - type: 'execute', - number: 3 } - ].map((v, i) => { - const isNextRejected = workflowSteps[i + 1]?.state === 'rejected'; + ]; + + // Add all approval steps from workflow_step_list + workflowSteps.forEach((step, index) => { + allSteps.push({ + ...step, + type: 'approve', + number: index + 2 + }); + }); + + // Add execute step + allSteps.push({ + type: 'execute', + number: allSteps.length + 1 + }); + + return allSteps.map((v, i) => { + const nextStep = allSteps[i + 1]; + const isNextRejected = nextStep?.state === 'rejected'; return { title: renderOrderStepsItem(renderTitle(v.type), v), - icon: renderOrderStepsItemIcon(v.type), + icon: renderOrderStepsItemIcon(v.type, v), className: classNames({ 'prev-rejected-step': isNextRejected }) diff --git a/packages/base/src/page/DataExportManagement/Detail/hooks/useInitDataWithRequest.ts b/packages/base/src/page/DataExportManagement/Detail/hooks/useInitDataWithRequest.ts index ba73b5f63f..e832a421b7 100644 --- a/packages/base/src/page/DataExportManagement/Detail/hooks/useInitDataWithRequest.ts +++ b/packages/base/src/page/DataExportManagement/Detail/hooks/useInitDataWithRequest.ts @@ -3,11 +3,14 @@ import DataExportWorkflows from '@actiontech/shared/lib/api/base/service/DataExp import { ResponseCode } from '@actiontech/dms-kit'; import { useCurrentProject } from '@actiontech/shared/lib/features'; import useDataExportDetailReduxManage from './index.redux'; -import { useRequest } from 'ahooks'; -import { useEffect } from 'react'; +import { useBoolean, useRequest } from 'ahooks'; +import { useEffect, useMemo } from 'react'; import eventEmitter from '../../../../utils/EventEmitter'; import EmitterKey from '../../../../data/EmitterKey'; -import { GetDataExportTaskStatusEnum } from '@actiontech/shared/lib/api/base/service/common.enum'; +import { + GetDataExportTaskStatusEnum, + WorkflowRecordStatusEnum +} from '@actiontech/shared/lib/api/base/service/common.enum'; import { useTypedParams } from '@actiontech/shared'; import { ROUTE_PATHS } from '@actiontech/dms-kit'; @@ -18,7 +21,14 @@ const useInitDataWithRequest = () => { const { updateTaskInfos, updateWorkflowInfo, updateTaskStatusNumber } = useDataExportDetailReduxManage(); - const { refresh: refreshWorkflow, loading: getWorkflowLoading } = useRequest( + const [polling, { setFalse: finishPollRequest, setTrue: startPollRequest }] = + useBoolean(); + + const { + refresh: refreshWorkflow, + loading: getWorkflowLoading, + cancel + } = useRequest( () => DataExportWorkflows.GetDataExportWorkflow({ project_uid: projectID, @@ -31,8 +41,27 @@ const useInitDataWithRequest = () => { ?.map((v) => v.task_uid ?? '') ?.join(',') ?? '' ); + + // Stop polling when no longer in exporting status + if ( + res.data.data?.workflow_record?.status !== + WorkflowRecordStatusEnum.exporting + ) { + cancel(); + finishPollRequest(); + } else { + startPollRequest(); + } } - }) + }), + { + pollingInterval: 1000, + pollingErrorRetryCount: 3, + onError: () => { + cancel(); + finishPollRequest(); + } + } ); const { loading: getTaskInfosLoading, run: batchGetDataExportTask } = @@ -82,9 +111,14 @@ const useInitDataWithRequest = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + const initLoading = useMemo( + () => (polling ? false : getTaskInfosLoading || getWorkflowLoading), + [getTaskInfosLoading, getWorkflowLoading, polling] + ); + return { - getWorkflowLoading, - getTaskInfosLoading + getWorkflowLoading: initLoading, + getTaskInfosLoading: initLoading }; }; diff --git a/packages/sqle/src/locale/en-US/workflowTemplate.ts b/packages/sqle/src/locale/en-US/workflowTemplate.ts index c68a9b89ae..9588e2e56f 100644 --- a/packages/sqle/src/locale/en-US/workflowTemplate.ts +++ b/packages/sqle/src/locale/en-US/workflowTemplate.ts @@ -76,7 +76,9 @@ export default { fourth: 'Audit tickets: the auditor can execute “pass audit” or “reject” operations in this step;', fifth: - 'Online tickets: the executor can execute “execute online” or “reject” operations in this step.' + 'Online tickets: the executor can execute “execute online” or “reject” operations in this step.', + fifthExport: + 'Export tickets: the executor can execute “execute export” or “reject” operations in this step.' } }, @@ -92,6 +94,10 @@ export default { execDesc: 'Edit the audit process. The executor can execute “execute online” or “reject” operations in this step', + exportExecTitle: 'Execute export', + exportExecDesc: + 'Edit the audit process. The executor can execute “execute export” or “reject” operations in this step', + resultTitle: 'Result', resultDesc: 'Change result' }, @@ -142,6 +148,15 @@ export default { matchExecute: 'Match members who have data source online permissions' } }, + exportExec: { + title: 'Execute export', + subTitle: + 'The executor can execute “execute export” or “reject” operations in this step', + executeUserType: { + specifyExecute: 'Specify executor', + matchExecute: 'Match members who have data source export permissions' + } + }, exportReview: { title: 'Export Review', subTitle: 'Reviewer checks the legitimacy of the export request' @@ -165,6 +180,10 @@ export default { 'The approval workflow template can set up to 4 audit steps, or no audit steps can be set;', rule3: 'When specifying the executor for a single step, at least one specified person needs to be added, and a maximum of three specified persons can be added.' + }, + exportRuler: { + rule1: + 'The approval process starts from the initiation of the ticket, and ends with the execution of export after passing through the set audit steps;' } }, diff --git a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts index 0dd16070cd..452304b1df 100644 --- a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts +++ b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts @@ -72,7 +72,8 @@ export default { '被驳回的工单,需要创建人更新SQL语句后重新发起,驳回记录可在 “工单进度-工单历史操作” 中查看;', third: '处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭;', fourth: '审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作;', - fifth: '上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。' + fifth: '上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。', + fifthExport: '导出工单:执行人在该步骤可以执行「执行导出」或「驳回」操作。' } }, @@ -87,6 +88,9 @@ export default { execTitle: '执行上线', execDesc: '编辑审核流程,执行人在该步骤可以执行「执行上线」或「驳回」操作', + exportExecTitle: '执行导出', + exportExecDesc: '编辑审核流程,执行人在该步骤可以执行「执行导出」或「驳回」操作', + resultTitle: '结果', resultDesc: '变更结果' }, @@ -134,6 +138,14 @@ export default { matchExecute: '匹配拥有数据源上线权限的成员' } }, + exportExec: { + title: '执行导出', + subTitle: '执行人在该步骤可以执行 执行导出或驳回 操作', + executeUserType: { + specifyExecute: '指定执行人', + matchExecute: '匹配拥有数据源导出权限的成员' + } + }, exportReview: { title: '导出审批', subTitle: '审批人在该步骤审核导出请求的合理性' @@ -155,6 +167,10 @@ export default { rule2: '审核流程模板最多可设置4个审核步骤,也可不设置审核步骤;', rule3: '单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加三个指定人。' + }, + exportRuler: { + rule1: + '审核流程自工单发起开始,通过设置的审核步骤后,最后以执行导出结束;' } }, diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx index a9575cf7c3..a90303c2be 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx @@ -20,6 +20,7 @@ const MAX_USER_COUNT = 10; const ReviewAndExecNodeInfo: React.FC = (props) => { const { t } = useTranslation(); + const isDataExport = props.workflowType === 'data_export'; const [authorizedParam, setAuthorizedParam] = useState( props.type === NodeTypeEnum.review ? 'approved_by_authorized' @@ -92,12 +93,16 @@ const ReviewAndExecNodeInfo: React.FC = (props) => {
{props.type === NodeTypeEnum.review ? t('workflowTemplate.step.progressTitle') - : t('workflowTemplate.step.execTitle')} + : isDataExport + ? t('workflowTemplate.step.exportExecTitle') + : t('workflowTemplate.step.execTitle')}
{props.type === NodeTypeEnum.review ? t('workflowTemplate.step.progressDesc') - : t('workflowTemplate.step.execDesc')} + : isDataExport + ? t('workflowTemplate.step.exportExecDesc') + : t('workflowTemplate.step.execDesc')}
@@ -133,9 +138,13 @@ const ReviewAndExecNodeInfo: React.FC = (props) => { ? t( 'workflowTemplate.progressConfig.review.reviewUserType.matchAudit' ) - : t( - 'workflowTemplate.progressConfig.exec.executeUserType.matchExecute' - ) + : isDataExport + ? t( + 'workflowTemplate.progressConfig.exportExec.executeUserType.matchExecute' + ) + : t( + 'workflowTemplate.progressConfig.exec.executeUserType.matchExecute' + ) } name={[authorizedParam]} valuePropName="checked" @@ -208,7 +217,11 @@ const ReviewAndExecNodeInfo: React.FC = (props) => {
    -
  • {t('workflowTemplate.progressConfig.ruler.rule1')}
  • +
  • + {isDataExport + ? t('workflowTemplate.progressConfig.exportRuler.rule1') + : t('workflowTemplate.progressConfig.ruler.rule1')} +
  • {t('workflowTemplate.progressConfig.ruler.rule2')}
  • {t('workflowTemplate.progressConfig.ruler.rule3')}
diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts index af1a5e391a..6eb21c3662 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts @@ -29,4 +29,5 @@ export type ReviewAndExecNodeInfoProps = { updateReviewAndExecNodeInfo: (data: IWorkFlowStepTemplateResV1) => void; generateUsernameSelectOption: () => React.ReactNode; getUsernameListLoading: boolean; + workflowType?: string; }; diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx index dd7bd5af05..d9b9c85e27 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx @@ -48,7 +48,8 @@ const StepInfo: React.FC = (props) => { reviewStepData: props.reviewStepData, execStepData: props.execStepData, usernameList: props.usernameList, - theme: sqleTheme.icon + theme: sqleTheme.icon, + isDataExport: props.isDataExport }), [ templateLevel, @@ -56,6 +57,7 @@ const StepInfo: React.FC = (props) => { props.execStepData, props.reviewStepData, props.usernameList, + props.isDataExport, sqleTheme ] ); diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx index 98e3c99726..e53efe17c3 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx @@ -197,6 +197,7 @@ const UpdateWorkflowTemplate: React.FC = () => { getUsernameListLoading={getUsernameListLoading} totalStep={reviewSteps.length + 1} updateReviewAndExecNodeInfo={updateReviewAndExecNodeInfo} + workflowType={workflowType} /> ); }; @@ -299,6 +300,7 @@ const UpdateWorkflowTemplate: React.FC = () => { exchangeReviewNode={handleExchangeReviewNode} clickReviewNode={handleClickReviewNode} usernameList={usernameList} + isDataExport={workflowType === 'data_export'} /> = ({ level, - time + time, + hideLevel }) => { const { t } = useTranslation(); const { sqleTheme } = useThemeStyleData(); const { currentLevelData, levelText } = useGetLevelData(level); return ( - - - {t('workflowTemplate.form.label.allowSubmitWhenLessAuditLevel')} - - - {levelText} - - - + {!hideLevel && ( + + + {t('workflowTemplate.form.label.allowSubmitWhenLessAuditLevel')} + + + {levelText} + + + + )} {t('workflowTemplate.detail.title.noticeInfo')} @@ -47,10 +50,16 @@ const WorkflowTemplateAuthInfo: React.FC = ({
  • {t('workflowTemplate.detail.authLevelInfo.first')}
  • -
  • {t('workflowTemplate.detail.authLevelInfo.second')}
  • + {!hideLevel && ( +
  • {t('workflowTemplate.detail.authLevelInfo.second')}
  • + )}
  • {t('workflowTemplate.detail.authLevelInfo.third')}
  • {t('workflowTemplate.detail.authLevelInfo.fourth')}
  • -
  • {t('workflowTemplate.detail.authLevelInfo.fifth')}
  • +
  • + {hideLevel + ? t('workflowTemplate.detail.authLevelInfo.fifthExport') + : t('workflowTemplate.detail.authLevelInfo.fifth')} +
diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateAuthInfo/index.type.ts b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateAuthInfo/index.type.ts index 49fa2bc6ab..3d24682fde 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateAuthInfo/index.type.ts +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateAuthInfo/index.type.ts @@ -1,8 +1,9 @@ import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; export interface WorkflowTemplateAuthInfoProps { - level: + level?: | WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum | undefined; time?: string; + hideLevel?: boolean; } diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.tsx index 98f636efb1..331971587e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.tsx @@ -22,7 +22,8 @@ const WorkflowTemplateStepInfo: React.FC = ( reviewStepData: props.reviewStepData, execStepData: props.execStepData, usernameList: props.usernameList, - theme: sqleTheme.icon + theme: sqleTheme.icon, + isDataExport: props.isDataExport }).map((step) => step.show ? ( diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.type.ts b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.type.ts index 49c118757b..de3c27bccd 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.type.ts +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.type.ts @@ -7,4 +7,5 @@ export interface IWorkflowTemplateStepInfoProps { reviewStepData: IWorkFlowStepTemplateResV1[]; execStepData: IWorkFlowStepTemplateResV1; usernameList: IUserTipResV1[]; + isDataExport?: boolean; } diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx index d0386ede54..7c780e1cd2 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx @@ -1,80 +1,236 @@ -import { useMemo, useCallback } from 'react'; +import { useMemo, useCallback, useState } from 'react'; import { useRequest } from 'ahooks'; import { useTranslation } from 'react-i18next'; +import { Col, Row, Spin, Tabs } from 'antd'; import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; import { useCurrentProject, - usePermission + PERMISSIONS, + PermissionControl } from '@actiontech/shared/lib/features'; -import { useTypedNavigate } from '@actiontech/shared'; +import { ActionButton } from '@actiontech/shared'; import { ROUTE_PATHS } from '@actiontech/dms-kit'; import { PageHeader } from '@actiontech/dms-kit'; -import { - ActiontechTable, - ActiontechTableWrapper -} from '@actiontech/dms-kit/es/components/ActiontechTable'; -import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; -import { WorkflowTemplateListColumn } from './column'; -import { WorkflowTemplateTableActions } from './actions'; +import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; +import WorkflowTemplateStepInfo from './components/WorkflowTemplateStepInfo'; +import WorkflowTemplateAuthInfo from './components/WorkflowTemplateAuthInfo'; +import { WorkflowTemplateStyleWrapper } from './style'; +import useUsername from '../../../hooks/useUsername'; +import { EditOutlined } from '@ant-design/icons'; const WorkflowTemplateDetail: React.FC = () => { const { t } = useTranslation(); const { projectName, projectID } = useCurrentProject(); - const { parse2TableActionPermissions } = usePermission(); - const navigate = useTypedNavigate(); + const [activeTab, setActiveTab] = useState('workflow'); - const columns = useMemo(() => WorkflowTemplateListColumn(), []); + const { + updateUsernameList, + usernameList, + loading: getUsernameListLoading + } = useUsername(); - const { data: templateList, loading } = useRequest( - () => - workflow - .getWorkflowTemplateListV1({ - project_name: projectName - }) - .then((res) => res.data.data ?? []), - { - ready: !!projectName - } - ); + useMemo(() => { + updateUsernameList({ + filter_project: projectName + }); + }, [projectName, updateUsernameList]); + + // Fetch SQL Exec Workflow template + const [workflowReviewSteps, setWorkflowReviewSteps] = useState< + IWorkFlowStepTemplateResV1[] + >([]); + const [workflowExecStep, setWorkflowExecStep] = + useState({ + assignee_user_id_list: [], + desc: '' + }); + + const { data: workflowTemplate, loading: getWorkflowTemplateLoading } = + useRequest( + () => + workflow + .getWorkflowTemplateV1({ + project_name: projectName, + workflow_type: 'workflow' + }) + .then((res) => { + const stepList = + res.data.data?.workflow_step_template_list ?? []; + if (stepList.length <= 1) { + setWorkflowExecStep(stepList[0] ?? { assignee_user_id_list: [], desc: '' }); + setWorkflowReviewSteps([]); + } else { + const execStep = stepList.pop(); + setWorkflowReviewSteps(stepList); + if (execStep) setWorkflowExecStep(execStep); + } + return res.data.data; + }), + { + ready: !!projectName + } + ); - const onEditTemplate = useCallback( - (record: IWorkflowTemplateDetailResV1) => { - navigate(ROUTE_PATHS.SQLE.PROGRESS.update, { - params: { - projectID, - workflowName: record.workflow_template_name ?? '' - }, - queries: { - workflowType: record.workflow_type ?? '' - } - }); + // Fetch Data Export workflow template + const [exportReviewSteps, setExportReviewSteps] = useState< + IWorkFlowStepTemplateResV1[] + >([]); + const [exportExecStep, setExportExecStep] = + useState({ + assignee_user_id_list: [], + desc: '' + }); + + const { data: exportTemplate, loading: getExportTemplateLoading } = + useRequest( + () => + workflow + .getWorkflowTemplateV1({ + project_name: projectName, + workflow_type: 'data_export' + }) + .then((res) => { + const stepList = + res.data.data?.workflow_step_template_list ?? []; + if (stepList.length <= 1) { + setExportExecStep(stepList[0] ?? { assignee_user_id_list: [], desc: '' }); + setExportReviewSteps([]); + } else { + const execStep = stepList.pop(); + setExportReviewSteps(stepList); + if (execStep) setExportExecStep(execStep); + } + return res.data.data; + }), + { + ready: !!projectName + } + ); + + const renderEditButton = useCallback( + (workflowType: string, templateName?: string) => { + return ( + // #if [ee] + + } + text={t('workflowTemplate.detail.updateTemplate')} + actionType="navigate-link" + link={{ + to: ROUTE_PATHS.SQLE.PROGRESS.update, + params: { + projectID, + workflowName: templateName ?? '' + }, + queries: { + workflowType + } + }} + /> + + // #endif + ); }, - [navigate, projectID] + [t, projectID] ); - const actions = useMemo(() => { - return parse2TableActionPermissions( - WorkflowTemplateTableActions(onEditTemplate) - ); - }, [parse2TableActionPermissions, onEditTemplate]); + const tabItems = useMemo( + () => [ + { + key: 'workflow', + label: t('workflowTemplate.list.type.workflow'), + children: ( + +
+ {renderEditButton( + 'workflow', + workflowTemplate?.workflow_template_name + )} +
+ + + + + + + + +
+ ) + }, + { + key: 'data_export', + label: t('workflowTemplate.list.type.dataExport'), + children: ( + +
+ {renderEditButton( + 'data_export', + exportTemplate?.workflow_template_name + )} +
+ + + + + + + + +
+ ) + } + ], + [ + t, + getUsernameListLoading, + getWorkflowTemplateLoading, + getExportTemplateLoading, + workflowReviewSteps, + workflowExecStep, + exportReviewSteps, + exportExecStep, + usernameList, + workflowTemplate, + exportTemplate, + renderEditButton + ] + ); return ( - <> + - - - record?.workflow_template_name ?? '' - } - loading={loading} - columns={columns} - // #if [ee] - actions={actions} - // #endif - /> - - + + ); }; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts index d63644aa9c..6270f268ad 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts @@ -2,4 +2,22 @@ import { styled } from '@mui/material/styles'; export const WorkflowTemplateStyleWrapper = styled('div')` height: 100%; + + .workflow-template-tabs { + padding: 0 40px; + + .ant-tabs-nav { + margin-bottom: 16px; + } + } + + .workflow-template-wrapper { + height: 100%; + } + + .workflow-template-right-module { + border-left: ${({ theme }) => + theme.sqleTheme.workflowTemplate.workflowTemplateAuthInfo.borderBottom}; + height: auto; + } `; diff --git a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.type.ts b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.type.ts index d79f776127..9f4ac9bbf1 100644 --- a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.type.ts +++ b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.type.ts @@ -38,6 +38,7 @@ export interface IStepInfoProps { execStepData: IWorkFlowStepTemplateResV1; usernameList: IUserTipResV1[]; theme?: IconTheme; + isDataExport?: boolean; } export interface IStepInfoDataProps extends IStepCardProps { @@ -60,4 +61,5 @@ export interface IUpdateWorkflowStepInfoProps { exchangeReviewNode: (from: number, to: number) => void; clickReviewNode: (index: number) => void; usernameList: IUserTipResV1[]; + isDataExport?: boolean; } diff --git a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx index 6e55ace1a9..ce4c7d62d3 100644 --- a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx @@ -23,7 +23,8 @@ const renderReviewUser = ( type: 'review' | 'exec', stepItem: IWorkFlowStepTemplateResV1, userList: IUserTipResV1[], - theme: IStepInfoProps['theme'] + theme: IStepInfoProps['theme'], + isDataExport?: boolean ) => { if (stepItem.assignee_user_id_list?.length === 0) { if (stepItem.approved_by_authorized && type === 'review') { @@ -51,7 +52,9 @@ const renderReviewUser = ( /> {t( - 'workflowTemplate.progressConfig.exec.executeUserType.matchExecute' + isDataExport + ? 'workflowTemplate.progressConfig.exportExec.executeUserType.matchExecute' + : 'workflowTemplate.progressConfig.exec.executeUserType.matchExecute' )} @@ -80,7 +83,7 @@ export const stepInfo = (props: IStepInfoProps): IStepInfoDataProps[] => { return [ { key: 'honour-step', - show: isUpdateMode, + show: isUpdateMode && !props.isDataExport, disabled: !(props?.currentStep === 0), icon: ( @@ -173,14 +176,17 @@ export const stepInfo = (props: IStepInfoProps): IStepInfoDataProps[] => { ), arrow: StepInfoArrowEnum.none, - title: t('workflowTemplate.progressConfig.exec.title'), + title: props.isDataExport + ? t('workflowTemplate.progressConfig.exportExec.title') + : t('workflowTemplate.progressConfig.exec.title'), desc: props.execStepData?.desc ?? '-', operatorTitle: t('workflowTemplate.form.label.execUser'), operator: renderReviewUser( 'exec', props?.execStepData, props.usernameList, - props.theme + props.theme, + props.isDataExport ) } ]; From eed1bd4aa87cf580b8e208a7f7ca069f063878ed Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Wed, 22 Apr 2026 10:31:35 +0000 Subject: [PATCH 08/16] fix(#784): optimize workflow template UI - tab style, redirect link, approval preview 1. Replace antd Tabs with SegmentedTabs for workflow template detail page to match audit rule template page styling convention. 2. Fix redirect link after saving data export workflow template: the "view updated template" button now navigates to the data export tab instead of always landing on the workflow tab. 3. Improve approval process preview styling in data export creation page with step indicator dots, connector lines, and better visual hierarchy. Refs: actiontech/dms-ee#784 (cherry picked from commit 56f11e29002f7c29427b4d342647bb60a1276aa8) --- .../__snapshots__/index.test.tsx.snap | 657 +-------------- .../__snapshots__/index.test.tsx.snap | 104 +-- .../__snapshots__/index.test.tsx.snap | 53 +- .../__tests__/index.test.tsx | 2 +- .../ApprovalProcessPreview/index.tsx | 41 +- .../ApprovalProcessPreview/style.ts | 92 ++- .../__snapshots__/index.test.tsx.snap | 178 ++-- .../__snapshots__/index.test.tsx.snap | 375 +-------- .../__snapshots__/index.test.tsx.snap | 2 +- packages/dms-kit/src/data/routePaths.ts | 3 +- .../__snapshots__/index.test.tsx.snap | 10 +- .../UpdateWorkflowTemplate/index.test.tsx | 2 +- .../UpdateWorkflowTemplate/index.tsx | 3 + .../__snapshots__/index.ce.test.tsx.snap | 700 +++++++++++++--- .../__snapshots__/index.test.tsx.snap | 782 +++++++++++++----- .../WorkflowTemplateDetail/index.ce.test.tsx | 6 +- .../WorkflowTemplateDetail/index.test.tsx | 66 +- .../WorkflowTemplateDetail/index.tsx | 23 +- .../WorkflowTemplateDetail/style.ts | 6 +- 19 files changed, 1437 insertions(+), 1668 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap index 5734d0b78c..1495acc62e 100644 --- a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap @@ -11,80 +11,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 1`] export-task-1
- -
- - - -
- -
@@ -101,80 +30,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 2`] export-task-1
desc -
- - - -
- -
@@ -264,80 +122,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 3`] export-task-1
desc -
- - - -
- -
@@ -427,80 +214,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 4`] export-task-1
desc -
- - - -
- -
@@ -590,80 +306,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 5`] export-task-1
desc -
- - - -
- -
@@ -753,80 +398,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 6`] export-task-1
desc -
- - - -
- -
@@ -916,80 +490,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 7`] export-task-1
desc -
- - - -
- -
@@ -1079,80 +582,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 8`] export-task-1
desc -
- - - -
- -
@@ -1242,80 +674,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 9`] export-task-1
desc -
- - - -
- -
diff --git a/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap index 02122de329..caa531c3a2 100644 --- a/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap @@ -1427,80 +1427,58 @@ exports[`first should match snapshot when pageState is equal SUBMIT_WORKFLOW 1`] test
desc -
- +
+
+
+
+
- - - + + + +
- -
+
- - - + 审批流程可在 项目配置 > 审批流程 中修改
- +
审批流程
+
- 审批流程可在 Project Configure > Approval Process 中修改 + 审批流程可在 项目配置 > 审批流程 中修改
@@ -103,7 +106,7 @@ exports[`base/DataExport/Create/ApprovalProcessPreview should render step list w
- - 步骤 1 - + 1
+
+
+
- - 导出审批 - + 导出审批 +
+
+ 按权限匹配
-
- 按权限匹配 -
- 审批流程可在 Project Configure > Approval Process 中修改 + 审批流程可在 项目配置 > 审批流程 中修改
diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx index 061044e843..3883b1cc8e 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx @@ -56,7 +56,7 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { expect(screen.getByText('按权限匹配')).toBeInTheDocument(); expect( screen.getByText( - '审批流程可在 Project Configure > Approval Process 中修改' + /审批流程可在.*中修改/ ) ).toBeInTheDocument(); expect(baseElement).toMatchSnapshot(); diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx index 2b0b7f4658..d9c2cd91f5 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx @@ -1,6 +1,6 @@ import { useTranslation } from 'react-i18next'; import { useRequest } from 'ahooks'; -import { Spin, Space, Typography } from 'antd'; +import { Spin } from 'antd'; import { Result } from 'antd'; import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; @@ -72,27 +72,28 @@ const ApprovalProcessPreview: React.FC = ({ {t('dmsDataExport.create.approvalProcess.title')}
- {templateData?.workflow_step_template_list?.map( - (step: IWorkFlowStepTemplateResV1, index: number) => ( -
-
- - - {t('dmsDataExport.create.approvalProcess.stepLabel', { - number: step.number ?? index + 1 - })} - - +
+ {templateData?.workflow_step_template_list?.map( + (step: IWorkFlowStepTemplateResV1, index: number) => ( +
+
+
+ {step.number ?? index + 1} +
+
+
+
+
{renderStepTypeName(step.type)} - - +
+
+ {renderAssigneeInfo(step)} +
+
-
- {renderAssigneeInfo(step)} -
-
- ) - )} + ) + )} +
{t('dmsDataExport.create.approvalProcess.hint')} diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts index 6423e16dda..bc6c47648d 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts @@ -7,40 +7,94 @@ export const ApprovalProcessPreviewStyleWrapper = styled('div')` .approval-process-title { color: ${({ theme }) => theme.sharedTheme.uiToken.colorText}; - font-size: 16px; - font-weight: 500; - line-height: 24px; + font-size: 14px; + font-weight: 600; + line-height: 22px; margin-bottom: 16px; } + .approval-process-steps { + display: flex; + flex-direction: column; + gap: 0; + } + .approval-process-step { - padding: 12px 16px; - margin-bottom: 8px; - border-radius: 8px; - border: 1px solid ${({ theme }) => theme.sharedTheme.basic.colorGrayLine}; - background: ${({ theme }) => theme.sharedTheme.uiToken.colorFillQuaternary}; + display: flex; + align-items: flex-start; + position: relative; + padding-left: 32px; + padding-bottom: 16px; + + &:last-child { + padding-bottom: 0; + + .step-connector { + display: none; + } + } + + .step-indicator { + position: absolute; + left: 0; + top: 0; + display: flex; + flex-direction: column; + align-items: center; + + .step-dot { + width: 24px; + height: 24px; + border-radius: 50%; + background: ${({ theme }) => + theme.sharedTheme.uiToken.colorPrimary}; + color: #fff; + font-size: 12px; + font-weight: 600; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + } + + .step-connector { + width: 2px; + flex: 1; + min-height: 16px; + background: ${({ theme }) => + theme.sharedTheme.basic.colorGrayLine}; + margin-top: 4px; + } + } - .approval-process-step-header { - margin-bottom: 4px; + .step-content { + flex: 1; + padding: 4px 0 0 12px; - .step-number { + .step-type-name { color: ${({ theme }) => theme.sharedTheme.uiToken.colorText}; - font-weight: 500; font-size: 14px; + font-weight: 500; + line-height: 22px; } - } - .approval-process-step-assignee { - color: ${({ theme }) => theme.sharedTheme.uiToken.colorTextSecondary}; - font-size: 13px; - line-height: 20px; + .step-assignee { + color: ${({ theme }) => + theme.sharedTheme.uiToken.colorTextSecondary}; + font-size: 13px; + line-height: 20px; + margin-top: 2px; + } } } .approval-process-hint { - margin-top: 12px; + margin-top: 16px; + padding-top: 12px; + border-top: 1px dashed + ${({ theme }) => theme.sharedTheme.basic.colorGrayLine}; color: ${({ theme }) => theme.sharedTheme.uiToken.colorTextTertiary}; - font-size: 13px; + font-size: 12px; line-height: 20px; } `; diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap index 5f611d78ee..0dd2c8ba80 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap @@ -79,80 +79,58 @@ exports[`test base/DataExport/Create/SubmitWorkflow should match snapshot 1`] = test
desc -
- +
+
+
+
+
- - + + + + +
- -
+
- - - + 审批流程可在 项目配置 > 审批流程 中修改
- +
desc +
+
+
+
- -
desc -
- - - -
- -
desc -
- - - -
- -
desc -
- - - -
- -
desc -
- - - -
- -
desc -
- - - -
- -
{ expect(getAllBySelector('a').length).toBe(2); expect(getAllBySelector('a')?.[1]).toHaveAttribute( 'href', - `/sqle/project/${mockProjectInfo.projectID}/progress` + `/sqle/project/${mockProjectInfo.projectID}/progress?activeTab=workflow` ); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx index e53efe17c3..d7c04a287e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx @@ -324,6 +324,9 @@ const UpdateWorkflowTemplate: React.FC = () => { to: ROUTE_PATHS.SQLE.PROGRESS.index, params: { projectID + }, + queries: { + activeTab: workflowType } }} /> diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap index eda47a95cf..179121d5fd 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap @@ -1,184 +1,612 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`page/WorkflowTemplate CE render workflow template list without edit actions in CE 1`] = ` +exports[`page/WorkflowTemplate CE render workflow template detail without edit actions in CE 1`] = `
- 审批流程模板 +
+ 审批流程模板 +
+
-
-
-
+
+
+ + +
+
+
+
+
+
+ + + + + + +
+
+
- - - - - - - - - - - - + + + +
+
-
- - - - - + + + +
+ + + + + + +
+
+
+ -
- - - - - + + + +
+
-
- - - - - -
- 审批流程模板名称 - - 适用类型 - - 审批节点描述 - + + - 更新时间 -
- 700300-WorkflowTemplate - - - 上线工单 - - - 审核节点 -> 审核节点 -> 执行上线 - - 2023-12-26 14:19:12 -
- 700300-DataExportWorkflowTemplate - - - 数据导出 - - - 导出审批 - - 2024-01-15 10:30:00 -
+ + 执行上线 + +
+ - +
+
+
+ 执行人 +
+
+ + + + + 匹配拥有数据源上线权限的成员 + +
+
+
+
+
+
+
+
+
+
+
+
+ + 允许创建工单的最高审核等级 + + + 告警(Warning) + +
+
+
+
+
+
+
+
+
+
+ + 注意事项 + +
+
    +
  • + 若项目管理员对审批流程模板进行了修改,不会对已经在审批流程的工单造成影响; +
  • +
  • + 被驳回的工单,需要创建人更新SQL语句后重新发起,驳回记录可在 “工单进度-工单历史操作” 中查看; +
  • +
  • + 处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭; +
  • +
  • + 审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作; +
  • +
  • + 上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。 +
  • +
+
+
+
+ + 审批流程模板更新时间 + +
+ + + + + 2023-12-26 14:19:12 + +
+
diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap index 4135a84379..1a9631e0b6 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap @@ -1,242 +1,648 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`page/WorkflowTemplate/WorkflowTemplateDetail render workflow template list 1`] = ` +exports[`page/WorkflowTemplate/WorkflowTemplateDetail render workflow template detail page with SegmentedTabs 1`] = `
- 审批流程模板 +
+ 审批流程模板 +
+
-
-
-
+
+
+ + +
+
+
+
+
+
+ + + + + + +
+
+
- - - - - - - - - - - - - - - - - - - + - - - - - - - + + + +
+ + + +
+
+
+ -
- - - - - - + + + +
+ + + + + + +
+
+
+ -
- - - - - - -
- 审批流程模板名称 - - 适用类型 - - 审批节点描述 - - 更新时间 - - 操作 -
- 700300-WorkflowTemplate - - - 上线工单 - - - 审核节点 -> 审核节点 -> 执行上线 - - 2023-12-26 14:19:12 - + + + +
+
+
- + +
+ step desc +
+
+
+ 审核人 +
+
+
+
+ + + 1 + + +
+
+
+
-
- 700300-DataExportWorkflowTemplate - - - 数据导出 - - - 导出审批 - - 2024-01-15 10:30:00 - + + + +
+
+
- + 执行上线 + +
+ - +
+
+
+ 执行人 +
+
+ + + + + 匹配拥有数据源上线权限的成员 + +
+
-
+
+
+
+
+
+
+
+
+
+ + 允许创建工单的最高审核等级 + + + 告警(Warning) + +
+
+
+
+
+
+
+
+
+
+ + 注意事项 + +
+
    +
  • + 若项目管理员对审批流程模板进行了修改,不会对已经在审批流程的工单造成影响; +
  • +
  • + 被驳回的工单,需要创建人更新SQL语句后重新发起,驳回记录可在 “工单进度-工单历史操作” 中查看; +
  • +
  • + 处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭; +
  • +
  • + 审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作; +
  • +
  • + 上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。 +
  • +
+
+
+
+ + 审批流程模板更新时间 + +
+ + + + + 2023-12-26 14:19:12 + +
+
diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx index acb09aebcb..1991994caa 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx @@ -43,11 +43,11 @@ describe('page/WorkflowTemplate CE', () => { return sqleSuperRender(); }; - it('render workflow template list without edit actions in CE', async () => { - const getListRequest = workflowTemplate.getWorkflowTemplateList(); + it('render workflow template detail without edit actions in CE', async () => { + const getTemplateRequest = workflowTemplate.getWorkflowTemplate(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); - expect(getListRequest).toHaveBeenCalled(); + expect(getTemplateRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); expect(screen.getByText('审批流程模板')).toBeInTheDocument(); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx index b94299593d..5f9d3f3f7f 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx @@ -1,11 +1,10 @@ import { sqleSuperRender } from '../../../testUtils/superRender'; import WorkflowTemplateDetail from '.'; -import { act, cleanup, screen, fireEvent } from '@testing-library/react'; +import { act, cleanup, screen } from '@testing-library/react'; import workflowTemplate from '@actiontech/shared/lib/testUtil/mockApi/sqle/workflowTemplate'; import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentUser'; import { mockUsePermission } from '@actiontech/shared/lib/testUtil/mockHook/mockUsePermission'; -import { useTypedNavigate } from '@actiontech/shared'; jest.mock('react-redux', () => { return { @@ -14,14 +13,7 @@ jest.mock('react-redux', () => { }; }); -jest.mock('@actiontech/shared', () => ({ - ...jest.requireActual('@actiontech/shared'), - useTypedNavigate: jest.fn() -})); - describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { - const navigateSpy = jest.fn(); - beforeEach(() => { workflowTemplate.mockAllApi(); mockUseCurrentProject(); @@ -30,7 +22,6 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { mockUsePermission(undefined, { mockSelector: true }); - (useTypedNavigate as jest.Mock).mockImplementation(() => navigateSpy); }); afterEach(() => { @@ -42,65 +33,20 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { return sqleSuperRender(); }; - it('render workflow template list', async () => { - const getListRequest = workflowTemplate.getWorkflowTemplateList(); + it('render workflow template detail page with SegmentedTabs', async () => { + const getTemplateRequest = workflowTemplate.getWorkflowTemplate(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); - expect(getListRequest).toHaveBeenCalled(); + expect(getTemplateRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); expect(screen.getByText('审批流程模板')).toBeInTheDocument(); }); - it('render workflow type tags correctly', async () => { - workflowTemplate.getWorkflowTemplateList(); + it('render segmented tab labels correctly', async () => { + workflowTemplate.getWorkflowTemplate(); customRender(); await act(async () => jest.advanceTimersByTime(3000)); expect(screen.getByText('上线工单')).toBeInTheDocument(); expect(screen.getByText('数据导出')).toBeInTheDocument(); }); - - it('render approval node description', async () => { - workflowTemplate.getWorkflowTemplateList(); - customRender(); - await act(async () => jest.advanceTimersByTime(3000)); - expect( - screen.getByText('审核节点 -> 审核节点 -> 执行上线') - ).toBeInTheDocument(); - expect(screen.getByText('导出审批')).toBeInTheDocument(); - }); - - it('should navigate with workflowType param when clicking edit button', async () => { - workflowTemplate.getWorkflowTemplateList(); - customRender(); - await act(async () => jest.advanceTimersByTime(3000)); - - const editButtons = screen.getAllByText('编 辑'); - expect(editButtons.length).toBe(2); - - fireEvent.click(editButtons[0]); - expect(navigateSpy).toHaveBeenCalledWith( - expect.anything(), - expect.objectContaining({ - params: expect.objectContaining({ - workflowName: '700300-WorkflowTemplate' - }), - queries: expect.objectContaining({ - workflowType: 'workflow' - }) - }) - ); - - fireEvent.click(editButtons[1]); - expect(navigateSpy).toHaveBeenCalledWith( - expect.anything(), - expect.objectContaining({ - params: expect.objectContaining({ - workflowName: '700300-DataExportWorkflowTemplate' - }), - queries: expect.objectContaining({ - workflowType: 'data_export' - }) - }) - ); - }); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx index 7c780e1cd2..b41d5f8dde 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx @@ -1,16 +1,16 @@ import { useMemo, useCallback, useState } from 'react'; import { useRequest } from 'ahooks'; import { useTranslation } from 'react-i18next'; -import { Col, Row, Spin, Tabs } from 'antd'; +import { Col, Row, Spin } from 'antd'; import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; import { useCurrentProject, PERMISSIONS, PermissionControl } from '@actiontech/shared/lib/features'; -import { ActionButton } from '@actiontech/shared'; +import { ActionButton, useTypedQuery } from '@actiontech/shared'; import { ROUTE_PATHS } from '@actiontech/dms-kit'; -import { PageHeader } from '@actiontech/dms-kit'; +import { PageHeader, SegmentedTabs } from '@actiontech/dms-kit'; import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; import WorkflowTemplateStepInfo from './components/WorkflowTemplateStepInfo'; import WorkflowTemplateAuthInfo from './components/WorkflowTemplateAuthInfo'; @@ -21,7 +21,10 @@ import { EditOutlined } from '@ant-design/icons'; const WorkflowTemplateDetail: React.FC = () => { const { t } = useTranslation(); const { projectName, projectID } = useCurrentProject(); - const [activeTab, setActiveTab] = useState('workflow'); + const extractQueries = useTypedQuery(); + const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.index); + const initialTab = searchParams?.activeTab === 'data_export' ? 'data_export' : 'workflow'; + const [activeTab, setActiveTab] = useState(initialTab); const { updateUsernameList, @@ -109,8 +112,8 @@ const WorkflowTemplateDetail: React.FC = () => { const renderEditButton = useCallback( (workflowType: string, templateName?: string) => { + // #if [ee] return ( - // #if [ee] @@ -131,8 +134,9 @@ const WorkflowTemplateDetail: React.FC = () => { }} /> - // #endif ); + // #endif + return null; }, [t, projectID] ); @@ -140,7 +144,7 @@ const WorkflowTemplateDetail: React.FC = () => { const tabItems = useMemo( () => [ { - key: 'workflow', + value: 'workflow', label: t('workflowTemplate.list.type.workflow'), children: ( { ) }, { - key: 'data_export', + value: 'data_export', label: t('workflowTemplate.list.type.dataExport'), children: ( { return ( - ); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts index 6270f268ad..915f047a9a 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts @@ -3,12 +3,8 @@ import { styled } from '@mui/material/styles'; export const WorkflowTemplateStyleWrapper = styled('div')` height: 100%; - .workflow-template-tabs { + .segmented-tabs-wrapper { padding: 0 40px; - - .ant-tabs-nav { - margin-bottom: 16px; - } } .workflow-template-wrapper { From b9358b66abfa70f5237bed99c26a3d7e944b06d9 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Thu, 23 Apr 2026 08:57:06 +0000 Subject: [PATCH 09/16] fix(#784): enforce audit node constraints, executor=creator, remove preview 1. Prevent removing last audit node (min 1) and hide close button when only 1 review node exists; max 4 already enforced by disabled button. 2. Data export exec step shows 'workflow creator' as executor (read-only, not modifiable) in template editor and step card display. 3. Remove ApprovalProcessPreview from SQL audit page (SubmitWorkflow). (cherry picked from commit 756a2dcfb9f7166784c9a2d226ce189dd1c12d78) --- .../components/SubmitWorkflow/index.tsx | 5 +---- .../sqle/src/locale/en-US/workflowTemplate.ts | 2 ++ .../sqle/src/locale/zh-CN/workflowTemplate.ts | 1 + .../components/ReviewNodeInfo/index.tsx | 22 +++++++++++++++++++ .../components/StepInfo/index.tsx | 12 ++++++++-- .../components/StepCard/index.tsx | 2 +- .../components/StepCard/stepInfo.tsx | 16 ++++++++++++++ 7 files changed, 53 insertions(+), 7 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx index 360857267e..75e37bfff7 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx @@ -15,7 +15,6 @@ import { CreateDataExportPageEnum } from '../../../../../store/dataExport'; import useCheckTaskAuditRuleExceptionStatus from '../../hooks/useCheckTaskAuditRuleExceptionStatus'; import { IListDataExportTaskSQL } from '@actiontech/shared/lib/api/base/service/common'; import SubmitWorkflowButton from './SubmitWorkflowButton'; -import ApprovalProcessPreview from './ApprovalProcessPreview'; const SubmitExportWorkflow: React.FC = () => { const { t } = useTranslation(); const { @@ -28,7 +27,7 @@ const SubmitExportWorkflow: React.FC = () => { updatePageState, updateWorkflowID } = useCreateDataExportReduxManage(); - const { projectID, projectName } = useCurrentProject(); + const { projectID } = useCurrentProject(); const [executeSQLsIsDQL, updateExecuteSQLsTypeIsDQL] = useState(true); const { hasExceptionAuditRule, @@ -106,8 +105,6 @@ const SubmitExportWorkflow: React.FC = () => { desc={formValues?.baseValues?.desc} /> - - = (props) => { const nextStep = async () => { props.form.validateFields().then(() => props?.nextStep?.()); }; + const isDataExportExec = isDataExport && props.type === NodeTypeEnum.exec; return (
@@ -107,6 +108,25 @@ const ReviewAndExecNodeInfo: React.FC = (props) => {
+ {isDataExportExec ? ( + <> + + + + {t( + 'workflowTemplate.progressConfig.exportExec.creatorAsExecutor' + )} + + + + + ) : ( + <> = (props) => { nextStep={nextStep} prevStep={prevStep} /> + + )} diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx index d9b9c85e27..41a89ca6ae 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx @@ -135,7 +135,11 @@ const StepInfo: React.FC = (props) => { key={step.key} indexNumber={index} rowKey={step.key} - removeReviewNode={props.removeReviewNode} + removeReviewNode={ + props.reviewStepData.length > 1 + ? props.removeReviewNode + : undefined + } clickReviewNode={props.clickReviewNode} /> ) : ( @@ -153,7 +157,11 @@ const StepInfo: React.FC = (props) => { {...step} key={`${step.key}-step-card`} indexNumber={index} - close={props?.removeReviewNode} + close={ + props.reviewStepData.length > 1 + ? props?.removeReviewNode + : undefined + } click={props.clickReviewNode} /> diff --git a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.tsx b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.tsx index 85c76706c8..54c5cbc09e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.tsx @@ -24,7 +24,7 @@ const StepCard: React.FC = (props) => {
{props?.operator}
) : null} - {props?.active ? ( + {props?.active && props?.close ? ( ); } else if (stepItem.execute_by_authorized && type === 'exec') { + if (isDataExport) { + return ( + <> + + + {t( + 'workflowTemplate.progressConfig.exportExec.creatorAsExecutor' + )} + + + ); + } return ( <> Date: Thu, 23 Apr 2026 10:23:30 +0000 Subject: [PATCH 10/16] fix(#784): update mock data to include export_execute step in data export template Align test mock data with the updated default data export workflow template which now includes both export_review and export_execute steps. (cherry picked from commit 009db1a54953e8022008e2f4e7a18c49a832eadd) --- .../lib/testUtil/mockApi/sqle/workflowTemplate/data.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts index c51548fe7c..dd1be11399 100644 --- a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts +++ b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts @@ -44,6 +44,13 @@ export const dataExportWorkflowTemplateData: IWorkflowTemplateDetailResV1 = { execute_by_authorized: false, number: 1, type: 'export_review' + }, + { + approved_by_authorized: false, + assignee_user_id_list: [], + execute_by_authorized: true, + number: 2, + type: 'export_execute' } ], workflow_template_name: '700300-DataExportWorkflowTemplate', From 4f7a468b1ad08930ec4b4b6b47b74e5de4e0ba0c Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Thu, 23 Apr 2026 10:33:01 +0000 Subject: [PATCH 11/16] fix(#784): update frontend tests for data export template with export_execute step MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update ApprovalProcessPreview test to handle multiple "按权限匹配" text elements since the default template now has both export_review and export_execute steps. Update related snapshots. (cherry picked from commit 2d249f465f59266e88730815a35167683df95b66) --- .../__snapshots__/index.test.tsx.snap | 49 ----------- .../__snapshots__/index.test.tsx.snap | 30 +++++++ .../__tests__/index.test.tsx | 2 +- .../__snapshots__/index.test.tsx.snap | 88 ------------------- 4 files changed, 31 insertions(+), 138 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap index caa531c3a2..b694a7e1c3 100644 --- a/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap @@ -1432,55 +1432,6 @@ exports[`first should match snapshot when pageState is equal SUBMIT_WORKFLOW 1`] desc
-
-
-
-
- - - - - - -
-
-
-
- 审批流程 -
-
-
- 审批流程可在 项目配置 > 审批流程 中修改 -
-
-
-
diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap index eea264a30a..3ee435a6b3 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap @@ -152,6 +152,36 @@ exports[`base/DataExport/Create/ApprovalProcessPreview should render step list w
+
+
+
+ 2 +
+
+
+
+
+ 导出执行确认 +
+
+ 按权限匹配 +
+
+
{ }); expect(screen.getByText('审批流程')).toBeInTheDocument(); expect(screen.getByText('导出审批')).toBeInTheDocument(); - expect(screen.getByText('按权限匹配')).toBeInTheDocument(); + expect(screen.getAllByText('按权限匹配').length).toBeGreaterThanOrEqual(1); expect( screen.getByText( /审批流程可在.*中修改/ diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap index 0dd2c8ba80..b9998fae22 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap @@ -84,55 +84,6 @@ exports[`test base/DataExport/Create/SubmitWorkflow should match snapshot 1`] = desc
-
-
-
-
- - - - - - -
-
-
-
- 审批流程 -
-
-
- 审批流程可在 项目配置 > 审批流程 中修改 -
-
-
-
@@ -380,45 +331,6 @@ exports[`test base/DataExport/Create/SubmitWorkflow should match snapshot 2`] = desc
-
-
-
- - - -
-
-
- 加载审批流程失败 -
-
-
From 3f795f877d64bd03e5971de806117e3fc79b850b Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Thu, 23 Apr 2026 11:28:06 +0000 Subject: [PATCH 12/16] fix(#784): update useInitDataWithRequest test to match initLoading behavior --- .../Detail/hooks/__tests__/useInitDataWithRequest.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Detail/hooks/__tests__/useInitDataWithRequest.test.ts b/packages/base/src/page/DataExportManagement/Detail/hooks/__tests__/useInitDataWithRequest.test.ts index 0b2df0751b..8e592bff34 100644 --- a/packages/base/src/page/DataExportManagement/Detail/hooks/__tests__/useInitDataWithRequest.test.ts +++ b/packages/base/src/page/DataExportManagement/Detail/hooks/__tests__/useInitDataWithRequest.test.ts @@ -48,7 +48,7 @@ describe('test base/DataExport/Detail/hooks/useInitDataWithRequest', () => { const { result } = renderHook(() => useInitDataWithRequest()); expect(result.current.getWorkflowLoading).toBeTruthy(); - expect(result.current.getTaskInfosLoading).toBeFalsy(); + expect(result.current.getTaskInfosLoading).toBeTruthy(); expect(getWorkflowSpy).toHaveBeenCalledTimes(1); expect(getWorkflowSpy).toHaveBeenCalledWith({ project_uid: mockProjectInfo.projectID, @@ -56,7 +56,7 @@ describe('test base/DataExport/Detail/hooks/useInitDataWithRequest', () => { }); await act(async () => jest.advanceTimersByTime(3000)); - expect(result.current.getWorkflowLoading).toBeFalsy(); + expect(result.current.getWorkflowLoading).toBeTruthy(); expect(result.current.getTaskInfosLoading).toBeTruthy(); expect(mockDataExportDetailRedux.updateWorkflowInfo).toHaveBeenCalledTimes( 1 From a717d17e42eba2c2611b10f5e24c7cf93c48d697 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Thu, 23 Apr 2026 11:34:17 +0000 Subject: [PATCH 13/16] style(#784): apply prettier formatting --- .../__tests__/index.test.tsx | 6 +- .../ApprovalProcessPreview/index.tsx | 4 +- .../ApprovalProcessPreview/style.ts | 9 +- .../sqle/src/locale/zh-CN/workflowTemplate.ts | 6 +- .../components/ReviewNodeInfo/index.tsx | 204 +++++++++--------- .../WorkflowTemplateDetail/index.tsx | 45 ++-- 6 files changed, 138 insertions(+), 136 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx index 646a7cbfad..d3be7bf366 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx @@ -54,11 +54,7 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { expect(screen.getByText('审批流程')).toBeInTheDocument(); expect(screen.getByText('导出审批')).toBeInTheDocument(); expect(screen.getAllByText('按权限匹配').length).toBeGreaterThanOrEqual(1); - expect( - screen.getByText( - /审批流程可在.*中修改/ - ) - ).toBeInTheDocument(); + expect(screen.getByText(/审批流程可在.*中修改/)).toBeInTheDocument(); expect(baseElement).toMatchSnapshot(); }); diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx index d9c2cd91f5..913e10b16e 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx @@ -77,9 +77,7 @@ const ApprovalProcessPreview: React.FC = ({ (step: IWorkFlowStepTemplateResV1, index: number) => (
-
- {step.number ?? index + 1} -
+
{step.number ?? index + 1}
diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts index bc6c47648d..52b6645edf 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts @@ -46,8 +46,7 @@ export const ApprovalProcessPreviewStyleWrapper = styled('div')` width: 24px; height: 24px; border-radius: 50%; - background: ${({ theme }) => - theme.sharedTheme.uiToken.colorPrimary}; + background: ${({ theme }) => theme.sharedTheme.uiToken.colorPrimary}; color: #fff; font-size: 12px; font-weight: 600; @@ -61,8 +60,7 @@ export const ApprovalProcessPreviewStyleWrapper = styled('div')` width: 2px; flex: 1; min-height: 16px; - background: ${({ theme }) => - theme.sharedTheme.basic.colorGrayLine}; + background: ${({ theme }) => theme.sharedTheme.basic.colorGrayLine}; margin-top: 4px; } } @@ -79,8 +77,7 @@ export const ApprovalProcessPreviewStyleWrapper = styled('div')` } .step-assignee { - color: ${({ theme }) => - theme.sharedTheme.uiToken.colorTextSecondary}; + color: ${({ theme }) => theme.sharedTheme.uiToken.colorTextSecondary}; font-size: 13px; line-height: 20px; margin-top: 2px; diff --git a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts index 79073d106c..b01b013fa1 100644 --- a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts +++ b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts @@ -73,7 +73,8 @@ export default { third: '处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭;', fourth: '审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作;', fifth: '上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。', - fifthExport: '导出工单:执行人在该步骤可以执行「执行导出」或「驳回」操作。' + fifthExport: + '导出工单:执行人在该步骤可以执行「执行导出」或「驳回」操作。' } }, @@ -89,7 +90,8 @@ export default { execDesc: '编辑审核流程,执行人在该步骤可以执行「执行上线」或「驳回」操作', exportExecTitle: '执行导出', - exportExecDesc: '编辑审核流程,执行人在该步骤可以执行「执行导出」或「驳回」操作', + exportExecDesc: + '编辑审核流程,执行人在该步骤可以执行「执行导出」或「驳回」操作', resultTitle: '结果', resultDesc: '变更结果' diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx index 454935445e..586777d763 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx @@ -95,15 +95,15 @@ const ReviewAndExecNodeInfo: React.FC = (props) => { {props.type === NodeTypeEnum.review ? t('workflowTemplate.step.progressTitle') : isDataExport - ? t('workflowTemplate.step.exportExecTitle') - : t('workflowTemplate.step.execTitle')} + ? t('workflowTemplate.step.exportExecTitle') + : t('workflowTemplate.step.execTitle')}
{props.type === NodeTypeEnum.review ? t('workflowTemplate.step.progressDesc') : isDataExport - ? t('workflowTemplate.step.exportExecDesc') - : t('workflowTemplate.step.execDesc')} + ? t('workflowTemplate.step.exportExecDesc') + : t('workflowTemplate.step.execDesc')}
@@ -127,107 +127,107 @@ const ReviewAndExecNodeInfo: React.FC = (props) => { ) : ( <> - + + + + + + - - - - - - - - {props.generateUsernameSelectOption()} - - - + ] + : [] + } + > + + {props.generateUsernameSelectOption()} + + + )} diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx index b41d5f8dde..e63a9ff08a 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx @@ -23,7 +23,8 @@ const WorkflowTemplateDetail: React.FC = () => { const { projectName, projectID } = useCurrentProject(); const extractQueries = useTypedQuery(); const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.index); - const initialTab = searchParams?.activeTab === 'data_export' ? 'data_export' : 'workflow'; + const initialTab = + searchParams?.activeTab === 'data_export' ? 'data_export' : 'workflow'; const [activeTab, setActiveTab] = useState(initialTab); const { @@ -57,10 +58,11 @@ const WorkflowTemplateDetail: React.FC = () => { workflow_type: 'workflow' }) .then((res) => { - const stepList = - res.data.data?.workflow_step_template_list ?? []; + const stepList = res.data.data?.workflow_step_template_list ?? []; if (stepList.length <= 1) { - setWorkflowExecStep(stepList[0] ?? { assignee_user_id_list: [], desc: '' }); + setWorkflowExecStep( + stepList[0] ?? { assignee_user_id_list: [], desc: '' } + ); setWorkflowReviewSteps([]); } else { const execStep = stepList.pop(); @@ -93,10 +95,11 @@ const WorkflowTemplateDetail: React.FC = () => { workflow_type: 'data_export' }) .then((res) => { - const stepList = - res.data.data?.workflow_step_template_list ?? []; + const stepList = res.data.data?.workflow_step_template_list ?? []; if (stepList.length <= 1) { - setExportExecStep(stepList[0] ?? { assignee_user_id_list: [], desc: '' }); + setExportExecStep( + stepList[0] ?? { assignee_user_id_list: [], desc: '' } + ); setExportReviewSteps([]); } else { const execStep = stepList.pop(); @@ -147,10 +150,14 @@ const WorkflowTemplateDetail: React.FC = () => { value: 'workflow', label: t('workflowTemplate.list.type.workflow'), children: ( - -
+ +
{renderEditButton( 'workflow', workflowTemplate?.workflow_template_name @@ -166,9 +173,7 @@ const WorkflowTemplateDetail: React.FC = () => { @@ -180,10 +185,14 @@ const WorkflowTemplateDetail: React.FC = () => { value: 'data_export', label: t('workflowTemplate.list.type.dataExport'), children: ( - -
+ +
{renderEditButton( 'data_export', exportTemplate?.workflow_template_name From 11d6256f8dadb22659e22129b2861189e3ed437c Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Mon, 27 Apr 2026 11:25:14 +0800 Subject: [PATCH 14/16] feat(workflow): type workflow_type for template APIs and align UI --- .../__snapshots__/index.test.tsx.snap | 18 ++--- .../Common/BasicInfoWrapper/index.tsx | 8 +- .../__snapshots__/index.test.tsx.snap | 2 +- .../ApprovalProcessPreview/index.tsx | 34 ++++---- .../__snapshots__/index.test.tsx.snap | 4 +- .../__snapshots__/index.test.tsx.snap | 10 +-- packages/base/src/scripts/version.ts | 2 +- .../shared/lib/api/sqle/service/common.d.ts | 21 +++-- .../lib/api/sqle/service/common.enum.ts | 12 +-- .../lib/api/sqle/service/workflow/index.d.ts | 22 +++--- .../api/sqle/service/workflow/index.enum.ts | 12 +++ .../lib/api/sqle/service/workflow/index.ts | 28 ++++--- .../mockApi/sqle/workflowTemplate/data.ts | 9 ++- .../sqle/src/locale/zh-CN/workflowTemplate.ts | 4 +- .../Create/hooks/useAllowAuditLevel.ts | 4 +- .../__snapshots__/index.test.tsx.snap | 10 +-- .../__snapshots__/index.test.tsx.snap | 10 +-- .../components/ReviewNodeInfo/index.tsx | 4 +- .../UpdateWorkflowTemplate/index.tsx | 21 +++-- .../__snapshots__/index.ce.test.tsx.snap | 5 +- .../__snapshots__/index.test.tsx.snap | 78 +++++++++---------- .../WorkflowTemplateDetail/column.tsx | 7 +- .../WorkflowTemplateDetail/index.tsx | 51 +++++------- .../WorkflowTemplateDetail/style.ts | 8 +- 24 files changed, 202 insertions(+), 182 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap index 1495acc62e..b0b0df09d7 100644 --- a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap @@ -11,7 +11,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 1`] export-task-1
-
@@ -30,7 +30,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 2`] export-task-1
desc
@@ -122,7 +122,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 3`] export-task-1
desc
@@ -214,7 +214,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 4`] export-task-1
desc
@@ -306,7 +306,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 5`] export-task-1
desc
@@ -398,7 +398,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 6`] export-task-1
desc
@@ -490,7 +490,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 7`] export-task-1
desc
@@ -582,7 +582,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 8`] export-task-1
desc
@@ -674,7 +674,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 9`] export-task-1
desc
diff --git a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx index 8a77c4c4ef..2b4f67084b 100644 --- a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx +++ b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx @@ -1,6 +1,6 @@ import classNames from 'classnames'; import { BasicInfoWrapperProps } from './index.type'; -import { EmptyBox } from '@actiontech/dms-kit'; +import { BasicTypographyEllipsis, EmptyBox } from '@actiontech/dms-kit'; import { DataExportStatusDictionary } from '../index.data'; import { BasicInfoStyleWrapper } from './style'; const BasicInfoWrapper: React.FC = ({ @@ -77,7 +77,11 @@ const BasicInfoWrapper: React.FC = ({
{title}
-
{desc ?? '-'}
+ ); }; diff --git a/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap index b694a7e1c3..13041bc945 100644 --- a/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap @@ -1427,7 +1427,7 @@ exports[`first should match snapshot when pageState is equal SUBMIT_WORKFLOW 1`] test
desc
diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx index 913e10b16e..8729dcb7fb 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx @@ -5,12 +5,14 @@ import { Result } from 'antd'; import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; import { ApprovalProcessPreviewStyleWrapper } from './style'; +import { I18nKey } from '../../../../../../locale'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; interface ApprovalProcessPreviewProps { projectName: string; } -const stepTypeNameMap: Record = { +const stepTypeNameMap: Record = { export_review: 'dmsDataExport.create.approvalProcess.stepType.export_review', export_execute: 'dmsDataExport.create.approvalProcess.stepType.export_execute' }; @@ -29,7 +31,7 @@ const ApprovalProcessPreview: React.FC = ({ workflow .getWorkflowTemplateV1({ project_name: projectName, - workflow_type: 'data_export' + workflow_type: getWorkflowTemplateV1WorkflowTypeEnum.data_export }) .then((res) => res.data.data), { @@ -73,24 +75,20 @@ const ApprovalProcessPreview: React.FC = ({
- {templateData?.workflow_step_template_list?.map( - (step: IWorkFlowStepTemplateResV1, index: number) => ( -
-
-
{step.number ?? index + 1}
-
-
-
-
- {renderStepTypeName(step.type)} -
-
- {renderAssigneeInfo(step)} -
+ {templateData?.workflow_step_template_list?.map((step, index) => ( +
+
+
{step.number ?? index + 1}
+
+
+
+
+ {renderStepTypeName(step.type)}
+
{renderAssigneeInfo(step)}
- ) - )} +
+ ))}
diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap index b9998fae22..74c935ca0c 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap @@ -79,7 +79,7 @@ exports[`test base/DataExport/Create/SubmitWorkflow should match snapshot 1`] = test
desc
@@ -326,7 +326,7 @@ exports[`test base/DataExport/Create/SubmitWorkflow should match snapshot 2`] = test
desc
diff --git a/packages/base/src/page/DataExportManagement/Detail/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Detail/__tests__/__snapshots__/index.test.tsx.snap index 7ac2693b49..1d47de3e85 100644 --- a/packages/base/src/page/DataExportManagement/Detail/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Detail/__tests__/__snapshots__/index.test.tsx.snap @@ -212,7 +212,7 @@ exports[`test base/DataExport/Detail should match snapshot 1`] = ` mysql-1_20240130113114
desc
@@ -1154,7 +1154,7 @@ exports[`test base/DataExport/Detail should match snapshot 2`] = ` mysql-1_20240130113114
desc
@@ -3735,7 +3735,7 @@ exports[`test base/DataExport/Detail should match snapshot 3`] = ` mysql-1_20240130113114
desc
@@ -6316,7 +6316,7 @@ exports[`test base/DataExport/Detail should match snapshot 4`] = ` mysql-1_20240130113114
desc
@@ -8897,7 +8897,7 @@ exports[`test base/DataExport/Detail should match snapshot with reject workflow mysql-1_20240130113114
desc
diff --git a/packages/base/src/scripts/version.ts b/packages/base/src/scripts/version.ts index 6d5baaff06..1320f2f7e2 100644 --- a/packages/base/src/scripts/version.ts +++ b/packages/base/src/scripts/version.ts @@ -1 +1 @@ -export const UI_VERSION = 'sync/data-masking 417b194dd'; +export const UI_VERSION = 'dms-ui/feat-784 a717d17e4'; diff --git a/packages/shared/lib/api/sqle/service/common.d.ts b/packages/shared/lib/api/sqle/service/common.d.ts index 333f923789..581a17455f 100644 --- a/packages/shared/lib/api/sqle/service/common.d.ts +++ b/packages/shared/lib/api/sqle/service/common.d.ts @@ -98,6 +98,7 @@ import { WorkflowStepResV1StateEnum, WorkflowStepResV1TypeEnum, WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum, + WorkflowTemplateDetailResV1WorkflowTypeEnum, pipelineNodeBaseAuditMethodEnum, pipelineNodeBaseObjectTypeEnum, pipelineNodeBaseTypeEnum, @@ -133,6 +134,12 @@ export interface IBaseRes { message?: string; } +export interface IGlobalAccountListDataV2 { + accounts?: IGlobalAccountListItemV2[]; + + can_manage?: boolean; +} + export interface IGlobalAccountListItemV2 { account_name?: string; @@ -154,7 +161,7 @@ export interface IGlobalAccountListItemV2 { export interface IGlobalAccountListResV2 { code?: number; - data?: IGlobalAccountListItemV2[]; + data?: IGlobalAccountListDataV2; message?: string; @@ -2495,18 +2502,18 @@ export interface IGetWorkflowTasksResV1 { message?: string; } -export interface IGetWorkflowTemplateResV1 { +export interface IGetWorkflowTemplateListResV1 { code?: number; - data?: IWorkflowTemplateDetailResV1; + data?: IWorkflowTemplateDetailResV1[]; message?: string; } -export interface IGetWorkflowTemplateListResV1 { +export interface IGetWorkflowTemplateResV1 { code?: number; - data?: IWorkflowTemplateDetailResV1[]; + data?: IWorkflowTemplateDetailResV1; message?: string; } @@ -4466,7 +4473,7 @@ export interface IWorkflowTemplateDetailResV1 { workflow_template_name?: string; - workflow_type?: string; + workflow_type?: WorkflowTemplateDetailResV1WorkflowTypeEnum; } export interface ICreatePipelineResData { @@ -5108,6 +5115,8 @@ export interface IUploadInstanceAuditPlanSQLsReqV2 { } export interface IWorkflowRecordResV2 { + assignee_user_name_list?: string[]; + current_step_number?: number; executable?: boolean; diff --git a/packages/shared/lib/api/sqle/service/common.enum.ts b/packages/shared/lib/api/sqle/service/common.enum.ts index 92982bee6a..6f7e06436b 100644 --- a/packages/shared/lib/api/sqle/service/common.enum.ts +++ b/packages/shared/lib/api/sqle/service/common.enum.ts @@ -836,12 +836,6 @@ export enum WorkFlowStepTemplateReqV1TypeEnum { 'export_execute' = 'export_execute' } -export enum WorkflowTemplateTypeEnum { - 'workflow' = 'workflow', - - 'data_export' = 'data_export' -} - export enum WorkflowDetailResV1CurrentStepTypeEnum { 'sql_review' = 'sql_review', @@ -950,6 +944,12 @@ export enum WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum { 'error' = 'error' } +export enum WorkflowTemplateDetailResV1WorkflowTypeEnum { + 'workflow' = 'workflow', + + 'data_export' = 'data_export' +} + export enum pipelineNodeBaseAuditMethodEnum { 'offline' = 'offline', diff --git a/packages/shared/lib/api/sqle/service/workflow/index.d.ts b/packages/shared/lib/api/sqle/service/workflow/index.d.ts index 8883cbacab..10d9f54bd8 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.d.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.d.ts @@ -3,9 +3,9 @@ import { IGetWorkflowsResV1, IGlobalWorkflowStatisticsResV1, IGetWorkflowTemplateResV1, - IGetWorkflowTemplateListResV1, IUpdateWorkflowTemplateReqV1, IBaseRes, + IGetWorkflowTemplateListResV1, ICreateWorkflowReqV1, IAutoCreateAndExecuteWorkflowResV1, IBatchCancelWorkflowsReqV1, @@ -43,6 +43,8 @@ import { getGlobalWorkflowsV1FilterProjectPriorityEnum, GetGlobalWorkflowStatisticsFilterStatusListEnum, GetGlobalWorkflowStatisticsFilterProjectPriorityEnum, + getWorkflowTemplateV1WorkflowTypeEnum, + updateWorkflowTemplateV1WorkflowTypeEnum, getWorkflowsV1FilterStatusEnum, autoCreateAndExecuteWorkflowV1ExecModeEnum, exportWorkflowV1FilterStatusEnum, @@ -131,28 +133,28 @@ export interface IGetGlobalWorkflowStatisticsReturn export interface IGetWorkflowTemplateV1Params { project_name: string; - workflow_type?: string; + workflow_type: getWorkflowTemplateV1WorkflowTypeEnum; } export interface IGetWorkflowTemplateV1Return extends IGetWorkflowTemplateResV1 {} -export interface IGetWorkflowTemplateListV1Params { - project_name: string; -} - -export interface IGetWorkflowTemplateListV1Return - extends IGetWorkflowTemplateListResV1 {} - export interface IUpdateWorkflowTemplateV1Params extends IUpdateWorkflowTemplateReqV1 { project_name: string; - workflow_type?: string; + workflow_type: updateWorkflowTemplateV1WorkflowTypeEnum; } export interface IUpdateWorkflowTemplateV1Return extends IBaseRes {} +export interface IGetWorkflowTemplateListV1Params { + project_name: string; +} + +export interface IGetWorkflowTemplateListV1Return + extends IGetWorkflowTemplateListResV1 {} + export interface IGetWorkflowsV1Params { filter_subject?: string; diff --git a/packages/shared/lib/api/sqle/service/workflow/index.enum.ts b/packages/shared/lib/api/sqle/service/workflow/index.enum.ts index 6dd919cb8f..5b6b68c466 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.enum.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.enum.ts @@ -96,6 +96,18 @@ export enum GetGlobalWorkflowStatisticsFilterProjectPriorityEnum { 'low' = 'low' } +export enum getWorkflowTemplateV1WorkflowTypeEnum { + 'workflow' = 'workflow', + + 'data_export' = 'data_export' +} + +export enum updateWorkflowTemplateV1WorkflowTypeEnum { + 'workflow' = 'workflow', + + 'data_export' = 'data_export' +} + export enum getWorkflowsV1FilterStatusEnum { 'wait_for_audit' = 'wait_for_audit', diff --git a/packages/shared/lib/api/sqle/service/workflow/index.ts b/packages/shared/lib/api/sqle/service/workflow/index.ts index 2eed9af557..28d2f084e0 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.ts @@ -18,10 +18,10 @@ import { IGetGlobalWorkflowStatisticsReturn, IGetWorkflowTemplateV1Params, IGetWorkflowTemplateV1Return, - IGetWorkflowTemplateListV1Params, - IGetWorkflowTemplateListV1Return, IUpdateWorkflowTemplateV1Params, IUpdateWorkflowTemplateV1Return, + IGetWorkflowTemplateListV1Params, + IGetWorkflowTemplateListV1Return, IGetWorkflowsV1Params, IGetWorkflowsV1Return, ICreateWorkflowV1Params, @@ -168,36 +168,34 @@ class WorkflowService extends ServiceBase { ); } - public getWorkflowTemplateListV1( - params: IGetWorkflowTemplateListV1Params, + public updateWorkflowTemplateV1( + params: IUpdateWorkflowTemplateV1Params, options?: AxiosRequestConfig ) { const paramsData = this.cloneDeep(params); const project_name = paramsData.project_name; delete paramsData.project_name; - return this.get( - `/v1/projects/${project_name}/workflow_templates`, + const workflow_type = paramsData.workflow_type; + delete paramsData.workflow_type; + + return this.patch( + `/v1/projects/${project_name}/workflow_template/${workflow_type}/`, paramsData, options ); } - public updateWorkflowTemplateV1( - params: IUpdateWorkflowTemplateV1Params, + public getWorkflowTemplateListV1( + params: IGetWorkflowTemplateListV1Params, options?: AxiosRequestConfig ) { const paramsData = this.cloneDeep(params); const project_name = paramsData.project_name; delete paramsData.project_name; - const workflow_type = paramsData.workflow_type; - delete paramsData.workflow_type; - - const queryString = workflow_type ? `?workflow_type=${workflow_type}` : ''; - - return this.patch( - `/v1/projects/${project_name}/workflow_template${queryString}`, + return this.get( + `/v1/projects/${project_name}/workflow_templates`, paramsData, options ); diff --git a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts index dd1be11399..dea106eebc 100644 --- a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts +++ b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts @@ -1,5 +1,8 @@ import { IWorkflowTemplateDetailResV1 } from '../../../../api/sqle/service/common'; -import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '../../../../api/sqle/service/common.enum'; +import { + WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum, + WorkflowTemplateDetailResV1WorkflowTypeEnum +} from '../../../../api/sqle/service/common.enum'; export const workflowTemplateData = { allow_submit_when_less_audit_level: @@ -31,7 +34,7 @@ export const workflowTemplateData = { } ], workflow_template_name: '700300-WorkflowTemplate', - workflow_type: 'workflow' + workflow_type: WorkflowTemplateDetailResV1WorkflowTypeEnum.workflow }; export const dataExportWorkflowTemplateData: IWorkflowTemplateDetailResV1 = { @@ -54,7 +57,7 @@ export const dataExportWorkflowTemplateData: IWorkflowTemplateDetailResV1 = { } ], workflow_template_name: '700300-DataExportWorkflowTemplate', - workflow_type: 'data_export' + workflow_type: WorkflowTemplateDetailResV1WorkflowTypeEnum.data_export }; export const workflowTemplateListData = [ diff --git a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts index b01b013fa1..ca1a153c84 100644 --- a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts +++ b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts @@ -112,7 +112,7 @@ export default { rule: { descMessage: '步骤描述不能超过255个字符', userRequired: '最少需要添加一个指定人', - userMessage: '最多只能添加十个指定人' + userMessage: '最多只能添加{{max}}个指定人' } }, @@ -169,7 +169,7 @@ export default { '审核流程自工单发起开始,通过设置的审核步骤后,最后以执行上线结束;', rule2: '审核流程模板最多可设置4个审核步骤,也可不设置审核步骤;', rule3: - '单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加三个指定人。' + '单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加十个指定人。' }, exportRuler: { rule1: diff --git a/packages/sqle/src/page/SqlExecWorkflow/Create/hooks/useAllowAuditLevel.ts b/packages/sqle/src/page/SqlExecWorkflow/Create/hooks/useAllowAuditLevel.ts index 577ffef04d..71b11ebb9e 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Create/hooks/useAllowAuditLevel.ts +++ b/packages/sqle/src/page/SqlExecWorkflow/Create/hooks/useAllowAuditLevel.ts @@ -1,5 +1,6 @@ import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; import { useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -32,7 +33,8 @@ export const useAllowAuditLevel = () => { ) => { const request = (projectName: string) => { return workflow.getWorkflowTemplateV1({ - project_name: projectName + project_name: projectName, + workflow_type: getWorkflowTemplateV1WorkflowTypeEnum.workflow }); }; const tips: string[] = []; diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap index 11faf33143..db6f251891 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap @@ -20,7 +20,7 @@ exports[`page/WorkflowTemplate/UpdateWorkflowTemplate change workflow template n />
  • - 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加三个指定人。 + 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加十个指定人。
  • @@ -616,7 +616,7 @@ exports[`page/WorkflowTemplate/ReviewNodeInfo render normal review node info 1`] 审核流程模板最多可设置4个审核步骤,也可不设置审核步骤;
  • - 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加三个指定人。 + 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加十个指定人。
  • @@ -953,7 +953,7 @@ exports[`page/WorkflowTemplate/ReviewNodeInfo render review node and update revi 审核流程模板最多可设置4个审核步骤,也可不设置审核步骤;
  • - 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加三个指定人。 + 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加十个指定人。
  • @@ -1314,7 +1314,7 @@ exports[`page/WorkflowTemplate/ReviewNodeInfo render review node with default as 审核流程模板最多可设置4个审核步骤,也可不设置审核步骤;
  • - 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加三个指定人。 + 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加十个指定人。
  • @@ -1841,7 +1841,7 @@ exports[`page/WorkflowTemplate/ReviewNodeInfo validate assignee user number 1`] 审核流程模板最多可设置4个审核步骤,也可不设置审核步骤;
  • - 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加三个指定人。 + 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加十个指定人。
  • diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx index 586777d763..780eb3c183 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx @@ -200,7 +200,9 @@ const ReviewAndExecNodeInfo: React.FC = (props) => { return Promise.resolve(); } return Promise.reject( - t('workflowTemplate.form.rule.userMessage') + t('workflowTemplate.form.rule.userMessage', { + max: MAX_USER_COUNT + }) ); } } diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx index d7c04a287e..f8d700bd3b 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx @@ -33,7 +33,12 @@ import { useBoolean, useRequest } from 'ahooks'; import { useForm } from 'antd/es/form/Form'; import { WorkflowTemplateStyleWrapper } from '../WorkflowTemplateDetail/style'; import useUsername from '../../../hooks/useUsername'; -import { ROUTE_PATHS } from '@actiontech/dms-kit'; +import { ROUTE_PATHS, ResponseCode } from '@actiontech/dms-kit'; +import { + getWorkflowTemplateV1WorkflowTypeEnum, + updateWorkflowTemplateV1WorkflowTypeEnum +} from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; + const UpdateWorkflowTemplate: React.FC = () => { const { t } = useTranslation(); const [form] = useForm(); @@ -47,10 +52,10 @@ const UpdateWorkflowTemplate: React.FC = () => { const { projectName, projectID } = useCurrentProject(); const extractQueries = useTypedQuery(); const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.update); - const workflowType = searchParams?.workflowType || 'workflow'; + const workflowType = searchParams?.workflowType; const pageTitle = - workflowType === 'data_export' + workflowType === updateWorkflowTemplateV1WorkflowTypeEnum.data_export ? t('workflowTemplate.update.title.dataExport') : t('workflowTemplate.update.title.workflow'); @@ -97,14 +102,16 @@ const UpdateWorkflowTemplate: React.FC = () => { return workflow .updateWorkflowTemplateV1({ project_name: projectName, - workflow_type: workflowType, + workflow_type: workflowType as updateWorkflowTemplateV1WorkflowTypeEnum, workflow_step_template_list: templateList, allow_submit_when_less_audit_level: selectLevel as | UpdateWorkflowTemplateReqV1AllowSubmitWhenLessAuditLevelEnum | undefined }) .then((res) => { - setUpdateSuccess(true); + if (res.data.code === ResponseCode.SUCCESS) { + setUpdateSuccess(true); + } return res; }) .finally(() => submitFinish()); @@ -115,7 +122,7 @@ const UpdateWorkflowTemplate: React.FC = () => { workflow .getWorkflowTemplateV1({ project_name: projectName, - workflow_type: workflowType + workflow_type: workflowType as getWorkflowTemplateV1WorkflowTypeEnum }) .then((res) => { const temp = res.data.data; @@ -231,6 +238,8 @@ const UpdateWorkflowTemplate: React.FC = () => { execute_by_authorized: true, type: executeType }); + basicForm.resetFields(); + form.resetFields(); }; const handleExchangeReviewNode = (from: number, to: number) => { const temp = cloneDeep(reviewSteps); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap index 179121d5fd..8aca3e9b2e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap @@ -4,7 +4,7 @@ exports[`page/WorkflowTemplate CE render workflow template detail without edit a
    -
    diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap index 1a9631e0b6..e818811750 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap @@ -4,7 +4,7 @@ exports[`page/WorkflowTemplate/WorkflowTemplateDetail render workflow template d
    -
    diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx index 633ae6ef0e..8268a16d12 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx @@ -1,9 +1,9 @@ import { ActiontechTableColumn } from '@actiontech/dms-kit/es/components/ActiontechTable'; import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; -import { WorkflowTemplateTypeEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; import { BasicTag } from '@actiontech/dms-kit'; import { formatTime } from '@actiontech/dms-kit'; import { t, I18nKey } from '../../../locale'; +import { WorkflowTemplateDetailResV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; const stepTypeNameMap: Record = { sql_review: 'workflowTemplate.progressConfig.review.title', @@ -29,7 +29,10 @@ export const WorkflowTemplateListColumn = dataIndex: 'workflow_type', title: () => t('workflowTemplate.list.table.applicableType'), render: (workflowType) => { - if (workflowType === WorkflowTemplateTypeEnum.data_export) { + if ( + workflowType === + WorkflowTemplateDetailResV1WorkflowTypeEnum.data_export + ) { return ( {t('workflowTemplate.list.type.dataExport')} diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx index e63a9ff08a..9548b01fd6 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx @@ -17,6 +17,9 @@ import WorkflowTemplateAuthInfo from './components/WorkflowTemplateAuthInfo'; import { WorkflowTemplateStyleWrapper } from './style'; import useUsername from '../../../hooks/useUsername'; import { EditOutlined } from '@ant-design/icons'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; + +type WorkflowTemplateDetailTab = 'workflow' | 'data_export'; const WorkflowTemplateDetail: React.FC = () => { const { t } = useTranslation(); @@ -25,7 +28,8 @@ const WorkflowTemplateDetail: React.FC = () => { const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.index); const initialTab = searchParams?.activeTab === 'data_export' ? 'data_export' : 'workflow'; - const [activeTab, setActiveTab] = useState(initialTab); + const [activeTab, setActiveTab] = + useState(initialTab); const { updateUsernameList, @@ -55,7 +59,7 @@ const WorkflowTemplateDetail: React.FC = () => { workflow .getWorkflowTemplateV1({ project_name: projectName, - workflow_type: 'workflow' + workflow_type: getWorkflowTemplateV1WorkflowTypeEnum.workflow }) .then((res) => { const stepList = res.data.data?.workflow_step_template_list ?? []; @@ -92,7 +96,7 @@ const WorkflowTemplateDetail: React.FC = () => { workflow .getWorkflowTemplateV1({ project_name: projectName, - workflow_type: 'data_export' + workflow_type: getWorkflowTemplateV1WorkflowTypeEnum.data_export }) .then((res) => { const stepList = res.data.data?.workflow_step_template_list ?? []; @@ -114,8 +118,7 @@ const WorkflowTemplateDetail: React.FC = () => { ); const renderEditButton = useCallback( - (workflowType: string, templateName?: string) => { - // #if [ee] + (workflowType: WorkflowTemplateDetailTab, templateName?: string) => { return ( { /> ); - // #endif - return null; }, [t, projectID] ); @@ -151,18 +152,6 @@ const WorkflowTemplateDetail: React.FC = () => { label: t('workflowTemplate.list.type.workflow'), children: ( -
    - {renderEditButton( - 'workflow', - workflowTemplate?.workflow_template_name - )} -
    { label: t('workflowTemplate.list.type.dataExport'), children: ( -
    - {renderEditButton( - 'data_export', - exportTemplate?.workflow_template_name - )} -
    { exportExecStep, usernameList, workflowTemplate, - exportTemplate, - renderEditButton + exportTemplate ] ); @@ -241,6 +217,15 @@ const WorkflowTemplateDetail: React.FC = () => { activeKey={activeTab} onChange={setActiveTab} items={tabItems} + // #if [ee] + segmentedRowClassName="flex-space-between" + segmentedRowExtraContent={renderEditButton( + activeTab, + activeTab === 'workflow' + ? workflowTemplate?.workflow_template_name + : exportTemplate?.workflow_template_name + )} + // #endif /> ); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts index 915f047a9a..6682b568f6 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts @@ -3,10 +3,6 @@ import { styled } from '@mui/material/styles'; export const WorkflowTemplateStyleWrapper = styled('div')` height: 100%; - .segmented-tabs-wrapper { - padding: 0 40px; - } - .workflow-template-wrapper { height: 100%; } @@ -17,3 +13,7 @@ export const WorkflowTemplateStyleWrapper = styled('div')` height: auto; } `; + +export const WorkflowTemplateStepInfoWrapper = styled('div')` + height: 100%; +`; From 9df4ddaf04845a276523b3d16fa157365ed57296 Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Mon, 27 Apr 2026 13:14:33 +0800 Subject: [PATCH 15/16] chore: restore version.ts --- packages/base/src/scripts/version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/base/src/scripts/version.ts b/packages/base/src/scripts/version.ts index 1320f2f7e2..6d5baaff06 100644 --- a/packages/base/src/scripts/version.ts +++ b/packages/base/src/scripts/version.ts @@ -1 +1 @@ -export const UI_VERSION = 'dms-ui/feat-784 a717d17e4'; +export const UI_VERSION = 'sync/data-masking 417b194dd'; From 6e5f2e6561dd8d43dae08ece16d2e33e60421243 Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Mon, 27 Apr 2026 15:22:44 +0800 Subject: [PATCH 16/16] fix: code review --- .../__snapshots__/index.test.tsx.snap | 6 +- .../__tests__/index.test.tsx | 45 ++++++-------- .../ApprovalProcessPreview/index.data.ts | 10 +++ .../ApprovalProcessPreview/index.tsx | 31 ++++------ .../ApprovalProcessPreview/style.ts | 2 +- .../WorkflowRecordInfo/WorkflowSteps.tsx | 8 +-- .../WorkflowRecordInfo/index.type.ts | 5 ++ .../components/BasicInfo/index.tsx | 5 +- .../components/BasicInfo/index.type.ts | 3 +- .../components/ReviewNodeInfo/index.tsx | 4 +- .../components/ReviewNodeInfo/index.type.ts | 3 +- .../UpdateWorkflowTemplate/index.tsx | 29 +++++++-- .../WorkflowTemplateDetail/actions.tsx | 56 +++++++++++------ .../WorkflowTemplateDetail/column.tsx | 16 ++--- .../WorkflowTemplateDetail/index.ce.test.tsx | 1 + .../WorkflowTemplateDetail/index.test.tsx | 1 + .../WorkflowTemplateDetail/index.tsx | 61 ++++++++----------- .../WorkflowTemplateDetail/style.ts | 4 -- .../components/StepCard/stepInfo.tsx | 12 ++-- 19 files changed, 168 insertions(+), 134 deletions(-) create mode 100644 packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.data.ts diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap index 3ee435a6b3..2822c8ca42 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap @@ -4,7 +4,7 @@ exports[`base/DataExport/Create/ApprovalProcessPreview should render fallback er
    { + let mockGetWorkflowTemplateApi: jest.SpyInstance; beforeEach(() => { jest.useFakeTimers(); + mockGetWorkflowTemplateApi = MockWorkflowTemplateApi.getWorkflowTemplate(); }); afterEach(() => { @@ -26,28 +29,20 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { }; it('should render loading state', () => { - jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation( - () => - new Promise(() => { - /* never resolves to keep loading */ - }) - ); const { baseElement } = customRender(); expect(baseElement).toMatchSnapshot(); }); it('should render step list when data loaded successfully', async () => { - const getTemplateSpy = jest - .spyOn(workflow, 'getWorkflowTemplateV1') - .mockImplementation(() => - createSpySuccessResponse({ - data: cloneDeep(dataExportWorkflowTemplateData) - }) - ); + mockGetWorkflowTemplateApi.mockImplementation(() => + createSpySuccessResponse({ + data: cloneDeep(dataExportWorkflowTemplateData) + }) + ); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); - expect(getTemplateSpy).toHaveBeenCalledWith({ + expect(mockGetWorkflowTemplateApi).toHaveBeenCalledWith({ project_name: 'test-project', workflow_type: 'data_export' }); @@ -59,9 +54,9 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { }); it('should render fallback error state when request fails', async () => { - jest - .spyOn(workflow, 'getWorkflowTemplateV1') - .mockImplementation(() => createSpyErrorResponse({})); + mockGetWorkflowTemplateApi.mockImplementation(() => + createSpyErrorResponse({}) + ); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); @@ -87,9 +82,9 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { type: 'export_execute' } ]; - jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation(() => + mockGetWorkflowTemplateApi.mockImplementation(() => createSpySuccessResponse({ - data: multiStepData + data: cloneDeep(multiStepData) }) ); customRender(); @@ -110,9 +105,9 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { type: 'export_review' } ]; - jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation(() => + mockGetWorkflowTemplateApi.mockImplementation(() => createSpySuccessResponse({ - data: customData + data: cloneDeep(customData) }) ); customRender(); @@ -122,10 +117,10 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { }); it('should not make API call when projectName is empty', () => { - const getTemplateSpy = jest - .spyOn(workflow, 'getWorkflowTemplateV1') - .mockImplementation(() => createSpySuccessResponse({ data: {} })); + mockGetWorkflowTemplateApi.mockImplementation(() => + createSpySuccessResponse({ data: {} }) + ); customRender(''); - expect(getTemplateSpy).not.toHaveBeenCalled(); + expect(mockGetWorkflowTemplateApi).not.toHaveBeenCalled(); }); }); diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.data.ts b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.data.ts new file mode 100644 index 0000000000..3783869ad3 --- /dev/null +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.data.ts @@ -0,0 +1,10 @@ +import { t } from '../../../../../../locale'; + +export const stepTypeNameMap: Record = { + export_review: t( + 'dmsDataExport.create.approvalProcess.stepType.export_review' + ), + export_execute: t( + 'dmsDataExport.create.approvalProcess.stepType.export_execute' + ) +}; diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx index 8729dcb7fb..1790abec1f 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx @@ -2,21 +2,16 @@ import { useTranslation } from 'react-i18next'; import { useRequest } from 'ahooks'; import { Spin } from 'antd'; import { Result } from 'antd'; -import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; import { ApprovalProcessPreviewStyleWrapper } from './style'; -import { I18nKey } from '../../../../../../locale'; import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; +import { stepTypeNameMap } from './index.data'; +import { SqleApi } from '@actiontech/shared/lib/api'; interface ApprovalProcessPreviewProps { projectName: string; } -const stepTypeNameMap: Record = { - export_review: 'dmsDataExport.create.approvalProcess.stepType.export_review', - export_execute: 'dmsDataExport.create.approvalProcess.stepType.export_execute' -}; - const ApprovalProcessPreview: React.FC = ({ projectName }) => { @@ -28,14 +23,14 @@ const ApprovalProcessPreview: React.FC = ({ error } = useRequest( () => - workflow - .getWorkflowTemplateV1({ - project_name: projectName, - workflow_type: getWorkflowTemplateV1WorkflowTypeEnum.data_export - }) - .then((res) => res.data.data), + SqleApi.WorkflowService.getWorkflowTemplateV1({ + project_name: projectName, + workflow_type: getWorkflowTemplateV1WorkflowTypeEnum.data_export + }).then((res) => res.data.data), { - ready: !!projectName + ready: !!projectName, + // eslint-disable-next-line @typescript-eslint/no-empty-function + onError: () => {} } ); @@ -50,10 +45,10 @@ const ApprovalProcessPreview: React.FC = ({ }; const renderStepTypeName = (type?: string) => { - if (type && stepTypeNameMap[type]) { - return t(stepTypeNameMap[type]); + if (type) { + return stepTypeNameMap[type] ?? '-'; } - return type ?? '-'; + return '-'; }; if (error) { @@ -78,7 +73,7 @@ const ApprovalProcessPreview: React.FC = ({ {templateData?.workflow_step_template_list?.map((step, index) => (
    -
    {step.number ?? index + 1}
    +
    {step.number}
    diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts index 52b6645edf..53aa909904 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts @@ -47,7 +47,7 @@ export const ApprovalProcessPreviewStyleWrapper = styled('div')` height: 24px; border-radius: 50%; background: ${({ theme }) => theme.sharedTheme.uiToken.colorPrimary}; - color: #fff; + color: ${({ theme }) => theme.sharedTheme.basic.colorWhite}; font-size: 12px; font-weight: 600; display: flex; diff --git a/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx b/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx index e6f436ea93..fb6ed26d02 100644 --- a/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx +++ b/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx @@ -1,6 +1,6 @@ import { Divider, StepProps } from 'antd'; import { useTranslation } from 'react-i18next'; -import { WorkflowStepsProps } from './index.type'; +import { WorkflowStep, WorkflowStepsProps } from './index.type'; import { useCallback, useMemo } from 'react'; import { CustomSteps, WorkflowStepsItemStyleWrapper } from './style'; import { Space } from 'antd'; @@ -151,7 +151,7 @@ const WorkflowSteps: React.FC = ({ ] ); const renderOrderStepsItem = useCallback( - (title: string, step: any) => { + (title: string, step: WorkflowStep) => { return (
    {title}
    @@ -163,7 +163,7 @@ const WorkflowSteps: React.FC = ({ [renderOrderStepsItemContent] ); const renderOrderStepsItemIcon = useCallback( - (type?: string, step?: any) => { + (type?: string, step?: WorkflowStep) => { if (type === 'create') { return ; } @@ -203,7 +203,7 @@ const WorkflowSteps: React.FC = ({ } // Build dynamic steps: create + N approval nodes + execute - const allSteps: any[] = [ + const allSteps: WorkflowStep[] = [ { type: 'create', number: 1, diff --git a/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/index.type.ts b/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/index.type.ts index b586ed0304..c5212372ce 100644 --- a/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/index.type.ts +++ b/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/index.type.ts @@ -23,3 +23,8 @@ export type WorkflowStepsProps = { export type WorkflowHistoryStepsProps = { recordHistoryList?: IWorkflowRecord[]; }; + +export type WorkflowStep = { + type: 'create' | 'approve' | 'execute'; + number: number; +} & IWorkflowStep; diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx index df97d96e7f..39ebf182e4 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx @@ -7,11 +7,14 @@ import { BaseFormProps } from './index.type'; import useStaticStatus from '../../../../../hooks/useStaticStatus'; import StepButton from '../StepButton'; import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; + const BasicInfo: React.FC = (props) => { const { t } = useTranslation(); const { form, workflowType } = props; const { getAuditLevelStatusSelectOption } = useStaticStatus(); - const isDataExport = workflowType === 'data_export'; + const isDataExport = + workflowType === getWorkflowTemplateV1WorkflowTypeEnum.data_export; const nextStep = async () => { const value = await form.validateFields(); props.updateBaseInfo(value?.allowSubmitWhenLessAuditLevel); diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.type.ts b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.type.ts index e494757a21..02b134c709 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.type.ts +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.type.ts @@ -1,5 +1,6 @@ import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; import { FormInstance } from 'antd'; export type BaseFormProps = { @@ -10,7 +11,7 @@ export type BaseFormProps = { info: BaseFormFields['allowSubmitWhenLessAuditLevel'] ) => void; totalStep: number; - workflowType?: string; + workflowType?: getWorkflowTemplateV1WorkflowTypeEnum; }; export type BaseFormFields = { diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx index 780eb3c183..e54441456e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx @@ -15,12 +15,14 @@ import { import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; import StepButton from '../StepButton'; import { InfoCircleOutlined } from '@ant-design/icons'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; const MAX_USER_COUNT = 10; const ReviewAndExecNodeInfo: React.FC = (props) => { const { t } = useTranslation(); - const isDataExport = props.workflowType === 'data_export'; + const isDataExport = + props.workflowType === getWorkflowTemplateV1WorkflowTypeEnum.data_export; const [authorizedParam, setAuthorizedParam] = useState( props.type === NodeTypeEnum.review ? 'approved_by_authorized' diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts index 6eb21c3662..18c67ebc1a 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts @@ -1,4 +1,5 @@ import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; import { FormInstance } from 'antd'; export enum NodeTypeEnum { @@ -29,5 +30,5 @@ export type ReviewAndExecNodeInfoProps = { updateReviewAndExecNodeInfo: (data: IWorkFlowStepTemplateResV1) => void; generateUsernameSelectOption: () => React.ReactNode; getUsernameListLoading: boolean; - workflowType?: string; + workflowType?: getWorkflowTemplateV1WorkflowTypeEnum; }; diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx index f8d700bd3b..5b2edc2a34 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx @@ -6,7 +6,7 @@ import { } from '@actiontech/shared'; import { ArrowLeftOutlined } from '@ant-design/icons'; import { Col, Row, Space, Spin } from 'antd'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import BasicInfo from './components/BasicInfo'; import StepInfo from './components/StepInfo'; @@ -51,11 +51,29 @@ const UpdateWorkflowTemplate: React.FC = () => { const urlParams = useTypedParams(); const { projectName, projectID } = useCurrentProject(); const extractQueries = useTypedQuery(); - const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.update); - const workflowType = searchParams?.workflowType; + const [workflowType, setWorkflowType] = useState< + getWorkflowTemplateV1WorkflowTypeEnum | undefined + >(undefined); + + useEffect(() => { + const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.update); + const isWorkflowType = ( + value: string + ): value is getWorkflowTemplateV1WorkflowTypeEnum => { + return Object.values(getWorkflowTemplateV1WorkflowTypeEnum).includes( + value as getWorkflowTemplateV1WorkflowTypeEnum + ); + }; + if ( + searchParams?.workflowType && + isWorkflowType(searchParams.workflowType) + ) { + setWorkflowType(searchParams.workflowType); + } + }, [extractQueries]); const pageTitle = - workflowType === updateWorkflowTemplateV1WorkflowTypeEnum.data_export + workflowType === getWorkflowTemplateV1WorkflowTypeEnum.data_export ? t('workflowTemplate.update.title.dataExport') : t('workflowTemplate.update.title.workflow'); @@ -102,7 +120,8 @@ const UpdateWorkflowTemplate: React.FC = () => { return workflow .updateWorkflowTemplateV1({ project_name: projectName, - workflow_type: workflowType as updateWorkflowTemplateV1WorkflowTypeEnum, + workflow_type: + workflowType as unknown as updateWorkflowTemplateV1WorkflowTypeEnum, workflow_step_template_list: templateList, allow_submit_when_less_audit_level: selectLevel as | UpdateWorkflowTemplateReqV1AllowSubmitWhenLessAuditLevelEnum diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx index ef92f7b9ab..4e61248dde 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx @@ -1,23 +1,39 @@ -import { t } from '../../../locale'; +import { ROUTE_PATHS } from '@actiontech/dms-kit'; import { - ActiontechTableActionsWithPermissions, - PERMISSIONS + PERMISSIONS, + PermissionControl } from '@actiontech/shared/lib/features'; -import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; +import { EditOutlined } from '@ant-design/icons'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; +import { ActionButton } from '@actiontech/shared'; +import { t } from '../../../locale'; -export const WorkflowTemplateTableActions: ( - onEdit: (record: IWorkflowTemplateDetailResV1) => void -) => ActiontechTableActionsWithPermissions = ( - onEdit -) => ({ - buttons: [ - { - key: 'edit-workflow-template', - text: t('common.edit'), - buttonProps: (record) => ({ - onClick: () => onEdit(record ?? {}) - }), - permissions: PERMISSIONS.ACTIONS.SQLE.WORKFLOW_TEMPLATE.UPDATE - } - ] -}); +export const workflowTemplateDetailAction = (params: { + projectID: string; + templateName?: string; + workflowType: getWorkflowTemplateV1WorkflowTypeEnum; +}) => { + const { projectID, templateName, workflowType } = params; + return ( + + } + text={t('workflowTemplate.detail.updateTemplate')} + actionType="navigate-link" + link={{ + to: ROUTE_PATHS.SQLE.PROGRESS.update, + params: { + projectID, + workflowName: templateName ?? '' + }, + queries: { + workflowType + } + }} + /> + + ); +}; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx index 8268a16d12..6b1f6e21f6 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx @@ -2,20 +2,20 @@ import { ActiontechTableColumn } from '@actiontech/dms-kit/es/components/Actiont import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; import { BasicTag } from '@actiontech/dms-kit'; import { formatTime } from '@actiontech/dms-kit'; -import { t, I18nKey } from '../../../locale'; +import { t } from '../../../locale'; import { WorkflowTemplateDetailResV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; -const stepTypeNameMap: Record = { - sql_review: 'workflowTemplate.progressConfig.review.title', - sql_execute: 'workflowTemplate.progressConfig.exec.title', - export_review: 'workflowTemplate.progressConfig.exportReview.title', - export_execute: 'workflowTemplate.progressConfig.exportExecute.title' +const stepTypeNameMap: Record = { + sql_review: t('workflowTemplate.progressConfig.review.title'), + sql_execute: t('workflowTemplate.progressConfig.exec.title'), + export_review: t('workflowTemplate.progressConfig.exportReview.title'), + export_execute: t('workflowTemplate.progressConfig.exportExecute.title') }; const getStepTypeName = (stepType?: string): string => { if (!stepType) return '-'; - const i18nKey = stepTypeNameMap[stepType]; - return i18nKey ? t(i18nKey) : stepType; + const name = stepTypeNameMap[stepType]; + return name ? name : stepType; }; export const WorkflowTemplateListColumn = diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx index 1991994caa..35d69a2c0e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx @@ -50,5 +50,6 @@ describe('page/WorkflowTemplate CE', () => { expect(getTemplateRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); expect(screen.getByText('审批流程模板')).toBeInTheDocument(); + expect(screen.queryByText('修改当前审批流程模板')).not.toBeInTheDocument(); }); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx index 5f9d3f3f7f..2c017746f9 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx @@ -40,6 +40,7 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { expect(getTemplateRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); expect(screen.getByText('审批流程模板')).toBeInTheDocument(); + expect(screen.queryByText('修改当前审批流程模板')).toBeInTheDocument(); }); it('render segmented tab labels correctly', async () => { diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx index 9548b01fd6..40885f6891 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx @@ -3,12 +3,8 @@ import { useRequest } from 'ahooks'; import { useTranslation } from 'react-i18next'; import { Col, Row, Spin } from 'antd'; import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; -import { - useCurrentProject, - PERMISSIONS, - PermissionControl -} from '@actiontech/shared/lib/features'; -import { ActionButton, useTypedQuery } from '@actiontech/shared'; +import { useCurrentProject } from '@actiontech/shared/lib/features'; +import { useTypedQuery } from '@actiontech/shared'; import { ROUTE_PATHS } from '@actiontech/dms-kit'; import { PageHeader, SegmentedTabs } from '@actiontech/dms-kit'; import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; @@ -16,20 +12,25 @@ import WorkflowTemplateStepInfo from './components/WorkflowTemplateStepInfo'; import WorkflowTemplateAuthInfo from './components/WorkflowTemplateAuthInfo'; import { WorkflowTemplateStyleWrapper } from './style'; import useUsername from '../../../hooks/useUsername'; -import { EditOutlined } from '@ant-design/icons'; import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; - -type WorkflowTemplateDetailTab = 'workflow' | 'data_export'; +import { workflowTemplateDetailAction } from './actions'; const WorkflowTemplateDetail: React.FC = () => { const { t } = useTranslation(); const { projectName, projectID } = useCurrentProject(); const extractQueries = useTypedQuery(); const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.index); - const initialTab = - searchParams?.activeTab === 'data_export' ? 'data_export' : 'workflow'; + const [activeTab, setActiveTab] = - useState(initialTab); + useState(() => { + if ( + searchParams?.activeTab === + getWorkflowTemplateV1WorkflowTypeEnum.data_export + ) { + return getWorkflowTemplateV1WorkflowTypeEnum.data_export; + } + return getWorkflowTemplateV1WorkflowTypeEnum.workflow; + }); const { updateUsernameList, @@ -118,31 +119,17 @@ const WorkflowTemplateDetail: React.FC = () => { ); const renderEditButton = useCallback( - (workflowType: WorkflowTemplateDetailTab, templateName?: string) => { - return ( - - } - text={t('workflowTemplate.detail.updateTemplate')} - actionType="navigate-link" - link={{ - to: ROUTE_PATHS.SQLE.PROGRESS.update, - params: { - projectID, - workflowName: templateName ?? '' - }, - queries: { - workflowType - } - }} - /> - - ); + ( + workflowType: getWorkflowTemplateV1WorkflowTypeEnum, + templateName?: string + ) => { + return workflowTemplateDetailAction({ + projectID, + templateName: templateName, + workflowType + }); }, - [t, projectID] + [projectID] ); const tabItems = useMemo( @@ -221,7 +208,7 @@ const WorkflowTemplateDetail: React.FC = () => { segmentedRowClassName="flex-space-between" segmentedRowExtraContent={renderEditButton( activeTab, - activeTab === 'workflow' + activeTab === getWorkflowTemplateV1WorkflowTypeEnum.workflow ? workflowTemplate?.workflow_template_name : exportTemplate?.workflow_template_name )} diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts index 6682b568f6..392f85f8bd 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts @@ -13,7 +13,3 @@ export const WorkflowTemplateStyleWrapper = styled('div')` height: auto; } `; - -export const WorkflowTemplateStepInfoWrapper = styled('div')` - height: 100%; -`; diff --git a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx index 236aa8725e..135dd135e6 100644 --- a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx @@ -67,11 +67,13 @@ const renderReviewUser = ( height={18} /> - {t( - isDataExport - ? 'workflowTemplate.progressConfig.exportExec.executeUserType.matchExecute' - : 'workflowTemplate.progressConfig.exec.executeUserType.matchExecute' - )} + {isDataExport + ? t( + 'workflowTemplate.progressConfig.exportExec.executeUserType.matchExecute' + ) + : t( + 'workflowTemplate.progressConfig.exec.executeUserType.matchExecute' + )} );