From ba4c7beab68cb8f2b8b434ad8dde2a21d19a2d01 Mon Sep 17 00:00:00 2001 From: zzyangh <799463087@qq.com> Date: Fri, 9 Aug 2024 13:24:58 +0800 Subject: [PATCH 1/4] [chore]: Update Api --- .../shared/lib/api/sqle/service/common.d.ts | 4 ++++ .../lib/api/sqle/service/workflow/index.d.ts | 14 +++++++------ .../lib/api/sqle/service/workflow/index.ts | 21 +++++++++++-------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/packages/shared/lib/api/sqle/service/common.d.ts b/packages/shared/lib/api/sqle/service/common.d.ts index ae3d55678..e3e231897 100644 --- a/packages/shared/lib/api/sqle/service/common.d.ts +++ b/packages/shared/lib/api/sqle/service/common.d.ts @@ -291,8 +291,12 @@ export interface IAuditTaskResV1 { exec_end_time?: string; + exec_mode?: string; + exec_start_time?: string; + file_order_method?: string; + instance_db_type?: string; instance_name?: string; 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 47f3b08e6..49e3ef045 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.d.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.d.ts @@ -127,12 +127,6 @@ export interface IExportWorkflowV1Params { fuzzy_keyword?: string; } -export interface IGetWorkflowAttachmentParams { - project_name: string; - - workflow_id: string; -} - export interface ITerminateMultipleTaskByWorkflowV1Params { workflow_id: string; @@ -141,6 +135,14 @@ export interface ITerminateMultipleTaskByWorkflowV1Params { export interface ITerminateMultipleTaskByWorkflowV1Return extends IBaseRes {} +export interface IGetWorkflowAttachmentParams { + project_name: string; + + workflow_id: string; + + task_id: string; +} + export interface ITerminateSingleTaskByWorkflowV1Params { workflow_id: string; diff --git a/packages/shared/lib/api/sqle/service/workflow/index.ts b/packages/shared/lib/api/sqle/service/workflow/index.ts index 1df250d73..68cef7bb4 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.ts @@ -21,9 +21,9 @@ import { IBatchCompleteWorkflowsV1Params, IBatchCompleteWorkflowsV1Return, IExportWorkflowV1Params, - IGetWorkflowAttachmentParams, ITerminateMultipleTaskByWorkflowV1Params, ITerminateMultipleTaskByWorkflowV1Return, + IGetWorkflowAttachmentParams, ITerminateSingleTaskByWorkflowV1Params, ITerminateSingleTaskByWorkflowV1Return, IGetWorkflowV1Params, @@ -188,8 +188,8 @@ class WorkflowService extends ServiceBase { ); } - public getWorkflowAttachment( - params: IGetWorkflowAttachmentParams, + public terminateMultipleTaskByWorkflowV1( + params: ITerminateMultipleTaskByWorkflowV1Params, options?: AxiosRequestConfig ) { const paramsData = this.cloneDeep(params); @@ -199,15 +199,15 @@ class WorkflowService extends ServiceBase { const workflow_id = paramsData.workflow_id; delete paramsData.workflow_id; - return this.get( - `/v1/projects/${project_name}/workflows/${workflow_id}/attachment`, + return this.post( + `/v1/projects/${project_name}/workflows/${workflow_id}/tasks/terminate`, paramsData, options ); } - public terminateMultipleTaskByWorkflowV1( - params: ITerminateMultipleTaskByWorkflowV1Params, + public getWorkflowAttachment( + params: IGetWorkflowAttachmentParams, options?: AxiosRequestConfig ) { const paramsData = this.cloneDeep(params); @@ -217,8 +217,11 @@ class WorkflowService extends ServiceBase { const workflow_id = paramsData.workflow_id; delete paramsData.workflow_id; - return this.post( - `/v1/projects/${project_name}/workflows/${workflow_id}/tasks/terminate`, + const task_id = paramsData.task_id; + delete paramsData.task_id; + + return this.get( + `/v1/projects/${project_name}/workflows/${workflow_id}/tasks/${task_id}/attachment`, paramsData, options ); From ba0e4d1e8016c0afd0f1457007c283a2c4aff65b Mon Sep 17 00:00:00 2001 From: zzyangh <799463087@qq.com> Date: Fri, 9 Aug 2024 13:36:08 +0800 Subject: [PATCH 2/4] [feature](SqlExecWorkflow): Add the function of execute on other instances --- .../shared/lib/api/common/ApiBase/index.ts | 7 +- packages/shared/lib/utils/Common.ts | 4 + .../sqle/src/locale/zh-CN/execWorkflow.ts | 7 +- .../components/SqlExecModeSelector.tsx | 9 +- .../src/page/SqlExecWorkflow/Common/data.ts | 1 + .../BaseInfoForm/BaseInfoFormItem.tsx | 104 +++++---- .../FormStep/BaseInfoForm/index.tsx | 7 +- .../hooks/useRenderDatabaseSelectionItems.tsx | 29 ++- .../SqlAuditInfoFormItem/index.tsx | 213 +++++++++--------- .../FormStep/SqlAuditInfoForm/index.tsx | 25 +- .../Create/components/FormStep/index.tsx | 34 ++- .../Create/hooks/useCreationMode.ts | 18 ++ .../src/page/SqlExecWorkflow/Create/index.tsx | 38 +++- .../components/AuditExecResultPanel/index.tsx | 3 +- .../hooks/useWorkflowDetailAction.tsx | 22 +- .../components/PageHeaderExtra/index.tsx | 29 ++- .../components/PageHeaderExtra/index.type.ts | 1 + .../Detail/hooks/useCloneExecWorkflowInfo.ts | 202 +++++++++++++++++ .../hooks/useGenerateWorkflowStepsProps.ts | 19 +- .../src/page/SqlExecWorkflow/Detail/index.tsx | 8 +- packages/sqle/src/store/index.ts | 4 +- .../sqle/src/store/sqlExecWorkflow/index.ts | 39 ++++ 22 files changed, 632 insertions(+), 191 deletions(-) create mode 100644 packages/sqle/src/page/SqlExecWorkflow/Common/data.ts create mode 100644 packages/sqle/src/page/SqlExecWorkflow/Create/hooks/useCreationMode.ts create mode 100644 packages/sqle/src/page/SqlExecWorkflow/Detail/hooks/useCloneExecWorkflowInfo.ts create mode 100644 packages/sqle/src/store/sqlExecWorkflow/index.ts diff --git a/packages/shared/lib/api/common/ApiBase/index.ts b/packages/shared/lib/api/common/ApiBase/index.ts index 32532c02e..389059ee0 100644 --- a/packages/shared/lib/api/common/ApiBase/index.ts +++ b/packages/shared/lib/api/common/ApiBase/index.ts @@ -6,7 +6,8 @@ import store from '../../../../../base/src/store'; import { getResponseErrorMessage, getResponseCode, - isExportFileResponse + isExportFileResponse, + isFileStreamResponse } from '../../../utils/Common'; import { eventEmitter } from '../../../utils/EventEmitter'; import { NotificationInstanceKeyType } from '../../../hooks/useNotificationContext'; @@ -34,7 +35,9 @@ class ApiBase { Download.downloadByCreateElementA(res.data, filename); return res; } else if ( - (res.status === 200 && code !== ResponseCode.SUCCESS) || + (res.status === 200 && + code !== ResponseCode.SUCCESS && + !isFileStreamResponse(res)) || res.status !== 200 ) { const message = await getResponseErrorMessage(res); diff --git a/packages/shared/lib/utils/Common.ts b/packages/shared/lib/utils/Common.ts index d84a9cc6b..6c69b2018 100644 --- a/packages/shared/lib/utils/Common.ts +++ b/packages/shared/lib/utils/Common.ts @@ -138,6 +138,10 @@ export const isExportFileResponse = (res: AxiosResponse): boolean => { return res.headers?.['content-disposition']?.includes('attachment') ?? false; }; +export const isFileStreamResponse = (res: AxiosResponse): boolean => { + return res.headers?.['content-disposition']?.includes('inline') ?? false; +}; + export const jsonParse = (str: string, defaultVal: any = {}): T => { let val: any; try { diff --git a/packages/sqle/src/locale/zh-CN/execWorkflow.ts b/packages/sqle/src/locale/zh-CN/execWorkflow.ts index f31a1fcca..adfa3cfac 100644 --- a/packages/sqle/src/locale/zh-CN/execWorkflow.ts +++ b/packages/sqle/src/locale/zh-CN/execWorkflow.ts @@ -103,6 +103,10 @@ export default { executeSqlMode: 'SQL模式', executeFileMode: '文件模式', selectFileSortMethod: '选择文件排序方式' + }, + tour: { + modifyName: '修改工单名称', + modifyDataSource: '修改数据源' } }, @@ -201,7 +205,8 @@ export default { stepNumberIsUndefined: '当前节点的步骤数未定义!', closeWorkflow: '关闭工单', closeConfirm: '您确认关闭当前工单?', - closeWorkflowSuccessTips: '工单关闭成功' + closeWorkflowSuccessTips: '工单关闭成功', + cloneExecWorkflow: '上线到其他实例' }, paginationDisplay: '分页展示', diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/components/SqlExecModeSelector.tsx b/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/components/SqlExecModeSelector.tsx index 7020efdf2..aa629e910 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/components/SqlExecModeSelector.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/components/SqlExecModeSelector.tsx @@ -35,10 +35,11 @@ const SqlExecModeSelector: React.FC = ({ const disabledSqlFileExecMode = !isSupportFileModeExecuteSql || - ![ - AuditTaskResV1SqlSourceEnum.sql_file, - AuditTaskResV1SqlSourceEnum.zip_file - ].includes(currentSqlUploadType); + (!!currentSqlUploadType && + ![ + AuditTaskResV1SqlSourceEnum.sql_file, + AuditTaskResV1SqlSourceEnum.zip_file + ].includes(currentSqlUploadType)); // #if [ee] const isSupportsFileSortUpload = diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/data.ts b/packages/sqle/src/page/SqlExecWorkflow/Common/data.ts new file mode 100644 index 000000000..99dbd9f2d --- /dev/null +++ b/packages/sqle/src/page/SqlExecWorkflow/Common/data.ts @@ -0,0 +1 @@ +export const SOURCE_WORKFLOW_PATH_KEY = 'sourceWorkflowId'; diff --git a/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/BaseInfoForm/BaseInfoFormItem.tsx b/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/BaseInfoForm/BaseInfoFormItem.tsx index e72b90627..3d07f3f91 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/BaseInfoForm/BaseInfoFormItem.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/BaseInfoForm/BaseInfoFormItem.tsx @@ -5,60 +5,64 @@ import { FormItemLabel } from '@actiontech/shared/lib/components/FormCom'; import { workflowNameRule } from '@actiontech/shared/lib/utils/FormRule'; -import { ReactNode } from 'react'; +import { ReactNode, forwardRef } from 'react'; import { useTranslation } from 'react-i18next'; -const BaseInfoFormItem: React.FC<{ slot?: ReactNode }> = ({ slot }) => { - const { t } = useTranslation(); +const BaseInfoFormItem = forwardRef( + ({ slot }, ref) => { + const { t } = useTranslation(); - return ( - <> - - - + return ( + <> +
+ + + +
- {slot} + {slot} - - - - - ); -}; + + + + + ); + } +); export default BaseInfoFormItem; diff --git a/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/BaseInfoForm/index.tsx b/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/BaseInfoForm/index.tsx index 9b2e32307..c82d68d13 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/BaseInfoForm/index.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/BaseInfoForm/index.tsx @@ -7,8 +7,9 @@ import { FormItemBigTitle } from '@actiontech/shared/lib/components/FormCom'; import BaseInfoFormItem from './BaseInfoFormItem'; import { BriefcaseFilled } from '@actiontech/icons'; import Icon from '@ant-design/icons'; +import { forwardRef } from 'react'; -const BaseInfoForm: React.FC = () => { +const BaseInfoForm = forwardRef((props, ref) => { const { t } = useTranslation(); return ( @@ -18,10 +19,10 @@ const BaseInfoForm: React.FC = () => { {t('execWorkflow.create.title')} - + ); -}; +}); export default BaseInfoForm; diff --git a/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/SqlAuditInfoForm/SqlAuditInfoFormItem/DatabaseSelectionItems/hooks/useRenderDatabaseSelectionItems.tsx b/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/SqlAuditInfoForm/SqlAuditInfoFormItem/DatabaseSelectionItems/hooks/useRenderDatabaseSelectionItems.tsx index 961d2a69c..817c869d1 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/SqlAuditInfoForm/SqlAuditInfoFormItem/DatabaseSelectionItems/hooks/useRenderDatabaseSelectionItems.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/SqlAuditInfoForm/SqlAuditInfoFormItem/DatabaseSelectionItems/hooks/useRenderDatabaseSelectionItems.tsx @@ -13,6 +13,10 @@ import { getSystemModuleStatusModuleNameEnum } from '@actiontech/shared/lib/api/sqle/service/system/index.enum'; import useThemeStyleData from '../../../../../../../../../hooks/useThemeStyleData'; +import useCreationMode from '../../../../../../hooks/useCreationMode'; +import { useEffect } from 'react'; +import { useSelector } from 'react-redux'; +import { IReduxState } from '../../../../../../../../../store'; const useRenderDatabaseSelectionItems = ({ dbSourceInfoCollection, @@ -24,6 +28,29 @@ const useRenderDatabaseSelectionItems = ({ const { t } = useTranslation(); const { projectName, projectID } = useCurrentProject(); const { sqleTheme } = useThemeStyleData(); + + const { isCloneMode } = useCreationMode(); + + const sqlExecWorkflowReduxState = useSelector((state: IReduxState) => { + return { + clonedExecWorkflowSqlAuditInfo: + state.sqlExecWorkflow.clonedExecWorkflowSqlAuditInfo + }; + }); + + useEffect(() => { + if (isCloneMode) { + sqlExecWorkflowReduxState.clonedExecWorkflowSqlAuditInfo?.databaseInfo?.forEach( + (database, index) => { + const key = `${index}`; + handleInstanceChange(key, database.instanceName); + handleInstanceSchemaChange(key, database.instanceSchema); + } + ); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const updateSchemaList = async (key: string, instanceName: string) => { instance .getInstanceSchemasV1({ @@ -87,7 +114,7 @@ const useRenderDatabaseSelectionItems = ({ ruleTemplate: undefined, dbType: undefined, testConnectResult: undefined, - isSupportFileModeExecuteSql: false + isSupportFileModeExecuteSql: true }); updateSchemaList(key, instanceName); updateRuleTemplateNameAndDbType(key, instanceName); diff --git a/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/SqlAuditInfoForm/SqlAuditInfoFormItem/index.tsx b/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/SqlAuditInfoForm/SqlAuditInfoFormItem/index.tsx index e6fb79a87..595ee4e32 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/SqlAuditInfoForm/SqlAuditInfoFormItem/index.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/SqlAuditInfoForm/SqlAuditInfoFormItem/index.tsx @@ -13,126 +13,127 @@ import SqlStatementFormController from '../../../../../Common/SqlStatementFormCo import { SAME_SQL_MODE_DEFAULT_FIELD_KEY } from '../../../../../Common/SqlStatementFormController/SqlStatementFormItem/index.data'; import { RingPieFilled } from '@actiontech/icons'; import { CommonIconStyleWrapper } from '@actiontech/shared/lib/styleWrapper/element'; +import { forwardRef } from 'react'; -const SqlAuditInfoFormItem: React.FC = ({ - auditAction, - handleInstanceNameChange, - ...sharedStepDetail -}) => { - const { t } = useTranslation(); - const form = Form.useFormInstance(); +const SqlAuditInfoFormItem = forwardRef( + ({ auditAction, handleInstanceNameChange, ...sharedStepDetail }, ref) => { + const { t } = useTranslation(); + const form = Form.useFormInstance(); - const isSameSqlForAll = Form.useWatch('isSameSqlForAll', form); + const isSameSqlForAll = Form.useWatch('isSameSqlForAll', form); - const databaseInfo: CreateWorkflowDatabaseInfo = useMemo(() => { - return Object.keys(sharedStepDetail.dbSourceInfoCollection.value) - .map((key) => { - return { - key, - instanceName: - sharedStepDetail.dbSourceInfoCollection.value?.[key]?.instanceName, - schemaName: - sharedStepDetail.dbSourceInfoCollection.value?.[key]?.schemaName - }; - }) - .filter((v) => !!v.instanceName); - }, [sharedStepDetail.dbSourceInfoCollection]); + const databaseInfo: CreateWorkflowDatabaseInfo = useMemo(() => { + return Object.keys(sharedStepDetail.dbSourceInfoCollection.value) + .map((key) => { + return { + key, + instanceName: + sharedStepDetail.dbSourceInfoCollection.value?.[key] + ?.instanceName, + schemaName: + sharedStepDetail.dbSourceInfoCollection.value?.[key]?.schemaName + }; + }) + .filter((v) => !!v.instanceName); + }, [sharedStepDetail.dbSourceInfoCollection]); - const isSupportFileModeExecuteSqlRecord: Record = - useMemo(() => { - if (isSameSqlForAll) { - // 相同 SQL 模式下,判断所有数据源是否都支持。虽然 相同 SQL 模式下所有数据源类型会相同,但还是做下校验 - return { - [SAME_SQL_MODE_DEFAULT_FIELD_KEY]: Object.keys( - sharedStepDetail.dbSourceInfoCollection.value - ).every((key) => { - return !!sharedStepDetail.dbSourceInfoCollection?.value?.[key] - ?.isSupportFileModeExecuteSql; - }) - }; - } - //不同 SQL 模式下,每个数据源对应各自当前数据源类型是否支持文件上线模式 - return Object.keys(sharedStepDetail.dbSourceInfoCollection.value).reduce( - (acc, key) => { + const isSupportFileModeExecuteSqlRecord: Record = + useMemo(() => { + if (isSameSqlForAll) { + // 相同 SQL 模式下,判断所有数据源是否都支持。虽然 相同 SQL 模式下所有数据源类型会相同,但还是做下校验 + return { + [SAME_SQL_MODE_DEFAULT_FIELD_KEY]: Object.keys( + sharedStepDetail.dbSourceInfoCollection.value + ).every((key) => { + return !!sharedStepDetail.dbSourceInfoCollection?.value?.[key] + ?.isSupportFileModeExecuteSql; + }) + }; + } + //不同 SQL 模式下,每个数据源对应各自当前数据源类型是否支持文件上线模式 + return Object.keys( + sharedStepDetail.dbSourceInfoCollection.value + ).reduce((acc, key) => { return { ...acc, [key]: !!sharedStepDetail.dbSourceInfoCollection?.value?.[key] ?.isSupportFileModeExecuteSql }; - }, - {} - ); - }, [isSameSqlForAll, sharedStepDetail.dbSourceInfoCollection.value]); + }, {}); + }, [isSameSqlForAll, sharedStepDetail.dbSourceInfoCollection.value]); - useEffect(() => { - const dbTypeSet = new Set( - Object.keys(sharedStepDetail.dbSourceInfoCollection.value) - ?.map((key) => { - return sharedStepDetail.dbSourceInfoCollection.value?.[key].dbType; - }) - .filter((v) => !!v) - ); - if (dbTypeSet.size > 1) { - form.setFieldValue('isSameSqlForAll', false); - sharedStepDetail.isDisabledForDifferenceSql.set(true); - } else { - sharedStepDetail.isDisabledForDifferenceSql.set(false); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [form, sharedStepDetail.dbSourceInfoCollection.value]); + useEffect(() => { + const dbTypeSet = new Set( + Object.keys(sharedStepDetail.dbSourceInfoCollection.value) + ?.map((key) => { + return sharedStepDetail.dbSourceInfoCollection.value?.[key].dbType; + }) + .filter((v) => !!v) + ); + if (dbTypeSet.size > 1) { + form.setFieldValue('isSameSqlForAll', false); + sharedStepDetail.isDisabledForDifferenceSql.set(true); + } else { + sharedStepDetail.isDisabledForDifferenceSql.set(false); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [form, sharedStepDetail.dbSourceInfoCollection.value]); - return ( - <> - + return ( + <> +
+ +
- + } + labelCol={{ span: 22 }} + wrapperCol={{ span: 2 }} + > + + - - - ); -}; + + + ); + } +); export default SqlAuditInfoFormItem; diff --git a/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/SqlAuditInfoForm/index.tsx b/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/SqlAuditInfoForm/index.tsx index 4cf4c6f2a..a9c04ba5a 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/SqlAuditInfoForm/index.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/SqlAuditInfoForm/index.tsx @@ -3,17 +3,20 @@ import { FormAreaBlockStyleWrapper } from '@actiontech/shared/lib/components/For import { useTranslation } from 'react-i18next'; import SqlAuditInfoFormItem from './SqlAuditInfoFormItem'; import { SqlAuditInfoFormProps } from './index.type'; +import { forwardRef } from 'react'; -const SqlAuditInfoForm: React.FC = (props) => { - const { t } = useTranslation(); - return ( - - - {t('execWorkflow.create.form.sqlInfo.title')} - - - - ); -}; +const SqlAuditInfoForm = forwardRef( + (props, ref) => { + const { t } = useTranslation(); + return ( + + + {t('execWorkflow.create.form.sqlInfo.title')} + + + + ); + } +); export default SqlAuditInfoForm; diff --git a/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/index.tsx b/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/index.tsx index bcc53e491..0db049aec 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/index.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Create/components/FormStep/index.tsx @@ -2,13 +2,17 @@ import { FormStyleWrapper } from '@actiontech/shared/lib/components/FormCom/styl import BaseInfoForm from './BaseInfoForm'; import { CreateWorkflowFormStepProps } from './index.type'; import { PageLayoutHasFixedHeaderStyleWrapper } from '@actiontech/shared/lib/styleWrapper/element'; -import { BasicButton, PageHeader } from '@actiontech/shared'; +import { BasicButton, PageHeader, EmptyBox } from '@actiontech/shared'; import { useTranslation } from 'react-i18next'; import SqlAuditInfoForm from './SqlAuditInfoForm'; import { SqlAuditInfoFormStyleWrapper } from './style'; import { useCallback } from 'react'; import dayjs from 'dayjs'; import BackToList from '../../../Common/BackToList'; +import { Tour } from 'antd'; +import type { TourProps } from 'antd'; +import { useState, useRef, useMemo } from 'react'; +import useCreationMode from '../../hooks/useCreationMode'; const FormStep: React.FC = ({ baseInfoForm, @@ -18,6 +22,27 @@ const FormStep: React.FC = ({ }) => { const { t } = useTranslation(); + const [open, setOpen] = useState(true); + + const { isCloneMode } = useCreationMode(); + + const workflowNameFieldRef = useRef(null); + const dataSourceFieldRef = useRef(null); + + const tourSteps: TourProps['steps'] = useMemo( + () => [ + { + title: t('execWorkflow.create.form.tour.modifyName'), + target: () => workflowNameFieldRef.current! + }, + { + title: t('execWorkflow.create.form.tour.modifyDataSource'), + target: () => dataSourceFieldRef.current! + } + ], + [t] + ); + const resetAllForm = () => { baseInfoForm.resetFields(); sqlAuditInfoForm.resetFields(); @@ -56,9 +81,8 @@ const FormStep: React.FC = ({ layout="vertical" labelAlign="left" > - + - = ({ handleInstanceNameChange={handleInstanceNameChange} auditAction={auditAction} {...sharedStepDetail} + ref={dataSourceFieldRef} /> + + setOpen(false)} steps={tourSteps} /> + ); }; diff --git a/packages/sqle/src/page/SqlExecWorkflow/Create/hooks/useCreationMode.ts b/packages/sqle/src/page/SqlExecWorkflow/Create/hooks/useCreationMode.ts new file mode 100644 index 000000000..704db33f5 --- /dev/null +++ b/packages/sqle/src/page/SqlExecWorkflow/Create/hooks/useCreationMode.ts @@ -0,0 +1,18 @@ +import { useSearchParams } from 'react-router-dom'; +import { useMemo } from 'react'; +import { SOURCE_WORKFLOW_PATH_KEY } from '../../Common/data'; + +const useCreationMode = () => { + const [searchParams] = useSearchParams(); + + const isCloneMode = useMemo( + () => searchParams.has(SOURCE_WORKFLOW_PATH_KEY), + [searchParams] + ); + + return { + isCloneMode + }; +}; + +export default useCreationMode; diff --git a/packages/sqle/src/page/SqlExecWorkflow/Create/index.tsx b/packages/sqle/src/page/SqlExecWorkflow/Create/index.tsx index a5a883c53..22ac9705b 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Create/index.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Create/index.tsx @@ -9,7 +9,7 @@ import CreateResultStep from './components/CreateResultStep'; import FormStep from './components/FormStep'; import useSharedStepDetail from './hooks/useSharedStepDetail'; import useAuditWorkflow from './hooks/useAuditWorkflow'; -import { useCallback, useRef } from 'react'; +import { useCallback, useRef, useEffect } from 'react'; import AuditResultStep from './components/AuditResultStep'; import { usePrompt } from '@actiontech/shared/lib/hooks'; import { useTranslation } from 'react-i18next'; @@ -19,6 +19,9 @@ import { ResponseCode } from '@actiontech/shared/lib/enum'; import { ICreateWorkflowV2Params } from '@actiontech/shared/lib/api/sqle/service/workflow/index.d'; import useCheckTaskAuditSqlCount from './hooks/useCheckTaskAuditSqlCount'; import { LazyLoadComponent } from '@actiontech/shared'; +import { useSelector } from 'react-redux'; +import { IReduxState } from '../../../store'; +import useCreationMode from './hooks/useCreationMode'; const CreateSqlExecWorkflow: React.FC = () => { const { t } = useTranslation(); @@ -30,6 +33,39 @@ const CreateSqlExecWorkflow: React.FC = () => { const { updateTaskRecordCount, checkTaskCountIsEmpty } = useCheckTaskAuditSqlCount(); + const { isCloneMode } = useCreationMode(); + + const sqlExecWorkflowReduxState = useSelector((state: IReduxState) => { + return { + clonedExecWorkflowSqlAuditInfo: + state.sqlExecWorkflow.clonedExecWorkflowSqlAuditInfo, + clonedExecWorkflowBaseInfo: + state.sqlExecWorkflow.clonedExecWorkflowBaseInfo + }; + }); + + useEffect(() => { + if (isCloneMode) { + baseInfoForm.setFieldsValue({ + workflow_subject: + sqlExecWorkflowReduxState.clonedExecWorkflowBaseInfo + ?.workflow_subject ?? '', + desc: sqlExecWorkflowReduxState.clonedExecWorkflowBaseInfo?.desc ?? '' + }); + if (sqlExecWorkflowReduxState.clonedExecWorkflowSqlAuditInfo) { + Object.keys( + sqlExecWorkflowReduxState.clonedExecWorkflowSqlAuditInfo + ).forEach((key) => { + sqlAuditInfoForm.setFieldsValue({ + [key]: + sqlExecWorkflowReduxState.clonedExecWorkflowSqlAuditInfo?.[key] + }); + }); + } + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const { isAtFormStep, isAtAuditResultStep, diff --git a/packages/sqle/src/page/SqlExecWorkflow/Detail/components/AuditExecResultPanel/index.tsx b/packages/sqle/src/page/SqlExecWorkflow/Detail/components/AuditExecResultPanel/index.tsx index 5942c921e..8f20fb19c 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Detail/components/AuditExecResultPanel/index.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Detail/components/AuditExecResultPanel/index.tsx @@ -193,7 +193,8 @@ const AuditExecResultPanel: React.FC = ({ pagination={pagination} tableChange={tableChange} executeMode={ - resetProps.workflowInfo?.exec_mode ?? WorkflowResV2ExecModeEnum.sqls + (currentTask?.exec_mode as WorkflowResV2ExecModeEnum) ?? + WorkflowResV2ExecModeEnum.sqls } /> diff --git a/packages/sqle/src/page/SqlExecWorkflow/Detail/components/PageHeaderExtra/hooks/useWorkflowDetailAction.tsx b/packages/sqle/src/page/SqlExecWorkflow/Detail/components/PageHeaderExtra/hooks/useWorkflowDetailAction.tsx index e1633773d..4280c19fb 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Detail/components/PageHeaderExtra/hooks/useWorkflowDetailAction.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Detail/components/PageHeaderExtra/hooks/useWorkflowDetailAction.tsx @@ -26,7 +26,8 @@ const useWorkflowDetailAction = ({ executingAction, terminateAction, completeAction, - maintenanceTimeInfo + maintenanceTimeInfo, + executeInOtherInstanceAction }: WorkflowDetailPageHeaderExtraProps & { projectName: string; }): { @@ -37,6 +38,7 @@ const useWorkflowDetailAction = ({ batchExecutingWorkflowButtonMeta: WorkflowDetailActionMeta; manualExecuteWorkflowButtonMeta: WorkflowDetailActionMeta; terminateWorkflowButtonMeta: WorkflowDetailActionMeta; + executeInOtherInstanceMeta: WorkflowDetailActionMeta; } => { const { t } = useTranslation(); const [messageApi, messageContextHolder] = message.useMessage(); @@ -245,6 +247,19 @@ const useWorkflowDetailAction = ({ return terminateAction().finally(terminateFinish); }; + const [ + executeInOtherInstanceLoading, + { + setTrue: executeInOtherInstanceStart, + setFalse: executeInOtherInstanceFinish + } + ] = useBoolean(); + + const executeInOtherInstance = () => { + executeInOtherInstanceStart(); + return executeInOtherInstanceAction().finally(executeInOtherInstanceFinish); + }; + return { messageContextHolder, @@ -277,6 +292,11 @@ const useWorkflowDetailAction = ({ action: terminateWorkflow, loading: terminateLoading, hidden: !terminateButtonVisibility + }, + executeInOtherInstanceMeta: { + action: executeInOtherInstance, + loading: executeInOtherInstanceLoading, + hidden: false } }; }; diff --git a/packages/sqle/src/page/SqlExecWorkflow/Detail/components/PageHeaderExtra/index.tsx b/packages/sqle/src/page/SqlExecWorkflow/Detail/components/PageHeaderExtra/index.tsx index bb9371fbc..7ba8af123 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Detail/components/PageHeaderExtra/index.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Detail/components/PageHeaderExtra/index.tsx @@ -5,8 +5,13 @@ import { useBoolean } from 'ahooks'; import { WorkflowPageHeaderExtraStyleWrapper } from './style'; import { WorkflowDetailPageHeaderExtraProps } from './index.type'; import useWorkflowDetailAction from './hooks/useWorkflowDetailAction'; -import { useCurrentProject } from '@actiontech/shared/lib/global'; +import { + useCurrentProject, + useCurrentUser +} from '@actiontech/shared/lib/global'; import RejectWorkflowModal from './RejectWorkflowModal'; +import { useMemo } from 'react'; +import { OpPermissionTypeUid } from '@actiontech/shared/lib/enum'; const WorkflowDetailPageHeaderExtra: React.FC< WorkflowDetailPageHeaderExtraProps @@ -15,6 +20,17 @@ const WorkflowDetailPageHeaderExtra: React.FC< const { projectArchive, projectName } = useCurrentProject(); + const { managementPermissions, isProjectManager } = useCurrentUser(); + + const isAllowExecuteInOtherInstance = useMemo(() => { + return ( + isProjectManager(projectName) || + managementPermissions.some( + (v) => OpPermissionTypeUid['create_workflow'] === (v?.uid ?? '') + ) + ); + }, [managementPermissions, isProjectManager, projectName]); + const [ rejectModalVisible, { setTrue: openRejectModal, setFalse: closeRejectModal } @@ -27,7 +43,8 @@ const WorkflowDetailPageHeaderExtra: React.FC< rejectWorkflowButtonMeta, batchExecutingWorkflowButtonMeta, manualExecuteWorkflowButtonMeta, - terminateWorkflowButtonMeta + terminateWorkflowButtonMeta, + executeInOtherInstanceMeta } = useWorkflowDetailAction({ projectName, ...props }); return ( @@ -51,6 +68,14 @@ const WorkflowDetailPageHeaderExtra: React.FC< + + executeInOtherInstanceMeta.action()} + loading={executeInOtherInstanceMeta.loading} + > + {t('execWorkflow.detail.operator.cloneExecWorkflow')} + +