From e725e33975c906fed19f4b5f6368891dd6c202a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B9=8B=E7=91=9B?= Date: Tue, 20 May 2025 18:35:45 +0800 Subject: [PATCH 01/74] PullRequest: 795 feat/task-refactor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge branch 'feat/task-refactor of git@code.alipay.com:oceanbase/oceanbase-developer-center.git into dev-4.4.0 https://code.alipay.com/oceanbase/oceanbase-developer-center/pull_requests/795 Reviewed-by: 艺泽 * refactor: 调整常量位置 * feat: 调整 modals位置 * refactor: 引用方式调整 * refactor: 修改引用 * refactor: 修改引用 * refactor: 调整引用 * refactor: modals 收到modals路径下 * refactor: detail modal 名称调整 * refactor: modals 相关代码路径调整 * refactor: 删除多余代码 * refactor: 容器组件放在container 路径下 * fix: index.less 引用修正 * refactor: 调整创建modal 代码位置 * refactor: 调整样式引用 * fix: 名称修正 * refactor: 调整引用代码顺序 * refactor: 代码引用 * refactor: 提示语调整 * refactor: 拆分 taskTable * feat: 简化隐藏项目列逻辑 * fix: 优化隐藏项目列依赖项 * refactor: 优化content文件代码样式 * refactor: 简化 loadList * refactor: 调整代码样式 * refactor: 删除多余代码 * refactor: 删除多余代码 * refactor: 调整loadList * refactor: 删除无用代码 * refactor: 提示语调整 * refactor: 合并 buttonConfig * refactor: 函数名称调整 * refactor: editCycleTask 调整 * refactor: 优化handleRetrCycleTask * refactor: 优化 handleRetry * refactor: 调整 enbale 控制 * feat: 简化任务操作 * refactor: 名称调整 * feat: 优化周期任务 tools 生成 * refactor: 优化 taskTools * refactor: 优化 taskTools * refactor: 改写exe 任务状态操作控制 * refactor: 优化 task 操作 * refactor: 优化取值 * refactor: 调整 tools 操作 * refactor: 调整 tools 操作 * refactor: 调整异步 * refactor: 调整url参数使用 * fix: 参数调整 * refactor: 拆分 actions * refactor: 优化taskTools * refactor: 整理的代码 * refactor: 优化 cycleTaskTools * refactor: 优化 cycleTaskTools * refactor: 名称调整 * refactor: 优化 cycleTaskTools * refactor: 优化 addOperations * refactor: 优化 addOperations 参数 * refactor: 提取 TS 定义 * refactor: 优化 editCycleTask * refactor: 调整taskTypeName * refactor: 优化 cycleTaskTools * refactor: 提取 taskTools 常量 * refactor: 添加注释 * fix: 补充缺失信息 * refactor: 删除多余代码 * refactor: 提取 rules * refactor: 常量与工具函数提取 * refactor: 调整 rules * refactor: 优化 Radio * refactor: 修正 const * refactor: 调整 radio 用法 * refactor: 优化写法 * refactor: 调整 radio 用法 * refactor: 删除多余代码 * refactor: radio 优化 * refactor: radio 替换 * refactor: 优化 Radio.Group 使用 * refactor: rules 提取 * refactor: rules 提取 * refactor: exportTask rules * refactor: 调整rules * fix: rules 替换 * refactor: rules 调整 * refactor: 遗漏 rules 提取 * refactor: 拆分 configModal * refactor: configModal 优化 * refactor: configModal 代码拆分 * refactor: ruleFormItem 提取 rules * refactor: 优化 ruleForm 中表单值读取 * refactor: 调整命名 * refactor: 名称调整 * refactor: Content 任务加载恢复按任务页类型区分 * fix: 优化样式引用 * refactor: 优化数组使用 * refactor: 调整 Content 中参数顺序 * refactor: loadTaskList 参数调整顺序 * refactor: 提取工单请求的公共参数 * refactor: 参数调整 * refactor: 删除多余代码 * refactor: 名称调整 * refactor: 删除无用代码 * feat: 注释 && 部分写法改动 --- src/common/network/task.ts | 2 +- src/component/OSSDragger/index.tsx | 2 +- .../Task/component/ActionBar/helper.tsx | 186 +++ .../Task/component/ActionBar/index.tsx | 1330 +++++++---------- .../Task/component/ActionBar/type.ts | 12 + .../Task/component/ApprovalModal/index.less | 10 + .../Task/component/ApprovalModal/index.tsx | 4 +- .../CommonDetailModal/ExcecuteDetailModal.tsx | 5 +- .../component/CommonDetailModal/LogModal.tsx | 1 - .../CommonDetailModal/Nodes/RollbackNode.tsx | 2 +- .../CommonDetailModal/TaskExecuteRecord.tsx | 4 +- .../component/CommonDetailModal/TaskFlow.tsx | 2 +- .../TaskProgress/ProgressDetailsModal.tsx | 4 +- .../TaskProgress/TaskProgressDrawer.tsx | 2 +- .../CommonDetailModal/TaskProgress/colums.tsx | 2 +- .../CommonDetailModal/TaskProgress/index.tsx | 4 +- .../CommonDetailModal/TaskProgress1.tsx | 4 +- .../CommonDetailModal/TaskRecord.tsx | 2 +- .../component/DataTransferModal/csvTables.tsx | 2 +- .../component/DataTransferModal/index.tsx | 4 +- .../Task/component/DirtyRowAction/index.tsx | 2 +- .../component/JoinTableConfigsModal/index.tsx | 2 +- .../MaxAllowedDirtyRowCount/index.tsx | 2 +- .../MultipleDatabaseSelect/index.tsx | 1 - .../components/CustomNamingRules.tsx | 34 + .../components/DropPartitionFormItems.tsx | 80 + .../{ => components}/EditTable/index.less | 0 .../{ => components}/EditTable/index.tsx | 2 +- .../IntervalGenerateExprFormItem.tsx | 33 + .../components/PreSuffixNamingRules.tsx | 132 ++ .../PreviewSQLModal/index.less | 0 .../PreviewSQLModal/index.tsx | 0 .../{ => components}/RuleFormItem/index.less | 0 .../{ => components}/RuleFormItem/index.tsx | 331 +--- .../PartitionPolicyFormTable/configModal.tsx | 609 +------- .../PartitionPolicyFormTable/const.ts | 323 +++- .../PartitionPolicyFormTable/index.tsx | 8 +- .../PartitionPolicyFormTable/utils.ts | 175 +++ .../PartitionPolicyTable/ConfigDrawer.tsx | 2 +- .../PartitionPolicyTable/ConfigTable.tsx | 2 +- .../component/PartitionPolicyTable/index.tsx | 2 +- src/component/Task/component/Status/index.tsx | 2 +- .../component/SynchronizationItem/index.tsx | 2 +- .../Task/component/TableSelecter/index.tsx | 2 +- .../Task/component/TaskTable/const.ts | 96 ++ .../Task/component/TaskTable/index.tsx | 128 +- .../Task/component/TaskTable/utils.ts | 28 + .../Task/component/ThrottleFormItem/index.tsx | 1 - .../component/VariableConfigTable/index.tsx | 2 +- src/component/Task/const.ts | 108 ++ .../Task/{ => container}/Content.tsx | 155 +- src/component/Task/{ => container}/Sider.tsx | 12 +- .../{ => container}/TaskDetailContext.tsx | 2 +- src/component/Task/helper.tsx | 5 +- .../{useProjects.tsx => useLoadProjects.tsx} | 2 +- src/component/Task/index.less | 11 - src/component/Task/index.tsx | 119 +- src/component/Task/interface.ts | 14 + .../modals/AlterDdlTask/CreateModal/const.ts | 80 + .../AlterDdlTask/CreateModal/index.less | 0 .../AlterDdlTask/CreateModal/index.tsx | 176 +-- .../AlterDdlTask/DetailContent/index.tsx | 10 +- .../Task/{ => modals}/AlterDdlTask/index.tsx | 0 .../ApplyDatabasePermission/CreateButton.tsx | 0 .../CreateModal/const.ts | 152 ++ .../CreateModal/index.less | 0 .../CreateModal/index.tsx | 199 +-- .../CreateModal/utils.tsx | 42 + .../DetailContent/index.less | 0 .../DetailContent/index.tsx | 0 .../ApplyDatabasePermission/index.tsx | 0 .../ApplyPermission/CreateButton.tsx | 0 .../ApplyPermission/CreateModal/const.ts | 38 + .../ApplyPermission/CreateModal/index.less | 0 .../ApplyPermission/CreateModal/index.tsx | 45 +- .../ApplyPermission/DetailContent/index.tsx | 0 .../{ => modals}/ApplyPermission/index.tsx | 0 .../ApplyTablePermission/CreateButton.tsx | 0 .../ApplyTablePermission/CreateModal/const.ts | 65 + .../CreateModal/index.less | 0 .../CreateModal/index.tsx | 68 +- .../DetailContent/index.tsx | 0 .../ApplyTablePermission/index.tsx | 0 .../CreateModal/PopconfirmButton.tsx | 0 .../modals/AsyncTask/CreateModal/const.ts | 109 ++ .../AsyncTask/CreateModal/index.less | 0 .../AsyncTask/CreateModal/index.tsx | 202 +-- .../AsyncTask/DetailContent/index.less | 0 .../AsyncTask/DetailContent/index.tsx | 8 +- .../Task/{ => modals}/AsyncTask/index.tsx | 0 .../Task/{ => modals}/CreateModals.tsx | 0 .../CreateModal/ArchiveRange.tsx | 43 +- .../CreateModal/VariableConfig.tsx | 31 +- .../DataArchiveTask/CreateModal/const.ts | 55 + .../DataArchiveTask/CreateModal/index.less | 0 .../DataArchiveTask/CreateModal/index.tsx | 27 +- .../DetailContent/ArchiveRange.tsx | 2 +- .../DataArchiveTask/DetailContent/index.tsx | 9 +- .../{ => modals}/DataArchiveTask/index.tsx | 0 .../CreateModal/ArchiveRange.tsx | 43 +- .../CreateModal/VariableConfig.tsx | 33 +- .../modals/DataClearTask/CreateModal/const.ts | 55 + .../DataClearTask/CreateModal/index.less | 0 .../DataClearTask/CreateModal/index.tsx | 27 +- .../DetailContent/ArchiveRange.tsx | 2 +- .../DataClearTask/DetailContent/index.tsx | 8 +- .../Task/{ => modals}/DataClearTask/index.tsx | 0 .../CreateModal/RuleConfigTable.tsx | 13 +- .../RuleContent/RangeInput/index.less | 0 .../RuleContent/RangeInput/index.tsx | 0 .../RuleContent/WrapItemWithTitle/index.less | 0 .../RuleContent/WrapItemWithTitle/index.tsx | 0 .../CreateModal/RuleContent/index.less | 0 .../CreateModal/RuleContent/index.tsx | 0 .../ruleItems/CharItem/converter.ts | 2 +- .../ruleItems/CharItem/defaultValue.tsx | 0 .../RuleContent/ruleItems/CharItem/index.tsx | 0 .../ruleItems/DateItem/converter.ts | 2 +- .../ruleItems/DateItem/defaultValue.tsx | 0 .../RuleContent/ruleItems/DateItem/index.tsx | 0 .../ruleItems/IntervalItem/converter.ts | 2 +- .../ruleItems/IntervalItem/defaultValue.tsx | 0 .../ruleItems/IntervalItem/index.tsx | 0 .../ruleItems/NumberItem/converter.ts | 2 +- .../ruleItems/NumberItem/defaultValue.tsx | 0 .../ruleItems/NumberItem/index.tsx | 0 .../ruleItems/OtherItem/converter.ts | 2 +- .../ruleItems/OtherItem/defaultValue.tsx | 0 .../RuleContent/ruleItems/OtherItem/index.tsx | 0 .../RuleContent/ruleItems/valid.tsx | 0 .../CreateModal/RuleContent/util.tsx | 0 .../DataMockerTask/CreateModal/RuleSelect.tsx | 0 .../DataMockerTask/CreateModal/const.ts | 63 + .../DataMockerTask/CreateModal/form.tsx | 82 +- .../DataMockerTask/CreateModal/index.less | 0 .../DataMockerTask/CreateModal/index.tsx | 0 .../DataMockerTask/CreateModal/type.ts | 0 .../DataMockerTask/DetailContent/index.tsx | 10 +- .../{ => modals}/DataMockerTask/index.tsx | 0 .../DetailModals.tsx} | 11 +- .../ExportForm/ConfigPanel/index.tsx | 134 +- .../ExportForm/ExportSelecter/index.less | 0 .../ExportForm/ExportSelecter/index.tsx | 0 .../CreateModal/ExportForm/FormContext.tsx | 0 .../ExportForm/ObjSelecterPanel/index.tsx | 84 +- .../CreateModal/ExportForm/index.less | 0 .../CreateModal/ExportForm/index.tsx | 0 .../modals/ExportTask/CreateModal/const.ts | 133 ++ .../ExportTask/CreateModal/index.less | 0 .../ExportTask/CreateModal/index.tsx | 4 +- .../Task/{ => modals}/ExportTask/index.tsx | 2 +- .../ImportForm/ConfigPanel/index.tsx | 104 +- .../CreateModal/ImportForm/CsvProvider.ts | 0 .../ImportForm/FileSelecterPanel/index.less | 0 .../ImportForm/FileSelecterPanel/index.tsx | 31 +- .../ImportForm/FormConfigContext.tsx | 0 .../CreateModal/ImportForm/FormContext.ts | 0 .../ImportForm/formitem/CsvFormItem.tsx | 39 +- .../formitem/StructDataFormItem.tsx | 54 +- .../CreateModal/ImportForm/helper.ts | 0 .../CreateModal/ImportForm/index.less | 0 .../CreateModal/ImportForm/index.tsx | 0 .../modals/ImportTask/CreateModal/const.ts | 96 ++ .../CreateModal/csvMapping/editable.less | 0 .../CreateModal/csvMapping/editable.tsx | 0 .../CreateModal/csvMapping/index.tsx | 0 .../ImportTask/CreateModal/index.less | 0 .../ImportTask/CreateModal/index.tsx | 2 +- .../Task/{ => modals}/ImportTask/index.tsx | 2 +- .../CreateModal/PopconfirmButton.tsx | 0 .../CreateModal/PreviewSQLDrawer.tsx | 0 .../CreateModal/const.ts | 50 + .../CreateModal/index.less | 0 .../CreateModal/index.tsx | 98 +- .../DetailContent/index.tsx | 5 +- .../LogicDatabaseAsyncTask/index.tsx | 0 .../CreateModal/DatabaseQueue.tsx | 0 .../CreateModal/DrawerFooter.tsx | 0 .../CreateModal/InnerSelecter.tsx | 33 +- .../CreateModal/MoreSetting.tsx | 203 +-- .../CreateModal/MultipleAsyncContext.ts | 0 .../CreateModal/ProjectSelect.tsx | 11 +- .../MutipleAsyncTask/CreateModal/helper.tsx | 4 +- .../MutipleAsyncTask/CreateModal/index.less | 0 .../MutipleAsyncTask/CreateModal/index.tsx | 96 +- .../MutipleAsyncTask/DetailContent/index.less | 0 .../MutipleAsyncTask/DetailContent/index.tsx | 8 +- .../components/Template/CreateTemplate.tsx | 29 +- .../components/Template/EditTemplate.tsx | 32 +- .../components/Template/ManageTemplate.tsx | 0 .../components/Template/SelectTemplate.tsx | 0 .../components/Template/ShowTemplate.tsx | 0 .../components/Template/index.less | 0 .../components/Template/index.tsx | 0 .../Task/modals/MutipleAsyncTask/const.ts | 218 +++ .../{ => modals}/MutipleAsyncTask/index.tsx | 0 .../modals/PartitionTask/CreateModal/const.ts | 30 + .../PartitionTask/CreateModal/index.less | 0 .../PartitionTask/CreateModal/index.tsx | 64 +- .../DetailContent/CycleDescriptionItem.tsx | 2 +- .../PartitionTask/DetailContent/index.less | 0 .../PartitionTask/DetailContent/index.tsx | 6 +- .../Task/{ => modals}/PartitionTask/index.tsx | 0 .../CreateModal/index.less | 0 .../CreateModal/index.tsx | 2 +- .../PermissionApplication/index.tsx | 0 .../CreateModal/CsvFormItemPanel.tsx | 44 +- .../ResultSetExportTask/CreateModal/const.ts | 90 ++ .../CreateModal/index.less | 0 .../ResultSetExportTask/CreateModal/index.tsx | 57 +- .../DetailContent/index.tsx | 6 +- .../ResultSetExportTask/index.tsx | 0 .../modals/SQLPlanTask/CreateModal/const.ts | 102 ++ .../SQLPlanTask/CreateModal/index.less | 0 .../SQLPlanTask/CreateModal/index.tsx | 186 +-- .../SQLPlanTask/CreateModal/interface.ts | 0 .../SQLPlanTask/DetailContent/index.tsx | 6 +- .../Task/{ => modals}/SQLPlanTask/index.tsx | 0 .../CreateModal/SelectPanel/index.less | 0 .../CreateModal/SelectPanel/index.tsx | 64 +- .../StructConfigPanel/RecordSQLView/index.tsx | 0 .../StructAnalysisResult/column.tsx | 0 .../StructAnalysisResult/index.tsx | 0 .../CreateModal/StructConfigPanel/index.tsx | 43 +- .../ShadowSyncTask/CreateModal/const.ts | 44 + .../ShadowSyncTask/CreateModal/index.less | 0 .../ShadowSyncTask/CreateModal/index.tsx | 0 .../ShadowSyncTask/CreateModal/interface.ts | 0 .../ShadowSyncTask/DetailContent/index.tsx | 8 +- .../{ => modals}/ShadowSyncTask/index.tsx | 0 .../CreateModal/TableSelector.tsx | 0 .../CreateModal/const.ts | 22 + .../CreateModal/index.less | 0 .../CreateModal/index.tsx | 63 +- .../CreateModal/interface.ts | 0 .../DetailContent/index.less | 0 .../DetailContent/index.tsx | 6 +- .../StructureComparisonTask/index.tsx | 0 src/constant/index.ts | 23 + src/d.ts/index.ts | 2 +- .../components/RecentlyDatabase/index.tsx | 12 +- .../components/AddDataBaseButton/index.tsx | 2 +- src/page/Project/Database/index.tsx | 10 +- src/page/Project/Project/index.tsx | 2 +- src/page/Project/Setting/Info/TaskList.tsx | 2 +- .../ManageModal/Database/CreateAuth/index.tsx | 2 +- .../Database/TaskApplyList/index.tsx | 4 +- .../Database/UserAuthList/index.tsx | 2 +- .../ManageModal/Table/CreateAuth/index.tsx | 2 +- .../ManageModal/Table/TaskApplyList/index.tsx | 4 +- .../ManageModal/Table/UserAuthList/index.tsx | 2 +- .../Secure/RiskLevel/components/options.ts | 2 +- src/page/Workspace/GlobalModals/index.tsx | 2 +- src/page/Workspace/SideBar/Task/index.tsx | 2 +- .../DBPermissionTableContent/index.tsx | 2 +- .../Workspace/components/TaskPage/index.tsx | 4 +- src/util/utils.ts | 9 + 257 files changed, 4199 insertions(+), 3939 deletions(-) create mode 100644 src/component/Task/component/ActionBar/helper.tsx create mode 100644 src/component/Task/component/ActionBar/type.ts create mode 100644 src/component/Task/component/ApprovalModal/index.less create mode 100644 src/component/Task/component/PartitionPolicyFormTable/components/CustomNamingRules.tsx create mode 100644 src/component/Task/component/PartitionPolicyFormTable/components/DropPartitionFormItems.tsx rename src/component/Task/component/PartitionPolicyFormTable/{ => components}/EditTable/index.less (100%) rename src/component/Task/component/PartitionPolicyFormTable/{ => components}/EditTable/index.tsx (99%) create mode 100644 src/component/Task/component/PartitionPolicyFormTable/components/IntervalGenerateExprFormItem.tsx create mode 100644 src/component/Task/component/PartitionPolicyFormTable/components/PreSuffixNamingRules.tsx rename src/component/Task/component/PartitionPolicyFormTable/{ => components}/PreviewSQLModal/index.less (100%) rename src/component/Task/component/PartitionPolicyFormTable/{ => components}/PreviewSQLModal/index.tsx (100%) rename src/component/Task/component/PartitionPolicyFormTable/{ => components}/RuleFormItem/index.less (100%) rename src/component/Task/component/PartitionPolicyFormTable/{ => components}/RuleFormItem/index.tsx (63%) create mode 100644 src/component/Task/component/PartitionPolicyFormTable/utils.ts create mode 100644 src/component/Task/component/TaskTable/const.ts create mode 100644 src/component/Task/component/TaskTable/utils.ts rename src/component/Task/{ => container}/Content.tsx (80%) rename src/component/Task/{ => container}/Sider.tsx (93%) rename src/component/Task/{ => container}/TaskDetailContext.tsx (91%) rename src/component/Task/hooks/{useProjects.tsx => useLoadProjects.tsx} (97%) create mode 100644 src/component/Task/modals/AlterDdlTask/CreateModal/const.ts rename src/component/Task/{ => modals}/AlterDdlTask/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/AlterDdlTask/CreateModal/index.tsx (83%) rename src/component/Task/{ => modals}/AlterDdlTask/DetailContent/index.tsx (97%) rename src/component/Task/{ => modals}/AlterDdlTask/index.tsx (100%) rename src/component/Task/{ => modals}/ApplyDatabasePermission/CreateButton.tsx (100%) create mode 100644 src/component/Task/modals/ApplyDatabasePermission/CreateModal/const.ts rename src/component/Task/{ => modals}/ApplyDatabasePermission/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/ApplyDatabasePermission/CreateModal/index.tsx (68%) create mode 100644 src/component/Task/modals/ApplyDatabasePermission/CreateModal/utils.tsx rename src/component/Task/{ => modals}/ApplyDatabasePermission/DetailContent/index.less (100%) rename src/component/Task/{ => modals}/ApplyDatabasePermission/DetailContent/index.tsx (100%) rename src/component/Task/{ => modals}/ApplyDatabasePermission/index.tsx (100%) rename src/component/Task/{ => modals}/ApplyPermission/CreateButton.tsx (100%) create mode 100644 src/component/Task/modals/ApplyPermission/CreateModal/const.ts rename src/component/Task/{ => modals}/ApplyPermission/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/ApplyPermission/CreateModal/index.tsx (88%) rename src/component/Task/{ => modals}/ApplyPermission/DetailContent/index.tsx (100%) rename src/component/Task/{ => modals}/ApplyPermission/index.tsx (100%) rename src/component/Task/{ => modals}/ApplyTablePermission/CreateButton.tsx (100%) create mode 100644 src/component/Task/modals/ApplyTablePermission/CreateModal/const.ts rename src/component/Task/{ => modals}/ApplyTablePermission/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/ApplyTablePermission/CreateModal/index.tsx (88%) rename src/component/Task/{ => modals}/ApplyTablePermission/DetailContent/index.tsx (100%) rename src/component/Task/{ => modals}/ApplyTablePermission/index.tsx (100%) rename src/component/Task/{ => modals}/AsyncTask/CreateModal/PopconfirmButton.tsx (100%) create mode 100644 src/component/Task/modals/AsyncTask/CreateModal/const.ts rename src/component/Task/{ => modals}/AsyncTask/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/AsyncTask/CreateModal/index.tsx (87%) rename src/component/Task/{ => modals}/AsyncTask/DetailContent/index.less (100%) rename src/component/Task/{ => modals}/AsyncTask/DetailContent/index.tsx (97%) rename src/component/Task/{ => modals}/AsyncTask/index.tsx (100%) rename src/component/Task/{ => modals}/CreateModals.tsx (100%) rename src/component/Task/{ => modals}/DataArchiveTask/CreateModal/ArchiveRange.tsx (92%) rename src/component/Task/{ => modals}/DataArchiveTask/CreateModal/VariableConfig.tsx (88%) create mode 100644 src/component/Task/modals/DataArchiveTask/CreateModal/const.ts rename src/component/Task/{ => modals}/DataArchiveTask/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/DataArchiveTask/CreateModal/index.tsx (96%) rename src/component/Task/{ => modals}/DataArchiveTask/DetailContent/ArchiveRange.tsx (97%) rename src/component/Task/{ => modals}/DataArchiveTask/DetailContent/index.tsx (97%) rename src/component/Task/{ => modals}/DataArchiveTask/index.tsx (100%) rename src/component/Task/{ => modals}/DataClearTask/CreateModal/ArchiveRange.tsx (92%) rename src/component/Task/{ => modals}/DataClearTask/CreateModal/VariableConfig.tsx (85%) create mode 100644 src/component/Task/modals/DataClearTask/CreateModal/const.ts rename src/component/Task/{ => modals}/DataClearTask/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/DataClearTask/CreateModal/index.tsx (96%) rename src/component/Task/{ => modals}/DataClearTask/DetailContent/ArchiveRange.tsx (98%) rename src/component/Task/{ => modals}/DataClearTask/DetailContent/index.tsx (97%) rename src/component/Task/{ => modals}/DataClearTask/index.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleConfigTable.tsx (93%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/RangeInput/index.less (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/RangeInput/index.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/WrapItemWithTitle/index.less (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/WrapItemWithTitle/index.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/index.less (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/index.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/CharItem/converter.ts (98%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/CharItem/defaultValue.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/CharItem/index.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/DateItem/converter.ts (97%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/DateItem/defaultValue.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/DateItem/index.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/IntervalItem/converter.ts (95%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/IntervalItem/defaultValue.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/IntervalItem/index.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/NumberItem/converter.ts (97%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/NumberItem/defaultValue.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/NumberItem/index.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/OtherItem/converter.ts (95%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/OtherItem/defaultValue.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/OtherItem/index.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/ruleItems/valid.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleContent/util.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/RuleSelect.tsx (100%) create mode 100644 src/component/Task/modals/DataMockerTask/CreateModal/const.ts rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/form.tsx (85%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/index.tsx (100%) rename src/component/Task/{ => modals}/DataMockerTask/CreateModal/type.ts (100%) rename src/component/Task/{ => modals}/DataMockerTask/DetailContent/index.tsx (95%) rename src/component/Task/{ => modals}/DataMockerTask/index.tsx (100%) rename src/component/Task/{DetailModal.tsx => modals/DetailModals.tsx} (97%) rename src/component/Task/{ => modals}/ExportTask/CreateModal/ExportForm/ConfigPanel/index.tsx (77%) rename src/component/Task/{ => modals}/ExportTask/CreateModal/ExportForm/ExportSelecter/index.less (100%) rename src/component/Task/{ => modals}/ExportTask/CreateModal/ExportForm/ExportSelecter/index.tsx (100%) rename src/component/Task/{ => modals}/ExportTask/CreateModal/ExportForm/FormContext.tsx (100%) rename src/component/Task/{ => modals}/ExportTask/CreateModal/ExportForm/ObjSelecterPanel/index.tsx (71%) rename src/component/Task/{ => modals}/ExportTask/CreateModal/ExportForm/index.less (100%) rename src/component/Task/{ => modals}/ExportTask/CreateModal/ExportForm/index.tsx (100%) create mode 100644 src/component/Task/modals/ExportTask/CreateModal/const.ts rename src/component/Task/{ => modals}/ExportTask/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/ExportTask/CreateModal/index.tsx (99%) rename src/component/Task/{ => modals}/ExportTask/index.tsx (87%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/ImportForm/ConfigPanel/index.tsx (77%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/ImportForm/CsvProvider.ts (100%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/ImportForm/FileSelecterPanel/index.less (100%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/ImportForm/FileSelecterPanel/index.tsx (94%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/ImportForm/FormConfigContext.tsx (100%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/ImportForm/FormContext.ts (100%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/ImportForm/formitem/CsvFormItem.tsx (78%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/ImportForm/formitem/StructDataFormItem.tsx (83%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/ImportForm/helper.ts (100%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/ImportForm/index.less (100%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/ImportForm/index.tsx (100%) create mode 100644 src/component/Task/modals/ImportTask/CreateModal/const.ts rename src/component/Task/{ => modals}/ImportTask/CreateModal/csvMapping/editable.less (100%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/csvMapping/editable.tsx (100%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/csvMapping/index.tsx (100%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/ImportTask/CreateModal/index.tsx (99%) rename src/component/Task/{ => modals}/ImportTask/index.tsx (87%) rename src/component/Task/{ => modals}/LogicDatabaseAsyncTask/CreateModal/PopconfirmButton.tsx (100%) rename src/component/Task/{ => modals}/LogicDatabaseAsyncTask/CreateModal/PreviewSQLDrawer.tsx (100%) create mode 100644 src/component/Task/modals/LogicDatabaseAsyncTask/CreateModal/const.ts rename src/component/Task/{ => modals}/LogicDatabaseAsyncTask/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/LogicDatabaseAsyncTask/CreateModal/index.tsx (86%) rename src/component/Task/{ => modals}/LogicDatabaseAsyncTask/DetailContent/index.tsx (97%) rename src/component/Task/{ => modals}/LogicDatabaseAsyncTask/index.tsx (100%) rename src/component/Task/{ => modals}/MutipleAsyncTask/CreateModal/DatabaseQueue.tsx (100%) rename src/component/Task/{ => modals}/MutipleAsyncTask/CreateModal/DrawerFooter.tsx (100%) rename src/component/Task/{ => modals}/MutipleAsyncTask/CreateModal/InnerSelecter.tsx (93%) rename src/component/Task/{ => modals}/MutipleAsyncTask/CreateModal/MoreSetting.tsx (57%) rename src/component/Task/{ => modals}/MutipleAsyncTask/CreateModal/MultipleAsyncContext.ts (100%) rename src/component/Task/{ => modals}/MutipleAsyncTask/CreateModal/ProjectSelect.tsx (78%) rename src/component/Task/{ => modals}/MutipleAsyncTask/CreateModal/helper.tsx (89%) rename src/component/Task/{ => modals}/MutipleAsyncTask/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/MutipleAsyncTask/CreateModal/index.tsx (92%) rename src/component/Task/{ => modals}/MutipleAsyncTask/DetailContent/index.less (100%) rename src/component/Task/{ => modals}/MutipleAsyncTask/DetailContent/index.tsx (98%) rename src/component/Task/{ => modals}/MutipleAsyncTask/components/Template/CreateTemplate.tsx (78%) rename src/component/Task/{ => modals}/MutipleAsyncTask/components/Template/EditTemplate.tsx (94%) rename src/component/Task/{ => modals}/MutipleAsyncTask/components/Template/ManageTemplate.tsx (100%) rename src/component/Task/{ => modals}/MutipleAsyncTask/components/Template/SelectTemplate.tsx (100%) rename src/component/Task/{ => modals}/MutipleAsyncTask/components/Template/ShowTemplate.tsx (100%) rename src/component/Task/{ => modals}/MutipleAsyncTask/components/Template/index.less (100%) rename src/component/Task/{ => modals}/MutipleAsyncTask/components/Template/index.tsx (100%) create mode 100644 src/component/Task/modals/MutipleAsyncTask/const.ts rename src/component/Task/{ => modals}/MutipleAsyncTask/index.tsx (100%) create mode 100644 src/component/Task/modals/PartitionTask/CreateModal/const.ts rename src/component/Task/{ => modals}/PartitionTask/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/PartitionTask/CreateModal/index.tsx (94%) rename src/component/Task/{ => modals}/PartitionTask/DetailContent/CycleDescriptionItem.tsx (99%) rename src/component/Task/{ => modals}/PartitionTask/DetailContent/index.less (100%) rename src/component/Task/{ => modals}/PartitionTask/DetailContent/index.tsx (96%) rename src/component/Task/{ => modals}/PartitionTask/index.tsx (100%) rename src/component/Task/{ => modals}/PermissionApplication/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/PermissionApplication/CreateModal/index.tsx (99%) rename src/component/Task/{ => modals}/PermissionApplication/index.tsx (100%) rename src/component/Task/{ => modals}/ResultSetExportTask/CreateModal/CsvFormItemPanel.tsx (83%) create mode 100644 src/component/Task/modals/ResultSetExportTask/CreateModal/const.ts rename src/component/Task/{ => modals}/ResultSetExportTask/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/ResultSetExportTask/CreateModal/index.tsx (85%) rename src/component/Task/{ => modals}/ResultSetExportTask/DetailContent/index.tsx (98%) rename src/component/Task/{ => modals}/ResultSetExportTask/index.tsx (100%) create mode 100644 src/component/Task/modals/SQLPlanTask/CreateModal/const.ts rename src/component/Task/{ => modals}/SQLPlanTask/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/SQLPlanTask/CreateModal/index.tsx (81%) rename src/component/Task/{ => modals}/SQLPlanTask/CreateModal/interface.ts (100%) rename src/component/Task/{ => modals}/SQLPlanTask/DetailContent/index.tsx (98%) rename src/component/Task/{ => modals}/SQLPlanTask/index.tsx (100%) rename src/component/Task/{ => modals}/ShadowSyncTask/CreateModal/SelectPanel/index.less (100%) rename src/component/Task/{ => modals}/ShadowSyncTask/CreateModal/SelectPanel/index.tsx (92%) rename src/component/Task/{ => modals}/ShadowSyncTask/CreateModal/StructConfigPanel/RecordSQLView/index.tsx (100%) rename src/component/Task/{ => modals}/ShadowSyncTask/CreateModal/StructConfigPanel/StructAnalysisResult/column.tsx (100%) rename src/component/Task/{ => modals}/ShadowSyncTask/CreateModal/StructConfigPanel/StructAnalysisResult/index.tsx (100%) rename src/component/Task/{ => modals}/ShadowSyncTask/CreateModal/StructConfigPanel/index.tsx (85%) create mode 100644 src/component/Task/modals/ShadowSyncTask/CreateModal/const.ts rename src/component/Task/{ => modals}/ShadowSyncTask/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/ShadowSyncTask/CreateModal/index.tsx (100%) rename src/component/Task/{ => modals}/ShadowSyncTask/CreateModal/interface.ts (100%) rename src/component/Task/{ => modals}/ShadowSyncTask/DetailContent/index.tsx (95%) rename src/component/Task/{ => modals}/ShadowSyncTask/index.tsx (100%) rename src/component/Task/{ => modals}/StructureComparisonTask/CreateModal/TableSelector.tsx (100%) create mode 100644 src/component/Task/modals/StructureComparisonTask/CreateModal/const.ts rename src/component/Task/{ => modals}/StructureComparisonTask/CreateModal/index.less (100%) rename src/component/Task/{ => modals}/StructureComparisonTask/CreateModal/index.tsx (88%) rename src/component/Task/{ => modals}/StructureComparisonTask/CreateModal/interface.ts (100%) rename src/component/Task/{ => modals}/StructureComparisonTask/DetailContent/index.less (100%) rename src/component/Task/{ => modals}/StructureComparisonTask/DetailContent/index.tsx (99%) rename src/component/Task/{ => modals}/StructureComparisonTask/index.tsx (100%) diff --git a/src/common/network/task.ts b/src/common/network/task.ts index 98e4f3f15..9ea01fe0f 100644 --- a/src/common/network/task.ts +++ b/src/common/network/task.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { IShadowSyncAnalysisResult } from '@/component/Task/ShadowSyncTask/CreateModal/interface'; +import { IShadowSyncAnalysisResult } from '@/component/Task/modals/ShadowSyncTask/CreateModal/interface'; import { AgainTaskRecord, CommonTaskLogType, diff --git a/src/component/OSSDragger/index.tsx b/src/component/OSSDragger/index.tsx index 2891cd8c5..9239449e6 100644 --- a/src/component/OSSDragger/index.tsx +++ b/src/component/OSSDragger/index.tsx @@ -20,7 +20,7 @@ import { uploadFileToOSS } from '@/util/aliyun'; import { Upload } from 'antd'; import { DraggerProps } from 'antd/lib/upload'; import React from 'react'; -import { getImportTypeByFileExtension } from '../Task/ImportTask/CreateModal/ImportForm/helper'; +import { getImportTypeByFileExtension } from '../Task/modals/ImportTask/CreateModal/ImportForm/helper'; interface IProps extends DraggerProps { uploadFileOpenAPIName?: string; diff --git a/src/component/Task/component/ActionBar/helper.tsx b/src/component/Task/component/ActionBar/helper.tsx new file mode 100644 index 000000000..d4ddaeebd --- /dev/null +++ b/src/component/Task/component/ActionBar/helper.tsx @@ -0,0 +1,186 @@ +import { TaskStatus, TaskType } from '@/d.ts'; +import modalStore from '@/store/modal'; +import { formatMessage } from '@/util/intl'; + +export const actions = { + [TaskType.DATA_ARCHIVE]: (args) => modalStore.changeDataArchiveModal(true, args), + [TaskType.DATA_DELETE]: (args) => modalStore.changeDataClearModal(true, args), + [TaskType.SQL_PLAN]: (args) => modalStore.changeCreateSQLPlanTaskModal(true, args), + [TaskType.LOGICAL_DATABASE_CHANGE]: (args) => modalStore.changeLogicialDatabaseModal(true, args), + [TaskType.ASYNC]: (args) => modalStore.changeCreateAsyncTaskModal(true, args), + [TaskType.DATAMOCK]: (args) => modalStore.changeDataMockerModal(true, args), + [TaskType.APPLY_DATABASE_PERMISSION]: (args) => + modalStore.changeApplyDatabasePermissionModal(true, args), + [TaskType.APPLY_TABLE_PERMISSION]: (args) => + modalStore.changeApplyTablePermissionModal(true, args), + [TaskType.MULTIPLE_ASYNC]: (args) => modalStore.changeMultiDatabaseChangeModal(true, args), + [TaskType.SHADOW]: (args) => modalStore.changeShadowSyncVisible(true, args), + [TaskType.STRUCTURE_COMPARISON]: (args) => modalStore.changeStructureComparisonModal(true, args), + [TaskType.EXPORT]: (args) => modalStore.changeExportModal(true, args), + [TaskType.IMPORT]: (args) => modalStore.changeImportModal(true, args), + [TaskType.EXPORT_RESULT_SET]: (args) => + modalStore.changeCreateResultSetExportTaskModal(true, args), + [TaskType.ONLINE_SCHEMA_CHANGE]: (args) => modalStore.changeCreateDDLAlterTaskModal(true, args), + [TaskType.PARTITION_PLAN]: (args) => modalStore.changePartitionModal(true, args), +}; +/** 周期任务 */ + +export const SCHEDULE_TASKS = [TaskType.DATA_ARCHIVE, TaskType.DATA_DELETE, TaskType.SQL_PLAN]; + +/** 作业调度任务 */ +export const JOB_SCHEDULE_TASKS = [TaskType.DATA_ARCHIVE, TaskType.DATA_DELETE]; + +export const limitRertyButtonShowConfig = { + [TaskStatus.COMPLETED]: [ + TaskType.DATA_ARCHIVE, + TaskType.DATA_DELETE, + TaskType.LOGICAL_DATABASE_CHANGE, + ], +}; + +export const actionInfo = { + reTryBtn: { + key: 'reTry', + text: formatMessage({ + id: 'src.component.Task.component.ActionBar.C324AD20', + defaultMessage: '再次发起', + }), //'再次发起' + type: 'button', + }, + editBtn: { + key: 'edit', + text: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.Edit', + defaultMessage: '编辑', + }), //编辑 + type: 'button', + }, + stopBtn: { + key: 'stop', + text: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.Termination', + defaultMessage: '终止', + }), //终止 + type: 'button', + }, + disableBtn: { + key: 'disable', + text: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.Disable', + defaultMessage: '禁用', + }), //禁用 + type: 'button', + }, + stopScheduleTaskBtn: { + key: 'stopLogicalChangeTask', + text: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.Termination', + defaultMessage: '终止', + }), //终止 + type: 'button', + }, + enableBtn: { + key: 'enable', + text: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.Enable', + defaultMessage: '启用', + }), //启用 + type: 'button', + }, + deleteBtn: { + key: 'delete', + text: formatMessage({ + id: 'src.component.Task.component.ActionBar.E16B982C', + defaultMessage: '删除', + }), + type: 'button', + }, + closeBtn: { + key: 'close', + text: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.Close', + defaultMessage: '关闭', + }), + type: 'button', + }, + copyBtn: { + key: 'copy', + text: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.Copy', + defaultMessage: '复制', + }), + type: 'button', + }, + rollbackBtn: { + key: 'rollback', + text: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.RollBack', + defaultMessage: '回滚', + }), + type: 'button', + }, + executeBtn: { + key: 'execute', + text: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.Run', + defaultMessage: '执行', + }), + type: 'button', + }, + approvalBtn: { + key: 'approval', + text: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.Pass', + defaultMessage: '通过', + }), + type: 'button', + }, + againBtn: { + key: 'again', + text: formatMessage({ + id: 'src.component.Task.component.ActionBar.57DBF8A7', + defaultMessage: '重试', + }), + type: 'button', + }, + downloadBtn: { + key: 'download', + text: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.Download', + defaultMessage: '下载', + }), + type: 'button', + }, + downloadSQLBtn: { + key: 'downloadSQL', + text: formatMessage({ + id: 'src.component.Task.component.ActionBar.DBA6CB6E', + defaultMessage: '下载 SQL', + }), //'下载 SQL' + type: 'button', + }, + structrueComparisonBySQL: { + key: 'structrueComparisonBySQL', + text: formatMessage({ + id: 'src.component.Task.component.ActionBar.46F2F0ED', + defaultMessage: '发起结构同步', + }), //'发起结构同步' + type: 'button', + }, + openLocalFolder: { + key: 'openLocalFolder', + text: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.OpenFolder', + defaultMessage: '打开文件夹', + }), + type: 'button', + }, + downloadViewResultBtn: { + key: 'downloadViewResult', + text: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.DownloadQueryResults', + defaultMessage: '下载查询结果', + }), + type: 'button', + }, +}; diff --git a/src/component/Task/component/ActionBar/index.tsx b/src/component/Task/component/ActionBar/index.tsx index 3a1e4d174..91263b2e8 100644 --- a/src/component/Task/component/ActionBar/index.tsx +++ b/src/component/Task/component/ActionBar/index.tsx @@ -27,7 +27,7 @@ import { getTaskDetail, } from '@/common/network/task'; import Action from '@/component/Action'; -import { TaskTypeMap } from '@/component/Task/component/TaskTable'; +import { TaskTypeMap } from '@/component/Task/component/TaskTable/const'; import type { ICycleSubTaskRecord, ICycleTaskRecord, @@ -58,14 +58,23 @@ import type { TaskStore } from '@/store/task'; import ipcInvoke from '@/util/client/service'; import { isClient } from '@/util/env'; import { formatMessage } from '@/util/intl'; -import { downloadFile, getLocalFormatDateTime } from '@/util/utils'; +import { downloadFile, getLocalFormatDateTime, uniqueTools } from '@/util/utils'; import { message, Modal, Popconfirm, Tooltip } from 'antd'; import { inject, observer } from 'mobx-react'; import React, { useEffect, useMemo, useState } from 'react'; -import { isCycleTask, isLogicalDbChangeTask } from '../../helper'; +import { isCycleTask, isLogicalDbChangeTask } from '@/component/Task/helper'; import RollBackModal from '../RollbackModal'; import { ProjectRole } from '@/d.ts/project'; import { useRequest } from 'ahooks'; +import { taskSuccessHintInfo } from '@/constant'; +import { + actionInfo, + actions, + JOB_SCHEDULE_TASKS, + limitRertyButtonShowConfig, + SCHEDULE_TASKS, +} from './helper'; +import { IAddOperationsParams } from './type'; interface IProps { userStore?: UserStore; taskStore?: TaskStore; @@ -92,7 +101,6 @@ const ActionBar: React.FC = inject( )( observer((props) => { const { - taskStore, modalStore, userStore: { user }, settingStore, @@ -122,11 +130,13 @@ const ActionBar: React.FC = inject( } return cancel(); }, [task?.id]); + const getScheduleTask = async () => { const taskList = await getDataArchiveSubTask(task?.id); setTaskList(taskList?.contents); return taskList?.contents; }; + const { run: loadtaskList, cancel } = useRequest(getScheduleTask, { pollingInterval: 3000, manual: true, @@ -141,7 +151,7 @@ const ActionBar: React.FC = inject( }, }); - const openTaskDetail = async () => { + const _openTaskDetail = async () => { props.onDetailVisible(task as TaskRecord, true); }; @@ -157,19 +167,24 @@ const ActionBar: React.FC = inject( setActiveBtnKey('stop'); const res = await stopTask(task.id); if (res) { - message.success( - formatMessage({ - id: 'odc.components.TaskManagePage.TerminatedSuccessfully', - defaultMessage: '终止成功', - }), - ); + message.success(taskSuccessHintInfo.terminate); props?.onReloadList?.(); props?.onReload?.(); } }; - const deleteTask = async () => { + const _executeTask = async () => { + setActiveBtnKey('execute'); + const res = await executeTask(task.id); + if (res) { + message.success(taskSuccessHintInfo.start); + closeTaskDetail(); + props?.onReloadList?.(); + } + }; + + const _deleteTask = async () => { const { id } = task; const res = await createTask({ taskType: TaskType.ALTER_SCHEDULE, @@ -180,12 +195,7 @@ const ActionBar: React.FC = inject( }); if (res) { setDelTaskList?.([...delTaskList, id]); - message.success( - formatMessage({ - id: 'src.component.Task.component.ActionBar.9EDD0936', - defaultMessage: '删除成功', - }), - ); + message.success(taskSuccessHintInfo.delete); props?.onReloadList?.(); } }; @@ -202,7 +212,7 @@ const ActionBar: React.FC = inject( const confirmRollback = async (type: RollbackType) => { closeTaskDetail(); - props.modalStore.changeCreateAsyncTaskModal(true, { + actions[TaskType.ASYNC]({ type, task: task as TaskDetail, databaseId: task?.database?.id, @@ -217,7 +227,7 @@ const ActionBar: React.FC = inject( } }, [task?.status]); - const handleRollback = async () => { + const _rollbackTask = async () => { setOpenRollback(true); }; @@ -225,85 +235,46 @@ const ActionBar: React.FC = inject( setOpenRollback(false); }; - const handleExecute = async () => { - setActiveBtnKey('execute'); - const res = await executeTask(task.id); - if (res) { - message.success( - formatMessage({ - id: 'src.component.Task.component.ActionBar.10A4FEFD', - defaultMessage: '开始执行', - }), - ); - closeTaskDetail(); - props?.onReloadList?.(); - } - }; - - const handleApproval = async (status: boolean) => { + const _approvalTask = async (status: boolean) => { props.onApprovalVisible(status, true); }; - const handleReTry = async () => { + const _retryTask = async () => { const { type } = task; switch (type) { - case TaskType.ASYNC: { - const detailRes = (await getTaskDetail(task?.id)) as TaskDetail; - props.modalStore.changeCreateAsyncTaskModal(true, { - task: detailRes, - }); - return; - } + case TaskType.ASYNC: case TaskType.DATAMOCK: { - const detailRes = (await getTaskDetail(task?.id)) as TaskDetail; - props.modalStore.changeDataMockerModal(true, { - task: detailRes, - }); + const detailRes = (await getTaskDetail(task?.id)) as TaskDetail; + actions[type]({ task: detailRes }); return; } case TaskType.APPLY_DATABASE_PERMISSION: { - modalStore.changeApplyDatabasePermissionModal(true, { + actions[type]({ task: task as TaskDetail, }); return; } case TaskType.APPLY_TABLE_PERMISSION: { - modalStore.changeApplyTablePermissionModal(true, { + actions[type]({ task: task as TaskDetail, }); return; } case TaskType.MULTIPLE_ASYNC: { - modalStore.changeMultiDatabaseChangeModal(true, { + actions[type]({ projectId: (task as TaskDetail)?.parameters?.projectId, task: task as TaskDetail, }); return; } - case TaskType.SHADOW: { - modalStore.changeShadowSyncVisible(true, { - taskId: task?.id, - databaseId: task.database?.id, - }); - return; - } - case TaskType.STRUCTURE_COMPARISON: { - modalStore.changeStructureComparisonModal(true, { - databaseId: task.database?.id, - taskId: task?.id, - }); - return; - } - case TaskType.EXPORT: { - modalStore.changeExportModal(true, { - databaseId: task.database?.id, - taskId: task?.id, - }); - return; - } - case TaskType.IMPORT: { - modalStore.changeImportModal(true, { + case TaskType.SHADOW: + case TaskType.STRUCTURE_COMPARISON: + case TaskType.EXPORT: + case TaskType.IMPORT: + case TaskType.ONLINE_SCHEMA_CHANGE: + case TaskType.PARTITION_PLAN: { + actions[type]({ databaseId: task.database?.id, taskId: task?.id, }); @@ -313,7 +284,7 @@ const ActionBar: React.FC = inject( const detailRes = (await getTaskDetail( task?.id, )) as TaskDetail; - modalStore.changeCreateResultSetExportTaskModal(true, { + actions[type]({ databaseId: task.database?.id, taskId: task?.id, sql: detailRes.parameters.sql, @@ -321,20 +292,6 @@ const ActionBar: React.FC = inject( }); return; } - case TaskType.ONLINE_SCHEMA_CHANGE: { - modalStore.changeCreateDDLAlterTaskModal(true, { - databaseId: task.database?.id, - taskId: task?.id, - }); - return; - } - case TaskType.PARTITION_PLAN: { - modalStore.changePartitionModal(true, { - databaseId: task.database?.id, - taskId: task?.id, - }); - return; - } default: { const { database, executionStrategy, executionTime, parameters, description } = task; @@ -349,85 +306,51 @@ const ActionBar: React.FC = inject( const res = await createTask(data); if (res) { - message.success( - formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.InitiatedAgain', - defaultMessage: '再次发起成功', - }), - - //再次发起成功 - ); + message.success(taskSuccessHintInfo.retry); //再次发起成功 } } } }; - const handleAgain = async () => { + const _againTask = async () => { const { id } = task; const res = await againTask({ id: id }); if (res) { - message.success( - formatMessage({ - id: 'src.component.Task.component.ActionBar.15961986', - defaultMessage: '发起重试成功', - }), - ); + message.success(taskSuccessHintInfo.again); props?.onReloadList?.(); props?.onReload?.(); } }; - const editCycleTask = async () => { + const _editCycleTask = async () => { props?.onClose?.(); - switch (task?.type) { - case TaskType.DATA_ARCHIVE: { - props.modalStore.changeDataArchiveModal(true, { - id: task?.id, - type: 'EDIT', - }); - break; - } - case TaskType.DATA_DELETE: { - props.modalStore.changeDataClearModal(true, { - id: task?.id, - type: 'EDIT', - }); - break; - } - default: { - props.modalStore.changeCreateSQLPlanTaskModal(true, { - id: task?.id, - }); - } - } + const actionType = JOB_SCHEDULE_TASKS.includes(task?.type) ? task?.type : TaskType.SQL_PLAN; + actions?.[actionType]?.({ + id: task?.id, + type: JOB_SCHEDULE_TASKS.includes(task?.type) ? ('EDIT' as 'EDIT') : undefined, + }); }; - const handleReTryCycleTask = async () => { + const _retryCycleTask = async () => { props?.onClose?.(); switch (task?.type) { - case TaskType.DATA_ARCHIVE: { - props.modalStore.changeDataArchiveModal(true, { + case TaskType.DATA_ARCHIVE: + case TaskType.DATA_DELETE: { + actions?.[task?.type]?.({ id: task?.id, type: 'RETRY', }); break; } case TaskType.LOGICAL_DATABASE_CHANGE: { - modalStore.changeLogicialDatabaseModal(true, { + actions?.[task?.type]?.({ task: task, }); break; } - case TaskType.DATA_DELETE: { - props.modalStore.changeDataClearModal(true, { - id: task?.id, - type: 'RETRY', - }); - break; - } case TaskType.SQL_PLAN: { - modalStore.changeCreateSQLPlanTaskModal(true, { + actions?.[task?.type]?.({ databaseId: task.database?.id, taskId: task?.id, }); @@ -436,158 +359,121 @@ const ActionBar: React.FC = inject( } }; - const stopScheduleTask = async () => { + const _stopScheduleTask = async () => { await stopDataArchiveSubTask(task?.id, taskList?.[0]?.id); await getScheduleTask(); props?.onReload?.(); }; - const disableCycleTask = async () => { - let databaseId; - if (task.database) { - databaseId = task.database?.id; - } else { - databaseId = (task as ICycleTaskRecord).jobParameters - ?.databaseId; - } - Modal.confirm({ - title: formatMessage( - { - id: 'src.component.Task.component.ActionBar.5495D4C7', - defaultMessage: '确认要禁用此{TaskTypeMapTaskType}?', - }, - { TaskTypeMapTaskType: TaskTypeMap[task.type] }, - ), - content: ( - <> -
- {formatMessage( - { - id: 'src.component.Task.component.ActionBar.EC0C09D6', - defaultMessage: '禁用{TaskTypeMapTaskType}', - }, - { TaskTypeMapTaskType: TaskTypeMap[task.type] }, - )} -
-
- { - formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.TheTaskNeedsToBe', - defaultMessage: '任务需要重新审批,审批通过后此任务将禁用', - }) /*任务需要重新审批,审批通过后此任务将禁用*/ - } -
- - ), - - cancelText: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Cancel', - defaultMessage: '取消', - }), //取消 - okText: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Ok.2', - defaultMessage: '确定', - }), //确定 - centered: true, - onOk: async () => { - await createTask({ - databaseId, - taskType: TaskType.ALTER_SCHEDULE, - parameters: { - taskId: task.id, - operationType: 'PAUSE', - }, - }); - props?.onReload?.(); + const _alterScheduleTask = async ({ databaseId, operationType }) => { + await createTask({ + databaseId, + taskType: TaskType.ALTER_SCHEDULE, + parameters: { + taskId: task.id, + operationType, }, }); + props?.onReload?.(); }; - const enableCycleTask = async () => { + const handleTaskOperation = async ({ + operationType, + callback, + }: { + operationType: TaskOperationType; + callback?: () => void; + }) => { let databaseId; - if (task.database) { - databaseId = task.database?.id; + if (task?.database) { + databaseId = task?.database?.id; } else { - databaseId = (task as ICycleTaskRecord).jobParameters + databaseId = (task as ICycleTaskRecord)?.jobParameters ?.databaseId; } - Modal.confirm({ - title: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.AreYouSureYouWant.2', - defaultMessage: '是否确认启用此 SQL 计划?', - }), //确认要启用此 SQL 计划吗? - content: ( - <> -
- { - formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.EnableSqlScheduling', - defaultMessage: '启用 SQL 计划', - }) /*启用 SQL 计划*/ - } -
-
- { - formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.TheTaskNeedsToBe.1', - defaultMessage: '任务需要重新审批,审批通过后此任务将启用', - }) /*任务需要重新审批,审批通过后此任务将启用*/ - } -
- - ), - - cancelText: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Cancel', - defaultMessage: '取消', - }), //取消 - okText: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Ok.2', - defaultMessage: '确定', - }), //确定 - centered: true, - onOk: async () => { - await createTask({ - databaseId, - taskType: TaskType.ALTER_SCHEDULE, - parameters: { - taskId: task?.id, - operationType: 'RESUME', + const taskTypeName = TaskTypeMap[task?.type]; + const config = { + [TaskOperationType.RESUME]: { + title: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.AreYouSureYouWant.2', + defaultMessage: '是否确认启用此 SQL 计划?', + }), + content: ( + <> +
+ { + formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.EnableSqlScheduling', + defaultMessage: '启用 SQL 计划', + }) /*启用 SQL 计划*/ + } +
+
+ { + formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.TheTaskNeedsToBe.1', + defaultMessage: '任务需要重新审批,审批通过后此任务将启用', + }) /*任务需要重新审批,审批通过后此任务将启用*/ + } +
+ + ), + }, + [TaskOperationType.TERMINATE]: { + title: formatMessage( + { + id: 'src.component.Task.component.ActionBar.718054C5', + defaultMessage: '确认要终止此{taskTypeName}?', }, - }); - props?.onReload?.(); + { taskTypeName }, + ), + content: ( + <> +
+ {formatMessage({ + id: 'src.component.Task.component.ActionBar.5E24502A', + defaultMessage: '任务终止后将不可恢复', + })} +
+ + ), + [TaskOperationType.PAUSE]: { + title: formatMessage( + { + id: 'src.component.Task.component.ActionBar.5495D4C7', + defaultMessage: '确认要禁用此{TaskTypeMapTaskType}?', + }, + { TaskTypeMapTaskType: taskTypeName }, + ), + content: ( + <> +
+ {formatMessage( + { + id: 'src.component.Task.component.ActionBar.EC0C09D6', + defaultMessage: '禁用{TaskTypeMapTaskType}', + }, + { TaskTypeMapTaskType: taskTypeName }, + )} +
+
+ { + formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.TheTaskNeedsToBe', + defaultMessage: '任务需要重新审批,审批通过后此任务将禁用', + }) /*任务需要重新审批,审批通过后此任务将禁用*/ + } +
+ + ), + }, }, - }); - }; + }; + const { title, content } = config[operationType] || {}; - const stopCycleTask = async () => { - let databaseId; - if (task.database) { - databaseId = task.database?.id; - } else { - databaseId = (task as ICycleTaskRecord).jobParameters - ?.databaseId; - } - const taskTypeName = TaskTypeMap[task?.type]; Modal.confirm({ - title: formatMessage( - { - id: 'src.component.Task.component.ActionBar.718054C5', - defaultMessage: '确认要终止此{taskTypeName}?', - }, - { taskTypeName }, - ), - content: ( - <> -
- {formatMessage({ - id: 'src.component.Task.component.ActionBar.5E24502A', - defaultMessage: '任务终止后将不可恢复', - })} -
- - ), - + title, + content, cancelText: formatMessage({ id: 'odc.TaskManagePage.component.TaskTools.Cancel', defaultMessage: '取消', @@ -598,25 +484,12 @@ const ActionBar: React.FC = inject( }), //确定 centered: true, onOk: async () => { - setActiveBtnKey('stop'); - await createTask({ - databaseId, - taskType: TaskType.ALTER_SCHEDULE, - parameters: { - taskId: task?.id, - operationType: TaskOperationType.TERMINATE, - }, - }); - props?.onReload?.(); + callback?.(); + await _alterScheduleTask({ databaseId, operationType }); }, }); }; - /** 去重数组 */ - const uniqueTools = (tools) => { - return Array.from(new Map(tools.map((obj) => [obj.key, obj])).values()); - }; - /** * 判断是否是创建人、项目DBA、项目owner,以操作工单 */ @@ -634,9 +507,41 @@ const ActionBar: React.FC = inject( tools.push(reTryBtn); } }; + const commonButtonConfig = { + viewBtn: { + key: 'view', + text: formatMessage({ id: 'odc.TaskManagePage.AsyncTask.See', defaultMessage: '查看' }), // 查看 + action: _openTaskDetail, + type: 'button', + isOpenBtn: true, + }, + rejectBtn: { + key: 'reject', + text: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.Reject', + defaultMessage: '拒绝', + }), + + //拒绝 + type: 'button', + action: async () => { + _approvalTask(false); + }, + }, + }; const getTaskTools = (_task) => { let tools = []; + const addOperations = ({ auth, taskTypeLimit, operations }: IAddOperationsParams) => { + const hasOperaitons = Boolean(operations?.length); + const useableTaskType = + (taskTypeLimit && taskTypeLimit.includes(task?.type)) || Boolean(taskTypeLimit?.length); + if (auth && useableTaskType && hasOperaitons) { + tools.push(...operations); + return true; + } + return false; + }; if (!_task) { return []; @@ -656,241 +561,223 @@ const ActionBar: React.FC = inject( SubTaskStatus.DONE === structureComparisonData?.status && ((structureComparisonData?.overSizeLimit && structureComparisonData?.storageObjectId) || (!structureComparisonData?.overSizeLimit && - !(structureComparisonData?.totalChangeScript?.length > 0))); - const viewBtn = { - key: 'view', - text: formatMessage({ id: 'odc.TaskManagePage.AsyncTask.See', defaultMessage: '查看' }), // 查看 - action: openTaskDetail, - type: 'button', - isOpenBtn: true, - }; - - const closeBtn = { - key: 'close', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Close', - defaultMessage: '关闭', - }), - - //关闭 - action: closeTaskDetail, - type: 'button', - }; - - const copyBtn = { - key: 'copy', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Copy', - defaultMessage: '复制', - }), - - //复制 - action: handleCopy, - type: 'button', - isOpenBtn: true, - }; - - const rollbackBtn = { - key: 'rollback', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.RollBack', - defaultMessage: '回滚', - }), - - //回滚 - action: handleRollback, - type: 'button', - }; - - const stopBtn = { - key: 'stop', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Terminate', - defaultMessage: '终止', - }), - - //终止 - action: _stopTask, - type: 'button', - }; - - const executeBtn = { - key: 'execute', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Run', - defaultMessage: '执行', - }), - - //执行 - type: 'button', - action: handleExecute, - isOpenBtn: true, - isPrimary: isDetailModal, - disabled: false, - tooltip: '', - }; - - const approvalBtn = { - key: 'approval', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Pass', - defaultMessage: '通过', - }), - - //通过 - type: 'button', - isPrimary: isDetailModal, - disabled: disabledApproval, - tooltip: disabledApproval - ? formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.SetPartitionPoliciesForAll', - defaultMessage: '请设置所有Range分区表的分区策略', - }) - : //请设置所有Range分区表的分区策略 - null, - action: async () => { - handleApproval(true); + !Boolean(structureComparisonData?.totalChangeScript?.length))); + const buttonConfig = { + ...commonButtonConfig, + closeBtn: { + ...actionInfo.closeBtn, + //关闭 + action: closeTaskDetail, }, - }; + copyBtn: { + ...actionInfo.copyBtn, + //复制 + action: handleCopy, - const rejectBtn = { - key: 'reject', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Reject', - defaultMessage: '拒绝', - }), - - //拒绝 - type: 'button', - action: async () => { - handleApproval(false); + isOpenBtn: true, + }, + rollbackBtn: { + ...actionInfo.rollbackBtn, + //回滚 + action: _rollbackTask, + }, + stopBtn: { + ...actionInfo.stopBtn, + //终止 + action: _stopTask, + }, + executeBtn: { + ...actionInfo.executeBtn, + //执行 + action: _executeTask, + isOpenBtn: true, + isPrimary: isDetailModal, + disabled: false, + tooltip: '', + }, + approvalBtn: { + ...actionInfo.approvalBtn, + //通过 + isPrimary: isDetailModal, + disabled: disabledApproval, + tooltip: disabledApproval + ? formatMessage({ + id: 'odc.TaskManagePage.component.TaskTools.SetPartitionPoliciesForAll', + defaultMessage: '请设置所有Range分区表的分区策略', + }) + : //请设置所有Range分区表的分区策略 + null, + action: async () => { + _approvalTask(true); + }, + }, + reTryBtn: { + ...actionInfo.reTryBtn, + //再次发起 + action: _retryTask, + }, + againBtn: { + ...actionInfo.againBtn, + // 重试 + action: _againTask, + }, + downloadBtn: { + ...actionInfo.downloadBtn, + disabled: isExpired, + isExpired, + tip: formatMessage({ + id: 'src.component.Task.component.ActionBar.F20AAC3F', + defaultMessage: '文件下载链接已超时,请重新发起工单。', + }), //'文件下载链接已超时,请重新发起工单。' + + action: download, + }, + downloadSQLBtn: { + ...actionInfo.downloadSQLBtn, + disabled: disableBtn || !structureComparisonData?.storageObjectId, + isExpired: disableBtn || !structureComparisonData?.storageObjectId, + tip: formatMessage({ + id: 'src.component.Task.component.ActionBar.A79907A3', + defaultMessage: '暂不可用', + }), //'暂不可用' + action: async () => { + if (structureComparisonData?.storageObjectId) { + const fileUrl = await getStructureComparisonTaskFile(_task?.id, [ + `${structureComparisonData?.storageObjectId}`, + ]); + fileUrl?.forEach((url) => { + url && downloadFile(url); + }); + } + }, + }, + structrueComparisonBySQL: { + ...actionInfo.structrueComparisonBySQL, + isExpired: disableBtn || noAction, + disabled: disableBtn || noAction, + tip: noAction + ? formatMessage({ + id: 'src.component.Task.component.ActionBar.D98B5B62', + defaultMessage: '结构一致,无需发起结构同步', + }) + : formatMessage({ + id: 'src.component.Task.component.ActionBar.4BF7D8BF', + defaultMessage: '暂不可用', + }), + isPrimary: true, + action: async () => { + structureComparisonData && + actions[TaskType.ASYNC]({ + sql: structureComparisonData?.totalChangeScript, + databaseId: structureComparisonData?.database?.id, + rules: null, + }); + }, + }, + openLocalFolder: { + ...actionInfo.openLocalFolder, + //打开文件夹 + action: async () => { + const info = await getTaskResult(task.id); + if (info?.exportZipFilePath) { + ipcInvoke('showItemInFolder', info?.exportZipFilePath); + } + }, + }, + downloadViewResultBtn: { + ...actionInfo.downloadViewResultBtn, + disabled: isExpired, + isExpired, + tip: formatMessage({ + id: 'src.component.Task.component.ActionBar.E9211B1A', + defaultMessage: '文件下载链接已超时,请重新发起工单。', + }), //'文件下载链接已超时,请重新发起工单。' + + action: downloadViewResult, }, }; - const reTryBtn = { - key: 'reTry', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.InitiateAgain', - defaultMessage: '再次发起', - }), - - //再次发起 - type: 'button', - action: handleReTry, + const addRetryButton = () => { + setBtnByCreater(tools, buttonConfig.reTryBtn); }; - const againBtn = { - key: 'again', - text: formatMessage({ - id: 'src.component.Task.component.ActionBar.57DBF8A7', - defaultMessage: '重试', - }), - // 重试 - type: 'button', - action: handleAgain, + const resetToolsForApprover = ( + target?: Array<{ + key: string; + text: any; + type: string; + action: () => Promise; + }>, + ) => { + if (isApprover) { + tools = target || []; + } }; - const downloadBtn = { - key: 'download', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Download', - defaultMessage: '下载', - }), - disabled: isExpired, - isExpired, - tip: formatMessage({ - id: 'src.component.Task.component.ActionBar.F20AAC3F', - defaultMessage: '文件下载链接已超时,请重新发起工单。', - }), //'文件下载链接已超时,请重新发起工单。' - - action: download, - type: 'button', - }; - const downloadSQLBtn = { - key: 'downloadSQL', - text: formatMessage({ - id: 'src.component.Task.component.ActionBar.DBA6CB6E', - defaultMessage: '下载 SQL', - }), //'下载 SQL' - disabled: disableBtn || !structureComparisonData?.storageObjectId, - isExpired: disableBtn || !structureComparisonData?.storageObjectId, - tip: formatMessage({ - id: 'src.component.Task.component.ActionBar.A79907A3', - defaultMessage: '暂不可用', - }), //'暂不可用' - type: 'button', - action: async () => { - if (structureComparisonData?.storageObjectId) { - const fileUrl = await getStructureComparisonTaskFile(_task?.id, [ - `${structureComparisonData?.storageObjectId}`, - ]); - fileUrl?.forEach((url) => { - url && downloadFile(url); - }); - } + const operationNeedPermission = { + [TaskStatus.EXECUTION_ABNORMAL]: { + operations: [buttonConfig.stopBtn, buttonConfig.againBtn], }, - }; - const structrueComparisonBySQL = { - key: 'structrueComparisonBySQL', - text: formatMessage({ - id: 'src.component.Task.component.ActionBar.46F2F0ED', - defaultMessage: '发起结构同步', - }), //'发起结构同步' - isExpired: disableBtn || noAction, - disabled: disableBtn || noAction, - tip: noAction - ? formatMessage({ - id: 'src.component.Task.component.ActionBar.D98B5B62', - defaultMessage: '结构一致,无需发起结构同步', - }) - : formatMessage({ - id: 'src.component.Task.component.ActionBar.4BF7D8BF', - defaultMessage: '暂不可用', - }), - type: 'button', - isPrimary: true, - action: async () => { - structureComparisonData && - modalStore?.changeCreateAsyncTaskModal(true, { - sql: structureComparisonData?.totalChangeScript, - databaseId: structureComparisonData?.database?.id, - rules: null, - }); + [TaskStatus.EXECUTING]: { + operations: [buttonConfig.stopBtn], + taskRules: [ + { + auth: true, + taskTypeLimit: [TaskType.STRUCTURE_COMPARISON], + operations: [buttonConfig.downloadSQLBtn, buttonConfig.structrueComparisonBySQL], + }, + ], }, - }; - const openLocalFolder = { - key: 'openLocalFolder', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.OpenFolder', - defaultMessage: '打开文件夹', - }), - - //打开文件夹 - action: async () => { - const info = await getTaskResult(task.id); - if (info?.exportZipFilePath) { - ipcInvoke('showItemInFolder', info?.exportZipFilePath); - } + [TaskStatus.APPROVING]: { + operations: [buttonConfig.stopBtn], + }, + [TaskStatus.EXECUTION_SUCCEEDED]: { + operations: [], + // taskRules 中的规则按顺序匹配,匹配上一个之后则应用该规则,不再继续匹配 + taskRules: [ + { + taskTypeLimit: [TaskType.EXPORT], + auth: settingStore.enableDataExport && isClient(), + operations: [buttonConfig.openLocalFolder], + }, + { + taskTypeLimit: [TaskType.EXPORT, TaskType.DATAMOCK, TaskType.EXPORT_RESULT_SET], + auth: settingStore.enableDataExport, + operations: [buttonConfig.downloadBtn], + }, + { + taskTypeLimit: [TaskType.ASYNC, TaskType.MULTIPLE_ASYNC], + auth: task?.rollbackable, + operations: [buttonConfig.rollbackBtn], + }, + { + taskTypeLimit: [TaskType.STRUCTURE_COMPARISON], + auth: true, + operations: [buttonConfig.downloadSQLBtn, buttonConfig.structrueComparisonBySQL], + }, + ], }, - type: 'button', }; + const getSpecialExecuteBtn = () => { + const _executeBtn = { ...buttonConfig.executeBtn }; + if (task?.executionStrategy === TaskExecStrategy.TIMER) { + _executeBtn.disabled = true; + const executionTime = getLocalFormatDateTime(task?.executionTime); + + _executeBtn.tooltip = formatMessage( + { + id: 'odc.TaskManagePage.component.TaskTools.ScheduledExecutionTimeExecutiontime', + defaultMessage: '定时执行时间:{executionTime}', + }, - const downloadViewResultBtn = { - key: 'downloadViewResult', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.DownloadQueryResults', - defaultMessage: '下载查询结果', - }), - disabled: isExpired, - isExpired, - tip: formatMessage({ - id: 'src.component.Task.component.ActionBar.E9211B1A', - defaultMessage: '文件下载链接已超时,请重新发起工单。', - }), //'文件下载链接已超时,请重新发起工单。' - - action: downloadViewResult, - type: 'button', + { executionTime }, + ); + + //`定时执行时间:${executionTime}` + } + return _executeBtn; }; + if (isDetailModal) { switch (status) { case TaskStatus.REJECTED: @@ -904,107 +791,46 @@ const ActionBar: React.FC = inject( case TaskStatus.CANCELLED: case TaskStatus.PRE_CHECK_FAILED: case TaskStatus.COMPLETED: { - setBtnByCreater(tools, reTryBtn); - if (isApprover) { - tools = []; - } - break; - } - case TaskStatus.EXECUTING: { - setBtnByCreater(tools, reTryBtn); - - if (haveOperationPermission) { - if (task.type === TaskType.STRUCTURE_COMPARISON) { - tools.push(downloadSQLBtn, structrueComparisonBySQL); - } - tools.push(stopBtn); - } - if (isApprover) { - tools = []; - } + addRetryButton(); + resetToolsForApprover(); break; } + case TaskStatus.EXECUTING: + case TaskStatus.EXECUTION_ABNORMAL: case TaskStatus.EXECUTION_SUCCEEDED: { - setBtnByCreater(tools, reTryBtn); - if (haveOperationPermission) { - if (task.type === TaskType.EXPORT && settingStore.enableDataExport) { - if (isClient()) { - tools.push(openLocalFolder); - } else { - tools.push(downloadBtn); - } - } else if (task.type === TaskType.DATAMOCK && settingStore.enableDataExport) { - tools.push(downloadBtn); - } else if ( - task.type === TaskType.EXPORT_RESULT_SET && - settingStore.enableDataExport - ) { - tools.push(downloadBtn); - } else if ( - [TaskType.ASYNC, TaskType.MULTIPLE_ASYNC]?.includes(task.type) && - task?.rollbackable - ) { - tools.push(rollbackBtn); - } else if (task.type === TaskType.STRUCTURE_COMPARISON) { - tools.push(downloadSQLBtn, structrueComparisonBySQL); - } - } + addRetryButton(); - if (isApprover) { - tools = []; + if (haveOperationPermission) { + const taskRules = operationNeedPermission?.[status]?.taskRules; + taskRules?.some((rule) => { + return addOperations(rule); + }); + tools.push(...operationNeedPermission[status].operations); } + resetToolsForApprover(); break; } case TaskStatus.WAIT_FOR_CONFIRM: case TaskStatus.APPROVING: { - if (isApprover) { - tools = [rejectBtn, approvalBtn]; - } - setBtnByCreater(tools, reTryBtn); + resetToolsForApprover([buttonConfig.rejectBtn, buttonConfig.approvalBtn]); + addRetryButton(); if (haveOperationPermission) { - tools.push(stopBtn); + tools.push(...operationNeedPermission[status].operations); } break; } case TaskStatus.WAIT_FOR_EXECUTION: { - setBtnByCreater(tools, reTryBtn); + addRetryButton(); if (haveOperationPermission) { - const _executeBtn = { ...executeBtn }; - if (task?.executionStrategy === TaskExecStrategy.TIMER) { - _executeBtn.disabled = true; - const executionTime = getLocalFormatDateTime(task?.executionTime); - - _executeBtn.tooltip = formatMessage( - { - id: 'odc.TaskManagePage.component.TaskTools.ScheduledExecutionTimeExecutiontime', - defaultMessage: '定时执行时间:{executionTime}', - }, - - { executionTime }, - ); - - //`定时执行时间:${executionTime}` - } + const _executeBtn = getSpecialExecuteBtn(); const tempTools = task?.executionStrategy === TaskExecStrategy.AUTO - ? [stopBtn] - : [stopBtn, _executeBtn]; + ? [buttonConfig.stopBtn] + : [buttonConfig.stopBtn, _executeBtn]; tools.push(...tempTools); } - if (isApprover) { - tools = []; - } - break; - } - case TaskStatus.EXECUTION_ABNORMAL: { - setBtnByCreater(tools, reTryBtn); - if (haveOperationPermission) { - tools.push(stopBtn, againBtn); - } - if (isApprover) { - tools = []; - } + resetToolsForApprover(); break; } default: @@ -1012,31 +838,19 @@ const ActionBar: React.FC = inject( if (task?.type === TaskType.ASYNC && result?.containQuery) { if (settingStore.enableDataExport) { - tools.unshift(downloadViewResultBtn); + tools.unshift(buttonConfig.downloadViewResultBtn); } } } else { - tools = [viewBtn]; + tools = [buttonConfig.viewBtn]; if (status === TaskStatus.WAIT_FOR_EXECUTION) { if (haveOperationPermission) { - const _executeBtn = { ...executeBtn }; - if (task?.executionStrategy === TaskExecStrategy.TIMER) { - _executeBtn.disabled = true; - const executionTime = getLocalFormatDateTime(task?.executionTime); - _executeBtn.tooltip = formatMessage( - { - id: 'odc.TaskManagePage.component.TaskTools.ScheduledExecutionTimeExecutiontime', - defaultMessage: '定时执行时间:{executionTime}', - }, - - { executionTime }, - ); - } + const _executeBtn = getSpecialExecuteBtn(); task?.executionStrategy === TaskExecStrategy.AUTO - ? tools.push(stopBtn) - : tools.push(_executeBtn, stopBtn); + ? tools.push(buttonConfig.stopBtn) + : tools.push(_executeBtn, buttonConfig.stopBtn); } - setBtnByCreater(tools, reTryBtn); + addRetryButton(); } } if (task?.executionStrategy === TaskExecStrategy.TIMER) { @@ -1053,204 +867,142 @@ const ActionBar: React.FC = inject( return []; } const { status } = _task; + const buttongConfig = { + ...commonButtonConfig, + stopBtn: { + ...actionInfo.stopBtn, + action: async () => { + await handleTaskOperation({ + operationType: TaskOperationType.TERMINATE, + callback: () => { + setActiveBtnKey('stop'); + }, + }); + }, + }, + editBtn: { + ...actionInfo.editBtn, + action: _editCycleTask, + }, + reTryBtn: { + ...actionInfo.reTryBtn, + action: _retryCycleTask, + }, + disableBtn: { + ...actionInfo.disableBtn, + action: async () => { + await handleTaskOperation({ operationType: TaskOperationType.PAUSE }); + }, + }, - const viewBtn = { - key: 'view', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.View', - defaultMessage: '查看', - }), //查看 - action: openTaskDetail, - type: 'button', - isOpenBtn: true, - }; - - const stopBtn = { - key: 'stop', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Termination', - defaultMessage: '终止', - }), //终止 - action: stopCycleTask, - type: 'button', - }; - - const editBtn = { - key: 'edit', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Edit', - defaultMessage: '编辑', - }), //编辑 - action: editCycleTask, - type: 'button', - }; - - const reTryBtn = { - key: 'reTry', - text: formatMessage({ - id: 'src.component.Task.component.ActionBar.C324AD20', - defaultMessage: '再次发起', - }), //'再次发起' - type: 'button', - action: handleReTryCycleTask, - }; - - const disableBtn = { - key: 'disable', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Disable', - defaultMessage: '禁用', - }), //禁用 - action: disableCycleTask, - type: 'button', - }; - - /* 禁用Schedule下的Task for logical database change task */ - /* 很脏的逻辑, ued少一层导致的 */ - const stopScheduleTaskBtn = { - key: 'stopLogicalChangeTask', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Termination', - defaultMessage: '终止', - }), //终止 - action: stopScheduleTask, - type: 'button', + /* 禁用Schedule下的Task for logical database change task */ + /* 很脏的逻辑, ued少一层导致的 */ + stopScheduleTaskBtn: { + ...actionInfo.stopScheduleTaskBtn, + action: _stopScheduleTask, + }, + enableBtn: { + ...actionInfo.enableBtn, + action: async () => { + await handleTaskOperation({ operationType: TaskOperationType.RESUME }); + }, + }, + approvalBtn: { + ...actionInfo.approvalBtn, + isPrimary: isDetailModal, + action: async () => { + _approvalTask(true); + }, + }, + deleteBtn: { + ...actionInfo.deleteBtn, + confirmText: formatMessage({ + id: 'src.component.Task.component.ActionBar.72AF1732', + defaultMessage: '你确定要删除这个任务吗?', + }), + action: _deleteTask, + }, }; - - const enableBtn = { - key: 'enable', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Enable', - defaultMessage: '启用', - }), //启用 - action: enableCycleTask, - type: 'button', + const initTools = ({ view, retry }: { view?: boolean; retry?: boolean }) => { + if (view) { + tools = [buttongConfig.viewBtn]; + } + if (retry) { + setBtnByCreater(tools, buttongConfig.reTryBtn); + } }; - const approvalBtn = { - key: 'approval', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Pass', - defaultMessage: '通过', - }), //通过 - type: 'button', - isPrimary: isDetailModal, - action: async () => { - handleApproval(true); + const operationNeedPermission = { + [TaskStatus.APPROVING]: { + auth: haveOperationPermission, + operations: [buttongConfig.stopBtn], + }, + [TaskStatus.PAUSE]: { + auth: haveOperationPermission, + operations: [buttongConfig.editBtn, buttongConfig.enableBtn, buttongConfig.stopBtn], + }, + [TaskStatus.CANCELLED]: { + auth: haveOperationPermission, + operations: [buttongConfig.stopBtn], + }, + [TaskStatus.REJECTED]: { auth: haveOperationPermission, operations: [] }, + [TaskStatus.APPROVAL_EXPIRED]: { + taskTypeLimit: SCHEDULE_TASKS, + auth: haveOperationPermission, + operations: [buttongConfig.deleteBtn], + }, + [TaskStatus.TERMINATED]: { + taskTypeLimit: SCHEDULE_TASKS, + auth: haveOperationPermission, + operations: [buttongConfig.deleteBtn], + }, + [TaskStatus.COMPLETED]: { + taskTypeLimit: SCHEDULE_TASKS, + auth: haveOperationPermission, + operations: [buttongConfig.deleteBtn], + }, + [TaskStatus.ENABLED]: { + auth: + haveOperationPermission && + !( + JOB_SCHEDULE_TASKS.includes(task?.type) && + (task as ICycleTaskRecord)?.triggerConfig?.triggerStrategy === + TaskExecStrategy.START_NOW + ), + operations: [buttongConfig.disableBtn, buttongConfig.stopBtn, buttongConfig.editBtn], }, }; - const rejectBtn = { - key: 'reject', - text: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTools.Reject', - defaultMessage: '拒绝', - }), //拒绝 - type: 'button', - action: async () => { - handleApproval(false); - }, + const operationNeedApprover = { + [TaskStatus.APPROVING]: [buttongConfig.approvalBtn, buttongConfig.rejectBtn], }; - const deleteBtn = { - key: 'delete', - text: formatMessage({ - id: 'src.component.Task.component.ActionBar.E16B982C', - defaultMessage: '删除', - }), - type: 'button', - confirmText: formatMessage({ - id: 'src.component.Task.component.ActionBar.72AF1732', - defaultMessage: '你确定要删除这个任务吗?', - }), - action: deleteTask, + const addOperations = ({ taskTypeLimit, auth, operations }: IAddOperationsParams) => { + const hasOperations = Boolean(operations?.length); + const useableTaskType = + (taskTypeLimit && taskTypeLimit.includes(task?.type)) || Boolean(taskTypeLimit?.length); + if (auth && hasOperations && useableTaskType) { + tools.push(...operations); + } }; + const enableRetry = + status !== TaskStatus.COMPLETED || + limitRertyButtonShowConfig?.[status]?.includes(task?.type); + initTools({ view: true, retry: enableRetry }); + addOperations(operationNeedPermission?.[status]); + switch (status) { - case TaskStatus.APPROVING: { - tools = [viewBtn]; - setBtnByCreater(tools, reTryBtn); - if (haveOperationPermission) { - tools.push(stopBtn); - } - if (isApprover) { - tools.push(approvalBtn, rejectBtn); - } + case TaskStatus.APPROVING: + addOperations({ auth: isApprover, operations: operationNeedApprover[status] }); break; - } - case TaskStatus.REJECTED: { - tools = [viewBtn]; - setBtnByCreater(tools, reTryBtn); - break; - } case TaskStatus.ENABLED: { - tools = [viewBtn]; - setBtnByCreater(tools, reTryBtn); - if (haveOperationPermission) { - if ( - !( - [TaskType.DATA_ARCHIVE, TaskType.DATA_DELETE].includes(task?.type) && - (task as ICycleTaskRecord)?.triggerConfig?.triggerStrategy === - TaskExecStrategy.START_NOW - ) - ) { - tools.push(disableBtn, stopBtn, editBtn); - } - } - if (haveOperationPermission && isLogicalDbChangeTask(task?.type)) { - tools = [viewBtn, editBtn, reTryBtn]; - } - break; - } - case TaskStatus.APPROVAL_EXPIRED: - case TaskStatus.TERMINATED: { - tools = [viewBtn]; - setBtnByCreater(tools, reTryBtn); - if (haveOperationPermission) { - if ( - [TaskType.DATA_ARCHIVE, TaskType.DATA_DELETE, TaskType.SQL_PLAN].includes(task?.type) - ) { - tools.push(deleteBtn); - } - } - break; - } - case TaskStatus.PAUSE: { - tools = [viewBtn]; - setBtnByCreater(tools, reTryBtn); - if (haveOperationPermission) { - tools.push(editBtn, enableBtn, stopBtn); - } - break; - } - case TaskStatus.COMPLETED: { - tools = [viewBtn]; - if ( - [ - TaskType.DATA_ARCHIVE, - TaskType.DATA_DELETE, - TaskType.LOGICAL_DATABASE_CHANGE, - ].includes(task?.type) - ) { - setBtnByCreater(tools, reTryBtn); - } - if ( - [TaskType.DATA_ARCHIVE, TaskType.DATA_DELETE, TaskType.SQL_PLAN].includes(task?.type) && - haveOperationPermission - ) { - tools.push(deleteBtn); - } - break; - } - case TaskStatus.CANCELLED: { - tools = [viewBtn]; - setBtnByCreater(tools, reTryBtn); - if (haveOperationPermission) { - tools.push(stopBtn); + tools = [buttongConfig.viewBtn, buttongConfig.editBtn, buttongConfig.reTryBtn]; } break; } default: + break; } if (isDetailModal) { @@ -1260,11 +1012,11 @@ const ActionBar: React.FC = inject( } // sql 计划 & 数据归档 & 数据清理 支持编辑 - if (![TaskType.SQL_PLAN, TaskType.DATA_ARCHIVE, TaskType.DATA_DELETE].includes(task?.type)) { + if (!SCHEDULE_TASKS.includes(task?.type)) { tools = tools.filter((item) => item.key !== 'edit'); } if ((taskList?.[0]?.status as any) === SubTaskStatus.RUNNING) { - tools = [...tools, stopScheduleTaskBtn]; + tools = [...tools, buttongConfig.stopScheduleTaskBtn]; } tools = uniqueTools(tools); return tools; diff --git a/src/component/Task/component/ActionBar/type.ts b/src/component/Task/component/ActionBar/type.ts new file mode 100644 index 000000000..e62511d42 --- /dev/null +++ b/src/component/Task/component/ActionBar/type.ts @@ -0,0 +1,12 @@ +import { TaskType } from '@/d.ts'; + +export interface IAddOperationsParams { + taskTypeLimit?: TaskType[]; + auth: boolean; + operations: { + key: string; + text: any; + action: () => Promise; + type: string; + }[]; +} diff --git a/src/component/Task/component/ApprovalModal/index.less b/src/component/Task/component/ApprovalModal/index.less new file mode 100644 index 000000000..4ff8d0d6e --- /dev/null +++ b/src/component/Task/component/ApprovalModal/index.less @@ -0,0 +1,10 @@ +.approvalModal { + .block:global(.ant-space) { + width: 100%; + } + :global { + .ant-modal-body { + padding: 20px; + } + } +} diff --git a/src/component/Task/component/ApprovalModal/index.tsx b/src/component/Task/component/ApprovalModal/index.tsx index ce0f8e799..ed964066c 100644 --- a/src/component/Task/component/ApprovalModal/index.tsx +++ b/src/component/Task/component/ApprovalModal/index.tsx @@ -20,7 +20,7 @@ import { formatMessage } from '@/util/intl'; import { Form, Input, message, Modal, Space } from 'antd'; import { inject, observer } from 'mobx-react'; import React, { useEffect, useRef, useState } from 'react'; -import styles from '../../index.less'; +import styles from './index.less'; const { TextArea } = Input; @@ -109,7 +109,7 @@ const ApprovalModal: React.FC = inject('taskStore')( onCancel={handleCancel} zIndex={1001} > - + { diff --git a/src/component/Task/component/CommonDetailModal/ExcecuteDetailModal.tsx b/src/component/Task/component/CommonDetailModal/ExcecuteDetailModal.tsx index 44c9ac8cd..90b413406 100644 --- a/src/component/Task/component/CommonDetailModal/ExcecuteDetailModal.tsx +++ b/src/component/Task/component/CommonDetailModal/ExcecuteDetailModal.tsx @@ -1,14 +1,13 @@ import { formatMessage } from '@/util/intl'; -import { Drawer, Table, Descriptions, Spin } from 'antd'; +import { Drawer, Descriptions } from 'antd'; import { useRequest } from 'ahooks'; import React, { useEffect, useState } from 'react'; import type { ColumnsType } from 'antd/es/table'; import StatusLabel from '@/component/Task/component/Status'; import { getCycleSubTaskDetail } from '@/common/network/task'; import { SubTaskStatus, ISubTaskTaskUnit } from '@/d.ts'; -import styles from './index.less'; import { getLocalFormatDateTime } from '@/util/utils'; -import { SubTaskTypeMap } from '../../const'; +import { SubTaskTypeMap } from '@/component/Task/const'; import CommonTable from '@/component/CommonTable'; interface IProps { diff --git a/src/component/Task/component/CommonDetailModal/LogModal.tsx b/src/component/Task/component/CommonDetailModal/LogModal.tsx index a12040e00..25f07a85d 100644 --- a/src/component/Task/component/CommonDetailModal/LogModal.tsx +++ b/src/component/Task/component/CommonDetailModal/LogModal.tsx @@ -20,7 +20,6 @@ import TaskLog from '@/component/Task/component/Log'; import { CommonTaskLogType, SubTaskStatus } from '@/d.ts'; import { useRequest } from 'ahooks'; import { Drawer } from 'antd'; -import login from '@/store/login'; import React, { useEffect, useState } from 'react'; interface IProps { scheduleId: number; diff --git a/src/component/Task/component/CommonDetailModal/Nodes/RollbackNode.tsx b/src/component/Task/component/CommonDetailModal/Nodes/RollbackNode.tsx index 6967c7715..65cfe550d 100644 --- a/src/component/Task/component/CommonDetailModal/Nodes/RollbackNode.tsx +++ b/src/component/Task/component/CommonDetailModal/Nodes/RollbackNode.tsx @@ -20,7 +20,7 @@ import { formatMessage } from '@/util/intl'; import { Descriptions, Space } from 'antd'; import { isEmpty } from 'lodash'; import React from 'react'; -import { DownloadFileAction } from '../../DownloadFileAction'; +import { DownloadFileAction } from '@/component/Task/component/DownloadFileAction'; import styles from '../index.less'; interface IProps { diff --git a/src/component/Task/component/CommonDetailModal/TaskExecuteRecord.tsx b/src/component/Task/component/CommonDetailModal/TaskExecuteRecord.tsx index 611ec0536..8a5cb60de 100644 --- a/src/component/Task/component/CommonDetailModal/TaskExecuteRecord.tsx +++ b/src/component/Task/component/CommonDetailModal/TaskExecuteRecord.tsx @@ -24,7 +24,7 @@ import StatusLabel, { status, subTaskStatus, } from '@/component/Task/component/Status'; -import DetailModal from '@/component/Task/DetailModal'; +import DetailModal from '@/component/Task/modals/DetailModals'; import { IAsyncTaskParams, IResponseData, @@ -45,7 +45,7 @@ import { getFormatDateTime } from '@/util/utils'; import Icon, { FilterOutlined, SearchOutlined } from '@ant-design/icons'; import { Space, Typography, message } from 'antd'; import React, { useEffect, useRef, useState } from 'react'; -import { isLogicalDbChangeTask } from '../../helper'; +import { isLogicalDbChangeTask } from '@/component/Task/helper'; import ExcecuteDetailModal from './ExcecuteDetailModal'; import styles from './index.less'; import LogModal from './LogModal'; diff --git a/src/component/Task/component/CommonDetailModal/TaskFlow.tsx b/src/component/Task/component/CommonDetailModal/TaskFlow.tsx index adb93671a..7421bd983 100644 --- a/src/component/Task/component/CommonDetailModal/TaskFlow.tsx +++ b/src/component/Task/component/CommonDetailModal/TaskFlow.tsx @@ -38,7 +38,7 @@ import { getLocalFormatDateTime } from '@/util/utils'; import { Descriptions, Space, Steps } from 'antd'; import classNames from 'classnames'; import React, { useEffect, useMemo, useState } from 'react'; -import { isLogicalDbChangeTask } from '../../helper'; +import { isLogicalDbChangeTask } from '@/component/Task/helper'; import styles from './index.less'; import { getStatusDisplayInfo } from './Nodes/helper'; import MultipleSQLCheckNode from './Nodes/MultipleSQLCheckNode'; diff --git a/src/component/Task/component/CommonDetailModal/TaskProgress/ProgressDetailsModal.tsx b/src/component/Task/component/CommonDetailModal/TaskProgress/ProgressDetailsModal.tsx index 6a4d2b0b7..9414d1676 100644 --- a/src/component/Task/component/CommonDetailModal/TaskProgress/ProgressDetailsModal.tsx +++ b/src/component/Task/component/CommonDetailModal/TaskProgress/ProgressDetailsModal.tsx @@ -1,7 +1,7 @@ import { formatMessage } from '@/util/intl'; import { ProgressOfLocklessStructureChangeTaskStatusMap } from '@/d.ts'; -import { Button, Modal, Steps } from 'antd'; -import React, { useEffect, useState } from 'react'; +import { Modal, Steps } from 'antd'; +import { useEffect, useState } from 'react'; export default ({ modalOpen, handleClose, parametersJson, resultJson }) => { const { state } = parametersJson || {}; diff --git a/src/component/Task/component/CommonDetailModal/TaskProgress/TaskProgressDrawer.tsx b/src/component/Task/component/CommonDetailModal/TaskProgress/TaskProgressDrawer.tsx index f44024aad..47957cbc2 100644 --- a/src/component/Task/component/CommonDetailModal/TaskProgress/TaskProgressDrawer.tsx +++ b/src/component/Task/component/CommonDetailModal/TaskProgress/TaskProgressDrawer.tsx @@ -3,7 +3,7 @@ import { TaskDetail, TaskRecordParameters } from '@/d.ts'; import { formatMessage } from '@/util/intl'; import { Drawer, Space } from 'antd'; import React from 'react'; -import { SimpleTextItem } from '../../SimpleTextItem'; +import { SimpleTextItem } from '@/component/Task/component/SimpleTextItem'; import { getDataSourceModeConfigByConnectionMode } from '@/common/datasource'; const TaskProgressDrawer: React.FC<{ diff --git a/src/component/Task/component/CommonDetailModal/TaskProgress/colums.tsx b/src/component/Task/component/CommonDetailModal/TaskProgress/colums.tsx index fc93c6e8e..4d04b201a 100644 --- a/src/component/Task/component/CommonDetailModal/TaskProgress/colums.tsx +++ b/src/component/Task/component/CommonDetailModal/TaskProgress/colums.tsx @@ -6,7 +6,7 @@ import { SubTaskStatus, TaskType, TaskStatus } from '@/d.ts'; import { formatMessage } from '@/util/intl'; import { getLocalFormatDateTime } from '@/util/utils'; import Icon, { QuestionCircleOutlined } from '@ant-design/icons'; -import { Popover, Space, Tooltip, Typography } from 'antd'; +import { Popover, Space, Tooltip } from 'antd'; const getColumns = (params: { handleDetailVisible: (id: number) => void; diff --git a/src/component/Task/component/CommonDetailModal/TaskProgress/index.tsx b/src/component/Task/component/CommonDetailModal/TaskProgress/index.tsx index 5c8e19035..53d40b281 100644 --- a/src/component/Task/component/CommonDetailModal/TaskProgress/index.tsx +++ b/src/component/Task/component/CommonDetailModal/TaskProgress/index.tsx @@ -31,8 +31,8 @@ import { useRequest } from 'ahooks'; import { message } from 'antd'; import { inject, observer } from 'mobx-react'; import React, { useContext, useEffect, useState, useMemo } from 'react'; -import { flatArray } from '../../../MutipleAsyncTask/CreateModal/helper'; -import { TaskDetailContext } from '../../../TaskDetailContext'; +import { flatArray } from '@/util/utils'; +import { TaskDetailContext } from '@/component/Task/container/TaskDetailContext'; import { getColumnsByTaskType } from './colums'; import styles from './index.less'; import TaskProgressDrawer from './TaskProgressDrawer'; diff --git a/src/component/Task/component/CommonDetailModal/TaskProgress1.tsx b/src/component/Task/component/CommonDetailModal/TaskProgress1.tsx index 433c3608b..5819ab056 100644 --- a/src/component/Task/component/CommonDetailModal/TaskProgress1.tsx +++ b/src/component/Task/component/CommonDetailModal/TaskProgress1.tsx @@ -39,8 +39,8 @@ import Icon from '@ant-design/icons'; import { useRequest } from 'ahooks'; import { inject, observer } from 'mobx-react'; import React, { useContext, useEffect, useState } from 'react'; -import { flatArray } from '../../MutipleAsyncTask/CreateModal/helper'; -import { TaskDetailContext } from '../../TaskDetailContext'; +import { flatArray } from '@/util/utils'; +import { TaskDetailContext } from '@/component/Task/container/TaskDetailContext'; import { SimpleTextItem } from '../SimpleTextItem'; import styles from './index.less'; const getColumns = (params: { diff --git a/src/component/Task/component/CommonDetailModal/TaskRecord.tsx b/src/component/Task/component/CommonDetailModal/TaskRecord.tsx index 178e44825..1e0d0f469 100644 --- a/src/component/Task/component/CommonDetailModal/TaskRecord.tsx +++ b/src/component/Task/component/CommonDetailModal/TaskRecord.tsx @@ -18,7 +18,7 @@ import { getTaskList } from '@/common/network/task'; import Action from '@/component/Action'; import DisplayTable from '@/component/DisplayTable'; import StatusLabel, { status } from '@/component/Task/component/Status'; -import DetailModal from '@/component/Task/DetailModal'; +import DetailModal from '@/component/Task/modals/DetailModals'; import { TaskDetail, TaskRecord, TaskRecordParameters, TaskType } from '@/d.ts'; import { formatMessage } from '@/util/intl'; import { getFormatDateTime } from '@/util/utils'; diff --git a/src/component/Task/component/DataTransferModal/csvTables.tsx b/src/component/Task/component/DataTransferModal/csvTables.tsx index 6a3178116..bf46da8a2 100644 --- a/src/component/Task/component/DataTransferModal/csvTables.tsx +++ b/src/component/Task/component/DataTransferModal/csvTables.tsx @@ -18,7 +18,7 @@ import { CsvColumnMapping } from '@/d.ts'; import { formatMessage } from '@/util/intl'; import { isNil } from 'lodash'; import React from 'react'; -import DisplayTable from '../../../DisplayTable'; +import DisplayTable from '@/component/DisplayTable'; interface ICsvTableProps { data: CsvColumnMapping[]; diff --git a/src/component/Task/component/DataTransferModal/index.tsx b/src/component/Task/component/DataTransferModal/index.tsx index e8505f959..6a15469ac 100644 --- a/src/component/Task/component/DataTransferModal/index.tsx +++ b/src/component/Task/component/DataTransferModal/index.tsx @@ -16,7 +16,6 @@ import { downloadTaskFlow } from '@/common/network/task'; import RiskLevelLabel from '@/component/RiskLevelLabel'; -import { getTaskExecStrategyMap } from '@/component/Task'; import { FILE_DATA_TYPE, IMPORT_TYPE, TaskExecStrategy } from '@/d.ts'; import { isClient } from '@/util/env'; import { formatMessage } from '@/util/intl'; @@ -26,7 +25,8 @@ import React from 'react'; import CsvTable from './csvTables'; import styles from './index.less'; import ObjTable from './ObjTables'; -import { getImportTypeLabel } from '../../ImportTask/CreateModal/ImportForm/helper'; +import { getImportTypeLabel } from '@/component/Task/modals/ImportTask/CreateModal/ImportForm/helper'; +import { getTaskExecStrategyMap } from '@/component/Task/const'; const SimpleTextItem: React.FC<{ label: string; content: React.ReactNode; diff --git a/src/component/Task/component/DirtyRowAction/index.tsx b/src/component/Task/component/DirtyRowAction/index.tsx index 480b82412..cc3b0cfbb 100644 --- a/src/component/Task/component/DirtyRowAction/index.tsx +++ b/src/component/Task/component/DirtyRowAction/index.tsx @@ -1,6 +1,6 @@ import { formatMessage } from '@/util/intl'; import { Form, Radio } from 'antd'; -import React, { useEffect, useMemo, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { DirtyRowActionEnum, DirtyRowActionLabelMap, diff --git a/src/component/Task/component/JoinTableConfigsModal/index.tsx b/src/component/Task/component/JoinTableConfigsModal/index.tsx index 8ce60306a..36dd85e23 100644 --- a/src/component/Task/component/JoinTableConfigsModal/index.tsx +++ b/src/component/Task/component/JoinTableConfigsModal/index.tsx @@ -1,4 +1,4 @@ -import { IDataArchiveJobParameters, IDLMJobParametersTables } from '@/d.ts'; +import { IDLMJobParametersTables } from '@/d.ts'; import { Modal, Form, Input, Button, Space, Select, Typography } from 'antd'; import { FormListFieldData } from 'antd/es/form/FormList'; import styles from './index.less'; diff --git a/src/component/Task/component/MaxAllowedDirtyRowCount/index.tsx b/src/component/Task/component/MaxAllowedDirtyRowCount/index.tsx index 237696a13..628a2938e 100644 --- a/src/component/Task/component/MaxAllowedDirtyRowCount/index.tsx +++ b/src/component/Task/component/MaxAllowedDirtyRowCount/index.tsx @@ -1,5 +1,5 @@ import { formatMessage } from '@/util/intl'; -import { Checkbox, Form, FormInstance, InputNumber, Radio, Space, Tooltip } from 'antd'; +import { Form, InputNumber } from 'antd'; import React, { useEffect, useState } from 'react'; import styles from './index.less'; import { DirtyRowActionEnum } from '@/component/ExecuteSqlDetailModal/constant'; diff --git a/src/component/Task/component/MultipleDatabaseSelect/index.tsx b/src/component/Task/component/MultipleDatabaseSelect/index.tsx index 79ff8fcbd..02e9fb97c 100644 --- a/src/component/Task/component/MultipleDatabaseSelect/index.tsx +++ b/src/component/Task/component/MultipleDatabaseSelect/index.tsx @@ -1,7 +1,6 @@ import SessionDropdown, { ISessionDropdownFiltersProps, } from '@/page/Workspace/components/SessionContextWrap/SessionSelect/SessionDropdown'; -import { IDatabase } from '@/d.ts/database'; import React, { useState } from 'react'; import { Divider, Select, Space, Form } from 'antd'; import { formatMessage } from '@/util/intl'; diff --git a/src/component/Task/component/PartitionPolicyFormTable/components/CustomNamingRules.tsx b/src/component/Task/component/PartitionPolicyFormTable/components/CustomNamingRules.tsx new file mode 100644 index 000000000..745de21c4 --- /dev/null +++ b/src/component/Task/component/PartitionPolicyFormTable/components/CustomNamingRules.tsx @@ -0,0 +1,34 @@ +import { formatMessage } from '@/util/intl'; +import { Form, Input, Space } from 'antd'; +import { rules } from '../const'; +import styles from '../index.less'; + +const CustomNamingRules = () => { + return ( + + + + + + ); +}; + +export default CustomNamingRules; diff --git a/src/component/Task/component/PartitionPolicyFormTable/components/DropPartitionFormItems.tsx b/src/component/Task/component/PartitionPolicyFormTable/components/DropPartitionFormItems.tsx new file mode 100644 index 000000000..74c1a9a51 --- /dev/null +++ b/src/component/Task/component/PartitionPolicyFormTable/components/DropPartitionFormItems.tsx @@ -0,0 +1,80 @@ +import FormItemPanel from '@/component/FormItemPanel'; +import HelpDoc from '@/component/helpDoc'; +import { formatMessage } from '@/util/intl'; +import { Form, InputNumber, Radio, Space } from 'antd'; +import { rules } from '../const'; + +const DropPatitionFormItems = () => { + return ( + + + + { + formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.7D6F23AE' /*分区保留数量*/, + defaultMessage: '分区保留数量', + }) /* 分区保留数量 */ + } + + } + rules={rules.keepLatestCount} + > + + + + + + + + ); +}; + +export default DropPatitionFormItems; diff --git a/src/component/Task/component/PartitionPolicyFormTable/EditTable/index.less b/src/component/Task/component/PartitionPolicyFormTable/components/EditTable/index.less similarity index 100% rename from src/component/Task/component/PartitionPolicyFormTable/EditTable/index.less rename to src/component/Task/component/PartitionPolicyFormTable/components/EditTable/index.less diff --git a/src/component/Task/component/PartitionPolicyFormTable/EditTable/index.tsx b/src/component/Task/component/PartitionPolicyFormTable/components/EditTable/index.tsx similarity index 99% rename from src/component/Task/component/PartitionPolicyFormTable/EditTable/index.tsx rename to src/component/Task/component/PartitionPolicyFormTable/components/EditTable/index.tsx index 54d10ca1c..e60ff0a4d 100644 --- a/src/component/Task/component/PartitionPolicyFormTable/EditTable/index.tsx +++ b/src/component/Task/component/PartitionPolicyFormTable/components/EditTable/index.tsx @@ -19,7 +19,7 @@ import { formatMessage } from '@/util/intl'; import type { FormInstance } from 'antd'; import { Form, Select, Typography } from 'antd'; import VirtualList from 'rc-virtual-list'; -import React, { useState } from 'react'; +import React from 'react'; import RuleFormItem from '../RuleFormItem'; import styles from './index.less'; diff --git a/src/component/Task/component/PartitionPolicyFormTable/components/IntervalGenerateExprFormItem.tsx b/src/component/Task/component/PartitionPolicyFormTable/components/IntervalGenerateExprFormItem.tsx new file mode 100644 index 000000000..a4e36e78a --- /dev/null +++ b/src/component/Task/component/PartitionPolicyFormTable/components/IntervalGenerateExprFormItem.tsx @@ -0,0 +1,33 @@ +import { formatMessage } from '@/util/intl'; +import { Form, Input } from 'antd'; + +const IntervalGenerateExprFormItem = () => { + return ( + + + + ); +}; + +export default IntervalGenerateExprFormItem; diff --git a/src/component/Task/component/PartitionPolicyFormTable/components/PreSuffixNamingRules.tsx b/src/component/Task/component/PartitionPolicyFormTable/components/PreSuffixNamingRules.tsx new file mode 100644 index 000000000..8e4af81e2 --- /dev/null +++ b/src/component/Task/component/PartitionPolicyFormTable/components/PreSuffixNamingRules.tsx @@ -0,0 +1,132 @@ +import { formatMessage } from '@/util/intl'; +import { AutoComplete, Form, Input, Select, Space, Tag } from 'antd'; +import { rules, suffixOptions } from '../const'; +import styles from '../index.less'; +import HelpDoc from '@/component/helpDoc'; +import { PartitionBound } from '@/constant'; + +const PreSuffixNamingRules = ({ partitionKeyOptions }) => { + return ( + + + + + + + + { + formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.0F79EE9C' /*后缀*/, + defaultMessage: '后缀', + }) /* 后缀 */ + } + + + + + + + + ); +}; + +export default PreSuffixNamingRules; diff --git a/src/component/Task/component/PartitionPolicyFormTable/PreviewSQLModal/index.less b/src/component/Task/component/PartitionPolicyFormTable/components/PreviewSQLModal/index.less similarity index 100% rename from src/component/Task/component/PartitionPolicyFormTable/PreviewSQLModal/index.less rename to src/component/Task/component/PartitionPolicyFormTable/components/PreviewSQLModal/index.less diff --git a/src/component/Task/component/PartitionPolicyFormTable/PreviewSQLModal/index.tsx b/src/component/Task/component/PartitionPolicyFormTable/components/PreviewSQLModal/index.tsx similarity index 100% rename from src/component/Task/component/PartitionPolicyFormTable/PreviewSQLModal/index.tsx rename to src/component/Task/component/PartitionPolicyFormTable/components/PreviewSQLModal/index.tsx diff --git a/src/component/Task/component/PartitionPolicyFormTable/RuleFormItem/index.less b/src/component/Task/component/PartitionPolicyFormTable/components/RuleFormItem/index.less similarity index 100% rename from src/component/Task/component/PartitionPolicyFormTable/RuleFormItem/index.less rename to src/component/Task/component/PartitionPolicyFormTable/components/RuleFormItem/index.less diff --git a/src/component/Task/component/PartitionPolicyFormTable/RuleFormItem/index.tsx b/src/component/Task/component/PartitionPolicyFormTable/components/RuleFormItem/index.tsx similarity index 63% rename from src/component/Task/component/PartitionPolicyFormTable/RuleFormItem/index.tsx rename to src/component/Task/component/PartitionPolicyFormTable/components/RuleFormItem/index.tsx index bc51503fb..5a9018cc4 100644 --- a/src/component/Task/component/PartitionPolicyFormTable/RuleFormItem/index.tsx +++ b/src/component/Task/component/PartitionPolicyFormTable/components/RuleFormItem/index.tsx @@ -31,121 +31,26 @@ import { Typography, } from 'antd'; import React, { useState } from 'react'; -import { intervalPrecisionOptions } from '../configModal'; -import { NameRuleType } from '../configModal'; -import { START_DATE, INCREAMENT_FIELD_TYPE, increamentFieldTypeLabelMap } from '../const'; -import styles from '../index.less'; -import { getLocale } from '@umijs/max'; +import { + START_DATE, + INCREAMENT_FIELD_TYPE, + intervalPrecisionOptions, + NameRuleType, + startDateOptionValues, + incrementFieldTypeOptionsValues, + incrementByDateOptionsInNumber, + ruleFormRules, +} from '../../const'; +import styles from '../../index.less'; +import { + getDefaultPrecisionByIncrementDateTypeInDate, + getIncrementByDateOptionsInChar, + getIntervalPrecisionOptionsByIncrementDateType, + getPartitionKeyConfigsFormItemName, +} from '../../utils'; const { Text } = Typography; -const startDateOptionValues = [ - { - label: formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.88D572DE', - defaultMessage: '当前时间', - }), //'当前时间' - value: START_DATE.CURRENT_DATE, - description: formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.684CAF92', - defaultMessage: '从实际执行的时间开始创建', - }), //'从实际执行的时间开始创建' - }, - { - label: formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.9CDC5E14', - defaultMessage: '指定时间', - }), //'指定时间' - value: START_DATE.CUSTOM_DATE, - description: formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.0E0ADD3E', - defaultMessage: '从指定的某个时间开始创建', - }), //'从指定的某个时间开始创建' - }, -]; - -const incrementFieldTypeOptionsValues = [ - { - label: increamentFieldTypeLabelMap[INCREAMENT_FIELD_TYPE.NUMBER], - value: INCREAMENT_FIELD_TYPE.NUMBER, - description: formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.33B07A9E', - defaultMessage: '仅代表数值数据,如:001、002', - }), - }, - { - label: increamentFieldTypeLabelMap[INCREAMENT_FIELD_TYPE.TIME_STRING], - value: INCREAMENT_FIELD_TYPE.TIME_STRING, - description: formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.38D2B418', - defaultMessage: '类型为数值但实际含义为日期时间,如: 20250207', - }), - }, - { - label: increamentFieldTypeLabelMap[INCREAMENT_FIELD_TYPE.TIMESTAMP], - value: INCREAMENT_FIELD_TYPE.TIMESTAMP, - description: formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.EBF8762C', - defaultMessage: '类型为数值但实际含义为时间戳,如: 1609459200', - }), - }, -]; - -const incrementByDateOptionsInNumber = ['yyyy', 'yyyyMM', 'yyyyMMdd', 'yyyyMMddHHmmss'].map( - (item) => ({ - label: item, - value: item, - }), -); - -const getIncrementByDateOptionsInChar = () => { - const locale = getLocale(); - const options = [ - 'yyyy', - formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.E205FB6F', - defaultMessage: 'yyyy年', - }), - - 'yyyyMM', - 'yyyy-MM', - 'yyyy/MM', - formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.216E3527', - defaultMessage: 'yyyy年MM月', - }), - - 'yyyyMMdd', - 'yyyy-MM-dd', - 'yyyy/MM/dd', - formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.EF0BF81D', - defaultMessage: 'yyyy年MM月dd日', - }), - 'yyyyMMdd HH:mm:ss', - 'yyyy-MM-dd HH:mm:ss', - 'yyyy/MM/dd HH:mm:ss', - formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.13B22678', - defaultMessage: 'yyyy年MM月dd日 HH:mm:ss', - }), - ]; - - if (locale !== 'zh-CN') { - return options - .filter((item) => !/[\u4e00-\u9fa5]/.test(item)) - .map((item) => ({ - label: item, - value: item, - })); - } - - return options.map((item) => ({ - label: item, - value: item, - })); -}; - const getOptionsByValueList = (valueList) => { return valueList.map(({ label, value, description }) => { return { @@ -193,123 +98,23 @@ interface TableFormProps { dataTypeName: string; } -const PRECISION_MAP = { - second: 63, - minute: 31, - hour: 15, - day: 7, - month: 3, - year: 1, -}; - -const getIntervalPrecisionOptionsByIncrementDateType = ( - incrementFieldTypeInDate: string, - incrementFieldType: INCREAMENT_FIELD_TYPE, -) => { - if (incrementFieldType !== INCREAMENT_FIELD_TYPE.TIME_STRING || !incrementFieldTypeInDate) { - return intervalPrecisionOptions; - } - - if (incrementFieldTypeInDate?.includes?.('s')) { - return intervalPrecisionOptions?.filter((item) => item.value <= PRECISION_MAP.second); - } - if (incrementFieldTypeInDate?.includes?.('m')) { - return intervalPrecisionOptions?.filter((item) => item.value <= PRECISION_MAP.minute); - } - if (incrementFieldTypeInDate?.includes?.('H')) { - return intervalPrecisionOptions?.filter((item) => item.value <= PRECISION_MAP.hour); - } - if (incrementFieldTypeInDate?.includes?.('d')) { - return intervalPrecisionOptions?.filter((item) => item.value <= PRECISION_MAP.day); - } - if (incrementFieldTypeInDate?.includes?.('M')) { - return intervalPrecisionOptions?.filter((item) => item.value <= PRECISION_MAP.month); - } - if (incrementFieldTypeInDate?.includes?.('y')) { - return intervalPrecisionOptions?.filter((item) => item.value <= PRECISION_MAP.year); - } - - return intervalPrecisionOptions; -}; - -const getDefaultPrecisionByIncrementDateTypeInDate = ( - incrementFieldTypeInDate: string, - incrementFieldType: INCREAMENT_FIELD_TYPE, -) => { - if (incrementFieldType !== INCREAMENT_FIELD_TYPE.TIME_STRING || !incrementFieldTypeInDate) { - return 3; - } - - if (incrementFieldTypeInDate?.includes?.('s')) { - return PRECISION_MAP.second; - } - if (incrementFieldTypeInDate?.includes?.('m')) { - return PRECISION_MAP.minute; - } - if (incrementFieldTypeInDate?.includes?.('H')) { - return PRECISION_MAP.hour; - } - if (incrementFieldTypeInDate?.includes?.('d')) { - return PRECISION_MAP.day; - } - if (incrementFieldTypeInDate?.includes?.('M')) { - return PRECISION_MAP.month; - } - if (incrementFieldTypeInDate?.includes?.('y')) { - return PRECISION_MAP.year; - } - - return 3; -}; - const RuleFormItem: React.FC = (props) => { const { field, precision, isDate, dataTypeName } = props; const [intervalErrorInBlur, setIntervalErrorInBlur] = useState(); return ( {({ getFieldValue, getFieldError, setFieldValue }) => { - const partitionKeyInvoker = getFieldValue([ - 'option', - 'partitionKeyConfigs', - field.name, - 'partitionKeyInvoker', - ]); - const fromCurrentTime = getFieldValue([ - 'option', - 'partitionKeyConfigs', - field.name, - 'fromCurrentTime', - ]); - const incrementFieldType = getFieldValue([ - 'option', - 'partitionKeyConfigs', - field.name, - 'incrementFieldType', - ]); - const incrementFieldTypeInDate = getFieldValue([ - 'option', - 'partitionKeyConfigs', - field.name, - 'incrementFieldTypeInDate', - ]); - const generateExprError = getFieldError([ - 'option', - 'partitionKeyConfigs', - field.name, - 'generateExpr', - ]); - const intervalGenerateExprError = getFieldError([ - 'option', - 'partitionKeyConfigs', - field.name, - 'intervalGenerateExpr', - ]); - const intervalError = getFieldError([ - 'option', - 'partitionKeyConfigs', - field.name, - 'interval', - ]); + const getFieldBySecondName = (key: string) => { + return getFieldValue(getPartitionKeyConfigsFormItemName({ name: field.name, key })); + }; + + const partitionKeyInvoker = getFieldBySecondName('partitionKeyInvoker'); + const fromCurrentTime = getFieldBySecondName('fromCurrentTime'); + const incrementFieldType = getFieldBySecondName('incrementFieldType'); + const incrementFieldTypeInDate = getFieldBySecondName('incrementFieldTypeInDate'); + const generateExprError = getFieldBySecondName('generateExpr'); + const intervalGenerateExprError = getFieldBySecondName('intervalGenerateExpr'); + const intervalError = getFieldBySecondName('interval'); const validateInput = (error) => { setIntervalErrorInBlur(error); @@ -347,15 +152,7 @@ const RuleFormItem: React.FC = (props) => { name={[field.name, 'intervalGenerateExpr']} className={styles.noMarginBottom} style={{ flexGrow: 2 }} - rules={[ - { - required: true, - message: formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.8368A05F', - defaultMessage: '请输入', - }), //'请输入' - }, - ]} + rules={ruleFormRules.intervalGenerateExpr} > = (props) => { {...field} name={[field.name, 'interval']} className={styles.noMarginBottom} - rules={[ - { - required: true, - message: formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.2F986FD8', - defaultMessage: '请输入', - }), //'请输入' - }, - ]} + rules={ruleFormRules.interval} help={EmptyHelp} > = (props) => { = (props) => { name={[field.name, 'intervalGenerateExpr']} className={styles.noMarginBottom} style={{ flexGrow: 2 }} - rules={[ - { - required: true, - message: formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.8368A05F', - defaultMessage: '请输入', - }), //'请输入' - }, - ]} + rules={ruleFormRules.intervalGenerateExpr} help={EmptyHelp} > = (props) => { {...field} name={[field.name, 'interval']} className={styles.noMarginBottom} - rules={[ - { - required: true, - message: formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.2F986FD8', - defaultMessage: '请输入', - }), //'请输入' - }, - ]} + rules={ruleFormRules.interval} help={EmptyHelp} > = (props) => { = (props) => { > {isCustomRuleType ? ( - - - - - + ) : ( - - - - - - - - { - formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.0F79EE9C' /*后缀*/, - defaultMessage: '后缀', - }) /* 后缀 */ - } - - - - - - {formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.602BD66C', - defaultMessage: '分区上界', - })} - - - {formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.2384A1C3', - defaultMessage: '分区下界', - })} - - - - - + )} @@ -1032,121 +645,11 @@ const ConfigDrawer: React.FC = (props) => { )} - {isCustomRuleType && ( - - - - )} + {isCustomRuleType && } )} - {isDropConfigVisible && ( - - - - { - formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.7D6F23AE' /*分区保留数量*/, - defaultMessage: '分区保留数量', - }) /* 分区保留数量 */ - } - - } - rules={[ - { - required: true, - message: formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.967356C8', - defaultMessage: '请输入', - }), //'请输入' - }, - ]} - > - - - - - - { - formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.77C8BE4D' /*是*/, - defaultMessage: '是', - }) /* 是 */ - } - - - { - formatMessage({ - id: 'src.component.Task.component.PartitionPolicyFormTable.E374E7C8' /*否*/, - defaultMessage: '否', - }) /* 否 */ - } - - - - - - )} + {isDropConfigVisible && } ({ + label: TaskPartitionStrategyMap[key], + value: key, +})); + export const getPartitionKeyInvokerByIncrementFieldType = ( partitionKeyInvoker: PARTITION_KEY_INVOKER, incrementFieldType: INCREAMENT_FIELD_TYPE, @@ -72,3 +82,314 @@ export const revertPartitionKeyInvokerByIncrementFieldType = ( } return PARTITION_KEY_INVOKER.TIME_INCREASING_GENERATOR; }; + +export const intervalPrecisionOptions = [ + { + label: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.436BC171', + defaultMessage: '秒', + }), //'秒' + value: 63, + }, + { + label: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.0E0CEBAC', + defaultMessage: '分', + }), //'分' + value: 31, + }, + { + label: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.9EC2D1FF', + defaultMessage: '时', + }), //'时' + value: 15, + }, + { + label: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.1E11DFEA', + defaultMessage: '日', + }), //'日' + value: 7, + }, + { + label: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.1FB1ABDC', + defaultMessage: '月', + }), //'月' + value: 3, + }, + { + label: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.069255DB', + defaultMessage: '年', + }), //'年' + value: 1, + }, +]; + +export const suffixOptions = [ + { + label: 'yyyy', + value: 'yyyy', + }, + + { + label: 'yyyyMMdd', + value: 'yyyyMMdd', + }, + + { + label: 'yyyyMM', + value: 'yyyyMM', + }, + + { + label: 'yyyy_MM_dd', + value: 'yyyy_MM_dd', + }, + + { + label: 'yyyy_MM', + value: 'yyyy_MM', + }, + { + label: 'yyyy/MM', + value: 'yyyy/MM', + }, + { + label: 'yyyy/MM/dd', + value: 'yyyy/MM/dd', + }, + { + label: 'yyyyMMddHHmmss', + value: 'yyyyMMddHHmmss', + }, + { + label: 'yyyy/MM/dd HH:mm:ss', + value: 'yyyy/MM/dd HH:mm:ss', + }, + { + label: 'yyyy_MM_dd HH:mm:ss', + value: 'yyyy_MM_dd HH:mm:ss', + }, +]; + +export const rules = { + generateCount: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.16355175', + defaultMessage: '请输入预创建分区数量', + }), //'请输入预创建分区数量' + }, + ], + nameRuleType: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.87D4D0BB', + defaultMessage: '请选择', + }), //'请选择' + }, + ], + generateExpr: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.E5DA1FA4', + defaultMessage: '请输入表达式', + }), //'请输入表达式' + }, + ], + namingPrefix: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.4293BED4', + defaultMessage: '请输入前缀', + }), //'请输入前缀' + }, + { + pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.F70A7891', + defaultMessage: '仅支持英文/数字/下划线,且以英文开头', + }), //'仅支持英文/数字/下划线,且以英文开头' + }, + { + max: 32, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.D76C944C', + defaultMessage: '不超过32个字符', + }), //'不超过32个字符' + }, + ], + refPartitionKey: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.CC74D506', + defaultMessage: '请选择', + }), //'请选择' + }, + ], + namingSuffixExpression: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.7183DAA0', + defaultMessage: '请选择后缀', + }), //'请选择后缀' + }, + ], + namingSuffixStrategy: [ + { + required: true, + }, + ], + keepLatestCount: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.967356C8', + defaultMessage: '请输入', + }), //'请输入' + }, + ], + reloadIndexes: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.393D1F82', + defaultMessage: '请选择', + }), //'请选择' + }, + ], +}; + +export const ruleFormRules = { + intervalPrecision: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.7FB4A416', + defaultMessage: '请选择', + }), //'请选择' + }, + ], + intervalGenerateExpr: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.8368A05F', + defaultMessage: '请输入', + }), //'请输入' + }, + ], + interval: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.2F986FD8', + defaultMessage: '请输入', + }), //'请输入' + }, + ], + incrementFieldType: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.88F8B3BE', + defaultMessage: '请选择', + }), + }, + ], + incrementFieldTypeInDate: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.3174105E', + defaultMessage: '请输入格式', + }), + }, + ], + generateExpr: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.DE258551', + defaultMessage: '请输入', + }), //'请输入' + }, + ], +}; + +export const startDateOptionValues = [ + { + label: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.88D572DE', + defaultMessage: '当前时间', + }), //'当前时间' + value: START_DATE.CURRENT_DATE, + description: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.684CAF92', + defaultMessage: '从实际执行的时间开始创建', + }), //'从实际执行的时间开始创建' + }, + { + label: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.9CDC5E14', + defaultMessage: '指定时间', + }), //'指定时间' + value: START_DATE.CUSTOM_DATE, + description: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.0E0ADD3E', + defaultMessage: '从指定的某个时间开始创建', + }), //'从指定的某个时间开始创建' + }, +]; + +export const incrementFieldTypeOptionsValues = [ + { + label: increamentFieldTypeLabelMap[INCREAMENT_FIELD_TYPE.NUMBER], + value: INCREAMENT_FIELD_TYPE.NUMBER, + description: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.33B07A9E', + defaultMessage: '仅代表数值数据,如:001、002', + }), + }, + { + label: increamentFieldTypeLabelMap[INCREAMENT_FIELD_TYPE.TIME_STRING], + value: INCREAMENT_FIELD_TYPE.TIME_STRING, + description: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.38D2B418', + defaultMessage: '类型为数值但实际含义为日期时间,如: 20250207', + }), + }, + { + label: increamentFieldTypeLabelMap[INCREAMENT_FIELD_TYPE.TIMESTAMP], + value: INCREAMENT_FIELD_TYPE.TIMESTAMP, + description: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.EBF8762C', + defaultMessage: '类型为数值但实际含义为时间戳,如: 1609459200', + }), + }, +]; + +export const incrementByDateOptionsInNumber = ['yyyy', 'yyyyMM', 'yyyyMMdd', 'yyyyMMddHHmmss'].map( + (item) => ({ + label: item, + value: item, + }), +); + +export const PRECISION_MAP = { + second: 63, + minute: 31, + hour: 15, + day: 7, + month: 3, + year: 1, +}; diff --git a/src/component/Task/component/PartitionPolicyFormTable/index.tsx b/src/component/Task/component/PartitionPolicyFormTable/index.tsx index 20c03b4bd..6a3c348d5 100644 --- a/src/component/Task/component/PartitionPolicyFormTable/index.tsx +++ b/src/component/Task/component/PartitionPolicyFormTable/index.tsx @@ -18,7 +18,7 @@ import { getPartitionPlanKeyDataTypes } from '@/common/network/task'; import CommonTable from '@/component/CommonTable'; import { CommonTableMode, ITableLoadOptions } from '@/component/CommonTable/interface'; import SearchFilter from '@/component/SearchFilter'; -import { PARTITION_KEY_INVOKER, TaskPartitionStrategy } from '@/d.ts'; +import { PARTITION_KEY_INVOKER } from '@/d.ts'; import { formatMessage } from '@/util/intl'; import { EditOutlined, @@ -28,10 +28,10 @@ import { } from '@ant-design/icons'; import { Checkbox, Space, Tooltip } from 'antd'; import React, { useRef, useState } from 'react'; -import { ITableConfig } from '../../PartitionTask/CreateModal'; +import { ITableConfig } from '@/component/Task/modals/PartitionTask/CreateModal'; import { getStrategyLabel } from '../PartitionPolicyTable'; -import ConfigDrawer, { NameRuleType } from './configModal'; -import { revertPartitionKeyInvokerByIncrementFieldType, START_DATE } from './const'; +import ConfigDrawer from './configModal'; +import { NameRuleType, revertPartitionKeyInvokerByIncrementFieldType, START_DATE } from './const'; import styles from './index.less'; const defaultIntervalPrecision = 3; diff --git a/src/component/Task/component/PartitionPolicyFormTable/utils.ts b/src/component/Task/component/PartitionPolicyFormTable/utils.ts new file mode 100644 index 000000000..771cb0b7d --- /dev/null +++ b/src/component/Task/component/PartitionPolicyFormTable/utils.ts @@ -0,0 +1,175 @@ +import { TaskPartitionStrategy } from '@/d.ts'; +import { formatMessage } from '@/util/intl'; +import { + INCREAMENT_FIELD_TYPE, + intervalPrecisionOptions, + NameRuleType, + PRECISION_MAP, +} from './const'; +import { getLocale } from '@umijs/max'; + +const DropConfigMessage = formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.A9C95E9D', + defaultMessage: + '当前表如果包含全局索引,删除分区会导致全局索引失效,如果选择重建全局索引可能耗时很久,请谨慎操作', +}); /*"当前表如果包含全局索引,删除分区会导致全局索引失效,请谨慎操作,如果选择重建全局索引可能耗时很久,请谨慎操作"*/ + +const CreateConfigMessage = formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.8DC77765', + defaultMessage: + '当前表如果属于表组(tablegroup),创建分区可能会失败或破坏负载均衡,请谨慎配置创建策略', +}); /*"当前表如果属于表组(tablegroup),创建分区可能会失败或破坏负载均衡,请谨慎配置创建策略"*/ + +export const getAlertMessage = (strategies: TaskPartitionStrategy[]) => { + const messages = []; + if (strategies?.includes(TaskPartitionStrategy.DROP)) { + messages.push(DropConfigMessage); + } + if (strategies?.includes(TaskPartitionStrategy.CREATE)) { + messages.push(CreateConfigMessage); + } + return messages; +}; + +export const getUnitLabel = (value: number) => { + return intervalPrecisionOptions.find((item) => item.value === value)?.label; +}; + +const nameRuleOptions = [ + { + label: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.EB655A6C', + defaultMessage: '前缀 + 后缀', + }), //'前缀 + 后缀' + value: NameRuleType.PRE_SUFFIX, + }, + { + label: formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.AB4964B2', + defaultMessage: '自定义', + }), //'自定义' + value: NameRuleType.CUSTOM, + }, +]; + +export const filteredNameRuleOptions = ( + dateTypes: boolean, + incrementFieldType: INCREAMENT_FIELD_TYPE, +) => { + if (dateTypes || incrementFieldType === INCREAMENT_FIELD_TYPE.TIME_STRING) { + return nameRuleOptions; + } + return nameRuleOptions.filter((item) => item.value === NameRuleType.CUSTOM); +}; + +export const getIncrementByDateOptionsInChar = () => { + const locale = getLocale(); + const options = [ + 'yyyy', + formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.E205FB6F', + defaultMessage: 'yyyy年', + }), + + 'yyyyMM', + 'yyyy-MM', + 'yyyy/MM', + formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.216E3527', + defaultMessage: 'yyyy年MM月', + }), + + 'yyyyMMdd', + 'yyyy-MM-dd', + 'yyyy/MM/dd', + formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.EF0BF81D', + defaultMessage: 'yyyy年MM月dd日', + }), + 'yyyyMMdd HH:mm:ss', + 'yyyy-MM-dd HH:mm:ss', + 'yyyy/MM/dd HH:mm:ss', + formatMessage({ + id: 'src.component.Task.component.PartitionPolicyFormTable.RuleFormItem.13B22678', + defaultMessage: 'yyyy年MM月dd日 HH:mm:ss', + }), + ]; + + if (locale !== 'zh-CN') { + return options + .filter((item) => !/[\u4e00-\u9fa5]/.test(item)) + .map((item) => ({ + label: item, + value: item, + })); + } + + return options.map((item) => ({ + label: item, + value: item, + })); +}; + +export const getIntervalPrecisionOptionsByIncrementDateType = ( + incrementFieldTypeInDate: string, + incrementFieldType: INCREAMENT_FIELD_TYPE, +) => { + if (incrementFieldType !== INCREAMENT_FIELD_TYPE.TIME_STRING || !incrementFieldTypeInDate) { + return intervalPrecisionOptions; + } + + if (incrementFieldTypeInDate?.includes?.('s')) { + return intervalPrecisionOptions?.filter((item) => item.value <= PRECISION_MAP.second); + } + if (incrementFieldTypeInDate?.includes?.('m')) { + return intervalPrecisionOptions?.filter((item) => item.value <= PRECISION_MAP.minute); + } + if (incrementFieldTypeInDate?.includes?.('H')) { + return intervalPrecisionOptions?.filter((item) => item.value <= PRECISION_MAP.hour); + } + if (incrementFieldTypeInDate?.includes?.('d')) { + return intervalPrecisionOptions?.filter((item) => item.value <= PRECISION_MAP.day); + } + if (incrementFieldTypeInDate?.includes?.('M')) { + return intervalPrecisionOptions?.filter((item) => item.value <= PRECISION_MAP.month); + } + if (incrementFieldTypeInDate?.includes?.('y')) { + return intervalPrecisionOptions?.filter((item) => item.value <= PRECISION_MAP.year); + } + + return intervalPrecisionOptions; +}; + +export const getDefaultPrecisionByIncrementDateTypeInDate = ( + incrementFieldTypeInDate: string, + incrementFieldType: INCREAMENT_FIELD_TYPE, +) => { + if (incrementFieldType !== INCREAMENT_FIELD_TYPE.TIME_STRING || !incrementFieldTypeInDate) { + return 3; + } + + if (incrementFieldTypeInDate?.includes?.('s')) { + return PRECISION_MAP.second; + } + if (incrementFieldTypeInDate?.includes?.('m')) { + return PRECISION_MAP.minute; + } + if (incrementFieldTypeInDate?.includes?.('H')) { + return PRECISION_MAP.hour; + } + if (incrementFieldTypeInDate?.includes?.('d')) { + return PRECISION_MAP.day; + } + if (incrementFieldTypeInDate?.includes?.('M')) { + return PRECISION_MAP.month; + } + if (incrementFieldTypeInDate?.includes?.('y')) { + return PRECISION_MAP.year; + } + + return 3; +}; + +export const getPartitionKeyConfigsFormItemName = ({ name, key }) => { + return ['option', 'partitionKeyConfigs', name, key]; +}; diff --git a/src/component/Task/component/PartitionPolicyTable/ConfigDrawer.tsx b/src/component/Task/component/PartitionPolicyTable/ConfigDrawer.tsx index cd7d743e4..1604d5f03 100644 --- a/src/component/Task/component/PartitionPolicyTable/ConfigDrawer.tsx +++ b/src/component/Task/component/PartitionPolicyTable/ConfigDrawer.tsx @@ -20,7 +20,7 @@ import type { IPartitionTableConfig } from '@/d.ts'; import { PARTITION_KEY_INVOKER, TaskPartitionStrategy } from '@/d.ts'; import { Button, Descriptions, Drawer, Space } from 'antd'; import React from 'react'; -import { SimpleTextItem } from '../../component/SimpleTextItem'; +import { SimpleTextItem } from '@/component/Task/component/SimpleTextItem'; import ConfigTable from './ConfigTable'; import { getStrategyLabelByConfig } from './index'; import styles from './index.less'; diff --git a/src/component/Task/component/PartitionPolicyTable/ConfigTable.tsx b/src/component/Task/component/PartitionPolicyTable/ConfigTable.tsx index ad3700537..95ef74fc9 100644 --- a/src/component/Task/component/PartitionPolicyTable/ConfigTable.tsx +++ b/src/component/Task/component/PartitionPolicyTable/ConfigTable.tsx @@ -15,7 +15,6 @@ import { formatMessage } from '@/util/intl'; * limitations under the License. */ import DisplayTable from '@/component/DisplayTable'; -import { intervalPrecisionOptions } from '@/component/Task/component/PartitionPolicyFormTable/configModal'; import { IPartitionKeyConfig, PARTITION_KEY_INVOKER } from '@/d.ts'; import { getFormatDateTime } from '@/util/utils'; import { Descriptions, Tooltip } from 'antd'; @@ -24,6 +23,7 @@ import styles from './index.less'; import { INCREAMENT_FIELD_TYPE, increamentFieldTypeLabelMap, + intervalPrecisionOptions, } from '../PartitionPolicyFormTable/const'; const getFromCurrentTimeLabel = (fromCurrentTime: boolean, baseTimestampMillis: number) => { diff --git a/src/component/Task/component/PartitionPolicyTable/index.tsx b/src/component/Task/component/PartitionPolicyTable/index.tsx index 3f0825bfc..0a3bca2c5 100644 --- a/src/component/Task/component/PartitionPolicyTable/index.tsx +++ b/src/component/Task/component/PartitionPolicyTable/index.tsx @@ -24,7 +24,7 @@ import { formatMessage } from '@/util/intl'; import { CheckCircleFilled, SearchOutlined, StopFilled } from '@ant-design/icons'; import { Space } from 'antd'; import React, { useEffect, useRef, useState } from 'react'; -import { TaskPartitionStrategyMap } from '../../const'; +import { TaskPartitionStrategyMap } from '@/component/Task/const'; import ConfigDrawer from './ConfigDrawer'; import styles from './index.less'; diff --git a/src/component/Task/component/Status/index.tsx b/src/component/Task/component/Status/index.tsx index d6cb25c0a..e44245455 100644 --- a/src/component/Task/component/Status/index.tsx +++ b/src/component/Task/component/Status/index.tsx @@ -35,7 +35,7 @@ import { import { Space, Tooltip } from 'antd'; import { isNil } from 'lodash'; import React from 'react'; -import { isCycleTask } from '../../helper'; +import { isCycleTask } from '@/component/Task/helper'; export const nodeStatus = { [TaskFlowNodeType.APPROVAL_TASK]: { [TaskNodeStatus.PENDING]: { diff --git a/src/component/Task/component/SynchronizationItem/index.tsx b/src/component/Task/component/SynchronizationItem/index.tsx index dd3aabd16..1f981cc40 100644 --- a/src/component/Task/component/SynchronizationItem/index.tsx +++ b/src/component/Task/component/SynchronizationItem/index.tsx @@ -2,7 +2,7 @@ import { formatMessage } from '@/util/intl'; import { Form, Space, Checkbox, FormInstance, Tooltip } from 'antd'; import React, { useEffect, useState } from 'react'; import { SyncTableStructureEnum } from '@/d.ts'; -import { SyncTableStructureOptions } from '../../const'; +import { SyncTableStructureOptions } from '@/component/Task/const'; import { IDatabase } from '@/d.ts/database'; import { isConnectTypeBeFileSystemGroup } from '@/util/connection'; diff --git a/src/component/Task/component/TableSelecter/index.tsx b/src/component/Task/component/TableSelecter/index.tsx index 9acf7a191..5bfabdce5 100644 --- a/src/component/Task/component/TableSelecter/index.tsx +++ b/src/component/Task/component/TableSelecter/index.tsx @@ -21,7 +21,7 @@ import ExportCard from '@/component/ExportCard'; import { EnvColorMap } from '@/constant'; import { ReactComponent as TableSvg } from '@/svgr/menuTable.svg'; import Icon, { DeleteOutlined } from '@ant-design/icons'; -import { Badge, Empty, Popconfirm, Space, Spin, Tree, Typography } from 'antd'; +import { Badge, Popconfirm, Space, Spin, Tree, Typography } from 'antd'; import { DataNode, EventDataNode, TreeProps } from 'antd/lib/tree'; import classnames from 'classnames'; import { isConnectTypeBeFileSystemGroup } from '@/util/connection'; diff --git a/src/component/Task/component/TaskTable/const.ts b/src/component/Task/component/TaskTable/const.ts new file mode 100644 index 000000000..364fada8f --- /dev/null +++ b/src/component/Task/component/TaskTable/const.ts @@ -0,0 +1,96 @@ +import { TaskType } from '@/d.ts'; +import { formatMessage } from '@/util/intl'; + +// dev_ing 工单类型对应工单名称 +export const TaskTypeMap = { + [TaskType.IMPORT]: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTable.Import', + defaultMessage: '导入', + }), + //导入 + [TaskType.EXPORT]: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTable.Export', + defaultMessage: '导出', + }), + //导出 + [TaskType.DATAMOCK]: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTable.AnalogData', + defaultMessage: '模拟数据', + }), + //模拟数据 + [TaskType.ASYNC]: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTable.DatabaseChanges', + defaultMessage: '数据库变更', + }), + // 数据库变更 + + [TaskType.PARTITION_PLAN]: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTable.PartitionPlan', + defaultMessage: '分区计划', + }), + //分区计划 + + [TaskType.SHADOW]: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTable.ShadowTableSynchronization', + defaultMessage: '影子表同步', + }), + //影子表同步 + + [TaskType.ALTER_SCHEDULE]: formatMessage({ + id: 'odc.TaskManagePage.component.TaskTable.PlannedChange', + defaultMessage: '计划变更', + }), + //计划变更 + [TaskType.EXPORT_RESULT_SET]: formatMessage({ + id: 'odc.src.component.Task.component.TaskTable.ExportResultSet', + defaultMessage: '导出结果集', + }), + //'导出结果集' + [TaskType.SQL_PLAN]: formatMessage({ + id: 'odc.component.TaskTable.SqlPlan', + defaultMessage: 'SQL 计划', + }), + //SQL 计划 + [TaskType.DATA_ARCHIVE]: formatMessage({ + id: 'odc.component.TaskTable.DataArchiving', + defaultMessage: '数据归档', + }), + //数据归档 + [TaskType.ONLINE_SCHEMA_CHANGE]: formatMessage({ + id: 'odc.component.TaskTable.LockFreeStructureChange', + defaultMessage: '无锁结构变更', + }), + //无锁结构变更 + [TaskType.DATA_DELETE]: formatMessage({ + id: 'odc.component.TaskTable.DataCleansing', + defaultMessage: '数据清理', + }), + //数据清理 + [TaskType.APPLY_PROJECT_PERMISSION]: formatMessage({ + id: 'odc.src.component.Task.component.TaskTable.ApplicationProjectPermissions', + defaultMessage: '申请项目权限', + }), //'申请项目权限' + [TaskType.APPLY_DATABASE_PERMISSION]: formatMessage({ + id: 'src.component.Task.component.TaskTable.E1E161BA', + defaultMessage: '申请库权限', + }), //'申请库权限' + [TaskType.APPLY_TABLE_PERMISSION]: formatMessage({ + id: 'src.component.Task.component.TaskTable.573E2A28', + defaultMessage: '申请表/视图权限', + }), + [TaskType.STRUCTURE_COMPARISON]: formatMessage({ + id: 'src.component.Task.component.TaskTable.80E1D16A', + defaultMessage: '结构比对', + }), //'结构比对' + [TaskType.MULTIPLE_ASYNC]: formatMessage({ + id: 'src.component.Task.component.TaskTable.A3CA13D5', + defaultMessage: '多库变更', + }), + [TaskType.LOGICAL_DATABASE_CHANGE]: formatMessage({ + id: 'src.component.Task.component.TaskTable.4203E912', + defaultMessage: '逻辑库变更', + }), +}; + +export const TASK_EXECUTE_TIME_KEY = 'task:executeTime'; +export const TASK_EXECUTE_DATE_KEY = 'task:executeDate'; diff --git a/src/component/Task/component/TaskTable/index.tsx b/src/component/Task/component/TaskTable/index.tsx index 25f0d2723..ca1007267 100644 --- a/src/component/Task/component/TaskTable/index.tsx +++ b/src/component/Task/component/TaskTable/index.tsx @@ -22,21 +22,19 @@ import type { ITableSorter, } from '@/component/CommonTable/interface'; import { CommonTableMode, IOperationOptionType } from '@/component/CommonTable/interface'; -import { getCronExecuteCycleByObject, translator } from '@/component/Crontab'; import SearchFilter from '@/component/SearchFilter'; import StatusLabel, { cycleStatus, status } from '@/component/Task/component/Status'; import { TIME_OPTION_ALL_TASK, TimeOptions } from '@/component/TimeSelect'; import UserPopover from '@/component/UserPopover'; import type { ICycleTaskRecord, - ICycleTaskTriggerConfig, IDataArchiveJobParameters, IResponseData, ISqlPlayJobParameters, TaskRecord, TaskRecordParameters, } from '@/d.ts'; -import { TaskExecStrategy, TaskPageType, TaskStatus, TaskType } from '@/d.ts'; +import { TaskPageType, TaskType } from '@/d.ts'; import type { PageStore } from '@/store/page'; import type { TaskStore } from '@/store/task'; import { isClient } from '@/util/env'; @@ -50,8 +48,8 @@ import { inject, observer } from 'mobx-react'; import type { Dayjs } from 'dayjs'; import dayjs from 'dayjs'; import React, { useEffect, useRef, useState, useContext } from 'react'; -import { getTaskGroupLabels, getTaskLabelByType, isCycleTaskPage } from '../../helper'; -import styles from '../../index.less'; +import { getTaskGroupLabels, getTaskLabelByType, isCycleTaskPage } from '@/component/Task/helper'; +import styles from '@/component/Task/index.less'; import TaskTools from '../ActionBar'; import { listProjects } from '@/common/network/project'; import ProjectContext from '@/page/Project/ProjectContext'; @@ -59,124 +57,11 @@ import { isProjectArchived } from '@/page/Project/helper'; import { useRequest } from 'ahooks'; import useUrlAction, { URL_ACTION } from '@/util/hooks/useUrlAction'; import useURLParams from '@/util/hooks/useUrlParams'; +import { TASK_EXECUTE_DATE_KEY, TASK_EXECUTE_TIME_KEY, TaskTypeMap } from './const'; +import { getStatusFilters } from './utils'; const { RangePicker } = DatePicker; const { Text } = Typography; -export const getCronCycle = (triggerConfig: ICycleTaskTriggerConfig) => { - const { triggerStrategy, days, hours, cronExpression } = triggerConfig; - return triggerStrategy !== TaskExecStrategy.CRON - ? getCronExecuteCycleByObject(triggerStrategy as any, { - hour: hours, - dayOfWeek: days, - dayOfMonth: days, - }) - : translator.parse(cronExpression).toLocaleString(); -}; -export const TaskTypeMap = { - [TaskType.IMPORT]: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTable.Import', - defaultMessage: '导入', - }), - //导入 - [TaskType.EXPORT]: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTable.Export', - defaultMessage: '导出', - }), - //导出 - [TaskType.DATAMOCK]: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTable.AnalogData', - defaultMessage: '模拟数据', - }), - //模拟数据 - [TaskType.ASYNC]: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTable.DatabaseChanges', - defaultMessage: '数据库变更', - }), - // 数据库变更 - - [TaskType.PARTITION_PLAN]: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTable.PartitionPlan', - defaultMessage: '分区计划', - }), - //分区计划 - - [TaskType.SHADOW]: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTable.ShadowTableSynchronization', - defaultMessage: '影子表同步', - }), - //影子表同步 - - [TaskType.ALTER_SCHEDULE]: formatMessage({ - id: 'odc.TaskManagePage.component.TaskTable.PlannedChange', - defaultMessage: '计划变更', - }), - //计划变更 - [TaskType.EXPORT_RESULT_SET]: formatMessage({ - id: 'odc.src.component.Task.component.TaskTable.ExportResultSet', - defaultMessage: '导出结果集', - }), - //'导出结果集' - [TaskType.SQL_PLAN]: formatMessage({ - id: 'odc.component.TaskTable.SqlPlan', - defaultMessage: 'SQL 计划', - }), - //SQL 计划 - [TaskType.DATA_ARCHIVE]: formatMessage({ - id: 'odc.component.TaskTable.DataArchiving', - defaultMessage: '数据归档', - }), - //数据归档 - [TaskType.ONLINE_SCHEMA_CHANGE]: formatMessage({ - id: 'odc.component.TaskTable.LockFreeStructureChange', - defaultMessage: '无锁结构变更', - }), - //无锁结构变更 - [TaskType.DATA_DELETE]: formatMessage({ - id: 'odc.component.TaskTable.DataCleansing', - defaultMessage: '数据清理', - }), - //数据清理 - [TaskType.APPLY_PROJECT_PERMISSION]: formatMessage({ - id: 'odc.src.component.Task.component.TaskTable.ApplicationProjectPermissions', - defaultMessage: '申请项目权限', - }), //'申请项目权限' - [TaskType.APPLY_DATABASE_PERMISSION]: formatMessage({ - id: 'src.component.Task.component.TaskTable.E1E161BA', - defaultMessage: '申请库权限', - }), //'申请库权限' - [TaskType.APPLY_TABLE_PERMISSION]: formatMessage({ - id: 'src.component.Task.component.TaskTable.573E2A28', - defaultMessage: '申请表/视图权限', - }), - [TaskType.STRUCTURE_COMPARISON]: formatMessage({ - id: 'src.component.Task.component.TaskTable.80E1D16A', - defaultMessage: '结构比对', - }), //'结构比对' - [TaskType.MULTIPLE_ASYNC]: formatMessage({ - id: 'src.component.Task.component.TaskTable.A3CA13D5', - defaultMessage: '多库变更', - }), - [TaskType.LOGICAL_DATABASE_CHANGE]: formatMessage({ - id: 'src.component.Task.component.TaskTable.4203E912', - defaultMessage: '逻辑库变更', - }), -}; -export const getStatusFilters = (status: { - [key: string]: { - text: string; - }; -}) => { - return Object.keys(status) - ?.filter((key) => key !== TaskStatus.WAIT_FOR_CONFIRM) - .map((key) => { - return { - text: status?.[key].text, - value: key, - }; - }); -}; -export const TASK_EXECUTE_TIME_KEY = 'task:executeTime'; -export const TASK_EXECUTE_DATE_KEY = 'task:executeDate'; interface IProps { tableRef: React.RefObject; taskStore?: TaskStore; @@ -422,7 +307,8 @@ const TaskTable: React.FC = inject( /> ); }, - + onFilter: (value, record) => + record?.creator?.name?.toLowerCase()?.includes(value?.toLowerCase()), filterIcon: (filtered) => ( { + const { triggerStrategy, days, hours, cronExpression } = triggerConfig; + return triggerStrategy !== TaskExecStrategy.CRON + ? getCronExecuteCycleByObject(triggerStrategy as any, { + hour: hours, + dayOfWeek: days, + dayOfMonth: days, + }) + : translator.parse(cronExpression).toLocaleString(); +}; + +export const getStatusFilters = (status: { + [key: string]: { + text: string; + }; +}) => { + return Object.keys(status) + ?.filter((key) => key !== TaskStatus.WAIT_FOR_CONFIRM) + .map((key) => { + return { + text: status?.[key].text, + value: key, + }; + }); +}; diff --git a/src/component/Task/component/ThrottleFormItem/index.tsx b/src/component/Task/component/ThrottleFormItem/index.tsx index 2bb150f82..979e01c9a 100644 --- a/src/component/Task/component/ThrottleFormItem/index.tsx +++ b/src/component/Task/component/ThrottleFormItem/index.tsx @@ -19,7 +19,6 @@ import HelpDoc from '@/component/helpDoc'; import setting from '@/store/setting'; import { Form, InputNumber, Space } from 'antd'; import React from 'react'; -import { TaskType } from '@/d.ts'; interface IProps { initialValue?: { rowLimit?: number; diff --git a/src/component/Task/component/VariableConfigTable/index.tsx b/src/component/Task/component/VariableConfigTable/index.tsx index 50d093046..bda5b9ddc 100644 --- a/src/component/Task/component/VariableConfigTable/index.tsx +++ b/src/component/Task/component/VariableConfigTable/index.tsx @@ -15,7 +15,7 @@ */ import DisplayTable from '@/component/DisplayTable'; -import { timeUnitOptions } from '@/component/Task/DataArchiveTask/CreateModal/VariableConfig'; +import { timeUnitOptions } from '@/component/Task/modals/DataArchiveTask/CreateModal/VariableConfig'; import { formatMessage } from '@/util/intl'; import React from 'react'; const oprationReg = /^[-+]\d+[shdwmMy]$/; diff --git a/src/component/Task/const.ts b/src/component/Task/const.ts index 730dc82ea..6c722177c 100644 --- a/src/component/Task/const.ts +++ b/src/component/Task/const.ts @@ -18,7 +18,9 @@ import { SubTaskType, SyncTableStructureEnum, TaskErrorStrategy, + TaskExecStrategy, TaskPartitionStrategy, + TaskType, } from '@/d.ts'; import { formatMessage } from '@/util/intl'; @@ -103,3 +105,109 @@ export const SubTaskTypeMap = { export const OscMinRowLimit = 1; export const OscMaxRowLimit = 10000; export const OscMaxDataSizeLimit = 1000; + +export const getTaskExecStrategyMap = (type: TaskType) => { + switch (type) { + case TaskType.DATA_ARCHIVE: + case TaskType.DATA_DELETE: + case TaskType.LOGICAL_DATABASE_CHANGE: + case TaskType.PARTITION_PLAN: + return { + [TaskExecStrategy.TIMER]: formatMessage({ + id: 'odc.src.component.Task.CycleExecution', + defaultMessage: '周期执行', + }), //'周期执行' + [TaskExecStrategy.CRON]: formatMessage({ + id: 'odc.src.component.Task.CycleExecution.1', + defaultMessage: '周期执行', + }), //'周期执行' + [TaskExecStrategy.DAY]: formatMessage({ + id: 'odc.src.component.Task.CycleExecution.2', + defaultMessage: '周期执行', + }), //'周期执行' + [TaskExecStrategy.MONTH]: formatMessage({ + id: 'odc.src.component.Task.CycleExecution.3', + defaultMessage: '周期执行', + }), //'周期执行' + [TaskExecStrategy.WEEK]: formatMessage({ + id: 'odc.src.component.Task.CycleExecution.4', + defaultMessage: '周期执行', + }), //'周期执行' + [TaskExecStrategy.START_NOW]: formatMessage({ + id: 'odc.src.component.Task.ExecuteImmediately', + defaultMessage: '立即执行', + }), //'立即执行' + [TaskExecStrategy.START_AT]: formatMessage({ + id: 'odc.src.component.Task.TimedExecution', + defaultMessage: '定时执行', + }), //'定时执行' + }; + case TaskType.STRUCTURE_COMPARISON: { + return { + [TaskExecStrategy.AUTO]: formatMessage({ + id: 'src.component.Task.9B79BD20', + defaultMessage: '自动执行', + }), //'自动执行' + [TaskExecStrategy.MANUAL]: formatMessage({ + id: 'src.component.Task.0B2B1D60', + defaultMessage: '手动执行', + }), //'手动执行' + }; + } + default: + return { + [TaskExecStrategy.AUTO]: formatMessage({ + id: 'odc.components.TaskManagePage.ExecuteNow', + defaultMessage: '立即执行', + }), + //立即执行 + [TaskExecStrategy.MANUAL]: formatMessage({ + id: 'odc.components.TaskManagePage.ManualExecution', + defaultMessage: '手动执行', + }), + //手动执行 + [TaskExecStrategy.TIMER]: formatMessage({ + id: 'odc.components.TaskManagePage.ScheduledExecution', + defaultMessage: '定时执行', + }), //定时执行 + }; + } +}; +export const getTaskExecStrategyTextMap = { + [TaskExecStrategy.TIMER]: formatMessage({ + id: 'odc.src.component.Task.CycleExecution', + defaultMessage: '周期执行', + }), //'周期执行' + [TaskExecStrategy.CRON]: formatMessage({ + id: 'odc.src.component.Task.CycleExecution.1', + defaultMessage: '周期执行', + }), //'周期执行' + [TaskExecStrategy.DAY]: formatMessage({ + id: 'odc.src.component.Task.CycleExecution.2', + defaultMessage: '周期执行', + }), //'周期执行' + [TaskExecStrategy.MONTH]: formatMessage({ + id: 'odc.src.component.Task.CycleExecution.3', + defaultMessage: '周期执行', + }), //'周期执行' + [TaskExecStrategy.WEEK]: formatMessage({ + id: 'odc.src.component.Task.CycleExecution.4', + defaultMessage: '周期执行', + }), //'周期执行' + [TaskExecStrategy.START_NOW]: formatMessage({ + id: 'odc.src.component.Task.ExecuteImmediately', + defaultMessage: '立即执行', + }), //'立即执行' + [TaskExecStrategy.START_AT]: formatMessage({ + id: 'odc.src.component.Task.TimedExecution', + defaultMessage: '定时执行', + }), //'定时执行' + [TaskExecStrategy.AUTO]: formatMessage({ + id: 'src.component.Task.9B79BD20', + defaultMessage: '自动执行', + }), //'自动执行' + [TaskExecStrategy.MANUAL]: formatMessage({ + id: 'src.component.Task.0B2B1D60', + defaultMessage: '手动执行', + }), //'手动执行' +}; diff --git a/src/component/Task/Content.tsx b/src/component/Task/container/Content.tsx similarity index 80% rename from src/component/Task/Content.tsx rename to src/component/Task/container/Content.tsx index 7a4d69c5e..6a0213c1b 100644 --- a/src/component/Task/Content.tsx +++ b/src/component/Task/container/Content.tsx @@ -1,4 +1,3 @@ -import { formatMessage } from '@/util/intl'; /* * Copyright 2023 OceanBase * @@ -14,17 +13,9 @@ import { formatMessage } from '@/util/intl'; * See the License for the specific language governing permissions and * limitations under the License. */ - import { getCycleTaskDetail, getTaskDetail } from '@/common/network/task'; import type { ITableInstance, ITableLoadOptions } from '@/component/CommonTable/interface'; -import type { - IAlterScheduleTaskParams, - IDataArchiveJobParameters, - IResponseData, - ISqlPlayJobParameters, - TaskRecordParameters, - TaskStatus, -} from '@/d.ts'; +import type { IAlterScheduleTaskParams, TaskRecordParameters } from '@/d.ts'; import { IConnectionType, ICycleTaskRecord, @@ -36,20 +27,23 @@ import { import { ModalStore } from '@/store/modal'; import type { TaskStore } from '@/store/task'; import tracert from '@/util/tracert'; -import { getPreTime } from '@/util/utils'; import { useLocation } from '@umijs/max'; import { useSetState } from 'ahooks'; import { message } from 'antd'; import { inject, observer } from 'mobx-react'; import type { Dayjs } from 'dayjs'; import React, { useEffect, useRef, useMemo } from 'react'; -import TaskTable from './component/TaskTable'; -import DetailModal from './DetailModal'; -import { isCycleTask, isCycleTaskPage } from './helper'; -import styles from './index.less'; +import TaskTable from '../component/TaskTable'; +import { isCycleTask, isCycleTaskPage } from '../helper'; +import styles from '../index.less'; import { UserStore } from '@/store/login'; import { TaskDetailContext } from './TaskDetailContext'; import useURLParams from '@/util/hooks/useUrlParams'; +import { IState } from '../interface'; +import CreateModals from '../modals/CreateModals'; +import DetailModals from '../modals/DetailModals'; +import { formatMessage } from '@/util/intl'; +import { getPreTime } from '@/util/utils'; interface IProps { taskStore?: TaskStore; @@ -63,14 +57,7 @@ interface IProps { defaultTaskId?: number; defaultTaskType?: TaskType; } -export interface IState { - detailId: number; - detailType: TaskType; - detailVisible: boolean; - status: TaskStatus; - tasks: IResponseData>; - cycleTasks: IResponseData>; -} + const TaskManaerContent: React.FC = (props) => { const { pageKey, @@ -100,7 +87,7 @@ const TaskManaerContent: React.FC = (props) => { const { getParam } = useURLParams(); const urlTriggerValue = getParam('filtered'); - const TaskEventMap = { + const taskModalActions = { [TaskPageType.IMPORT]: () => modalStore.changeImportModal(true), [TaskPageType.EXPORT]: () => modalStore.changeExportModal(), [TaskPageType.DATAMOCK]: () => modalStore.changeDataMockerModal(true), @@ -128,6 +115,7 @@ const TaskManaerContent: React.FC = (props) => { ), [TaskPageType.LOGICAL_DATABASE_CHANGE]: () => modalStore.changeLogicialDatabaseModal(true), }; + const loadList = async (args: ITableLoadOptions, executeDate: [Dayjs, Dayjs]) => { const { pageKey, taskStore } = props; const taskTabType = pageKey || taskStore?.taskPageType; @@ -137,39 +125,59 @@ const TaskManaerContent: React.FC = (props) => { await loadTaskList(taskTabType, args, executeDate); } }; + + const getListParams = (taskTabType, args: ITableLoadOptions, executeDate: [Dayjs, Dayjs]) => { + const { projectId } = props; + const { filters, sorter } = args ?? {}; + const { status, candidateApprovers, creator, projectIdList, executeTime } = filters ?? {}; + const { column, order } = sorter ?? {}; + + const isAllScope = ![ + TaskPageType.CREATED_BY_CURRENT_USER, + TaskPageType.APPROVE_BY_CURRENT_USER, + ].includes(taskTabType); + const isAll = taskTabType === TaskPageType.ALL; + + const commonParams = { + projectId: projectId || projectIdList || undefined, + status, + startTime: executeDate?.length > 0 ? executeDate?.[0]?.valueOf() ?? getPreTime(7) : undefined, + endTime: executeDate?.length > 0 ? executeDate?.[1]?.valueOf() ?? getPreTime(0) : undefined, + candidateApprovers, + creator, + sort: column?.dataIndex, + containsAll: isAll || isAllScope, + }; + if (executeTime !== 'custom' && typeof executeTime === 'number') { + commonParams.startTime = getPreTime(executeTime); + commonParams.endTime = getPreTime(0); + } + const sort = column ? `${column.dataIndex},${order === 'ascend' ? 'asc' : 'desc'}` : undefined; + return { commonParams, sort, isAllScope, isAll }; + }; + const loadTaskList = async ( taskTabType, args: ITableLoadOptions, executeDate: [Dayjs, Dayjs], ) => { - const { projectId } = props; - const { filters, sorter, pagination, pageSize } = args ?? {}; - const { status, executeTime, candidateApprovers, creator, connection, id, projectIdList } = - filters ?? {}; - const { column, order } = sorter ?? {}; - const { current = 1 } = pagination ?? {}; + const { filters, pageSize, pagination } = args ?? {}; + const { connection, id } = filters ?? {}; const connectionId = connection?.filter( (key) => ![IConnectionType.PRIVATE, IConnectionType.ORGANIZATION].includes(key), ); - const isAllScope = ![ - TaskPageType.CREATED_BY_CURRENT_USER, - TaskPageType.APPROVE_BY_CURRENT_USER, - ].includes(taskTabType); - const isAll = taskTabType === TaskPageType.ALL; + const { current = 1 } = pagination ?? {}; + + const { commonParams, sort, isAll, isAllScope } = getListParams(taskTabType, args, executeDate); + if (!pageSize) { return; } const params = { + ...commonParams, fuzzySearchKeyword: id ? id : undefined, taskType: isAllScope ? (isAll ? undefined : taskTabType) : undefined, - projectId: projectId || projectIdList || undefined, - status, - startTime: executeDate?.length > 0 ? executeDate?.[0]?.valueOf() ?? getPreTime(7) : undefined, - endTime: executeDate?.length > 0 ? executeDate?.[1]?.valueOf() ?? getPreTime(0) : undefined, connectionId, - candidateApprovers, - creator, - sort: column?.dataIndex, page: current, size: pageSize, createdByCurrentUser: isAllScope @@ -178,14 +186,10 @@ const TaskManaerContent: React.FC = (props) => { approveByCurrentUser: isAllScope ? true : taskTabType === TaskPageType.APPROVE_BY_CURRENT_USER, - containsAll: isAll || isAllScope, }; - if (executeTime !== 'custom' && typeof executeTime === 'number') { - params.startTime = getPreTime(executeTime); - params.endTime = getPreTime(0); - } // sorter - params.sort = column ? `${column.dataIndex},${order === 'ascend' ? 'asc' : 'desc'}` : undefined; + params.sort = sort; + const tasks = await props.taskStore.getTaskList(params); setState({ tasks, @@ -196,41 +200,27 @@ const TaskManaerContent: React.FC = (props) => { args: ITableLoadOptions, executeDate: [Dayjs, Dayjs], ) => { - const { projectId } = props; - const { filters, sorter, pagination, pageSize } = args ?? {}; - const { status, executeTime, candidateApprovers, creator, id, projectIdList } = filters ?? {}; - const { column, order } = sorter ?? {}; + const { filters, pageSize, pagination } = args ?? {}; + const { id } = filters ?? {}; const { current = 1 } = pagination ?? {}; - const isAllScope = ![ - TaskPageType.CREATED_BY_CURRENT_USER, - TaskPageType.APPROVE_BY_CURRENT_USER, - ].includes(taskTabType); - const isAll = taskTabType === TaskPageType.ALL; + + const { commonParams, sort, isAll, isAllScope } = getListParams(taskTabType, args, executeDate); + if (!pageSize) { return; } const params = { + ...commonParams, id: id ? id : undefined, type: isAllScope ? (isAll ? undefined : taskTabType) : undefined, - projectId: projectId || projectIdList, - status, - candidateApprovers, - creator, - startTime: executeDate?.length > 0 ? executeDate?.[0]?.valueOf() ?? getPreTime(7) : undefined, - endTime: executeDate?.length > 0 ? executeDate?.[1]?.valueOf() ?? getPreTime(0) : undefined, - createdByCurrentUser: taskTabType === TaskPageType.CREATED_BY_CURRENT_USER, - approveByCurrentUser: taskTabType === TaskPageType.APPROVE_BY_CURRENT_USER, - sort: column?.dataIndex, page: urlTriggerValue ? undefined : current, size: urlTriggerValue ? undefined : pageSize, - containsAll: isAll || isAllScope, + createdByCurrentUser: taskTabType === TaskPageType.CREATED_BY_CURRENT_USER, + approveByCurrentUser: taskTabType === TaskPageType.APPROVE_BY_CURRENT_USER, }; - if (executeTime !== 'custom' && typeof executeTime === 'number') { - params.startTime = getPreTime(executeTime); - params.endTime = getPreTime(0); - } // sorter - params.sort = column ? `${column.dataIndex},${order === 'ascend' ? 'asc' : 'desc'}` : undefined; + params.sort = sort; + const cycleTasks = await props.taskStore.getCycleTaskList(params); const filteredContents = cycleTasks?.contents?.filter( (item) => @@ -246,6 +236,7 @@ const TaskManaerContent: React.FC = (props) => { const reloadList = () => { tableRef.current.reload(); }; + const handleDetailVisible = ( task: TaskRecord | ICycleTaskRecord, visible: boolean = false, @@ -265,12 +256,14 @@ const TaskManaerContent: React.FC = (props) => { }); taskOpenRef.current = visible; }; - const handleMenuClick = (type: TaskPageType) => { + + const handleMenuItemClick = (type: TaskPageType) => { tracert.click('a3112.b64006.c330917.d367464', { type, }); - TaskEventMap?.[type]?.(); + taskModalActions?.[type]?.(); }; + const openDefaultTask = async () => { const { defaultTaskId, defaultTaskType } = props; if (defaultTaskId) { @@ -295,6 +288,7 @@ const TaskManaerContent: React.FC = (props) => { taskOpenRef.current = true; } }; + useEffect(() => { openDefaultTask(); }, []); @@ -305,15 +299,11 @@ const TaskManaerContent: React.FC = (props) => { * 显示:sql控制台 */ const disableProjectCol = useMemo(() => { - if (inProject) { - return true; - } else if (userStore.isPrivateSpace()) { + if (inProject || userStore.isPrivateSpace()) { return true; - } else if (pageKey === TaskPageType.ALL && !userStore.isPrivateSpace()) { - return false; } return false; - }, [inProject, pageKey, userStore.organizationId]); + }, [inProject, userStore.organizationId]); return ( = (props) => { getTaskList={loadList} onDetailVisible={handleDetailVisible} onReloadList={reloadList} - onMenuClick={handleMenuClick} + onMenuClick={handleMenuItemClick} /> - + = function ({ taskStore, pageStore, className, isPage, inProject }) { +const { Text } = Typography; + +const Sider: React.FC = function ({ taskStore, pageStore, className, isPage }) { const firstEnabledTask = getFirstEnabledTask(); const pageKey = isPage ? pageStore?.activePageKey : taskStore?.taskPageType; - const { Text } = Typography; const { getParam, deleteParam } = useURLParams(); const urlTriggerValue = getParam('filtered'); const urlStatusValue = getParam('status'); diff --git a/src/component/Task/TaskDetailContext.tsx b/src/component/Task/container/TaskDetailContext.tsx similarity index 91% rename from src/component/Task/TaskDetailContext.tsx rename to src/component/Task/container/TaskDetailContext.tsx index 4b1cc2e52..26bc96f88 100644 --- a/src/component/Task/TaskDetailContext.tsx +++ b/src/component/Task/container/TaskDetailContext.tsx @@ -1,6 +1,6 @@ import type { ICycleTaskRecord, TaskRecord, TaskRecordParameters } from '@/d.ts'; import React from 'react'; -import { IState } from './Content'; +import { IState } from '../interface'; interface ITaskDetailContext { handleDetailVisible: ( diff --git a/src/component/Task/helper.tsx b/src/component/Task/helper.tsx index 2f4e693af..4c079fa4f 100644 --- a/src/component/Task/helper.tsx +++ b/src/component/Task/helper.tsx @@ -20,8 +20,11 @@ import login from '@/store/login'; import settingStore from '@/store/setting'; import { isClient } from '@/util/env'; import { formatMessage } from '@/util/intl'; +import { getPreTime } from '@/util/utils'; import { flatten } from 'lodash'; -export { TaskTypeMap } from '@/component/Task/component/TaskTable'; +import type { Dayjs } from 'dayjs'; +import { ITableLoadOptions } from '../CommonTable/interface'; +export { TaskTypeMap } from '@/component/Task/component/TaskTable/const'; // 423 屏蔽 SysFormItem 配置 export const ENABLED_SYS_FROM_ITEM = false; diff --git a/src/component/Task/hooks/useProjects.tsx b/src/component/Task/hooks/useLoadProjects.tsx similarity index 97% rename from src/component/Task/hooks/useProjects.tsx rename to src/component/Task/hooks/useLoadProjects.tsx index 23e0e4182..6858edadc 100644 --- a/src/component/Task/hooks/useProjects.tsx +++ b/src/component/Task/hooks/useLoadProjects.tsx @@ -18,7 +18,7 @@ import { useState } from 'react'; import { getProjectList } from '@/common/network/task'; import { IProject } from '@/d.ts/project'; -export const useProjects = () => { +export const useLoadProjects = () => { const [projects, setProjects] = useState([]); const [projectMap, setProjectMap] = useState>({}); const projectOptions = projects?.map(({ name, id }) => ({ diff --git a/src/component/Task/index.less b/src/component/Task/index.less index 0a64f9d4d..45c02c289 100644 --- a/src/component/Task/index.less +++ b/src/component/Task/index.less @@ -36,17 +36,6 @@ } } -.approvalModal { - .block:global(.ant-space) { - width: 100%; - } - :global { - .ant-modal-body { - padding: 20px; - } - } -} - .tools { :global { .ant-dropdown-menu-item { diff --git a/src/component/Task/index.tsx b/src/component/Task/index.tsx index 28c27a4ad..a619ee75f 100644 --- a/src/component/Task/index.tsx +++ b/src/component/Task/index.tsx @@ -14,127 +14,19 @@ * limitations under the License. */ -import { TaskExecStrategy, TaskType } from '@/d.ts'; +import { TaskType } from '@/d.ts'; import login from '@/store/login'; -import { formatMessage } from '@/util/intl'; import { useSearchParams } from '@umijs/max'; import { toInteger } from 'lodash'; -import Content from './Content'; -import CreateModals from './CreateModals'; +import Content from './container/Content'; import styles from './index.less'; -import Sider from './Sider'; - -export const getTaskExecStrategyMap = (type: TaskType) => { - switch (type) { - case TaskType.DATA_ARCHIVE: - case TaskType.DATA_DELETE: - case TaskType.LOGICAL_DATABASE_CHANGE: - case TaskType.PARTITION_PLAN: - return { - [TaskExecStrategy.TIMER]: formatMessage({ - id: 'odc.src.component.Task.CycleExecution', - defaultMessage: '周期执行', - }), //'周期执行' - [TaskExecStrategy.CRON]: formatMessage({ - id: 'odc.src.component.Task.CycleExecution.1', - defaultMessage: '周期执行', - }), //'周期执行' - [TaskExecStrategy.DAY]: formatMessage({ - id: 'odc.src.component.Task.CycleExecution.2', - defaultMessage: '周期执行', - }), //'周期执行' - [TaskExecStrategy.MONTH]: formatMessage({ - id: 'odc.src.component.Task.CycleExecution.3', - defaultMessage: '周期执行', - }), //'周期执行' - [TaskExecStrategy.WEEK]: formatMessage({ - id: 'odc.src.component.Task.CycleExecution.4', - defaultMessage: '周期执行', - }), //'周期执行' - [TaskExecStrategy.START_NOW]: formatMessage({ - id: 'odc.src.component.Task.ExecuteImmediately', - defaultMessage: '立即执行', - }), //'立即执行' - [TaskExecStrategy.START_AT]: formatMessage({ - id: 'odc.src.component.Task.TimedExecution', - defaultMessage: '定时执行', - }), //'定时执行' - }; - case TaskType.STRUCTURE_COMPARISON: { - return { - [TaskExecStrategy.AUTO]: formatMessage({ - id: 'src.component.Task.9B79BD20', - defaultMessage: '自动执行', - }), //'自动执行' - [TaskExecStrategy.MANUAL]: formatMessage({ - id: 'src.component.Task.0B2B1D60', - defaultMessage: '手动执行', - }), //'手动执行' - }; - } - default: - return { - [TaskExecStrategy.AUTO]: formatMessage({ - id: 'odc.components.TaskManagePage.ExecuteNow', - defaultMessage: '立即执行', - }), - //立即执行 - [TaskExecStrategy.MANUAL]: formatMessage({ - id: 'odc.components.TaskManagePage.ManualExecution', - defaultMessage: '手动执行', - }), - //手动执行 - [TaskExecStrategy.TIMER]: formatMessage({ - id: 'odc.components.TaskManagePage.ScheduledExecution', - defaultMessage: '定时执行', - }), //定时执行 - }; - } -}; -export const getTaskExecStrategyTextMap = { - [TaskExecStrategy.TIMER]: formatMessage({ - id: 'odc.src.component.Task.CycleExecution', - defaultMessage: '周期执行', - }), //'周期执行' - [TaskExecStrategy.CRON]: formatMessage({ - id: 'odc.src.component.Task.CycleExecution.1', - defaultMessage: '周期执行', - }), //'周期执行' - [TaskExecStrategy.DAY]: formatMessage({ - id: 'odc.src.component.Task.CycleExecution.2', - defaultMessage: '周期执行', - }), //'周期执行' - [TaskExecStrategy.MONTH]: formatMessage({ - id: 'odc.src.component.Task.CycleExecution.3', - defaultMessage: '周期执行', - }), //'周期执行' - [TaskExecStrategy.WEEK]: formatMessage({ - id: 'odc.src.component.Task.CycleExecution.4', - defaultMessage: '周期执行', - }), //'周期执行' - [TaskExecStrategy.START_NOW]: formatMessage({ - id: 'odc.src.component.Task.ExecuteImmediately', - defaultMessage: '立即执行', - }), //'立即执行' - [TaskExecStrategy.START_AT]: formatMessage({ - id: 'odc.src.component.Task.TimedExecution', - defaultMessage: '定时执行', - }), //'定时执行' - [TaskExecStrategy.AUTO]: formatMessage({ - id: 'src.component.Task.9B79BD20', - defaultMessage: '自动执行', - }), //'自动执行' - [TaskExecStrategy.MANUAL]: formatMessage({ - id: 'src.component.Task.0B2B1D60', - defaultMessage: '手动执行', - }), //'手动执行' -}; +import Sider from './container/Sider'; interface IProps { projectId?: number; inProject?: boolean; } -const TaskManaerPage: React.FC = (props) => { +const TaskManagerPage: React.FC = (props) => { const { projectId, inProject } = props; const [search] = useSearchParams(); const defaultTaskId = search.get('taskId'); @@ -154,9 +46,8 @@ const TaskManaerPage: React.FC = (props) => { defaultTaskType={defaultTaskType} defaultTaskId={isOrganizationMatch ? toInteger(defaultTaskId) : null} /> - ); }; -export default TaskManaerPage; +export default TaskManagerPage; diff --git a/src/component/Task/interface.ts b/src/component/Task/interface.ts index 9a4f3cda5..6cafb48d5 100644 --- a/src/component/Task/interface.ts +++ b/src/component/Task/interface.ts @@ -24,7 +24,21 @@ import type { TaskRecordParameters, IResponseData, Operation, + TaskStatus, + ICycleTaskRecord, + ISqlPlayJobParameters, + IDataArchiveJobParameters, + TaskType, } from '@/d.ts'; + +export interface IState { + detailId: number; + detailType: TaskType; + detailVisible: boolean; + status: TaskStatus; + tasks: IResponseData>; + cycleTasks: IResponseData>; +} export interface ITaskDetailModalProps { visible: boolean; taskTools: React.ReactNode; diff --git a/src/component/Task/modals/AlterDdlTask/CreateModal/const.ts b/src/component/Task/modals/AlterDdlTask/CreateModal/const.ts new file mode 100644 index 000000000..ef5d65d61 --- /dev/null +++ b/src/component/Task/modals/AlterDdlTask/CreateModal/const.ts @@ -0,0 +1,80 @@ +import { formatMessage } from '@/util/intl'; + +export const rules = { + sqlType: [ + { + required: true, + message: formatMessage({ + id: 'odc.AlterDdlTask.CreateModal.SelectAChangeDefinition', + defaultMessage: '请选择变更定义', + }), //请选择变更定义 + }, + ], + sqlContent: [ + { + required: true, + message: formatMessage({ + id: 'odc.AlterDdlTask.CreateModal.EnterTheSqlContent', + defaultMessage: '请填写 SQL 内容', + }), //请填写 SQL 内容 + }, + ], + lockTableTimeOutSeconds: [ + { + required: true, + message: formatMessage({ + id: 'odc.AlterDdlTask.CreateModal.EnterATimeoutPeriod', + defaultMessage: '请输入超时时间', + }), //请输入超时时间 + }, + { + type: 'number', + max: 3600, + message: formatMessage({ + id: 'odc.AlterDdlTask.CreateModal.UpToSeconds', + defaultMessage: '最大不超过 3600 秒', + }), //最大不超过 3600 秒 + }, + ], + swapTableNameRetryTimes: [ + { + required: true, + message: formatMessage({ + id: 'odc.AlterDdlTask.CreateModal.PleaseEnterTheNumberOf', + defaultMessage: '请输入失败重试次数', + }), //请输入失败重试次数 + }, + ], + originTableCleanStrategy: [ + { + required: true, + message: formatMessage({ + id: 'odc.AlterDdlTask.CreateModal.SelectACleanupPolicy', + defaultMessage: '请选择清理策略', + }), //请选择清理策略 + }, + ], + errorStrategy: [ + { + required: true, + message: formatMessage({ + id: 'odc.AlterDdlTask.CreateModal.SelectTaskErrorHandling', + defaultMessage: '请选择任务错误处理', + }), //请选择任务错误处理 + }, + ], + swapTableType: [ + { + required: true, + message: formatMessage({ + id: 'odc.src.component.Task.AlterDdlTask.CreateModal.PleaseSelectTheTableName', + defaultMessage: '请选择表名切换方式', + }), //'请选择表名切换方式' + }, + ], +}; + +export enum SwapTableType { + AUTO = 'AUTO', + MANUAL = 'MANUAL', +} diff --git a/src/component/Task/AlterDdlTask/CreateModal/index.less b/src/component/Task/modals/AlterDdlTask/CreateModal/index.less similarity index 100% rename from src/component/Task/AlterDdlTask/CreateModal/index.less rename to src/component/Task/modals/AlterDdlTask/CreateModal/index.less diff --git a/src/component/Task/AlterDdlTask/CreateModal/index.tsx b/src/component/Task/modals/AlterDdlTask/CreateModal/index.tsx similarity index 83% rename from src/component/Task/AlterDdlTask/CreateModal/index.tsx rename to src/component/Task/modals/AlterDdlTask/CreateModal/index.tsx index fbe917527..743c64f5b 100644 --- a/src/component/Task/AlterDdlTask/CreateModal/index.tsx +++ b/src/component/Task/modals/AlterDdlTask/CreateModal/index.tsx @@ -60,12 +60,14 @@ import { import { useRequest } from 'ahooks'; import { inject, observer } from 'mobx-react'; import React, { useEffect, useRef, useState } from 'react'; -import DatabaseSelect from '../../component/DatabaseSelect'; -import ThrottleFormItem from '../../component/ThrottleFormItem'; -import { OscMaxDataSizeLimit, OscMaxRowLimit, OscMinRowLimit } from '../../const'; +import DatabaseSelect from '@/component/Task/component/DatabaseSelect'; +import ThrottleFormItem from '@/component/Task/component/ThrottleFormItem'; +import { OscMaxDataSizeLimit, OscMaxRowLimit, OscMinRowLimit } from '@/component/Task/const'; import { haveOCP } from '@/util/env'; import styles from './index.less'; import { isBoolean } from 'lodash'; +import { rules, SwapTableType } from './const'; +import { Rule } from 'antd/es/form'; interface IProps { modalStore?: ModalStore; @@ -81,10 +83,7 @@ enum SqlType { CREATE = 'CREATE', ALTER = 'ALTER', } -export enum SwapTableType { - AUTO = 'AUTO', - MANUAL = 'MANUAL', -} + export enum ClearStrategy { ORIGIN_TABLE_RENAME_AND_RESERVED = 'ORIGIN_TABLE_RENAME_AND_RESERVED', ORIGIN_TABLE_DROP = 'ORIGIN_TABLE_DROP', @@ -513,20 +512,17 @@ const CreateDDLTaskModal: React.FC = (props) => { })} /*变更定义*/ name="sqlType" initialValue={SqlType.CREATE} - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.AlterDdlTask.CreateModal.SelectAChangeDefinition', - defaultMessage: '请选择变更定义', - }), //请选择变更定义 - }, - ]} + rules={rules.sqlType} > - - CREATE TABLE - ALTER TABLE - + = (props) => { })} /*SQL 内容*/ className={styles.sqlContent} - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.AlterDdlTask.CreateModal.EnterTheSqlContent', - defaultMessage: '请填写 SQL 内容', - }), //请填写 SQL 内容 - }, - ]} + rules={rules.sqlContent} style={{ height: '280px', }} @@ -592,23 +580,7 @@ const CreateDDLTaskModal: React.FC = (props) => { defaultMessage: '秒', })} /*秒*/ name="lockTableTimeOutSeconds" - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.AlterDdlTask.CreateModal.EnterATimeoutPeriod', - defaultMessage: '请输入超时时间', - }), //请输入超时时间 - }, - { - type: 'number', - max: 3600, - message: formatMessage({ - id: 'odc.AlterDdlTask.CreateModal.UpToSeconds', - defaultMessage: '最大不超过 3600 秒', - }), //最大不超过 3600 秒 - }, - ]} + rules={rules.lockTableTimeOutSeconds as Rule[]} initialValue={5} noStyle > @@ -639,15 +611,7 @@ const CreateDDLTaskModal: React.FC = (props) => { } initialValue={3} required - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.AlterDdlTask.CreateModal.PleaseEnterTheNumberOf', - defaultMessage: '请输入失败重试次数', - }), //请输入失败重试次数 - }, - ]} + rules={rules.swapTableNameRetryTimes} > @@ -660,34 +624,26 @@ const CreateDDLTaskModal: React.FC = (props) => { })} /*完成后源表清理策略*/ name="originTableCleanStrategy" initialValue={ClearStrategy.ORIGIN_TABLE_RENAME_AND_RESERVED} - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.AlterDdlTask.CreateModal.SelectACleanupPolicy', - defaultMessage: '请选择清理策略', - }), //请选择清理策略 - }, - ]} + rules={rules.originTableCleanStrategy} > - - + - + }) /*重命名不处理*/, + value: ClearStrategy.ORIGIN_TABLE_RENAME_AND_RESERVED, + }, { - formatMessage({ + label: formatMessage({ id: 'odc.AlterDdlTask.CreateModal.DeleteNow', defaultMessage: '立即删除', - }) /*立即删除*/ - } - - + }) /*立即删除*/, + value: ClearStrategy.ORIGIN_TABLE_DROP, + }, + ]} + /> = (props) => { })} /*任务错误处理*/ name="errorStrategy" initialValue={ErrorStrategy.ABORT} - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.AlterDdlTask.CreateModal.SelectTaskErrorHandling', - defaultMessage: '请选择任务错误处理', - }), //请选择任务错误处理 - }, - ]} + rules={rules.errorStrategy} > - - + - + }) /*停止任务*/, + }, { - formatMessage({ + value: ErrorStrategy.CONTINUE, + label: formatMessage({ id: 'odc.AlterDdlTask.CreateModal.IgnoreErrorsToContinueThe', defaultMessage: '忽略错误继续任务', - }) /*忽略错误继续任务*/ - } - - + }) /*忽略错误继续任务*/, + }, + ]} + /> = (props) => { } name="swapTableType" initialValue={SwapTableType.AUTO} - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.src.component.Task.AlterDdlTask.CreateModal.PleaseSelectTheTableName', - defaultMessage: '请选择表名切换方式', - }), //'请选择表名切换方式' - }, - ]} + rules={rules.swapTableType} > - - + - + }) /* 自动切换 */, + }, { - formatMessage({ + value: SwapTableType.MANUAL, + label: formatMessage({ id: 'odc.src.component.Task.AlterDdlTask.CreateModal.ManualSwitch', defaultMessage: '手动切换', - }) /* 手工切换 */ - } - - + }) /* 手工切换 */, + }, + ]} + /> {settingStore.enableOSCLimiting && ( { - if (isCustomExpireTime) { - return customExpireTime?.valueOf(); - } else { - const [offset, unit] = expireTime.split(',') ?? []; - return offset === 'never' ? dayjs(MAX_DATE)?.valueOf() : dayjs().add(offset, unit)?.valueOf(); - } -}; - -export const getExpireTimeLabel = (expireTime) => { - const label = dayjs(expireTime).format('YYYY-MM-DD'); - return label === MAX_DATE_LABEL - ? formatMessage({ - id: 'src.component.Task.ApplyDatabasePermission.CreateModal.B5C7760D', - defaultMessage: '永不过期', - }) - : label; -}; - -const Label: React.FC<{ - text: string; - docKey: string; -}> = ({ text, docKey }) => ( - - {text} - -); - -export const permissionOptionsMap = { - [DatabasePermissionType.QUERY]: { - text: formatMessage({ - id: 'src.component.Task.ApplyDatabasePermission.CreateModal.8890FE39', - defaultMessage: '查询', - }), //'查询' - docKey: 'ApplyDatabasePermissionQueryTip', - value: DatabasePermissionType.QUERY, - }, - [DatabasePermissionType.EXPORT]: { - text: formatMessage({ - id: 'src.component.Task.ApplyDatabasePermission.CreateModal.3B7A9E11', - defaultMessage: '导出', - }), //'导出' - docKey: 'ApplyDatabasePermissionExportTip', - value: DatabasePermissionType.EXPORT, - }, - [DatabasePermissionType.CHANGE]: { - text: formatMessage({ - id: 'src.component.Task.ApplyDatabasePermission.CreateModal.985A0E7F', - defaultMessage: '变更', - }), //'变更' - docKey: 'ApplyDatabasePermissionChangeTip', - value: DatabasePermissionType.CHANGE, - }, -}; - -export const permissionOptions = Object.values(permissionOptionsMap)?.map( - ({ text, docKey, ...rest }) => ({ - ...rest, - label: @@ -1053,27 +971,7 @@ const CreateModal: React.FC = (props) => { defaultMessage: '小时', })} /* 小时 */ name="timeoutMillis" - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.components.CreateAsyncTaskModal.EnterATimeoutPeriod', - defaultMessage: '请输入超时时间', - }), - - // 请输入超时时间 - }, - { - type: 'number', - max: 480, - message: formatMessage({ - id: 'odc.components.CreateAsyncTaskModal.MaximumLengthOfHours', - defaultMessage: '最大不超过 480 小时', - }), - - // 最大不超过480小时 - }, - ]} + rules={rules.timeoutMillis as Rule[]} initialValue={48} noStyle > diff --git a/src/component/Task/AsyncTask/DetailContent/index.less b/src/component/Task/modals/AsyncTask/DetailContent/index.less similarity index 100% rename from src/component/Task/AsyncTask/DetailContent/index.less rename to src/component/Task/modals/AsyncTask/DetailContent/index.less diff --git a/src/component/Task/AsyncTask/DetailContent/index.tsx b/src/component/Task/modals/AsyncTask/DetailContent/index.tsx similarity index 97% rename from src/component/Task/AsyncTask/DetailContent/index.tsx rename to src/component/Task/modals/AsyncTask/DetailContent/index.tsx index bdd63a9f0..44fd77fb3 100644 --- a/src/component/Task/AsyncTask/DetailContent/index.tsx +++ b/src/component/Task/modals/AsyncTask/DetailContent/index.tsx @@ -17,18 +17,18 @@ import { getDataSourceModeConfigByConnectionMode } from '@/common/datasource'; import RiskLevelLabel from '@/component/RiskLevelLabel'; import { SQLContent } from '@/component/SQLContent'; -import { getTaskExecStrategyMap } from '@/component/Task'; import type { IAsyncTaskParams, ITaskResult, TaskDetail } from '@/d.ts'; import { TaskExecStrategy, TaskFlowNodeType, TaskNodeStatus } from '@/d.ts'; import { formatMessage } from '@/util/intl'; import { getFormatDateTime, milliSecondsToHour } from '@/util/utils'; import { InfoCircleOutlined, LoadingOutlined } from '@ant-design/icons'; import { Descriptions, Divider, Space, Tooltip } from 'antd'; -import DatabaseLabel from '../../component/DatabaseLabel'; -import { DownloadFileAction } from '../../component/DownloadFileAction'; -import { SimpleTextItem } from '../../component/SimpleTextItem'; +import DatabaseLabel from '@/component/Task/component/DatabaseLabel'; +import { DownloadFileAction } from '@/component/Task/component/DownloadFileAction'; +import { SimpleTextItem } from '@/component/Task/component/SimpleTextItem'; import styles from './index.less'; import login from '@/store/login'; +import { getTaskExecStrategyMap } from '@/component/Task/const'; export const ErrorStrategy = { ABORT: formatMessage({ diff --git a/src/component/Task/AsyncTask/index.tsx b/src/component/Task/modals/AsyncTask/index.tsx similarity index 100% rename from src/component/Task/AsyncTask/index.tsx rename to src/component/Task/modals/AsyncTask/index.tsx diff --git a/src/component/Task/CreateModals.tsx b/src/component/Task/modals/CreateModals.tsx similarity index 100% rename from src/component/Task/CreateModals.tsx rename to src/component/Task/modals/CreateModals.tsx diff --git a/src/component/Task/DataArchiveTask/CreateModal/ArchiveRange.tsx b/src/component/Task/modals/DataArchiveTask/CreateModal/ArchiveRange.tsx similarity index 92% rename from src/component/Task/DataArchiveTask/CreateModal/ArchiveRange.tsx rename to src/component/Task/modals/DataArchiveTask/CreateModal/ArchiveRange.tsx index fd199eb4c..5ff6d1004 100644 --- a/src/component/Task/DataArchiveTask/CreateModal/ArchiveRange.tsx +++ b/src/component/Task/modals/DataArchiveTask/CreateModal/ArchiveRange.tsx @@ -20,15 +20,16 @@ import { PlusOutlined, SettingOutlined, SettingFilled } from '@ant-design/icons' import { Button, Checkbox, Form, Input, Radio, Select, Typography, Tooltip } from 'antd'; import classNames from 'classnames'; import { useEffect, useState } from 'react'; -import ArchiveRangeTip from '../../component/ArchiveRangeTip'; -import { PartitionTextArea } from '../../component/PartitionTextArea'; +import ArchiveRangeTip from '@/component/Task/component/ArchiveRangeTip'; +import { PartitionTextArea } from '@/component/Task/component/PartitionTextArea'; import { IArchiveRange } from './index'; import styles from './index.less'; import BatchSelectionPopover from '@/component/BatchSelectionPopover'; import { isConnectTypeBeFileSystemGroup } from '@/util/connection'; import { IDatabase } from '@/d.ts/database'; -import JoinTableConfigModal from '../../component/JoinTableConfigsModal'; -import useJoinTableConfig from '../../component/JoinTableConfigsModal/useJoinTableConfig'; +import JoinTableConfigModal from '@/component/Task/component/JoinTableConfigsModal'; +import useJoinTableConfig from '@/component/Task/component/JoinTableConfigsModal/useJoinTableConfig'; +import { rules } from './const'; const { Text, Link } = Typography; @@ -81,24 +82,24 @@ const ArchiveRange: React.FC = (props) => { /*归档范围*/ name="archiveRange" required > - - + - + }) /*部分归档*/, + value: IArchiveRange.PORTION, + }, { - formatMessage({ + label: formatMessage({ id: 'odc.DataArchiveTask.CreateModal.ArchiveRange.ArchiveTheEntireDatabase', defaultMessage: '整库归档', - }) /*整库归档*/ - } - - + }) /*整库归档*/, + value: IArchiveRange.ALL, + }, + ]} + /> {({ getFieldValue }) => { @@ -202,15 +203,7 @@ const ArchiveRange: React.FC = (props) => { = (props) => { = (props) => { ({ label: item, @@ -166,15 +167,7 @@ const VariableConfig: React.FC = (props) => { { + return [ + { + required, + message: formatMessage({ + id: 'odc.src.component.Task.DataClearTask.CreateModal.PleaseChoose.1', + defaultMessage: '请选择', + }), //'请选择' + }, + ]; + }, + operator: ({ required }) => { + return [ + { + required, + message: formatMessage({ + id: 'odc.src.component.Task.DataClearTask.CreateModal.PleaseChoose', + defaultMessage: '请选择', + }), //'请选择' + }, + ]; + }, + step: ({ required }) => { + return [ + { + required, + message: formatMessage({ + id: 'odc.src.component.Task.DataClearTask.CreateModal.PleaseEnter', + defaultMessage: '请输入', + }), //'请输入' + }, + ]; + }, +}; diff --git a/src/component/Task/DataClearTask/CreateModal/index.less b/src/component/Task/modals/DataClearTask/CreateModal/index.less similarity index 100% rename from src/component/Task/DataClearTask/CreateModal/index.less rename to src/component/Task/modals/DataClearTask/CreateModal/index.less diff --git a/src/component/Task/DataClearTask/CreateModal/index.tsx b/src/component/Task/modals/DataClearTask/CreateModal/index.tsx similarity index 96% rename from src/component/Task/DataClearTask/CreateModal/index.tsx rename to src/component/Task/modals/DataClearTask/CreateModal/index.tsx index d12e21d6e..f9a807057 100644 --- a/src/component/Task/DataClearTask/CreateModal/index.tsx +++ b/src/component/Task/modals/DataClearTask/CreateModal/index.tsx @@ -45,19 +45,20 @@ import { Button, Checkbox, DatePicker, Drawer, Form, Modal, Radio, Space, Spin } import { inject, observer } from 'mobx-react'; import dayjs from 'dayjs'; import React, { useEffect, useRef, useState } from 'react'; -import DatabaseSelect from '../../component/DatabaseSelect'; -import SQLPreviewModal from '../../component/SQLPreviewModal'; -import TaskdurationItem from '../../component/TaskdurationItem'; -import ThrottleFormItem from '../../component/ThrottleFormItem'; -import { getVariableValue } from '../../DataArchiveTask/CreateModal'; +import DatabaseSelect from '@/component/Task/component/DatabaseSelect'; +import SQLPreviewModal from '@/component/Task/component/SQLPreviewModal'; +import TaskdurationItem from '@/component/Task/component/TaskdurationItem'; +import ThrottleFormItem from '@/component/Task/component/ThrottleFormItem'; +import { getVariableValue } from '@/component/Task/modals/DataArchiveTask/CreateModal'; import ArchiveRange from './ArchiveRange'; import styles from './index.less'; import VariableConfig from './VariableConfig'; -import ShardingStrategyItem from '../../component/ShardingStrategyItem'; +import ShardingStrategyItem from '@/component/Task/component/ShardingStrategyItem'; import { disabledDate, disabledTime } from '@/util/utils'; import { useRequest } from 'ahooks'; -import DirtyRowAction from '../../component/DirtyRowAction'; -import MaxAllowedDirtyRowCount from '../../component/MaxAllowedDirtyRowCount'; +import DirtyRowAction from '@/component/Task/component/DirtyRowAction'; +import MaxAllowedDirtyRowCount from '@/component/Task/component/MaxAllowedDirtyRowCount'; +import { rules } from './const'; export enum IArchiveRange { PORTION = 'portion', @@ -681,15 +682,7 @@ const CreateModal: React.FC = (props) => { }) /*"使用主键清理"*/ } name="deleteByUniqueKey" - rules={[ - { - required: true, - message: formatMessage({ - id: 'src.component.Task.DataClearTask.CreateModal.23542D89', - defaultMessage: '请选择', - }), //'请选择' - }, - ]} + rules={rules.deleteByUniqueKey} > diff --git a/src/component/Task/DataClearTask/DetailContent/ArchiveRange.tsx b/src/component/Task/modals/DataClearTask/DetailContent/ArchiveRange.tsx similarity index 98% rename from src/component/Task/DataClearTask/DetailContent/ArchiveRange.tsx rename to src/component/Task/modals/DataClearTask/DetailContent/ArchiveRange.tsx index db2b92bcb..8bf5e2e8c 100644 --- a/src/component/Task/DataClearTask/DetailContent/ArchiveRange.tsx +++ b/src/component/Task/modals/DataClearTask/DetailContent/ArchiveRange.tsx @@ -18,7 +18,7 @@ import DisplayTable from '@/component/DisplayTable'; import { formatMessage } from '@/util/intl'; import { Flex, Popover, Tooltip, Typography } from 'antd'; import React from 'react'; -import { conditionExpressionColumns } from '../../helper'; +import { conditionExpressionColumns } from '@/component/Task/helper'; const columns = (needCheckBeforeDelete: boolean) => [ { diff --git a/src/component/Task/DataClearTask/DetailContent/index.tsx b/src/component/Task/modals/DataClearTask/DetailContent/index.tsx similarity index 97% rename from src/component/Task/DataClearTask/DetailContent/index.tsx rename to src/component/Task/modals/DataClearTask/DetailContent/index.tsx index d82c19a33..3dfcf570d 100644 --- a/src/component/Task/DataClearTask/DetailContent/index.tsx +++ b/src/component/Task/modals/DataClearTask/DetailContent/index.tsx @@ -16,7 +16,6 @@ import { updateLimiterConfig } from '@/common/network/task'; import RiskLevelLabel from '@/component/RiskLevelLabel'; -import { getTaskExecStrategyMap } from '@/component/Task'; import { SimpleTextItem } from '@/component/Task/component/SimpleTextItem'; import VariableConfigTable from '@/component/Task/component/VariableConfigTable'; import { isCycleTriggerStrategy } from '@/component/Task/helper'; @@ -34,14 +33,15 @@ import { import { DownOutlined, UpOutlined } from '@ant-design/icons'; import { Collapse, Descriptions, Divider, message, Space, Typography } from 'antd'; import React from 'react'; -import ThrottleEditableCell from '../../component/ThrottleEditableCell'; -import styles from '../../index.less'; +import ThrottleEditableCell from '@/component/Task/component/ThrottleEditableCell'; +import styles from '@/component/Task/index.less'; import ArchiveRange from './ArchiveRange'; -import { shardingStrategyOptions } from '../../component/ShardingStrategyItem'; +import { shardingStrategyOptions } from '@/component/Task/component/ShardingStrategyItem'; import { DirtyRowActionEnum, DirtyRowActionLabelMap, } from '@/component/ExecuteSqlDetailModal/constant'; +import { getTaskExecStrategyMap } from '@/component/Task/const'; const { Panel } = Collapse; const { Text } = Typography; diff --git a/src/component/Task/DataClearTask/index.tsx b/src/component/Task/modals/DataClearTask/index.tsx similarity index 100% rename from src/component/Task/DataClearTask/index.tsx rename to src/component/Task/modals/DataClearTask/index.tsx diff --git a/src/component/Task/DataMockerTask/CreateModal/RuleConfigTable.tsx b/src/component/Task/modals/DataMockerTask/CreateModal/RuleConfigTable.tsx similarity index 93% rename from src/component/Task/DataMockerTask/CreateModal/RuleConfigTable.tsx rename to src/component/Task/modals/DataMockerTask/CreateModal/RuleConfigTable.tsx index 359446993..176357908 100644 --- a/src/component/Task/DataMockerTask/CreateModal/RuleConfigTable.tsx +++ b/src/component/Task/modals/DataMockerTask/CreateModal/RuleConfigTable.tsx @@ -22,7 +22,8 @@ import { ColumnProps } from 'antd/es/table'; import React, { useState } from 'react'; import RuleContent, { getDefaultValue } from './RuleContent'; import RuleSelect from './RuleSelect'; -import { IMockFormColumn, IMockFormData, RuleConfigList } from './type'; +import { IMockFormColumn, IMockFormData } from './type'; +import { rules } from './const'; const { Option } = Select; @@ -98,15 +99,7 @@ const RuleConfigTable: React.FC = (props) => { style={{ marginBottom: 0 }} shouldUpdate name={['columns', index, 'rule']} - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.component.DataMockerDrawer.RuleConfigTable.SelectARule', - defaultMessage: '请选择规则', - }), // 请选择规则 - }, - ]} + rules={rules.columnsRule} > { + return [ + { + required: true, + message: formatMessage({ + id: 'odc.component.DataMockerDrawer.form.EnterTheSimulatedDataVolume', + defaultMessage: '请输入模拟数据量', + }), + + // 请输入模拟数据量 + }, + { + max: maxMockLimit, + type: 'number', + }, + ]; + }, +}; diff --git a/src/component/Task/DataMockerTask/CreateModal/form.tsx b/src/component/Task/modals/DataMockerTask/CreateModal/form.tsx similarity index 85% rename from src/component/Task/DataMockerTask/CreateModal/form.tsx rename to src/component/Task/modals/DataMockerTask/CreateModal/form.tsx index c6d450f43..b9e683c80 100644 --- a/src/component/Task/DataMockerTask/CreateModal/form.tsx +++ b/src/component/Task/modals/DataMockerTask/CreateModal/form.tsx @@ -29,12 +29,14 @@ import { FormInstance } from 'antd/es/form/Form'; import { cloneDeep } from 'lodash'; import { inject, observer } from 'mobx-react'; import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from 'react'; -import DatabaseSelect from '../../component/DatabaseSelect'; +import DatabaseSelect from '@/component/Task/component/DatabaseSelect'; import RuleConfigTable from './RuleConfigTable'; import { convertFormToServerColumns, getDefaultRule, getDefaultValue } from './RuleContent'; import { IMockFormData, MockStrategy, MockStrategyTextMap, RuleConfigList } from './type'; import { NumberRuleType } from './RuleContent/ruleItems/NumberItem'; import styles from './index.less'; +import { rules } from './const'; +import { Rule } from 'antd/es/form'; const { Option } = Select; @@ -207,17 +209,7 @@ const DataMockerForm: React.FC = inject('settingStore')( = inject('settingStore')( = inject('settingStore')( = inject('settingStore')( /* 插入模拟数据清空表 */ > - - + - + }), + value: false, + }, { - formatMessage({ + label: formatMessage({ id: 'odc.component.DataMockerDrawer.form.Is', defaultMessage: '是', - }) - - /* 是 */ - } - - + }), + value: true, + }, + ]} + /> diff --git a/src/component/Task/DataMockerTask/CreateModal/index.less b/src/component/Task/modals/DataMockerTask/CreateModal/index.less similarity index 100% rename from src/component/Task/DataMockerTask/CreateModal/index.less rename to src/component/Task/modals/DataMockerTask/CreateModal/index.less diff --git a/src/component/Task/DataMockerTask/CreateModal/index.tsx b/src/component/Task/modals/DataMockerTask/CreateModal/index.tsx similarity index 100% rename from src/component/Task/DataMockerTask/CreateModal/index.tsx rename to src/component/Task/modals/DataMockerTask/CreateModal/index.tsx diff --git a/src/component/Task/DataMockerTask/CreateModal/type.ts b/src/component/Task/modals/DataMockerTask/CreateModal/type.ts similarity index 100% rename from src/component/Task/DataMockerTask/CreateModal/type.ts rename to src/component/Task/modals/DataMockerTask/CreateModal/type.ts diff --git a/src/component/Task/DataMockerTask/DetailContent/index.tsx b/src/component/Task/modals/DataMockerTask/DetailContent/index.tsx similarity index 95% rename from src/component/Task/DataMockerTask/DetailContent/index.tsx rename to src/component/Task/modals/DataMockerTask/DetailContent/index.tsx index a37b87e32..f7921070f 100644 --- a/src/component/Task/DataMockerTask/DetailContent/index.tsx +++ b/src/component/Task/modals/DataMockerTask/DetailContent/index.tsx @@ -15,10 +15,9 @@ */ import RiskLevelLabel from '@/component/RiskLevelLabel'; -import { getTaskExecStrategyMap } from '@/component/Task'; -import RuleConfigTable from '@/component/Task/DataMockerTask/CreateModal/RuleConfigTable'; -import { convertServerColumnsToFormColumns } from '@/component/Task/DataMockerTask/CreateModal/RuleContent'; -import { MockStrategyTextMap } from '@/component/Task/DataMockerTask/CreateModal/type'; +import RuleConfigTable from '@/component/Task/modals/DataMockerTask/CreateModal/RuleConfigTable'; +import { convertServerColumnsToFormColumns } from '@/component/Task/modals/DataMockerTask/CreateModal/RuleContent'; +import { MockStrategyTextMap } from '@/component/Task/modals/DataMockerTask/CreateModal/type'; import { IMockDataParams, IServerMockTable, @@ -29,7 +28,8 @@ import { import { formatMessage } from '@/util/intl'; import { getFormatDateTime } from '@/util/utils'; import Form from 'antd/lib/form/Form'; -import DatabaseLabel from '../../component/DatabaseLabel'; +import DatabaseLabel from '@/component/Task/component/DatabaseLabel'; +import { getTaskExecStrategyMap } from '@/component/Task/const'; export function getItems(task: TaskDetail, result: ITaskResult, hasFlow: boolean) { if (!task) { return []; diff --git a/src/component/Task/DataMockerTask/index.tsx b/src/component/Task/modals/DataMockerTask/index.tsx similarity index 100% rename from src/component/Task/DataMockerTask/index.tsx rename to src/component/Task/modals/DataMockerTask/index.tsx diff --git a/src/component/Task/DetailModal.tsx b/src/component/Task/modals/DetailModals.tsx similarity index 97% rename from src/component/Task/DetailModal.tsx rename to src/component/Task/modals/DetailModals.tsx index 50c4fdd83..150ab82d2 100644 --- a/src/component/Task/DetailModal.tsx +++ b/src/component/Task/modals/DetailModals.tsx @@ -13,8 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -import { getProjectWithErrorCatch } from '@/common/network/project'; import { getCycleTaskDetail, getCycleTaskLog, @@ -42,7 +40,6 @@ import type { ITaskResult, TaskDetail, Operation, - TaskRecord, } from '@/d.ts'; import { CommonTaskLogType, @@ -58,13 +55,13 @@ import { ApplyDatabasePermissionTaskContent } from './ApplyDatabasePermission'; import { ApplyPermissionTaskContent } from './ApplyPermission'; import { ApplyTablePermissionTaskContent } from './ApplyTablePermission'; import { AsyncTaskContent } from './AsyncTask'; -import TaskTools from './component/ActionBar'; -import ApprovalModal from './component/ApprovalModal'; +import TaskTools from '../component/ActionBar'; +import ApprovalModal from '../component/ApprovalModal'; import { DataArchiveTaskContent } from './DataArchiveTask'; import { DataClearTaskContent } from './DataClearTask'; import { getItems as getDataMockerItems } from './DataMockerTask'; -import { isCycleTask, isLogicalDbChangeTask } from './helper'; -import { TaskDetailType } from './interface'; +import { isCycleTask, isLogicalDbChangeTask } from '../helper'; +import { TaskDetailType } from '../interface'; import { LogicDatabaseAsyncTaskContent } from './LogicDatabaseAsyncTask'; import { MutipleAsyncTaskContent } from './MutipleAsyncTask'; import { PartitionTaskContent } from './PartitionTask'; diff --git a/src/component/Task/ExportTask/CreateModal/ExportForm/ConfigPanel/index.tsx b/src/component/Task/modals/ExportTask/CreateModal/ExportForm/ConfigPanel/index.tsx similarity index 77% rename from src/component/Task/ExportTask/CreateModal/ExportForm/ConfigPanel/index.tsx rename to src/component/Task/modals/ExportTask/CreateModal/ExportForm/ConfigPanel/index.tsx index dfdb7c95f..2df89287b 100644 --- a/src/component/Task/ExportTask/CreateModal/ExportForm/ConfigPanel/index.tsx +++ b/src/component/Task/modals/ExportTask/CreateModal/ExportForm/ConfigPanel/index.tsx @@ -28,6 +28,7 @@ import { AutoComplete, Checkbox, Col, Form, FormInstance, InputNumber, Row, Sele import React, { useContext } from 'react'; import FormContext from '../FormContext'; import { CRLFToSeparatorString } from '@/util/utils'; +import { rules } from '../../const'; const FormItem = Form.Item; const Option = Select.Option; @@ -60,40 +61,6 @@ const ConfigPanel: React.FC = function ({ form, connection }) { }, ]; - const validator = (_, value) => { - if ( - value === - formatMessage({ id: 'odc.ExportForm.ConfigPanel.Unlimited', defaultMessage: '无限制' }) //无限制 - ) { - return Promise.resolve(); - } else { - // 当value不为'无限制'时,它的类型可能为string或者number。 - const size = parseInt(value); - // 当value为011时,它可以转换为整数,但不是我们想要的参数形式,所以使用转换前后的长度来进行比较。 - if (Number.isNaN(size) || size.toString().length !== value.toString().length) { - return Promise.reject( - new Error( - formatMessage({ - id: 'odc.ExportForm.ConfigPanel.SelectUnlimitedOrEnterA', - defaultMessage: '请选择"无限制"或者输入 0 < size <= 2048 范围内的正整数', - }), - ), //请选择"无限制"或者输入0 < size <= 2048范围内的正整数 - ); - } - if (size > 0 && size <= 2048) { - return Promise.resolve(); - } else { - return Promise.reject( - new Error( - formatMessage({ - id: 'odc.ExportForm.ConfigPanel.SetTheUpperLimitOf', - defaultMessage: '请将单个文件上限设定为 0 < size <= 2048 范围内的正整数', - }), - ), //请将单个文件上限设定为0 < size <= 2048范围内的正整数 - ); - } - } - }; return ( <> @@ -135,15 +102,7 @@ const ConfigPanel: React.FC = function ({ form, connection }) { // 数据格式 } - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.ExportDrawer.ExportForm.SelectExportFormat', - defaultMessage: '请选择导出格式', - }), - }, - ]} + rules={rules.dataTransferFormat} > {Object.entries(IMPORT_ENCODING).map(([text, value]) => { @@ -221,18 +172,7 @@ const ConfigPanel: React.FC = function ({ form, connection }) { } name="exportFileMaxSize" - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.ExportForm.ConfigPanel.PleaseFillInOrSelect', - defaultMessage: '请填写或者选择单个文件上限(MB)', - }), //请填写或者选择单个文件上限(MB) - }, - () => ({ - validator, - }), - ]} + rules={rules.exportFileMaxSize} > @@ -281,15 +221,9 @@ const ConfigPanel: React.FC = function ({ form, connection }) { = function ({ form, connection }) { } name="columnSeparator" - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.ImportDrawer.ImportForm.EnterAFieldDelimiter', - defaultMessage: '请填写字段分隔符', - }), - }, - - { - max: 1, - message: formatMessage({ - id: 'odc.ExportDrawer.ExportForm.YouCanEnterOnlyOne', - defaultMessage: '只能输入一个字符', - }), - - // 只能输入一个字符 - }, - ]} + rules={rules.columnSeparator} > { @@ -399,15 +315,7 @@ const ConfigPanel: React.FC = function ({ form, connection }) { } name="columnDelimiter" - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.ImportDrawer.ImportForm.EnterATextIdentifier', - defaultMessage: '请填写文本识别符', - }), - }, - ]} + rules={rules.columnDelimiter} > = function ({ })} /* 任务错误处理 */ name="stopWhenError" > - - + - + }), + value: true, + }, { - formatMessage({ + label: formatMessage({ id: 'odc.ImportDrawer.ImportForm.IgnoreErrorsContinueTasks', defaultMessage: '忽略错误继续任务', - }) - - /* 忽略错误继续任务 */ - } - - + }), + value: false, + }, + ]} + /> )} diff --git a/src/component/Task/ImportTask/CreateModal/ImportForm/CsvProvider.ts b/src/component/Task/modals/ImportTask/CreateModal/ImportForm/CsvProvider.ts similarity index 100% rename from src/component/Task/ImportTask/CreateModal/ImportForm/CsvProvider.ts rename to src/component/Task/modals/ImportTask/CreateModal/ImportForm/CsvProvider.ts diff --git a/src/component/Task/ImportTask/CreateModal/ImportForm/FileSelecterPanel/index.less b/src/component/Task/modals/ImportTask/CreateModal/ImportForm/FileSelecterPanel/index.less similarity index 100% rename from src/component/Task/ImportTask/CreateModal/ImportForm/FileSelecterPanel/index.less rename to src/component/Task/modals/ImportTask/CreateModal/ImportForm/FileSelecterPanel/index.less diff --git a/src/component/Task/ImportTask/CreateModal/ImportForm/FileSelecterPanel/index.tsx b/src/component/Task/modals/ImportTask/CreateModal/ImportForm/FileSelecterPanel/index.tsx similarity index 94% rename from src/component/Task/ImportTask/CreateModal/ImportForm/FileSelecterPanel/index.tsx rename to src/component/Task/modals/ImportTask/CreateModal/ImportForm/FileSelecterPanel/index.tsx index c9cc072b6..092a4ec5d 100644 --- a/src/component/Task/ImportTask/CreateModal/ImportForm/FileSelecterPanel/index.tsx +++ b/src/component/Task/modals/ImportTask/CreateModal/ImportForm/FileSelecterPanel/index.tsx @@ -40,6 +40,7 @@ import FormContext from '../FormContext'; import styles from './index.less'; import { selectFolder } from '@/util/client'; import { getImportFileMeta } from '@/common/network/exportAndImport'; +import { rules } from '../../const'; const FormItem = Form.Item; const Option = Select.Option; @@ -211,15 +212,7 @@ const FileSelecterPanel: React.FC = function ({ isSingleImport, form }) defaultMessage: '导入文件格式', })} name="fileType" - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.ImportDrawer.ImportForm.SelectAnImportFormat', - defaultMessage: '请选择导入格式', - }), - }, - ]} + rules={rules.fileType} > {Object.entries(IMPORT_ENCODING).map(([text, value]) => { diff --git a/src/component/Task/ImportTask/CreateModal/ImportForm/FormConfigContext.tsx b/src/component/Task/modals/ImportTask/CreateModal/ImportForm/FormConfigContext.tsx similarity index 100% rename from src/component/Task/ImportTask/CreateModal/ImportForm/FormConfigContext.tsx rename to src/component/Task/modals/ImportTask/CreateModal/ImportForm/FormConfigContext.tsx diff --git a/src/component/Task/ImportTask/CreateModal/ImportForm/FormContext.ts b/src/component/Task/modals/ImportTask/CreateModal/ImportForm/FormContext.ts similarity index 100% rename from src/component/Task/ImportTask/CreateModal/ImportForm/FormContext.ts rename to src/component/Task/modals/ImportTask/CreateModal/ImportForm/FormContext.ts diff --git a/src/component/Task/ImportTask/CreateModal/ImportForm/formitem/CsvFormItem.tsx b/src/component/Task/modals/ImportTask/CreateModal/ImportForm/formitem/CsvFormItem.tsx similarity index 78% rename from src/component/Task/ImportTask/CreateModal/ImportForm/formitem/CsvFormItem.tsx rename to src/component/Task/modals/ImportTask/CreateModal/ImportForm/formitem/CsvFormItem.tsx index 3c427eee4..4473d3e55 100644 --- a/src/component/Task/ImportTask/CreateModal/ImportForm/formitem/CsvFormItem.tsx +++ b/src/component/Task/modals/ImportTask/CreateModal/ImportForm/formitem/CsvFormItem.tsx @@ -20,6 +20,7 @@ import { formatMessage } from '@/util/intl'; import { CRLFToSeparatorString } from '@/util/utils'; import { AutoComplete, Checkbox, Col, Form, Row, Select } from 'antd'; import React from 'react'; +import { rules } from '../../const'; const { Option } = Select; const FormItem = Form.Item; @@ -81,23 +82,7 @@ const CsvFormItem: React.FC = function (props) { } name="columnSeparator" - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.ImportDrawer.ImportForm.EnterAFieldDelimiter', - defaultMessage: '请填写字段分隔符', - }), - }, - - { - max: 1, - message: formatMessage({ - id: 'odc.ImportForm.formitem.CsvFormItem.YouCanEnterOnlyOne', - defaultMessage: '只能输入一个字符', - }), // 只能输入一个字符 - }, - ]} + rules={rules.columnSeparator} > { @@ -118,15 +103,7 @@ const CsvFormItem: React.FC = function (props) { } name="columnDelimiter" - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.ImportDrawer.ImportForm.EnterATextIdentifier', - defaultMessage: '请填写文本识别符', - }), - }, - ]} + rules={rules.columnDelimiter} > { - return array?.reduce?.((pre, cur) => pre?.concat(Array.isArray(cur) ? flatArray(cur) : cur), []); -}; + export enum SiderTabKeys { SELECT_DATABASE = 'SELECT_DATABASE', SQL_CONTENT = 'SQL_CONTENT', diff --git a/src/component/Task/MutipleAsyncTask/CreateModal/index.less b/src/component/Task/modals/MutipleAsyncTask/CreateModal/index.less similarity index 100% rename from src/component/Task/MutipleAsyncTask/CreateModal/index.less rename to src/component/Task/modals/MutipleAsyncTask/CreateModal/index.less diff --git a/src/component/Task/MutipleAsyncTask/CreateModal/index.tsx b/src/component/Task/modals/MutipleAsyncTask/CreateModal/index.tsx similarity index 92% rename from src/component/Task/MutipleAsyncTask/CreateModal/index.tsx rename to src/component/Task/modals/MutipleAsyncTask/CreateModal/index.tsx index 117ec97e4..27a946198 100644 --- a/src/component/Task/MutipleAsyncTask/CreateModal/index.tsx +++ b/src/component/Task/modals/MutipleAsyncTask/CreateModal/index.tsx @@ -41,12 +41,14 @@ import { inject, observer } from 'mobx-react'; import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; import DatabaseQueue from './DatabaseQueue'; import DrawerFooter from './DrawerFooter'; -import { flatArray, IProps, items, SiderTabKeys } from './helper'; +import { IProps, items, SiderTabKeys } from './helper'; +import { flatArray } from '@/util/utils'; import styles from './index.less'; import MoreSetting from './MoreSetting'; import { MultipleAsyncContext } from './MultipleAsyncContext'; import ProjectSelect from './ProjectSelect'; import setting from '@/store/setting'; +import { rules } from '../const'; const MAX_FILE_SIZE = 1024 * 1024 * 256; @@ -588,59 +590,37 @@ const CreateModal: React.FC = (props) => { })} name="sqlContentType" initialValue={SQLContentType.TEXT} - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.components.CreateAsyncTaskModal.SelectSqlContent', - defaultMessage: '请选择 SQL 内容', - }), - - // 请选择 SQL 内容 - }, - ]} + rules={rules.sqlContentType} > { - handleChange('sqlContentType', e.target.value); - }} - > - + options={[ { - formatMessage({ + label: formatMessage({ id: 'odc.components.CreateAsyncTaskModal.SqlEntry', defaultMessage: 'SQL 录入', - }) - - /* SQL录入 */ - } - - + }), + value: SQLContentType.TEXT, + }, { - formatMessage({ + label: formatMessage({ id: 'odc.components.CreateAsyncTaskModal.UploadAttachments', defaultMessage: '上传附件', - }) - - /* 上传附件 */ - } - - + }), + value: SQLContentType.FILE, + }, + ]} + optionType="button" + onChange={(e) => handleChange('sqlContentType', e.target.value)} + /> = (props) => { noStyle > { - handleChange('rollbackContentType', e.target.value); - }} - > - - {formatMessage({ - id: 'src.component.Task.MutipleAsyncTask.CreateModal.F79FDCAD', - defaultMessage: 'SQL 录入', - })} - - - {formatMessage({ - id: 'src.component.Task.MutipleAsyncTask.CreateModal.447DDBF6', - defaultMessage: '上传附件', - })} - - + options={[ + { + label: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.CreateModal.F79FDCAD', + defaultMessage: 'SQL 录入', + }), + value: SQLContentType.TEXT, + }, + { + label: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.CreateModal.447DDBF6', + defaultMessage: '上传附件', + }), + value: SQLContentType.FILE, + }, + ]} + optionType="button" + onChange={(e) => handleChange('rollbackContentType', e.target.value)} + /> ; @@ -43,16 +44,6 @@ const CreateTemplate: React.FC<{ } }; - const checkNameRepeat = async (ruler, value) => { - const name = value?.trim(); - if (!name) { - return; - } - const isRepeat = await existsTemplateName(name, projectId, login.organizationId?.toString()); - if (isRepeat) { - throw new Error(); - } - }; return ( { - const name = value?.trim(); - if (!name) { - return; - } - const isRepeat = await existsTemplateName(name, projectId, login.organizationId?.toString()); - if (isRepeat && name !== currentTemplate?.name) { - throw new Error( - formatMessage({ - id: 'src.component.Task.MutipleAsyncTask.components.Template.A6EB2822', - defaultMessage: '模版名称已存在', - }), - ); - } - }; + useEffect(() => { if (open) { loadDatabaseList(projectId); @@ -231,18 +218,7 @@ const EditTemplate: React.FC<{ defaultMessage: '模版名称', })} name="name" - rules={[ - { - required: true, - message: formatMessage({ - id: 'src.component.Task.MutipleAsyncTask.components.Template.F3DD7E9F', - defaultMessage: '请输入', - }), - }, - { - validator: checkNameRepeat, - }, - ]} + rules={rules.editName({ projectId, currentTemplate })} > [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.components.Template.F3DD7E9F', + defaultMessage: '请输入', + }), + }, + { + validator: async (ruler, value) => { + const name = value?.trim(); + if (!name) { + return; + } + const isRepeat = await existsTemplateName( + name, + projectId, + login.organizationId?.toString(), + ); + if (isRepeat && name !== currentTemplate?.name) { + throw new Error( + formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.components.Template.A6EB2822', + defaultMessage: '模版名称已存在', + }), + ); + } + }, + }, + ], + name: ({ projectId }) => [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.components.Template.4B3E6B15', + defaultMessage: '请输入模版名称', + }), + }, + { + message: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.components.Template.1797C71B', + defaultMessage: '模版名称已存在', + }), + required: true, + validator: async (ruler, value) => { + const name = value?.trim(); + if (!name) { + return; + } + const isRepeat = await existsTemplateName( + name, + projectId, + login.organizationId?.toString(), + ); + if (isRepeat) { + throw new Error(); + } + }, + }, + ], + ['parameters-sqlContent']: ({ required }) => { + return [ + { + required, + message: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.CreateModal.20CA9283', + defaultMessage: '请填写 SQL 内容', + }), + }, + ]; + }, + innerName: ({ databaseOptionMap }) => { + return [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.CreateModal.E7E1BCF3', + defaultMessage: '请选择数据库', + }), + }, + { + validateTrigger: 'onChange', + validator: async (ruler, value) => { + if (value && !databaseOptionMap?.[value]) { + throw new Error( + formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.CreateModal.94128D2B', + defaultMessage: '该数据库不属于当前项目', + }), + ); + } + }, + }, + ]; + }, + ['parameters-delimiter']: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.CreateModal.FF497D5B', + defaultMessage: '请输入分隔符', + }), + }, + ], + ['parameters-queryLimit']: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.CreateModal.631AD60F', + defaultMessage: '请输入查询结果限制', + }), + }, + { + validator: (_, value) => { + const max = setting.getSpaceConfigByKey('odc.sqlexecute.default.maxQueryLimit'); + if (value !== undefined && value > max) { + return Promise.reject( + formatMessage( + { + id: 'src.component.Task.MutipleAsyncTask.CreateModal.61AA1269', + defaultMessage: '不超过查询条数上限 {max}', + }, + { max }, + ), + ); + } + return Promise.resolve(); + }, + }, + ], + ['parameters-timeoutMillis']: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.CreateModal.57804D6A', + defaultMessage: '请输入超时时间', + }), + }, + { + type: 'number', + max: 480, + message: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.CreateModal.50D2F13E', + defaultMessage: '最大不超过480小时', + }), + }, + ], + ['parameters-errorStrategy']: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.CreateModal.C3F2CC4E', + defaultMessage: '请选择SQL 执行处理', + }), + }, + ], + executionStrategy: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.CreateModal.B1EBE15F', + defaultMessage: '请选择执行方式', + }), + }, + ], + ['parameters-autoErrorStrategy']: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.CreateModal.D2818FDA', + defaultMessage: '请选择任务错误处理', + }), + }, + ], + ['parameters-manualTimeoutMillis']: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.CreateModal.73A16360', + defaultMessage: '请输入手动确认超时时间', + }), + }, + { + type: 'number', + max: 480, + message: formatMessage({ + id: 'src.component.Task.MutipleAsyncTask.CreateModal.61541BB4', + defaultMessage: '最大不超过480小时', + }), + }, + ], + projectId: [ + { + required: true, + message: formatMessage({ + id: 'odc.src.component.Task.ApplyPermission.CreateModal.PleaseSelectTheProject', + defaultMessage: '请选择项目', + }), //'请选择项目' + }, + ], +}; diff --git a/src/component/Task/MutipleAsyncTask/index.tsx b/src/component/Task/modals/MutipleAsyncTask/index.tsx similarity index 100% rename from src/component/Task/MutipleAsyncTask/index.tsx rename to src/component/Task/modals/MutipleAsyncTask/index.tsx diff --git a/src/component/Task/modals/PartitionTask/CreateModal/const.ts b/src/component/Task/modals/PartitionTask/CreateModal/const.ts new file mode 100644 index 000000000..7f2d3e921 --- /dev/null +++ b/src/component/Task/modals/PartitionTask/CreateModal/const.ts @@ -0,0 +1,30 @@ +import { formatMessage } from '@/util/intl'; + +export const rules = { + errorStrategy: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.PartitionTask.CreateModal.6C651A64', + defaultMessage: '请选择任务错误处理', + }), //'请选择任务错误处理' + }, + ], + timeoutMillis: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.PartitionTask.CreateModal.05B817DF', + defaultMessage: '请输入超时时间', + }), //'请输入超时时间' + }, + { + type: 'number', + max: 480, + message: formatMessage({ + id: 'src.component.Task.PartitionTask.CreateModal.25D1BD6D', + defaultMessage: '最大不超过480小时', + }), //'最大不超过480小时' + }, + ], +}; diff --git a/src/component/Task/PartitionTask/CreateModal/index.less b/src/component/Task/modals/PartitionTask/CreateModal/index.less similarity index 100% rename from src/component/Task/PartitionTask/CreateModal/index.less rename to src/component/Task/modals/PartitionTask/CreateModal/index.less diff --git a/src/component/Task/PartitionTask/CreateModal/index.tsx b/src/component/Task/modals/PartitionTask/CreateModal/index.tsx similarity index 94% rename from src/component/Task/PartitionTask/CreateModal/index.tsx rename to src/component/Task/modals/PartitionTask/CreateModal/index.tsx index 71d4bc40f..bb6ba32c3 100644 --- a/src/component/Task/PartitionTask/CreateModal/index.tsx +++ b/src/component/Task/modals/PartitionTask/CreateModal/index.tsx @@ -57,15 +57,17 @@ import { DrawerProps } from 'antd/es/drawer'; import { inject, observer } from 'mobx-react'; import dayjs from 'dayjs'; import React, { useCallback, useEffect, useRef, useState } from 'react'; -import DatabaseSelect from '../../component/DatabaseSelect'; -import PartitionPolicyFormTable from '../../component/PartitionPolicyFormTable'; +import DatabaseSelect from '@/component/Task/component/DatabaseSelect'; +import PartitionPolicyFormTable from '@/component/Task/component/PartitionPolicyFormTable'; import { getPartitionKeyInvokerByIncrementFieldType, INCREAMENT_FIELD_TYPE, START_DATE, -} from '../../component/PartitionPolicyFormTable/const'; +} from '@/component/Task/component/PartitionPolicyFormTable/const'; import styles from './index.less'; import { useRequest } from 'ahooks'; +import { rules } from './const'; +import { Rule } from 'antd/es/form'; const { Paragraph, Text } = Typography; @@ -795,34 +797,26 @@ const CreateModal: React.FC = inject('modalStore')( }) /*"任务错误处理"*/ } name="errorStrategy" - rules={[ - { - required: true, - message: formatMessage({ - id: 'src.component.Task.PartitionTask.CreateModal.6C651A64', - defaultMessage: '请选择任务错误处理', - }), //'请选择任务错误处理' - }, - ]} + rules={rules.errorStrategy} > - - + - + }), + value: TaskErrorStrategy.ABORT, + }, { - formatMessage({ - id: 'src.component.Task.PartitionTask.CreateModal.E454F701' /*忽略错误继续任务*/, + label: formatMessage({ + id: 'src.component.Task.PartitionTask.CreateModal.E454F701', defaultMessage: '忽略错误继续任务', - }) /* 忽略错误继续任务 */ - } - - + }), + value: TaskErrorStrategy.CONTINUE, + }, + ]} + /> = inject('modalStore')( }) /*"小时"*/ } name="timeoutMillis" - rules={[ - { - required: true, - message: formatMessage({ - id: 'src.component.Task.PartitionTask.CreateModal.05B817DF', - defaultMessage: '请输入超时时间', - }), //'请输入超时时间' - }, - { - type: 'number', - max: 480, - message: formatMessage({ - id: 'src.component.Task.PartitionTask.CreateModal.25D1BD6D', - defaultMessage: '最大不超过480小时', - }), //'最大不超过480小时' - }, - ]} + rules={rules.timeoutMillis as Rule[]} noStyle > diff --git a/src/component/Task/PartitionTask/DetailContent/CycleDescriptionItem.tsx b/src/component/Task/modals/PartitionTask/DetailContent/CycleDescriptionItem.tsx similarity index 99% rename from src/component/Task/PartitionTask/DetailContent/CycleDescriptionItem.tsx rename to src/component/Task/modals/PartitionTask/DetailContent/CycleDescriptionItem.tsx index f55e79968..fe444351b 100644 --- a/src/component/Task/PartitionTask/DetailContent/CycleDescriptionItem.tsx +++ b/src/component/Task/modals/PartitionTask/DetailContent/CycleDescriptionItem.tsx @@ -16,7 +16,7 @@ import { formatMessage } from '@/util/intl'; */ import { SimpleTextItem } from '@/component/Task/component/SimpleTextItem'; -import { getCronCycle } from '@/component/Task/component/TaskTable'; +import { getCronCycle } from '@/component/Task/component/TaskTable/utils'; import type { ICycleTaskTriggerConfig } from '@/d.ts'; import { getFormatDateTime } from '@/util/utils'; import { DownOutlined, UpOutlined } from '@ant-design/icons'; diff --git a/src/component/Task/PartitionTask/DetailContent/index.less b/src/component/Task/modals/PartitionTask/DetailContent/index.less similarity index 100% rename from src/component/Task/PartitionTask/DetailContent/index.less rename to src/component/Task/modals/PartitionTask/DetailContent/index.less diff --git a/src/component/Task/PartitionTask/DetailContent/index.tsx b/src/component/Task/modals/PartitionTask/DetailContent/index.tsx similarity index 96% rename from src/component/Task/PartitionTask/DetailContent/index.tsx rename to src/component/Task/modals/PartitionTask/DetailContent/index.tsx index 90c154ad6..893059ec8 100644 --- a/src/component/Task/PartitionTask/DetailContent/index.tsx +++ b/src/component/Task/modals/PartitionTask/DetailContent/index.tsx @@ -20,9 +20,9 @@ import type { IIPartitionPlanTaskDetail, IPartitionPlanParams, ITaskResult } fro import { getFormatDateTime, milliSecondsToHour } from '@/util/utils'; import { Descriptions, Divider, Typography } from 'antd'; import React from 'react'; -import DatabaseLabel from '../../component/DatabaseLabel'; -import PartitionPolicyTable from '../../component/PartitionPolicyTable'; -import { ErrorStrategyMap } from '../../const'; +import DatabaseLabel from '@/component/Task/component/DatabaseLabel'; +import PartitionPolicyTable from '@/component/Task/component/PartitionPolicyTable'; +import { ErrorStrategyMap } from '@/component/Task/const'; import CycleDescriptionItem from './CycleDescriptionItem'; const { Text } = Typography; diff --git a/src/component/Task/PartitionTask/index.tsx b/src/component/Task/modals/PartitionTask/index.tsx similarity index 100% rename from src/component/Task/PartitionTask/index.tsx rename to src/component/Task/modals/PartitionTask/index.tsx diff --git a/src/component/Task/PermissionApplication/CreateModal/index.less b/src/component/Task/modals/PermissionApplication/CreateModal/index.less similarity index 100% rename from src/component/Task/PermissionApplication/CreateModal/index.less rename to src/component/Task/modals/PermissionApplication/CreateModal/index.less diff --git a/src/component/Task/PermissionApplication/CreateModal/index.tsx b/src/component/Task/modals/PermissionApplication/CreateModal/index.tsx similarity index 99% rename from src/component/Task/PermissionApplication/CreateModal/index.tsx rename to src/component/Task/modals/PermissionApplication/CreateModal/index.tsx index 976b74fe3..9e07c877a 100644 --- a/src/component/Task/PermissionApplication/CreateModal/index.tsx +++ b/src/component/Task/modals/PermissionApplication/CreateModal/index.tsx @@ -386,7 +386,7 @@ const CreateModal: React.FC = inject('modalStore')( value: 'custom', }, ]} - > + /> = (props) => { }) /* 字段分隔符 */ } name={['csvFormat', 'columnSeparator']} - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.src.component.Task.ResultSetExportTask.CreateModal.PleaseFillInTheField', - defaultMessage: '请填写字段分隔符', - }), //'请填写字段分隔符' - }, - { - max: 1, - message: formatMessage({ - id: 'odc.src.component.Task.ResultSetExportTask.CreateModal.YouCanOnlyEnterOne', - defaultMessage: '只能输入一个字符', - }), //'只能输入一个字符' - }, - ]} + rules={rules['csvFormat-columnSeparator']} > { @@ -130,15 +116,7 @@ export const CsvFormItemPanel: React.FC = (props) => { }) /* 文本识别符 */ } name={['csvFormat', 'columnDelimiter']} - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.src.component.Task.ResultSetExportTask.CreateModal.PleaseFillInTheText', - defaultMessage: '请填写文本识别符', - }), //'请填写文本识别符' - }, - ]} + rules={rules['csvFormat-columnDelimiter']} > , result: ITaskResult, diff --git a/src/component/Task/ResultSetExportTask/index.tsx b/src/component/Task/modals/ResultSetExportTask/index.tsx similarity index 100% rename from src/component/Task/ResultSetExportTask/index.tsx rename to src/component/Task/modals/ResultSetExportTask/index.tsx diff --git a/src/component/Task/modals/SQLPlanTask/CreateModal/const.ts b/src/component/Task/modals/SQLPlanTask/CreateModal/const.ts new file mode 100644 index 000000000..964fff0d8 --- /dev/null +++ b/src/component/Task/modals/SQLPlanTask/CreateModal/const.ts @@ -0,0 +1,102 @@ +import setting from '@/store/setting'; +import { formatMessage } from '@/util/intl'; + +export const rules = { + sqlContentType: [ + { + required: true, + message: formatMessage({ + id: 'odc.components.CreateSQLPlanTaskModal.SelectSqlContent', + defaultMessage: '请选择 SQL 内容', + }), + //请选择 SQL 内容 + }, + ], + sqlContent: ({ required }) => { + return [ + { + required, + message: formatMessage({ + id: 'odc.components.CreateSQLPlanTaskModal.EnterTheSqlContent', + defaultMessage: '请填写 SQL 内容', + }), + //请填写 SQL 内容 + }, + ]; + }, + delimiter: [ + { + required: true, + message: formatMessage({ + id: 'odc.components.CreateSQLPlanTaskModal.EnterADelimiter', + defaultMessage: '请输入分隔符', + }), + //请输入分隔符 + }, + ], + queryLimit: [ + { + required: true, + message: formatMessage({ + id: 'odc.components.CreateSQLPlanTaskModal.PleaseEnterTheQueryResult', + defaultMessage: '请输入查询结果限制', + }), + //请输入查询结果限制 + }, + { + validator: (_, value) => { + const max = setting.getSpaceConfigByKey('odc.sqlexecute.default.maxQueryLimit'); + if (value !== undefined && value > max) { + return Promise.reject( + formatMessage( + { + id: 'src.component.Task.SQLPlanTask.CreateModal.B88FB9EC', + defaultMessage: '不超过查询条数上限 {max}', + }, + { max }, + ), + ); + } + return Promise.resolve(); + }, + }, + ], + timeoutMillis: [ + { + required: true, + message: formatMessage({ + id: 'odc.components.CreateSQLPlanTaskModal.EnterATimeoutPeriod', + defaultMessage: '请输入超时时间', + }), + //请输入超时时间 + }, + { + type: 'number', + max: 480, + message: formatMessage({ + id: 'odc.components.CreateSQLPlanTaskModal.UpToHours', + defaultMessage: '最大不超过 480 小时', + }), + //最大不超过480小时 + }, + ], + errorStrategy: [ + { + required: true, + message: formatMessage({ + id: 'odc.components.CreateSQLPlanTaskModal.SelectTaskErrorHandling', + defaultMessage: '请选择任务错误处理', + }), + //请选择任务错误处理 + }, + ], + allowConcurrent: [ + { + required: true, + message: formatMessage({ + id: 'odc.components.CreateSQLPlanTaskModal.PleaseSelectTaskExecutionDuration', + defaultMessage: '请选择任务执行时长超周期处理', + }), //请选择任务执行时长超周期处理 + }, + ], +}; diff --git a/src/component/Task/SQLPlanTask/CreateModal/index.less b/src/component/Task/modals/SQLPlanTask/CreateModal/index.less similarity index 100% rename from src/component/Task/SQLPlanTask/CreateModal/index.less rename to src/component/Task/modals/SQLPlanTask/CreateModal/index.less diff --git a/src/component/Task/SQLPlanTask/CreateModal/index.tsx b/src/component/Task/modals/SQLPlanTask/CreateModal/index.tsx similarity index 81% rename from src/component/Task/SQLPlanTask/CreateModal/index.tsx rename to src/component/Task/modals/SQLPlanTask/CreateModal/index.tsx index e0fe1a416..01f729f8e 100644 --- a/src/component/Task/SQLPlanTask/CreateModal/index.tsx +++ b/src/component/Task/modals/SQLPlanTask/CreateModal/index.tsx @@ -55,11 +55,13 @@ import { import type { UploadFile } from 'antd/lib/upload/interface'; import Cookies from 'js-cookie'; import { inject, observer } from 'mobx-react'; -import React, { useCallback, useEffect, useRef, useState } from 'react'; -import DatabaseSelect from '../../component/DatabaseSelect'; +import React, { useEffect, useRef, useState } from 'react'; +import DatabaseSelect from '@/component/Task/component/DatabaseSelect'; import { useRequest } from 'ahooks'; import styles from './index.less'; import setting from '@/store/setting'; +import { rules } from './const'; +import { Rule } from '@@node_modules/antd/es/form'; const MAX_FILE_SIZE = 1024 * 1024 * 256; @@ -566,53 +568,35 @@ const CreateModal: React.FC = (props) => { })} /*SQL 内容*/ name="sqlContentType" - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.components.CreateSQLPlanTaskModal.SelectSqlContent', - defaultMessage: '请选择 SQL 内容', - }), - //请选择 SQL 内容 - }, - ]} + rules={rules.sqlContentType} > - - + - + }), + value: SQLContentType.TEXT, + }, { - formatMessage({ + label: formatMessage({ id: 'odc.components.CreateSQLPlanTaskModal.UploadAnAttachment', defaultMessage: '上传附件', - }) - /*上传附件*/ - } - - + }), + value: SQLContentType.FILE, + }, + ]} + /> {isInitContent && ( @@ -662,16 +646,7 @@ const CreateModal: React.FC = (props) => { })} /*分隔符*/ required - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.components.CreateSQLPlanTaskModal.EnterADelimiter', - defaultMessage: '请输入分隔符', - }), - //请输入分隔符 - }, - ]} + rules={rules.delimiter} > = (props) => { })} /*查询结果限制*/ required - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.components.CreateSQLPlanTaskModal.PleaseEnterTheQueryResult', - defaultMessage: '请输入查询结果限制', - }), - //请输入查询结果限制 - }, - { - validator: (_, value) => { - const max = setting.getSpaceConfigByKey('odc.sqlexecute.default.maxQueryLimit'); - if (value !== undefined && value > max) { - return Promise.reject( - formatMessage( - { - id: 'src.component.Task.SQLPlanTask.CreateModal.B88FB9EC', - defaultMessage: '不超过查询条数上限 {max}', - }, - { max }, - ), - ); - } - return Promise.resolve(); - }, - }, - ]} + rules={rules.queryLimit} > @@ -734,25 +683,7 @@ const CreateModal: React.FC = (props) => { })} /*小时*/ name="timeoutMillis" - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.components.CreateSQLPlanTaskModal.EnterATimeoutPeriod', - defaultMessage: '请输入超时时间', - }), - //请输入超时时间 - }, - { - type: 'number', - max: 480, - message: formatMessage({ - id: 'odc.components.CreateSQLPlanTaskModal.UpToHours', - defaultMessage: '最大不超过 480 小时', - }), - //最大不超过480小时 - }, - ]} + rules={rules.timeoutMillis as Rule[]} noStyle > @@ -785,37 +716,26 @@ const CreateModal: React.FC = (props) => { })} /*任务错误处理*/ name="errorStrategy" - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.components.CreateSQLPlanTaskModal.SelectTaskErrorHandling', - defaultMessage: '请选择任务错误处理', - }), - //请选择任务错误处理 - }, - ]} + rules={rules.errorStrategy} > - - + - + }), + value: ErrorStrategy.ABORT, + }, { - formatMessage({ + label: formatMessage({ id: 'odc.components.CreateSQLPlanTaskModal.IgnoreErrorsToContinueThe', defaultMessage: '忽略错误继续任务', - }) - /*忽略错误继续任务*/ - } - - + }), + value: ErrorStrategy.CONTINUE, + }, + ]} + /> = (props) => { defaultMessage: '任务执行时长超周期处理', })} /*任务执行时长超周期处理*/ name="allowConcurrent" - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.components.CreateSQLPlanTaskModal.PleaseSelectTaskExecutionDuration', - defaultMessage: '请选择任务执行时长超周期处理', - }), //请选择任务执行时长超周期处理 - }, - ]} + rules={rules.allowConcurrent} > - - + - + }), + value: false, + }, { - formatMessage({ + label: formatMessage({ id: 'odc.components.CreateSQLPlanTaskModal.IgnoreTheCurrentTaskStatus', defaultMessage: '忽略当前任务状态,定期发起新任务', - }) /*忽略当前任务状态,定期发起新任务*/ - } - - + }), + value: true, + }, + ]} + /> diff --git a/src/component/Task/SQLPlanTask/CreateModal/interface.ts b/src/component/Task/modals/SQLPlanTask/CreateModal/interface.ts similarity index 100% rename from src/component/Task/SQLPlanTask/CreateModal/interface.ts rename to src/component/Task/modals/SQLPlanTask/CreateModal/interface.ts diff --git a/src/component/Task/SQLPlanTask/DetailContent/index.tsx b/src/component/Task/modals/SQLPlanTask/DetailContent/index.tsx similarity index 98% rename from src/component/Task/SQLPlanTask/DetailContent/index.tsx rename to src/component/Task/modals/SQLPlanTask/DetailContent/index.tsx index e203658f7..64ba978b7 100644 --- a/src/component/Task/SQLPlanTask/DetailContent/index.tsx +++ b/src/component/Task/modals/SQLPlanTask/DetailContent/index.tsx @@ -26,9 +26,9 @@ import { getFormatDateTime, milliSecondsToHour } from '@/util/utils'; import { DownOutlined, UpOutlined } from '@ant-design/icons'; import { Collapse, Descriptions, Divider, Space } from 'antd'; import React from 'react'; -import { getCronCycle } from '../../component/TaskTable'; -import styles from '../../index.less'; -import DatabaseLabel from '../../component/DatabaseLabel'; +import { getCronCycle } from '@/component/Task/component/TaskTable/utils'; +import styles from '@/component/Task/index.less'; +import DatabaseLabel from '@/component/Task/component/DatabaseLabel'; const { Panel } = Collapse; const ErrorStrategy = { diff --git a/src/component/Task/SQLPlanTask/index.tsx b/src/component/Task/modals/SQLPlanTask/index.tsx similarity index 100% rename from src/component/Task/SQLPlanTask/index.tsx rename to src/component/Task/modals/SQLPlanTask/index.tsx diff --git a/src/component/Task/ShadowSyncTask/CreateModal/SelectPanel/index.less b/src/component/Task/modals/ShadowSyncTask/CreateModal/SelectPanel/index.less similarity index 100% rename from src/component/Task/ShadowSyncTask/CreateModal/SelectPanel/index.less rename to src/component/Task/modals/ShadowSyncTask/CreateModal/SelectPanel/index.less diff --git a/src/component/Task/ShadowSyncTask/CreateModal/SelectPanel/index.tsx b/src/component/Task/modals/ShadowSyncTask/CreateModal/SelectPanel/index.tsx similarity index 92% rename from src/component/Task/ShadowSyncTask/CreateModal/SelectPanel/index.tsx rename to src/component/Task/modals/ShadowSyncTask/CreateModal/SelectPanel/index.tsx index c471a2bbd..0c53bf9ed 100644 --- a/src/component/Task/ShadowSyncTask/CreateModal/SelectPanel/index.tsx +++ b/src/component/Task/modals/ShadowSyncTask/CreateModal/SelectPanel/index.tsx @@ -34,10 +34,11 @@ import { clone, cloneDeep } from 'lodash'; import { inject, observer } from 'mobx-react'; import { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'; import { List as VirtualList } from 'react-virtualized'; -import DatabaseSelect from '../../../component/DatabaseSelect'; +import DatabaseSelect from '@/component/Task/component/DatabaseSelect'; import { IContentProps, IShaodwSyncData } from '../interface'; import { useRequest } from 'ahooks'; import styles from './index.less'; +import { rules } from '../const'; const Option = Select.Option; @@ -341,28 +342,23 @@ const SelectPanel = forwardRef(function ( originTableNames: new Set(), }); }} - > - + options={[ { - formatMessage({ + label: formatMessage({ id: 'odc.CreateShadowSyncModal.SelectPanel.PartialTable', defaultMessage: '部分表', - }) - - /*部分表*/ - } - - + }), + value: false, + }, { - formatMessage({ + label: formatMessage({ id: 'odc.CreateShadowSyncModal.SelectPanel.AllTables', defaultMessage: '全部表', - }) - - /*全部表*/ - } - - + }), + value: true, + }, + ]} + /> (function ( - + diff --git a/src/component/Task/ShadowSyncTask/CreateModal/StructConfigPanel/RecordSQLView/index.tsx b/src/component/Task/modals/ShadowSyncTask/CreateModal/StructConfigPanel/RecordSQLView/index.tsx similarity index 100% rename from src/component/Task/ShadowSyncTask/CreateModal/StructConfigPanel/RecordSQLView/index.tsx rename to src/component/Task/modals/ShadowSyncTask/CreateModal/StructConfigPanel/RecordSQLView/index.tsx diff --git a/src/component/Task/ShadowSyncTask/CreateModal/StructConfigPanel/StructAnalysisResult/column.tsx b/src/component/Task/modals/ShadowSyncTask/CreateModal/StructConfigPanel/StructAnalysisResult/column.tsx similarity index 100% rename from src/component/Task/ShadowSyncTask/CreateModal/StructConfigPanel/StructAnalysisResult/column.tsx rename to src/component/Task/modals/ShadowSyncTask/CreateModal/StructConfigPanel/StructAnalysisResult/column.tsx diff --git a/src/component/Task/ShadowSyncTask/CreateModal/StructConfigPanel/StructAnalysisResult/index.tsx b/src/component/Task/modals/ShadowSyncTask/CreateModal/StructConfigPanel/StructAnalysisResult/index.tsx similarity index 100% rename from src/component/Task/ShadowSyncTask/CreateModal/StructConfigPanel/StructAnalysisResult/index.tsx rename to src/component/Task/modals/ShadowSyncTask/CreateModal/StructConfigPanel/StructAnalysisResult/index.tsx diff --git a/src/component/Task/ShadowSyncTask/CreateModal/StructConfigPanel/index.tsx b/src/component/Task/modals/ShadowSyncTask/CreateModal/StructConfigPanel/index.tsx similarity index 85% rename from src/component/Task/ShadowSyncTask/CreateModal/StructConfigPanel/index.tsx rename to src/component/Task/modals/ShadowSyncTask/CreateModal/StructConfigPanel/index.tsx index fcd3e744a..607e761c8 100644 --- a/src/component/Task/ShadowSyncTask/CreateModal/StructConfigPanel/index.tsx +++ b/src/component/Task/modals/ShadowSyncTask/CreateModal/StructConfigPanel/index.tsx @@ -21,9 +21,10 @@ import { SchemaComparingResult } from '@/d.ts'; import { formatMessage } from '@/util/intl'; import { Divider, Form, Radio } from 'antd'; import { forwardRef, useImperativeHandle } from 'react'; -import TaskTimer from '../../../component/TimerSelect'; +import TaskTimer from '@/component/Task/component/TimerSelect'; import { ErrorStrategy, IContentProps } from '../interface'; import StructAnalysisResult from './StructAnalysisResult'; +import { rules } from '../const'; type IProps = IContentProps; @@ -150,40 +151,26 @@ const StructConfigPanel = forwardRef(function ( })} /* 任务错误处理 */ name="errorStrategy" - rules={[ - { - required: true, - message: formatMessage({ - id: 'odc.components.CreateAsyncTaskModal.SelectTaskErrorHandling', - defaultMessage: '请选择任务错误处理', - }), - - // 请选择任务错误处理 - }, - ]} + rules={rules.errorStrategy} > - - + - + }), + value: ErrorStrategy.ABORT, + }, { - formatMessage({ + label: formatMessage({ id: 'odc.components.CreateAsyncTaskModal.IgnoreErrorsContinueTasks', defaultMessage: '忽略错误继续任务', - }) - - /* 忽略错误继续任务 */ - } - - + }), + value: ErrorStrategy.CONTINUE, + }, + ]} + /> diff --git a/src/component/Task/modals/ShadowSyncTask/CreateModal/const.ts b/src/component/Task/modals/ShadowSyncTask/CreateModal/const.ts new file mode 100644 index 000000000..627c7bb19 --- /dev/null +++ b/src/component/Task/modals/ShadowSyncTask/CreateModal/const.ts @@ -0,0 +1,44 @@ +import { formatMessage } from '@/util/intl'; + +export const rules = { + name: [ + { + required: true, + message: formatMessage({ + id: 'odc.CreateShadowSyncModal.SelectPanel.EnterAShadowTableName', + defaultMessage: '请输入影子表名', + }), + + //请输入影子表名 + }, + { + pattern: /^[\w]*$/, + message: formatMessage({ + id: 'odc.CreateShadowSyncModal.SelectPanel.OnlyEnglishNumbersAndUnderscores', + defaultMessage: '仅支持英文/数字/下划线', + }), + + //仅支持英文/数字/下划线 + }, + { + max: 32, + message: formatMessage({ + id: 'odc.CreateShadowSyncModal.SelectPanel.NoMoreThanCharacters', + defaultMessage: '不超过 32 个字符', + }), + + //不超过 32 个字符 + }, + ], + errorStrategy: [ + { + required: true, + message: formatMessage({ + id: 'odc.components.CreateAsyncTaskModal.SelectTaskErrorHandling', + defaultMessage: '请选择任务错误处理', + }), + + // 请选择任务错误处理 + }, + ], +}; diff --git a/src/component/Task/ShadowSyncTask/CreateModal/index.less b/src/component/Task/modals/ShadowSyncTask/CreateModal/index.less similarity index 100% rename from src/component/Task/ShadowSyncTask/CreateModal/index.less rename to src/component/Task/modals/ShadowSyncTask/CreateModal/index.less diff --git a/src/component/Task/ShadowSyncTask/CreateModal/index.tsx b/src/component/Task/modals/ShadowSyncTask/CreateModal/index.tsx similarity index 100% rename from src/component/Task/ShadowSyncTask/CreateModal/index.tsx rename to src/component/Task/modals/ShadowSyncTask/CreateModal/index.tsx diff --git a/src/component/Task/ShadowSyncTask/CreateModal/interface.ts b/src/component/Task/modals/ShadowSyncTask/CreateModal/interface.ts similarity index 100% rename from src/component/Task/ShadowSyncTask/CreateModal/interface.ts rename to src/component/Task/modals/ShadowSyncTask/CreateModal/interface.ts diff --git a/src/component/Task/ShadowSyncTask/DetailContent/index.tsx b/src/component/Task/modals/ShadowSyncTask/DetailContent/index.tsx similarity index 95% rename from src/component/Task/ShadowSyncTask/DetailContent/index.tsx rename to src/component/Task/modals/ShadowSyncTask/DetailContent/index.tsx index ee8b1d21a..42062c43e 100644 --- a/src/component/Task/ShadowSyncTask/DetailContent/index.tsx +++ b/src/component/Task/modals/ShadowSyncTask/DetailContent/index.tsx @@ -20,15 +20,15 @@ import { ErrorStrategy, IShadowSyncAnalysisResult, ShadowTableSyncTaskResult, -} from '@/component/Task/ShadowSyncTask/CreateModal/interface'; -import StructAnalysisResult from '@/component/Task/ShadowSyncTask/CreateModal/StructConfigPanel/StructAnalysisResult'; +} from '@/component/Task/modals/ShadowSyncTask/CreateModal/interface'; +import StructAnalysisResult from '@/component/Task/modals/ShadowSyncTask/CreateModal/StructConfigPanel/StructAnalysisResult'; import { ConnectionMode, TaskDetail, TaskExecStrategy } from '@/d.ts'; import { formatMessage } from '@/util/intl'; import { getFormatDateTime } from '@/util/utils'; import { Spin } from 'antd'; import { useEffect, useState } from 'react'; -import { getTaskExecStrategyMap } from '../..'; -import DatabaseLabel from '../../component/DatabaseLabel'; +import DatabaseLabel from '@/component/Task/component/DatabaseLabel'; +import { getTaskExecStrategyMap } from '@/component/Task/const'; interface IShadowSyncParamters { errorStrategy: ErrorStrategy; connectionId: string; diff --git a/src/component/Task/ShadowSyncTask/index.tsx b/src/component/Task/modals/ShadowSyncTask/index.tsx similarity index 100% rename from src/component/Task/ShadowSyncTask/index.tsx rename to src/component/Task/modals/ShadowSyncTask/index.tsx diff --git a/src/component/Task/StructureComparisonTask/CreateModal/TableSelector.tsx b/src/component/Task/modals/StructureComparisonTask/CreateModal/TableSelector.tsx similarity index 100% rename from src/component/Task/StructureComparisonTask/CreateModal/TableSelector.tsx rename to src/component/Task/modals/StructureComparisonTask/CreateModal/TableSelector.tsx diff --git a/src/component/Task/modals/StructureComparisonTask/CreateModal/const.ts b/src/component/Task/modals/StructureComparisonTask/CreateModal/const.ts new file mode 100644 index 000000000..0b2a5d3c3 --- /dev/null +++ b/src/component/Task/modals/StructureComparisonTask/CreateModal/const.ts @@ -0,0 +1,22 @@ +import { formatMessage } from '@/util/intl'; + +export const rules = { + ['parameters-tableNamesToBeCompared']: [ + { + required: true, + message: formatMessage({ + id: 'src.component.Task.StructureComparisonTask.CreateModal.BCA1854E', + defaultMessage: '请选择比对对象', + }), //'请选择对比对象' + }, + ], + description: [ + { + max: 200, + message: formatMessage({ + id: 'src.component.Task.StructureComparisonTask.CreateModal.FBBFFC4C', + defaultMessage: '描述不超过 200 个字符', + }), //'描述不超过 200 个字符' + }, + ], +}; diff --git a/src/component/Task/StructureComparisonTask/CreateModal/index.less b/src/component/Task/modals/StructureComparisonTask/CreateModal/index.less similarity index 100% rename from src/component/Task/StructureComparisonTask/CreateModal/index.less rename to src/component/Task/modals/StructureComparisonTask/CreateModal/index.less diff --git a/src/component/Task/StructureComparisonTask/CreateModal/index.tsx b/src/component/Task/modals/StructureComparisonTask/CreateModal/index.tsx similarity index 88% rename from src/component/Task/StructureComparisonTask/CreateModal/index.tsx rename to src/component/Task/modals/StructureComparisonTask/CreateModal/index.tsx index bda96d1e4..5cbf75c4a 100644 --- a/src/component/Task/StructureComparisonTask/CreateModal/index.tsx +++ b/src/component/Task/modals/StructureComparisonTask/CreateModal/index.tsx @@ -35,10 +35,11 @@ import { Button, Drawer, Form, Input, message, Modal, Radio, Space } from 'antd' import { useForm } from 'antd/lib/form/Form'; import { inject, observer } from 'mobx-react'; import React, { useEffect, useState } from 'react'; -import { getTaskExecStrategyMap } from '../..'; -import DatabaseSelect from '../../component/DatabaseSelect'; +import DatabaseSelect from '@/component/Task/component/DatabaseSelect'; import { comparisonScopeMap } from './interface'; import TableSelector from './TableSelector'; +import { getTaskExecStrategyMap } from '@/component/Task/const'; +import { rules } from './const'; interface IProps { projectId?: number; modalStore?: ModalStore; @@ -244,12 +245,18 @@ const StructureComparisonTask: React.FC = ({ projectId, modalStore }) => name={['parameters', 'comparisonScope']} required > - - - {comparisonScopeMap[EComparisonScope.PART]} - - {comparisonScopeMap[EComparisonScope.ALL]} - + {({ getFieldValue }) => { @@ -266,15 +273,7 @@ const StructureComparisonTask: React.FC = ({ projectId, modalStore }) => }) /*"比对对象"*/ } name={['parameters', 'tableNamesToBeCompared']} - rules={[ - { - required: true, - message: formatMessage({ - id: 'src.component.Task.StructureComparisonTask.CreateModal.BCA1854E', - defaultMessage: '请选择比对对象', - }), //'请选择对比对象' - }, - ]} + rules={rules['parameters-tableNamesToBeCompared']} > = ({ projectId, modalStore }) => required name="executionStrategy" > - - - {taskExecStrategyMap?.[TaskExecStrategy.AUTO]} - - - {taskExecStrategyMap?.[TaskExecStrategy.MANUAL]} - - + = ({ projectId, modalStore }) => } name="description" required={false} - rules={[ - { - max: 200, - message: formatMessage({ - id: 'src.component.Task.StructureComparisonTask.CreateModal.FBBFFC4C', - defaultMessage: '描述不超过 200 个字符', - }), //'描述不超过 200 个字符' - }, - ]} + rules={rules.description} > { diff --git a/src/page/Workspace/GlobalModals/index.tsx b/src/page/Workspace/GlobalModals/index.tsx index 04ae16ae0..4d5abd5bc 100644 --- a/src/page/Workspace/GlobalModals/index.tsx +++ b/src/page/Workspace/GlobalModals/index.tsx @@ -19,7 +19,7 @@ import CreatePackageModal from '@/component/CreatePackageModal'; import CreateProcedureModal from '@/component/CreateProcedureModal'; import CreateSynonymModal from '@/component/CreateSynonymModal'; import CreateTypeModal from '@/component/CreateTypeModal'; -import CreateModals from '@/component/Task/CreateModals'; +import CreateModals from '@/component/Task/modals/CreateModals'; import ExecuteSqlDetailModal from '@/component/ExecuteSqlDetailModal'; import { ModalStore } from '@/store/modal'; import { inject, observer } from 'mobx-react'; diff --git a/src/page/Workspace/SideBar/Task/index.tsx b/src/page/Workspace/SideBar/Task/index.tsx index 425e10fe0..5309ba568 100644 --- a/src/page/Workspace/SideBar/Task/index.tsx +++ b/src/page/Workspace/SideBar/Task/index.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import Sider from '@/component/Task/Sider'; +import Sider from '@/component/Task/container/Sider'; import { formatMessage } from '@/util/intl'; import tracert from '@/util/tracert'; import React, { useEffect } from 'react'; diff --git a/src/page/Workspace/components/DBPermissionTableContent/index.tsx b/src/page/Workspace/components/DBPermissionTableContent/index.tsx index 8be7adc67..471095710 100644 --- a/src/page/Workspace/components/DBPermissionTableContent/index.tsx +++ b/src/page/Workspace/components/DBPermissionTableContent/index.tsx @@ -6,7 +6,7 @@ import { import { DatabasePermissionType } from '@/d.ts/database'; import { ColumnType } from 'antd/es/table'; import { formatMessage } from '@/util/intl'; -import { permissionOptionsMap } from '@/component/Task/ApplyDatabasePermission'; +import { permissionOptionsMap } from '@/component/Task/modals/ApplyDatabasePermission'; import Action from '@/component/Action'; import DisplayTable from '@/component/DisplayTable'; import { ModalStore } from '@/store/modal'; diff --git a/src/page/Workspace/components/TaskPage/index.tsx b/src/page/Workspace/components/TaskPage/index.tsx index 0a2593b25..9d25a5a82 100644 --- a/src/page/Workspace/components/TaskPage/index.tsx +++ b/src/page/Workspace/components/TaskPage/index.tsx @@ -15,8 +15,8 @@ import { formatMessage } from '@/util/intl'; * limitations under the License. */ -import { TaskTypeMap } from '@/component/Task/component/TaskTable'; -import Content from '@/component/Task/Content'; +import { TaskTypeMap } from '@/component/Task/component/TaskTable/const'; +import Content from '@/component/Task/container/Content'; import { TaskPageType } from '@/d.ts'; import styles from './index.less'; export const getTitleByParams = (params: { type: TaskPageType }) => { diff --git a/src/util/utils.ts b/src/util/utils.ts index 9808ec6d9..440baff39 100644 --- a/src/util/utils.ts +++ b/src/util/utils.ts @@ -749,3 +749,12 @@ export async function getSpaceConfigForFormInitialValue(isShow, callback) { callback(); } } + +/** 根据Key去重数组 */ +export const uniqueTools = (tools) => { + return Array.from(new Map(tools.map((obj) => [obj.key, obj])).values()); +}; + +export const flatArray = (array: any[]): any[] => { + return array?.reduce?.((pre, cur) => pre?.concat(Array.isArray(cur) ? flatArray(cur) : cur), []); +}; From 6c3ca926522164a999592fd65c15f1ba56222696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B9=8B=E7=91=9B?= Date: Wed, 21 May 2025 15:22:37 +0800 Subject: [PATCH 02/74] =?UTF-8?q?PullRequest:=20801=20fix:=20=E6=9B=BF?= =?UTF-8?q?=E6=8D=A2=E5=BA=9F=E5=BC=83=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge branch 'fix/popconfirm of git@code.alipay.com:oceanbase/oceanbase-developer-center.git into dev-4.4.0 https://code.alipay.com/oceanbase/oceanbase-developer-center/pull_requests/801 Reviewed-by: 晓康 * fix: 替换废弃属性 --- .../Task/component/PartitionPolicyFormTable/configModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/component/Task/component/PartitionPolicyFormTable/configModal.tsx b/src/component/Task/component/PartitionPolicyFormTable/configModal.tsx index 7852e4652..1167f1b10 100644 --- a/src/component/Task/component/PartitionPolicyFormTable/configModal.tsx +++ b/src/component/Task/component/PartitionPolicyFormTable/configModal.tsx @@ -379,7 +379,7 @@ const ConfigDrawer: React.FC = (props) => { if (isBatch || isSingleGenerateCount) { return ( {isSingleGenerateCount &&
{isSingleGenerateCountMessage}
} From 9145b3dcd3bc4b23a5258a0831cc4c2bd4a37dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=89=BA=E6=B3=BD?= Date: Wed, 4 Jun 2025 10:53:34 +0800 Subject: [PATCH 03/74] =?UTF-8?q?PullRequest:=20812=20feat:=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9listDatabases=E5=87=BD=E6=95=B0=E4=BC=A0=E5=8F=82?= =?UTF-8?q?=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge branch 'feat/temp435_yz of git@code.alipay.com:oceanbase/oceanbase-developer-center.git into dev-4.4.0 https://code.alipay.com/oceanbase/oceanbase-developer-center/pull_requests/812 Reviewed-by: 晓康 * fix: 修改listDatabases函数传参写法 * fix: 删掉无用注释 * fix: 删除多余包裹标签 --- src/common/network/database.ts | 53 ++- src/component/CreateSynonymModal/index.tsx | 16 +- .../Task/component/DatabaseSelecter/index.tsx | 5 +- .../Task/component/TableSelecter/index.tsx | 6 +- .../CreateModal/DatabaseQueue.tsx | 23 +- .../components/Template/EditTemplate.tsx | 23 +- src/page/Gateway/customConnect.ts | 2 +- src/page/Gateway/newCloudConnection.ts | 2 +- .../components/AddDataBaseButton/index.tsx | 8 +- .../components/AddObjectStorage/index.tsx | 312 +++++++++--------- .../components/ChangeOwnerModal/index.tsx | 17 +- .../LogicDatabase/CreateLogicialDatabase.tsx | 23 +- src/page/Project/Database/hooks/useData.ts | 25 +- .../SensitiveColumn/components/ManualForm.tsx | 3 - src/page/Project/index.tsx | 2 +- .../DatabaseSearchModal/hooks/useData.ts | 18 +- .../TableConstraint/Foreign/index.tsx | 2 +- .../components/CreateTriggerPage/index.tsx | 16 +- .../SessionSelect/SessionDropdown/index.tsx | 27 +- src/page/Workspace/context/WorkspaceStore.tsx | 20 +- 20 files changed, 279 insertions(+), 324 deletions(-) diff --git a/src/common/network/database.ts b/src/common/network/database.ts index 6c4ff9a70..bb113b769 100644 --- a/src/common/network/database.ts +++ b/src/common/network/database.ts @@ -22,42 +22,29 @@ import request from '@/util/request'; import { getDropSQL } from '@/util/sql'; import { executeSQL } from './sql'; +interface listDatabasesParams { + projectId?: number; + dataSourceId?: number; + page?: number; + size?: number; + name?: string; + environmentId?: number[]; + /** 是否包含未分配项目的数据库 */ + containsUnassigned?: boolean; + existed?: boolean; + includesPermittedAction?: boolean; + type?: DBType[]; + connectType?: ConnectType[]; + dataSourceName?: string; + clusterName?: string; + tenantName?: string; +} + export async function listDatabases( - projectId?: number, - dataSourceId?: number, - page?: number, - size?: number, - name?: string, - environmentId?: number[], - /** - * 是否包含未分配项目的数据库 - */ - containsUnassigned?: boolean, - existed?: boolean, - includesPermittedAction?: boolean, - type?: DBType[], - connectType?: ConnectType[], - dataSourceName?: string, - clusterName?: string, - tenantName?: string, + params: listDatabasesParams, ): Promise> { const res = await request.get(`/api/v2/database/databases`, { - params: { - projectId, - dataSourceId, - name, - page, - size, - environmentId, - containsUnassigned, - existed, - includesPermittedAction, - type: type, - connectType: connectType, - dataSourceName, - clusterName, - tenantName, - }, + params: params, }); return res?.data; diff --git a/src/component/CreateSynonymModal/index.tsx b/src/component/CreateSynonymModal/index.tsx index 8e3184a63..5b9af3752 100644 --- a/src/component/CreateSynonymModal/index.tsx +++ b/src/component/CreateSynonymModal/index.tsx @@ -96,16 +96,12 @@ class CreateSynonymModal extends Component = function ({ const loadExportObjects = async () => { setIsLoading(true); try { - const res = await listDatabases(projectId, null, null, null, null, null, null, true, null); + const res = await listDatabases({ + projectId, + existed: true, + }); if (res?.contents) { setDatabaseList(databaseFilter ? databaseFilter(res?.contents) : res?.contents); datasourceStatus.asyncUpdateStatus([ diff --git a/src/component/Task/component/TableSelecter/index.tsx b/src/component/Task/component/TableSelecter/index.tsx index 5bfabdce5..d29f38a3c 100644 --- a/src/component/Task/component/TableSelecter/index.tsx +++ b/src/component/Task/component/TableSelecter/index.tsx @@ -232,7 +232,11 @@ const TableSelecter: React.ForwardRefRenderFunction = if (!projectId) return; setIsLoading(true); try { - const res = await listDatabases(projectId, null, null, null, null, null, null, true, true); + const res = await listDatabases({ + projectId, + existed: true, + includesPermittedAction: true, + }); if (res?.contents) { datasourceStatus.asyncUpdateStatus( res?.contents diff --git a/src/component/Task/modals/MutipleAsyncTask/CreateModal/DatabaseQueue.tsx b/src/component/Task/modals/MutipleAsyncTask/CreateModal/DatabaseQueue.tsx index 4c7b516a6..621567465 100644 --- a/src/component/Task/modals/MutipleAsyncTask/CreateModal/DatabaseQueue.tsx +++ b/src/component/Task/modals/MutipleAsyncTask/CreateModal/DatabaseQueue.tsx @@ -42,25 +42,18 @@ export const DatabaseQueueSelect: React.FC<{ const orderedDatabaseIds = Form.useWatch(['parameters', 'orderedDatabaseIds'], form); const [databaseIdMap, setDatabaseIdMap] = useState>(new Map()); const [_databaseOptions, setDatabaseOptions] = useState([]); - const { - data, - run, - loading: fetchLoading, - } = useRequest(listDatabases, { + const { run } = useRequest(listDatabases, { manual: true, }); const loadDatabaseList = async (projectId: number) => { - const databaseList = await run( + const databaseList = await run({ projectId, - null, - 1, - 99999, - null, - null, - login.isPrivateSpace(), - true, - true, - ); + page: 1, + size: 99999, + containsUnassigned: login.isPrivateSpace(), + existed: true, + includesPermittedAction: true, + }); if (databaseList?.contents?.length) { setDefaultDatasource(databaseList?.contents?.[0]?.dataSource); datasourceStatus.asyncUpdateStatus([ diff --git a/src/component/Task/modals/MutipleAsyncTask/components/Template/EditTemplate.tsx b/src/component/Task/modals/MutipleAsyncTask/components/Template/EditTemplate.tsx index 35daa38a2..4a0c951c2 100644 --- a/src/component/Task/modals/MutipleAsyncTask/components/Template/EditTemplate.tsx +++ b/src/component/Task/modals/MutipleAsyncTask/components/Template/EditTemplate.tsx @@ -36,25 +36,18 @@ const EditTemplate: React.FC<{ const orderedDatabaseIds = Form.useWatch(['orders'], form); const [currentTemplate, setCurrentTemplate] = useState