From 42f23849f06a7107d9eb1ef84b9c3956fc354121 Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Tue, 14 Apr 2026 13:53:07 +0800 Subject: [PATCH 01/36] fix(tsconfig): update module resolution and include jest test types --- tsconfig.json | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 7cb34100a0..54ac65d2a3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,17 +10,15 @@ "strict": true, "forceConsistentCasingInFileNames": true, "module": "ESNext", - "moduleResolution": "Node", + "moduleResolution": "Bundler", "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", + "types": ["jest", "node", "testing-library__jest-dom"], "paths": { "~/*": ["./src/*"] } }, - "exclude": [ - "**/demo/**", - "**/demos/**" - ] + "exclude": ["**/demo/**", "**/demos/**"] } From 17a4f73e241f405b11cc47b8bcc56286b32be16d Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Tue, 14 Apr 2026 15:05:47 +0800 Subject: [PATCH 02/36] chore(build): upgrade toolchain to Vite 8 and migrate chunk splitting --- eslint.config.mjs | 2 +- package.json | 13 +- packages/base/src/scripts/version.ts | 2 +- packages/base/vite.config.mts | 46 +- packages/sqle/src/index.tsx | 2 - .../markdownPreviewOptions.tsx | 15 +- .../SqlFileStatementOverview/index.tsx | 4 +- .../components/AuditExecResultPanel/index.tsx | 8 +- pnpm-lock.yaml | 1185 +++++++++++------ tsconfig.json | 4 +- 10 files changed, 823 insertions(+), 458 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index b92397d45c..fb8164f8d3 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -9,7 +9,7 @@ import pluginNode from 'eslint-plugin-node'; export default defineConfig([ tseslint.configs.recommended, { - files: ['**/scripts/**/*.{js,mjs,cjs,ts,jsx,tsx}'], + files: ['**/scripts/**/*.{js,mjs,cjs,ts,jsx,tsx}', '**/vite.config.mts'], plugins: { import: pluginImport, node: pluginNode diff --git a/package.json b/package.json index 567c18aebd..ea0f9fac51 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "pnpm": ">=9.7.0" }, "scripts": { + "preview": "pnpm --filter base preview", "preinstall": "npx only-allow pnpm", "start": "concurrently \"pnpm --filter base start\" \"pnpm --filter @actiontech/dms-kit dev\"", "start:ee": "concurrently \"pnpm --filter base start:ee\" \"pnpm --filter @actiontech/dms-kit dev\"", @@ -60,7 +61,7 @@ "@types/testing-library__jest-dom": "^5.14.5", "@typescript-eslint/eslint-plugin": "^5.30.6", "@typescript-eslint/parser": "^5.30.6", - "@vitejs/plugin-react": "^4.2.1", + "@vitejs/plugin-react": "^6", "babel-jest": "^29.7.0", "babel-preset-react-app": "^10.0.1", "blob-polyfill": "^7.0.20220408", @@ -95,11 +96,11 @@ "stylelint-prettier": "^4.0.2", "ts-jest": "27.1.5", "tsx": "^4.20.5", - "typescript": "^5.0.2", + "typescript": "^6", "typescript-eslint": "^8.28.0", - "vite": "^5.2.6", + "vite": "^8", "vite-plugin-conditional-compile": "1.4.3", - "vite-plugin-eslint": "^1.8.1", + "vite-plugin-eslint2": "^5.1.0", "vite-plugin-html": "^3.2.2" }, "dependencies": { @@ -117,6 +118,7 @@ "@mui/styles": "^5.11.16", "@mui/system": "^5.9.1", "@reduxjs/toolkit": "^1.9.3", + "@uiw/react-md-editor": "^3.23.5", "@xyflow/react": "^12.3.0", "ahooks": "^3.7.0", "antd": "^5.7.3", @@ -140,8 +142,7 @@ "react-redux": "^8.0.5", "react-router-dom": "^6.10.0", "recoil": "^0.7.4", - "sql-formatter": "^12.2.4", - "@uiw/react-md-editor": "^3.23.5" + "sql-formatter": "^12.2.4" }, "resolutions": { "headers-polyfill": "3.0.10", diff --git a/packages/base/src/scripts/version.ts b/packages/base/src/scripts/version.ts index 6d5baaff06..400cc67d18 100644 --- a/packages/base/src/scripts/version.ts +++ b/packages/base/src/scripts/version.ts @@ -1 +1 @@ -export const UI_VERSION = 'sync/data-masking 417b194dd'; +export const UI_VERSION = 'chore/update-tsconfig 42f23849f0'; diff --git a/packages/base/vite.config.mts b/packages/base/vite.config.mts index d625f08098..9803a0ac55 100644 --- a/packages/base/vite.config.mts +++ b/packages/base/vite.config.mts @@ -1,6 +1,6 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; -import eslint from 'vite-plugin-eslint'; +import eslint from 'vite-plugin-eslint2'; import vitePluginConditionalCompile from 'vite-plugin-conditional-compile'; import { createHtmlPlugin } from 'vite-plugin-html'; import * as path from 'path'; @@ -50,14 +50,7 @@ export default defineConfig(() => { demo: isDemo } }), - eslint({ - exclude: [ - '**/node_modules/**', - '**/packages/**/lib/**', - '**/packages/**/es/**', - '!**/packages/**/lib/api/common/**' - ] - }), + eslint(), react(), createHtmlPlugin({ inject: { @@ -81,6 +74,7 @@ export default defineConfig(() => { } }, build: { + target: 'chrome80', rollupOptions: { // resolve css in js 'use client' warn onwarn(warning, warn) { @@ -91,13 +85,33 @@ export default defineConfig(() => { }, output: { minifyInternalExports: true, - manualChunks: { - 'antd.module': ['antd'], - 'react.module': ['react'], - 'lodash.module': ['lodash'], - 'antd.icon.module': ['@ant-design/icons'], - 'antd.plots': ['@ant-design/plots'], - 'actiontech.shared': ['@actiontech/shared'] + codeSplitting: { + groups: [ + { + test: /[\\/]node_modules[\\/]antd[\\/]/, + name: 'antd.module' + }, + { + test: /[\\/]node_modules[\\/]react[\\/]/, + name: 'react.module' + }, + { + test: /[\\/]node_modules[\\/]lodash[\\/]/, + name: 'lodash.module' + }, + { + test: /[\\/]node_modules[\\/]@ant-design[\\/]icons[\\/]/, + name: 'antd.icon.module' + }, + { + test: /[\\/]node_modules[\\/]@ant-design[\\/]plots[\\/]/, + name: 'antd.plots' + }, + { + test: /[\\/]node_modules[\\/]@actiontech[\\/]shared[\\/]/, + name: 'actiontech.shared' + } + ] } } } diff --git a/packages/sqle/src/index.tsx b/packages/sqle/src/index.tsx index 6a1ae6db08..a15dc4bfef 100644 --- a/packages/sqle/src/index.tsx +++ b/packages/sqle/src/index.tsx @@ -6,8 +6,6 @@ import { Provider } from 'react-redux'; import store from './store'; import { BrowserRouter as Router } from 'react-router-dom'; import './locale'; -import './utils/HighlightCode'; -import './index.less'; import { initReactI18n } from './locale'; ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( diff --git a/packages/sqle/src/page/RuleKnowledge/Common/MarkdownPreview/markdownPreviewOptions.tsx b/packages/sqle/src/page/RuleKnowledge/Common/MarkdownPreview/markdownPreviewOptions.tsx index 049c13cec9..a436268ccb 100644 --- a/packages/sqle/src/page/RuleKnowledge/Common/MarkdownPreview/markdownPreviewOptions.tsx +++ b/packages/sqle/src/page/RuleKnowledge/Common/MarkdownPreview/markdownPreviewOptions.tsx @@ -9,7 +9,15 @@ type PreviewOptions = BasicMDEditorProps['previewOptions']; export const markdownPreviewOptions: PreviewOptions = { components: { - code: ({ children, className, ...props }) => { + code: ({ + children, + className, + node + }: { + children: string; + className: string; + node: { children: Parameters[0] }; + }) => { /** * label 代码块 * Example: @@ -23,11 +31,8 @@ export const markdownPreviewOptions: PreviewOptions = { if (isArray(match) && !!match[1]) { return ; } - const code = - props.node && props.node.children - ? getCodeString(props.node.children) - : children; + node && node.children ? getCodeString(node.children) : children; /** * sql_diff 代码块 * Example: diff --git a/packages/sqle/src/page/SqlExecWorkflow/Detail/components/AuditExecResultPanel/TaskResultList/SqlFileStatementOverview/index.tsx b/packages/sqle/src/page/SqlExecWorkflow/Detail/components/AuditExecResultPanel/TaskResultList/SqlFileStatementOverview/index.tsx index 287e3a463c..26a41d681c 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Detail/components/AuditExecResultPanel/TaskResultList/SqlFileStatementOverview/index.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Detail/components/AuditExecResultPanel/TaskResultList/SqlFileStatementOverview/index.tsx @@ -14,7 +14,7 @@ import useAuditResultFilterParams from '../../../../../Common/AuditResultFilterC import { IAuditTaskSQLResV2 } from '@actiontech/shared/lib/api/sqle/service/common'; import { AuditTaskExtraFilterMeta } from '../../index.data'; import task from '@actiontech/shared/lib/api/sqle/service/task'; -import { ResponseCode } from '@actiontech/dms-kit'; +import { FilterCustomProps, ResponseCode } from '@actiontech/dms-kit'; import { GetAuditTaskSQLsPrams } from '../../index.type'; import { BasicButton, @@ -228,7 +228,7 @@ const SqlFileStatementOverview: React.FC = () => { filterContainerMeta={filterContainerMeta} updateTableFilterInfo={updateTableFilterInfo} filterCustomProps={ - new Map([ + new Map([ [ 'audit_level', { diff --git a/packages/sqle/src/page/SqlExecWorkflow/Detail/components/AuditExecResultPanel/index.tsx b/packages/sqle/src/page/SqlExecWorkflow/Detail/components/AuditExecResultPanel/index.tsx index d27310fcdf..012b012818 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Detail/components/AuditExecResultPanel/index.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Detail/components/AuditExecResultPanel/index.tsx @@ -1,7 +1,10 @@ import { useTranslation } from 'react-i18next'; import { AuditExecResultPanelProps } from './index.type'; import { AuditExecResultPanelStyleWrapper } from './style'; -import { SegmentedRowStyleWrapper } from '@actiontech/dms-kit'; +import { + FilterCustomProps, + SegmentedRowStyleWrapper +} from '@actiontech/dms-kit'; import { BasicSegmented, EmptyBox } from '@actiontech/dms-kit'; import { WORKFLOW_OVERVIEW_TAB_KEY } from '../../hooks/useAuditExecResultPanelSetup'; import { @@ -35,6 +38,7 @@ import { ModalName } from '../../../../../data/ModalName'; import EmitterKey from '../../../../../data/EmitterKey'; import EventEmitter from '../../../../../utils/EventEmitter'; import useRetryExecute from './hooks/useRetryExecute'; +import { IAuditTaskSQLResV2 } from '@actiontech/shared/lib/api/sqle/service/common'; const AuditExecResultPanel: React.FC = ({ activeTabKey, @@ -180,7 +184,7 @@ const AuditExecResultPanel: React.FC = ({ filterContainerMeta={filterContainerMeta} updateTableFilterInfo={updateTableFilterInfo} filterCustomProps={ - new Map([ + new Map([ [ 'audit_level', { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b5d220abec..f0aa3197ef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -149,7 +149,7 @@ importers: version: 9.3.4 '@testing-library/jest-dom': specifier: 6.4.2 - version: 6.4.2(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2))) + version: 6.4.2(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2))) '@testing-library/react': specifier: ^16.2.0 version: 16.2.0(@testing-library/dom@9.3.4)(@types/react-dom@18.3.5(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -188,13 +188,13 @@ importers: version: 5.14.9 '@typescript-eslint/eslint-plugin': specifier: ^5.30.6 - version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@5.8.2))(eslint@9.23.0)(typescript@5.8.2) + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@6.0.2))(eslint@9.23.0)(typescript@6.0.2) '@typescript-eslint/parser': specifier: ^5.30.6 - version: 5.62.0(eslint@9.23.0)(typescript@5.8.2) + version: 5.62.0(eslint@9.23.0)(typescript@6.0.2) '@vitejs/plugin-react': - specifier: ^4.2.1 - version: 4.3.4(vite@5.4.15(@types/node@18.19.84)(less@4.2.2)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0)) + specifier: ^6 + version: 6.0.1(vite@8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5)) babel-jest: specifier: ^29.7.0 version: 29.7.0(@babel/core@7.26.10) @@ -224,7 +224,7 @@ importers: version: 9.23.0 eslint-plugin-import: specifier: ^2.31.0 - version: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@5.8.2))(eslint@9.23.0) + version: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@6.0.2))(eslint@9.23.0) eslint-plugin-node: specifier: ^11.1.0 version: 11.1.0(eslint@9.23.0) @@ -245,7 +245,7 @@ importers: version: 3.0.0 jest: specifier: 29.1.2 - version: 29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)) + version: 29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)) jest-canvas-mock: specifier: ^2.2.0 version: 2.5.2 @@ -257,7 +257,7 @@ importers: version: 1.0.0 jest-watch-typeahead: specifier: ^2.1.1 - version: 2.2.2(jest@29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2))) + version: 2.2.2(jest@29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2))) less: specifier: ^4.1.3 version: 4.2.2 @@ -266,7 +266,7 @@ importers: version: 3.0.5 msw: specifier: ^0.45.0 - version: 0.45.0(encoding@0.1.13)(typescript@5.8.2) + version: 0.45.0(encoding@0.1.13)(typescript@6.0.2) postcss-less: specifier: ^6.0.0 version: 6.0.0(postcss@8.5.3) @@ -278,43 +278,43 @@ importers: version: 2.8.8 stylelint: specifier: ^15.10.2 - version: 15.11.0(typescript@5.8.2) + version: 15.11.0(typescript@6.0.2) stylelint-config-prettier: specifier: ^9.0.5 - version: 9.0.5(stylelint@15.11.0(typescript@5.8.2)) + version: 9.0.5(stylelint@15.11.0(typescript@6.0.2)) stylelint-config-standard-less: specifier: ^1.0.0 - version: 1.0.0(postcss@8.5.3)(stylelint@15.11.0(typescript@5.8.2)) + version: 1.0.0(postcss@8.5.3)(stylelint@15.11.0(typescript@6.0.2)) stylelint-config-styled-components: specifier: ^0.1.1 version: 0.1.1 stylelint-prettier: specifier: ^4.0.2 - version: 4.1.0(prettier@2.8.8)(stylelint@15.11.0(typescript@5.8.2)) + version: 4.1.0(prettier@2.8.8)(stylelint@15.11.0(typescript@6.0.2)) ts-jest: specifier: 27.1.5 - version: 27.1.5(@babel/core@7.26.10)(@types/jest@29.5.12)(babel-jest@29.7.0(@babel/core@7.26.10))(jest@29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)))(typescript@5.8.2) + version: 27.1.5(@babel/core@7.26.10)(@types/jest@29.5.12)(babel-jest@29.7.0(@babel/core@7.26.10))(jest@29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)))(typescript@6.0.2) tsx: specifier: ^4.20.5 version: 4.20.5 typescript: - specifier: ^5.0.2 - version: 5.8.2 + specifier: ^6 + version: 6.0.2 typescript-eslint: specifier: ^8.28.0 - version: 8.28.0(eslint@9.23.0)(typescript@5.8.2) + version: 8.28.0(eslint@9.23.0)(typescript@6.0.2) vite: - specifier: ^5.2.6 - version: 5.4.15(@types/node@18.19.84)(less@4.2.2)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0) + specifier: ^8 + version: 8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5) vite-plugin-conditional-compile: specifier: 1.4.3 - version: 1.4.3(vite@5.4.15(@types/node@18.19.84)(less@4.2.2)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0)) - vite-plugin-eslint: - specifier: ^1.8.1 - version: 1.8.1(eslint@9.23.0)(vite@5.4.15(@types/node@18.19.84)(less@4.2.2)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0)) + version: 1.4.3(vite@8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5)) + vite-plugin-eslint2: + specifier: ^5.1.0 + version: 5.1.0(@types/eslint@8.56.12)(eslint@9.23.0)(rolldown@1.0.0-rc.15)(rollup@4.38.0)(vite@8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5)) vite-plugin-html: specifier: ^3.2.2 - version: 3.2.2(vite@5.4.15(@types/node@18.19.84)(less@4.2.2)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0)) + version: 3.2.2(vite@8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5)) packages/base: dependencies: @@ -420,7 +420,7 @@ importers: version: 1.13.8 dumi: specifier: ^2.3.8 - version: 2.4.18(@babel/core@7.26.10)(@swc/helpers@0.5.1)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.8.2)))(lightningcss@1.22.1)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(stylelint@15.11.0(typescript@5.8.2))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.8.2)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) + version: 2.4.18(@babel/core@7.26.10)(@swc/helpers@0.5.1)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.8.2)))(lightningcss@1.32.0)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(stylelint@15.11.0(typescript@5.8.2))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.8.2)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) father: specifier: ^4.5.2 version: 4.5.2(@babel/core@7.26.10)(@types/node@22.13.14)(styled-components@6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(type-fest@1.4.0)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) @@ -435,7 +435,7 @@ importers: version: 8.1.0(typescript@5.3.3) dumi: specifier: ^2.3.8 - version: 2.4.18(@babel/core@7.26.10)(@swc/helpers@0.5.1)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.3.3)))(lightningcss@1.22.1)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(stylelint@15.11.0(typescript@5.3.3))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.3.3)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) + version: 2.4.18(@babel/core@7.26.10)(@swc/helpers@0.5.1)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.3.3)))(lightningcss@1.32.0)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(stylelint@15.11.0(typescript@5.3.3))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.3.3)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) father: specifier: ^4.1.0 version: 4.5.2(@babel/core@7.26.10)(@types/node@22.13.14)(styled-components@6.1.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(type-fest@1.4.0)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) @@ -451,7 +451,7 @@ importers: devDependencies: tsup: specifier: ^8.5.0 - version: 8.5.0(@microsoft/api-extractor@7.39.1(@types/node@22.13.14))(@swc/core@1.9.2(@swc/helpers@0.5.1))(postcss@8.5.3)(tsx@4.20.5)(typescript@5.8.2) + version: 8.5.0(@microsoft/api-extractor@7.39.1(@types/node@22.13.14))(@swc/core@1.9.2(@swc/helpers@0.5.1))(postcss@8.5.9)(tsx@4.20.5)(typescript@6.0.2) packages/sqle: dependencies: @@ -1700,6 +1700,15 @@ packages: peerDependencies: react: '>=16.8.0' + '@emnapi/core@1.9.2': + resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} + + '@emnapi/runtime@1.9.2': + resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@emotion/babel-plugin@11.13.5': resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} @@ -1787,12 +1796,6 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - '@esbuild/aix-ppc64@0.25.9': resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} engines: {node: '>=18'} @@ -1817,12 +1820,6 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.25.9': resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} engines: {node: '>=18'} @@ -1847,12 +1844,6 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.25.9': resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} engines: {node: '>=18'} @@ -1877,12 +1868,6 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - '@esbuild/android-x64@0.25.9': resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} engines: {node: '>=18'} @@ -1907,12 +1892,6 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.25.9': resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} engines: {node: '>=18'} @@ -1937,12 +1916,6 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - '@esbuild/darwin-x64@0.25.9': resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} engines: {node: '>=18'} @@ -1967,12 +1940,6 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.25.9': resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} engines: {node: '>=18'} @@ -1997,12 +1964,6 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - '@esbuild/freebsd-x64@0.25.9': resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} engines: {node: '>=18'} @@ -2027,12 +1988,6 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.25.9': resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} engines: {node: '>=18'} @@ -2057,12 +2012,6 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.25.9': resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} engines: {node: '>=18'} @@ -2087,12 +2036,6 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.25.9': resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} engines: {node: '>=18'} @@ -2117,12 +2060,6 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.25.9': resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} engines: {node: '>=18'} @@ -2147,12 +2084,6 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.25.9': resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} engines: {node: '>=18'} @@ -2177,12 +2108,6 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.25.9': resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} engines: {node: '>=18'} @@ -2207,12 +2132,6 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.25.9': resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} engines: {node: '>=18'} @@ -2237,12 +2156,6 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.25.9': resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} engines: {node: '>=18'} @@ -2267,12 +2180,6 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.25.9': resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} engines: {node: '>=18'} @@ -2303,12 +2210,6 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.25.9': resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} engines: {node: '>=18'} @@ -2339,12 +2240,6 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.25.9': resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} engines: {node: '>=18'} @@ -2375,12 +2270,6 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - '@esbuild/sunos-x64@0.25.9': resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} engines: {node: '>=18'} @@ -2405,12 +2294,6 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.25.9': resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} engines: {node: '>=18'} @@ -2435,12 +2318,6 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.25.9': resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} engines: {node: '>=18'} @@ -2465,12 +2342,6 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - '@esbuild/win32-x64@0.25.9': resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} engines: {node: '>=18'} @@ -3035,6 +2906,12 @@ packages: resolution: {integrity: sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==} engines: {node: '>= 10'} + '@napi-rs/wasm-runtime@1.1.3': + resolution: {integrity: sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} @@ -3105,6 +2982,9 @@ packages: '@open-draft/until@1.0.3': resolution: {integrity: sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q==} + '@oxc-project/types@0.124.0': + resolution: {integrity: sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==} + '@parcel/watcher-android-arm64@2.5.1': resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} engines: {node: '>= 10.0.0'} @@ -3296,10 +3176,120 @@ packages: resolution: {integrity: sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg==} engines: {node: '>=14'} + '@rolldown/binding-android-arm64@1.0.0-rc.15': + resolution: {integrity: sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.0.0-rc.15': + resolution: {integrity: sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.0.0-rc.15': + resolution: {integrity: sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.0.0-rc.15': + resolution: {integrity: sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': + resolution: {integrity: sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': + resolution: {integrity: sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': + resolution: {integrity: sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': + resolution: {integrity: sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': + resolution: {integrity: sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': + resolution: {integrity: sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': + resolution: {integrity: sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': + resolution: {integrity: sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': + resolution: {integrity: sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': + resolution: {integrity: sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': + resolution: {integrity: sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.0-rc.15': + resolution: {integrity: sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==} + + '@rolldown/pluginutils@1.0.0-rc.7': + resolution: {integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA==} + '@rollup/pluginutils@4.2.1': resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rollup/rollup-android-arm-eabi@4.38.0': resolution: {integrity: sha512-ldomqc4/jDZu/xpYU+aRxo3V4mGCV9HeTgUBANI3oIQMOL+SsxB+S2lxMpkFp5UamSS3XuTMQVbsS24R4J4Qjg==} cpu: [arm] @@ -3930,6 +3920,9 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@types/archiver@6.0.4': resolution: {integrity: sha512-ULdQpARQ3sz9WH4nb98mJDYA0ft2A8C4f4fovvUcFwINa1cgGjY36JCAYuP5YypRq4mco1lJp1/7jEMS2oR0Hg==} @@ -4521,11 +4514,18 @@ packages: peerDependencies: vite: ^4.2.0 - '@vitejs/plugin-react@4.3.4': - resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==} - engines: {node: ^14.18.0 || >=16.0.0} + '@vitejs/plugin-react@6.0.1': + resolution: {integrity: sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ==} + engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 + babel-plugin-react-compiler: ^1.0.0 + vite: ^8.0.0 + peerDependenciesMeta: + '@rolldown/plugin-babel': + optional: true + babel-plugin-react-compiler: + optional: true '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -5770,6 +5770,15 @@ packages: supports-color: optional: true + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} engines: {node: '>=0.10.0'} @@ -5887,6 +5896,10 @@ packages: engines: {node: '>=0.10'} hasBin: true + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -6187,11 +6200,6 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true - esbuild@0.25.9: resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} engines: {node: '>=18'} @@ -7183,6 +7191,7 @@ packages: intersection-observer@0.12.2: resolution: {integrity: sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==} + deprecated: The Intersection Observer polyfill is no longer needed and can safely be removed. Intersection Observer has been Baseline since 2019. intl-messageformat@10.7.16: resolution: {integrity: sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug==} @@ -7826,30 +7835,60 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + lightningcss-darwin-arm64@1.22.1: resolution: {integrity: sha512-ldvElu+R0QimNTjsKpaZkUv3zf+uefzLy/R1R19jtgOfSRM+zjUCUgDhfEDRmVqJtMwYsdhMI2aJtJChPC6Osg==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + lightningcss-darwin-x64@1.22.1: resolution: {integrity: sha512-5p2rnlVTv6Gpw4PlTLq925nTVh+HFh4MpegX8dPDYJae+NFVjQ67gY7O6iHIzQjLipDiYejFF0yHrhjU3XgLBQ==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + lightningcss-freebsd-x64@1.22.1: resolution: {integrity: sha512-1FaBtcFrZqB2hkFbAxY//Pnp8koThvyB6AhjbdVqKD4/pu13Rl91fKt2N9qyeQPUt3xy7ORUvSO+dPk3J6EjXg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + lightningcss-linux-arm-gnueabihf@1.22.1: resolution: {integrity: sha512-6rub98tYGfE5I5j0BP8t/2d4BZyu1S7Iz9vUkm0H26snAFHYxLfj3RbQn0xHHIePSetjLnhcg3QlfwUAkD/FYg==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + lightningcss-linux-arm64-gnu@1.22.1: resolution: {integrity: sha512-nYO5qGtb/1kkTZu3FeTiM+2B2TAb7m2DkLCTgQIs2bk2o9aEs7I96fwySKcoHWQAiQDGR9sMux9vkV4KQXqPaQ==} engines: {node: '>= 12.0.0'} @@ -7857,6 +7896,13 @@ packages: os: [linux] libc: [glibc] + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + lightningcss-linux-arm64-musl@1.22.1: resolution: {integrity: sha512-MCV6RuRpzXbunvzwY644iz8cw4oQxvW7oer9xPkdadYqlEyiJJ6wl7FyJOH7Q6ZYH4yjGAUCvxDBxPbnDu9ZVg==} engines: {node: '>= 12.0.0'} @@ -7864,6 +7910,13 @@ packages: os: [linux] libc: [musl] + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + lightningcss-linux-x64-gnu@1.22.1: resolution: {integrity: sha512-RjNgpdM20VUXgV7us/VmlO3Vn2ZRiDnc3/bUxCVvySZWPiVPprpqW/QDWuzkGa+NCUf6saAM5CLsZLSxncXJwg==} engines: {node: '>= 12.0.0'} @@ -7871,6 +7924,13 @@ packages: os: [linux] libc: [glibc] + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + lightningcss-linux-x64-musl@1.22.1: resolution: {integrity: sha512-ZgO4C7Rd6Hv/5MnyY2KxOYmIlzk4rplVolDt3NbkNR8DndnyX0Q5IR4acJWNTBICQ21j3zySzKbcJaiJpk/4YA==} engines: {node: '>= 12.0.0'} @@ -7878,16 +7938,39 @@ packages: os: [linux] libc: [musl] + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + lightningcss-win32-x64-msvc@1.22.1: resolution: {integrity: sha512-4pozV4eyD0MDET41ZLHAeBo+H04Nm2UEYIk5w/ts40231dRFV7E0cjwbnZvSoc1DXFgecAhiC0L16ruv/ZDCpg==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + lightningcss@1.22.1: resolution: {integrity: sha512-Fy45PhibiNXkm0cK5FJCbfO8Y6jUpD/YcHf/BtuI+jvYYqSXKF4muk61jjE8YxCR9y+hDYIWSzHTc+bwhDE6rQ==} engines: {node: '>= 12.0.0'} + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} @@ -8734,6 +8817,10 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} @@ -9062,6 +9149,10 @@ packages: resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} engines: {node: ^10 || ^12 || >=14} + postcss@8.5.9: + resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==} + engines: {node: ^10 || ^12 || >=14} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -9986,6 +10077,11 @@ packages: ripemd160@2.0.2: resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + rolldown@1.0.0-rc.15: + resolution: {integrity: sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup-plugin-visualizer@5.9.0: resolution: {integrity: sha512-bbDOv47+Bw4C/cgs0czZqfm8L82xOZssk4ayZjG40y9zbXclNk7YikrZTDao6p7+HDiGxrN0b65SgZiVm9k1Cg==} engines: {node: '>=14'} @@ -10000,11 +10096,6 @@ packages: resolution: {integrity: sha512-a2S4Bh3bgrdO4BhKr2E4nZkjTvrJ2m2bWjMTzVYtoqSCn0HnuxosXnaJUHrMEziOWr3CzL9GjilQQKcyCQpJoA==} hasBin: true - rollup@2.79.2: - resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==} - engines: {node: '>=10.0.0'} - hasBin: true - rollup@3.29.5: resolution: {integrity: sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w==} engines: {node: '>=14.18.0', npm: '>=8.0.0'} @@ -10698,6 +10789,10 @@ packages: resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + engines: {node: '>=12.0.0'} + titleize@3.0.0: resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==} engines: {node: '>=12'} @@ -10937,6 +11032,11 @@ packages: engines: {node: '>=14.17'} hasBin: true + typescript@6.0.2: + resolution: {integrity: sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==} + engines: {node: '>=14.17'} + hasBin: true + ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} @@ -11174,11 +11274,22 @@ packages: peerDependencies: vite: ^4.5.0 - vite-plugin-eslint@1.8.1: - resolution: {integrity: sha512-PqdMf3Y2fLO9FsNPmMX+//2BF5SF8nEWspZdgl4kSt7UvHDRHVVfHvxsD7ULYzZrJDGRxR81Nq7TOFgwMnUang==} + vite-plugin-eslint2@5.1.0: + resolution: {integrity: sha512-fNuO/D7b+EZ5ejhuBA80tiaxWztZWDHc+lCZaXMOHgYfqFXq8WKmGwrudS+/jscp0UNAKGB71du+xoP8azSXiw==} + engines: {node: '>=18'} peerDependencies: - eslint: '>=7' - vite: '>=2' + '@types/eslint': ^7.0.0 || ^8.0.0 || ^9.0.0 + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 + rolldown: ^1.0.0-0 || ^1.0.0 + rollup: ^2.0.0 || ^3.0.0 || ^4.0.0 + vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@types/eslint': + optional: true + rolldown: + optional: true + rollup: + optional: true vite-plugin-html@3.2.2: resolution: {integrity: sha512-vb9C9kcdzcIo/Oc3CLZVS03dL5pDlOFuhGlZYDCJ840BhWl/0nGeZWf3Qy7NlOayscY4Cm/QRgULCQkEZige5Q==} @@ -11213,25 +11324,33 @@ packages: terser: optional: true - vite@5.4.15: - resolution: {integrity: sha512-6ANcZRivqL/4WtwPGTKNaosuNJr5tWiftOC7liM7G9+rMb8+oeJeyzymDu4rTN93seySBmbjSfsS3Vzr19KNtA==} - engines: {node: ^18.0.0 || >=20.0.0} + vite@8.0.8: + resolution: {integrity: sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==} + engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.0 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 peerDependenciesMeta: '@types/node': optional: true - less: + '@vitejs/devtools': optional: true - lightningcss: + esbuild: + optional: true + jiti: + optional: true + less: optional: true sass: optional: true @@ -11243,6 +11362,10 @@ packages: optional: true terser: optional: true + tsx: + optional: true + yaml: + optional: true vm-browserify@1.1.2: resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} @@ -13143,6 +13266,22 @@ snapshots: react: 18.3.1 tslib: 2.8.1 + '@emnapi/core@1.9.2': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.9.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + '@emotion/babel-plugin@11.13.5': dependencies: '@babel/helper-module-imports': 7.25.9 @@ -13256,9 +13395,6 @@ snapshots: '@esbuild/aix-ppc64@0.21.4': optional: true - '@esbuild/aix-ppc64@0.21.5': - optional: true - '@esbuild/aix-ppc64@0.25.9': optional: true @@ -13271,9 +13407,6 @@ snapshots: '@esbuild/android-arm64@0.21.4': optional: true - '@esbuild/android-arm64@0.21.5': - optional: true - '@esbuild/android-arm64@0.25.9': optional: true @@ -13286,9 +13419,6 @@ snapshots: '@esbuild/android-arm@0.21.4': optional: true - '@esbuild/android-arm@0.21.5': - optional: true - '@esbuild/android-arm@0.25.9': optional: true @@ -13301,9 +13431,6 @@ snapshots: '@esbuild/android-x64@0.21.4': optional: true - '@esbuild/android-x64@0.21.5': - optional: true - '@esbuild/android-x64@0.25.9': optional: true @@ -13316,9 +13443,6 @@ snapshots: '@esbuild/darwin-arm64@0.21.4': optional: true - '@esbuild/darwin-arm64@0.21.5': - optional: true - '@esbuild/darwin-arm64@0.25.9': optional: true @@ -13331,9 +13455,6 @@ snapshots: '@esbuild/darwin-x64@0.21.4': optional: true - '@esbuild/darwin-x64@0.21.5': - optional: true - '@esbuild/darwin-x64@0.25.9': optional: true @@ -13346,9 +13467,6 @@ snapshots: '@esbuild/freebsd-arm64@0.21.4': optional: true - '@esbuild/freebsd-arm64@0.21.5': - optional: true - '@esbuild/freebsd-arm64@0.25.9': optional: true @@ -13361,9 +13479,6 @@ snapshots: '@esbuild/freebsd-x64@0.21.4': optional: true - '@esbuild/freebsd-x64@0.21.5': - optional: true - '@esbuild/freebsd-x64@0.25.9': optional: true @@ -13376,9 +13491,6 @@ snapshots: '@esbuild/linux-arm64@0.21.4': optional: true - '@esbuild/linux-arm64@0.21.5': - optional: true - '@esbuild/linux-arm64@0.25.9': optional: true @@ -13391,9 +13503,6 @@ snapshots: '@esbuild/linux-arm@0.21.4': optional: true - '@esbuild/linux-arm@0.21.5': - optional: true - '@esbuild/linux-arm@0.25.9': optional: true @@ -13406,9 +13515,6 @@ snapshots: '@esbuild/linux-ia32@0.21.4': optional: true - '@esbuild/linux-ia32@0.21.5': - optional: true - '@esbuild/linux-ia32@0.25.9': optional: true @@ -13421,9 +13527,6 @@ snapshots: '@esbuild/linux-loong64@0.21.4': optional: true - '@esbuild/linux-loong64@0.21.5': - optional: true - '@esbuild/linux-loong64@0.25.9': optional: true @@ -13436,9 +13539,6 @@ snapshots: '@esbuild/linux-mips64el@0.21.4': optional: true - '@esbuild/linux-mips64el@0.21.5': - optional: true - '@esbuild/linux-mips64el@0.25.9': optional: true @@ -13451,9 +13551,6 @@ snapshots: '@esbuild/linux-ppc64@0.21.4': optional: true - '@esbuild/linux-ppc64@0.21.5': - optional: true - '@esbuild/linux-ppc64@0.25.9': optional: true @@ -13466,9 +13563,6 @@ snapshots: '@esbuild/linux-riscv64@0.21.4': optional: true - '@esbuild/linux-riscv64@0.21.5': - optional: true - '@esbuild/linux-riscv64@0.25.9': optional: true @@ -13481,9 +13575,6 @@ snapshots: '@esbuild/linux-s390x@0.21.4': optional: true - '@esbuild/linux-s390x@0.21.5': - optional: true - '@esbuild/linux-s390x@0.25.9': optional: true @@ -13496,9 +13587,6 @@ snapshots: '@esbuild/linux-x64@0.21.4': optional: true - '@esbuild/linux-x64@0.21.5': - optional: true - '@esbuild/linux-x64@0.25.9': optional: true @@ -13514,9 +13602,6 @@ snapshots: '@esbuild/netbsd-x64@0.21.4': optional: true - '@esbuild/netbsd-x64@0.21.5': - optional: true - '@esbuild/netbsd-x64@0.25.9': optional: true @@ -13532,9 +13617,6 @@ snapshots: '@esbuild/openbsd-x64@0.21.4': optional: true - '@esbuild/openbsd-x64@0.21.5': - optional: true - '@esbuild/openbsd-x64@0.25.9': optional: true @@ -13547,10 +13629,7 @@ snapshots: '@esbuild/sunos-x64@0.18.20': optional: true - '@esbuild/sunos-x64@0.21.4': - optional: true - - '@esbuild/sunos-x64@0.21.5': + '@esbuild/sunos-x64@0.21.4': optional: true '@esbuild/sunos-x64@0.25.9': @@ -13565,9 +13644,6 @@ snapshots: '@esbuild/win32-arm64@0.21.4': optional: true - '@esbuild/win32-arm64@0.21.5': - optional: true - '@esbuild/win32-arm64@0.25.9': optional: true @@ -13580,9 +13656,6 @@ snapshots: '@esbuild/win32-ia32@0.21.4': optional: true - '@esbuild/win32-ia32@0.21.5': - optional: true - '@esbuild/win32-ia32@0.25.9': optional: true @@ -13595,9 +13668,6 @@ snapshots: '@esbuild/win32-x64@0.21.4': optional: true - '@esbuild/win32-x64@0.21.5': - optional: true - '@esbuild/win32-x64@0.25.9': optional: true @@ -13882,7 +13952,7 @@ snapshots: jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2))': + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -13896,7 +13966,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)) + jest-config: 29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -14436,6 +14506,13 @@ snapshots: '@napi-rs/nice-win32-x64-msvc': 1.0.1 optional: true + '@napi-rs/wasm-runtime@1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@tybys/wasm-util': 0.10.1 + optional: true + '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': dependencies: eslint-scope: 5.1.1 @@ -14517,6 +14594,8 @@ snapshots: '@open-draft/until@1.0.3': {} + '@oxc-project/types@0.124.0': {} + '@parcel/watcher-android-arm64@2.5.1': optional: true @@ -14714,11 +14793,72 @@ snapshots: '@remix-run/router@1.5.0': {} + '@rolldown/binding-android-arm64@1.0.0-rc.15': + optional: true + + '@rolldown/binding-darwin-arm64@1.0.0-rc.15': + optional: true + + '@rolldown/binding-darwin-x64@1.0.0-rc.15': + optional: true + + '@rolldown/binding-freebsd-x64@1.0.0-rc.15': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.15': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.15': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.0.0-rc.15': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.15': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.15': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.0.0-rc.15': + optional: true + + '@rolldown/binding-linux-x64-musl@1.0.0-rc.15': + optional: true + + '@rolldown/binding-openharmony-arm64@1.0.0-rc.15': + optional: true + + '@rolldown/binding-wasm32-wasi@1.0.0-rc.15': + dependencies: + '@emnapi/core': 1.9.2 + '@emnapi/runtime': 1.9.2 + '@napi-rs/wasm-runtime': 1.1.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.15': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.0.0-rc.15': + optional: true + + '@rolldown/pluginutils@1.0.0-rc.15': {} + + '@rolldown/pluginutils@1.0.0-rc.7': {} + '@rollup/pluginutils@4.2.1': dependencies: estree-walker: 2.0.2 picomatch: 2.3.1 + '@rollup/pluginutils@5.3.0(rollup@4.38.0)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.38.0 + '@rollup/rollup-android-arm-eabi@4.38.0': optional: true @@ -15343,7 +15483,7 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.4.2(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)))': + '@testing-library/jest-dom@6.4.2(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)))': dependencies: '@adobe/css-tools': 4.4.2 '@babel/runtime': 7.27.0 @@ -15356,7 +15496,7 @@ snapshots: optionalDependencies: '@jest/globals': 29.7.0 '@types/jest': 29.5.12 - jest: 29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)) + jest: 29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)) '@testing-library/react-hooks@8.0.1(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: @@ -15393,6 +15533,11 @@ snapshots: '@tsconfig/node16@1.0.4': optional: true + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + '@types/archiver@6.0.4': dependencies: '@types/readdir-glob': 1.1.5 @@ -15467,12 +15612,12 @@ snapshots: '@types/eslint@8.56.12': dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 '@types/estree-jsx@1.0.5': dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 '@types/estree@1.0.7': {} @@ -15682,10 +15827,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@5.8.2))(eslint@9.23.0)(typescript@5.8.2)': + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@6.0.2))(eslint@9.23.0)(typescript@5.8.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 5.62.0(eslint@9.23.0)(typescript@5.8.2) + '@typescript-eslint/parser': 5.62.0(eslint@9.23.0)(typescript@6.0.2) '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/type-utils': 5.62.0(eslint@9.23.0)(typescript@5.8.2) '@typescript-eslint/utils': 5.62.0(eslint@9.23.0)(typescript@5.8.2) @@ -15701,20 +15846,39 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.28.0(@typescript-eslint/parser@8.28.0(eslint@9.23.0)(typescript@5.8.2))(eslint@9.23.0)(typescript@5.8.2)': + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@6.0.2))(eslint@9.23.0)(typescript@6.0.2)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 5.62.0(eslint@9.23.0)(typescript@6.0.2) + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/type-utils': 5.62.0(eslint@9.23.0)(typescript@6.0.2) + '@typescript-eslint/utils': 5.62.0(eslint@9.23.0)(typescript@6.0.2) + debug: 4.4.0 + eslint: 9.23.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare-lite: 1.4.0 + semver: 7.7.3 + tsutils: 3.21.0(typescript@6.0.2) + optionalDependencies: + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/eslint-plugin@8.28.0(@typescript-eslint/parser@8.28.0(eslint@9.23.0)(typescript@6.0.2))(eslint@9.23.0)(typescript@6.0.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.28.0(eslint@9.23.0)(typescript@5.8.2) + '@typescript-eslint/parser': 8.28.0(eslint@9.23.0)(typescript@6.0.2) '@typescript-eslint/scope-manager': 8.28.0 - '@typescript-eslint/type-utils': 8.28.0(eslint@9.23.0)(typescript@5.8.2) - '@typescript-eslint/utils': 8.28.0(eslint@9.23.0)(typescript@5.8.2) + '@typescript-eslint/type-utils': 8.28.0(eslint@9.23.0)(typescript@6.0.2) + '@typescript-eslint/utils': 8.28.0(eslint@9.23.0)(typescript@6.0.2) '@typescript-eslint/visitor-keys': 8.28.0 eslint: 9.23.0 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@5.8.2) - typescript: 5.8.2 + ts-api-utils: 2.1.0(typescript@6.0.2) + typescript: 6.0.2 transitivePeerDependencies: - supports-color @@ -15742,15 +15906,27 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.28.0(eslint@9.23.0)(typescript@5.8.2)': + '@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@6.0.2)': + dependencies: + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@6.0.2) + debug: 4.4.0 + eslint: 9.23.0 + optionalDependencies: + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.28.0(eslint@9.23.0)(typescript@6.0.2)': dependencies: '@typescript-eslint/scope-manager': 8.28.0 '@typescript-eslint/types': 8.28.0 - '@typescript-eslint/typescript-estree': 8.28.0(typescript@5.8.2) + '@typescript-eslint/typescript-estree': 8.28.0(typescript@6.0.2) '@typescript-eslint/visitor-keys': 8.28.0 debug: 4.4.0 eslint: 9.23.0 - typescript: 5.8.2 + typescript: 6.0.2 transitivePeerDependencies: - supports-color @@ -15788,14 +15964,26 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.28.0(eslint@9.23.0)(typescript@5.8.2)': + '@typescript-eslint/type-utils@5.62.0(eslint@9.23.0)(typescript@6.0.2)': dependencies: - '@typescript-eslint/typescript-estree': 8.28.0(typescript@5.8.2) - '@typescript-eslint/utils': 8.28.0(eslint@9.23.0)(typescript@5.8.2) + '@typescript-eslint/typescript-estree': 5.62.0(typescript@6.0.2) + '@typescript-eslint/utils': 5.62.0(eslint@9.23.0)(typescript@6.0.2) debug: 4.4.0 eslint: 9.23.0 - ts-api-utils: 2.1.0(typescript@5.8.2) - typescript: 5.8.2 + tsutils: 3.21.0(typescript@6.0.2) + optionalDependencies: + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/type-utils@8.28.0(eslint@9.23.0)(typescript@6.0.2)': + dependencies: + '@typescript-eslint/typescript-estree': 8.28.0(typescript@6.0.2) + '@typescript-eslint/utils': 8.28.0(eslint@9.23.0)(typescript@6.0.2) + debug: 4.4.0 + eslint: 9.23.0 + ts-api-utils: 2.1.0(typescript@6.0.2) + typescript: 6.0.2 transitivePeerDependencies: - supports-color @@ -15831,7 +16019,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.28.0(typescript@5.8.2)': + '@typescript-eslint/typescript-estree@5.62.0(typescript@6.0.2)': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.4.0 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.7.3 + tsutils: 3.21.0(typescript@6.0.2) + optionalDependencies: + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@8.28.0(typescript@6.0.2)': dependencies: '@typescript-eslint/types': 8.28.0 '@typescript-eslint/visitor-keys': 8.28.0 @@ -15840,8 +16042,8 @@ snapshots: is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.7.3 - ts-api-utils: 2.1.0(typescript@5.8.2) - typescript: 5.8.2 + ts-api-utils: 2.1.0(typescript@6.0.2) + typescript: 6.0.2 transitivePeerDependencies: - supports-color @@ -15875,14 +16077,29 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@8.28.0(eslint@9.23.0)(typescript@5.8.2)': + '@typescript-eslint/utils@5.62.0(eslint@9.23.0)(typescript@6.0.2)': + dependencies: + '@eslint-community/eslint-utils': 4.5.1(eslint@9.23.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.7.1 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@6.0.2) + eslint: 9.23.0 + eslint-scope: 5.1.1 + semver: 7.7.3 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/utils@8.28.0(eslint@9.23.0)(typescript@6.0.2)': dependencies: '@eslint-community/eslint-utils': 4.5.1(eslint@9.23.0) '@typescript-eslint/scope-manager': 8.28.0 '@typescript-eslint/types': 8.28.0 - '@typescript-eslint/typescript-estree': 8.28.0(typescript@5.8.2) + '@typescript-eslint/typescript-estree': 8.28.0(typescript@6.0.2) eslint: 9.23.0 - typescript: 5.8.2 + typescript: 6.0.2 transitivePeerDependencies: - supports-color @@ -15984,18 +16201,18 @@ snapshots: transitivePeerDependencies: - supports-color - '@umijs/bundler-vite@4.4.6(@types/node@22.13.14)(lightningcss@1.22.1)(postcss@8.5.3)(rollup@3.29.5)(sass@1.86.0)(terser@5.39.0)': + '@umijs/bundler-vite@4.4.6(@types/node@22.13.14)(lightningcss@1.32.0)(postcss@8.5.3)(rollup@3.29.5)(sass@1.86.0)(terser@5.39.0)': dependencies: '@svgr/core': 6.5.1 '@umijs/bundler-utils': 4.4.6 '@umijs/utils': 4.4.6 - '@vitejs/plugin-react': 4.0.0(vite@4.5.2(@types/node@22.13.14)(less@4.1.3)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0)) + '@vitejs/plugin-react': 4.0.0(vite@4.5.2(@types/node@22.13.14)(less@4.1.3)(lightningcss@1.32.0)(sass@1.86.0)(terser@5.39.0)) core-js: 3.34.0 less: 4.1.3 postcss-preset-env: 7.5.0(postcss@8.5.3) rollup-plugin-visualizer: 5.9.0(rollup@3.29.5) systemjs: 6.15.1 - vite: 4.5.2(@types/node@22.13.14)(less@4.1.3)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0) + vite: 4.5.2(@types/node@22.13.14)(less@4.1.3)(lightningcss@1.32.0)(sass@1.86.0)(terser@5.39.0) transitivePeerDependencies: - '@types/node' - lightningcss @@ -16161,10 +16378,10 @@ snapshots: '@babel/core': 7.26.10 '@babel/eslint-parser': 7.23.3(@babel/core@7.26.10)(eslint@9.23.0) '@stylelint/postcss-css-in-js': 0.38.0(postcss-syntax@0.36.2(postcss-less@6.0.0(postcss@8.5.3))(postcss@8.5.3))(postcss@8.5.3) - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@5.8.2))(eslint@9.23.0)(typescript@5.8.2) + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@6.0.2))(eslint@9.23.0)(typescript@5.8.2) '@typescript-eslint/parser': 5.62.0(eslint@9.23.0)(typescript@5.8.2) '@umijs/babel-preset-umi': 4.4.6 - eslint-plugin-jest: 27.2.3(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@5.8.2))(eslint@9.23.0)(typescript@5.8.2))(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.8.2)))(typescript@5.8.2) + eslint-plugin-jest: 27.2.3(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@6.0.2))(eslint@9.23.0)(typescript@6.0.2))(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.8.2)))(typescript@5.8.2) eslint-plugin-react: 7.33.2(eslint@9.23.0) eslint-plugin-react-hooks: 4.6.0(eslint@9.23.0) postcss: 8.5.3 @@ -16246,7 +16463,7 @@ snapshots: dependencies: tsx: 3.12.2 - '@umijs/preset-umi@4.4.6(@types/node@22.13.14)(@types/react@18.3.23)(lightningcss@1.22.1)(rollup@3.29.5)(sass@1.86.0)(terser@5.39.0)(type-fest@1.4.0)(typescript@5.3.3)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1)))': + '@umijs/preset-umi@4.4.6(@types/node@22.13.14)(@types/react@18.3.23)(lightningcss@1.32.0)(rollup@3.29.5)(sass@1.86.0)(terser@5.39.0)(type-fest@1.4.0)(typescript@5.3.3)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1)))': dependencies: '@iconify/utils': 2.1.1 '@svgr/core': 6.5.1 @@ -16255,7 +16472,7 @@ snapshots: '@umijs/bundler-esbuild': 4.4.6 '@umijs/bundler-mako': 0.11.5 '@umijs/bundler-utils': 4.4.6 - '@umijs/bundler-vite': 4.4.6(@types/node@22.13.14)(lightningcss@1.22.1)(postcss@8.5.3)(rollup@3.29.5)(sass@1.86.0)(terser@5.39.0) + '@umijs/bundler-vite': 4.4.6(@types/node@22.13.14)(lightningcss@1.32.0)(postcss@8.5.3)(rollup@3.29.5)(sass@1.86.0)(terser@5.39.0) '@umijs/bundler-webpack': 4.4.6(type-fest@1.4.0)(typescript@5.3.3)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) '@umijs/core': 4.4.6 '@umijs/did-you-know': 1.0.3 @@ -16304,7 +16521,7 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - '@umijs/preset-umi@4.4.6(@types/node@22.13.14)(@types/react@18.3.23)(lightningcss@1.22.1)(rollup@3.29.5)(sass@1.86.0)(terser@5.39.0)(type-fest@1.4.0)(typescript@5.8.2)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1)))': + '@umijs/preset-umi@4.4.6(@types/node@22.13.14)(@types/react@18.3.23)(lightningcss@1.32.0)(rollup@3.29.5)(sass@1.86.0)(terser@5.39.0)(type-fest@1.4.0)(typescript@5.8.2)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1)))': dependencies: '@iconify/utils': 2.1.1 '@svgr/core': 6.5.1 @@ -16313,7 +16530,7 @@ snapshots: '@umijs/bundler-esbuild': 4.4.6 '@umijs/bundler-mako': 0.11.5 '@umijs/bundler-utils': 4.4.6 - '@umijs/bundler-vite': 4.4.6(@types/node@22.13.14)(lightningcss@1.22.1)(postcss@8.5.3)(rollup@3.29.5)(sass@1.86.0)(terser@5.39.0) + '@umijs/bundler-vite': 4.4.6(@types/node@22.13.14)(lightningcss@1.32.0)(postcss@8.5.3)(rollup@3.29.5)(sass@1.86.0)(terser@5.39.0) '@umijs/bundler-webpack': 4.4.6(type-fest@1.4.0)(typescript@5.8.2)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) '@umijs/core': 4.4.6 '@umijs/did-you-know': 1.0.3 @@ -16425,26 +16642,20 @@ snapshots: '@vercel/ncc@0.33.3': {} - '@vitejs/plugin-react@4.0.0(vite@4.5.2(@types/node@22.13.14)(less@4.1.3)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0))': + '@vitejs/plugin-react@4.0.0(vite@4.5.2(@types/node@22.13.14)(less@4.1.3)(lightningcss@1.32.0)(sass@1.86.0)(terser@5.39.0))': dependencies: '@babel/core': 7.26.10 '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.10) '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.10) react-refresh: 0.14.2 - vite: 4.5.2(@types/node@22.13.14)(less@4.1.3)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0) + vite: 4.5.2(@types/node@22.13.14)(less@4.1.3)(lightningcss@1.32.0)(sass@1.86.0)(terser@5.39.0) transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@4.3.4(vite@5.4.15(@types/node@18.19.84)(less@4.2.2)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0))': + '@vitejs/plugin-react@6.0.1(vite@8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5))': dependencies: - '@babel/core': 7.26.10 - '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.10) - '@types/babel__core': 7.20.5 - react-refresh: 0.14.2 - vite: 5.4.15(@types/node@18.19.84)(less@4.2.2)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0) - transitivePeerDependencies: - - supports-color + '@rolldown/pluginutils': 1.0.0-rc.7 + vite: 8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5) '@webassemblyjs/ast@1.14.1': dependencies: @@ -17643,6 +17854,15 @@ snapshots: optionalDependencies: typescript: 5.8.2 + cosmiconfig@8.3.6(typescript@6.0.2): + dependencies: + import-fresh: 3.3.1 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 6.0.2 + crc-32@1.2.2: {} crc32-stream@6.0.0: @@ -17672,13 +17892,13 @@ snapshots: safe-buffer: 5.2.1 sha.js: 2.4.11 - create-jest@29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)): + create-jest@29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)) + jest-config: 29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -17974,6 +18194,10 @@ snapshots: dependencies: ms: 2.1.3 + debug@4.4.3: + dependencies: + ms: 2.1.3 + decamelize-keys@1.1.1: dependencies: decamelize: 1.2.0 @@ -18091,6 +18315,8 @@ snapshots: detect-libc@1.0.3: {} + detect-libc@2.1.2: {} + detect-newline@3.1.0: {} detect-newline@4.0.1: {} @@ -18224,7 +18450,7 @@ snapshots: dumi-assets-types@2.4.14: {} - dumi@2.4.18(@babel/core@7.26.10)(@swc/helpers@0.5.1)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.3.3)))(lightningcss@1.22.1)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(stylelint@15.11.0(typescript@5.3.3))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.3.3)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))): + dumi@2.4.18(@babel/core@7.26.10)(@swc/helpers@0.5.1)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.3.3)))(lightningcss@1.32.0)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(stylelint@15.11.0(typescript@5.3.3))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.3.3)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))): dependencies: '@ant-design/icons-svg': 4.4.2 '@makotot/ghostui': 2.0.0(react@18.3.1) @@ -18289,7 +18515,7 @@ snapshots: sass: 1.86.0 sitemap: 7.1.2 sucrase: 3.35.0 - umi: 4.4.6(@babel/core@7.26.10)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.3.3)))(lightningcss@1.22.1)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(sass@1.86.0)(stylelint@15.11.0(typescript@5.3.3))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.3.3)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) + umi: 4.4.6(@babel/core@7.26.10)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.3.3)))(lightningcss@1.32.0)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(sass@1.86.0)(stylelint@15.11.0(typescript@5.3.3))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.3.3)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) unified: 10.1.2 unist-util-visit: 4.1.2 unist-util-visit-parents: 5.1.3 @@ -18327,7 +18553,7 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - dumi@2.4.18(@babel/core@7.26.10)(@swc/helpers@0.5.1)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.8.2)))(lightningcss@1.22.1)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(stylelint@15.11.0(typescript@5.8.2))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.8.2)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))): + dumi@2.4.18(@babel/core@7.26.10)(@swc/helpers@0.5.1)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.8.2)))(lightningcss@1.32.0)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(stylelint@15.11.0(typescript@5.8.2))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.8.2)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))): dependencies: '@ant-design/icons-svg': 4.4.2 '@makotot/ghostui': 2.0.0(react@18.3.1) @@ -18392,7 +18618,7 @@ snapshots: sass: 1.86.0 sitemap: 7.1.2 sucrase: 3.35.0 - umi: 4.4.6(@babel/core@7.26.10)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.8.2)))(lightningcss@1.22.1)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(sass@1.86.0)(stylelint@15.11.0(typescript@5.8.2))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.8.2)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) + umi: 4.4.6(@babel/core@7.26.10)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.8.2)))(lightningcss@1.32.0)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(sass@1.86.0)(stylelint@15.11.0(typescript@5.8.2))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.8.2)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) unified: 10.1.2 unist-util-visit: 4.1.2 unist-util-visit-parents: 5.1.3 @@ -18751,32 +18977,6 @@ snapshots: '@esbuild/win32-ia32': 0.21.4 '@esbuild/win32-x64': 0.21.4 - esbuild@0.21.5: - optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 - esbuild@0.25.9: optionalDependencies: '@esbuild/aix-ppc64': 0.25.9 @@ -18834,11 +19034,11 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.23.0): + eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@6.0.2))(eslint-import-resolver-node@0.3.9)(eslint@9.23.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@9.23.0)(typescript@5.8.2) + '@typescript-eslint/parser': 5.62.0(eslint@9.23.0)(typescript@6.0.2) eslint: 9.23.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: @@ -18850,7 +19050,7 @@ snapshots: eslint-utils: 2.1.0 regexpp: 3.2.0 - eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@5.8.2))(eslint@9.23.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@6.0.2))(eslint@9.23.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -18861,7 +19061,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.23.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint@9.23.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@6.0.2))(eslint-import-resolver-node@0.3.9)(eslint@9.23.0) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -18873,7 +19073,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@9.23.0)(typescript@5.8.2) + '@typescript-eslint/parser': 5.62.0(eslint@9.23.0)(typescript@6.0.2) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -18890,12 +19090,12 @@ snapshots: - supports-color - typescript - eslint-plugin-jest@27.2.3(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@5.8.2))(eslint@9.23.0)(typescript@5.8.2))(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.8.2)))(typescript@5.8.2): + eslint-plugin-jest@27.2.3(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@6.0.2))(eslint@9.23.0)(typescript@6.0.2))(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.8.2)))(typescript@5.8.2): dependencies: '@typescript-eslint/utils': 5.62.0(eslint@9.23.0)(typescript@5.8.2) eslint: 9.23.0 optionalDependencies: - '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@5.8.2))(eslint@9.23.0)(typescript@5.8.2) + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.23.0)(typescript@6.0.2))(eslint@9.23.0)(typescript@6.0.2) jest: 29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.8.2)) transitivePeerDependencies: - supports-color @@ -19045,7 +19245,7 @@ snapshots: estree-util-attach-comments@2.1.1: dependencies: - '@types/estree': 1.0.7 + '@types/estree': 1.0.8 estree-util-is-identifier-name@2.1.0: {} @@ -19275,6 +19475,10 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + fecha@4.2.3: {} fetch-blob@3.2.0: @@ -20493,16 +20697,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)): + jest-cli@29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)) + create-jest: 29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)) + jest-config: 29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -20552,7 +20756,7 @@ snapshots: - ts-node optional: true - jest-config@29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)): + jest-config@29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)): dependencies: '@babel/core': 7.26.10 '@jest/test-sequencer': 29.7.0 @@ -20578,7 +20782,7 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 18.19.84 - ts-node: 10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2) + ts-node: 10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -20934,11 +21138,11 @@ snapshots: leven: 3.1.0 pretty-format: 29.7.0 - jest-watch-typeahead@2.2.2(jest@29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2))): + jest-watch-typeahead@2.2.2(jest@29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2))): dependencies: ansi-escapes: 6.2.1 chalk: 5.4.1 - jest: 29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)) + jest: 29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)) jest-regex-util: 29.6.3 jest-watcher: 29.7.0 slash: 5.1.0 @@ -20976,12 +21180,12 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)): + jest@29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)) + jest-cli: 29.7.0(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -21230,33 +21434,66 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + lightningcss-android-arm64@1.32.0: + optional: true + lightningcss-darwin-arm64@1.22.1: optional: true + lightningcss-darwin-arm64@1.32.0: + optional: true + lightningcss-darwin-x64@1.22.1: optional: true + lightningcss-darwin-x64@1.32.0: + optional: true + lightningcss-freebsd-x64@1.22.1: optional: true + lightningcss-freebsd-x64@1.32.0: + optional: true + lightningcss-linux-arm-gnueabihf@1.22.1: optional: true + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + lightningcss-linux-arm64-gnu@1.22.1: optional: true + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + lightningcss-linux-arm64-musl@1.22.1: optional: true + lightningcss-linux-arm64-musl@1.32.0: + optional: true + lightningcss-linux-x64-gnu@1.22.1: optional: true + lightningcss-linux-x64-gnu@1.32.0: + optional: true + lightningcss-linux-x64-musl@1.22.1: optional: true + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + lightningcss-win32-x64-msvc@1.22.1: optional: true + lightningcss-win32-x64-msvc@1.32.0: + optional: true + lightningcss@1.22.1: dependencies: detect-libc: 1.0.3 @@ -21271,6 +21508,22 @@ snapshots: lightningcss-linux-x64-musl: 1.22.1 lightningcss-win32-x64-msvc: 1.22.1 + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + lilconfig@3.1.3: {} lines-and-columns@1.2.4: {} @@ -21892,7 +22145,7 @@ snapshots: ms@2.1.3: {} - msw@0.45.0(encoding@0.1.13)(typescript@5.8.2): + msw@0.45.0(encoding@0.1.13)(typescript@6.0.2): dependencies: '@mswjs/cookies': 0.2.2 '@mswjs/interceptors': 0.17.10 @@ -21914,7 +22167,7 @@ snapshots: type-fest: 1.4.0 yargs: 17.7.2 optionalDependencies: - typescript: 5.8.2 + typescript: 6.0.2 transitivePeerDependencies: - encoding - supports-color @@ -22379,6 +22632,8 @@ snapshots: picomatch@4.0.3: {} + picomatch@4.0.4: {} + pify@4.0.1: optional: true @@ -22526,11 +22781,11 @@ snapshots: dependencies: postcss: 8.5.3 - postcss-load-config@6.0.1(postcss@8.5.3)(tsx@4.20.5): + postcss-load-config@6.0.1(postcss@8.5.9)(tsx@4.20.5): dependencies: lilconfig: 3.1.3 optionalDependencies: - postcss: 8.5.3 + postcss: 8.5.9 tsx: 4.20.5 postcss-logical@5.0.4(postcss@8.5.3): @@ -22696,6 +22951,12 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + postcss@8.5.9: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + prelude-ls@1.2.1: {} prettier-linter-helpers@1.0.0: @@ -23843,6 +24104,27 @@ snapshots: hash-base: 3.0.5 inherits: 2.0.4 + rolldown@1.0.0-rc.15: + dependencies: + '@oxc-project/types': 0.124.0 + '@rolldown/pluginutils': 1.0.0-rc.15 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.0-rc.15 + '@rolldown/binding-darwin-arm64': 1.0.0-rc.15 + '@rolldown/binding-darwin-x64': 1.0.0-rc.15 + '@rolldown/binding-freebsd-x64': 1.0.0-rc.15 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.15 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.15 + '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.15 + '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.15 + '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.15 + '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.15 + '@rolldown/binding-linux-x64-musl': 1.0.0-rc.15 + '@rolldown/binding-openharmony-arm64': 1.0.0-rc.15 + '@rolldown/binding-wasm32-wasi': 1.0.0-rc.15 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.15 + '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.15 + rollup-plugin-visualizer@5.9.0(rollup@3.29.5): dependencies: open: 8.4.2 @@ -23858,10 +24140,6 @@ snapshots: minimist: 1.2.8 source-map-support: 0.3.3 - rollup@2.79.2: - optionalDependencies: - fsevents: 2.3.3 - rollup@3.29.5: optionalDependencies: fsevents: 2.3.3 @@ -24429,9 +24707,9 @@ snapshots: stylis: 4.3.2 tslib: 2.6.2 - stylelint-config-prettier@9.0.5(stylelint@15.11.0(typescript@5.8.2)): + stylelint-config-prettier@9.0.5(stylelint@15.11.0(typescript@6.0.2)): dependencies: - stylelint: 15.11.0(typescript@5.8.2) + stylelint: 15.11.0(typescript@6.0.2) stylelint-config-recommended-less@1.0.4: dependencies: @@ -24441,9 +24719,9 @@ snapshots: transitivePeerDependencies: - supports-color - stylelint-config-recommended@10.0.1(stylelint@15.11.0(typescript@5.8.2)): + stylelint-config-recommended@10.0.1(stylelint@15.11.0(typescript@6.0.2)): dependencies: - stylelint: 15.11.0(typescript@5.8.2) + stylelint: 15.11.0(typescript@6.0.2) stylelint-config-recommended@6.0.0(stylelint@14.16.1): dependencies: @@ -24457,11 +24735,11 @@ snapshots: dependencies: stylelint: 15.11.0(typescript@5.8.2) - stylelint-config-standard-less@1.0.0(postcss@8.5.3)(stylelint@15.11.0(typescript@5.8.2)): + stylelint-config-standard-less@1.0.0(postcss@8.5.3)(stylelint@15.11.0(typescript@6.0.2)): dependencies: - stylelint: 15.11.0(typescript@5.8.2) + stylelint: 15.11.0(typescript@6.0.2) stylelint-config-recommended-less: 1.0.4 - stylelint-config-standard: 30.0.1(stylelint@15.11.0(typescript@5.8.2)) + stylelint-config-standard: 30.0.1(stylelint@15.11.0(typescript@6.0.2)) optionalDependencies: postcss: 8.5.3 transitivePeerDependencies: @@ -24477,10 +24755,10 @@ snapshots: stylelint: 15.11.0(typescript@5.8.2) stylelint-config-recommended: 7.0.0(stylelint@15.11.0(typescript@5.8.2)) - stylelint-config-standard@30.0.1(stylelint@15.11.0(typescript@5.8.2)): + stylelint-config-standard@30.0.1(stylelint@15.11.0(typescript@6.0.2)): dependencies: - stylelint: 15.11.0(typescript@5.8.2) - stylelint-config-recommended: 10.0.1(stylelint@15.11.0(typescript@5.8.2)) + stylelint: 15.11.0(typescript@6.0.2) + stylelint-config-recommended: 10.0.1(stylelint@15.11.0(typescript@6.0.2)) stylelint-config-styled-components@0.1.1: {} @@ -24490,11 +24768,11 @@ snapshots: postcss-value-parser: 4.2.0 stylelint: 14.16.1 - stylelint-prettier@4.1.0(prettier@2.8.8)(stylelint@15.11.0(typescript@5.8.2)): + stylelint-prettier@4.1.0(prettier@2.8.8)(stylelint@15.11.0(typescript@6.0.2)): dependencies: prettier: 2.8.8 prettier-linter-helpers: 1.0.0 - stylelint: 15.11.0(typescript@5.8.2) + stylelint: 15.11.0(typescript@6.0.2) stylelint@14.16.1: dependencies: @@ -24631,6 +24909,52 @@ snapshots: - supports-color - typescript + stylelint@15.11.0(typescript@6.0.2): + dependencies: + '@csstools/css-parser-algorithms': 2.7.1(@csstools/css-tokenizer@2.4.1) + '@csstools/css-tokenizer': 2.4.1 + '@csstools/media-query-list-parser': 2.1.13(@csstools/css-parser-algorithms@2.7.1(@csstools/css-tokenizer@2.4.1))(@csstools/css-tokenizer@2.4.1) + '@csstools/selector-specificity': 3.1.1(postcss-selector-parser@6.1.2) + balanced-match: 2.0.0 + colord: 2.9.3 + cosmiconfig: 8.3.6(typescript@6.0.2) + css-functions-list: 3.2.3 + css-tree: 2.3.1 + debug: 4.4.0 + fast-glob: 3.3.3 + fastest-levenshtein: 1.0.16 + file-entry-cache: 7.0.2 + global-modules: 2.0.0 + globby: 11.1.0 + globjoin: 0.1.4 + html-tags: 3.3.1 + ignore: 5.3.2 + import-lazy: 4.0.0 + imurmurhash: 0.1.4 + is-plain-object: 5.0.0 + known-css-properties: 0.29.0 + mathml-tag-names: 2.1.3 + meow: 10.1.5 + micromatch: 4.0.8 + normalize-path: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.3 + postcss-resolve-nested-selector: 0.1.6 + postcss-safe-parser: 6.0.0(postcss@8.5.3) + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + resolve-from: 5.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + style-search: 0.1.0 + supports-hyperlinks: 3.2.0 + svg-tags: 1.0.0 + table: 6.9.0 + write-file-atomic: 5.0.1 + transitivePeerDependencies: + - supports-color + - typescript + stylis@4.2.0: {} stylis@4.3.2: {} @@ -24830,6 +25154,11 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tinyglobby@0.2.16: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + titleize@3.0.0: {} tmp@0.0.33: @@ -24881,30 +25210,30 @@ snapshots: trough@2.2.0: {} - ts-api-utils@2.1.0(typescript@5.8.2): + ts-api-utils@2.1.0(typescript@6.0.2): dependencies: - typescript: 5.8.2 + typescript: 6.0.2 ts-interface-checker@0.1.13: {} - ts-jest@27.1.5(@babel/core@7.26.10)(@types/jest@29.5.12)(babel-jest@29.7.0(@babel/core@7.26.10))(jest@29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)))(typescript@5.8.2): + ts-jest@27.1.5(@babel/core@7.26.10)(@types/jest@29.5.12)(babel-jest@29.7.0(@babel/core@7.26.10))(jest@29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)))(typescript@6.0.2): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2)) + jest: 29.1.2(@types/node@18.19.84)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2)) jest-util: 27.5.1 json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 semver: 7.7.3 - typescript: 5.8.2 + typescript: 6.0.2 yargs-parser: 20.2.9 optionalDependencies: '@babel/core': 7.26.10 '@types/jest': 29.5.12 babel-jest: 29.7.0(@babel/core@7.26.10) - ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@5.8.2): + ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@18.19.84)(typescript@6.0.2): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -24918,7 +25247,7 @@ snapshots: create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.8.2 + typescript: 6.0.2 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: @@ -24988,7 +25317,7 @@ snapshots: tslib@2.8.1: {} - tsup@8.5.0(@microsoft/api-extractor@7.39.1(@types/node@22.13.14))(@swc/core@1.9.2(@swc/helpers@0.5.1))(postcss@8.5.3)(tsx@4.20.5)(typescript@5.8.2): + tsup@8.5.0(@microsoft/api-extractor@7.39.1(@types/node@22.13.14))(@swc/core@1.9.2(@swc/helpers@0.5.1))(postcss@8.5.9)(tsx@4.20.5)(typescript@6.0.2): dependencies: bundle-require: 5.1.0(esbuild@0.25.9) cac: 6.7.14 @@ -24999,7 +25328,7 @@ snapshots: fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 picocolors: 1.1.1 - postcss-load-config: 6.0.1(postcss@8.5.3)(tsx@4.20.5) + postcss-load-config: 6.0.1(postcss@8.5.9)(tsx@4.20.5) resolve-from: 5.0.0 rollup: 4.38.0 source-map: 0.8.0-beta.0 @@ -25010,8 +25339,8 @@ snapshots: optionalDependencies: '@microsoft/api-extractor': 7.39.1(@types/node@22.13.14) '@swc/core': 1.9.2(@swc/helpers@0.5.1) - postcss: 8.5.3 - typescript: 5.8.2 + postcss: 8.5.9 + typescript: 6.0.2 transitivePeerDependencies: - jiti - supports-color @@ -25028,6 +25357,11 @@ snapshots: tslib: 1.14.1 typescript: 5.8.2 + tsutils@3.21.0(typescript@6.0.2): + dependencies: + tslib: 1.14.1 + typescript: 6.0.2 + tsx@3.12.2: dependencies: '@esbuild-kit/cjs-loader': 2.4.4 @@ -25103,13 +25437,13 @@ snapshots: dependencies: ts-toolbelt: 9.6.0 - typescript-eslint@8.28.0(eslint@9.23.0)(typescript@5.8.2): + typescript-eslint@8.28.0(eslint@9.23.0)(typescript@6.0.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.28.0(@typescript-eslint/parser@8.28.0(eslint@9.23.0)(typescript@5.8.2))(eslint@9.23.0)(typescript@5.8.2) - '@typescript-eslint/parser': 8.28.0(eslint@9.23.0)(typescript@5.8.2) - '@typescript-eslint/utils': 8.28.0(eslint@9.23.0)(typescript@5.8.2) + '@typescript-eslint/eslint-plugin': 8.28.0(@typescript-eslint/parser@8.28.0(eslint@9.23.0)(typescript@6.0.2))(eslint@9.23.0)(typescript@6.0.2) + '@typescript-eslint/parser': 8.28.0(eslint@9.23.0)(typescript@6.0.2) + '@typescript-eslint/utils': 8.28.0(eslint@9.23.0)(typescript@6.0.2) eslint: 9.23.0 - typescript: 5.8.2 + typescript: 6.0.2 transitivePeerDependencies: - supports-color @@ -25122,6 +25456,8 @@ snapshots: typescript@5.8.2: {} + typescript@6.0.2: {} + ufo@1.6.1: {} uglify-js@2.8.29: @@ -25134,14 +25470,14 @@ snapshots: uglify-to-browserify@1.0.2: optional: true - umi@4.4.6(@babel/core@7.26.10)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.3.3)))(lightningcss@1.22.1)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(sass@1.86.0)(stylelint@15.11.0(typescript@5.3.3))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.3.3)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))): + umi@4.4.6(@babel/core@7.26.10)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.3.3)))(lightningcss@1.32.0)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(sass@1.86.0)(stylelint@15.11.0(typescript@5.3.3))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.3.3)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))): dependencies: '@babel/runtime': 7.23.6 '@umijs/bundler-utils': 4.4.6 '@umijs/bundler-webpack': 4.4.6(type-fest@1.4.0)(typescript@5.3.3)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) '@umijs/core': 4.4.6 '@umijs/lint': 4.4.6(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.3.3)))(postcss-less@6.0.0(postcss@8.5.3))(stylelint@15.11.0(typescript@5.3.3))(typescript@5.3.3) - '@umijs/preset-umi': 4.4.6(@types/node@22.13.14)(@types/react@18.3.23)(lightningcss@1.22.1)(rollup@3.29.5)(sass@1.86.0)(terser@5.39.0)(type-fest@1.4.0)(typescript@5.3.3)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) + '@umijs/preset-umi': 4.4.6(@types/node@22.13.14)(@types/react@18.3.23)(lightningcss@1.32.0)(rollup@3.29.5)(sass@1.86.0)(terser@5.39.0)(type-fest@1.4.0)(typescript@5.3.3)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) '@umijs/renderer-react': 4.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@umijs/server': 4.4.6 '@umijs/test': 4.4.6(@babel/core@7.26.10) @@ -25181,14 +25517,14 @@ snapshots: - webpack-hot-middleware - webpack-plugin-serve - umi@4.4.6(@babel/core@7.26.10)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.8.2)))(lightningcss@1.22.1)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(sass@1.86.0)(stylelint@15.11.0(typescript@5.8.2))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.8.2)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))): + umi@4.4.6(@babel/core@7.26.10)(@types/node@22.13.14)(@types/react@18.3.23)(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.8.2)))(lightningcss@1.32.0)(postcss-less@6.0.0(postcss@8.5.3))(prettier@3.5.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(rollup@3.29.5)(sass@1.86.0)(stylelint@15.11.0(typescript@5.8.2))(terser@5.39.0)(type-fest@1.4.0)(typescript@5.8.2)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))): dependencies: '@babel/runtime': 7.23.6 '@umijs/bundler-utils': 4.4.6 '@umijs/bundler-webpack': 4.4.6(type-fest@1.4.0)(typescript@5.8.2)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) '@umijs/core': 4.4.6 '@umijs/lint': 4.4.6(eslint@9.23.0)(jest@29.1.2(@types/node@22.13.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.9.2(@swc/helpers@0.5.1))(@types/node@22.13.14)(typescript@5.8.2)))(postcss-less@6.0.0(postcss@8.5.3))(stylelint@15.11.0(typescript@5.8.2))(typescript@5.8.2) - '@umijs/preset-umi': 4.4.6(@types/node@22.13.14)(@types/react@18.3.23)(lightningcss@1.22.1)(rollup@3.29.5)(sass@1.86.0)(terser@5.39.0)(type-fest@1.4.0)(typescript@5.8.2)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) + '@umijs/preset-umi': 4.4.6(@types/node@22.13.14)(@types/react@18.3.23)(lightningcss@1.32.0)(rollup@3.29.5)(sass@1.86.0)(terser@5.39.0)(type-fest@1.4.0)(typescript@5.8.2)(webpack@5.101.3(@swc/core@1.9.2(@swc/helpers@0.5.1))) '@umijs/renderer-react': 4.4.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@umijs/server': 4.4.6 '@umijs/test': 4.4.6(@babel/core@7.26.10) @@ -25481,22 +25817,27 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-plugin-conditional-compile@1.4.3(vite@5.4.15(@types/node@18.19.84)(less@4.2.2)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0)): + vite-plugin-conditional-compile@1.4.3(vite@8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5)): dependencies: '@babel/core': 7.26.10 - vite: 5.4.15(@types/node@18.19.84)(less@4.2.2)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0) + vite: 8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5) transitivePeerDependencies: - supports-color - vite-plugin-eslint@1.8.1(eslint@9.23.0)(vite@5.4.15(@types/node@18.19.84)(less@4.2.2)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0)): + vite-plugin-eslint2@5.1.0(@types/eslint@8.56.12)(eslint@9.23.0)(rolldown@1.0.0-rc.15)(rollup@4.38.0)(vite@8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5)): dependencies: - '@rollup/pluginutils': 4.2.1 - '@types/eslint': 8.56.12 + '@rollup/pluginutils': 5.3.0(rollup@4.38.0) + debug: 4.4.3 eslint: 9.23.0 - rollup: 2.79.2 - vite: 5.4.15(@types/node@18.19.84)(less@4.2.2)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0) + vite: 8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5) + optionalDependencies: + '@types/eslint': 8.56.12 + rolldown: 1.0.0-rc.15 + rollup: 4.38.0 + transitivePeerDependencies: + - supports-color - vite-plugin-html@3.2.2(vite@5.4.15(@types/node@18.19.84)(less@4.2.2)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0)): + vite-plugin-html@3.2.2(vite@8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5)): dependencies: '@rollup/pluginutils': 4.2.1 colorette: 2.0.20 @@ -25510,9 +25851,9 @@ snapshots: html-minifier-terser: 6.1.0 node-html-parser: 5.4.2 pathe: 0.2.0 - vite: 5.4.15(@types/node@18.19.84)(less@4.2.2)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0) + vite: 8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5) - vite@4.5.2(@types/node@22.13.14)(less@4.1.3)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0): + vite@4.5.2(@types/node@22.13.14)(less@4.1.3)(lightningcss@1.32.0)(sass@1.86.0)(terser@5.39.0): dependencies: esbuild: 0.18.20 postcss: 8.5.3 @@ -25521,22 +25862,24 @@ snapshots: '@types/node': 22.13.14 fsevents: 2.3.3 less: 4.1.3 - lightningcss: 1.22.1 + lightningcss: 1.32.0 sass: 1.86.0 terser: 5.39.0 - vite@5.4.15(@types/node@18.19.84)(less@4.2.2)(lightningcss@1.22.1)(sass@1.86.0)(terser@5.39.0): + vite@8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5): dependencies: - esbuild: 0.21.5 - postcss: 8.5.3 - rollup: 4.38.0 + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.9 + rolldown: 1.0.0-rc.15 + tinyglobby: 0.2.16 optionalDependencies: '@types/node': 18.19.84 fsevents: 2.3.3 less: 4.2.2 - lightningcss: 1.22.1 sass: 1.86.0 terser: 5.39.0 + tsx: 4.20.5 vm-browserify@1.1.2: {} diff --git a/tsconfig.json b/tsconfig.json index 54ac65d2a3..6653e57972 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,8 +9,8 @@ "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, - "module": "ESNext", - "moduleResolution": "Bundler", + "module": "esnext", + "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, From 2e45e21b8e7dd6ce4bde05437a2102e6aae11abe Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Tue, 14 Apr 2026 15:29:19 +0800 Subject: [PATCH 03/36] [chore]: restore version.ts --- packages/base/src/scripts/version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/base/src/scripts/version.ts b/packages/base/src/scripts/version.ts index 400cc67d18..6d5baaff06 100644 --- a/packages/base/src/scripts/version.ts +++ b/packages/base/src/scripts/version.ts @@ -1 +1 @@ -export const UI_VERSION = 'chore/update-tsconfig 42f23849f0'; +export const UI_VERSION = 'sync/data-masking 417b194dd'; From f16e752632cb0fbc346f41d59d3283253e8d7497 Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Wed, 15 Apr 2026 14:18:19 +0800 Subject: [PATCH 04/36] chore(ci): switch test pipeline to turbo per-package coverage reports --- .github/workflows/main.yml | 83 ++- .gitignore | 3 +- .oxfmtrc.json | 18 + .oxlintrc.json | 42 ++ package.json | 27 +- packages/base/jest.config.mjs | 19 + packages/base/package.json | 9 +- packages/base/vite.config.mts | 2 - packages/dms-kit/jest.config.mjs | 18 + packages/dms-kit/package.json | 14 +- packages/icons/package.json | 6 +- packages/shared/jest.config.mjs | 26 + packages/shared/package.json | 11 +- packages/sqle/jest.config.mjs | 21 + packages/sqle/package.json | 9 +- packages/sqle/src/types/ambient-modules.d.ts | 7 + .../tooling-config/jest/create-jest-config.js | 162 +++++ packages/tooling-config/package.json | 20 + packages/tooling-config/tsconfig/base.json | 20 + pnpm-lock.yaml | 599 +++++++++++++++--- scripts/format/oxfmt-changed.mjs | 57 ++ scripts/jest/README.md | 41 +- scripts/jest/merge-report-json.js | 86 --- scripts/jest/run-ci.sh | 29 - tsconfig.json | 17 +- turbo.json | 49 ++ 26 files changed, 1096 insertions(+), 299 deletions(-) create mode 100644 .oxfmtrc.json create mode 100644 .oxlintrc.json create mode 100644 packages/base/jest.config.mjs create mode 100644 packages/dms-kit/jest.config.mjs create mode 100644 packages/shared/jest.config.mjs create mode 100644 packages/sqle/jest.config.mjs create mode 100644 packages/sqle/src/types/ambient-modules.d.ts create mode 100644 packages/tooling-config/jest/create-jest-config.js create mode 100644 packages/tooling-config/package.json create mode 100644 packages/tooling-config/tsconfig/base.json create mode 100644 scripts/format/oxfmt-changed.mjs delete mode 100644 scripts/jest/merge-report-json.js delete mode 100644 scripts/jest/run-ci.sh create mode 100644 turbo.json diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 397ad2eb92..dd0b899fd7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -24,9 +24,6 @@ jobs: test: runs-on: ubuntu-latest if: ${{ !contains(github.event.pull_request.title, '[skip checker]') }} - strategy: - matrix: - shard: [1, 2, 3, 4] steps: - name: Checkout repository uses: actions/checkout@v4 @@ -34,13 +31,32 @@ jobs: - name: Install dependencies uses: ./.github/actions/catch-install-pnpm - - name: Coverage test report - run: sh ./scripts/jest/run-ci.sh ${{ matrix.shard }} ${{ strategy.job-total }} + - name: Run package test suites + run: pnpm test:ci:turbo - - uses: actions/upload-artifact@v4 + - name: Upload base coverage artifact + uses: actions/upload-artifact@v4 with: - name: coverage-artifacts-${{ matrix.shard }} - path: coverage/ + name: coverage-artifacts-base + path: packages/base/coverage/ + + - name: Upload dms-kit coverage artifact + uses: actions/upload-artifact@v4 + with: + name: coverage-artifacts-dms-kit + path: packages/dms-kit/coverage/ + + - name: Upload shared coverage artifact + uses: actions/upload-artifact@v4 + with: + name: coverage-artifacts-shared + path: packages/shared/coverage/ + + - name: Upload sqle coverage artifact + uses: actions/upload-artifact@v4 + with: + name: coverage-artifacts-sqle + path: packages/sqle/coverage/ report: runs-on: ubuntu-latest @@ -53,45 +69,56 @@ jobs: - name: Get Coverage 1 uses: actions/download-artifact@v4 with: - name: coverage-artifacts-1 - path: coverage + name: coverage-artifacts-base + path: coverage/base - name: Get Coverage 2 uses: actions/download-artifact@v4 with: - name: coverage-artifacts-2 - path: coverage + name: coverage-artifacts-dms-kit + path: coverage/dms-kit - name: Get Coverage 3 uses: actions/download-artifact@v4 with: - name: coverage-artifacts-3 - path: coverage + name: coverage-artifacts-shared + path: coverage/shared - name: Get Coverage 4 uses: actions/download-artifact@v4 with: - name: coverage-artifacts-4 - path: coverage + name: coverage-artifacts-sqle + path: coverage/sqle - - name: Install dependencies - uses: ./.github/actions/catch-install-pnpm + - name: Coverage report (base) + uses: ArtiomTr/jest-coverage-report-action@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + coverage-file: coverage/base/report.json - - name: Merge coverage reports - run: node ./scripts/jest/merge-report-json.js + - name: Coverage report (dms-kit) + uses: ArtiomTr/jest-coverage-report-action@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + coverage-file: coverage/dms-kit/report.json + + - name: Coverage report (shared) + uses: ArtiomTr/jest-coverage-report-action@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + coverage-file: coverage/shared/report.json - - name: Coverage test report + - name: Coverage report (sqle) uses: ArtiomTr/jest-coverage-report-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} - base-coverage-file: coverage-merged.json - coverage-file: coverage-merged.json + coverage-file: coverage/sqle/report.json - - name: Delete artifact + - name: Delete coverage artifacts uses: geekyeggo/delete-artifact@v5 with: name: | - coverage-artifacts-1 - coverage-artifacts-2 - coverage-artifacts-3 - coverage-artifacts-4 + coverage-artifacts-base + coverage-artifacts-dms-kit + coverage-artifacts-shared + coverage-artifacts-sqle diff --git a/.gitignore b/.gitignore index 4dbb2d65dd..37cc7fdbb5 100644 --- a/.gitignore +++ b/.gitignore @@ -16,9 +16,8 @@ dist # testing /ce_coverage /coverage +**/coverage/** /report.json -/coverage-merged -/coverage-merged.json # production /build diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 0000000000..aa9ef744a3 --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,18 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "tabWidth": 2, + "semi": true, + "printWidth": 80, + "trailingComma": "none", + "arrowParens": "always", + "proseWrap": "preserve", + "useTabs": false, + "singleQuote": true, + "bracketSpacing": true, + "jsxBracketSameLine": false, + "sortPackageJson": false, + "ignorePatterns": [ + "*.snap", + "*.md" + ] +} diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 0000000000..72db1b5f1f --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,42 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": [ + "react", + "import", + "node", + "jest", + "typescript", + "unicorn", + "oxc" + ], + "categories": { + "correctness": "warn", + "suspicious": "warn" + }, + "rules": { + "no-console": "warn", + "react-in-jsx-scope": "off", + "no-shadow": "off", + "no-shadow-restricted-names": "error", + "prefer-const": "warn", + "no-extra-boolean-cast": "off", + "no-template-curly-in-string": "warn", + "react/display-name": "off", + "import/no-anonymous-default-export": "warn" + }, + "env": { + "builtin": true + }, + "ignorePatterns": [ + "**/*.test.ts", + "**/*.test.tsx", + "**/demo/**", + "**/demos/**", + "**/dist/**", + "**/es/**", + "**/node_modules/**", + "packages/shared/lib/api/*", + "packages/**/mockApi/*", + "packages/**/testUtil/*" + ] +} \ No newline at end of file diff --git a/package.json b/package.json index ea0f9fac51..eb7d5748ba 100644 --- a/package.json +++ b/package.json @@ -10,21 +10,26 @@ "scripts": { "preview": "pnpm --filter base preview", "preinstall": "npx only-allow pnpm", - "start": "concurrently \"pnpm --filter base start\" \"pnpm --filter @actiontech/dms-kit dev\"", - "start:ee": "concurrently \"pnpm --filter base start:ee\" \"pnpm --filter @actiontech/dms-kit dev\"", - "start:demo": "concurrently \"pnpm --filter base start:demo\" \"pnpm --filter @actiontech/dms-kit dev\"", + "start": "turbo run start --filter=base --filter=@actiontech/dms-kit --parallel", + "start:ee": "turbo run start:ee --filter=base --filter=@actiontech/dms-kit --parallel", + "start:demo": "turbo run start:demo --filter=base --filter=@actiontech/dms-kit --parallel", "build": "pnpm --filter @actiontech/dms-kit build && pnpm --filter base build", "build:ee": "pnpm --filter @actiontech/dms-kit build && pnpm --filter base build:ee", "build:demo": "pnpm --filter @actiontech/dms-kit build && pnpm --filter base build:demo", - "prettier:w": "prettier -w packages/*/src/ packages/shared/lib/ scripts/cli/*/src", - "prettier:c": "prettier -c packages/*/src/ packages/shared/lib/ scripts/cli/*/src", - "eslint": "eslint packages/*/src/ packages/shared/lib/ scripts/cli/*/src", + "check:turbo": "turbo run check --filter='./packages/*'", + "oxfmt:w": "node ./scripts/format/oxfmt-changed.mjs", + "oxfmt:c": "node ./scripts/format/oxfmt-changed.mjs --check", + "oxfmt:w:all": "oxfmt --write \"packages/*/src/**/*\" \"packages/shared/lib/**/*\" \"scripts/cli/*/src/**/*\"", + "oxfmt:c:all": "oxfmt --check \"packages/*/src/**/*\" \"packages/shared/lib/**/*\" \"scripts/cli/*/src/**/*\"", + "oxlint": "oxlint --no-error-on-unmatched-pattern packages/base/src packages/dms-kit/src packages/shared/src packages/shared/lib packages/sqle/src scripts/cli/create-dms-page/src scripts/cli/dms-kit-publish/src packages/base/vite.config.mts", + "oxlint:turbo": "turbo run oxlint --filter='./packages/*'", "stylelint": "stylelint packages/*/{src,lib}/**/{*.less,style.ts,element.ts}", "ts-check": "tsc --noEmit", - "checker": "concurrently \"pnpm ts-check\" \"pnpm eslint\" \"pnpm stylelint\" \"pnpm prettier:c\"", + "checker": "pnpm check:turbo", "test": "sh ./scripts/jest/run.sh", "test:c": "sh ./scripts/jest/run-coverage.sh", - "test:ci": "sh ./scripts/jest/run-ci.sh 1 1 && node ./scripts/jest/merge-report-json.js", + "test:ci": "turbo run test:ci --filter='./packages/*'", + "test:ci:turbo": "pnpm test:ci", "test:clean": "jest --clearCache", "icon:g": "pnpm --filter @actiontech/icons icon:g", "icon:docs:g": "pnpm --filter @actiontech/icons docs:g", @@ -41,6 +46,7 @@ "keywords": [], "author": "", "devDependencies": { + "@actiontech/tooling-config": "workspace:^", "@actiontech/cli-create-dms-page": "workspace:^", "@actiontech/cli-dms-kit-publish": "workspace:^", "@cfaester/enzyme-adapter-react-18": "^0.7.0", @@ -66,7 +72,6 @@ "babel-preset-react-app": "^10.0.1", "blob-polyfill": "^7.0.20220408", "comment-parser": "^1.4.1", - "concurrently": "^9.1.2", "cross-env": "^7.0.3", "enzyme": "^3.11.0", "enzyme-to-json": "^3.6.2", @@ -86,6 +91,8 @@ "less": "^4.1.3", "mockdate": "^3.0.5", "msw": "^0.45.0", + "oxfmt": "^0.45.0", + "oxlint": "^1.60.0", "postcss-less": "^6.0.0", "postcss-styled-syntax": "^0.6.4", "prettier": "^2.7.1", @@ -96,11 +103,11 @@ "stylelint-prettier": "^4.0.2", "ts-jest": "27.1.5", "tsx": "^4.20.5", + "turbo": "^2.9.6", "typescript": "^6", "typescript-eslint": "^8.28.0", "vite": "^8", "vite-plugin-conditional-compile": "1.4.3", - "vite-plugin-eslint2": "^5.1.0", "vite-plugin-html": "^3.2.2" }, "dependencies": { diff --git a/packages/base/jest.config.mjs b/packages/base/jest.config.mjs new file mode 100644 index 0000000000..c3629d79b9 --- /dev/null +++ b/packages/base/jest.config.mjs @@ -0,0 +1,19 @@ +import { createJestConfig } from '@actiontech/tooling-config/jest/create-jest-config'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; + +const packageRoot = path.dirname(fileURLToPath(import.meta.url)); + +export default createJestConfig({ + packageRoot, + enabledProjects: ['dms', 'sqle-ce', 'sqle-ee'], + collectCoverageFrom: [ + 'src/{page,components,hooks,global,store,utils}/**/*.{ts,tsx}', + 'src/App.tsx', + '!src/**/*.test.{ts,tsx}', + '!src/**/*.type.ts', + '!src/**/*.enum.ts', + '!src/**/demo/**', + '!src/**/demos/**' + ] +}); diff --git a/packages/base/package.json b/packages/base/package.json index b0aa6eb18f..0cf4c1ba6c 100644 --- a/packages/base/package.json +++ b/packages/base/package.json @@ -10,13 +10,18 @@ "build:ee": "node ../../scripts/getGitVersion.mjs ee && tsc && cross-env NODE_OPTIONS=--max_old_space_size=102400 buildType=ee,SQLE vite build", "build:demo": "node ../../scripts/getGitVersion.mjs trial && tsc && cross-env NODE_OPTIONS=--max_old_space_size=102400 buildType=ce,SQLE,DEMO vite build", "preview": "vite preview", + "oxlint": "oxlint --no-error-on-unmatched-pattern src vite.config.mts", + "typecheck": "tsc --noEmit -p tsconfig.json", + "stylelint": "stylelint \"src/**/{*.less,style.ts,element.ts}\" --allow-empty-input", + "check": "echo \"base check\"", "test": "jest --watchAll=true", - "test:c": "jest --coverage", - "test:ci": "jest --ci --watchAll=false --coverage --color --silent --testLocationInResults" + "test:c": "jest --watchAll=false --coverage --coverageDirectory=coverage", + "test:ci": "jest --ci --watchAll=false --coverage --coverageDirectory=coverage --json --outputFile=coverage/report.json --color --silent --testLocationInResults" }, "dependencies": { "@actiontech/shared": "workspace:^", "@actiontech/dms-kit": "workspace:^", + "@actiontech/tooling-config": "workspace:^", "babel-preset-react-app": "^10.0.1", "sqle": "workspace:^", "@actiontech/icons": "workspace:^" diff --git a/packages/base/vite.config.mts b/packages/base/vite.config.mts index 9803a0ac55..ce3c5ed5ae 100644 --- a/packages/base/vite.config.mts +++ b/packages/base/vite.config.mts @@ -1,6 +1,5 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; -import eslint from 'vite-plugin-eslint2'; import vitePluginConditionalCompile from 'vite-plugin-conditional-compile'; import { createHtmlPlugin } from 'vite-plugin-html'; import * as path from 'path'; @@ -50,7 +49,6 @@ export default defineConfig(() => { demo: isDemo } }), - eslint(), react(), createHtmlPlugin({ inject: { diff --git a/packages/dms-kit/jest.config.mjs b/packages/dms-kit/jest.config.mjs new file mode 100644 index 0000000000..b5af9812ef --- /dev/null +++ b/packages/dms-kit/jest.config.mjs @@ -0,0 +1,18 @@ +import { createJestConfig } from '@actiontech/tooling-config/jest/create-jest-config'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; + +const packageRoot = path.dirname(fileURLToPath(import.meta.url)); + +export default createJestConfig({ + packageRoot, + enabledProjects: ['dms'], + collectCoverageFrom: [ + 'src/**/*.{ts,tsx}', + '!src/**/*.test.{ts,tsx}', + '!src/**/*.type.ts', + '!src/**/*.enum.ts', + '!src/**/demo/**', + '!src/**/demos/**' + ] +}); diff --git a/packages/dms-kit/package.json b/packages/dms-kit/package.json index 311f8f1ebb..8e8b8f24fa 100644 --- a/packages/dms-kit/package.json +++ b/packages/dms-kit/package.json @@ -16,12 +16,19 @@ "scripts": { "build": "father build", "dev": "father dev --incremental", + "start": "pnpm dev", + "start:ee": "pnpm dev", + "start:demo": "pnpm dev", "docs:dev": "dumi dev", "docs:build": "dumi build", "docs:preview": "dumi preview", + "oxlint": "oxlint --no-error-on-unmatched-pattern src", + "typecheck": "tsc --noEmit -p tsconfig.json", + "stylelint": "stylelint \"src/**/{*.less,style.ts,element.ts}\" --allow-empty-input", + "check": "echo \"dms-kit check\"", "test": "jest --watchAll=true", - "test:c": "jest --watchAll=false --coverage", - "test:ci": "jest --ci --watchAll=false --coverage --color --silent --testLocationInResults" + "test:c": "jest --watchAll=false --coverage --coverageDirectory=coverage", + "test:ci": "jest --ci --watchAll=false --coverage --coverageDirectory=coverage --json --outputFile=coverage/report.json --color --silent --testLocationInResults" }, "dependencies": { "ahooks": "^3.7.0", @@ -54,8 +61,9 @@ "typescript": "^5.0.2" }, "devDependencies": { + "@actiontech/tooling-config": "workspace:^", "father": "^4.5.2", "dumi": "^2.3.8", "babel-plugin-import": "^1.13.8" } -} \ No newline at end of file +} diff --git a/packages/icons/package.json b/packages/icons/package.json index 48cf230afa..485090a0f4 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -9,6 +9,10 @@ "docs:build": "dumi build", "docs:preview": "dumi preview", "build": "father build", + "oxlint": "oxlint --no-error-on-unmatched-pattern src", + "typecheck": "tsc --noEmit -p tsconfig.json", + "stylelint": "stylelint \"src/**/{*.less,style.ts,element.ts}\" --allow-empty-input", + "check": "echo \"icons check\"", "icon:g": "svgr --template template/template.cjs -d src svg/ ", "docs:g": "node scripts/generate.js" }, @@ -21,4 +25,4 @@ "dumi": "^2.3.8", "father": "^4.1.0" } -} \ No newline at end of file +} diff --git a/packages/shared/jest.config.mjs b/packages/shared/jest.config.mjs new file mode 100644 index 0000000000..ed7c7a116c --- /dev/null +++ b/packages/shared/jest.config.mjs @@ -0,0 +1,26 @@ +import { createJestConfig } from '@actiontech/tooling-config/jest/create-jest-config'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; + +const packageRoot = path.dirname(fileURLToPath(import.meta.url)); + +export default createJestConfig({ + packageRoot, + enabledProjects: ['dms', 'sqle-ce'], + collectCoverageFrom: [ + 'src/**/*.{ts,tsx}', + 'lib/**/*.{ts,tsx}', + 'api/common/**/*.{ts,tsx}', + '!src/**/*.test.{ts,tsx}', + '!lib/**/*.test.{ts,tsx}', + '!src/**/*.type.ts', + '!src/**/*.enum.ts', + '!lib/**/*.type.ts', + '!lib/**/*.enum.ts', + '!lib/hooks/usePrompt/index.tsx', + '!src/**/demo/**', + '!src/**/demos/**', + '!lib/**/demo/**', + '!lib/**/demos/**' + ] +}); diff --git a/packages/shared/package.json b/packages/shared/package.json index f78ab4c849..340adcbb99 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -5,15 +5,20 @@ "license": "MIT", "scripts": { "build": "tsup", + "oxlint": "oxlint --no-error-on-unmatched-pattern src lib api", + "typecheck": "tsc --noEmit -p tsconfig.json", + "stylelint": "stylelint \"{src,lib}/**/{*.less,style.ts,element.ts}\" --allow-empty-input", + "check": "echo \"shared check\"", "test": "jest --watchAll=true", - "test:c": "jest --watchAll=false --coverage", - "test:ci": "jest --ci --watchAll=false --coverage --color --silent --testLocationInResults" + "test:c": "jest --watchAll=false --coverage --coverageDirectory=coverage", + "test:ci": "jest --ci --watchAll=false --coverage --coverageDirectory=coverage --json --outputFile=coverage/report.json --color --silent --testLocationInResults" }, "dependencies": { "@actiontech/icons": "workspace:^", "@actiontech/dms-kit": "workspace:^" }, "devDependencies": { + "@actiontech/tooling-config": "workspace:^", "tsup": "^8.5.0" } -} \ No newline at end of file +} diff --git a/packages/sqle/jest.config.mjs b/packages/sqle/jest.config.mjs new file mode 100644 index 0000000000..06aa954798 --- /dev/null +++ b/packages/sqle/jest.config.mjs @@ -0,0 +1,21 @@ +import { createJestConfig } from '@actiontech/tooling-config/jest/create-jest-config'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; + +const packageRoot = path.dirname(fileURLToPath(import.meta.url)); + +export default createJestConfig({ + packageRoot, + enabledProjects: ['dms', 'sqle-ce', 'sqle-ee'], + collectCoverageFrom: [ + 'src/{page,components,hooks,global,store,utils}/**/*.{ts,tsx}', + 'src/App.tsx', + '!src/**/*.test.{ts,tsx}', + '!src/**/*.type.ts', + '!src/**/*.enum.ts', + '!src/page/SqlAnalyze/SqlAnalyze/ProcessListCom/**', + '!src/page/Knowledge/Graph/components/**', + '!src/**/demo/**', + '!src/**/demos/**' + ] +}); diff --git a/packages/sqle/package.json b/packages/sqle/package.json index 68dacf6a58..8e8dad5573 100644 --- a/packages/sqle/package.json +++ b/packages/sqle/package.json @@ -23,6 +23,7 @@ "web-vitals": "^0.2.4" }, "devDependencies": { + "@actiontech/tooling-config": "workspace:^", "@types/react-grid-layout": "^1.3.2", "graphology-types": "^0.24.8", "jest-canvas-mock": "^2.2.0" @@ -30,9 +31,13 @@ "scripts": { "start": "PORT=3030 craco start", "build": "craco build", + "oxlint": "oxlint --no-error-on-unmatched-pattern src", + "typecheck": "tsc --noEmit -p tsconfig.json", + "stylelint": "stylelint \"src/**/{*.less,style.ts,element.ts}\" --allow-empty-input", + "check": "echo \"sqle check\"", "test": "jest --watchAll=true", - "test:c": "jest --watchAll=false --coverage", - "test:ci": "jest --ci --watchAll=false --coverage --color --silent --testLocationInResults", + "test:c": "jest --watchAll=false --coverage --coverageDirectory=coverage", + "test:ci": "jest --ci --watchAll=false --coverage --coverageDirectory=coverage --json --outputFile=coverage/report.json --color --silent --testLocationInResults", "eject": "react-scripts eject" }, "browserslist": { diff --git a/packages/sqle/src/types/ambient-modules.d.ts b/packages/sqle/src/types/ambient-modules.d.ts new file mode 100644 index 0000000000..8768095c44 --- /dev/null +++ b/packages/sqle/src/types/ambient-modules.d.ts @@ -0,0 +1,7 @@ +declare module '*.less'; +declare module '*.css'; + +declare module 'monaco-editor/esm/vs/language/json/json.worker?worker' { + const workerFactory: new () => Worker; + export default workerFactory; +} diff --git a/packages/tooling-config/jest/create-jest-config.js b/packages/tooling-config/jest/create-jest-config.js new file mode 100644 index 0000000000..70d9073bbc --- /dev/null +++ b/packages/tooling-config/jest/create-jest-config.js @@ -0,0 +1,162 @@ +import path from 'node:path'; + +const CE_TEST_FILE_RE = '\\.ce(\\.[^./]+)*\\.test\\.[jt]sx?$'; +const SQLE_TEST_FILE_RE = '\\.sqle(\\.[^./]+)*\\.test\\.[jt]sx?$'; +const PROVISION_TEST_FILE_RE = '\\.provision(\\.[^./]+)*\\.test\\.[jt]sx?$'; + +const PROJECT_CONDITIONS = { + dms: { + ee: true, + ce: false, + sqle: true, + provision: true, + dms: true + }, + 'sqle-ce': { + ee: false, + ce: true, + sqle: true, + provision: false, + dms: false + }, + 'sqle-ee': { + ee: true, + ce: false, + sqle: true, + provision: false, + dms: false + }, + provision: { + ee: true, + ce: false, + sqle: false, + provision: true, + dms: false + } +}; + +function createProject(name, sharedProjectConfig, sharedIgnorePatterns) { + if (!PROJECT_CONDITIONS[name]) { + throw new Error(`Unsupported Jest project: ${name}`); + } + + const config = { + ...sharedProjectConfig, + displayName: name, + globals: { + TEST_CONDITIONS: PROJECT_CONDITIONS[name] + } + }; + + if (name === 'dms') { + config.testPathIgnorePatterns = [ + ...sharedIgnorePatterns, + CE_TEST_FILE_RE, + SQLE_TEST_FILE_RE, + PROVISION_TEST_FILE_RE + ]; + return config; + } + + if (name === 'sqle-ce') { + config.testRegex = CE_TEST_FILE_RE; + config.testPathIgnorePatterns = sharedIgnorePatterns; + return config; + } + + if (name === 'sqle-ee') { + config.testRegex = SQLE_TEST_FILE_RE; + config.testPathIgnorePatterns = [...sharedIgnorePatterns, CE_TEST_FILE_RE]; + return config; + } + + config.testRegex = PROVISION_TEST_FILE_RE; + config.testPathIgnorePatterns = [...sharedIgnorePatterns, CE_TEST_FILE_RE]; + return config; +} + +export function createJestConfig(options) { + const { + packageRoot, + collectCoverageFrom = [], + enabledProjects = ['dms'], + useSlowReporter = false + } = options; + + const repoRoot = path.resolve(packageRoot, '../..'); + const sharedIgnorePatterns = ['/node_modules/', '/demo/', '/demos/']; + + const sharedProjectConfig = { + transform: { + '^.+\\.(ts|tsx|js|jsx)$': path.resolve( + repoRoot, + 'scripts/jest/custom-transform.js' + ), + '^.+\\.(png|jpg|jpeg|css|json)$': path.resolve( + repoRoot, + 'scripts/jest/file-transform.js' + ) + }, + transformIgnorePatterns: [ + '/dist/', + 'node_modules/(?!(?:.pnpm/)?(@react-sigma|.+/es))[^/]+?/(?!(es|node_modules)/)' + ], + moduleFileExtensions: ['ts', 'tsx', 'js', 'json', 'jsx', 'node'], + testEnvironment: 'jest-environment-jsdom', + resetMocks: true, + moduleNameMapper: { + '.+\\.(css|style|less|sass|scss|ttf|woff|woff2)$': 'identity-obj-proxy', + '^~/(.*)$': '/src/$1', + '@ant-design/plots': path.resolve( + repoRoot, + 'packages/shared/lib/testUtil/mockModule/mockAntDesignPlots.jsx' + ), + 'monaco-editor': path.resolve( + repoRoot, + 'packages/shared/lib/testUtil/mockModule/mockEditor.jsx' + ), + '@monaco-editor/react': path.resolve( + repoRoot, + 'packages/shared/lib/testUtil/mockModule/mockEditor.jsx' + ), + '@uiw/react-md-editor': path.resolve( + repoRoot, + 'packages/shared/lib/testUtil/mockModule/mockEditor.jsx' + ), + '@react-sigma/core(.*)$': path.resolve( + repoRoot, + 'packages/shared/lib/testUtil/mockModule/mockSigmaCore.tsx' + ), + '@react-sigma/graph-search$': path.resolve( + repoRoot, + 'packages/shared/lib/testUtil/mockModule/mockSigmaGraphSearch.tsx' + ), + '^@actiontech/(.*)$': path.resolve(packageRoot, '../$1') + }, + collectCoverageFrom, + setupFilesAfterEnv: [path.resolve(repoRoot, 'jest-setup.ts')] + }; + + const projects = enabledProjects.map((name) => + createProject(name, sharedProjectConfig, sharedIgnorePatterns) + ); + + const reporters = ['default']; + if (useSlowReporter) { + reporters.push([ + 'jest-slow-test-reporter', + { + numTests: 8, + outputDirectory: 'reports', + outputName: 'report.xml', + color: true, + warnSlowerThan: 6000 + } + ]); + } + + return { + projects, + reporters + }; +} diff --git a/packages/tooling-config/package.json b/packages/tooling-config/package.json new file mode 100644 index 0000000000..047be524c4 --- /dev/null +++ b/packages/tooling-config/package.json @@ -0,0 +1,20 @@ +{ + "name": "@actiontech/tooling-config", + "version": "1.0.0", + "private": true, + "type": "module", + "exports": { + "./jest/create-jest-config": "./jest/create-jest-config.js", + "./tsconfig/base": "./tsconfig/base.json" + }, + "scripts": { + "oxlint": "oxlint --no-error-on-unmatched-pattern jest tsconfig", + "typecheck": "echo \"tooling-config typecheck skipped\"", + "stylelint": "echo \"tooling-config stylelint skipped\"", + "check": "echo \"tooling-config check\"" + }, + "files": [ + "jest", + "tsconfig" + ] +} diff --git a/packages/tooling-config/tsconfig/base.json b/packages/tooling-config/tsconfig/base.json new file mode 100644 index 0000000000..68a5b6acaf --- /dev/null +++ b/packages/tooling-config/tsconfig/base.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "allowJs": false, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + "types": ["jest", "node", "testing-library__jest-dom"] + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f0aa3197ef..a966468350 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -138,6 +138,9 @@ importers: '@actiontech/cli-dms-kit-publish': specifier: workspace:^ version: link:scripts/cli/dms-kit-publish + '@actiontech/tooling-config': + specifier: workspace:^ + version: link:packages/tooling-config '@cfaester/enzyme-adapter-react-18': specifier: ^0.7.0 version: 0.7.1(enzyme@3.11.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -207,9 +210,6 @@ importers: comment-parser: specifier: ^1.4.1 version: 1.4.1 - concurrently: - specifier: ^9.1.2 - version: 9.1.2 cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -267,6 +267,12 @@ importers: msw: specifier: ^0.45.0 version: 0.45.0(encoding@0.1.13)(typescript@6.0.2) + oxfmt: + specifier: ^0.45.0 + version: 0.45.0 + oxlint: + specifier: ^1.60.0 + version: 1.60.0 postcss-less: specifier: ^6.0.0 version: 6.0.0(postcss@8.5.3) @@ -297,6 +303,9 @@ importers: tsx: specifier: ^4.20.5 version: 4.20.5 + turbo: + specifier: ^2.9.6 + version: 2.9.6 typescript: specifier: ^6 version: 6.0.2 @@ -309,9 +318,6 @@ importers: vite-plugin-conditional-compile: specifier: 1.4.3 version: 1.4.3(vite@8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5)) - vite-plugin-eslint2: - specifier: ^5.1.0 - version: 5.1.0(@types/eslint@8.56.12)(eslint@9.23.0)(rolldown@1.0.0-rc.15)(rollup@4.38.0)(vite@8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5)) vite-plugin-html: specifier: ^3.2.2 version: 3.2.2(vite@8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5)) @@ -327,6 +333,9 @@ importers: '@actiontech/shared': specifier: workspace:^ version: link:../shared + '@actiontech/tooling-config': + specifier: workspace:^ + version: link:../tooling-config babel-preset-react-app: specifier: ^10.0.1 version: 10.1.0 @@ -415,6 +424,9 @@ importers: specifier: ^5.0.2 version: 5.8.2 devDependencies: + '@actiontech/tooling-config': + specifier: workspace:^ + version: link:../tooling-config babel-plugin-import: specifier: ^1.13.8 version: 1.13.8 @@ -449,6 +461,9 @@ importers: specifier: workspace:^ version: link:../icons devDependencies: + '@actiontech/tooling-config': + specifier: workspace:^ + version: link:../tooling-config tsup: specifier: ^8.5.0 version: 8.5.0(@microsoft/api-extractor@7.39.1(@types/node@22.13.14))(@swc/core@1.9.2(@swc/helpers@0.5.1))(postcss@8.5.9)(tsx@4.20.5)(typescript@6.0.2) @@ -507,6 +522,9 @@ importers: specifier: ^0.2.4 version: 0.2.4 devDependencies: + '@actiontech/tooling-config': + specifier: workspace:^ + version: link:../tooling-config '@types/react-grid-layout': specifier: ^1.3.2 version: 1.3.5 @@ -517,6 +535,8 @@ importers: specifier: ^2.2.0 version: 2.5.2 + packages/tooling-config: {} + scripts/cli/create-dms-page: dependencies: '@babel/generator': @@ -2985,6 +3005,250 @@ packages: '@oxc-project/types@0.124.0': resolution: {integrity: sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==} + '@oxfmt/binding-android-arm-eabi@0.45.0': + resolution: {integrity: sha512-A/UMxFob1fefCuMeGxQBulGfFE38g2Gm23ynr3u6b+b7fY7/ajGbNsa3ikMIkGMLJW/TRoQaMoP1kME7S+815w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxfmt/binding-android-arm64@0.45.0': + resolution: {integrity: sha512-L63z4uZmHjgvvqvMJD7mwff8aSBkM0+X4uFr6l6U5t6+Qc9DCLVZWIunJ7Gm4fn4zHPdSq6FFQnhu9yqqobxIg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxfmt/binding-darwin-arm64@0.45.0': + resolution: {integrity: sha512-UV34dd623FzqT+outIGndsCA/RBB+qgB3XVQhgmmJ9PJwa37NzPC9qzgKeOhPKxVk2HW+JKldQrVL54zs4Noww==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxfmt/binding-darwin-x64@0.45.0': + resolution: {integrity: sha512-pMNJv0CMa1pDefVPeNbuQxibh8ITpWDFEhMC/IBB9Zlu76EbgzYwrzI4Cb11mqX2+rIYN70UTrh3z06TM59ptQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxfmt/binding-freebsd-x64@0.45.0': + resolution: {integrity: sha512-xTcRoxbbo61sW2+ZRPeH+vp/o9G8gkdhiVumFU+TpneiPm14c79l6GFlxPXlCE9bNWikigbsrvJw46zCVAQFfg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxfmt/binding-linux-arm-gnueabihf@0.45.0': + resolution: {integrity: sha512-hWL8Hdni+3U1mPFx1UtWeGp3tNb6EhBAUHRMbKUxVkOp3WwoJbpVO2bfUVbS4PfpledviXXNHSTl1veTa6FhkQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxfmt/binding-linux-arm-musleabihf@0.45.0': + resolution: {integrity: sha512-6Blt/0OBT7vvfQpqYuYbpbFLPqSiaYpEJzUUWhinPEuADypDbtV1+LdjM0vYBNGPvnj85ex7lTerEX6JGcPt9w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxfmt/binding-linux-arm64-gnu@0.45.0': + resolution: {integrity: sha512-jLjoLfe+hGfjhA8hNBSdw85yCA8ePKq7ME4T+g6P9caQXvmt6IhE2X7iVjnVdkmYUWEzZrxlh4p6RkDmAMJY/A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-arm64-musl@0.45.0': + resolution: {integrity: sha512-XQKXZIKYJC3GQJ8FnD3iMntpw69Wd9kDDK/Xt79p6xnFYlGGxSNv2vIBvRTDg5CKByWFWWZLCRDOXoP/m6YN4g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxfmt/binding-linux-ppc64-gnu@0.45.0': + resolution: {integrity: sha512-+g5RiG+xOkdrCWkKodv407nTvMq4vYM18Uox2MhZBm/YoqFxxJpWKsloskFFG5NU13HGPw1wzYjjOVcyd9moCA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-riscv64-gnu@0.45.0': + resolution: {integrity: sha512-V7dXKoSyEbWAkkSF4JJNtF+NJZDmJoSarSoP30WCsB3X636Rehd3CvxBj49FIJxEBFWhvcUjGSHVeU8Erck1bQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-riscv64-musl@0.45.0': + resolution: {integrity: sha512-Vdelft1sAEYojVGgcODEFXSWYQYlIvoyIGWebKCuUibd1tvS1TjTx413xG2ZLuHpYj45CkN/ztMLMX6jrgqpgg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxfmt/binding-linux-s390x-gnu@0.45.0': + resolution: {integrity: sha512-RR7xKgNpqwENnK0aYCGYg0JycY2n93J0reNjHyes+I9Gq52dH95x+CBlnlAQHCPfz6FGnKA9HirgUl14WO6o7w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-x64-gnu@0.45.0': + resolution: {integrity: sha512-U/QQ0+BQNSHxjuXR/utvXnQ50Vu5kUuqEomZvQ1/3mhgbBiMc2WU9q5kZ5WwLp3gnFIx9ibkveoRSe2EZubkqg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-x64-musl@0.45.0': + resolution: {integrity: sha512-o5TLOUCF0RWQjsIS06yVC+kFgp092/yLe6qBGSUvtnmTVw9gxjpdQSXc3VN5Cnive4K11HNstEZF8ROKHfDFSw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxfmt/binding-openharmony-arm64@0.45.0': + resolution: {integrity: sha512-RnGcV3HgPuOjsGx/k9oyRNKmOp+NBLGzZTdPDYbc19r7NGeYPplnUU/BfU35bX2Y/O4ejvHxcfkvW2WoYL/gsg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxfmt/binding-win32-arm64-msvc@0.45.0': + resolution: {integrity: sha512-v3Vj7iKKsUFwt9w5hsqIIoErKVoENC6LoqfDlteOQ5QMDCXihlqLoxpmviUhXnNncg4zV6U9BPwlBbwa+qm4wg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxfmt/binding-win32-ia32-msvc@0.45.0': + resolution: {integrity: sha512-N8yotPBX6ph0H3toF4AEpdCeVPrdcSetj+8eGiZGsrLsng3bs/Q5HPu4bbSxip5GBPx5hGbGHrZwH4+rcrjhHA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxfmt/binding-win32-x64-msvc@0.45.0': + resolution: {integrity: sha512-w5MMTRCK1dpQeRA+HHqXQXyN33DlG/N2LOYxJmaT4fJjcmZrbNnqw7SmIk7I2/a2493PPLZ+2E/Ar6t2iKVMug==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxlint/binding-android-arm-eabi@1.60.0': + resolution: {integrity: sha512-YdeJKaZckDQL1qa62a1aKq/goyq48aX3yOxaaWqWb4sau4Ee4IiLbamftNLU3zbePky6QsDj6thnSSzHRBjDfA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxlint/binding-android-arm64@1.60.0': + resolution: {integrity: sha512-7ANS7PpXCfq84xZQ8E5WPs14gwcuPcl+/8TFNXfpSu0CQBXz3cUo2fDpHT8v8HJN+Ut02eacvMAzTnc9s6X4tw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxlint/binding-darwin-arm64@1.60.0': + resolution: {integrity: sha512-pJsgd9AfplLGBm1fIr25V6V14vMrayhx4uIQvlfH7jWs2SZwSrvi3TfgfJySB8T+hvyEH8K2zXljQiUnkgUnfQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxlint/binding-darwin-x64@1.60.0': + resolution: {integrity: sha512-Ue1aXHX49ivwflKqGJc7zcd/LeLgbhaTcDCQStgx5x06AXgjEAZmvrlMuIkWd4AL4FHQe6QJ9f33z04Cg448VQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxlint/binding-freebsd-x64@1.60.0': + resolution: {integrity: sha512-YCyQzsQtusQw+gNRW9rRTifSO+Dt/+dtCl2NHoDMZqJlRTEZ/Oht9YnuporI9yiTx7+cB+eqzX3MtHHVHGIWhg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxlint/binding-linux-arm-gnueabihf@1.60.0': + resolution: {integrity: sha512-c7dxM2Zksa45Qw16i2iGY3Fti2NirJ38FrsBsKw+qcJ0OtqTsBgKJLF0xV+yLG56UH01Z8WRPgsw31e0MoRoGQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxlint/binding-linux-arm-musleabihf@1.60.0': + resolution: {integrity: sha512-ZWALoA42UYqBEP1Tbw9OWURgFGS1nWj2AAvLdY6ZcGx/Gj93qVCBKjcvwXMupZibYwFbi9s/rzqkZseb/6gVtQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxlint/binding-linux-arm64-gnu@1.60.0': + resolution: {integrity: sha512-tpy+1w4p9hN5CicMCxqNy6ymfRtV5ayE573vFNjp1k1TN/qhLFgflveZoE/0++RlkHikBz2vY545NWm/hp7big==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxlint/binding-linux-arm64-musl@1.60.0': + resolution: {integrity: sha512-eDYDXZGhQAXyn6GwtwiX/qcLS0HlOLPJ/+iiIY8RYr+3P8oKBmgKxADLlniL6FtWfE7pPk7IGN9/xvDEvDvFeg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxlint/binding-linux-ppc64-gnu@1.60.0': + resolution: {integrity: sha512-nxehly5XYBHUWI9VJX1bqCf9j/B43DaK/aS/T1fcxCpX3PA4Rm9BB54nPD1CKayT8xg6REN1ao+01hSRNgy8OA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxlint/binding-linux-riscv64-gnu@1.60.0': + resolution: {integrity: sha512-j1qf/NaUfOWQutjeoooNG1Q0zsK0XGmSu1uDLq3cctquRF3j7t9Hxqf/76ehCc5GEUAanth2W4Fa+XT1RFg/nw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxlint/binding-linux-riscv64-musl@1.60.0': + resolution: {integrity: sha512-YELKPRefQ/q/h3RUmeRfPCUhh2wBvgV1RyZ/F9M9u8cDyXsQW2ojv1DeWQTt466yczDITjZnIOg/s05pk7Ve2A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxlint/binding-linux-s390x-gnu@1.60.0': + resolution: {integrity: sha512-JkO3C6Gki7Y6h/MiIkFKvHFOz98/YWvQ4WYbK9DLXACMP2rjULzkeGyAzorJE5S1dzLQGFgeqvN779kSFwoV1g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxlint/binding-linux-x64-gnu@1.60.0': + resolution: {integrity: sha512-XjKHdFVCpZZZSWBCKyyqCq65s2AKXykMXkjLoKYODrD+f5toLhlwsMESscu8FbgnJQ4Y/dpR/zdazsahmgBJIA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxlint/binding-linux-x64-musl@1.60.0': + resolution: {integrity: sha512-js29ZWIuPhNWzY8NC7KoffEMEeWG105vbmm+8EOJsC+T/jHBiKIJEUF78+F/IrgEWMMP9N0kRND4Pp75+xAhKg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxlint/binding-openharmony-arm64@1.60.0': + resolution: {integrity: sha512-H+PUITKHk04stFpWj3x3Kg08Afp/bcXSBi0EhasR5a0Vw7StXHTzdl655PUI0fB4qdh2Wsu6Dsi+3ACxPoyQnA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxlint/binding-win32-arm64-msvc@1.60.0': + resolution: {integrity: sha512-WA/yc7f7ZfCefBXVzNHn1Ztulb1EFwNBb4jMZ6pjML0zz6pHujlF3Q3jySluz3XHl/GNeMTntG1seUBWVMlMag==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxlint/binding-win32-ia32-msvc@1.60.0': + resolution: {integrity: sha512-33YxL1sqwYNZXtn3MD/4dno6s0xeedXOJlT1WohkVD565WvohClZUr7vwKdAk954n4xiEWJkewiCr+zLeq7AeA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxlint/binding-win32-x64-msvc@1.60.0': + resolution: {integrity: sha512-JOro4ZcfBLamJCyfURQmOQByoorgOdx3ZjAkSqnb/CyG/i+lN3KoV5LAgk5ZAW6DPq7/Cx7n23f8DuTWXTWgyQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@parcel/watcher-android-arm64@2.5.1': resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} engines: {node: '>= 10.0.0'} @@ -3281,15 +3545,6 @@ packages: resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} - '@rollup/pluginutils@5.3.0': - resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rollup/rollup-android-arm-eabi@4.38.0': resolution: {integrity: sha512-ldomqc4/jDZu/xpYU+aRxo3V4mGCV9HeTgUBANI3oIQMOL+SsxB+S2lxMpkFp5UamSS3XuTMQVbsS24R4J4Qjg==} cpu: [arm] @@ -3920,6 +4175,36 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@turbo/darwin-64@2.9.6': + resolution: {integrity: sha512-X/56SnVXIQZBLKwniGTwEQTGmtE5brSACnKMBWpY3YafuxVYefrC2acamfjgxP7BG5w3I+6jf0UrLoSzgPcSJg==} + cpu: [x64] + os: [darwin] + + '@turbo/darwin-arm64@2.9.6': + resolution: {integrity: sha512-aalBeSl4agT/QtYGDyf/XLajedWzUC9Vg/pm/YO6QQ93vkQ91Vz5uK1ta5RbVRDozQSz4njxUNqRNmOXDzW+qw==} + cpu: [arm64] + os: [darwin] + + '@turbo/linux-64@2.9.6': + resolution: {integrity: sha512-YKi05jnNHaD7vevgYwahpzGwbsNNTwzU2c7VZdmdFm7+cGDP4oREUWSsainiMfRqjRuolQxBwRn8wf1jmu+YZA==} + cpu: [x64] + os: [linux] + + '@turbo/linux-arm64@2.9.6': + resolution: {integrity: sha512-02o/ZS69cOYEDczXvOB2xmyrtzjQ2hVFtWZK1iqxXUfzMmTjZK4UumrfNnjckSg+gqeBfnPRHa0NstA173Ik3g==} + cpu: [arm64] + os: [linux] + + '@turbo/windows-64@2.9.6': + resolution: {integrity: sha512-wVdQjvnBI15wB6JrA+43CtUtagjIMmX6XYO758oZHAsCNSxqRlJtdyujih0D8OCnwCRWiGWGI63zAxR0hO6s9g==} + cpu: [x64] + os: [win32] + + '@turbo/windows-arm64@2.9.6': + resolution: {integrity: sha512-1XUUyWW0W6FTSqGEhU8RHVqb2wP1SPkr7hIvBlMEwH9jr+sJQK5kqeosLJ/QaUv4ecSAd1ZhIrLoW7qslAzT4A==} + cpu: [arm64] + os: [win32] + '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -5403,11 +5688,6 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - concurrently@9.1.2: - resolution: {integrity: sha512-H9MWcoPsYddwbOGM6difjVwVZHl63nwMEwDJG/L7VGtuaJhb12h2caPG2tVPWs7emuYix252iGfqOyrz1GczTQ==} - engines: {node: '>=18'} - hasBin: true - confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} @@ -5770,15 +6050,6 @@ packages: supports-color: optional: true - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} engines: {node: '>=0.10.0'} @@ -8667,6 +8938,21 @@ packages: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} + oxfmt@0.45.0: + resolution: {integrity: sha512-0o/COoN9fY50bjVeM7PQsNgbhndKurBIeTIcspW033OumksjJJmIVDKjAk5HMwU/GHTxSOdGDdhJ6BRzGPmsHg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + oxlint@1.60.0: + resolution: {integrity: sha512-tnRzTWiWJ9pg3ftRWnD0+Oqh78L6ZSwcEudvCZaER0PIqiAnNyXj5N1dPwjmNpDalkKS9m/WMLN1CTPUBPmsgw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + oxlint-tsgolint: '>=0.18.0' + peerDependenciesMeta: + oxlint-tsgolint: + optional: true + p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -10259,10 +10545,6 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shell-quote@1.8.2: - resolution: {integrity: sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==} - engines: {node: '>= 0.4'} - side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -10793,6 +11075,10 @@ packages: resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} engines: {node: '>=12.0.0'} + tinypool@2.1.0: + resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==} + engines: {node: ^20.0.0 || >=22.0.0} + titleize@3.0.0: resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==} engines: {node: '>=12'} @@ -10959,6 +11245,10 @@ packages: tty-browserify@0.0.0: resolution: {integrity: sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==} + turbo@2.9.6: + resolution: {integrity: sha512-+v2QJey7ZUeUiuigkU+uFfklvNUyPI2VO2vBpMYJA+a1hKFLFiKtUYlRHdb3P9CrAvMzi0upbjI4WT+zKtqkBg==} + hasBin: true + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -11274,23 +11564,6 @@ packages: peerDependencies: vite: ^4.5.0 - vite-plugin-eslint2@5.1.0: - resolution: {integrity: sha512-fNuO/D7b+EZ5ejhuBA80tiaxWztZWDHc+lCZaXMOHgYfqFXq8WKmGwrudS+/jscp0UNAKGB71du+xoP8azSXiw==} - engines: {node: '>=18'} - peerDependencies: - '@types/eslint': ^7.0.0 || ^8.0.0 || ^9.0.0 - eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 - rolldown: ^1.0.0-0 || ^1.0.0 - rollup: ^2.0.0 || ^3.0.0 || ^4.0.0 - vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - '@types/eslint': - optional: true - rolldown: - optional: true - rollup: - optional: true - vite-plugin-html@3.2.2: resolution: {integrity: sha512-vb9C9kcdzcIo/Oc3CLZVS03dL5pDlOFuhGlZYDCJ840BhWl/0nGeZWf3Qy7NlOayscY4Cm/QRgULCQkEZige5Q==} peerDependencies: @@ -14596,6 +14869,120 @@ snapshots: '@oxc-project/types@0.124.0': {} + '@oxfmt/binding-android-arm-eabi@0.45.0': + optional: true + + '@oxfmt/binding-android-arm64@0.45.0': + optional: true + + '@oxfmt/binding-darwin-arm64@0.45.0': + optional: true + + '@oxfmt/binding-darwin-x64@0.45.0': + optional: true + + '@oxfmt/binding-freebsd-x64@0.45.0': + optional: true + + '@oxfmt/binding-linux-arm-gnueabihf@0.45.0': + optional: true + + '@oxfmt/binding-linux-arm-musleabihf@0.45.0': + optional: true + + '@oxfmt/binding-linux-arm64-gnu@0.45.0': + optional: true + + '@oxfmt/binding-linux-arm64-musl@0.45.0': + optional: true + + '@oxfmt/binding-linux-ppc64-gnu@0.45.0': + optional: true + + '@oxfmt/binding-linux-riscv64-gnu@0.45.0': + optional: true + + '@oxfmt/binding-linux-riscv64-musl@0.45.0': + optional: true + + '@oxfmt/binding-linux-s390x-gnu@0.45.0': + optional: true + + '@oxfmt/binding-linux-x64-gnu@0.45.0': + optional: true + + '@oxfmt/binding-linux-x64-musl@0.45.0': + optional: true + + '@oxfmt/binding-openharmony-arm64@0.45.0': + optional: true + + '@oxfmt/binding-win32-arm64-msvc@0.45.0': + optional: true + + '@oxfmt/binding-win32-ia32-msvc@0.45.0': + optional: true + + '@oxfmt/binding-win32-x64-msvc@0.45.0': + optional: true + + '@oxlint/binding-android-arm-eabi@1.60.0': + optional: true + + '@oxlint/binding-android-arm64@1.60.0': + optional: true + + '@oxlint/binding-darwin-arm64@1.60.0': + optional: true + + '@oxlint/binding-darwin-x64@1.60.0': + optional: true + + '@oxlint/binding-freebsd-x64@1.60.0': + optional: true + + '@oxlint/binding-linux-arm-gnueabihf@1.60.0': + optional: true + + '@oxlint/binding-linux-arm-musleabihf@1.60.0': + optional: true + + '@oxlint/binding-linux-arm64-gnu@1.60.0': + optional: true + + '@oxlint/binding-linux-arm64-musl@1.60.0': + optional: true + + '@oxlint/binding-linux-ppc64-gnu@1.60.0': + optional: true + + '@oxlint/binding-linux-riscv64-gnu@1.60.0': + optional: true + + '@oxlint/binding-linux-riscv64-musl@1.60.0': + optional: true + + '@oxlint/binding-linux-s390x-gnu@1.60.0': + optional: true + + '@oxlint/binding-linux-x64-gnu@1.60.0': + optional: true + + '@oxlint/binding-linux-x64-musl@1.60.0': + optional: true + + '@oxlint/binding-openharmony-arm64@1.60.0': + optional: true + + '@oxlint/binding-win32-arm64-msvc@1.60.0': + optional: true + + '@oxlint/binding-win32-ia32-msvc@1.60.0': + optional: true + + '@oxlint/binding-win32-x64-msvc@1.60.0': + optional: true + '@parcel/watcher-android-arm64@2.5.1': optional: true @@ -14851,14 +15238,6 @@ snapshots: estree-walker: 2.0.2 picomatch: 2.3.1 - '@rollup/pluginutils@5.3.0(rollup@4.38.0)': - dependencies: - '@types/estree': 1.0.8 - estree-walker: 2.0.2 - picomatch: 4.0.3 - optionalDependencies: - rollup: 4.38.0 - '@rollup/rollup-android-arm-eabi@4.38.0': optional: true @@ -15533,6 +15912,24 @@ snapshots: '@tsconfig/node16@1.0.4': optional: true + '@turbo/darwin-64@2.9.6': + optional: true + + '@turbo/darwin-arm64@2.9.6': + optional: true + + '@turbo/linux-64@2.9.6': + optional: true + + '@turbo/linux-arm64@2.9.6': + optional: true + + '@turbo/windows-64@2.9.6': + optional: true + + '@turbo/windows-arm64@2.9.6': + optional: true + '@tybys/wasm-util@0.10.1': dependencies: tslib: 2.8.1 @@ -17763,16 +18160,6 @@ snapshots: concat-map@0.0.1: {} - concurrently@9.1.2: - dependencies: - chalk: 4.1.2 - lodash: 4.17.21 - rxjs: 7.8.2 - shell-quote: 1.8.2 - supports-color: 8.1.1 - tree-kill: 1.2.2 - yargs: 17.7.2 - confbox@0.1.8: {} connect-history-api-fallback@1.6.0: {} @@ -18194,10 +18581,6 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.4.3: - dependencies: - ms: 2.1.3 - decamelize-keys@1.1.1: dependencies: decamelize: 1.2.0 @@ -22488,6 +22871,52 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 + oxfmt@0.45.0: + dependencies: + tinypool: 2.1.0 + optionalDependencies: + '@oxfmt/binding-android-arm-eabi': 0.45.0 + '@oxfmt/binding-android-arm64': 0.45.0 + '@oxfmt/binding-darwin-arm64': 0.45.0 + '@oxfmt/binding-darwin-x64': 0.45.0 + '@oxfmt/binding-freebsd-x64': 0.45.0 + '@oxfmt/binding-linux-arm-gnueabihf': 0.45.0 + '@oxfmt/binding-linux-arm-musleabihf': 0.45.0 + '@oxfmt/binding-linux-arm64-gnu': 0.45.0 + '@oxfmt/binding-linux-arm64-musl': 0.45.0 + '@oxfmt/binding-linux-ppc64-gnu': 0.45.0 + '@oxfmt/binding-linux-riscv64-gnu': 0.45.0 + '@oxfmt/binding-linux-riscv64-musl': 0.45.0 + '@oxfmt/binding-linux-s390x-gnu': 0.45.0 + '@oxfmt/binding-linux-x64-gnu': 0.45.0 + '@oxfmt/binding-linux-x64-musl': 0.45.0 + '@oxfmt/binding-openharmony-arm64': 0.45.0 + '@oxfmt/binding-win32-arm64-msvc': 0.45.0 + '@oxfmt/binding-win32-ia32-msvc': 0.45.0 + '@oxfmt/binding-win32-x64-msvc': 0.45.0 + + oxlint@1.60.0: + optionalDependencies: + '@oxlint/binding-android-arm-eabi': 1.60.0 + '@oxlint/binding-android-arm64': 1.60.0 + '@oxlint/binding-darwin-arm64': 1.60.0 + '@oxlint/binding-darwin-x64': 1.60.0 + '@oxlint/binding-freebsd-x64': 1.60.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.60.0 + '@oxlint/binding-linux-arm-musleabihf': 1.60.0 + '@oxlint/binding-linux-arm64-gnu': 1.60.0 + '@oxlint/binding-linux-arm64-musl': 1.60.0 + '@oxlint/binding-linux-ppc64-gnu': 1.60.0 + '@oxlint/binding-linux-riscv64-gnu': 1.60.0 + '@oxlint/binding-linux-riscv64-musl': 1.60.0 + '@oxlint/binding-linux-s390x-gnu': 1.60.0 + '@oxlint/binding-linux-x64-gnu': 1.60.0 + '@oxlint/binding-linux-x64-musl': 1.60.0 + '@oxlint/binding-openharmony-arm64': 1.60.0 + '@oxlint/binding-win32-arm64-msvc': 1.60.0 + '@oxlint/binding-win32-ia32-msvc': 1.60.0 + '@oxlint/binding-win32-x64-msvc': 1.60.0 + p-limit@2.3.0: dependencies: p-try: 2.2.0 @@ -24349,8 +24778,6 @@ snapshots: shebang-regex@3.0.0: {} - shell-quote@1.8.2: {} - side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -25159,6 +25586,8 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 + tinypool@2.1.0: {} + titleize@3.0.0: {} tmp@0.0.33: @@ -25379,6 +25808,15 @@ snapshots: tty-browserify@0.0.0: {} + turbo@2.9.6: + optionalDependencies: + '@turbo/darwin-64': 2.9.6 + '@turbo/darwin-arm64': 2.9.6 + '@turbo/linux-64': 2.9.6 + '@turbo/linux-arm64': 2.9.6 + '@turbo/windows-64': 2.9.6 + '@turbo/windows-arm64': 2.9.6 + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -25824,19 +26262,6 @@ snapshots: transitivePeerDependencies: - supports-color - vite-plugin-eslint2@5.1.0(@types/eslint@8.56.12)(eslint@9.23.0)(rolldown@1.0.0-rc.15)(rollup@4.38.0)(vite@8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5)): - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.38.0) - debug: 4.4.3 - eslint: 9.23.0 - vite: 8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5) - optionalDependencies: - '@types/eslint': 8.56.12 - rolldown: 1.0.0-rc.15 - rollup: 4.38.0 - transitivePeerDependencies: - - supports-color - vite-plugin-html@3.2.2(vite@8.0.8(@types/node@18.19.84)(less@4.2.2)(sass@1.86.0)(terser@5.39.0)(tsx@4.20.5)): dependencies: '@rollup/pluginutils': 4.2.1 diff --git a/scripts/format/oxfmt-changed.mjs b/scripts/format/oxfmt-changed.mjs new file mode 100644 index 0000000000..c4c1a4c86e --- /dev/null +++ b/scripts/format/oxfmt-changed.mjs @@ -0,0 +1,57 @@ +import { spawnSync } from 'node:child_process'; + +const allowedPrefixes = ['packages/', 'scripts/cli/']; +const allowedExtensions = new Set([ + '.js', + '.jsx', + '.ts', + '.tsx', + '.json', + '.css', + '.less', + '.scss' +]); + +function runGit(args) { + const result = spawnSync('git', args, { encoding: 'utf8' }); + if (result.status !== 0) { + throw new Error(result.stderr || `git ${args.join(' ')} failed`); + } + return result.stdout + .split('\n') + .map((line) => line.trim()) + .filter(Boolean); +} + +function isAllowedFile(file) { + if (!allowedPrefixes.some((prefix) => file.startsWith(prefix))) { + return false; + } + if ( + file.includes('/node_modules/') || + file.includes('/dist/') || + file.includes('/coverage/') + ) { + return false; + } + const dot = file.lastIndexOf('.'); + const ext = dot >= 0 ? file.slice(dot) : ''; + return allowedExtensions.has(ext); +} + +const mode = process.argv.includes('--check') ? '--check' : '--write'; + +const changedTracked = runGit(['diff', '--name-only', '--diff-filter=ACMR', 'HEAD']); +const changedUntracked = runGit(['ls-files', '--others', '--exclude-standard']); +const merged = [...new Set([...changedTracked, ...changedUntracked])].filter( + isAllowedFile +); + +if (merged.length === 0) { + console.log('No changed files matched oxfmt scope.'); + process.exit(0); +} + +const args = ['oxfmt', mode, ...merged]; +const run = spawnSync('pnpm', args, { stdio: 'inherit' }); +process.exit(run.status ?? 1); diff --git a/scripts/jest/README.md b/scripts/jest/README.md index 3d0d3bd88e..5855c20cfa 100644 --- a/scripts/jest/README.md +++ b/scripts/jest/README.md @@ -187,48 +187,35 @@ pnpm test:clean ## CI 流程(GitHub Actions) -### 执行步骤 +### 执行步骤(Turbo + 按包覆盖率) ``` ┌─────────────────────────────────────────────────────────┐ -│ test job (matrix: shard [1,2,3,4]) │ +│ test job │ │ │ -│ run-ci.sh $shard_index $shard_count │ +│ pnpm test:ci:turbo │ │ │ │ -│ ├── pnpm test:clean │ -│ ├── pnpm jest --ci --shard=$i/4 │ -│ │ ├── ee project ┐ │ -│ │ ├── ce project ├── 全部 project 的测试 │ -│ │ └── sqle project ┘ 被统一 shard │ -│ ├── coverage/report-$i.json │ -│ └── coverage/coverage-final-$i.json │ +│ └── turbo run test:ci --filter='./packages/*' │ +│ ├── packages/base/test:ci │ +│ ├── packages/dms-kit/test:ci │ +│ ├── packages/shared/test:ci │ +│ └── packages/sqle/test:ci │ +│ │ +│ 每个包独立产出 coverage/report.json │ └─────────────────────────────────────────────────────────┘ - ↓ + ↓ ┌─────────────────────────────────────────────────────────┐ │ report job (needs: test) │ │ │ -│ 下载 4 个 shard 的 artifacts │ -│ node merge-report-json.js │ -│ ├── 合并 4 份 report-*.json(测试计数) │ -│ └── 合并 4 份 coverage-final-*.json(覆盖率) │ -│ │ -│ → coverage-merged.json(最终报告) │ +│ 下载各包 coverage artifact │ +│ 对每个包分别执行 ArtiomTr/jest-coverage-report-action │ └─────────────────────────────────────────────────────────┘ ``` -### Shard 机制 - -Jest 的 `--shard=i/N` 将**所有 project 的测试文件总集合**平均分配到 N 个 runner 上。 - -- 添加新的 project 会自动被纳入分片,无需修改 CI 配置 -- `SHARD_COUNT` 环境变量控制 `merge-report-json.js` 的合并逻辑(默认值 4,与 matrix 一致) - ### 关键脚本 | 脚本 | 用途 | |---|---| -| `scripts/jest/run-ci.sh` | CI 单个 shard 的完整执行流程 | -| `scripts/jest/merge-report-json.js` | 合并所有 shard 的覆盖率与测试报告 | | `scripts/jest/custom-transform.js` | 条件编译 + Babel 的自定义 transformer | | `scripts/jest/run.sh` | 本地开发监视模式运行入口 | | `scripts/jest/run-coverage.sh` | 本地覆盖率报告运行入口 | @@ -309,7 +296,5 @@ CI= pnpm jest --updateSnapshot --testPathPattern="" - [`jest.config.js`](../../jest.config.js) — Jest Projects 完整配置 - [`scripts/jest/custom-transform.js`](./custom-transform.js) — 条件编译 transformer -- [`scripts/jest/run-ci.sh`](./run-ci.sh) — CI shard 执行脚本 -- [`scripts/jest/merge-report-json.js`](./merge-report-json.js) — 报告合并脚本 - [`.github/workflows/main.yml`](../../.github/workflows/main.yml) — GitHub Actions CI 配置 - [`.cursor/commands/unit-testing.md`](../../.cursor/commands/unit-testing.md) — 单元测试编写规范 diff --git a/scripts/jest/merge-report-json.js b/scripts/jest/merge-report-json.js deleted file mode 100644 index ff05e65c9c..0000000000 --- a/scripts/jest/merge-report-json.js +++ /dev/null @@ -1,86 +0,0 @@ -// https://github.com/ArtiomTr/jest-coverage-report-action/issues/244 - -const path = require('path'); -const fs = require('fs'); -const istanbul = require('istanbul-lib-coverage'); - -const SHARD_COUNT = parseInt(process.env.SHARD_COUNT || '4', 10); - -const finalReportJSONFilePath = path.resolve( - process.cwd(), - 'coverage-merged.json' -); - -for (let i = 1; i <= SHARD_COUNT; i++) { - const reportPath = path.resolve( - process.cwd(), - `coverage/report-${i}.json` - ); - if (!fs.existsSync(reportPath)) { - console.error(`not found report-${i}.json: ${reportPath}`); - process.exit(1); - } -} - -const coverageJsonReport = Array.from({ length: SHARD_COUNT }, (_, i) => - require(path.resolve(process.cwd(), `coverage/report-${i + 1}.json`)) -).reduce( - (acc, cur) => ({ - numFailedTestSuites: - (acc.numFailedTestSuites ?? 0) + cur.numFailedTestSuites, - numFailedTests: (acc.numFailedTests ?? 0) + cur.numFailedTests, - numPassedTestSuites: - (acc.numPassedTestSuites ?? 0) + cur.numPassedTestSuites, - numPassedTests: (acc.numPassedTests ?? 0) + cur.numPassedTests, - numPendingTestSuites: - (acc.numPendingTestSuites ?? 0) + cur.numPendingTestSuites, - numPendingTests: (acc.numPendingTests ?? 0) + cur.numPendingTests, - numRuntimeErrorTestSuites: - (acc.numRuntimeErrorTestSuites ?? 0) + cur.numRuntimeErrorTestSuites, - numTodoTests: (acc.numTodoTests ?? 0) + cur.numTodoTests, - numTotalTestSuites: (acc.numTotalTestSuites ?? 0) + cur.numTotalTestSuites, - numTotalTests: (acc.numTotalTests ?? 0) + cur.numTotalTests, - success: (acc.success ?? true) && cur.success - }), - {} -); - -const coverageMergedDir = path.resolve(process.cwd(), 'coverage-merged'); -if (!fs.existsSync(coverageMergedDir)) { - fs.mkdirSync(coverageMergedDir); -} - -for (let i = 1; i <= SHARD_COUNT; i++) { - const src = path.resolve( - process.cwd(), - `coverage/coverage-final-${i}.json` - ); - if (fs.existsSync(src)) { - fs.renameSync( - src, - path.resolve(coverageMergedDir, `coverage-map-${i}.json`) - ); - } -} - -const mergeCoverageReport = istanbul.createCoverageMap({}); - -fs.readdirSync(coverageMergedDir).forEach((file) => { - const json = fs.readFileSync(path.resolve(coverageMergedDir, file)); - mergeCoverageReport.merge(JSON.parse(json)); -}); - -coverageJsonReport.coverageMap = mergeCoverageReport; - -fs.writeFile( - finalReportJSONFilePath, - JSON.stringify(coverageJsonReport), - (err) => { - if (err) { - console.error(err); - process.exit(1); - } - - console.log('Coverage report merged to ' + finalReportJSONFilePath); - } -); diff --git a/scripts/jest/run-ci.sh b/scripts/jest/run-ci.sh deleted file mode 100644 index 0d04ad862f..0000000000 --- a/scripts/jest/run-ci.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -shard_index=${1:-1} -shard_count=${2:-1} - -pnpm test:clean -pnpm jest --ci --maxWorkers=50% --silent --watchAll=false --coverage --coverageDirectory=coverage --json --testLocationInResults --outputFile=coverage/report.json --shard=$shard_index/$shard_count -if [ $? -ne 0 ]; then - echo "Jest test failed." - exit 1 -fi - -mv coverage/report.json coverage/report-$shard_index.json -if [ $? -ne 0 ]; then - echo "Move report.json failed." - exit 1 -fi - -mv coverage/coverage-final.json coverage/coverage-final-$shard_index.json -if [ $? -ne 0 ]; then - echo "Move coverage-final.json failed." - exit 1 -fi - -rm -rf coverage/lcov-report coverage/clover.xml coverage/lcov.info -if [ $? -ne 0 ]; then - echo "Jest test failed." - exit 1 -fi diff --git a/tsconfig.json b/tsconfig.json index 6653e57972..16410eab30 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,21 +1,6 @@ { + "extends": "./packages/tooling-config/tsconfig/base.json", "compilerOptions": { - "target": "ESNext", - "useDefineForClassFields": true, - "lib": ["DOM", "DOM.Iterable", "ESNext"], - "allowJs": false, - "skipLibCheck": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "module": "esnext", - "moduleResolution": "bundler", - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx", - "types": ["jest", "node", "testing-library__jest-dom"], "paths": { "~/*": ["./src/*"] } diff --git a/turbo.json b/turbo.json new file mode 100644 index 0000000000..7de8309d45 --- /dev/null +++ b/turbo.json @@ -0,0 +1,49 @@ +{ + "$schema": "https://turbo.build/schema.json", + "tasks": { + "build": { + "dependsOn": ["^build"], + "outputs": ["dist/**", "lib/**", "es/**", "build/**"] + }, + "test:ci": { + "dependsOn": [], + "cache": false, + "outputs": ["coverage/**"] + }, + "oxlint": { + "dependsOn": [], + "cache": false, + "outputs": [] + }, + "typecheck": { + "dependsOn": [], + "cache": false, + "outputs": [] + }, + "stylelint": { + "dependsOn": [], + "cache": false, + "outputs": [] + }, + "check": { + "dependsOn": ["oxlint", "typecheck", "stylelint"], + "cache": false, + "outputs": [] + }, + "start": { + "dependsOn": [], + "cache": false, + "persistent": true + }, + "start:ee": { + "dependsOn": [], + "cache": false, + "persistent": true + }, + "start:demo": { + "dependsOn": [], + "cache": false, + "persistent": true + } + } +} From 905373b87dcb7d034ec702631ea40fce85297228 Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Wed, 15 Apr 2026 14:28:05 +0800 Subject: [PATCH 05/36] fix(tsconfig): remove deprecated baseUrl usage to stabilize CI typecheck across TS versions --- .github/workflows/main.yml | 43 +++++++++++------------ packages/icons/tsconfig.json | 7 ++-- scripts/cli/create-dms-page/tsconfig.json | 2 +- scripts/cli/dms-kit-publish/tsconfig.json | 2 +- 4 files changed, 25 insertions(+), 29 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dd0b899fd7..6725d25340 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -24,6 +24,21 @@ jobs: test: runs-on: ubuntu-latest if: ${{ !contains(github.event.pull_request.title, '[skip checker]') }} + strategy: + matrix: + include: + - package_name: base + package_path: packages/base + artifact_name: coverage-artifacts-base + - package_name: '@actiontech/dms-kit' + package_path: packages/dms-kit + artifact_name: coverage-artifacts-dms-kit + - package_name: '@actiontech/shared' + package_path: packages/shared + artifact_name: coverage-artifacts-shared + - package_name: sqle + package_path: packages/sqle + artifact_name: coverage-artifacts-sqle steps: - name: Checkout repository uses: actions/checkout@v4 @@ -31,32 +46,14 @@ jobs: - name: Install dependencies uses: ./.github/actions/catch-install-pnpm - - name: Run package test suites - run: pnpm test:ci:turbo + - name: Run package test suite + run: pnpm turbo run test:ci --filter=${{ matrix.package_name }} - - name: Upload base coverage artifact + - name: Upload coverage artifact uses: actions/upload-artifact@v4 with: - name: coverage-artifacts-base - path: packages/base/coverage/ - - - name: Upload dms-kit coverage artifact - uses: actions/upload-artifact@v4 - with: - name: coverage-artifacts-dms-kit - path: packages/dms-kit/coverage/ - - - name: Upload shared coverage artifact - uses: actions/upload-artifact@v4 - with: - name: coverage-artifacts-shared - path: packages/shared/coverage/ - - - name: Upload sqle coverage artifact - uses: actions/upload-artifact@v4 - with: - name: coverage-artifacts-sqle - path: packages/sqle/coverage/ + name: ${{ matrix.artifact_name }} + path: ${{ matrix.package_path }}/coverage/ report: runs-on: ubuntu-latest diff --git a/packages/icons/tsconfig.json b/packages/icons/tsconfig.json index 6cec366d2e..574fae7d54 100644 --- a/packages/icons/tsconfig.json +++ b/packages/icons/tsconfig.json @@ -6,11 +6,10 @@ "esModuleInterop": true, "resolveJsonModule": true, "jsx": "react-jsx", - "baseUrl": "./", "paths": { - "@@/*": [".dumi/tmp/*"], - "@actiontech/icons": ["src"], - "@actiontech/icons/*": ["src/*", "*"] + "@@/*": ["./.dumi/tmp/*"], + "@actiontech/icons": ["./src"], + "@actiontech/icons/*": ["./src/*", "./*"] } }, "include": [".dumirc.ts", "src/**/*"] diff --git a/scripts/cli/create-dms-page/tsconfig.json b/scripts/cli/create-dms-page/tsconfig.json index af9c7a1415..aeaf722c93 100644 --- a/scripts/cli/create-dms-page/tsconfig.json +++ b/scripts/cli/create-dms-page/tsconfig.json @@ -27,7 +27,7 @@ "module": "CommonJS" /* Specify what module code is generated. */, "rootDir": "./src" /* Specify the root folder within your source files. */, "moduleResolution": "Node" /* Specify how TypeScript looks up a file from a given module specifier. */, - "baseUrl": "./" /* Specify the base directory to resolve non-relative module names. */, + // "baseUrl": "./" /* removed: deprecated in TS6 */, // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [ // "./src", diff --git a/scripts/cli/dms-kit-publish/tsconfig.json b/scripts/cli/dms-kit-publish/tsconfig.json index af9c7a1415..aeaf722c93 100644 --- a/scripts/cli/dms-kit-publish/tsconfig.json +++ b/scripts/cli/dms-kit-publish/tsconfig.json @@ -27,7 +27,7 @@ "module": "CommonJS" /* Specify what module code is generated. */, "rootDir": "./src" /* Specify the root folder within your source files. */, "moduleResolution": "Node" /* Specify how TypeScript looks up a file from a given module specifier. */, - "baseUrl": "./" /* Specify the base directory to resolve non-relative module names. */, + // "baseUrl": "./" /* removed: deprecated in TS6 */, // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [ // "./src", From fb3bbf0bb81874a23d267cd584734d451046e296 Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Wed, 15 Apr 2026 14:55:54 +0800 Subject: [PATCH 06/36] fix: test error --- packages/tooling-config/jest/create-jest-config.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/tooling-config/jest/create-jest-config.js b/packages/tooling-config/jest/create-jest-config.js index 70d9073bbc..6ce77afdbc 100644 --- a/packages/tooling-config/jest/create-jest-config.js +++ b/packages/tooling-config/jest/create-jest-config.js @@ -1,5 +1,7 @@ import path from 'node:path'; +process.env.TZ = 'Asia/Shanghai'; + const CE_TEST_FILE_RE = '\\.ce(\\.[^./]+)*\\.test\\.[jt]sx?$'; const SQLE_TEST_FILE_RE = '\\.sqle(\\.[^./]+)*\\.test\\.[jt]sx?$'; const PROVISION_TEST_FILE_RE = '\\.provision(\\.[^./]+)*\\.test\\.[jt]sx?$'; From cd0abbb88e0e2d49979f19a33eccbb2704817921 Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Tue, 28 Apr 2026 14:51:18 +0800 Subject: [PATCH 07/36] refactor(test): run root tests per package and remove legacy root jest runner --- jest.config.js | 150 --------------------------- package.json | 4 +- packages/base/package.json | 1 + packages/dms-kit/package.json | 1 + packages/shared/package.json | 1 + packages/sqle/package.json | 1 + scripts/jest/README.md | 187 ++++++++++++++++------------------ scripts/jest/run-coverage.sh | 26 ----- scripts/jest/run.sh | 29 ------ 9 files changed, 93 insertions(+), 307 deletions(-) delete mode 100644 jest.config.js delete mode 100644 scripts/jest/run-coverage.sh delete mode 100644 scripts/jest/run.sh diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 6515087c59..0000000000 --- a/jest.config.js +++ /dev/null @@ -1,150 +0,0 @@ -process.env.TZ = 'Asia/Shanghai'; - -const path = require('path'); - -const { compilerOptions } = require('./tsconfig.json'); -const { pathsToModuleNameMapper } = require('ts-jest'); - -compilerOptions.paths['~/*'][0] = path.resolve(compilerOptions.paths['~/*'][0]); - -const sharedModuleNameMapper = { - '.+\\.(css|style|less|sass|scss|ttf|woff|woff2)$': 'identity-obj-proxy', - '@ant-design/plots': - '/packages/shared/lib/testUtil/mockModule/mockAntDesignPlots.jsx', - 'monaco-editor': - '/packages/shared/lib/testUtil/mockModule/mockEditor.jsx', - '@monaco-editor/react': - '/packages/shared/lib/testUtil/mockModule/mockEditor.jsx', - '@uiw/react-md-editor': - '/packages/shared/lib/testUtil/mockModule/mockEditor.jsx', - '@actiontech/(.*)': '/packages/$1', - '@react-sigma/core(.*)$': - '/packages/shared/lib/testUtil/mockModule/mockSigmaCore.tsx', - '@react-sigma/graph-search$': - '/packages/shared/lib/testUtil/mockModule/mockSigmaGraphSearch.tsx', - ...pathsToModuleNameMapper(compilerOptions.paths) -}; - -const sharedIgnorePatterns = ['/node_modules/', '/demo/', '/demos/']; - -// Naming conventions for condition-specific test files: -// *.ce.test.{ts,tsx} → CE project (ee=false, ce=true, sqle=true, dms=false) 不要强制匹配 ce.test, ce.[可选项].test.{ts,tsx} -// *.sqle.test.{ts,tsx} → EE project (ee=true, ce=false, sqle=true, dms=false) 同上 -// *.provision.test.{ts,tsx} → PROVISION project (ee=true, ce=false, sqle=false, provision=true, dms=false) 同上 -// *.test.{ts,tsx} → DMS project (ee=true, ce=false, sqle=true, provision=true, dms=true) [default] 同上 -// 实现:`.ce.` / `.sqle.` / `.provision.` 与 `.test.` 之间可有零段或多段 `.xxx.`(正则见下方 *_TEST_FILE_RE)。 -const CE_TEST_FILE_RE = '\\.ce(\\.[^./]+)*\\.test\\.[jt]sx?$'; -const SQLE_TEST_FILE_RE = '\\.sqle(\\.[^./]+)*\\.test\\.[jt]sx?$'; -const PROVISION_TEST_FILE_RE = '\\.provision(\\.[^./]+)*\\.test\\.[jt]sx?$'; - -const sharedProjectConfig = { - transform: { - '^.+\\.(ts|tsx|js|jsx)$': '/scripts/jest/custom-transform.js', - '^.+\\.(png|jpg|jpeg|css|json)$': '/scripts/jest/file-transform.js' - }, - transformIgnorePatterns: [ - '/dist/', - 'node_modules/(?!(?:.pnpm/)?(@react-sigma|.+/es))[^/]+?/(?!(es|node_modules)/)' - ], - moduleFileExtensions: ['ts', 'tsx', 'js', 'json', 'jsx', 'node'], - testEnvironment: 'jest-environment-jsdom', - resetMocks: true, - moduleNameMapper: sharedModuleNameMapper, - collectCoverageFrom: [ - 'packages/**/{src,lib}/{page,components,hooks,global,store,utils}/**/*.{ts,tsx}', - 'packages/**/src/App.tsx', - 'packages/shared/api/common/**', - '!packages/**/index.type.ts', - '!packages/**/index.enum.ts', - '!packages/sqle/src/page/SqlAnalyze/SqlAnalyze/ProcessListCom/**', - '!packages/shared/lib/hooks/usePrompt/index.tsx', - '!packages/sqle/src/page/Knowledge/Graph/components/**', - '!packages/**/demo/**', - '!packages/**/demos/**' - ], - setupFilesAfterEnv: ['/jest-setup.ts'] -}; - -module.exports = { - projects: [ - { - ...sharedProjectConfig, - displayName: 'dms', - globals: { - TEST_CONDITIONS: { - ee: true, - ce: false, - sqle: true, - provision: true, - dms: true - } - }, - // Default tests only: exclude CE / sqle / provision condition tests (dedicated projects) - testPathIgnorePatterns: [ - ...sharedIgnorePatterns, - CE_TEST_FILE_RE, - SQLE_TEST_FILE_RE, - PROVISION_TEST_FILE_RE - ] - }, - { - ...sharedProjectConfig, - displayName: 'sqle-ce', - globals: { - TEST_CONDITIONS: { - ee: false, - ce: true, - sqle: true, - provision: false, - dms: false - } - }, - testRegex: CE_TEST_FILE_RE, - testPathIgnorePatterns: sharedIgnorePatterns - }, - { - ...sharedProjectConfig, - displayName: 'sqle-ee', - globals: { - TEST_CONDITIONS: { - ee: true, - ce: false, - sqle: true, - provision: false, - dms: false - } - }, - testRegex: SQLE_TEST_FILE_RE, - // e.g. *.ce.sqle.test.* belongs to CE, not EE - testPathIgnorePatterns: [...sharedIgnorePatterns, CE_TEST_FILE_RE] - }, - { - ...sharedProjectConfig, - displayName: 'provision', - globals: { - TEST_CONDITIONS: { - ee: true, - ce: false, - sqle: false, - provision: true, - dms: false - } - }, - testRegex: PROVISION_TEST_FILE_RE, - testPathIgnorePatterns: [...sharedIgnorePatterns, CE_TEST_FILE_RE] - } - ], - reporters: [ - 'default', - [ - 'jest-slow-test-reporter', - { - numTests: 8, - outputDirectory: 'reports', - outputName: 'report.xml', - color: true, - warnSlowerThan: 6000 - } - ] - ] -}; diff --git a/package.json b/package.json index eb7d5748ba..30c98687f9 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ "stylelint": "stylelint packages/*/{src,lib}/**/{*.less,style.ts,element.ts}", "ts-check": "tsc --noEmit", "checker": "pnpm check:turbo", - "test": "sh ./scripts/jest/run.sh", - "test:c": "sh ./scripts/jest/run-coverage.sh", + "test": "pnpm --parallel --filter base --filter @actiontech/dms-kit --filter @actiontech/shared --filter sqle run test:run", + "test:c": "pnpm --parallel --filter base --filter @actiontech/dms-kit --filter @actiontech/shared --filter sqle run test:c", "test:ci": "turbo run test:ci --filter='./packages/*'", "test:ci:turbo": "pnpm test:ci", "test:clean": "jest --clearCache", diff --git a/packages/base/package.json b/packages/base/package.json index 0cf4c1ba6c..6adc38c69a 100644 --- a/packages/base/package.json +++ b/packages/base/package.json @@ -16,6 +16,7 @@ "check": "echo \"base check\"", "test": "jest --watchAll=true", "test:c": "jest --watchAll=false --coverage --coverageDirectory=coverage", + "test:run": "jest --watchAll=false --color", "test:ci": "jest --ci --watchAll=false --coverage --coverageDirectory=coverage --json --outputFile=coverage/report.json --color --silent --testLocationInResults" }, "dependencies": { diff --git a/packages/dms-kit/package.json b/packages/dms-kit/package.json index 8e8b8f24fa..c3f0cfa395 100644 --- a/packages/dms-kit/package.json +++ b/packages/dms-kit/package.json @@ -28,6 +28,7 @@ "check": "echo \"dms-kit check\"", "test": "jest --watchAll=true", "test:c": "jest --watchAll=false --coverage --coverageDirectory=coverage", + "test:run": "jest --watchAll=false --color", "test:ci": "jest --ci --watchAll=false --coverage --coverageDirectory=coverage --json --outputFile=coverage/report.json --color --silent --testLocationInResults" }, "dependencies": { diff --git a/packages/shared/package.json b/packages/shared/package.json index 340adcbb99..126c435ec9 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -11,6 +11,7 @@ "check": "echo \"shared check\"", "test": "jest --watchAll=true", "test:c": "jest --watchAll=false --coverage --coverageDirectory=coverage", + "test:run": "jest --watchAll=false --color", "test:ci": "jest --ci --watchAll=false --coverage --coverageDirectory=coverage --json --outputFile=coverage/report.json --color --silent --testLocationInResults" }, "dependencies": { diff --git a/packages/sqle/package.json b/packages/sqle/package.json index 8e8dad5573..b7cdb976b6 100644 --- a/packages/sqle/package.json +++ b/packages/sqle/package.json @@ -37,6 +37,7 @@ "check": "echo \"sqle check\"", "test": "jest --watchAll=true", "test:c": "jest --watchAll=false --coverage --coverageDirectory=coverage", + "test:run": "jest --watchAll=false --color", "test:ci": "jest --ci --watchAll=false --coverage --coverageDirectory=coverage --json --outputFile=coverage/report.json --color --silent --testLocationInResults", "eject": "react-scripts eject" }, diff --git a/scripts/jest/README.md b/scripts/jest/README.md index 5855c20cfa..04434d1812 100644 --- a/scripts/jest/README.md +++ b/scripts/jest/README.md @@ -37,40 +37,36 @@ menus = genMenuItemsWithMenuStructTree(DMS_ALL_MENUS, DMS_MENU_STRUCT); ### 架构图 ``` -pnpm jest +pnpm jest(包级别) │ -├── project: ee (dms=true) → 运行 *.test.tsx / *.ee.test.tsx -├── project: ce (ce=true) → 运行 *.ce.test.tsx / *.ce.sqle.test.tsx -└── project: sqle (dms=false) → 运行 *.sqle.test.tsx +├── project: dms (dms=true) → 运行 *.test.tsx / *.ee.test.tsx +├── project: sqle-ce (ce=true) → 运行 *.ce.test.tsx / *.ce.sqle.test.tsx +└── project: sqle-ee (sqle=true) → 运行 *.sqle.test.tsx │ └── 每个 project 由 custom-transform.js 用对应条件编译源代码 ``` --- -## 三个 Project 的配置 +## Project 配置(`packages/tooling-config/jest/create-jest-config.js`) -| Project | displayName | ee | ce | sqle | provision | dms | demo | -|---|---|---|---|---|---|---|---| -| EE(默认)| `ee` | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ | -| CE(社区版)| `ce` | ❌ | ✅ | ✅ | ❌ | ❌ | ❌ | -| SQLE-only | `sqle` | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | +| Project | displayName | ee | ce | sqle | provision | dms | +|---|---|---|---|---|---|---| +| EE(默认)| `dms` | ✅ | ❌ | ✅ | ✅ | ✅ | +| CE(社区版)| `sqle-ce` | ❌ | ✅ | ✅ | ❌ | ❌ | +| SQLE-only | `sqle-ee` | ✅ | ❌ | ✅ | ❌ | ❌ | +| Provision | `provision` | ✅ | ❌ | ❌ | ✅ | ❌ | -### 各 Project 的文件匹配规则 +各包通过 `enabledProjects` 按需开启所需 project: -**ee project**(默认): - -- 包含:`*.test.tsx`、`*.test.ts`(所有普通测试文件) -- 排除:`*.ce.test.*`、`*.sqle.test.*`(这些由其他 project 处理) - -**ce project**: - -- 仅包含:`*.ce.test.{ts,tsx}`、`*.ce.sqle.test.{ts,tsx}` - -**sqle project**: - -- 仅包含:`*.sqle.test.{ts,tsx}` -- 排除:`*.ce.sqle.test.*`(已归属 ce project) +```js +// packages/base/jest.config.mjs +export default createJestConfig({ + packageRoot, + enabledProjects: ['dms', 'sqle-ce', 'sqle-ee'], + collectCoverageFrom: [ ... ] +}); +``` --- @@ -96,85 +92,72 @@ babel-jest (babel-preset-react-app) ← JSX / TypeScript 转换 Jest 可执行的 JS 代码 ``` -### 缓存 key 策略 - -```javascript -getCacheKey: (sourceText, sourcePath, options) => { - const conditions = options?.config?.globals?.TEST_CONDITIONS ?? getDefaultConditions(); - const baseKey = babelJestConfig.getCacheKey(sourceText, sourcePath, options); - return crypto.createHash('md5') - .update(baseKey) - .update(JSON.stringify(conditions)) - .digest('hex'); -} -``` - -同一源文件在 `ee` 和 `sqle` project 下会生成**不同的缓存 key**,确保两套编译结果各自独立存储。 - --- ## 测试文件命名约定 | 文件名 | 归属 Project | 对应源码分支 | |---|---|---| -| `Foo.test.tsx` | ee | `#else` / 默认 EE/DMS 分支 | -| `Foo.ee.test.tsx` | ee | 同上(显式标注) | -| `Foo.ce.test.tsx` | ce | `#if [ce]` / `#if [!ee]` 分支 | -| `Foo.ce.sqle.test.tsx` | ce | `#if [ce && sqle]` 组合条件分支 | -| `Foo.sqle.test.tsx` | sqle | `#if [sqle && !dms]` 分支 | +| `Foo.test.tsx` | dms | `#else` / 默认 EE/DMS 分支 | +| `Foo.ee.test.tsx` | dms | 同上(显式标注) | +| `Foo.ce.test.tsx` | sqle-ce | `#if [ce]` / `#if [!ee]` 分支 | +| `Foo.ce.sqle.test.tsx` | sqle-ce | `#if [ce && sqle]` 组合条件分支 | +| `Foo.sqle.test.tsx` | sqle-ee | `#if [sqle && !dms]` 分支 | **实际示例**: ``` packages/base/src/page/Nav/SideMenu/MenuList/ ├── index.tsx # 源文件(含 #if [sqle && !dms] 分支) -├── index.test.tsx # ee project → dms=true,DMS 模式(空菜单) -└── index.sqle.test.tsx # sqle project → dms=false,SQLE 专属菜单 +├── index.test.tsx # dms project → dms=true,DMS 模式(空菜单) +└── index.sqle.test.tsx # sqle-ee project → dms=false,SQLE 专属菜单 ``` --- ## 本地运行命令 -所有命令均通过 `package.json` scripts 调用: - -### 开发时监视运行 +### 根目录(全量,按包并行执行) ```bash -# 运行全部 projects(ee + ce + sqle) +# 运行全部包的测试(非 watch) pnpm test -# 按路径过滤(推荐:开发时只跑相关文件) -pnpm test packages/base/src/page/Nav/SideMenu/MenuList +# 全部包收集覆盖率(各包独立输出 packages//coverage/) +pnpm test:c +``` + +### 单包开发(watch 模式) -# 指定 project + 路径(sqle / ce / ee) -pnpm test packages/base/src/page/Nav/SideMenu/MenuList sqle +```bash +# 进入特定包目录开启 watch +pnpm --filter base test +pnpm --filter sqle test +pnpm --filter @actiontech/shared test -# 只跑某个 project 的全部测试 -pnpm test "" sqle +# 单包覆盖率 +pnpm --filter base test:c ``` -### 覆盖率报告(本地) +### 单包直接调用 jest(路径过滤、project 选择) ```bash -# 全量覆盖率 -pnpm test:c - -# 路径过滤 -pnpm test:c packages/base/src/page/Nav/SideMenu/MenuList +# 指定测试文件路径 +pnpm --filter base jest -- --testPathPattern="SideMenu/MenuList" # 指定 project -pnpm test:c packages/base/src/page/Nav/SideMenu/MenuList sqle +pnpm --filter base jest -- --selectProjects sqle-ee + +# 指定 project + 路径 +pnpm --filter base jest -- --selectProjects sqle-ee --testPathPattern="SideMenu/MenuList" ``` ### 更新快照 ```bash -# 更新指定文件的快照(需取消 CI 环境变量) -CI= pnpm jest --updateSnapshot --testPathPattern="MenuList/index" - -# 更新指定 project 的快照 -CI= pnpm jest --selectProjects sqle --updateSnapshot --testPathPattern="MenuList/index" +# 在对应包目录下更新快照(需取消 CI 环境变量) +CI= pnpm --filter base jest -- --updateSnapshot --testPathPattern="MenuList/index" +CI= pnpm --filter base jest -- --selectProjects sqle-ee --updateSnapshot --testPathPattern="MenuList/index" ``` ### 清理缓存 @@ -212,13 +195,17 @@ pnpm test:clean └─────────────────────────────────────────────────────────┘ ``` -### 关键脚本 +--- + +## 各脚本对比 -| 脚本 | 用途 | -|---|---| -| `scripts/jest/custom-transform.js` | 条件编译 + Babel 的自定义 transformer | -| `scripts/jest/run.sh` | 本地开发监视模式运行入口 | -| `scripts/jest/run-coverage.sh` | 本地覆盖率报告运行入口 | +| 脚本 | 执行方式 | watch | 覆盖率 | 用途 | +|---|---|---|---|---| +| `pnpm test`(根目录) | pnpm 并行,按包 | ❌ | ❌ | 本地全量验证 | +| `pnpm test:c`(根目录) | pnpm 并行,按包 | ❌ | ✅ 各包独立 | 本地覆盖率报告 | +| `pnpm --filter test` | 单包 jest | ✅ | ❌ | 开发时 watch | +| `pnpm --filter test:c` | 单包 jest | ❌ | ✅ | 单包覆盖率 | +| `pnpm test:ci:turbo` | turbo 并行,按包 | ❌ | ✅ + json | CI 流水线 | --- @@ -226,44 +213,44 @@ pnpm test:clean 当出现新的条件组合(例如需要专门覆盖 `provision=true, dms=false` 的代码分支)时: -### 第一步:在 `jest.config.js` 中添加 project +### 第一步:在 `packages/tooling-config/jest/create-jest-config.js` 中注册 project ```javascript -{ - ...sharedProjectConfig, - displayName: 'provision', - globals: { - TEST_CONDITIONS: { - ee: true, ce: false, sqle: true, - provision: true, dms: false, demo: false - } - }, - testMatch: ['**/*.provision.test.{ts,tsx}'], - testPathIgnorePatterns: sharedIgnorePatterns -} +const PROJECT_CONDITIONS = { + // ... 已有 project + 'my-new-project': { + ee: true, ce: false, sqle: false, provision: true, dms: false + } +}; ``` -### 第二步:按约定命名测试文件 +### 第二步:在需要的包的 `jest.config.mjs` 中启用 -``` -Foo.provision.test.tsx +```js +export default createJestConfig({ + packageRoot, + enabledProjects: ['dms', 'sqle-ce', 'my-new-project'], + collectCoverageFrom: [ ... ] +}); ``` -### 第三步:编写测试 +### 第三步:按约定命名测试文件 -测试文件无需任何特殊配置,直接按普通测试文件结构编写即可。 +``` +Foo.my-new-project.test.tsx +``` ### 第四步:验证 ```bash -pnpm test "" provision +pnpm --filter base jest -- --selectProjects my-new-project ``` --- ## 常见问题 -### Q:为何在 ee project 下 MenuList 的菜单是空的? +### Q:为何在 dms project 下 MenuList 的菜单是空的? **A**:`dms=true` 时源码走 `#else` 分支,使用 `DMS_ALL_MENUS` 和 `DMS_MENU_STRUCT`。这两个变量在本仓库中均为空数组(DMS 菜单由 `dms-ui-ee` 仓库维护)。这是预期行为,对应的 `index.test.tsx` 已验证此空菜单状态。 @@ -272,29 +259,29 @@ pnpm test "" provision **A**:运行时 Jest 会在每行测试结果前显示 project 名,例如: ``` -PASS ee packages/base/src/page/Nav/SideMenu/MenuList/index.test.tsx -PASS sqle packages/base/src/page/Nav/SideMenu/MenuList/index.sqle.test.tsx +PASS dms packages/base/src/page/Nav/SideMenu/MenuList/index.test.tsx +PASS sqle-ee packages/base/src/page/Nav/SideMenu/MenuList/index.sqle.test.tsx ``` -也可以用 `--selectProjects sqle` 明确指定只运行 sqle project。 +也可以用 `--selectProjects sqle-ee` 明确指定只运行某个 project。 ### Q:更新快照时为何提示 "New snapshot was not written"? **A**:这是因为 `CI=true` 环境变量被设置。本地更新快照时需要: ```bash -CI= pnpm jest --updateSnapshot --testPathPattern="" +CI= pnpm --filter base jest -- --updateSnapshot --testPathPattern="" ``` ### Q:两个 project 能运行同一个测试文件吗? -**A**:不能,文件命名约定保证了互斥性。`ee` project 通过 `testPathIgnorePatterns` 排除了 `*.ce.test.*` 和 `*.sqle.test.*`;`ce` 和 `sqle` project 通过 `testMatch` 只匹配特定命名模式。 +**A**:不能,文件命名约定保证了互斥性。`dms` project 通过 `testPathIgnorePatterns` 排除了 `*.ce.test.*` 和 `*.sqle.test.*`;`sqle-ce` 和 `sqle-ee` project 通过 `testRegex` 只匹配特定命名模式。 --- ## 参考文件 -- [`jest.config.js`](../../jest.config.js) — Jest Projects 完整配置 +- [`packages/tooling-config/jest/create-jest-config.js`](../../packages/tooling-config/jest/create-jest-config.js) — Jest Projects 配置工厂函数 - [`scripts/jest/custom-transform.js`](./custom-transform.js) — 条件编译 transformer - [`.github/workflows/main.yml`](../../.github/workflows/main.yml) — GitHub Actions CI 配置 - [`.cursor/commands/unit-testing.md`](../../.cursor/commands/unit-testing.md) — 单元测试编写规范 diff --git a/scripts/jest/run-coverage.sh b/scripts/jest/run-coverage.sh deleted file mode 100644 index 0bb8bb6291..0000000000 --- a/scripts/jest/run-coverage.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh - -# Usage: pnpm test:c [path] [project] -# -# Arguments: -# path - (optional) test path pattern, e.g. packages/sqle/src/components/Foo -# project - (optional) project name: ee | ce (default: runs both) - -test_path="${1:-}" -test_project="${2:-}" - -echo "project: ${test_project:-all} | path: ${test_path:-all}" - -pnpm test:clean - -base_args="--watchAll=false --coverage --coverageDirectory=coverage --logHeapUsage" - -if [ -n "$test_project" ]; then - base_args="$base_args --selectProjects $test_project" -fi - -if [ -n "$test_path" ]; then - pnpm jest $base_args --testPathPattern="$test_path" -else - pnpm jest $base_args -fi diff --git a/scripts/jest/run.sh b/scripts/jest/run.sh deleted file mode 100644 index 5044549ccc..0000000000 --- a/scripts/jest/run.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -# Usage: pnpm test [path] [project] -# -# Arguments: -# path - (optional) test path pattern, e.g. packages/sqle/src/components/Foo -# project - (optional) project name: ee | ce (default: runs both) -# -# Examples: -# pnpm test → all projects, all tests -# pnpm test "" ee → ee project, all tests -# pnpm test packages/sqle/src/components/Foo → all projects, filtered path -# pnpm test packages/sqle/src/components/Foo ee → ee project, filtered path - -test_path="${1:-}" -test_project="${2:-}" - -base_args="--maxWorkers=50% --watchAll=true" - -if [ -n "$test_project" ]; then - base_args="$base_args --selectProjects $test_project" -fi - -if [ -n "$test_path" ]; then - # Use --testPathPattern explicitly; positional args are ignored in --watchAll mode - pnpm jest $base_args --testPathPattern="$test_path" -else - pnpm jest $base_args -fi From d4d3ada8ac82175a2639fb28372ad8d7e31a272a Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Tue, 28 Apr 2026 17:19:05 +0800 Subject: [PATCH 08/36] chore: migrate toolchain to oxc, turbo, and source-based dms-kit consumption --- .github/workflows/main.yml | 74 +------------ .gitignore | 4 +- Makefile | 6 +- eslint.config.mjs | 101 ------------------ package.json | 18 ++-- packages/base/package.json | 9 +- packages/base/tsconfig.json | 5 +- packages/base/vite.config.mts | 17 ++- .../dms-kit/src/types/ambient-modules.d.ts | 1 + packages/dms-kit/src/utils/HighlightCode.ts | 4 +- .../shared/lib/types/ambient-modules.d.ts | 1 + packages/shared/tsconfig.json | 5 +- packages/sqle/tsconfig.json | 5 +- .../tooling-config/jest/create-jest-config.js | 7 +- turbo.json | 1 + 15 files changed, 62 insertions(+), 196 deletions(-) delete mode 100644 eslint.config.mjs create mode 100644 packages/dms-kit/src/types/ambient-modules.d.ts create mode 100644 packages/shared/lib/types/ambient-modules.d.ts diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6725d25340..6b67d23586 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,16 +29,12 @@ jobs: include: - package_name: base package_path: packages/base - artifact_name: coverage-artifacts-base - package_name: '@actiontech/dms-kit' package_path: packages/dms-kit - artifact_name: coverage-artifacts-dms-kit - package_name: '@actiontech/shared' package_path: packages/shared - artifact_name: coverage-artifacts-shared - package_name: sqle package_path: packages/sqle - artifact_name: coverage-artifacts-sqle steps: - name: Checkout repository uses: actions/checkout@v4 @@ -49,73 +45,9 @@ jobs: - name: Run package test suite run: pnpm turbo run test:ci --filter=${{ matrix.package_name }} - - name: Upload coverage artifact - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.artifact_name }} - path: ${{ matrix.package_path }}/coverage/ - - report: - runs-on: ubuntu-latest - if: ${{ !contains(github.event.pull_request.title, '[skip checker]') }} - needs: [test] - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Get Coverage 1 - uses: actions/download-artifact@v4 - with: - name: coverage-artifacts-base - path: coverage/base - - - name: Get Coverage 2 - uses: actions/download-artifact@v4 - with: - name: coverage-artifacts-dms-kit - path: coverage/dms-kit - - - name: Get Coverage 3 - uses: actions/download-artifact@v4 - with: - name: coverage-artifacts-shared - path: coverage/shared - - - name: Get Coverage 4 - uses: actions/download-artifact@v4 - with: - name: coverage-artifacts-sqle - path: coverage/sqle - - - name: Coverage report (base) - uses: ArtiomTr/jest-coverage-report-action@v2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - coverage-file: coverage/base/report.json - - - name: Coverage report (dms-kit) + - name: Coverage report + if: always() uses: ArtiomTr/jest-coverage-report-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} - coverage-file: coverage/dms-kit/report.json - - - name: Coverage report (shared) - uses: ArtiomTr/jest-coverage-report-action@v2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - coverage-file: coverage/shared/report.json - - - name: Coverage report (sqle) - uses: ArtiomTr/jest-coverage-report-action@v2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - coverage-file: coverage/sqle/report.json - - - name: Delete coverage artifacts - uses: geekyeggo/delete-artifact@v5 - with: - name: | - coverage-artifacts-base - coverage-artifacts-dms-kit - coverage-artifacts-shared - coverage-artifacts-sqle + coverage-file: ${{ matrix.package_path }}/coverage/report.json diff --git a/.gitignore b/.gitignore index 37cc7fdbb5..ebf2981337 100644 --- a/.gitignore +++ b/.gitignore @@ -52,4 +52,6 @@ verdaccio ftp-data -/scripts/cli/dms-kit-publish/docs \ No newline at end of file +/scripts/cli/dms-kit-publish/docs + +*.turbo \ No newline at end of file diff --git a/Makefile b/Makefile index 58996cf147..c07ec1a575 100644 --- a/Makefile +++ b/Makefile @@ -38,13 +38,13 @@ docker_clean: $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app -w /usr/src/app --rm $(DOCKER_IMAGE) sh -c "git config --global --add safe.directory /usr/src/app && git clean -dfx" docker_build_ce: pull_image docker_install_node_modules - $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app --user $(UID):$(GID) -w /usr/src/app --rm $(DOCKER_IMAGE) sh -c "pnpm build" + $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app --user $(UID):$(GID) -w /usr/src/app --rm $(DOCKER_IMAGE) sh -c "pnpm build:release" docker_build_ee: pull_image docker_install_node_modules - $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app --user $(UID):$(GID) -w /usr/src/app --rm $(DOCKER_IMAGE) sh -c "pnpm build:ee" + $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app --user $(UID):$(GID) -w /usr/src/app --rm $(DOCKER_IMAGE) sh -c "pnpm build:release:ee" docker_build_demo: pull_image docker_install_node_modules - $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app --user $(UID):$(GID) -w /usr/src/app --rm $(DOCKER_IMAGE) sh -c "pnpm build:demo" + $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app --user $(UID):$(GID) -w /usr/src/app --rm $(DOCKER_IMAGE) sh -c "pnpm build:release:demo" docker_dms_kit_publish: docker_install_node_modules $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app --user $(UID):$(GID) -w /usr/src/app --rm \ diff --git a/eslint.config.mjs b/eslint.config.mjs deleted file mode 100644 index fb8164f8d3..0000000000 --- a/eslint.config.mjs +++ /dev/null @@ -1,101 +0,0 @@ -import { defineConfig, globalIgnores } from 'eslint/config'; -import globals from 'globals'; -import tseslint from 'typescript-eslint'; -import pluginReact from 'eslint-plugin-react'; -import pluginImport from 'eslint-plugin-import'; -import pluginReactHooks from 'eslint-plugin-react-hooks'; -import pluginNode from 'eslint-plugin-node'; - -export default defineConfig([ - tseslint.configs.recommended, - { - files: ['**/scripts/**/*.{js,mjs,cjs,ts,jsx,tsx}', '**/vite.config.mts'], - plugins: { - import: pluginImport, - node: pluginNode - }, - languageOptions: { - globals: { - ...globals.node - } - }, - rules: { - '@typescript-eslint/no-unused-vars': 'warn', - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-require-imports': 'warn', - '@typescript-eslint/no-empty-object-type': 'off' - } - }, - { - files: ['**/packages/**/*.{js,mjs,cjs,ts,jsx,tsx}'], - ...pluginReact.configs.flat.recommended, - plugins: { - import: pluginImport, - react: pluginReact, - 'react-hooks': pluginReactHooks - }, - languageOptions: { - ...pluginReact.configs.flat.recommended.languageOptions, - globals: { - ...globals.browser - } - }, - settings: { - react: { - pragma: 'React', - version: 'detect' - } - }, - rules: { - ...pluginReactHooks.configs.recommended.rules, - 'no-shadow': 'off', - '@typescript-eslint/no-shadow': 'error', - 'no-shadow-restricted-names': 'error', - 'testing-library/render-result-naming-convention': 0, - 'prefer-const': 'warn', - '@typescript-eslint/no-non-null-asserted-optional-chain': 0, - '@typescript-eslint/no-non-null-assertion': 0, - 'no-extra-boolean-cast': 'off', - 'import/no-anonymous-default-export': [2, { allowNew: true }], - '@typescript-eslint/no-empty-interface': [ - 'error', - { - allowSingleExtends: true - } - ], - '@typescript-eslint/no-explicit-any': 'off', - 'react/display-name': 0, - 'react/prop-types': 'off', - 'react/require-default-props': 'off', - 'no-console': 'warn', - '@typescript-eslint/no-unused-vars': 'warn', - 'no-template-curly-in-string': 'warn', - '@typescript-eslint/no-empty-object-type': 'off', - '@typescript-eslint/no-empty-function': 'warn', - 'import/no-anonymous-default-export': 'warn' - } - }, - globalIgnores([ - 'jest.config.js', - 'eslint.config.mjs', - '**/packages/**/*.test.ts', - '**/packages/**/*.test.tsx', - '**/packages/shared/lib/api/*', - '**/packages/**/mockApi/*', - '**/packages/**/testUtil/*', - '**/packages/**/demo/*', - '**/packages/**/demos/*', - 'jest-setup.ts', - 'node_modules/*', - '**/packages/*/node_modules/*', - '**/scripts/jest/*.js', - '/**/node_modules/*', - 'dist', - 'packages/*/dist', - 'packages/*/scripts', - '# config', - 'vite.config.ts', - '.eslintrc.json', - 'es' - ]) -]); diff --git a/package.json b/package.json index 30c98687f9..9491b360f6 100644 --- a/package.json +++ b/package.json @@ -10,12 +10,12 @@ "scripts": { "preview": "pnpm --filter base preview", "preinstall": "npx only-allow pnpm", - "start": "turbo run start --filter=base --filter=@actiontech/dms-kit --parallel", - "start:ee": "turbo run start:ee --filter=base --filter=@actiontech/dms-kit --parallel", - "start:demo": "turbo run start:demo --filter=base --filter=@actiontech/dms-kit --parallel", - "build": "pnpm --filter @actiontech/dms-kit build && pnpm --filter base build", - "build:ee": "pnpm --filter @actiontech/dms-kit build && pnpm --filter base build:ee", - "build:demo": "pnpm --filter @actiontech/dms-kit build && pnpm --filter base build:demo", + "start": "turbo run start --filter=base --parallel", + "start:ee": "turbo run start:ee --filter=base --parallel", + "start:demo": "turbo run start:demo --filter=base --parallel", + "build": "turbo run build --filter=@actiontech/dms-kit && pnpm --filter base build", + "build:ee": "turbo run build --filter=@actiontech/dms-kit && pnpm --filter base build:ee", + "build:demo": "turbo run build --filter=@actiontech/dms-kit && pnpm --filter base build:demo", "check:turbo": "turbo run check --filter='./packages/*'", "oxfmt:w": "node ./scripts/format/oxfmt-changed.mjs", "oxfmt:c": "node ./scripts/format/oxfmt-changed.mjs --check", @@ -26,8 +26,8 @@ "stylelint": "stylelint packages/*/{src,lib}/**/{*.less,style.ts,element.ts}", "ts-check": "tsc --noEmit", "checker": "pnpm check:turbo", - "test": "pnpm --parallel --filter base --filter @actiontech/dms-kit --filter @actiontech/shared --filter sqle run test:run", - "test:c": "pnpm --parallel --filter base --filter @actiontech/dms-kit --filter @actiontech/shared --filter sqle run test:c", + "test": "pnpm --workspace-concurrency=1 --filter base --filter @actiontech/dms-kit --filter @actiontech/shared --filter sqle run test:run", + "test:c": "pnpm --workspace-concurrency=1 --filter base --filter @actiontech/dms-kit --filter @actiontech/shared --filter sqle run test:c", "test:ci": "turbo run test:ci --filter='./packages/*'", "test:ci:turbo": "pnpm test:ci", "test:clean": "jest --clearCache", @@ -40,7 +40,7 @@ "api_client:g": "cross-env npm_config_registry=http://10.186.18.19:4873 pnpx @actiontech/cli api-client -y", "api_mocks:g": "cross-env npm_config_registry=http://10.186.18.19:4873 pnpx @actiontech/cli api-mocks -y", "ai-doc": "cross-env npm_config_registry=http://10.186.18.19:4873 pnpx @actiontech/cli ai-doc", - "postinstall": "pnpm --filter @actiontech/dms-kit build", + "dms-kit:build": "turbo run build --filter=@actiontech/dms-kit", "dms-kit:publish": "pnpm --filter @actiontech/cli-dms-kit-publish build && dms-kit-publish" }, "keywords": [], diff --git a/packages/base/package.json b/packages/base/package.json index 6adc38c69a..791f7c183a 100644 --- a/packages/base/package.json +++ b/packages/base/package.json @@ -6,9 +6,12 @@ "start": "cross-env buildType=ce,SQLE vite --port=3020", "start:ee": "cross-env buildType=ee,SQLE vite --port=3020", "start:demo": "cross-env buildType=ce,SQLE,DEMO vite --port=3020", - "build": "node ../../scripts/getGitVersion.mjs ce && tsc && cross-env NODE_OPTIONS=--max_old_space_size=102400 buildType=ce,SQLE vite build", - "build:ee": "node ../../scripts/getGitVersion.mjs ee && tsc && cross-env NODE_OPTIONS=--max_old_space_size=102400 buildType=ee,SQLE vite build", - "build:demo": "node ../../scripts/getGitVersion.mjs trial && tsc && cross-env NODE_OPTIONS=--max_old_space_size=102400 buildType=ce,SQLE,DEMO vite build", + "build": "tsc && cross-env NODE_OPTIONS=--max_old_space_size=102400 buildType=ce,SQLE vite build", + "build:ee": "tsc && cross-env NODE_OPTIONS=--max_old_space_size=102400 buildType=ee,SQLE vite build", + "build:demo": "tsc && cross-env NODE_OPTIONS=--max_old_space_size=102400 buildType=ce,SQLE,DEMO vite build", + "build:release": "node ../../scripts/getGitVersion.mjs ce && pnpm build", + "build:release:ee": "node ../../scripts/getGitVersion.mjs ee && pnpm build:ee", + "build:release:demo": "node ../../scripts/getGitVersion.mjs trial && pnpm build:demo", "preview": "vite preview", "oxlint": "oxlint --no-error-on-unmatched-pattern src vite.config.mts", "typecheck": "tsc --noEmit -p tsconfig.json", diff --git a/packages/base/tsconfig.json b/packages/base/tsconfig.json index 740aafa02b..cc3ae8dea9 100644 --- a/packages/base/tsconfig.json +++ b/packages/base/tsconfig.json @@ -3,7 +3,10 @@ "include": ["src"], "compilerOptions": { "paths": { - "~/*": ["./src/*"] + "~/*": ["./src/*"], + "@actiontech/dms-kit": ["../dms-kit/src/index.ts"], + "@actiontech/dms-kit/es/*": ["../dms-kit/src/*"], + "@actiontech/dms-kit/*": ["../dms-kit/src/*"] }, "skipLibCheck": true } diff --git a/packages/base/vite.config.mts b/packages/base/vite.config.mts index ce3c5ed5ae..7f1ef1754b 100644 --- a/packages/base/vite.config.mts +++ b/packages/base/vite.config.mts @@ -59,9 +59,20 @@ export default defineConfig(() => { }) ], resolve: { - alias: { - '~': path.resolve(__dirname, '../provision/src') - } + alias: [ + { + find: /^@actiontech\/dms-kit\/es\/(.*)$/, + replacement: path.resolve(__dirname, '../dms-kit/src/$1') + }, + { + find: '@actiontech/dms-kit', + replacement: path.resolve(__dirname, '../dms-kit/src') + }, + { + find: '~', + replacement: path.resolve(__dirname, '../provision/src') + } + ] }, css: { preprocessorOptions: { diff --git a/packages/dms-kit/src/types/ambient-modules.d.ts b/packages/dms-kit/src/types/ambient-modules.d.ts new file mode 100644 index 0000000000..35306c6fc9 --- /dev/null +++ b/packages/dms-kit/src/types/ambient-modules.d.ts @@ -0,0 +1 @@ +declare module '*.css'; diff --git a/packages/dms-kit/src/utils/HighlightCode.ts b/packages/dms-kit/src/utils/HighlightCode.ts index 60e822f67a..a3d4b763ee 100644 --- a/packages/dms-kit/src/utils/HighlightCode.ts +++ b/packages/dms-kit/src/utils/HighlightCode.ts @@ -1,5 +1,7 @@ import hljs from 'highlight.js/lib/core'; import sqlCore from 'highlight.js/lib/languages/sql'; + +// oxlint-disable-next-line import/no-unassigned-import import 'highlight.js/styles/github.css'; class HighlightCode { @@ -13,5 +15,5 @@ class HighlightCode { } } -// eslint-disable-next-line import/no-anonymous-default-export +// oxlint-disable-next-line import/no-anonymous-default-export export default new HighlightCode(); diff --git a/packages/shared/lib/types/ambient-modules.d.ts b/packages/shared/lib/types/ambient-modules.d.ts new file mode 100644 index 0000000000..35306c6fc9 --- /dev/null +++ b/packages/shared/lib/types/ambient-modules.d.ts @@ -0,0 +1 @@ +declare module '*.css'; diff --git a/packages/shared/tsconfig.json b/packages/shared/tsconfig.json index ee6467a89f..123b998894 100644 --- a/packages/shared/tsconfig.json +++ b/packages/shared/tsconfig.json @@ -3,7 +3,10 @@ "include": ["./lib"], "compilerOptions": { "paths": { - "~/*": ["./src/*"] + "~/*": ["./src/*"], + "@actiontech/dms-kit": ["../dms-kit/src/index.ts"], + "@actiontech/dms-kit/es/*": ["../dms-kit/src/*"], + "@actiontech/dms-kit/*": ["../dms-kit/src/*"] } } } diff --git a/packages/sqle/tsconfig.json b/packages/sqle/tsconfig.json index a4cb7b26e9..05b880371a 100644 --- a/packages/sqle/tsconfig.json +++ b/packages/sqle/tsconfig.json @@ -3,7 +3,10 @@ "include": ["src"], "compilerOptions": { "paths": { - "~/*": ["./src/*"] + "~/*": ["./src/*"], + "@actiontech/dms-kit": ["../dms-kit/src/index.ts"], + "@actiontech/dms-kit/es/*": ["../dms-kit/src/*"], + "@actiontech/dms-kit/*": ["../dms-kit/src/*"] } } } diff --git a/packages/tooling-config/jest/create-jest-config.js b/packages/tooling-config/jest/create-jest-config.js index 6ce77afdbc..0d422783ee 100644 --- a/packages/tooling-config/jest/create-jest-config.js +++ b/packages/tooling-config/jest/create-jest-config.js @@ -133,9 +133,13 @@ export function createJestConfig(options) { repoRoot, 'packages/shared/lib/testUtil/mockModule/mockSigmaGraphSearch.tsx' ), + '^@actiontech/dms-kit/es/(.*)$': path.resolve( + repoRoot, + 'packages/dms-kit/src/$1' + ), + '^@actiontech/dms-kit$': path.resolve(repoRoot, 'packages/dms-kit/src'), '^@actiontech/(.*)$': path.resolve(packageRoot, '../$1') }, - collectCoverageFrom, setupFilesAfterEnv: [path.resolve(repoRoot, 'jest-setup.ts')] }; @@ -158,6 +162,7 @@ export function createJestConfig(options) { } return { + collectCoverageFrom, projects, reporters }; diff --git a/turbo.json b/turbo.json index 7de8309d45..8cb6060dec 100644 --- a/turbo.json +++ b/turbo.json @@ -3,6 +3,7 @@ "tasks": { "build": { "dependsOn": ["^build"], + "cache": false, "outputs": ["dist/**", "lib/**", "es/**", "build/**"] }, "test:ci": { From 9fc5f53a90bd94176ac1b4a707d03db476a467be Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Fri, 10 Apr 2026 17:48:28 +0800 Subject: [PATCH 09/36] fix(ldap-settings): remove duplicate ldap search base DN field --- .../src/page/System/LoginConnection/LDAPSetting/index.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/base/src/page/System/LoginConnection/LDAPSetting/index.tsx b/packages/base/src/page/System/LoginConnection/LDAPSetting/index.tsx index 34cc31f14c..58fc107cd3 100644 --- a/packages/base/src/page/System/LoginConnection/LDAPSetting/index.tsx +++ b/packages/base/src/page/System/LoginConnection/LDAPSetting/index.tsx @@ -192,12 +192,6 @@ const LDAPSetting = () => { dataIndex: 'ldap_search_base_dn', hidden: !ldapSetting?.enable_ldap }, - { - label: t('dmsSystem.ldap.ldapSearchBaseDn'), - span: 3, - dataIndex: 'ldap_search_base_dn', - hidden: !ldapSetting?.enable_ldap - }, { label: t('dmsSystem.ldap.ldapUserNameRdnKey'), span: 3, From f159b55c8182bed44dce5c92bea2d8fadc16aed2 Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Tue, 14 Apr 2026 16:57:25 +0800 Subject: [PATCH 10/36] fix(workflow): improve long-text display and add SQL upload type tooltip --- .../__snapshots__/index.test.tsx.snap | 675 +++++- .../Common/BasicInfoWrapper/index.tsx | 7 +- .../Common/BasicInfoWrapper/style.ts | 4 +- .../__snapshots__/index.test.tsx.snap | 75 +- .../__snapshots__/index.test.tsx.snap | 150 +- .../__snapshots__/index.test.tsx.snap | 375 +++- .../__snapshots__/index.test.tsx.snap | 20 +- .../page/DataExportManagement/List/column.tsx | 2 +- .../sqle/src/locale/en-US/execWorkflow.ts | 2 + .../sqle/src/locale/zh-CN/execWorkflow.ts | 1 + .../__snapshots__/index.test.tsx.snap | 8 +- .../Common/BasicInfoWrapper/index.tsx | 13 +- .../Common/BasicInfoWrapper/style.ts | 3 +- .../__snapshots__/index.ce.test.tsx.snap | 98 +- .../__snapshots__/index.test.tsx.snap | 196 +- .../SqlStatementFormItem/index.tsx | 12 +- .../__snapshots__/index.ce.test.tsx.snap | 98 +- .../__snapshots__/index.test.tsx.snap | 294 ++- .../__snapshots__/index.ce.test.tsx.snap | 98 +- .../__snapshots__/index.test.tsx.snap | 1892 ++++++++++++----- .../__snapshots__/index.ce.test.tsx.snap | 4 +- .../__snapshots__/index.test.tsx.snap | 12 +- .../__snapshots__/index.test.tsx.snap | 20 +- .../__snapshots__/index.test.tsx.snap | 392 +++- 24 files changed, 3584 insertions(+), 867 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap index d7beddeca8..5734d0b78c 100644 --- a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap @@ -3,7 +3,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 1`] = `
- +
+ + + +
+ +
@@ -22,7 +93,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 1`] exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 2`] = `
desc +
+ + + +
+ +
@@ -41,7 +183,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 2`] exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 3`] = `
desc +
+ + + +
+ +
@@ -133,7 +346,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 3`] exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 4`] = `
desc +
+ + + +
+ +
@@ -225,7 +509,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 4`] exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 5`] = `
desc +
+ + + +
+ +
@@ -317,7 +672,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 5`] exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 6`] = `
desc +
+ + + +
+ +
@@ -409,7 +835,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 6`] exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 7`] = `
desc +
+ + + +
+ +
@@ -501,7 +998,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 7`] exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 8`] = `
desc +
+ + + +
+ +
@@ -593,7 +1161,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 8`] exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 9`] = `
desc +
+ + + +
+ +
diff --git a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx index 8a77c4c4ef..3db4fdf939 100644 --- a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx +++ b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx @@ -1,6 +1,6 @@ import classNames from 'classnames'; import { BasicInfoWrapperProps } from './index.type'; -import { EmptyBox } from '@actiontech/dms-kit'; +import { BasicTypographyEllipsis, EmptyBox } from '@actiontech/dms-kit'; import { DataExportStatusDictionary } from '../index.data'; import { BasicInfoStyleWrapper } from './style'; const BasicInfoWrapper: React.FC = ({ @@ -77,7 +77,10 @@ const BasicInfoWrapper: React.FC = ({
{title}
-
{desc ?? '-'}
+ ); }; diff --git a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/style.ts b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/style.ts index 8a1b88db18..725afceb79 100644 --- a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/style.ts +++ b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/style.ts @@ -60,9 +60,11 @@ export const BasicInfoStyleWrapper = styled('div')<{ } .workflow-base-info-desc { - color: ${({ theme }) => theme.sharedTheme.uiToken.colorTextTertiary}; + color: ${({ theme }) => + theme.sharedTheme.uiToken.colorTextTertiary} !important; font-size: 14px; font-weight: 400; line-height: 22px; + max-width: 800px; } `; diff --git a/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap index 243d581774..02122de329 100644 --- a/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap @@ -1419,7 +1419,7 @@ exports[`first should match snapshot when pageState is equal SUBMIT_WORKFLOW 1`]
desc +
+ + + +
+ +
desc +
+ + + +
+ +
desc +
+ + + +
+ +
desc +
+ + + +
+ +
desc +
+ + + +
+ +
desc +
+ + + +
+ +
desc +
+ + + +
+ +
desc +
+ + + +
+ +
描述 @@ -516,7 +516,7 @@ exports[`test base/DataExport/List render batch close button When the user is no
描述 @@ -2078,7 +2078,7 @@ exports[`test base/DataExport/List render init snapshot 2`] = ` 工单名称 描述 @@ -2247,7 +2247,7 @@ exports[`test base/DataExport/List render init snapshot 2`] = `
描述 @@ -3610,7 +3610,7 @@ exports[`test base/DataExport/List render table filter items 1`] = `
t('dmsDataExport.list.column.desc'), - className: 'ellipsis-column-width-large', + className: 'ellipsis-column-width', render: (desc, record) => desc ? (
this is a desc str
@@ -118,7 +118,7 @@ exports[`sqle/ExecWorkflow/BasicInfoWrapper render snap when has need params 1`]
-
diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/BasicInfoWrapper/index.tsx b/packages/sqle/src/page/SqlExecWorkflow/Common/BasicInfoWrapper/index.tsx index 85be210af6..c9185530c7 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Common/BasicInfoWrapper/index.tsx +++ b/packages/sqle/src/page/SqlExecWorkflow/Common/BasicInfoWrapper/index.tsx @@ -1,13 +1,18 @@ import classNames from 'classnames'; import { BasicInfoStyleWrapper } from './style'; import { BasicInfoWrapperProps } from './index.type'; -import { EmptyBox, BasicTag } from '@actiontech/dms-kit'; +import { + EmptyBox, + BasicTag, + BasicTypographyEllipsis +} from '@actiontech/dms-kit'; import { TypedLink } from '@actiontech/shared'; import { useTranslation } from 'react-i18next'; import { execWorkflowStatusDictionary } from '../../../../hooks/useStaticStatus/index.data'; import { Space } from 'antd'; import { useCurrentProject } from '@actiontech/shared/lib/features'; import { ROUTE_PATHS } from '@actiontech/dms-kit'; + const BasicInfoWrapper: React.FC = ({ title, desc, @@ -102,7 +107,11 @@ const BasicInfoWrapper: React.FC = ({ -
{desc ?? '-'}
+ ); }; diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/BasicInfoWrapper/style.ts b/packages/sqle/src/page/SqlExecWorkflow/Common/BasicInfoWrapper/style.ts index 35a0ee53e9..41775b6f89 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Common/BasicInfoWrapper/style.ts +++ b/packages/sqle/src/page/SqlExecWorkflow/Common/BasicInfoWrapper/style.ts @@ -62,9 +62,10 @@ export const BasicInfoStyleWrapper = styled('div')<{ .workflow-base-info-desc { color: ${({ theme }) => - theme.sqleTheme.execWorkflow.common.basicInfo.descColor}; + theme.sqleTheme.execWorkflow.common.basicInfo.descColor} !important; font-size: 14px; font-weight: 400; line-height: 22px; + max-width: 800px; } `; diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/__tests__/__snapshots__/index.ce.test.tsx.snap b/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/__tests__/__snapshots__/index.ce.test.tsx.snap index 450eb6802b..10b0a3a26f 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/__tests__/__snapshots__/index.ce.test.tsx.snap +++ b/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/SqlStatementFormItem/__tests__/__snapshots__/index.ce.test.tsx.snap @@ -18,32 +18,80 @@ exports[`test SqlStatementFormItem renders SqlStatementFormItem component 1`] = class="" title="" > - - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
= ({ <> + {t('execWorkflow.create.form.sqlInfo.uploadType')} - + + } className="form-item-label-mb-16" /> diff --git a/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/__tests__/__snapshots__/index.ce.test.tsx.snap b/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/__tests__/__snapshots__/index.ce.test.tsx.snap index 81cda300f2..6fd5812f40 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/__tests__/__snapshots__/index.ce.test.tsx.snap +++ b/packages/sqle/src/page/SqlExecWorkflow/Common/SqlStatementFormController/__tests__/__snapshots__/index.ce.test.tsx.snap @@ -18,32 +18,80 @@ exports[`test SqlStatementFormController ce should match snapshot 1`] = ` class="" title="" > - - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
-
@@ -6666,32 +6810,80 @@ exports[`sqle/SqlExecWorkflow/Create render create rollback workflow 1`] = ` class="ant-form-item-no-colon" title="" > - - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
test desc
@@ -8702,32 +8894,80 @@ exports[`sqle/SqlExecWorkflow/Create render create rollback workflow 2`] = ` class="ant-form-item-no-colon" title="" > - - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
test desc
@@ -11118,32 +11358,80 @@ exports[`sqle/SqlExecWorkflow/Create should handle form submission and audit act class="ant-form-item-no-colon" title="" > - - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
workflow desc
@@ -13737,32 +14025,80 @@ exports[`sqle/SqlExecWorkflow/Create should handle form submission and audit act class="ant-form-item-no-colon" title="" > - - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
workflow desc
@@ -16368,32 +16704,80 @@ exports[`sqle/SqlExecWorkflow/Create should handle form submission and audit act class="ant-form-item-no-colon" title="" > - - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
workflow desc
@@ -20808,32 +21240,80 @@ exports[`sqle/SqlExecWorkflow/Create should handle form submission and audit act class="ant-form-item-no-colon" title="" > - - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
-
@@ -30107,32 +30779,80 @@ exports[`sqle/SqlExecWorkflow/Create should snapshot render initial workflow cre class="ant-form-item-no-colon" title="" > - - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
desc
diff --git a/packages/sqle/src/page/SqlExecWorkflow/Create/components/AuditResultStep/__tests__/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlExecWorkflow/Create/components/AuditResultStep/__tests__/__snapshots__/index.test.tsx.snap index 43f47563e8..4de1e0c167 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Create/components/AuditResultStep/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlExecWorkflow/Create/components/AuditResultStep/__tests__/__snapshots__/index.test.tsx.snap @@ -72,7 +72,7 @@ exports[`test AuditResultStep render switch backup policy button 1`] = `
desc
@@ -655,7 +655,7 @@ exports[`test AuditResultStep render switch data source backup policy 1`] = `
desc
@@ -1713,7 +1713,7 @@ exports[`test AuditResultStep should match snapshot 1`] = `
desc
diff --git a/packages/sqle/src/page/SqlExecWorkflow/Detail/__tests__/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlExecWorkflow/Detail/__tests__/__snapshots__/index.test.tsx.snap index 7b1100c14f..c119fd18e3 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Detail/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlExecWorkflow/Detail/__tests__/__snapshots__/index.test.tsx.snap @@ -200,7 +200,7 @@ exports[`sqle/ExecWorkflow/Detail render current workflow status is wait for exe
this is a desc
@@ -951,7 +951,7 @@ exports[`sqle/ExecWorkflow/Detail render snap detail 1`] = `
-
@@ -1522,7 +1522,7 @@ exports[`sqle/ExecWorkflow/Detail render snap detail 2`] = `
this is a desc
@@ -2414,7 +2414,7 @@ exports[`sqle/ExecWorkflow/Detail render snap detail 3`] = `
this is a desc
@@ -3338,7 +3338,7 @@ exports[`sqle/ExecWorkflow/Detail render snap detail when have multiple states 1
this is a desc
diff --git a/packages/sqle/src/page/SqlExecWorkflow/Detail/components/ModifySqlStatement/__tests__/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlExecWorkflow/Detail/components/ModifySqlStatement/__tests__/__snapshots__/index.test.tsx.snap index c565aaab7a..92dcec665b 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Detail/components/ModifySqlStatement/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlExecWorkflow/Detail/components/ModifySqlStatement/__tests__/__snapshots__/index.test.tsx.snap @@ -104,32 +104,80 @@ exports[`sqle/ExecWorkflow/Detail/ModifySqlStatement render snap when click form class="ant-form-item-no-colon" title="" > - - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
Date: Tue, 14 Apr 2026 10:05:08 +0000 Subject: [PATCH 11/36] test: update 1 snapshot(s) for DMS UI --- .../__snapshots__/index.test.tsx.snap | 196 +++++++++++++----- 1 file changed, 146 insertions(+), 50 deletions(-) diff --git a/packages/sqle/src/page/VersionManagement/Detail/components/ModifyWorkflowSql/__tests__/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/VersionManagement/Detail/components/ModifyWorkflowSql/__tests__/__snapshots__/index.test.tsx.snap index 26987a56c5..015fd498fc 100644 --- a/packages/sqle/src/page/VersionManagement/Detail/components/ModifyWorkflowSql/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/VersionManagement/Detail/components/ModifyWorkflowSql/__tests__/__snapshots__/index.test.tsx.snap @@ -101,32 +101,80 @@ exports[`sqle/VersionManagement/Detail/ModifyWorkflowSql render init snap shot 1 class="ant-form-item-no-colon" title="" > - - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
- - - - - - 选择SQL语句上传方式 - +
+ + + + +
+
+ + 选择SQL语句上传方式 + +
+
+
+
+ + + +
+
+
+
Date: Tue, 21 Apr 2026 05:25:12 +0000 Subject: [PATCH 12/36] feat(workflow-template): add frontend API adaptation and i18n keys for data export workflow - DEV-022: Extend WorkFlowStepTemplateReqV1TypeEnum with export_review/export_execute; add WorkflowTemplateTypeEnum (workflow/data_export); add workflow_type field to IWorkflowTemplateDetailResV1 - DEV-023: Add optional workflow_type param to getWorkflowTemplateV1 and updateWorkflowTemplateV1; add new getWorkflowTemplateListV1 function calling GET /v1/projects/{name}/workflow_templates; add IGetWorkflowTemplateListResV1 type - DEV-029: Add zh-CN and en-US i18n keys in sqle workflowTemplate (list table columns, type tags, edit page titles, export review/execute step descriptions) and base dmsDataExport (approval process preview section) refs actiontech/dms-ee#784 (cherry picked from commit 4dd5e5c985fb49d2684609cf0530bfe86d686678) --- .../base/src/locale/en-US/dmsDataExport.ts | 7 +++++ .../base/src/locale/zh-CN/dmsDataExport.ts | 7 +++++ .../shared/lib/api/sqle/service/common.d.ts | 10 +++++++ .../lib/api/sqle/service/common.enum.ts | 12 ++++++++- .../lib/api/sqle/service/workflow/index.d.ts | 12 +++++++++ .../lib/api/sqle/service/workflow/index.ts | 26 ++++++++++++++++++- .../sqle/src/locale/en-US/workflowTemplate.ts | 23 ++++++++++++++-- .../sqle/src/locale/zh-CN/workflowTemplate.ts | 22 ++++++++++++++-- 8 files changed, 113 insertions(+), 6 deletions(-) diff --git a/packages/base/src/locale/en-US/dmsDataExport.ts b/packages/base/src/locale/en-US/dmsDataExport.ts index 10c6c50e3d..6d25445c00 100644 --- a/packages/base/src/locale/en-US/dmsDataExport.ts +++ b/packages/base/src/locale/en-US/dmsDataExport.ts @@ -56,6 +56,13 @@ export default { result: { success: 'Task created successfully', guide: 'View the newly created task' + }, + approvalProcess: { + title: 'Approval Process', + hint: 'Approval process can be modified in Project Configure > Approval Process', + stepLabel: 'Step {{number}}', + matchByPermission: 'Match by Permission', + loadFailed: 'Failed to load approval process' } }, batchClose: { diff --git a/packages/base/src/locale/zh-CN/dmsDataExport.ts b/packages/base/src/locale/zh-CN/dmsDataExport.ts index 28a2e382d7..80b18dd8d0 100644 --- a/packages/base/src/locale/zh-CN/dmsDataExport.ts +++ b/packages/base/src/locale/zh-CN/dmsDataExport.ts @@ -52,6 +52,13 @@ export default { hasExceptionRule: '当前存在审核规则未被校验,请排除问题后重新触发审核', continueSubmission: '仍要创建' }, + approvalProcess: { + title: '审批流程', + hint: '审批流程可在 Project Configure > Approval Process 中修改', + stepLabel: '步骤 {{number}}', + matchByPermission: '按权限匹配', + loadFailed: '加载审批流程失败' + }, update: { baseTitle: '工单基本信息', sourceTitle: '工单导出对象', diff --git a/packages/shared/lib/api/sqle/service/common.d.ts b/packages/shared/lib/api/sqle/service/common.d.ts index 993b7cdaf3..333f923789 100644 --- a/packages/shared/lib/api/sqle/service/common.d.ts +++ b/packages/shared/lib/api/sqle/service/common.d.ts @@ -2503,6 +2503,14 @@ export interface IGetWorkflowTemplateResV1 { message?: string; } +export interface IGetWorkflowTemplateListResV1 { + code?: number; + + data?: IWorkflowTemplateDetailResV1[]; + + message?: string; +} + export interface IGetWorkflowsResV1 { code?: number; @@ -4457,6 +4465,8 @@ export interface IWorkflowTemplateDetailResV1 { workflow_step_template_list?: IWorkFlowStepTemplateResV1[]; workflow_template_name?: string; + + workflow_type?: string; } export interface ICreatePipelineResData { diff --git a/packages/shared/lib/api/sqle/service/common.enum.ts b/packages/shared/lib/api/sqle/service/common.enum.ts index 0bdc064516..92982bee6a 100644 --- a/packages/shared/lib/api/sqle/service/common.enum.ts +++ b/packages/shared/lib/api/sqle/service/common.enum.ts @@ -829,7 +829,17 @@ export enum UpdateWorkflowTemplateReqV1AllowSubmitWhenLessAuditLevelEnum { export enum WorkFlowStepTemplateReqV1TypeEnum { 'sql_review' = 'sql_review', - 'sql_execute' = 'sql_execute' + 'sql_execute' = 'sql_execute', + + 'export_review' = 'export_review', + + 'export_execute' = 'export_execute' +} + +export enum WorkflowTemplateTypeEnum { + 'workflow' = 'workflow', + + 'data_export' = 'data_export' } export enum WorkflowDetailResV1CurrentStepTypeEnum { diff --git a/packages/shared/lib/api/sqle/service/workflow/index.d.ts b/packages/shared/lib/api/sqle/service/workflow/index.d.ts index c899fa201c..8883cbacab 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.d.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.d.ts @@ -3,6 +3,7 @@ import { IGetWorkflowsResV1, IGlobalWorkflowStatisticsResV1, IGetWorkflowTemplateResV1, + IGetWorkflowTemplateListResV1, IUpdateWorkflowTemplateReqV1, IBaseRes, ICreateWorkflowReqV1, @@ -129,14 +130,25 @@ export interface IGetGlobalWorkflowStatisticsReturn export interface IGetWorkflowTemplateV1Params { project_name: string; + + workflow_type?: string; } export interface IGetWorkflowTemplateV1Return extends IGetWorkflowTemplateResV1 {} +export interface IGetWorkflowTemplateListV1Params { + project_name: string; +} + +export interface IGetWorkflowTemplateListV1Return + extends IGetWorkflowTemplateListResV1 {} + export interface IUpdateWorkflowTemplateV1Params extends IUpdateWorkflowTemplateReqV1 { project_name: string; + + workflow_type?: string; } export interface IUpdateWorkflowTemplateV1Return extends IBaseRes {} diff --git a/packages/shared/lib/api/sqle/service/workflow/index.ts b/packages/shared/lib/api/sqle/service/workflow/index.ts index 13a5d63d3a..4d4a698fe1 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.ts @@ -18,6 +18,8 @@ import { IGetGlobalWorkflowStatisticsReturn, IGetWorkflowTemplateV1Params, IGetWorkflowTemplateV1Return, + IGetWorkflowTemplateListV1Params, + IGetWorkflowTemplateListV1Return, IUpdateWorkflowTemplateV1Params, IUpdateWorkflowTemplateV1Return, IGetWorkflowsV1Params, @@ -166,6 +168,21 @@ class WorkflowService extends ServiceBase { ); } + public getWorkflowTemplateListV1( + params: IGetWorkflowTemplateListV1Params, + options?: AxiosRequestConfig + ) { + const paramsData = this.cloneDeep(params); + const project_name = paramsData.project_name; + delete paramsData.project_name; + + return this.get( + `/v1/projects/${project_name}/workflow_templates`, + paramsData, + options + ); + } + public updateWorkflowTemplateV1( params: IUpdateWorkflowTemplateV1Params, options?: AxiosRequestConfig @@ -174,8 +191,15 @@ class WorkflowService extends ServiceBase { const project_name = paramsData.project_name; delete paramsData.project_name; + const workflow_type = paramsData.workflow_type; + delete paramsData.workflow_type; + + const queryString = workflow_type + ? `?workflow_type=${workflow_type}` + : ''; + return this.patch( - `/v1/projects/${project_name}/workflow_template`, + `/v1/projects/${project_name}/workflow_template${queryString}`, paramsData, options ); diff --git a/packages/sqle/src/locale/en-US/workflowTemplate.ts b/packages/sqle/src/locale/en-US/workflowTemplate.ts index eebcd5119d..59be44862f 100644 --- a/packages/sqle/src/locale/en-US/workflowTemplate.ts +++ b/packages/sqle/src/locale/en-US/workflowTemplate.ts @@ -10,7 +10,15 @@ export default { table: { workflowTemplateName: 'Approval workflow template name', - desc: 'Approval workflow template description' + desc: 'Approval workflow template description', + applicableType: 'Applicable Type', + approvalNodeDesc: 'Approval Node Description', + updateTime: 'Update Time' + }, + + type: { + workflow: 'SQL Exec Workflow', + dataExport: 'Data Export' }, operator: { @@ -33,7 +41,9 @@ export default { update: { title: { - wrapper: 'Update approval workflow template' + wrapper: 'Update approval workflow template', + workflow: 'Edit Approval Process - SQL Exec Workflow', + dataExport: 'Edit Approval Process - Data Export' }, result: { title: 'Update approval workflow template successfully', @@ -132,6 +142,15 @@ export default { matchExecute: 'Match members who have data source online permissions' } }, + exportReview: { + title: 'Export Review', + subTitle: + 'Reviewer checks the legitimacy of the export request' + }, + exportExecute: { + title: 'Export Execution Confirm', + subTitle: 'Confirm to execute the export operation' + }, operator: { remove: 'Remove this step', moveUp: 'Move this step up', diff --git a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts index 0e7ea1c556..0dd16070cd 100644 --- a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts +++ b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts @@ -10,7 +10,15 @@ export default { table: { workflowTemplateName: '审批流程模板名称', - desc: '审批流程模板描述' + desc: '审批流程模板描述', + applicableType: '适用类型', + approvalNodeDesc: '审批节点描述', + updateTime: '更新时间' + }, + + type: { + workflow: '上线工单', + dataExport: '数据导出' }, operator: { @@ -32,7 +40,9 @@ export default { update: { title: { - wrapper: '更新审批流程模板' + wrapper: '更新审批流程模板', + workflow: '编辑审批流程 - 上线工单', + dataExport: '编辑审批流程 - 数据导出' }, result: { title: '更新审批流程模板成功', @@ -124,6 +134,14 @@ export default { matchExecute: '匹配拥有数据源上线权限的成员' } }, + exportReview: { + title: '导出审批', + subTitle: '审批人在该步骤审核导出请求的合理性' + }, + exportExecute: { + title: '导出执行确认', + subTitle: '确认执行导出操作' + }, operator: { remove: '移除该步骤', moveUp: '上移该步骤', From 6fd0f977bacbbf7358db8697c1988c7ae17be714 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Tue, 21 Apr 2026 05:47:35 +0000 Subject: [PATCH 13/36] feat(workflow-template): refactor approval process page from detail view to list view - DEV-024: Replace WorkflowTemplateStepInfo/AuthInfo with ActiontechTable - Add column.tsx with workflow_type tag, approval node description, update time columns - Refactor actions.tsx to use table row edit button with permission control - Edit button navigates with workflowType query parameter - Add getWorkflowTemplateList mock API and update test files - Remove old snapshots for updated page structure refs actiontech/dms-ee#784 (cherry picked from commit d6789673acb3de193e7cfa9119b8ac4f4b905d9e) --- .../mockApi/sqle/workflowTemplate/data.ts | 25 +- .../mockApi/sqle/workflowTemplate/index.ts | 16 +- .../__snapshots__/index.ce.test.tsx.snap | 544 ------ .../__snapshots__/index.test.tsx.snap | 1478 ----------------- .../WorkflowTemplateDetail/actions.tsx | 47 +- .../WorkflowTemplateDetail/column.tsx | 66 + .../WorkflowTemplateDetail/index.ce.test.tsx | 12 +- .../WorkflowTemplateDetail/index.test.tsx | 118 +- .../WorkflowTemplateDetail/index.tsx | 147 +- .../WorkflowTemplateDetail/style.ts | 10 - 10 files changed, 213 insertions(+), 2250 deletions(-) delete mode 100644 packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap delete mode 100644 packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap create mode 100644 packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx diff --git a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts index d7337181fc..3098e799a2 100644 --- a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts +++ b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts @@ -29,5 +29,28 @@ export const workflowTemplateData = { type: 'sql_execute' } ], - workflow_template_name: '700300-WorkflowTemplate' + workflow_template_name: '700300-WorkflowTemplate', + workflow_type: 'workflow' }; + +export const dataExportWorkflowTemplateData = { + allow_submit_when_less_audit_level: '', + desc: '', + update_time: '2024-01-15T10:30:00+08:00', + workflow_step_template_list: [ + { + approved_by_authorized: true, + assignee_user_id_list: [], + execute_by_authorized: false, + number: 1, + type: 'export_review' + } + ], + workflow_template_name: '700300-DataExportWorkflowTemplate', + workflow_type: 'data_export' +}; + +export const workflowTemplateListData = [ + workflowTemplateData, + dataExportWorkflowTemplateData +]; diff --git a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts index 9663d8174f..87a85ff092 100644 --- a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts +++ b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts @@ -1,12 +1,16 @@ import workflow from '../../../../api/sqle/service/workflow'; import { MockSpyApy, createSpySuccessResponse } from '../../common'; -import { workflowTemplateData } from './data'; +import { + workflowTemplateData, + workflowTemplateListData +} from './data'; import { cloneDeep } from 'lodash'; class MockWorkflowTemplateApi implements MockSpyApy { public mockAllApi(): void { this.updateWorkflowTemplate(); this.getWorkflowTemplate(); + this.getWorkflowTemplateList(); this.cancelWorkflow(); } @@ -26,6 +30,16 @@ class MockWorkflowTemplateApi implements MockSpyApy { return spy; } + public getWorkflowTemplateList() { + const spy = jest.spyOn(workflow, 'getWorkflowTemplateListV1'); + spy.mockImplementation(() => { + return createSpySuccessResponse({ + data: cloneDeep(workflowTemplateListData) + }); + }); + return spy; + } + public cancelWorkflow() { const spy = jest.spyOn(workflow, 'cancelWorkflowV2'); spy.mockImplementation(() => { diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap deleted file mode 100644 index fe53f498d2..0000000000 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap +++ /dev/null @@ -1,544 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`page/WorkflowTemplate CE render workflow template detail 1`] = ` - -
-
-
-
- 审批流程模板 -
-
-
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
- - 工单发起/工单更新SQL语句 - -
- 工单被创建,或者工单被驳回后等待修改SQL语句 -
-
-
-
-
-
-
- - - - - - -
-
-
- - - - - -
-
-
-
-
- - 审核节点 - - #1 - - -
- - -
-
-
- 审核人 -
-
- - - - - 匹配拥有数据源审核权限的成员 - -
-
-
-
-
-
-
-
- - - -
-
-
- - - - - -
-
-
-
-
- - 审核节点 - - #2 - - -
- step desc -
-
-
- 审核人 -
-
-
-
- - - T - - -
-
-
-
-
-
-
-
-
-
- - - - - - -
-
-
- - - - - -
-
-
-
-
- - 执行上线 - -
- - -
-
-
- 执行人 -
-
- - - - - 匹配拥有数据源上线权限的成员 - -
-
-
-
-
-
-
-
-
-
-
-
- - 允许创建工单的最高审核等级 - - - 告警(Warning) - -
-
-
-
-
-
-
-
-
-
- - 注意事项 - -
-
    -
  • - 若项目管理员对审批流程模板进行了修改,不会对已经在审批流程的工单造成影响; -
  • -
  • - 被驳回的工单,需要创建人更新SQL语句后重新发起,驳回记录可在 “工单进度-工单历史操作” 中查看; -
  • -
  • - 处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭; -
  • -
  • - 审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作; -
  • -
  • - 上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。 -
  • -
-
-
-
- - 审批流程模板更新时间 - -
- - - - - 2023-12-26 14:19:12 - -
-
-
-
-
-
-
-
-
- -`; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap deleted file mode 100644 index ac86d7daac..0000000000 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap +++ /dev/null @@ -1,1478 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`page/WorkflowTemplate/WorkflowTemplateDetail render workflow template detail 1`] = ` - -
-
- -
-
-
-
-
-
-
- - - - - -
-
-
-
-
- - 工单发起/工单更新SQL语句 - -
- 工单被创建,或者工单被驳回后等待修改SQL语句 -
-
-
-
-
-
-
- - - - - - -
-
-
- - - - - -
-
-
-
-
- - 审核节点 - - #1 - - -
- - -
-
-
- 审核人 -
-
- - - - - 匹配拥有数据源审核权限的成员 - -
-
-
-
-
-
-
-
- - - -
-
-
- - - - - -
-
-
-
-
- - 审核节点 - - #2 - - -
- step desc -
-
-
- 审核人 -
-
-
-
- - - T - - -
-
-
-
-
-
-
-
-
-
- - - - - - -
-
-
- - - - - -
-
-
-
-
- - 执行上线 - -
- - -
-
-
- 执行人 -
-
- - - - - 匹配拥有数据源上线权限的成员 - -
-
-
-
-
-
-
-
-
-
-
-
- - 允许创建工单的最高审核等级 - - - 告警(Warning) - -
-
-
-
-
-
-
-
-
-
- - 注意事项 - -
-
    -
  • - 若项目管理员对审批流程模板进行了修改,不会对已经在审批流程的工单造成影响; -
  • -
  • - 被驳回的工单,需要创建人更新SQL语句后重新发起,驳回记录可在 “工单进度-工单历史操作” 中查看; -
  • -
  • - 处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭; -
  • -
  • - 审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作; -
  • -
  • - 上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。 -
  • -
-
-
-
- - 审批流程模板更新时间 - -
- - - - - 2023-12-26 14:19:12 - -
-
-
-
-
-
-
-
-
- -`; - -exports[`page/WorkflowTemplate/WorkflowTemplateDetail render workflow template detail with no review step 1`] = ` - -
-
- -
-
-
-
-
-
-
- - - - - -
-
-
-
-
- - 工单发起/工单更新SQL语句 - -
- 工单被创建,或者工单被驳回后等待修改SQL语句 -
-
-
-
-
-
-
- - - - - - -
-
-
- - - - - -
-
-
-
-
- - 执行上线 - -
- - -
-
-
- 执行人 -
-
- - - - - 匹配拥有数据源上线权限的成员 - -
-
-
-
-
-
-
-
-
-
-
-
- - 允许创建工单的最高审核等级 - - - 告警(Warning) - -
-
-
-
-
-
-
-
-
-
- - 注意事项 - -
-
    -
  • - 若项目管理员对审批流程模板进行了修改,不会对已经在审批流程的工单造成影响; -
  • -
  • - 被驳回的工单,需要创建人更新SQL语句后重新发起,驳回记录可在 “工单进度-工单历史操作” 中查看; -
  • -
  • - 处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭; -
  • -
  • - 审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作; -
  • -
  • - 上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。 -
  • -
-
-
-
- - 审批流程模板更新时间 - -
- - - - - 2023-12-26 14:19:12 - -
-
-
-
-
-
-
-
-
- -`; - -exports[`page/WorkflowTemplate/WorkflowTemplateDetail render workflow template detail without permission 1`] = ` - -
-
-
-
- 审批流程模板 -
-
-
-
-
-
-
-
-
-
- - - - - -
-
-
-
-
- - 工单发起/工单更新SQL语句 - -
- 工单被创建,或者工单被驳回后等待修改SQL语句 -
-
-
-
-
-
-
- - - - - - -
-
-
- - - - - -
-
-
-
-
- - 审核节点 - - #1 - - -
- - -
-
-
- 审核人 -
-
- - - - - 匹配拥有数据源审核权限的成员 - -
-
-
-
-
-
-
-
- - - -
-
-
- - - - - -
-
-
-
-
- - 审核节点 - - #2 - - -
- step desc -
-
-
- 审核人 -
-
-
-
- - - T - - -
-
-
-
-
-
-
-
-
-
- - - - - - -
-
-
- - - - - -
-
-
-
-
- - 执行上线 - -
- - -
-
-
- 执行人 -
-
- - - - - 匹配拥有数据源上线权限的成员 - -
-
-
-
-
-
-
-
-
-
-
-
- - 允许创建工单的最高审核等级 - - - 告警(Warning) - -
-
-
-
-
-
-
-
-
-
- - 注意事项 - -
-
    -
  • - 若项目管理员对审批流程模板进行了修改,不会对已经在审批流程的工单造成影响; -
  • -
  • - 被驳回的工单,需要创建人更新SQL语句后重新发起,驳回记录可在 “工单进度-工单历史操作” 中查看; -
  • -
  • - 处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭; -
  • -
  • - 审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作; -
  • -
  • - 上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。 -
  • -
-
-
-
- - 审批流程模板更新时间 - -
- - - - - 2023-12-26 14:19:12 - -
-
-
-
-
-
-
-
-
- -`; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx index 326a4d82c8..ef92f7b9ab 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx @@ -1,32 +1,23 @@ import { t } from '../../../locale'; import { - PERMISSIONS, - PermissionControl + ActiontechTableActionsWithPermissions, + PERMISSIONS } from '@actiontech/shared/lib/features'; -import { ActionButton } from '@actiontech/shared'; -import { EditOutlined } from '@ant-design/icons'; -import { ROUTE_PATHS } from '@actiontech/dms-kit'; -export const WorkflowTemplatePageHeaderActions = ( - projectID: string, - templateName?: string -): Record<'update-workflow-template', React.ReactNode> => ({ - 'update-workflow-template': ( - - } - text={t('workflowTemplate.detail.updateTemplate')} - actionType="navigate-link" - link={{ - to: ROUTE_PATHS.SQLE.PROGRESS.update, - params: { - projectID, - workflowName: templateName ?? '' - } - }} - /> - - ) +import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; + +export const WorkflowTemplateTableActions: ( + onEdit: (record: IWorkflowTemplateDetailResV1) => void +) => ActiontechTableActionsWithPermissions = ( + onEdit +) => ({ + buttons: [ + { + key: 'edit-workflow-template', + text: t('common.edit'), + buttonProps: (record) => ({ + onClick: () => onEdit(record ?? {}) + }), + permissions: PERMISSIONS.ACTIONS.SQLE.WORKFLOW_TEMPLATE.UPDATE + } + ] }); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx new file mode 100644 index 0000000000..4cfbfa1b88 --- /dev/null +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx @@ -0,0 +1,66 @@ +import { ActiontechTableColumn } from '@actiontech/dms-kit/es/components/ActiontechTable'; +import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; +import { WorkflowTemplateTypeEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; +import { BasicTag } from '@actiontech/dms-kit'; +import { formatTime } from '@actiontech/dms-kit'; +import { t } from '../../../locale'; + +const stepTypeNameMap: Record = { + sql_review: 'workflowTemplate.progressConfig.review.title', + sql_execute: 'workflowTemplate.progressConfig.exec.title', + export_review: 'workflowTemplate.progressConfig.exportReview.title', + export_execute: 'workflowTemplate.progressConfig.exportExecute.title' +}; + +const getStepTypeName = (stepType?: string): string => { + if (!stepType) return '-'; + const i18nKey = stepTypeNameMap[stepType]; + return i18nKey ? t(i18nKey) : stepType; +}; + +export const WorkflowTemplateListColumn = + (): ActiontechTableColumn => { + return [ + { + dataIndex: 'workflow_template_name', + title: () => t('workflowTemplate.list.table.workflowTemplateName') + }, + { + dataIndex: 'workflow_type', + title: () => t('workflowTemplate.list.table.applicableType'), + render: (workflowType) => { + if (workflowType === WorkflowTemplateTypeEnum.data_export) { + return ( + + {t('workflowTemplate.list.type.dataExport')} + + ); + } + return ( + + {t('workflowTemplate.list.type.workflow')} + + ); + } + }, + { + dataIndex: 'workflow_step_template_list', + title: () => t('workflowTemplate.list.table.approvalNodeDesc'), + render: (stepList) => { + if (!stepList || stepList.length === 0) return '-'; + return stepList + .map( + (step: { type?: string }) => getStepTypeName(step.type) + ) + .join(' -> '); + } + }, + { + dataIndex: 'update_time', + title: () => t('workflowTemplate.list.table.updateTime'), + render: (value) => { + return formatTime(value, '-'); + } + } + ]; + }; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx index 2557caa0f6..8672ba519b 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx @@ -8,12 +8,10 @@ import { act, cleanup, screen } from '@testing-library/react'; import workflowTemplate from '@actiontech/shared/lib/testUtil/mockApi/sqle/workflowTemplate'; import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentUser'; -import user from '@actiontech/shared/lib/testUtil/mockApi/sqle/user'; describe('page/WorkflowTemplate CE', () => { beforeEach(() => { workflowTemplate.mockAllApi(); - user.mockAllApi(); mockUseCurrentProject(); mockUseCurrentUser(); jest.useFakeTimers(); @@ -28,14 +26,12 @@ describe('page/WorkflowTemplate CE', () => { return sqleSuperRender(); }; - it('render workflow template detail', async () => { - const getInfoRequest = workflowTemplate.getWorkflowTemplate(); - const userInfoRequest = user.getUserTipList(); + it('render workflow template list without edit actions in CE', async () => { + const getListRequest = workflowTemplate.getWorkflowTemplateList(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); - expect(getInfoRequest).toHaveBeenCalled(); - expect(userInfoRequest).toHaveBeenCalled(); + expect(getListRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); - expect(screen.queryByText('修改当前审批流程模板')).not.toBeInTheDocument(); + expect(screen.getByText('审批流程模板')).toBeInTheDocument(); }); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx index 8c48e3e424..a3af58e417 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx @@ -1,19 +1,10 @@ import { sqleSuperRender } from '../../../testUtils/superRender'; import WorkflowTemplateDetail from '.'; -import { workflowTemplateData } from '@actiontech/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data'; import { act, cleanup, screen } from '@testing-library/react'; import workflowTemplate from '@actiontech/shared/lib/testUtil/mockApi/sqle/workflowTemplate'; import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentUser'; -import { getBySelector } from '@actiontech/shared/lib/testUtil/customQuery'; -import { - mockProjectInfo, - mockCurrentUserReturn -} from '@actiontech/shared/lib/testUtil/mockHook/data'; -import { createSpySuccessResponse } from '@actiontech/shared/lib/testUtil/mockApi'; -import user from '@actiontech/shared/lib/testUtil/mockApi/sqle/user'; import { mockUsePermission } from '@actiontech/shared/lib/testUtil/mockHook/mockUsePermission'; -import { SystemRole } from '@actiontech/dms-kit'; jest.mock('react-redux', () => { return { @@ -25,7 +16,6 @@ jest.mock('react-redux', () => { describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { beforeEach(() => { workflowTemplate.mockAllApi(); - user.mockAllApi(); mockUseCurrentProject(); mockUseCurrentUser(); jest.useFakeTimers(); @@ -43,108 +33,30 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { return sqleSuperRender(); }; - it('render workflow template detail', async () => { - const getInfoRequest = workflowTemplate.getWorkflowTemplate(); - const userInfoRequest = user.getUserTipList(); + it('render workflow template list', async () => { + const getListRequest = workflowTemplate.getWorkflowTemplateList(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); - expect(getInfoRequest).toHaveBeenCalled(); - expect(userInfoRequest).toHaveBeenCalled(); + expect(getListRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); expect(screen.getByText('审批流程模板')).toBeInTheDocument(); - expect(getBySelector('a')).toBeInTheDocument(); - expect(getBySelector('a')).toHaveAttribute( - 'href', - `/sqle/project/${mockProjectInfo.projectID}/progress/update/${workflowTemplateData.workflow_template_name}` - ); - - expect(screen.getByText('工单发起/工单更新SQL语句')).toBeInTheDocument(); - expect(screen.getAllByText('审核节点')?.[0]).toBeInTheDocument(); - expect(screen.getByText('执行上线')).toBeInTheDocument(); - - expect(screen.getByText('告警(Warning)')).toBeInTheDocument(); - expect(screen.getByText('2023-12-26 14:19:12')).toBeInTheDocument(); }); - it('render workflow template detail without permission', async () => { - // not admin or global manager or project manager - mockUseCurrentUser({ - ...mockCurrentUserReturn, - userRoles: { - ...mockCurrentUserReturn.userRoles, - [SystemRole.admin]: false, - [SystemRole.systemAdministrator]: false - } - }); - const getInfoRequest = workflowTemplate.getWorkflowTemplate(); - const userInfoRequest = user.getUserTipList(); - const { baseElement } = customRender(); - await act(async () => jest.advanceTimersByTime(3000)); - expect(getInfoRequest).toHaveBeenCalled(); - expect(userInfoRequest).toHaveBeenCalled(); - expect(baseElement).toMatchSnapshot(); - expect(screen.queryByText('修改当前审批流程模板')).not.toBeInTheDocument(); - - // project manager - cleanup(); - mockUseCurrentUser({ - ...mockCurrentUserReturn, - userRoles: { - ...mockCurrentUserReturn.userRoles, - [SystemRole.admin]: false, - [SystemRole.systemAdministrator]: false - }, - bindProjects: [ - { - is_manager: true, - project_name: mockProjectInfo.projectName, - project_id: mockProjectInfo.projectID, - archived: false - } - ] - }); + it('render workflow type tags correctly', async () => { + workflowTemplate.getWorkflowTemplateList(); customRender(); - expect(screen.getByText('修改当前审批流程模板')).toBeInTheDocument(); - - // project is archived - cleanup(); - mockUseCurrentUser({ - ...mockCurrentUserReturn, - userRoles: { - ...mockCurrentUserReturn.userRoles, - [SystemRole.admin]: false, - [SystemRole.systemAdministrator]: false - }, - bindProjects: [ - { - is_manager: true, - project_name: mockProjectInfo.projectName, - project_id: mockProjectInfo.projectID, - archived: true - } - ] - }); - customRender(); - expect(screen.queryByText('修改当前审批流程模板')).not.toBeInTheDocument(); + await act(async () => jest.advanceTimersByTime(3000)); + expect(screen.getByText('上线工单')).toBeInTheDocument(); + expect(screen.getByText('数据导出')).toBeInTheDocument(); }); - it('render workflow template detail with no review step', async () => { - const getInfoRequest = workflowTemplate.getWorkflowTemplate(); - getInfoRequest.mockImplementation(() => { - const execStepData = - workflowTemplateData.workflow_step_template_list.pop(); - return createSpySuccessResponse({ - data: { - ...workflowTemplateData, - workflow_step_template_list: [execStepData] - } - }); - }); - const { baseElement } = customRender(); + it('render approval node description', async () => { + workflowTemplate.getWorkflowTemplateList(); + customRender(); await act(async () => jest.advanceTimersByTime(3000)); - expect(getInfoRequest).toHaveBeenCalled(); - expect(baseElement).toMatchSnapshot(); - expect(screen.getByText('审批流程模板')).toBeInTheDocument(); - expect(screen.getByText('执行上线')).toBeInTheDocument(); + expect( + screen.getByText('审核节点 -> 审核节点 -> 执行上线') + ).toBeInTheDocument(); + expect(screen.getByText('导出审批')).toBeInTheDocument(); }); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx index a7189e0f61..d0386ede54 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx @@ -1,88 +1,81 @@ -import { Col, Row, Spin } from 'antd'; -import React, { useState } from 'react'; -import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; +import { useMemo, useCallback } from 'react'; import { useRequest } from 'ahooks'; -import { useCurrentProject } from '@actiontech/shared/lib/features'; -import WorkflowTemplateAuthInfo from './components/WorkflowTemplateAuthInfo'; -import WorkflowTemplateStepInfo from './components/WorkflowTemplateStepInfo'; -import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; -import { PageHeader } from '@actiontech/dms-kit'; import { useTranslation } from 'react-i18next'; -import { WorkflowTemplateStyleWrapper } from './style'; -import useUsername from '../../../hooks/useUsername'; -import { WorkflowTemplatePageHeaderActions } from './actions'; +import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; +import { + useCurrentProject, + usePermission +} from '@actiontech/shared/lib/features'; +import { useTypedNavigate } from '@actiontech/shared'; +import { ROUTE_PATHS } from '@actiontech/dms-kit'; +import { PageHeader } from '@actiontech/dms-kit'; +import { + ActiontechTable, + ActiontechTableWrapper +} from '@actiontech/dms-kit/es/components/ActiontechTable'; +import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; +import { WorkflowTemplateListColumn } from './column'; +import { WorkflowTemplateTableActions } from './actions'; + const WorkflowTemplateDetail: React.FC = () => { const { t } = useTranslation(); const { projectName, projectID } = useCurrentProject(); - const { - updateUsernameList, - usernameList, - loading: getUsernameListLoading - } = useUsername(); - React.useEffect(() => { - updateUsernameList({ - filter_project: projectName - }); - }, [projectName, updateUsernameList]); - const [reviewSteps, setReviewSteps] = useState( - [] + const { parse2TableActionPermissions } = usePermission(); + const navigate = useTypedNavigate(); + + const columns = useMemo(() => WorkflowTemplateListColumn(), []); + + const { data: templateList, loading } = useRequest( + () => + workflow + .getWorkflowTemplateListV1({ + project_name: projectName + }) + .then((res) => res.data.data ?? []), + { + ready: !!projectName + } ); - const [execSteps, setExecSteps] = useState({ - assignee_user_id_list: [], - desc: '' - }); - const { data: workflowTemplate, loading: getWorkflowTemplateLoading } = - useRequest( - () => - workflow - .getWorkflowTemplateV1({ - project_name: projectName - }) - .then((res) => { - const stepList = res.data.data?.workflow_step_template_list ?? []; - if (stepList.length <= 1) { - setExecSteps(stepList[0]); - } else { - const execStep = stepList.pop(); - setReviewSteps(stepList); - if (execStep) setExecSteps(execStep); - } - return res.data.data; - }), - { - ready: !!projectName - } - ); - const pageHeaderActions = WorkflowTemplatePageHeaderActions( - projectID, - workflowTemplate?.workflow_template_name + + const onEditTemplate = useCallback( + (record: IWorkflowTemplateDetailResV1) => { + navigate(ROUTE_PATHS.SQLE.PROGRESS.update, { + params: { + projectID, + workflowName: record.workflow_template_name ?? '' + }, + queries: { + workflowType: record.workflow_type ?? '' + } + }); + }, + [navigate, projectID] ); + + const actions = useMemo(() => { + return parse2TableActionPermissions( + WorkflowTemplateTableActions(onEditTemplate) + ); + }, [parse2TableActionPermissions, onEditTemplate]); + return ( - - - - - - - - - - - - - + <> + + + + record?.workflow_template_name ?? '' + } + loading={loading} + columns={columns} + // #if [ee] + actions={actions} + // #endif + /> + + ); }; + export default WorkflowTemplateDetail; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts index 392f85f8bd..d63644aa9c 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts @@ -2,14 +2,4 @@ import { styled } from '@mui/material/styles'; export const WorkflowTemplateStyleWrapper = styled('div')` height: 100%; - - .workflow-template-wrapper { - height: 100%; - } - - .workflow-template-right-module { - border-left: ${({ theme }) => - theme.sqleTheme.workflowTemplate.workflowTemplateAuthInfo.borderBottom}; - height: auto; - } `; From 59cf60e7f55c4cff360163c897c50a0034ddc740 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Tue, 21 Apr 2026 08:37:44 +0000 Subject: [PATCH 14/36] feat(workflow-template): differentiate edit page by workflow type - DEV-025: Read workflowType from URL query params, switch step type enums (export_review/export_execute vs sql_review/sql_execute) and page title based on workflow type, pass workflow_type to API calls - DEV-026: Hide AllowSubmitWhenLessAuditLevel field in BasicInfo component when editing data_export type template - Add query field to PROGRESS.update route definition for workflowType - Fix TS error in column.tsx stepTypeNameMap by using I18nKey type - Prettier formatting fixes refs actiontech/dms-ee#784 (cherry picked from commit 966319e09eb8dd6f0389c32118d9f9dbe28654c2) --- packages/dms-kit/src/data/routePaths.ts | 3 +- .../lib/api/sqle/service/workflow/index.ts | 4 +- .../mockApi/sqle/workflowTemplate/index.ts | 5 +- .../sqle/src/locale/en-US/workflowTemplate.ts | 3 +- .../components/BasicInfo/index.tsx | 50 ++++++++++--------- .../components/BasicInfo/index.type.ts | 1 + .../UpdateWorkflowTemplate/index.tsx | 38 +++++++++++--- .../WorkflowTemplateDetail/column.tsx | 8 ++- 8 files changed, 67 insertions(+), 45 deletions(-) diff --git a/packages/dms-kit/src/data/routePaths.ts b/packages/dms-kit/src/data/routePaths.ts index c5d8b7c504..4edda84e33 100644 --- a/packages/dms-kit/src/data/routePaths.ts +++ b/packages/dms-kit/src/data/routePaths.ts @@ -325,7 +325,8 @@ export const ROUTE_PATHS = { }, update: { prefix: '/sqle/project/:projectID/progress', - path: 'update/:workflowName' + path: 'update/:workflowName', + query: 'workflowType' } }, WHITELIST: { diff --git a/packages/shared/lib/api/sqle/service/workflow/index.ts b/packages/shared/lib/api/sqle/service/workflow/index.ts index 4d4a698fe1..2eed9af557 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.ts @@ -194,9 +194,7 @@ class WorkflowService extends ServiceBase { const workflow_type = paramsData.workflow_type; delete paramsData.workflow_type; - const queryString = workflow_type - ? `?workflow_type=${workflow_type}` - : ''; + const queryString = workflow_type ? `?workflow_type=${workflow_type}` : ''; return this.patch( `/v1/projects/${project_name}/workflow_template${queryString}`, diff --git a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts index 87a85ff092..819cf80a27 100644 --- a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts +++ b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts @@ -1,9 +1,6 @@ import workflow from '../../../../api/sqle/service/workflow'; import { MockSpyApy, createSpySuccessResponse } from '../../common'; -import { - workflowTemplateData, - workflowTemplateListData -} from './data'; +import { workflowTemplateData, workflowTemplateListData } from './data'; import { cloneDeep } from 'lodash'; class MockWorkflowTemplateApi implements MockSpyApy { diff --git a/packages/sqle/src/locale/en-US/workflowTemplate.ts b/packages/sqle/src/locale/en-US/workflowTemplate.ts index 59be44862f..c68a9b89ae 100644 --- a/packages/sqle/src/locale/en-US/workflowTemplate.ts +++ b/packages/sqle/src/locale/en-US/workflowTemplate.ts @@ -144,8 +144,7 @@ export default { }, exportReview: { title: 'Export Review', - subTitle: - 'Reviewer checks the legitimacy of the export request' + subTitle: 'Reviewer checks the legitimacy of the export request' }, exportExecute: { title: 'Export Execution Confirm', diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx index 3216bb5c4e..df97d96e7f 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx @@ -9,14 +9,16 @@ import StepButton from '../StepButton'; import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; const BasicInfo: React.FC = (props) => { const { t } = useTranslation(); - const { form } = props; + const { form, workflowType } = props; const { getAuditLevelStatusSelectOption } = useStaticStatus(); + const isDataExport = workflowType === 'data_export'; const nextStep = async () => { const value = await form.validateFields(); props.updateBaseInfo(value?.allowSubmitWhenLessAuditLevel); props.nextStep(); }; useEffect(() => { + if (isDataExport) return; if (!!props.defaultData) { form.setFieldsValue({ allowSubmitWhenLessAuditLevel: props.defaultData @@ -30,7 +32,7 @@ const BasicInfo: React.FC = (props) => { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum.warn }); } - }, [form, props.defaultData]); + }, [form, props.defaultData, isDataExport]); const handleChangeLevel = ( level: WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum ) => { @@ -49,28 +51,30 @@ const BasicInfo: React.FC = (props) => {
- - - {getAuditLevelStatusSelectOption()} - - + + {getAuditLevelStatusSelectOption()} + + + )} void; totalStep: number; + workflowType?: string; }; export type BaseFormFields = { diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx index 0154e97fd0..98e3c99726 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx @@ -1,5 +1,9 @@ import { BasicButton, BasicResult, PageHeader } from '@actiontech/dms-kit'; -import { ActionButton, useTypedParams } from '@actiontech/shared'; +import { + ActionButton, + useTypedParams, + useTypedQuery +} from '@actiontech/shared'; import { ArrowLeftOutlined } from '@ant-design/icons'; import { Col, Row, Space, Spin } from 'antd'; import React, { useState } from 'react'; @@ -41,6 +45,23 @@ const UpdateWorkflowTemplate: React.FC = () => { const [updateSuccess, setUpdateSuccess] = useState(false); const urlParams = useTypedParams(); const { projectName, projectID } = useCurrentProject(); + const extractQueries = useTypedQuery(); + const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.update); + const workflowType = searchParams?.workflowType || 'workflow'; + + const pageTitle = + workflowType === 'data_export' + ? t('workflowTemplate.update.title.dataExport') + : t('workflowTemplate.update.title.workflow'); + + const reviewType = + workflowType === 'data_export' + ? WorkFlowStepTemplateReqV1TypeEnum.export_review + : WorkFlowStepTemplateReqV1TypeEnum.sql_review; + const executeType = + workflowType === 'data_export' + ? WorkFlowStepTemplateReqV1TypeEnum.export_execute + : WorkFlowStepTemplateReqV1TypeEnum.sql_execute; const { loading: getUsernameListLoading, updateUsernameList, @@ -63,19 +84,20 @@ const UpdateWorkflowTemplate: React.FC = () => { await form?.validateFields(); const reviewTempData = reviewSteps.map((item) => ({ ...item, - type: WorkFlowStepTemplateReqV1TypeEnum.sql_review + type: reviewType })); const templateList: IWorkFlowStepTemplateReqV1[] = [ ...reviewTempData, { ...execSteps, - type: WorkFlowStepTemplateReqV1TypeEnum.sql_execute + type: executeType } ]; startSubmit(); return workflow .updateWorkflowTemplateV1({ project_name: projectName, + workflow_type: workflowType, workflow_step_template_list: templateList, allow_submit_when_less_audit_level: selectLevel as | UpdateWorkflowTemplateReqV1AllowSubmitWhenLessAuditLevelEnum @@ -92,7 +114,8 @@ const UpdateWorkflowTemplate: React.FC = () => { () => workflow .getWorkflowTemplateV1({ - project_name: projectName + project_name: projectName, + workflow_type: workflowType }) .then((res) => { const temp = res.data.data; @@ -150,6 +173,7 @@ const UpdateWorkflowTemplate: React.FC = () => { nextStep={nextStep} updateBaseInfo={updateBaseInfo} totalStep={reviewSteps.length + 2} + workflowType={workflowType} /> ); } @@ -184,7 +208,7 @@ const UpdateWorkflowTemplate: React.FC = () => { assignee_user_id_list: [], desc: '', approved_by_authorized: true, - type: WorkFlowStepTemplateReqV1TypeEnum.sql_review + type: reviewType } ]); setCurrentStep(reviewSteps.length + 1); @@ -204,7 +228,7 @@ const UpdateWorkflowTemplate: React.FC = () => { assignee_user_id_list: [], desc: '', execute_by_authorized: true, - type: WorkFlowStepTemplateReqV1TypeEnum.sql_execute + type: executeType }); }; const handleExchangeReviewNode = (from: number, to: number) => { @@ -232,7 +256,7 @@ const UpdateWorkflowTemplate: React.FC = () => { } - text={t('workflowTemplate.create.title.returnButton')} + text={pageTitle} actionType="navigate-link" link={{ to: ROUTE_PATHS.SQLE.PROGRESS.index, diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx index 4cfbfa1b88..633ae6ef0e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx @@ -3,9 +3,9 @@ import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/se import { WorkflowTemplateTypeEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; import { BasicTag } from '@actiontech/dms-kit'; import { formatTime } from '@actiontech/dms-kit'; -import { t } from '../../../locale'; +import { t, I18nKey } from '../../../locale'; -const stepTypeNameMap: Record = { +const stepTypeNameMap: Record = { sql_review: 'workflowTemplate.progressConfig.review.title', sql_execute: 'workflowTemplate.progressConfig.exec.title', export_review: 'workflowTemplate.progressConfig.exportReview.title', @@ -49,9 +49,7 @@ export const WorkflowTemplateListColumn = render: (stepList) => { if (!stepList || stepList.length === 0) return '-'; return stepList - .map( - (step: { type?: string }) => getStepTypeName(step.type) - ) + .map((step: { type?: string }) => getStepTypeName(step.type)) .join(' -> '); } }, From 1d5c20f24ddefbcaa16f5afe8721c4e2d4dd85ac Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Tue, 21 Apr 2026 08:52:00 +0000 Subject: [PATCH 15/36] feat(data-export): add approval process preview component to data export creation page - DEV-027: New ApprovalProcessPreview component with read-only workflow step display - Calls getWorkflowTemplateV1 with workflow_type=data_export to fetch template - Renders step list with step number, step type name, and assignee info - Shows "match by permission" when approved_by_authorized/execute_by_authorized is true - Loading state with Spin, error state with Result fallback - Bottom hint guiding users to modify approval process in Project Configure - DEV-028: Integrate preview between BasicInfoWrapper and AuditResultList in SubmitWorkflow - Add step type name i18n keys (export_review/export_execute) to base package dmsDataExport refs actiontech/dms-ee#784 (cherry picked from commit 58397af27ee9914de241e531e8c146e3d613bdcc) --- .../base/src/locale/en-US/dmsDataExport.ts | 6 +- .../base/src/locale/zh-CN/dmsDataExport.ts | 6 +- .../ApprovalProcessPreview/index.tsx | 105 ++++++++++++++++++ .../ApprovalProcessPreview/style.ts | 46 ++++++++ .../components/SubmitWorkflow/index.tsx | 5 +- 5 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx create mode 100644 packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts diff --git a/packages/base/src/locale/en-US/dmsDataExport.ts b/packages/base/src/locale/en-US/dmsDataExport.ts index 6d25445c00..fba5efe8a6 100644 --- a/packages/base/src/locale/en-US/dmsDataExport.ts +++ b/packages/base/src/locale/en-US/dmsDataExport.ts @@ -62,7 +62,11 @@ export default { hint: 'Approval process can be modified in Project Configure > Approval Process', stepLabel: 'Step {{number}}', matchByPermission: 'Match by Permission', - loadFailed: 'Failed to load approval process' + loadFailed: 'Failed to load approval process', + stepType: { + export_review: 'Export Review', + export_execute: 'Export Execution Confirm' + } } }, batchClose: { diff --git a/packages/base/src/locale/zh-CN/dmsDataExport.ts b/packages/base/src/locale/zh-CN/dmsDataExport.ts index 80b18dd8d0..ed1601ef33 100644 --- a/packages/base/src/locale/zh-CN/dmsDataExport.ts +++ b/packages/base/src/locale/zh-CN/dmsDataExport.ts @@ -57,7 +57,11 @@ export default { hint: '审批流程可在 Project Configure > Approval Process 中修改', stepLabel: '步骤 {{number}}', matchByPermission: '按权限匹配', - loadFailed: '加载审批流程失败' + loadFailed: '加载审批流程失败', + stepType: { + export_review: '导出审批', + export_execute: '导出执行确认' + } }, update: { baseTitle: '工单基本信息', diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx new file mode 100644 index 0000000000..2b0b7f4658 --- /dev/null +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx @@ -0,0 +1,105 @@ +import { useTranslation } from 'react-i18next'; +import { useRequest } from 'ahooks'; +import { Spin, Space, Typography } from 'antd'; +import { Result } from 'antd'; +import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; +import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; +import { ApprovalProcessPreviewStyleWrapper } from './style'; + +interface ApprovalProcessPreviewProps { + projectName: string; +} + +const stepTypeNameMap: Record = { + export_review: 'dmsDataExport.create.approvalProcess.stepType.export_review', + export_execute: 'dmsDataExport.create.approvalProcess.stepType.export_execute' +}; + +const ApprovalProcessPreview: React.FC = ({ + projectName +}) => { + const { t } = useTranslation(); + + const { + data: templateData, + loading, + error + } = useRequest( + () => + workflow + .getWorkflowTemplateV1({ + project_name: projectName, + workflow_type: 'data_export' + }) + .then((res) => res.data.data), + { + ready: !!projectName + } + ); + + const renderAssigneeInfo = (step: IWorkFlowStepTemplateResV1) => { + if (step.approved_by_authorized || step.execute_by_authorized) { + return t('dmsDataExport.create.approvalProcess.matchByPermission'); + } + if (step.assignee_user_id_list && step.assignee_user_id_list.length > 0) { + return step.assignee_user_id_list.join(', '); + } + return '-'; + }; + + const renderStepTypeName = (type?: string) => { + if (type && stepTypeNameMap[type]) { + return t(stepTypeNameMap[type]); + } + return type ?? '-'; + }; + + if (error) { + return ( + + + + ); + } + + return ( + + +
+ {t('dmsDataExport.create.approvalProcess.title')} +
+ + {templateData?.workflow_step_template_list?.map( + (step: IWorkFlowStepTemplateResV1, index: number) => ( +
+
+ + + {t('dmsDataExport.create.approvalProcess.stepLabel', { + number: step.number ?? index + 1 + })} + + + {renderStepTypeName(step.type)} + + +
+
+ {renderAssigneeInfo(step)} +
+
+ ) + )} + +
+ {t('dmsDataExport.create.approvalProcess.hint')} +
+
+
+ ); +}; + +export default ApprovalProcessPreview; diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts new file mode 100644 index 0000000000..6423e16dda --- /dev/null +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts @@ -0,0 +1,46 @@ +import { styled } from '@mui/material/styles'; + +export const ApprovalProcessPreviewStyleWrapper = styled('div')` + padding: 24px 40px; + border-bottom: 1px solid + ${({ theme }) => theme.sharedTheme.basic.colorGrayLine}; + + .approval-process-title { + color: ${({ theme }) => theme.sharedTheme.uiToken.colorText}; + font-size: 16px; + font-weight: 500; + line-height: 24px; + margin-bottom: 16px; + } + + .approval-process-step { + padding: 12px 16px; + margin-bottom: 8px; + border-radius: 8px; + border: 1px solid ${({ theme }) => theme.sharedTheme.basic.colorGrayLine}; + background: ${({ theme }) => theme.sharedTheme.uiToken.colorFillQuaternary}; + + .approval-process-step-header { + margin-bottom: 4px; + + .step-number { + color: ${({ theme }) => theme.sharedTheme.uiToken.colorText}; + font-weight: 500; + font-size: 14px; + } + } + + .approval-process-step-assignee { + color: ${({ theme }) => theme.sharedTheme.uiToken.colorTextSecondary}; + font-size: 13px; + line-height: 20px; + } + } + + .approval-process-hint { + margin-top: 12px; + color: ${({ theme }) => theme.sharedTheme.uiToken.colorTextTertiary}; + font-size: 13px; + line-height: 20px; + } +`; diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx index 75e37bfff7..360857267e 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx @@ -15,6 +15,7 @@ import { CreateDataExportPageEnum } from '../../../../../store/dataExport'; import useCheckTaskAuditRuleExceptionStatus from '../../hooks/useCheckTaskAuditRuleExceptionStatus'; import { IListDataExportTaskSQL } from '@actiontech/shared/lib/api/base/service/common'; import SubmitWorkflowButton from './SubmitWorkflowButton'; +import ApprovalProcessPreview from './ApprovalProcessPreview'; const SubmitExportWorkflow: React.FC = () => { const { t } = useTranslation(); const { @@ -27,7 +28,7 @@ const SubmitExportWorkflow: React.FC = () => { updatePageState, updateWorkflowID } = useCreateDataExportReduxManage(); - const { projectID } = useCurrentProject(); + const { projectID, projectName } = useCurrentProject(); const [executeSQLsIsDQL, updateExecuteSQLsTypeIsDQL] = useState(true); const { hasExceptionAuditRule, @@ -105,6 +106,8 @@ const SubmitExportWorkflow: React.FC = () => { desc={formValues?.baseValues?.desc} /> + + Date: Tue, 21 Apr 2026 09:44:39 +0000 Subject: [PATCH 16/36] test(workflow-template): add/update unit tests for workflow template components - DEV-030: Update WorkflowTemplateDetail list page tests to cover edit button navigation with workflowType param, fix CE test missing usePermission mock - DEV-031: Update UpdateWorkflowTemplate edit page tests to mock useTypedQuery for workflowType, add data_export type title and step type tests, update BasicInfo test for hidden audit level field - DEV-032: Add ApprovalProcessPreview component tests covering loading state, success rendering, error fallback, step type name mapping, assignee display, and empty projectName guard refs actiontech/dms-ee#784 (cherry picked from commit 9b4a1b1ac6d301c2f4cc182503a934877c025d03) --- .../__snapshots__/index.test.tsx.snap | 165 ++++++++++++ .../__tests__/index.test.tsx | 135 ++++++++++ .../__snapshots__/index.test.tsx.snap | 20 +- .../__snapshots__/index.test.tsx.snap | 45 ++++ .../components/BasicInfo/index.test.tsx | 21 +- .../UpdateWorkflowTemplate/index.test.tsx | 55 +++- .../__snapshots__/index.ce.test.tsx.snap | 192 ++++++++++++++ .../__snapshots__/index.test.tsx.snap | 250 ++++++++++++++++++ .../WorkflowTemplateDetail/index.ce.test.tsx | 17 ++ .../WorkflowTemplateDetail/index.test.tsx | 46 +++- 10 files changed, 932 insertions(+), 14 deletions(-) create mode 100644 packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap create mode 100644 packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx create mode 100644 packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap create mode 100644 packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap new file mode 100644 index 0000000000..3d4d58f9a5 --- /dev/null +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap @@ -0,0 +1,165 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`base/DataExport/Create/ApprovalProcessPreview should render fallback error state when request fails 1`] = ` + +
+
+
+
+ + + +
+
+
+ 加载审批流程失败 +
+
+
+
+ +`; + +exports[`base/DataExport/Create/ApprovalProcessPreview should render loading state 1`] = ` + +
+
+
+
+
+ + + + + + +
+
+
+
+ 审批流程 +
+
+ 审批流程可在 Project Configure > Approval Process 中修改 +
+
+
+
+
+ +`; + +exports[`base/DataExport/Create/ApprovalProcessPreview should render step list when data loaded successfully 1`] = ` + +
+
+
+
+
+ 审批流程 +
+
+
+
+
+ + 步骤 1 + +
+
+ + 导出审批 + +
+
+
+
+ 按权限匹配 +
+
+
+ 审批流程可在 Project Configure > Approval Process 中修改 +
+
+
+
+
+ +`; diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx new file mode 100644 index 0000000000..285b4c9910 --- /dev/null +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx @@ -0,0 +1,135 @@ +import { act, screen } from '@testing-library/react'; +import { baseSuperRender } from '../../../../../../../testUtils/superRender'; +import ApprovalProcessPreview from '..'; +import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; +import { + createSpySuccessResponse, + createSpyErrorResponse +} from '@actiontech/shared/lib/testUtil/mockApi'; +import { dataExportWorkflowTemplateData } from '@actiontech/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data'; +import { cloneDeep } from 'lodash'; + +describe('base/DataExport/Create/ApprovalProcessPreview', () => { + beforeEach(() => { + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + jest.clearAllMocks(); + }); + + const customRender = (projectName = 'test-project') => { + return baseSuperRender( + + ); + }; + + it('should render loading state', () => { + jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation( + () => + new Promise(() => { + /* never resolves to keep loading */ + }) + ); + const { baseElement } = customRender(); + expect(baseElement).toMatchSnapshot(); + }); + + it('should render step list when data loaded successfully', async () => { + const getTemplateSpy = jest + .spyOn(workflow, 'getWorkflowTemplateV1') + .mockImplementation(() => + createSpySuccessResponse({ + data: cloneDeep(dataExportWorkflowTemplateData) + }) + ); + const { baseElement } = customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + + expect(getTemplateSpy).toHaveBeenCalledWith({ + project_name: 'test-project', + workflow_type: 'data_export' + }); + expect(screen.getByText('审批流程')).toBeInTheDocument(); + expect(screen.getByText('导出审批')).toBeInTheDocument(); + expect(screen.getByText('按权限匹配')).toBeInTheDocument(); + expect( + screen.getByText( + '审批流程可在 Project Configure > Approval Process 中修改' + ) + ).toBeInTheDocument(); + expect(baseElement).toMatchSnapshot(); + }); + + it('should render fallback error state when request fails', async () => { + jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation(() => + createSpyErrorResponse({}) + ); + const { baseElement } = customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + + expect(screen.getByText('加载审批流程失败')).toBeInTheDocument(); + expect(baseElement).toMatchSnapshot(); + }); + + it('should render correct step type names for export_review and export_execute', async () => { + const multiStepData = cloneDeep(dataExportWorkflowTemplateData); + multiStepData.workflow_step_template_list = [ + { + approved_by_authorized: true, + assignee_user_id_list: [], + execute_by_authorized: false, + number: 1, + type: 'export_review' + }, + { + approved_by_authorized: false, + assignee_user_id_list: [], + execute_by_authorized: true, + number: 2, + type: 'export_execute' + } + ]; + jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation(() => + createSpySuccessResponse({ + data: multiStepData + }) + ); + customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + + expect(screen.getByText('导出审批')).toBeInTheDocument(); + expect(screen.getByText('导出执行确认')).toBeInTheDocument(); + }); + + it('should render assignee user list when not matched by permission', async () => { + const customData = cloneDeep(dataExportWorkflowTemplateData); + customData.workflow_step_template_list = [ + { + approved_by_authorized: false, + assignee_user_id_list: ['user1', 'user2'], + execute_by_authorized: false, + number: 1, + type: 'export_review' + } + ]; + jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation(() => + createSpySuccessResponse({ + data: customData + }) + ); + customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + + expect(screen.getByText('user1, user2')).toBeInTheDocument(); + }); + + it('should not make API call when projectName is empty', () => { + const getTemplateSpy = jest + .spyOn(workflow, 'getWorkflowTemplateV1') + .mockImplementation(() => createSpySuccessResponse({ data: {} })); + customRender(''); + expect(getTemplateSpy).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap index fb864dc284..9ada633d8d 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap @@ -20,7 +20,7 @@ exports[`page/WorkflowTemplate/UpdateWorkflowTemplate change workflow template n />
- 返回审批流程模板 + 编辑审批流程 - 上线工单 @@ -712,7 +712,7 @@ exports[`page/WorkflowTemplate/UpdateWorkflowTemplate no review node in template />
- 返回审批流程模板 + 编辑审批流程 - 上线工单 @@ -1205,7 +1205,7 @@ exports[`page/WorkflowTemplate/UpdateWorkflowTemplate render update workflow tem
- 返回审批流程模板 + 编辑审批流程 - 上线工单 @@ -1881,7 +1881,7 @@ exports[`page/WorkflowTemplate/UpdateWorkflowTemplate render update workflow tem
- 返回审批流程模板 + 编辑审批流程 - 上线工单 @@ -2557,7 +2557,7 @@ exports[`page/WorkflowTemplate/UpdateWorkflowTemplate update workflow template i
- 返回审批流程模板 + 编辑审批流程 - 上线工单 diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/__snapshots__/index.test.tsx.snap index 38907a3002..eb20958d48 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/__snapshots__/index.test.tsx.snap @@ -278,3 +278,48 @@ exports[`page/WorkflowTemplate/BasicInfo render basic info without default data
`; + +exports[`page/WorkflowTemplate/BasicInfo should hide AllowSubmitWhenLessAuditLevel when workflowType is data_export 1`] = ` + +
+
+
+
+ 基本信息 +
+
+ 设定模板的基本信息 +
+
+
+ +
+ +
+ +
+
+
+ +`; diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.test.tsx index 26c8799069..95bfa5c4e5 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.test.tsx @@ -3,7 +3,8 @@ import BasicInfo from '.'; import { act, fireEvent, screen, renderHook } from '@testing-library/react'; import { getAllBySelector, - getBySelector + getBySelector, + queryBySelector } from '@actiontech/shared/lib/testUtil/customQuery'; import { workflowTemplateData } from '@actiontech/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data'; import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; @@ -24,7 +25,7 @@ describe('page/WorkflowTemplate/BasicInfo', () => { const updateMock = jest.fn(); const { result } = renderHook(() => Form.useForm()); - const customRender = (data?: { [key: string]: undefined }) => { + const customRender = (data?: Record) => { return sqleSuperRender( { expect(baseElement).toMatchSnapshot(); expect(screen.getByText('告警(Warning)')).toBeInTheDocument(); }); + + it('should hide AllowSubmitWhenLessAuditLevel when workflowType is data_export', async () => { + const { baseElement } = customRender({ workflowType: 'data_export' }); + expect(baseElement).toMatchSnapshot(); + expect(screen.getByText('基本信息')).toBeInTheDocument(); + expect( + screen.queryByText('允许创建工单的最高审核等级') + ).not.toBeInTheDocument(); + expect( + queryBySelector('.ant-select-selection-search-input') + ).not.toBeInTheDocument(); + + fireEvent.click(screen.getByText('下一步')); + await act(async () => jest.advanceTimersByTime(300)); + expect(nextStepMock).toHaveBeenCalled(); + }); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx index 3f572b005a..cdcadd0f4f 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx @@ -20,18 +20,25 @@ import { UtilsConsoleErrorStringsEnum } from '@actiontech/shared/lib/testUtil/common'; import user from '@actiontech/shared/lib/testUtil/mockApi/sqle/user'; +import { useTypedQuery } from '@actiontech/shared'; jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), useParams: jest.fn() })); +jest.mock('@actiontech/shared', () => ({ + ...jest.requireActual('@actiontech/shared'), + useTypedQuery: jest.fn() +})); + describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { ignoreConsoleErrors([ UtilsConsoleErrorStringsEnum.UNCONNECTED_FORM_COMPONENT ]); const useParamsMock: jest.Mock = useParams as jest.Mock; + const extractQuerySpy = jest.fn(); const customRender = () => { return sqleSuperRender(); @@ -45,6 +52,8 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { mockUseCurrentUser(); jest.useFakeTimers(); workflowTemplate.mockAllApi(); + (useTypedQuery as jest.Mock).mockImplementation(() => extractQuerySpy); + extractQuerySpy.mockReturnValue({ workflowType: 'workflow' }); }); afterEach(() => { @@ -66,7 +75,9 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { expect(getInfoRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); await act(async () => jest.advanceTimersByTime(3000)); - expect(screen.getByText('返回审批流程模板')).toBeInTheDocument(); + expect( + screen.getByText('编辑审批流程 - 上线工单') + ).toBeInTheDocument(); expect(getBySelector('a')).toBeInTheDocument(); expect(getBySelector('a')).toHaveAttribute( 'href', @@ -81,6 +92,7 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { }); expect(updateInfoRequest).toHaveBeenCalledWith({ project_name: mockProjectInfo.projectName, + workflow_type: 'workflow', workflow_step_template_list: workflowTemplateData.workflow_step_template_list, allow_submit_when_less_audit_level: @@ -119,6 +131,7 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { }); expect(updateInfoRequest).toHaveBeenCalledWith({ project_name: mockProjectInfo.projectName, + workflow_type: 'workflow', workflow_step_template_list: workflowTemplateData.workflow_step_template_list, allow_submit_when_less_audit_level: @@ -176,6 +189,7 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { }); expect(updateInfoRequest).toHaveBeenCalledWith({ project_name: mockProjectInfo.projectName, + workflow_type: 'workflow', workflow_step_template_list: tempList, allow_submit_when_less_audit_level: UpdateWorkflowTemplateReqV1AllowSubmitWhenLessAuditLevelEnum.normal @@ -246,4 +260,43 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { await act(async () => jest.advanceTimersByTime(300)); }); }); + + describe('data_export workflow type', () => { + beforeEach(() => { + extractQuerySpy.mockReturnValue({ workflowType: 'data_export' }); + }); + + it('should render data export title when workflowType is data_export', async () => { + workflowTemplate.getWorkflowTemplate(); + user.getUserTipList(); + customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + await act(async () => jest.advanceTimersByTime(3000)); + expect( + screen.getByText('编辑审批流程 - 数据导出') + ).toBeInTheDocument(); + }); + + it('should use export step types when workflowType is data_export', async () => { + workflowTemplate.getWorkflowTemplate(); + const updateInfoRequest = workflowTemplate.updateWorkflowTemplate(); + user.getUserTipList(); + customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + await act(async () => jest.advanceTimersByTime(3000)); + + fireEvent.click(screen.getByText('下一步')); + await act(async () => jest.advanceTimersByTime(3000)); + + await act(async () => { + fireEvent.click(screen.getByText('保 存')); + await act(async () => jest.advanceTimersByTime(300)); + }); + expect(updateInfoRequest).toHaveBeenCalledWith( + expect.objectContaining({ + workflow_type: 'data_export' + }) + ); + }); + }); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap new file mode 100644 index 0000000000..eda47a95cf --- /dev/null +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap @@ -0,0 +1,192 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`page/WorkflowTemplate CE render workflow template list without edit actions in CE 1`] = ` + +
+
+
+ 审批流程模板 +
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 审批流程模板名称 + + 适用类型 + + 审批节点描述 + + 更新时间 +
+ 700300-WorkflowTemplate + + + 上线工单 + + + 审核节点 -> 审核节点 -> 执行上线 + + 2023-12-26 14:19:12 +
+ 700300-DataExportWorkflowTemplate + + + 数据导出 + + + 导出审批 + + 2024-01-15 10:30:00 +
+
+
+
+
+
+
+
+
+
+ +`; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap new file mode 100644 index 0000000000..4135a84379 --- /dev/null +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap @@ -0,0 +1,250 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`page/WorkflowTemplate/WorkflowTemplateDetail render workflow template list 1`] = ` + +
+
+
+ 审批流程模板 +
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 审批流程模板名称 + + 适用类型 + + 审批节点描述 + + 更新时间 + + 操作 +
+ 700300-WorkflowTemplate + + + 上线工单 + + + 审核节点 -> 审核节点 -> 执行上线 + + 2023-12-26 14:19:12 + +
+ +
+
+ 700300-DataExportWorkflowTemplate + + + 数据导出 + + + 导出审批 + + 2024-01-15 10:30:00 + +
+ +
+
+
+
+
+
+
+
+
+
+
+ +`; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx index 8672ba519b..acb09aebcb 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx @@ -9,12 +9,29 @@ import workflowTemplate from '@actiontech/shared/lib/testUtil/mockApi/sqle/workf import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentUser'; +jest.mock('react-redux', () => { + return { + ...jest.requireActual('react-redux'), + useSelector: jest.fn() + }; +}); + describe('page/WorkflowTemplate CE', () => { beforeEach(() => { workflowTemplate.mockAllApi(); mockUseCurrentProject(); mockUseCurrentUser(); jest.useFakeTimers(); + + const { useSelector } = require('react-redux'); + (useSelector as jest.Mock).mockImplementation((selector: Function) => + selector({ + permission: { + moduleFeatureSupport: {}, + userOperationPermissions: null + } + }) + ); }); afterEach(() => { diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx index a3af58e417..b94299593d 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx @@ -1,10 +1,11 @@ import { sqleSuperRender } from '../../../testUtils/superRender'; import WorkflowTemplateDetail from '.'; -import { act, cleanup, screen } from '@testing-library/react'; +import { act, cleanup, screen, fireEvent } from '@testing-library/react'; import workflowTemplate from '@actiontech/shared/lib/testUtil/mockApi/sqle/workflowTemplate'; import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentUser'; import { mockUsePermission } from '@actiontech/shared/lib/testUtil/mockHook/mockUsePermission'; +import { useTypedNavigate } from '@actiontech/shared'; jest.mock('react-redux', () => { return { @@ -13,7 +14,14 @@ jest.mock('react-redux', () => { }; }); +jest.mock('@actiontech/shared', () => ({ + ...jest.requireActual('@actiontech/shared'), + useTypedNavigate: jest.fn() +})); + describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { + const navigateSpy = jest.fn(); + beforeEach(() => { workflowTemplate.mockAllApi(); mockUseCurrentProject(); @@ -22,6 +30,7 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { mockUsePermission(undefined, { mockSelector: true }); + (useTypedNavigate as jest.Mock).mockImplementation(() => navigateSpy); }); afterEach(() => { @@ -59,4 +68,39 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { ).toBeInTheDocument(); expect(screen.getByText('导出审批')).toBeInTheDocument(); }); + + it('should navigate with workflowType param when clicking edit button', async () => { + workflowTemplate.getWorkflowTemplateList(); + customRender(); + await act(async () => jest.advanceTimersByTime(3000)); + + const editButtons = screen.getAllByText('编 辑'); + expect(editButtons.length).toBe(2); + + fireEvent.click(editButtons[0]); + expect(navigateSpy).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + params: expect.objectContaining({ + workflowName: '700300-WorkflowTemplate' + }), + queries: expect.objectContaining({ + workflowType: 'workflow' + }) + }) + ); + + fireEvent.click(editButtons[1]); + expect(navigateSpy).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ + params: expect.objectContaining({ + workflowName: '700300-DataExportWorkflowTemplate' + }), + queries: expect.objectContaining({ + workflowType: 'data_export' + }) + }) + ); + }); }); From 05124915ae575b3a1a5dbbaa208fe92d7c5a5ea4 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Tue, 21 Apr 2026 10:01:10 +0000 Subject: [PATCH 17/36] fix(test): add type annotation to dataExportWorkflowTemplateData and fix prettier formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为 dataExportWorkflowTemplateData 添加 IWorkflowTemplateDetailResV1 类型注解, 解决 assignee_user_id_list 空数组被推断为 never[] 导致的 TS2322 编译错误; 同时移除不合法的空字符串 allow_submit_when_less_audit_level 枚举值; 修复两个测试文件的 prettier 格式问题。 (cherry picked from commit 5b8b7238c1b9df63e1d3a6bb35a1b55b7fd5157d) --- .../ApprovalProcessPreview/__tests__/index.test.tsx | 6 +++--- .../lib/testUtil/mockApi/sqle/workflowTemplate/data.ts | 4 ++-- .../UpdateWorkflowTemplate/index.test.tsx | 8 ++------ 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx index 285b4c9910..061044e843 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx @@ -63,9 +63,9 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { }); it('should render fallback error state when request fails', async () => { - jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation(() => - createSpyErrorResponse({}) - ); + jest + .spyOn(workflow, 'getWorkflowTemplateV1') + .mockImplementation(() => createSpyErrorResponse({})); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); diff --git a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts index 3098e799a2..c51548fe7c 100644 --- a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts +++ b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts @@ -1,3 +1,4 @@ +import { IWorkflowTemplateDetailResV1 } from '../../../../api/sqle/service/common'; import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '../../../../api/sqle/service/common.enum'; export const workflowTemplateData = { @@ -33,8 +34,7 @@ export const workflowTemplateData = { workflow_type: 'workflow' }; -export const dataExportWorkflowTemplateData = { - allow_submit_when_less_audit_level: '', +export const dataExportWorkflowTemplateData: IWorkflowTemplateDetailResV1 = { desc: '', update_time: '2024-01-15T10:30:00+08:00', workflow_step_template_list: [ diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx index cdcadd0f4f..04b7acf416 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.test.tsx @@ -75,9 +75,7 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { expect(getInfoRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); await act(async () => jest.advanceTimersByTime(3000)); - expect( - screen.getByText('编辑审批流程 - 上线工单') - ).toBeInTheDocument(); + expect(screen.getByText('编辑审批流程 - 上线工单')).toBeInTheDocument(); expect(getBySelector('a')).toBeInTheDocument(); expect(getBySelector('a')).toHaveAttribute( 'href', @@ -272,9 +270,7 @@ describe('page/WorkflowTemplate/UpdateWorkflowTemplate', () => { customRender(); await act(async () => jest.advanceTimersByTime(3000)); await act(async () => jest.advanceTimersByTime(3000)); - expect( - screen.getByText('编辑审批流程 - 数据导出') - ).toBeInTheDocument(); + expect(screen.getByText('编辑审批流程 - 数据导出')).toBeInTheDocument(); }); it('should use export step types when workflowType is data_export', async () => { From 0630ca12afc1c6760ae324489b8ac89e38701214 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Wed, 22 Apr 2026 08:21:45 +0000 Subject: [PATCH 18/36] fix(#784): fix data export workflow template UI issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Issue 1: Change workflow template page from list to tab-based layout with separate tabs for SQL exec workflow and data export - Issue 2: Fix i18n text in template edit page for data export context (e.g. "执行上线" -> "执行导出", match permission text) - Issue 3: Fix description truncation in export order detail page by replacing BasicTypographyEllipsis with plain div - Issue 4: Restore polling logic for export status refresh in detail page - Issue 5: Fix workflow progress display to show dynamic approval nodes instead of hardcoded 3 steps - Issue 6: Fix approval flow i18n mixing in create export review page (Chinese text was mixed with English labels) (cherry picked from commit d5b3e259538d63bebb99871e945d3b9d5259a76c) --- .../base/src/locale/zh-CN/dmsDataExport.ts | 2 +- .../Common/BasicInfoWrapper/index.tsx | 7 +- .../WorkflowRecordInfo/WorkflowSteps.tsx | 85 ++++-- .../Detail/hooks/useInitDataWithRequest.ts | 48 +++- .../sqle/src/locale/en-US/workflowTemplate.ts | 21 +- .../sqle/src/locale/zh-CN/workflowTemplate.ts | 18 +- .../components/ReviewNodeInfo/index.tsx | 25 +- .../components/ReviewNodeInfo/index.type.ts | 1 + .../components/StepInfo/index.tsx | 4 +- .../UpdateWorkflowTemplate/index.tsx | 2 + .../WorkflowTemplateAuthInfo/index.tsx | 53 ++-- .../WorkflowTemplateAuthInfo/index.type.ts | 3 +- .../WorkflowTemplateStepInfo/index.tsx | 3 +- .../WorkflowTemplateStepInfo/index.type.ts | 1 + .../WorkflowTemplateDetail/index.tsx | 268 ++++++++++++++---- .../WorkflowTemplateDetail/style.ts | 18 ++ .../components/StepCard/index.type.ts | 2 + .../components/StepCard/stepInfo.tsx | 16 +- 18 files changed, 441 insertions(+), 136 deletions(-) diff --git a/packages/base/src/locale/zh-CN/dmsDataExport.ts b/packages/base/src/locale/zh-CN/dmsDataExport.ts index ed1601ef33..1bdebc0f3a 100644 --- a/packages/base/src/locale/zh-CN/dmsDataExport.ts +++ b/packages/base/src/locale/zh-CN/dmsDataExport.ts @@ -54,7 +54,7 @@ export default { }, approvalProcess: { title: '审批流程', - hint: '审批流程可在 Project Configure > Approval Process 中修改', + hint: '审批流程可在 项目配置 > 审批流程 中修改', stepLabel: '步骤 {{number}}', matchByPermission: '按权限匹配', loadFailed: '加载审批流程失败', diff --git a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx index 3db4fdf939..8a77c4c4ef 100644 --- a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx +++ b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx @@ -1,6 +1,6 @@ import classNames from 'classnames'; import { BasicInfoWrapperProps } from './index.type'; -import { BasicTypographyEllipsis, EmptyBox } from '@actiontech/dms-kit'; +import { EmptyBox } from '@actiontech/dms-kit'; import { DataExportStatusDictionary } from '../index.data'; import { BasicInfoStyleWrapper } from './style'; const BasicInfoWrapper: React.FC = ({ @@ -77,10 +77,7 @@ const BasicInfoWrapper: React.FC = ({
{title}
- +
{desc ?? '-'}
); }; diff --git a/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx b/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx index 38d4e26a9e..e6f436ea93 100644 --- a/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx +++ b/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx @@ -26,20 +26,38 @@ const WorkflowSteps: React.FC = ({ }) => { const { t } = useTranslation(); const { sharedTheme } = useThemeStyleData(); + + // Dynamic step number calculation based on workflow status and steps const stepNumber = useMemo(() => { - if (!workflowStatus) { + if (!workflowStatus || !workflowSteps) { return currentStepNumber; } - //本期后端没有流程模板,当前固定为:创建、审核、执行 三步,所以前端自己判断当前到第几步了 - if ( - workflowStatus === WorkflowRecordStatusEnum.wait_for_approve || - workflowStatus === WorkflowRecordStatusEnum.rejected - ) { + // Total steps: create(1) + N approval nodes + execute(1) + const totalApprovalSteps = workflowSteps.length; + + if (workflowStatus === WorkflowRecordStatusEnum.rejected) { + // Find which approval step was rejected + for (let i = 0; i < workflowSteps.length; i++) { + if (workflowSteps[i]?.state === 'rejected') { + return i + 2; // +1 for create step, +1 for 1-indexed + } + } return 2; } + + if (workflowStatus === WorkflowRecordStatusEnum.wait_for_approve) { + // Find the current step being awaited + if (currentStepNumber !== undefined && currentStepNumber !== null) { + // currentStepNumber from API represents which step we are on (1-indexed) + return (currentStepNumber as number) + 1; // +1 for create step + } + return 2; + } + if (workflowStatus === WorkflowRecordStatusEnum.wait_for_export) { - return 3; + return totalApprovalSteps + 2; // all approval done, at execute step } + if ( [ WorkflowRecordStatusEnum.exporting, @@ -48,19 +66,16 @@ const WorkflowSteps: React.FC = ({ WorkflowRecordStatusEnum.cancel ].includes(workflowStatus) ) { - return 4; + return totalApprovalSteps + 2; // at execute step } - }, [currentStepNumber, workflowStatus]); + }, [currentStepNumber, workflowStatus, workflowSteps]); + const renderTitle = useCallback( (type?: string) => { if (type === 'create') { return t('dmsDataExport.detail.record.steps.create'); } - // if (type === WorkflowStepResV2TypeEnum.update_workflow) { - // return t('dmsDataExport.detail.record.steps.update'); - // } - if (type === 'approve') { return t('dmsDataExport.detail.record.steps.approve'); } @@ -148,12 +163,14 @@ const WorkflowSteps: React.FC = ({ [renderOrderStepsItemContent] ); const renderOrderStepsItemIcon = useCallback( - (type?: string) => { + (type?: string, step?: any) => { if (type === 'create') { return ; } if (type === 'approve') { - const isRejected = workflowStatus === WorkflowRecordStatusEnum.rejected; + const isRejected = + workflowStatus === WorkflowRecordStatusEnum.rejected && + step?.state === 'rejected'; return ( = ({ }, [workflowStatus, sharedTheme.uiToken.colorWarning] ); + const stepsItems = useMemo(() => { if (!workflowSteps) { return []; } - // 没有流程模板,先固定这 3 步 - return [ + // Build dynamic steps: create + N approval nodes + execute + const allSteps: any[] = [ { type: 'create', number: 1, @@ -193,21 +211,30 @@ const WorkflowSteps: React.FC = ({ name: createUser }, operation_time: createTime - }, - { - ...workflowSteps[0], - type: 'approve', - number: 2 - }, - { - type: 'execute', - number: 3 } - ].map((v, i) => { - const isNextRejected = workflowSteps[i + 1]?.state === 'rejected'; + ]; + + // Add all approval steps from workflow_step_list + workflowSteps.forEach((step, index) => { + allSteps.push({ + ...step, + type: 'approve', + number: index + 2 + }); + }); + + // Add execute step + allSteps.push({ + type: 'execute', + number: allSteps.length + 1 + }); + + return allSteps.map((v, i) => { + const nextStep = allSteps[i + 1]; + const isNextRejected = nextStep?.state === 'rejected'; return { title: renderOrderStepsItem(renderTitle(v.type), v), - icon: renderOrderStepsItemIcon(v.type), + icon: renderOrderStepsItemIcon(v.type, v), className: classNames({ 'prev-rejected-step': isNextRejected }) diff --git a/packages/base/src/page/DataExportManagement/Detail/hooks/useInitDataWithRequest.ts b/packages/base/src/page/DataExportManagement/Detail/hooks/useInitDataWithRequest.ts index ba73b5f63f..e832a421b7 100644 --- a/packages/base/src/page/DataExportManagement/Detail/hooks/useInitDataWithRequest.ts +++ b/packages/base/src/page/DataExportManagement/Detail/hooks/useInitDataWithRequest.ts @@ -3,11 +3,14 @@ import DataExportWorkflows from '@actiontech/shared/lib/api/base/service/DataExp import { ResponseCode } from '@actiontech/dms-kit'; import { useCurrentProject } from '@actiontech/shared/lib/features'; import useDataExportDetailReduxManage from './index.redux'; -import { useRequest } from 'ahooks'; -import { useEffect } from 'react'; +import { useBoolean, useRequest } from 'ahooks'; +import { useEffect, useMemo } from 'react'; import eventEmitter from '../../../../utils/EventEmitter'; import EmitterKey from '../../../../data/EmitterKey'; -import { GetDataExportTaskStatusEnum } from '@actiontech/shared/lib/api/base/service/common.enum'; +import { + GetDataExportTaskStatusEnum, + WorkflowRecordStatusEnum +} from '@actiontech/shared/lib/api/base/service/common.enum'; import { useTypedParams } from '@actiontech/shared'; import { ROUTE_PATHS } from '@actiontech/dms-kit'; @@ -18,7 +21,14 @@ const useInitDataWithRequest = () => { const { updateTaskInfos, updateWorkflowInfo, updateTaskStatusNumber } = useDataExportDetailReduxManage(); - const { refresh: refreshWorkflow, loading: getWorkflowLoading } = useRequest( + const [polling, { setFalse: finishPollRequest, setTrue: startPollRequest }] = + useBoolean(); + + const { + refresh: refreshWorkflow, + loading: getWorkflowLoading, + cancel + } = useRequest( () => DataExportWorkflows.GetDataExportWorkflow({ project_uid: projectID, @@ -31,8 +41,27 @@ const useInitDataWithRequest = () => { ?.map((v) => v.task_uid ?? '') ?.join(',') ?? '' ); + + // Stop polling when no longer in exporting status + if ( + res.data.data?.workflow_record?.status !== + WorkflowRecordStatusEnum.exporting + ) { + cancel(); + finishPollRequest(); + } else { + startPollRequest(); + } } - }) + }), + { + pollingInterval: 1000, + pollingErrorRetryCount: 3, + onError: () => { + cancel(); + finishPollRequest(); + } + } ); const { loading: getTaskInfosLoading, run: batchGetDataExportTask } = @@ -82,9 +111,14 @@ const useInitDataWithRequest = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + const initLoading = useMemo( + () => (polling ? false : getTaskInfosLoading || getWorkflowLoading), + [getTaskInfosLoading, getWorkflowLoading, polling] + ); + return { - getWorkflowLoading, - getTaskInfosLoading + getWorkflowLoading: initLoading, + getTaskInfosLoading: initLoading }; }; diff --git a/packages/sqle/src/locale/en-US/workflowTemplate.ts b/packages/sqle/src/locale/en-US/workflowTemplate.ts index c68a9b89ae..9588e2e56f 100644 --- a/packages/sqle/src/locale/en-US/workflowTemplate.ts +++ b/packages/sqle/src/locale/en-US/workflowTemplate.ts @@ -76,7 +76,9 @@ export default { fourth: 'Audit tickets: the auditor can execute “pass audit” or “reject” operations in this step;', fifth: - 'Online tickets: the executor can execute “execute online” or “reject” operations in this step.' + 'Online tickets: the executor can execute “execute online” or “reject” operations in this step.', + fifthExport: + 'Export tickets: the executor can execute “execute export” or “reject” operations in this step.' } }, @@ -92,6 +94,10 @@ export default { execDesc: 'Edit the audit process. The executor can execute “execute online” or “reject” operations in this step', + exportExecTitle: 'Execute export', + exportExecDesc: + 'Edit the audit process. The executor can execute “execute export” or “reject” operations in this step', + resultTitle: 'Result', resultDesc: 'Change result' }, @@ -142,6 +148,15 @@ export default { matchExecute: 'Match members who have data source online permissions' } }, + exportExec: { + title: 'Execute export', + subTitle: + 'The executor can execute “execute export” or “reject” operations in this step', + executeUserType: { + specifyExecute: 'Specify executor', + matchExecute: 'Match members who have data source export permissions' + } + }, exportReview: { title: 'Export Review', subTitle: 'Reviewer checks the legitimacy of the export request' @@ -165,6 +180,10 @@ export default { 'The approval workflow template can set up to 4 audit steps, or no audit steps can be set;', rule3: 'When specifying the executor for a single step, at least one specified person needs to be added, and a maximum of three specified persons can be added.' + }, + exportRuler: { + rule1: + 'The approval process starts from the initiation of the ticket, and ends with the execution of export after passing through the set audit steps;' } }, diff --git a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts index 0dd16070cd..452304b1df 100644 --- a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts +++ b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts @@ -72,7 +72,8 @@ export default { '被驳回的工单,需要创建人更新SQL语句后重新发起,驳回记录可在 “工单进度-工单历史操作” 中查看;', third: '处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭;', fourth: '审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作;', - fifth: '上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。' + fifth: '上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。', + fifthExport: '导出工单:执行人在该步骤可以执行「执行导出」或「驳回」操作。' } }, @@ -87,6 +88,9 @@ export default { execTitle: '执行上线', execDesc: '编辑审核流程,执行人在该步骤可以执行「执行上线」或「驳回」操作', + exportExecTitle: '执行导出', + exportExecDesc: '编辑审核流程,执行人在该步骤可以执行「执行导出」或「驳回」操作', + resultTitle: '结果', resultDesc: '变更结果' }, @@ -134,6 +138,14 @@ export default { matchExecute: '匹配拥有数据源上线权限的成员' } }, + exportExec: { + title: '执行导出', + subTitle: '执行人在该步骤可以执行 执行导出或驳回 操作', + executeUserType: { + specifyExecute: '指定执行人', + matchExecute: '匹配拥有数据源导出权限的成员' + } + }, exportReview: { title: '导出审批', subTitle: '审批人在该步骤审核导出请求的合理性' @@ -155,6 +167,10 @@ export default { rule2: '审核流程模板最多可设置4个审核步骤,也可不设置审核步骤;', rule3: '单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加三个指定人。' + }, + exportRuler: { + rule1: + '审核流程自工单发起开始,通过设置的审核步骤后,最后以执行导出结束;' } }, diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx index a9575cf7c3..a90303c2be 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx @@ -20,6 +20,7 @@ const MAX_USER_COUNT = 10; const ReviewAndExecNodeInfo: React.FC = (props) => { const { t } = useTranslation(); + const isDataExport = props.workflowType === 'data_export'; const [authorizedParam, setAuthorizedParam] = useState( props.type === NodeTypeEnum.review ? 'approved_by_authorized' @@ -92,12 +93,16 @@ const ReviewAndExecNodeInfo: React.FC = (props) => {
{props.type === NodeTypeEnum.review ? t('workflowTemplate.step.progressTitle') - : t('workflowTemplate.step.execTitle')} + : isDataExport + ? t('workflowTemplate.step.exportExecTitle') + : t('workflowTemplate.step.execTitle')}
{props.type === NodeTypeEnum.review ? t('workflowTemplate.step.progressDesc') - : t('workflowTemplate.step.execDesc')} + : isDataExport + ? t('workflowTemplate.step.exportExecDesc') + : t('workflowTemplate.step.execDesc')}
@@ -133,9 +138,13 @@ const ReviewAndExecNodeInfo: React.FC = (props) => { ? t( 'workflowTemplate.progressConfig.review.reviewUserType.matchAudit' ) - : t( - 'workflowTemplate.progressConfig.exec.executeUserType.matchExecute' - ) + : isDataExport + ? t( + 'workflowTemplate.progressConfig.exportExec.executeUserType.matchExecute' + ) + : t( + 'workflowTemplate.progressConfig.exec.executeUserType.matchExecute' + ) } name={[authorizedParam]} valuePropName="checked" @@ -208,7 +217,11 @@ const ReviewAndExecNodeInfo: React.FC = (props) => {
    -
  • {t('workflowTemplate.progressConfig.ruler.rule1')}
  • +
  • + {isDataExport + ? t('workflowTemplate.progressConfig.exportRuler.rule1') + : t('workflowTemplate.progressConfig.ruler.rule1')} +
  • {t('workflowTemplate.progressConfig.ruler.rule2')}
  • {t('workflowTemplate.progressConfig.ruler.rule3')}
diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts index af1a5e391a..6eb21c3662 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts @@ -29,4 +29,5 @@ export type ReviewAndExecNodeInfoProps = { updateReviewAndExecNodeInfo: (data: IWorkFlowStepTemplateResV1) => void; generateUsernameSelectOption: () => React.ReactNode; getUsernameListLoading: boolean; + workflowType?: string; }; diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx index dd7bd5af05..d9b9c85e27 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx @@ -48,7 +48,8 @@ const StepInfo: React.FC = (props) => { reviewStepData: props.reviewStepData, execStepData: props.execStepData, usernameList: props.usernameList, - theme: sqleTheme.icon + theme: sqleTheme.icon, + isDataExport: props.isDataExport }), [ templateLevel, @@ -56,6 +57,7 @@ const StepInfo: React.FC = (props) => { props.execStepData, props.reviewStepData, props.usernameList, + props.isDataExport, sqleTheme ] ); diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx index 98e3c99726..e53efe17c3 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx @@ -197,6 +197,7 @@ const UpdateWorkflowTemplate: React.FC = () => { getUsernameListLoading={getUsernameListLoading} totalStep={reviewSteps.length + 1} updateReviewAndExecNodeInfo={updateReviewAndExecNodeInfo} + workflowType={workflowType} /> ); }; @@ -299,6 +300,7 @@ const UpdateWorkflowTemplate: React.FC = () => { exchangeReviewNode={handleExchangeReviewNode} clickReviewNode={handleClickReviewNode} usernameList={usernameList} + isDataExport={workflowType === 'data_export'} /> = ({ level, - time + time, + hideLevel }) => { const { t } = useTranslation(); const { sqleTheme } = useThemeStyleData(); const { currentLevelData, levelText } = useGetLevelData(level); return ( - - - {t('workflowTemplate.form.label.allowSubmitWhenLessAuditLevel')} - - - {levelText} - - - + {!hideLevel && ( + + + {t('workflowTemplate.form.label.allowSubmitWhenLessAuditLevel')} + + + {levelText} + + + + )} {t('workflowTemplate.detail.title.noticeInfo')} @@ -47,10 +50,16 @@ const WorkflowTemplateAuthInfo: React.FC = ({
  • {t('workflowTemplate.detail.authLevelInfo.first')}
  • -
  • {t('workflowTemplate.detail.authLevelInfo.second')}
  • + {!hideLevel && ( +
  • {t('workflowTemplate.detail.authLevelInfo.second')}
  • + )}
  • {t('workflowTemplate.detail.authLevelInfo.third')}
  • {t('workflowTemplate.detail.authLevelInfo.fourth')}
  • -
  • {t('workflowTemplate.detail.authLevelInfo.fifth')}
  • +
  • + {hideLevel + ? t('workflowTemplate.detail.authLevelInfo.fifthExport') + : t('workflowTemplate.detail.authLevelInfo.fifth')} +
diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateAuthInfo/index.type.ts b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateAuthInfo/index.type.ts index 49fa2bc6ab..3d24682fde 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateAuthInfo/index.type.ts +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateAuthInfo/index.type.ts @@ -1,8 +1,9 @@ import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; export interface WorkflowTemplateAuthInfoProps { - level: + level?: | WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum | undefined; time?: string; + hideLevel?: boolean; } diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.tsx index 98f636efb1..331971587e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.tsx @@ -22,7 +22,8 @@ const WorkflowTemplateStepInfo: React.FC = ( reviewStepData: props.reviewStepData, execStepData: props.execStepData, usernameList: props.usernameList, - theme: sqleTheme.icon + theme: sqleTheme.icon, + isDataExport: props.isDataExport }).map((step) => step.show ? ( diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.type.ts b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.type.ts index 49c118757b..de3c27bccd 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.type.ts +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/components/WorkflowTemplateStepInfo/index.type.ts @@ -7,4 +7,5 @@ export interface IWorkflowTemplateStepInfoProps { reviewStepData: IWorkFlowStepTemplateResV1[]; execStepData: IWorkFlowStepTemplateResV1; usernameList: IUserTipResV1[]; + isDataExport?: boolean; } diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx index d0386ede54..7c780e1cd2 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx @@ -1,80 +1,236 @@ -import { useMemo, useCallback } from 'react'; +import { useMemo, useCallback, useState } from 'react'; import { useRequest } from 'ahooks'; import { useTranslation } from 'react-i18next'; +import { Col, Row, Spin, Tabs } from 'antd'; import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; import { useCurrentProject, - usePermission + PERMISSIONS, + PermissionControl } from '@actiontech/shared/lib/features'; -import { useTypedNavigate } from '@actiontech/shared'; +import { ActionButton } from '@actiontech/shared'; import { ROUTE_PATHS } from '@actiontech/dms-kit'; import { PageHeader } from '@actiontech/dms-kit'; -import { - ActiontechTable, - ActiontechTableWrapper -} from '@actiontech/dms-kit/es/components/ActiontechTable'; -import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; -import { WorkflowTemplateListColumn } from './column'; -import { WorkflowTemplateTableActions } from './actions'; +import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; +import WorkflowTemplateStepInfo from './components/WorkflowTemplateStepInfo'; +import WorkflowTemplateAuthInfo from './components/WorkflowTemplateAuthInfo'; +import { WorkflowTemplateStyleWrapper } from './style'; +import useUsername from '../../../hooks/useUsername'; +import { EditOutlined } from '@ant-design/icons'; const WorkflowTemplateDetail: React.FC = () => { const { t } = useTranslation(); const { projectName, projectID } = useCurrentProject(); - const { parse2TableActionPermissions } = usePermission(); - const navigate = useTypedNavigate(); + const [activeTab, setActiveTab] = useState('workflow'); - const columns = useMemo(() => WorkflowTemplateListColumn(), []); + const { + updateUsernameList, + usernameList, + loading: getUsernameListLoading + } = useUsername(); - const { data: templateList, loading } = useRequest( - () => - workflow - .getWorkflowTemplateListV1({ - project_name: projectName - }) - .then((res) => res.data.data ?? []), - { - ready: !!projectName - } - ); + useMemo(() => { + updateUsernameList({ + filter_project: projectName + }); + }, [projectName, updateUsernameList]); + + // Fetch SQL Exec Workflow template + const [workflowReviewSteps, setWorkflowReviewSteps] = useState< + IWorkFlowStepTemplateResV1[] + >([]); + const [workflowExecStep, setWorkflowExecStep] = + useState({ + assignee_user_id_list: [], + desc: '' + }); + + const { data: workflowTemplate, loading: getWorkflowTemplateLoading } = + useRequest( + () => + workflow + .getWorkflowTemplateV1({ + project_name: projectName, + workflow_type: 'workflow' + }) + .then((res) => { + const stepList = + res.data.data?.workflow_step_template_list ?? []; + if (stepList.length <= 1) { + setWorkflowExecStep(stepList[0] ?? { assignee_user_id_list: [], desc: '' }); + setWorkflowReviewSteps([]); + } else { + const execStep = stepList.pop(); + setWorkflowReviewSteps(stepList); + if (execStep) setWorkflowExecStep(execStep); + } + return res.data.data; + }), + { + ready: !!projectName + } + ); - const onEditTemplate = useCallback( - (record: IWorkflowTemplateDetailResV1) => { - navigate(ROUTE_PATHS.SQLE.PROGRESS.update, { - params: { - projectID, - workflowName: record.workflow_template_name ?? '' - }, - queries: { - workflowType: record.workflow_type ?? '' - } - }); + // Fetch Data Export workflow template + const [exportReviewSteps, setExportReviewSteps] = useState< + IWorkFlowStepTemplateResV1[] + >([]); + const [exportExecStep, setExportExecStep] = + useState({ + assignee_user_id_list: [], + desc: '' + }); + + const { data: exportTemplate, loading: getExportTemplateLoading } = + useRequest( + () => + workflow + .getWorkflowTemplateV1({ + project_name: projectName, + workflow_type: 'data_export' + }) + .then((res) => { + const stepList = + res.data.data?.workflow_step_template_list ?? []; + if (stepList.length <= 1) { + setExportExecStep(stepList[0] ?? { assignee_user_id_list: [], desc: '' }); + setExportReviewSteps([]); + } else { + const execStep = stepList.pop(); + setExportReviewSteps(stepList); + if (execStep) setExportExecStep(execStep); + } + return res.data.data; + }), + { + ready: !!projectName + } + ); + + const renderEditButton = useCallback( + (workflowType: string, templateName?: string) => { + return ( + // #if [ee] + + } + text={t('workflowTemplate.detail.updateTemplate')} + actionType="navigate-link" + link={{ + to: ROUTE_PATHS.SQLE.PROGRESS.update, + params: { + projectID, + workflowName: templateName ?? '' + }, + queries: { + workflowType + } + }} + /> + + // #endif + ); }, - [navigate, projectID] + [t, projectID] ); - const actions = useMemo(() => { - return parse2TableActionPermissions( - WorkflowTemplateTableActions(onEditTemplate) - ); - }, [parse2TableActionPermissions, onEditTemplate]); + const tabItems = useMemo( + () => [ + { + key: 'workflow', + label: t('workflowTemplate.list.type.workflow'), + children: ( + +
+ {renderEditButton( + 'workflow', + workflowTemplate?.workflow_template_name + )} +
+ + + + + + + + +
+ ) + }, + { + key: 'data_export', + label: t('workflowTemplate.list.type.dataExport'), + children: ( + +
+ {renderEditButton( + 'data_export', + exportTemplate?.workflow_template_name + )} +
+ + + + + + + + +
+ ) + } + ], + [ + t, + getUsernameListLoading, + getWorkflowTemplateLoading, + getExportTemplateLoading, + workflowReviewSteps, + workflowExecStep, + exportReviewSteps, + exportExecStep, + usernameList, + workflowTemplate, + exportTemplate, + renderEditButton + ] + ); return ( - <> + - - - record?.workflow_template_name ?? '' - } - loading={loading} - columns={columns} - // #if [ee] - actions={actions} - // #endif - /> - - + + ); }; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts index d63644aa9c..6270f268ad 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts @@ -2,4 +2,22 @@ import { styled } from '@mui/material/styles'; export const WorkflowTemplateStyleWrapper = styled('div')` height: 100%; + + .workflow-template-tabs { + padding: 0 40px; + + .ant-tabs-nav { + margin-bottom: 16px; + } + } + + .workflow-template-wrapper { + height: 100%; + } + + .workflow-template-right-module { + border-left: ${({ theme }) => + theme.sqleTheme.workflowTemplate.workflowTemplateAuthInfo.borderBottom}; + height: auto; + } `; diff --git a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.type.ts b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.type.ts index d79f776127..9f4ac9bbf1 100644 --- a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.type.ts +++ b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.type.ts @@ -38,6 +38,7 @@ export interface IStepInfoProps { execStepData: IWorkFlowStepTemplateResV1; usernameList: IUserTipResV1[]; theme?: IconTheme; + isDataExport?: boolean; } export interface IStepInfoDataProps extends IStepCardProps { @@ -60,4 +61,5 @@ export interface IUpdateWorkflowStepInfoProps { exchangeReviewNode: (from: number, to: number) => void; clickReviewNode: (index: number) => void; usernameList: IUserTipResV1[]; + isDataExport?: boolean; } diff --git a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx index 6e55ace1a9..ce4c7d62d3 100644 --- a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx @@ -23,7 +23,8 @@ const renderReviewUser = ( type: 'review' | 'exec', stepItem: IWorkFlowStepTemplateResV1, userList: IUserTipResV1[], - theme: IStepInfoProps['theme'] + theme: IStepInfoProps['theme'], + isDataExport?: boolean ) => { if (stepItem.assignee_user_id_list?.length === 0) { if (stepItem.approved_by_authorized && type === 'review') { @@ -51,7 +52,9 @@ const renderReviewUser = ( /> {t( - 'workflowTemplate.progressConfig.exec.executeUserType.matchExecute' + isDataExport + ? 'workflowTemplate.progressConfig.exportExec.executeUserType.matchExecute' + : 'workflowTemplate.progressConfig.exec.executeUserType.matchExecute' )} @@ -80,7 +83,7 @@ export const stepInfo = (props: IStepInfoProps): IStepInfoDataProps[] => { return [ { key: 'honour-step', - show: isUpdateMode, + show: isUpdateMode && !props.isDataExport, disabled: !(props?.currentStep === 0), icon: ( @@ -173,14 +176,17 @@ export const stepInfo = (props: IStepInfoProps): IStepInfoDataProps[] => { ), arrow: StepInfoArrowEnum.none, - title: t('workflowTemplate.progressConfig.exec.title'), + title: props.isDataExport + ? t('workflowTemplate.progressConfig.exportExec.title') + : t('workflowTemplate.progressConfig.exec.title'), desc: props.execStepData?.desc ?? '-', operatorTitle: t('workflowTemplate.form.label.execUser'), operator: renderReviewUser( 'exec', props?.execStepData, props.usernameList, - props.theme + props.theme, + props.isDataExport ) } ]; From a3bbc1bb7481f8ed5b36c94a1c16c019d63fd657 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Wed, 22 Apr 2026 10:31:35 +0000 Subject: [PATCH 19/36] fix(#784): optimize workflow template UI - tab style, redirect link, approval preview 1. Replace antd Tabs with SegmentedTabs for workflow template detail page to match audit rule template page styling convention. 2. Fix redirect link after saving data export workflow template: the "view updated template" button now navigates to the data export tab instead of always landing on the workflow tab. 3. Improve approval process preview styling in data export creation page with step indicator dots, connector lines, and better visual hierarchy. Refs: actiontech/dms-ee#784 (cherry picked from commit 56f11e29002f7c29427b4d342647bb60a1276aa8) --- .../__snapshots__/index.test.tsx.snap | 657 +-------------- .../__snapshots__/index.test.tsx.snap | 104 +-- .../__snapshots__/index.test.tsx.snap | 53 +- .../__tests__/index.test.tsx | 2 +- .../ApprovalProcessPreview/index.tsx | 41 +- .../ApprovalProcessPreview/style.ts | 92 ++- .../__snapshots__/index.test.tsx.snap | 178 ++-- .../__snapshots__/index.test.tsx.snap | 375 +-------- .../__snapshots__/index.test.tsx.snap | 2 +- packages/dms-kit/src/data/routePaths.ts | 3 +- .../__snapshots__/index.test.tsx.snap | 10 +- .../UpdateWorkflowTemplate/index.test.tsx | 2 +- .../UpdateWorkflowTemplate/index.tsx | 3 + .../__snapshots__/index.ce.test.tsx.snap | 700 +++++++++++++--- .../__snapshots__/index.test.tsx.snap | 782 +++++++++++++----- .../WorkflowTemplateDetail/index.ce.test.tsx | 6 +- .../WorkflowTemplateDetail/index.test.tsx | 66 +- .../WorkflowTemplateDetail/index.tsx | 23 +- .../WorkflowTemplateDetail/style.ts | 6 +- 19 files changed, 1437 insertions(+), 1668 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap index 5734d0b78c..1495acc62e 100644 --- a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap @@ -11,80 +11,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 1`] export-task-1
- -
- - - -
- -
@@ -101,80 +30,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 2`] export-task-1
desc -
- - - -
- -
@@ -264,80 +122,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 3`] export-task-1
desc -
- - - -
- -
@@ -427,80 +214,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 4`] export-task-1
desc -
- - - -
- -
@@ -590,80 +306,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 5`] export-task-1
desc -
- - - -
- -
@@ -753,80 +398,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 6`] export-task-1
desc -
- - - -
- -
@@ -916,80 +490,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 7`] export-task-1
desc -
- - - -
- -
@@ -1079,80 +582,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 8`] export-task-1
desc -
- - - -
- -
@@ -1242,80 +674,9 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 9`] export-task-1
desc -
- - - -
- -
diff --git a/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap index 02122de329..caa531c3a2 100644 --- a/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap @@ -1427,80 +1427,58 @@ exports[`first should match snapshot when pageState is equal SUBMIT_WORKFLOW 1`] test
desc -
- +
+
+
+
+
- - - + + + +
- -
+
- - - + 审批流程可在 项目配置 > 审批流程 中修改
- +
审批流程
+
- 审批流程可在 Project Configure > Approval Process 中修改 + 审批流程可在 项目配置 > 审批流程 中修改
@@ -103,7 +106,7 @@ exports[`base/DataExport/Create/ApprovalProcessPreview should render step list w
- - 步骤 1 - + 1
+
+
+
- - 导出审批 - + 导出审批 +
+
+ 按权限匹配
-
- 按权限匹配 -
- 审批流程可在 Project Configure > Approval Process 中修改 + 审批流程可在 项目配置 > 审批流程 中修改
diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx index 061044e843..3883b1cc8e 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx @@ -56,7 +56,7 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { expect(screen.getByText('按权限匹配')).toBeInTheDocument(); expect( screen.getByText( - '审批流程可在 Project Configure > Approval Process 中修改' + /审批流程可在.*中修改/ ) ).toBeInTheDocument(); expect(baseElement).toMatchSnapshot(); diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx index 2b0b7f4658..d9c2cd91f5 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx @@ -1,6 +1,6 @@ import { useTranslation } from 'react-i18next'; import { useRequest } from 'ahooks'; -import { Spin, Space, Typography } from 'antd'; +import { Spin } from 'antd'; import { Result } from 'antd'; import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; @@ -72,27 +72,28 @@ const ApprovalProcessPreview: React.FC = ({ {t('dmsDataExport.create.approvalProcess.title')}
- {templateData?.workflow_step_template_list?.map( - (step: IWorkFlowStepTemplateResV1, index: number) => ( -
-
- - - {t('dmsDataExport.create.approvalProcess.stepLabel', { - number: step.number ?? index + 1 - })} - - +
+ {templateData?.workflow_step_template_list?.map( + (step: IWorkFlowStepTemplateResV1, index: number) => ( +
+
+
+ {step.number ?? index + 1} +
+
+
+
+
{renderStepTypeName(step.type)} - - +
+
+ {renderAssigneeInfo(step)} +
+
-
- {renderAssigneeInfo(step)} -
-
- ) - )} + ) + )} +
{t('dmsDataExport.create.approvalProcess.hint')} diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts index 6423e16dda..bc6c47648d 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts @@ -7,40 +7,94 @@ export const ApprovalProcessPreviewStyleWrapper = styled('div')` .approval-process-title { color: ${({ theme }) => theme.sharedTheme.uiToken.colorText}; - font-size: 16px; - font-weight: 500; - line-height: 24px; + font-size: 14px; + font-weight: 600; + line-height: 22px; margin-bottom: 16px; } + .approval-process-steps { + display: flex; + flex-direction: column; + gap: 0; + } + .approval-process-step { - padding: 12px 16px; - margin-bottom: 8px; - border-radius: 8px; - border: 1px solid ${({ theme }) => theme.sharedTheme.basic.colorGrayLine}; - background: ${({ theme }) => theme.sharedTheme.uiToken.colorFillQuaternary}; + display: flex; + align-items: flex-start; + position: relative; + padding-left: 32px; + padding-bottom: 16px; + + &:last-child { + padding-bottom: 0; + + .step-connector { + display: none; + } + } + + .step-indicator { + position: absolute; + left: 0; + top: 0; + display: flex; + flex-direction: column; + align-items: center; + + .step-dot { + width: 24px; + height: 24px; + border-radius: 50%; + background: ${({ theme }) => + theme.sharedTheme.uiToken.colorPrimary}; + color: #fff; + font-size: 12px; + font-weight: 600; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + } + + .step-connector { + width: 2px; + flex: 1; + min-height: 16px; + background: ${({ theme }) => + theme.sharedTheme.basic.colorGrayLine}; + margin-top: 4px; + } + } - .approval-process-step-header { - margin-bottom: 4px; + .step-content { + flex: 1; + padding: 4px 0 0 12px; - .step-number { + .step-type-name { color: ${({ theme }) => theme.sharedTheme.uiToken.colorText}; - font-weight: 500; font-size: 14px; + font-weight: 500; + line-height: 22px; } - } - .approval-process-step-assignee { - color: ${({ theme }) => theme.sharedTheme.uiToken.colorTextSecondary}; - font-size: 13px; - line-height: 20px; + .step-assignee { + color: ${({ theme }) => + theme.sharedTheme.uiToken.colorTextSecondary}; + font-size: 13px; + line-height: 20px; + margin-top: 2px; + } } } .approval-process-hint { - margin-top: 12px; + margin-top: 16px; + padding-top: 12px; + border-top: 1px dashed + ${({ theme }) => theme.sharedTheme.basic.colorGrayLine}; color: ${({ theme }) => theme.sharedTheme.uiToken.colorTextTertiary}; - font-size: 13px; + font-size: 12px; line-height: 20px; } `; diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap index 5f611d78ee..0dd2c8ba80 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap @@ -79,80 +79,58 @@ exports[`test base/DataExport/Create/SubmitWorkflow should match snapshot 1`] = test
desc -
- +
+
+
+
+
- - + + + + +
- -
+
- - - + 审批流程可在 项目配置 > 审批流程 中修改
- +
desc +
+
+
+
- -
desc -
- - - -
- -
desc -
- - - -
- -
desc -
- - - -
- -
desc -
- - - -
- -
desc -
- - - -
- -
{ expect(getAllBySelector('a').length).toBe(2); expect(getAllBySelector('a')?.[1]).toHaveAttribute( 'href', - `/sqle/project/${mockProjectInfo.projectID}/progress` + `/sqle/project/${mockProjectInfo.projectID}/progress?activeTab=workflow` ); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx index e53efe17c3..d7c04a287e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx @@ -324,6 +324,9 @@ const UpdateWorkflowTemplate: React.FC = () => { to: ROUTE_PATHS.SQLE.PROGRESS.index, params: { projectID + }, + queries: { + activeTab: workflowType } }} /> diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap index eda47a95cf..179121d5fd 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap @@ -1,184 +1,612 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`page/WorkflowTemplate CE render workflow template list without edit actions in CE 1`] = ` +exports[`page/WorkflowTemplate CE render workflow template detail without edit actions in CE 1`] = `
- 审批流程模板 +
+ 审批流程模板 +
+
-
-
-
+
+
+ + +
+
+
+
+
+
+ + + + + + +
+
+
- - - - - - - - - - - - + + + +
+
-
- - - - - + + + +
+ + + + + + +
+
+
+ -
- - - - - + + + +
+
-
- - - - - -
- 审批流程模板名称 - - 适用类型 - - 审批节点描述 - + + - 更新时间 -
- 700300-WorkflowTemplate - - - 上线工单 - - - 审核节点 -> 审核节点 -> 执行上线 - - 2023-12-26 14:19:12 -
- 700300-DataExportWorkflowTemplate - - - 数据导出 - - - 导出审批 - - 2024-01-15 10:30:00 -
+ + 执行上线 + +
+ - +
+
+
+ 执行人 +
+
+ + + + + 匹配拥有数据源上线权限的成员 + +
+
+
+
+
+
+
+
+
+
+
+
+ + 允许创建工单的最高审核等级 + + + 告警(Warning) + +
+
+
+
+
+
+
+
+
+
+ + 注意事项 + +
+
    +
  • + 若项目管理员对审批流程模板进行了修改,不会对已经在审批流程的工单造成影响; +
  • +
  • + 被驳回的工单,需要创建人更新SQL语句后重新发起,驳回记录可在 “工单进度-工单历史操作” 中查看; +
  • +
  • + 处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭; +
  • +
  • + 审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作; +
  • +
  • + 上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。 +
  • +
+
+
+
+ + 审批流程模板更新时间 + +
+ + + + + 2023-12-26 14:19:12 + +
+
diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap index 4135a84379..1a9631e0b6 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap @@ -1,242 +1,648 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`page/WorkflowTemplate/WorkflowTemplateDetail render workflow template list 1`] = ` +exports[`page/WorkflowTemplate/WorkflowTemplateDetail render workflow template detail page with SegmentedTabs 1`] = `
- 审批流程模板 +
+ 审批流程模板 +
+
-
-
-
+
+
+ + +
+
+
+
+
+
+ + + + + + +
+
+
- - - - - - - - - - - - - - - - - - - + - - - - - - - + + + +
+ + + +
+
+
+ -
- - - - - - + + + +
+ + + + + + +
+
+
+ -
- - - - - - -
- 审批流程模板名称 - - 适用类型 - - 审批节点描述 - - 更新时间 - - 操作 -
- 700300-WorkflowTemplate - - - 上线工单 - - - 审核节点 -> 审核节点 -> 执行上线 - - 2023-12-26 14:19:12 - + + + +
+
+
- + +
+ step desc +
+
+
+ 审核人 +
+
+
+
+ + + 1 + + +
+
+
+
-
- 700300-DataExportWorkflowTemplate - - - 数据导出 - - - 导出审批 - - 2024-01-15 10:30:00 - + + + +
+
+
- + 执行上线 + +
+ - +
+
+
+ 执行人 +
+
+ + + + + 匹配拥有数据源上线权限的成员 + +
+
-
+
+
+
+
+
+
+
+
+
+ + 允许创建工单的最高审核等级 + + + 告警(Warning) + +
+
+
+
+
+
+
+
+
+
+ + 注意事项 + +
+
    +
  • + 若项目管理员对审批流程模板进行了修改,不会对已经在审批流程的工单造成影响; +
  • +
  • + 被驳回的工单,需要创建人更新SQL语句后重新发起,驳回记录可在 “工单进度-工单历史操作” 中查看; +
  • +
  • + 处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭; +
  • +
  • + 审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作; +
  • +
  • + 上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。 +
  • +
+
+
+
+ + 审批流程模板更新时间 + +
+ + + + + 2023-12-26 14:19:12 + +
+
diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx index acb09aebcb..1991994caa 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx @@ -43,11 +43,11 @@ describe('page/WorkflowTemplate CE', () => { return sqleSuperRender(); }; - it('render workflow template list without edit actions in CE', async () => { - const getListRequest = workflowTemplate.getWorkflowTemplateList(); + it('render workflow template detail without edit actions in CE', async () => { + const getTemplateRequest = workflowTemplate.getWorkflowTemplate(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); - expect(getListRequest).toHaveBeenCalled(); + expect(getTemplateRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); expect(screen.getByText('审批流程模板')).toBeInTheDocument(); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx index b94299593d..5f9d3f3f7f 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx @@ -1,11 +1,10 @@ import { sqleSuperRender } from '../../../testUtils/superRender'; import WorkflowTemplateDetail from '.'; -import { act, cleanup, screen, fireEvent } from '@testing-library/react'; +import { act, cleanup, screen } from '@testing-library/react'; import workflowTemplate from '@actiontech/shared/lib/testUtil/mockApi/sqle/workflowTemplate'; import { mockUseCurrentProject } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentProject'; import { mockUseCurrentUser } from '@actiontech/shared/lib/testUtil/mockHook/mockUseCurrentUser'; import { mockUsePermission } from '@actiontech/shared/lib/testUtil/mockHook/mockUsePermission'; -import { useTypedNavigate } from '@actiontech/shared'; jest.mock('react-redux', () => { return { @@ -14,14 +13,7 @@ jest.mock('react-redux', () => { }; }); -jest.mock('@actiontech/shared', () => ({ - ...jest.requireActual('@actiontech/shared'), - useTypedNavigate: jest.fn() -})); - describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { - const navigateSpy = jest.fn(); - beforeEach(() => { workflowTemplate.mockAllApi(); mockUseCurrentProject(); @@ -30,7 +22,6 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { mockUsePermission(undefined, { mockSelector: true }); - (useTypedNavigate as jest.Mock).mockImplementation(() => navigateSpy); }); afterEach(() => { @@ -42,65 +33,20 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { return sqleSuperRender(); }; - it('render workflow template list', async () => { - const getListRequest = workflowTemplate.getWorkflowTemplateList(); + it('render workflow template detail page with SegmentedTabs', async () => { + const getTemplateRequest = workflowTemplate.getWorkflowTemplate(); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); - expect(getListRequest).toHaveBeenCalled(); + expect(getTemplateRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); expect(screen.getByText('审批流程模板')).toBeInTheDocument(); }); - it('render workflow type tags correctly', async () => { - workflowTemplate.getWorkflowTemplateList(); + it('render segmented tab labels correctly', async () => { + workflowTemplate.getWorkflowTemplate(); customRender(); await act(async () => jest.advanceTimersByTime(3000)); expect(screen.getByText('上线工单')).toBeInTheDocument(); expect(screen.getByText('数据导出')).toBeInTheDocument(); }); - - it('render approval node description', async () => { - workflowTemplate.getWorkflowTemplateList(); - customRender(); - await act(async () => jest.advanceTimersByTime(3000)); - expect( - screen.getByText('审核节点 -> 审核节点 -> 执行上线') - ).toBeInTheDocument(); - expect(screen.getByText('导出审批')).toBeInTheDocument(); - }); - - it('should navigate with workflowType param when clicking edit button', async () => { - workflowTemplate.getWorkflowTemplateList(); - customRender(); - await act(async () => jest.advanceTimersByTime(3000)); - - const editButtons = screen.getAllByText('编 辑'); - expect(editButtons.length).toBe(2); - - fireEvent.click(editButtons[0]); - expect(navigateSpy).toHaveBeenCalledWith( - expect.anything(), - expect.objectContaining({ - params: expect.objectContaining({ - workflowName: '700300-WorkflowTemplate' - }), - queries: expect.objectContaining({ - workflowType: 'workflow' - }) - }) - ); - - fireEvent.click(editButtons[1]); - expect(navigateSpy).toHaveBeenCalledWith( - expect.anything(), - expect.objectContaining({ - params: expect.objectContaining({ - workflowName: '700300-DataExportWorkflowTemplate' - }), - queries: expect.objectContaining({ - workflowType: 'data_export' - }) - }) - ); - }); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx index 7c780e1cd2..b41d5f8dde 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx @@ -1,16 +1,16 @@ import { useMemo, useCallback, useState } from 'react'; import { useRequest } from 'ahooks'; import { useTranslation } from 'react-i18next'; -import { Col, Row, Spin, Tabs } from 'antd'; +import { Col, Row, Spin } from 'antd'; import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; import { useCurrentProject, PERMISSIONS, PermissionControl } from '@actiontech/shared/lib/features'; -import { ActionButton } from '@actiontech/shared'; +import { ActionButton, useTypedQuery } from '@actiontech/shared'; import { ROUTE_PATHS } from '@actiontech/dms-kit'; -import { PageHeader } from '@actiontech/dms-kit'; +import { PageHeader, SegmentedTabs } from '@actiontech/dms-kit'; import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; import WorkflowTemplateStepInfo from './components/WorkflowTemplateStepInfo'; import WorkflowTemplateAuthInfo from './components/WorkflowTemplateAuthInfo'; @@ -21,7 +21,10 @@ import { EditOutlined } from '@ant-design/icons'; const WorkflowTemplateDetail: React.FC = () => { const { t } = useTranslation(); const { projectName, projectID } = useCurrentProject(); - const [activeTab, setActiveTab] = useState('workflow'); + const extractQueries = useTypedQuery(); + const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.index); + const initialTab = searchParams?.activeTab === 'data_export' ? 'data_export' : 'workflow'; + const [activeTab, setActiveTab] = useState(initialTab); const { updateUsernameList, @@ -109,8 +112,8 @@ const WorkflowTemplateDetail: React.FC = () => { const renderEditButton = useCallback( (workflowType: string, templateName?: string) => { + // #if [ee] return ( - // #if [ee] @@ -131,8 +134,9 @@ const WorkflowTemplateDetail: React.FC = () => { }} /> - // #endif ); + // #endif + return null; }, [t, projectID] ); @@ -140,7 +144,7 @@ const WorkflowTemplateDetail: React.FC = () => { const tabItems = useMemo( () => [ { - key: 'workflow', + value: 'workflow', label: t('workflowTemplate.list.type.workflow'), children: ( { ) }, { - key: 'data_export', + value: 'data_export', label: t('workflowTemplate.list.type.dataExport'), children: ( { return ( - ); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts index 6270f268ad..915f047a9a 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts @@ -3,12 +3,8 @@ import { styled } from '@mui/material/styles'; export const WorkflowTemplateStyleWrapper = styled('div')` height: 100%; - .workflow-template-tabs { + .segmented-tabs-wrapper { padding: 0 40px; - - .ant-tabs-nav { - margin-bottom: 16px; - } } .workflow-template-wrapper { From b1bf6329b416b8b9c0bcca9e4da242f3ac0c60e5 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Thu, 23 Apr 2026 08:57:06 +0000 Subject: [PATCH 20/36] fix(#784): enforce audit node constraints, executor=creator, remove preview 1. Prevent removing last audit node (min 1) and hide close button when only 1 review node exists; max 4 already enforced by disabled button. 2. Data export exec step shows 'workflow creator' as executor (read-only, not modifiable) in template editor and step card display. 3. Remove ApprovalProcessPreview from SQL audit page (SubmitWorkflow). (cherry picked from commit 756a2dcfb9f7166784c9a2d226ce189dd1c12d78) --- .../components/SubmitWorkflow/index.tsx | 5 +---- .../sqle/src/locale/en-US/workflowTemplate.ts | 2 ++ .../sqle/src/locale/zh-CN/workflowTemplate.ts | 1 + .../components/ReviewNodeInfo/index.tsx | 22 +++++++++++++++++++ .../components/StepInfo/index.tsx | 12 ++++++++-- .../components/StepCard/index.tsx | 2 +- .../components/StepCard/stepInfo.tsx | 16 ++++++++++++++ 7 files changed, 53 insertions(+), 7 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx index 360857267e..75e37bfff7 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/index.tsx @@ -15,7 +15,6 @@ import { CreateDataExportPageEnum } from '../../../../../store/dataExport'; import useCheckTaskAuditRuleExceptionStatus from '../../hooks/useCheckTaskAuditRuleExceptionStatus'; import { IListDataExportTaskSQL } from '@actiontech/shared/lib/api/base/service/common'; import SubmitWorkflowButton from './SubmitWorkflowButton'; -import ApprovalProcessPreview from './ApprovalProcessPreview'; const SubmitExportWorkflow: React.FC = () => { const { t } = useTranslation(); const { @@ -28,7 +27,7 @@ const SubmitExportWorkflow: React.FC = () => { updatePageState, updateWorkflowID } = useCreateDataExportReduxManage(); - const { projectID, projectName } = useCurrentProject(); + const { projectID } = useCurrentProject(); const [executeSQLsIsDQL, updateExecuteSQLsTypeIsDQL] = useState(true); const { hasExceptionAuditRule, @@ -106,8 +105,6 @@ const SubmitExportWorkflow: React.FC = () => { desc={formValues?.baseValues?.desc} /> - - = (props) => { const nextStep = async () => { props.form.validateFields().then(() => props?.nextStep?.()); }; + const isDataExportExec = isDataExport && props.type === NodeTypeEnum.exec; return (
@@ -107,6 +108,25 @@ const ReviewAndExecNodeInfo: React.FC = (props) => {
+ {isDataExportExec ? ( + <> + + + + {t( + 'workflowTemplate.progressConfig.exportExec.creatorAsExecutor' + )} + + + + + ) : ( + <> = (props) => { nextStep={nextStep} prevStep={prevStep} /> + + )} diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx index d9b9c85e27..41a89ca6ae 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/StepInfo/index.tsx @@ -135,7 +135,11 @@ const StepInfo: React.FC = (props) => { key={step.key} indexNumber={index} rowKey={step.key} - removeReviewNode={props.removeReviewNode} + removeReviewNode={ + props.reviewStepData.length > 1 + ? props.removeReviewNode + : undefined + } clickReviewNode={props.clickReviewNode} /> ) : ( @@ -153,7 +157,11 @@ const StepInfo: React.FC = (props) => { {...step} key={`${step.key}-step-card`} indexNumber={index} - close={props?.removeReviewNode} + close={ + props.reviewStepData.length > 1 + ? props?.removeReviewNode + : undefined + } click={props.clickReviewNode} /> diff --git a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.tsx b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.tsx index 85c76706c8..54c5cbc09e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/index.tsx @@ -24,7 +24,7 @@ const StepCard: React.FC = (props) => {
{props?.operator}
) : null} - {props?.active ? ( + {props?.active && props?.close ? ( ); } else if (stepItem.execute_by_authorized && type === 'exec') { + if (isDataExport) { + return ( + <> + + + {t( + 'workflowTemplate.progressConfig.exportExec.creatorAsExecutor' + )} + + + ); + } return ( <> Date: Thu, 23 Apr 2026 10:23:30 +0000 Subject: [PATCH 21/36] fix(#784): update mock data to include export_execute step in data export template Align test mock data with the updated default data export workflow template which now includes both export_review and export_execute steps. (cherry picked from commit 009db1a54953e8022008e2f4e7a18c49a832eadd) --- .../lib/testUtil/mockApi/sqle/workflowTemplate/data.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts index c51548fe7c..dd1be11399 100644 --- a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts +++ b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts @@ -44,6 +44,13 @@ export const dataExportWorkflowTemplateData: IWorkflowTemplateDetailResV1 = { execute_by_authorized: false, number: 1, type: 'export_review' + }, + { + approved_by_authorized: false, + assignee_user_id_list: [], + execute_by_authorized: true, + number: 2, + type: 'export_execute' } ], workflow_template_name: '700300-DataExportWorkflowTemplate', From 608daf9026972ee60aa7a97713d844749330a289 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Thu, 23 Apr 2026 10:33:01 +0000 Subject: [PATCH 22/36] fix(#784): update frontend tests for data export template with export_execute step MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update ApprovalProcessPreview test to handle multiple "按权限匹配" text elements since the default template now has both export_review and export_execute steps. Update related snapshots. (cherry picked from commit 2d249f465f59266e88730815a35167683df95b66) --- .../__snapshots__/index.test.tsx.snap | 49 ----------- .../__snapshots__/index.test.tsx.snap | 30 +++++++ .../__tests__/index.test.tsx | 2 +- .../__snapshots__/index.test.tsx.snap | 88 ------------------- 4 files changed, 31 insertions(+), 138 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap index caa531c3a2..b694a7e1c3 100644 --- a/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap @@ -1432,55 +1432,6 @@ exports[`first should match snapshot when pageState is equal SUBMIT_WORKFLOW 1`] desc
-
-
-
-
- - - - - - -
-
-
-
- 审批流程 -
-
-
- 审批流程可在 项目配置 > 审批流程 中修改 -
-
-
-
diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap index eea264a30a..3ee435a6b3 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap @@ -152,6 +152,36 @@ exports[`base/DataExport/Create/ApprovalProcessPreview should render step list w
+
+
+
+ 2 +
+
+
+
+
+ 导出执行确认 +
+
+ 按权限匹配 +
+
+
{ }); expect(screen.getByText('审批流程')).toBeInTheDocument(); expect(screen.getByText('导出审批')).toBeInTheDocument(); - expect(screen.getByText('按权限匹配')).toBeInTheDocument(); + expect(screen.getAllByText('按权限匹配').length).toBeGreaterThanOrEqual(1); expect( screen.getByText( /审批流程可在.*中修改/ diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap index 0dd2c8ba80..b9998fae22 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap @@ -84,55 +84,6 @@ exports[`test base/DataExport/Create/SubmitWorkflow should match snapshot 1`] = desc
-
-
-
-
- - - - - - -
-
-
-
- 审批流程 -
-
-
- 审批流程可在 项目配置 > 审批流程 中修改 -
-
-
-
@@ -380,45 +331,6 @@ exports[`test base/DataExport/Create/SubmitWorkflow should match snapshot 2`] = desc
-
-
-
- - - -
-
-
- 加载审批流程失败 -
-
-
From 8068e5a795564020185bf92f06586971a3b922e2 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Thu, 23 Apr 2026 11:28:06 +0000 Subject: [PATCH 23/36] fix(#784): update useInitDataWithRequest test to match initLoading behavior --- .../Detail/hooks/__tests__/useInitDataWithRequest.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Detail/hooks/__tests__/useInitDataWithRequest.test.ts b/packages/base/src/page/DataExportManagement/Detail/hooks/__tests__/useInitDataWithRequest.test.ts index 0b2df0751b..8e592bff34 100644 --- a/packages/base/src/page/DataExportManagement/Detail/hooks/__tests__/useInitDataWithRequest.test.ts +++ b/packages/base/src/page/DataExportManagement/Detail/hooks/__tests__/useInitDataWithRequest.test.ts @@ -48,7 +48,7 @@ describe('test base/DataExport/Detail/hooks/useInitDataWithRequest', () => { const { result } = renderHook(() => useInitDataWithRequest()); expect(result.current.getWorkflowLoading).toBeTruthy(); - expect(result.current.getTaskInfosLoading).toBeFalsy(); + expect(result.current.getTaskInfosLoading).toBeTruthy(); expect(getWorkflowSpy).toHaveBeenCalledTimes(1); expect(getWorkflowSpy).toHaveBeenCalledWith({ project_uid: mockProjectInfo.projectID, @@ -56,7 +56,7 @@ describe('test base/DataExport/Detail/hooks/useInitDataWithRequest', () => { }); await act(async () => jest.advanceTimersByTime(3000)); - expect(result.current.getWorkflowLoading).toBeFalsy(); + expect(result.current.getWorkflowLoading).toBeTruthy(); expect(result.current.getTaskInfosLoading).toBeTruthy(); expect(mockDataExportDetailRedux.updateWorkflowInfo).toHaveBeenCalledTimes( 1 From 88f5b675ab2a29cc1f286b3b1d86043e5112d7bf Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Thu, 23 Apr 2026 11:34:17 +0000 Subject: [PATCH 24/36] style(#784): apply prettier formatting --- .../__tests__/index.test.tsx | 6 +- .../ApprovalProcessPreview/index.tsx | 4 +- .../ApprovalProcessPreview/style.ts | 9 +- .../sqle/src/locale/zh-CN/workflowTemplate.ts | 6 +- .../components/ReviewNodeInfo/index.tsx | 204 +++++++++--------- .../WorkflowTemplateDetail/index.tsx | 45 ++-- 6 files changed, 138 insertions(+), 136 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx index 646a7cbfad..d3be7bf366 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/index.test.tsx @@ -54,11 +54,7 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { expect(screen.getByText('审批流程')).toBeInTheDocument(); expect(screen.getByText('导出审批')).toBeInTheDocument(); expect(screen.getAllByText('按权限匹配').length).toBeGreaterThanOrEqual(1); - expect( - screen.getByText( - /审批流程可在.*中修改/ - ) - ).toBeInTheDocument(); + expect(screen.getByText(/审批流程可在.*中修改/)).toBeInTheDocument(); expect(baseElement).toMatchSnapshot(); }); diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx index d9c2cd91f5..913e10b16e 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx @@ -77,9 +77,7 @@ const ApprovalProcessPreview: React.FC = ({ (step: IWorkFlowStepTemplateResV1, index: number) => (
-
- {step.number ?? index + 1} -
+
{step.number ?? index + 1}
diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts index bc6c47648d..52b6645edf 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts @@ -46,8 +46,7 @@ export const ApprovalProcessPreviewStyleWrapper = styled('div')` width: 24px; height: 24px; border-radius: 50%; - background: ${({ theme }) => - theme.sharedTheme.uiToken.colorPrimary}; + background: ${({ theme }) => theme.sharedTheme.uiToken.colorPrimary}; color: #fff; font-size: 12px; font-weight: 600; @@ -61,8 +60,7 @@ export const ApprovalProcessPreviewStyleWrapper = styled('div')` width: 2px; flex: 1; min-height: 16px; - background: ${({ theme }) => - theme.sharedTheme.basic.colorGrayLine}; + background: ${({ theme }) => theme.sharedTheme.basic.colorGrayLine}; margin-top: 4px; } } @@ -79,8 +77,7 @@ export const ApprovalProcessPreviewStyleWrapper = styled('div')` } .step-assignee { - color: ${({ theme }) => - theme.sharedTheme.uiToken.colorTextSecondary}; + color: ${({ theme }) => theme.sharedTheme.uiToken.colorTextSecondary}; font-size: 13px; line-height: 20px; margin-top: 2px; diff --git a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts index 79073d106c..b01b013fa1 100644 --- a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts +++ b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts @@ -73,7 +73,8 @@ export default { third: '处于 “审核节点” 中的工单,创建人可在工单详情页随时关闭;', fourth: '审核工单:审核人在该步骤可以执行「审核通过」或「驳回」操作;', fifth: '上线工单:执行人在该步骤可以执行「执行上线」或「驳回」操作。', - fifthExport: '导出工单:执行人在该步骤可以执行「执行导出」或「驳回」操作。' + fifthExport: + '导出工单:执行人在该步骤可以执行「执行导出」或「驳回」操作。' } }, @@ -89,7 +90,8 @@ export default { execDesc: '编辑审核流程,执行人在该步骤可以执行「执行上线」或「驳回」操作', exportExecTitle: '执行导出', - exportExecDesc: '编辑审核流程,执行人在该步骤可以执行「执行导出」或「驳回」操作', + exportExecDesc: + '编辑审核流程,执行人在该步骤可以执行「执行导出」或「驳回」操作', resultTitle: '结果', resultDesc: '变更结果' diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx index 454935445e..586777d763 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx @@ -95,15 +95,15 @@ const ReviewAndExecNodeInfo: React.FC = (props) => { {props.type === NodeTypeEnum.review ? t('workflowTemplate.step.progressTitle') : isDataExport - ? t('workflowTemplate.step.exportExecTitle') - : t('workflowTemplate.step.execTitle')} + ? t('workflowTemplate.step.exportExecTitle') + : t('workflowTemplate.step.execTitle')}
{props.type === NodeTypeEnum.review ? t('workflowTemplate.step.progressDesc') : isDataExport - ? t('workflowTemplate.step.exportExecDesc') - : t('workflowTemplate.step.execDesc')} + ? t('workflowTemplate.step.exportExecDesc') + : t('workflowTemplate.step.execDesc')}
@@ -127,107 +127,107 @@ const ReviewAndExecNodeInfo: React.FC = (props) => { ) : ( <> - + + + + + + - - - - - - - - {props.generateUsernameSelectOption()} - - - + ] + : [] + } + > + + {props.generateUsernameSelectOption()} + + + )} diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx index b41d5f8dde..e63a9ff08a 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx @@ -23,7 +23,8 @@ const WorkflowTemplateDetail: React.FC = () => { const { projectName, projectID } = useCurrentProject(); const extractQueries = useTypedQuery(); const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.index); - const initialTab = searchParams?.activeTab === 'data_export' ? 'data_export' : 'workflow'; + const initialTab = + searchParams?.activeTab === 'data_export' ? 'data_export' : 'workflow'; const [activeTab, setActiveTab] = useState(initialTab); const { @@ -57,10 +58,11 @@ const WorkflowTemplateDetail: React.FC = () => { workflow_type: 'workflow' }) .then((res) => { - const stepList = - res.data.data?.workflow_step_template_list ?? []; + const stepList = res.data.data?.workflow_step_template_list ?? []; if (stepList.length <= 1) { - setWorkflowExecStep(stepList[0] ?? { assignee_user_id_list: [], desc: '' }); + setWorkflowExecStep( + stepList[0] ?? { assignee_user_id_list: [], desc: '' } + ); setWorkflowReviewSteps([]); } else { const execStep = stepList.pop(); @@ -93,10 +95,11 @@ const WorkflowTemplateDetail: React.FC = () => { workflow_type: 'data_export' }) .then((res) => { - const stepList = - res.data.data?.workflow_step_template_list ?? []; + const stepList = res.data.data?.workflow_step_template_list ?? []; if (stepList.length <= 1) { - setExportExecStep(stepList[0] ?? { assignee_user_id_list: [], desc: '' }); + setExportExecStep( + stepList[0] ?? { assignee_user_id_list: [], desc: '' } + ); setExportReviewSteps([]); } else { const execStep = stepList.pop(); @@ -147,10 +150,14 @@ const WorkflowTemplateDetail: React.FC = () => { value: 'workflow', label: t('workflowTemplate.list.type.workflow'), children: ( - -
+ +
{renderEditButton( 'workflow', workflowTemplate?.workflow_template_name @@ -166,9 +173,7 @@ const WorkflowTemplateDetail: React.FC = () => { @@ -180,10 +185,14 @@ const WorkflowTemplateDetail: React.FC = () => { value: 'data_export', label: t('workflowTemplate.list.type.dataExport'), children: ( - -
+ +
{renderEditButton( 'data_export', exportTemplate?.workflow_template_name From ce866d7ed715a0674936250ab6091a74469f3c63 Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Mon, 27 Apr 2026 11:25:14 +0800 Subject: [PATCH 25/36] feat(workflow): type workflow_type for template APIs and align UI --- .../__snapshots__/index.test.tsx.snap | 18 ++--- .../Common/BasicInfoWrapper/index.tsx | 8 +- .../__snapshots__/index.test.tsx.snap | 2 +- .../ApprovalProcessPreview/index.tsx | 34 ++++---- .../__snapshots__/index.test.tsx.snap | 4 +- .../__snapshots__/index.test.tsx.snap | 10 +-- packages/base/src/scripts/version.ts | 2 +- .../shared/lib/api/sqle/service/common.d.ts | 21 +++-- .../lib/api/sqle/service/common.enum.ts | 12 +-- .../lib/api/sqle/service/workflow/index.d.ts | 22 +++--- .../api/sqle/service/workflow/index.enum.ts | 12 +++ .../lib/api/sqle/service/workflow/index.ts | 28 ++++--- .../mockApi/sqle/workflowTemplate/data.ts | 9 ++- .../sqle/src/locale/zh-CN/workflowTemplate.ts | 4 +- .../Create/hooks/useAllowAuditLevel.ts | 4 +- .../__snapshots__/index.test.tsx.snap | 10 +-- .../__snapshots__/index.test.tsx.snap | 10 +-- .../components/ReviewNodeInfo/index.tsx | 4 +- .../UpdateWorkflowTemplate/index.tsx | 21 +++-- .../__snapshots__/index.ce.test.tsx.snap | 5 +- .../__snapshots__/index.test.tsx.snap | 78 +++++++++---------- .../WorkflowTemplateDetail/column.tsx | 7 +- .../WorkflowTemplateDetail/index.tsx | 51 +++++------- .../WorkflowTemplateDetail/style.ts | 8 +- 24 files changed, 202 insertions(+), 182 deletions(-) diff --git a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap index 1495acc62e..b0b0df09d7 100644 --- a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/__snapshots__/index.test.tsx.snap @@ -11,7 +11,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 1`] export-task-1
-
@@ -30,7 +30,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 2`] export-task-1
desc
@@ -122,7 +122,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 3`] export-task-1
desc
@@ -214,7 +214,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 4`] export-task-1
desc
@@ -306,7 +306,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 5`] export-task-1
desc
@@ -398,7 +398,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 6`] export-task-1
desc
@@ -490,7 +490,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 7`] export-task-1
desc
@@ -582,7 +582,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 8`] export-task-1
desc
@@ -674,7 +674,7 @@ exports[`test base/DataExport/Common/BasicInfoWrapper should match snapshot 9`] export-task-1
desc
diff --git a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx index 8a77c4c4ef..2b4f67084b 100644 --- a/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx +++ b/packages/base/src/page/DataExportManagement/Common/BasicInfoWrapper/index.tsx @@ -1,6 +1,6 @@ import classNames from 'classnames'; import { BasicInfoWrapperProps } from './index.type'; -import { EmptyBox } from '@actiontech/dms-kit'; +import { BasicTypographyEllipsis, EmptyBox } from '@actiontech/dms-kit'; import { DataExportStatusDictionary } from '../index.data'; import { BasicInfoStyleWrapper } from './style'; const BasicInfoWrapper: React.FC = ({ @@ -77,7 +77,11 @@ const BasicInfoWrapper: React.FC = ({
{title}
-
{desc ?? '-'}
+ ); }; diff --git a/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap index b694a7e1c3..13041bc945 100644 --- a/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/__tests__/__snapshots__/index.test.tsx.snap @@ -1427,7 +1427,7 @@ exports[`first should match snapshot when pageState is equal SUBMIT_WORKFLOW 1`] test
desc
diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx index 913e10b16e..8729dcb7fb 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx @@ -5,12 +5,14 @@ import { Result } from 'antd'; import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; import { ApprovalProcessPreviewStyleWrapper } from './style'; +import { I18nKey } from '../../../../../../locale'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; interface ApprovalProcessPreviewProps { projectName: string; } -const stepTypeNameMap: Record = { +const stepTypeNameMap: Record = { export_review: 'dmsDataExport.create.approvalProcess.stepType.export_review', export_execute: 'dmsDataExport.create.approvalProcess.stepType.export_execute' }; @@ -29,7 +31,7 @@ const ApprovalProcessPreview: React.FC = ({ workflow .getWorkflowTemplateV1({ project_name: projectName, - workflow_type: 'data_export' + workflow_type: getWorkflowTemplateV1WorkflowTypeEnum.data_export }) .then((res) => res.data.data), { @@ -73,24 +75,20 @@ const ApprovalProcessPreview: React.FC = ({
- {templateData?.workflow_step_template_list?.map( - (step: IWorkFlowStepTemplateResV1, index: number) => ( -
-
-
{step.number ?? index + 1}
-
-
-
-
- {renderStepTypeName(step.type)} -
-
- {renderAssigneeInfo(step)} -
+ {templateData?.workflow_step_template_list?.map((step, index) => ( +
+
+
{step.number ?? index + 1}
+
+
+
+
+ {renderStepTypeName(step.type)}
+
{renderAssigneeInfo(step)}
- ) - )} +
+ ))}
diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap index b9998fae22..74c935ca0c 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/__tests__/__snapshots__/index.test.tsx.snap @@ -79,7 +79,7 @@ exports[`test base/DataExport/Create/SubmitWorkflow should match snapshot 1`] = test
desc
@@ -326,7 +326,7 @@ exports[`test base/DataExport/Create/SubmitWorkflow should match snapshot 2`] = test
desc
diff --git a/packages/base/src/page/DataExportManagement/Detail/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Detail/__tests__/__snapshots__/index.test.tsx.snap index 7ac2693b49..1d47de3e85 100644 --- a/packages/base/src/page/DataExportManagement/Detail/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Detail/__tests__/__snapshots__/index.test.tsx.snap @@ -212,7 +212,7 @@ exports[`test base/DataExport/Detail should match snapshot 1`] = ` mysql-1_20240130113114
desc
@@ -1154,7 +1154,7 @@ exports[`test base/DataExport/Detail should match snapshot 2`] = ` mysql-1_20240130113114
desc
@@ -3735,7 +3735,7 @@ exports[`test base/DataExport/Detail should match snapshot 3`] = ` mysql-1_20240130113114
desc
@@ -6316,7 +6316,7 @@ exports[`test base/DataExport/Detail should match snapshot 4`] = ` mysql-1_20240130113114
desc
@@ -8897,7 +8897,7 @@ exports[`test base/DataExport/Detail should match snapshot with reject workflow mysql-1_20240130113114
desc
diff --git a/packages/base/src/scripts/version.ts b/packages/base/src/scripts/version.ts index 6d5baaff06..1320f2f7e2 100644 --- a/packages/base/src/scripts/version.ts +++ b/packages/base/src/scripts/version.ts @@ -1 +1 @@ -export const UI_VERSION = 'sync/data-masking 417b194dd'; +export const UI_VERSION = 'dms-ui/feat-784 a717d17e4'; diff --git a/packages/shared/lib/api/sqle/service/common.d.ts b/packages/shared/lib/api/sqle/service/common.d.ts index 333f923789..581a17455f 100644 --- a/packages/shared/lib/api/sqle/service/common.d.ts +++ b/packages/shared/lib/api/sqle/service/common.d.ts @@ -98,6 +98,7 @@ import { WorkflowStepResV1StateEnum, WorkflowStepResV1TypeEnum, WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum, + WorkflowTemplateDetailResV1WorkflowTypeEnum, pipelineNodeBaseAuditMethodEnum, pipelineNodeBaseObjectTypeEnum, pipelineNodeBaseTypeEnum, @@ -133,6 +134,12 @@ export interface IBaseRes { message?: string; } +export interface IGlobalAccountListDataV2 { + accounts?: IGlobalAccountListItemV2[]; + + can_manage?: boolean; +} + export interface IGlobalAccountListItemV2 { account_name?: string; @@ -154,7 +161,7 @@ export interface IGlobalAccountListItemV2 { export interface IGlobalAccountListResV2 { code?: number; - data?: IGlobalAccountListItemV2[]; + data?: IGlobalAccountListDataV2; message?: string; @@ -2495,18 +2502,18 @@ export interface IGetWorkflowTasksResV1 { message?: string; } -export interface IGetWorkflowTemplateResV1 { +export interface IGetWorkflowTemplateListResV1 { code?: number; - data?: IWorkflowTemplateDetailResV1; + data?: IWorkflowTemplateDetailResV1[]; message?: string; } -export interface IGetWorkflowTemplateListResV1 { +export interface IGetWorkflowTemplateResV1 { code?: number; - data?: IWorkflowTemplateDetailResV1[]; + data?: IWorkflowTemplateDetailResV1; message?: string; } @@ -4466,7 +4473,7 @@ export interface IWorkflowTemplateDetailResV1 { workflow_template_name?: string; - workflow_type?: string; + workflow_type?: WorkflowTemplateDetailResV1WorkflowTypeEnum; } export interface ICreatePipelineResData { @@ -5108,6 +5115,8 @@ export interface IUploadInstanceAuditPlanSQLsReqV2 { } export interface IWorkflowRecordResV2 { + assignee_user_name_list?: string[]; + current_step_number?: number; executable?: boolean; diff --git a/packages/shared/lib/api/sqle/service/common.enum.ts b/packages/shared/lib/api/sqle/service/common.enum.ts index 92982bee6a..6f7e06436b 100644 --- a/packages/shared/lib/api/sqle/service/common.enum.ts +++ b/packages/shared/lib/api/sqle/service/common.enum.ts @@ -836,12 +836,6 @@ export enum WorkFlowStepTemplateReqV1TypeEnum { 'export_execute' = 'export_execute' } -export enum WorkflowTemplateTypeEnum { - 'workflow' = 'workflow', - - 'data_export' = 'data_export' -} - export enum WorkflowDetailResV1CurrentStepTypeEnum { 'sql_review' = 'sql_review', @@ -950,6 +944,12 @@ export enum WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum { 'error' = 'error' } +export enum WorkflowTemplateDetailResV1WorkflowTypeEnum { + 'workflow' = 'workflow', + + 'data_export' = 'data_export' +} + export enum pipelineNodeBaseAuditMethodEnum { 'offline' = 'offline', diff --git a/packages/shared/lib/api/sqle/service/workflow/index.d.ts b/packages/shared/lib/api/sqle/service/workflow/index.d.ts index 8883cbacab..10d9f54bd8 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.d.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.d.ts @@ -3,9 +3,9 @@ import { IGetWorkflowsResV1, IGlobalWorkflowStatisticsResV1, IGetWorkflowTemplateResV1, - IGetWorkflowTemplateListResV1, IUpdateWorkflowTemplateReqV1, IBaseRes, + IGetWorkflowTemplateListResV1, ICreateWorkflowReqV1, IAutoCreateAndExecuteWorkflowResV1, IBatchCancelWorkflowsReqV1, @@ -43,6 +43,8 @@ import { getGlobalWorkflowsV1FilterProjectPriorityEnum, GetGlobalWorkflowStatisticsFilterStatusListEnum, GetGlobalWorkflowStatisticsFilterProjectPriorityEnum, + getWorkflowTemplateV1WorkflowTypeEnum, + updateWorkflowTemplateV1WorkflowTypeEnum, getWorkflowsV1FilterStatusEnum, autoCreateAndExecuteWorkflowV1ExecModeEnum, exportWorkflowV1FilterStatusEnum, @@ -131,28 +133,28 @@ export interface IGetGlobalWorkflowStatisticsReturn export interface IGetWorkflowTemplateV1Params { project_name: string; - workflow_type?: string; + workflow_type: getWorkflowTemplateV1WorkflowTypeEnum; } export interface IGetWorkflowTemplateV1Return extends IGetWorkflowTemplateResV1 {} -export interface IGetWorkflowTemplateListV1Params { - project_name: string; -} - -export interface IGetWorkflowTemplateListV1Return - extends IGetWorkflowTemplateListResV1 {} - export interface IUpdateWorkflowTemplateV1Params extends IUpdateWorkflowTemplateReqV1 { project_name: string; - workflow_type?: string; + workflow_type: updateWorkflowTemplateV1WorkflowTypeEnum; } export interface IUpdateWorkflowTemplateV1Return extends IBaseRes {} +export interface IGetWorkflowTemplateListV1Params { + project_name: string; +} + +export interface IGetWorkflowTemplateListV1Return + extends IGetWorkflowTemplateListResV1 {} + export interface IGetWorkflowsV1Params { filter_subject?: string; diff --git a/packages/shared/lib/api/sqle/service/workflow/index.enum.ts b/packages/shared/lib/api/sqle/service/workflow/index.enum.ts index 6dd919cb8f..5b6b68c466 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.enum.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.enum.ts @@ -96,6 +96,18 @@ export enum GetGlobalWorkflowStatisticsFilterProjectPriorityEnum { 'low' = 'low' } +export enum getWorkflowTemplateV1WorkflowTypeEnum { + 'workflow' = 'workflow', + + 'data_export' = 'data_export' +} + +export enum updateWorkflowTemplateV1WorkflowTypeEnum { + 'workflow' = 'workflow', + + 'data_export' = 'data_export' +} + export enum getWorkflowsV1FilterStatusEnum { 'wait_for_audit' = 'wait_for_audit', diff --git a/packages/shared/lib/api/sqle/service/workflow/index.ts b/packages/shared/lib/api/sqle/service/workflow/index.ts index 2eed9af557..28d2f084e0 100644 --- a/packages/shared/lib/api/sqle/service/workflow/index.ts +++ b/packages/shared/lib/api/sqle/service/workflow/index.ts @@ -18,10 +18,10 @@ import { IGetGlobalWorkflowStatisticsReturn, IGetWorkflowTemplateV1Params, IGetWorkflowTemplateV1Return, - IGetWorkflowTemplateListV1Params, - IGetWorkflowTemplateListV1Return, IUpdateWorkflowTemplateV1Params, IUpdateWorkflowTemplateV1Return, + IGetWorkflowTemplateListV1Params, + IGetWorkflowTemplateListV1Return, IGetWorkflowsV1Params, IGetWorkflowsV1Return, ICreateWorkflowV1Params, @@ -168,36 +168,34 @@ class WorkflowService extends ServiceBase { ); } - public getWorkflowTemplateListV1( - params: IGetWorkflowTemplateListV1Params, + public updateWorkflowTemplateV1( + params: IUpdateWorkflowTemplateV1Params, options?: AxiosRequestConfig ) { const paramsData = this.cloneDeep(params); const project_name = paramsData.project_name; delete paramsData.project_name; - return this.get( - `/v1/projects/${project_name}/workflow_templates`, + const workflow_type = paramsData.workflow_type; + delete paramsData.workflow_type; + + return this.patch( + `/v1/projects/${project_name}/workflow_template/${workflow_type}/`, paramsData, options ); } - public updateWorkflowTemplateV1( - params: IUpdateWorkflowTemplateV1Params, + public getWorkflowTemplateListV1( + params: IGetWorkflowTemplateListV1Params, options?: AxiosRequestConfig ) { const paramsData = this.cloneDeep(params); const project_name = paramsData.project_name; delete paramsData.project_name; - const workflow_type = paramsData.workflow_type; - delete paramsData.workflow_type; - - const queryString = workflow_type ? `?workflow_type=${workflow_type}` : ''; - - return this.patch( - `/v1/projects/${project_name}/workflow_template${queryString}`, + return this.get( + `/v1/projects/${project_name}/workflow_templates`, paramsData, options ); diff --git a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts index dd1be11399..dea106eebc 100644 --- a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts +++ b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts @@ -1,5 +1,8 @@ import { IWorkflowTemplateDetailResV1 } from '../../../../api/sqle/service/common'; -import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '../../../../api/sqle/service/common.enum'; +import { + WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum, + WorkflowTemplateDetailResV1WorkflowTypeEnum +} from '../../../../api/sqle/service/common.enum'; export const workflowTemplateData = { allow_submit_when_less_audit_level: @@ -31,7 +34,7 @@ export const workflowTemplateData = { } ], workflow_template_name: '700300-WorkflowTemplate', - workflow_type: 'workflow' + workflow_type: WorkflowTemplateDetailResV1WorkflowTypeEnum.workflow }; export const dataExportWorkflowTemplateData: IWorkflowTemplateDetailResV1 = { @@ -54,7 +57,7 @@ export const dataExportWorkflowTemplateData: IWorkflowTemplateDetailResV1 = { } ], workflow_template_name: '700300-DataExportWorkflowTemplate', - workflow_type: 'data_export' + workflow_type: WorkflowTemplateDetailResV1WorkflowTypeEnum.data_export }; export const workflowTemplateListData = [ diff --git a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts index b01b013fa1..ca1a153c84 100644 --- a/packages/sqle/src/locale/zh-CN/workflowTemplate.ts +++ b/packages/sqle/src/locale/zh-CN/workflowTemplate.ts @@ -112,7 +112,7 @@ export default { rule: { descMessage: '步骤描述不能超过255个字符', userRequired: '最少需要添加一个指定人', - userMessage: '最多只能添加十个指定人' + userMessage: '最多只能添加{{max}}个指定人' } }, @@ -169,7 +169,7 @@ export default { '审核流程自工单发起开始,通过设置的审核步骤后,最后以执行上线结束;', rule2: '审核流程模板最多可设置4个审核步骤,也可不设置审核步骤;', rule3: - '单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加三个指定人。' + '单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加十个指定人。' }, exportRuler: { rule1: diff --git a/packages/sqle/src/page/SqlExecWorkflow/Create/hooks/useAllowAuditLevel.ts b/packages/sqle/src/page/SqlExecWorkflow/Create/hooks/useAllowAuditLevel.ts index 577ffef04d..71b11ebb9e 100644 --- a/packages/sqle/src/page/SqlExecWorkflow/Create/hooks/useAllowAuditLevel.ts +++ b/packages/sqle/src/page/SqlExecWorkflow/Create/hooks/useAllowAuditLevel.ts @@ -1,5 +1,6 @@ import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; import { useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -32,7 +33,8 @@ export const useAllowAuditLevel = () => { ) => { const request = (projectName: string) => { return workflow.getWorkflowTemplateV1({ - project_name: projectName + project_name: projectName, + workflow_type: getWorkflowTemplateV1WorkflowTypeEnum.workflow }); }; const tips: string[] = []; diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap index 11faf33143..db6f251891 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap @@ -20,7 +20,7 @@ exports[`page/WorkflowTemplate/UpdateWorkflowTemplate change workflow template n />
  • - 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加三个指定人。 + 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加十个指定人。
  • @@ -616,7 +616,7 @@ exports[`page/WorkflowTemplate/ReviewNodeInfo render normal review node info 1`] 审核流程模板最多可设置4个审核步骤,也可不设置审核步骤;
  • - 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加三个指定人。 + 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加十个指定人。
  • @@ -953,7 +953,7 @@ exports[`page/WorkflowTemplate/ReviewNodeInfo render review node and update revi 审核流程模板最多可设置4个审核步骤,也可不设置审核步骤;
  • - 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加三个指定人。 + 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加十个指定人。
  • @@ -1314,7 +1314,7 @@ exports[`page/WorkflowTemplate/ReviewNodeInfo render review node with default as 审核流程模板最多可设置4个审核步骤,也可不设置审核步骤;
  • - 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加三个指定人。 + 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加十个指定人。
  • @@ -1841,7 +1841,7 @@ exports[`page/WorkflowTemplate/ReviewNodeInfo validate assignee user number 1`] 审核流程模板最多可设置4个审核步骤,也可不设置审核步骤;
  • - 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加三个指定人。 + 单个步骤指定执行人时,最少需要添加一个指定人,最多只能添加十个指定人。
  • diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx index 586777d763..780eb3c183 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx @@ -200,7 +200,9 @@ const ReviewAndExecNodeInfo: React.FC = (props) => { return Promise.resolve(); } return Promise.reject( - t('workflowTemplate.form.rule.userMessage') + t('workflowTemplate.form.rule.userMessage', { + max: MAX_USER_COUNT + }) ); } } diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx index d7c04a287e..f8d700bd3b 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx @@ -33,7 +33,12 @@ import { useBoolean, useRequest } from 'ahooks'; import { useForm } from 'antd/es/form/Form'; import { WorkflowTemplateStyleWrapper } from '../WorkflowTemplateDetail/style'; import useUsername from '../../../hooks/useUsername'; -import { ROUTE_PATHS } from '@actiontech/dms-kit'; +import { ROUTE_PATHS, ResponseCode } from '@actiontech/dms-kit'; +import { + getWorkflowTemplateV1WorkflowTypeEnum, + updateWorkflowTemplateV1WorkflowTypeEnum +} from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; + const UpdateWorkflowTemplate: React.FC = () => { const { t } = useTranslation(); const [form] = useForm(); @@ -47,10 +52,10 @@ const UpdateWorkflowTemplate: React.FC = () => { const { projectName, projectID } = useCurrentProject(); const extractQueries = useTypedQuery(); const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.update); - const workflowType = searchParams?.workflowType || 'workflow'; + const workflowType = searchParams?.workflowType; const pageTitle = - workflowType === 'data_export' + workflowType === updateWorkflowTemplateV1WorkflowTypeEnum.data_export ? t('workflowTemplate.update.title.dataExport') : t('workflowTemplate.update.title.workflow'); @@ -97,14 +102,16 @@ const UpdateWorkflowTemplate: React.FC = () => { return workflow .updateWorkflowTemplateV1({ project_name: projectName, - workflow_type: workflowType, + workflow_type: workflowType as updateWorkflowTemplateV1WorkflowTypeEnum, workflow_step_template_list: templateList, allow_submit_when_less_audit_level: selectLevel as | UpdateWorkflowTemplateReqV1AllowSubmitWhenLessAuditLevelEnum | undefined }) .then((res) => { - setUpdateSuccess(true); + if (res.data.code === ResponseCode.SUCCESS) { + setUpdateSuccess(true); + } return res; }) .finally(() => submitFinish()); @@ -115,7 +122,7 @@ const UpdateWorkflowTemplate: React.FC = () => { workflow .getWorkflowTemplateV1({ project_name: projectName, - workflow_type: workflowType + workflow_type: workflowType as getWorkflowTemplateV1WorkflowTypeEnum }) .then((res) => { const temp = res.data.data; @@ -231,6 +238,8 @@ const UpdateWorkflowTemplate: React.FC = () => { execute_by_authorized: true, type: executeType }); + basicForm.resetFields(); + form.resetFields(); }; const handleExchangeReviewNode = (from: number, to: number) => { const temp = cloneDeep(reviewSteps); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap index 179121d5fd..8aca3e9b2e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.ce.test.tsx.snap @@ -4,7 +4,7 @@ exports[`page/WorkflowTemplate CE render workflow template detail without edit a
    -
    diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap index 1a9631e0b6..e818811750 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/__snapshots__/index.test.tsx.snap @@ -4,7 +4,7 @@ exports[`page/WorkflowTemplate/WorkflowTemplateDetail render workflow template d
    -
    diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx index 633ae6ef0e..8268a16d12 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx @@ -1,9 +1,9 @@ import { ActiontechTableColumn } from '@actiontech/dms-kit/es/components/ActiontechTable'; import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; -import { WorkflowTemplateTypeEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; import { BasicTag } from '@actiontech/dms-kit'; import { formatTime } from '@actiontech/dms-kit'; import { t, I18nKey } from '../../../locale'; +import { WorkflowTemplateDetailResV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; const stepTypeNameMap: Record = { sql_review: 'workflowTemplate.progressConfig.review.title', @@ -29,7 +29,10 @@ export const WorkflowTemplateListColumn = dataIndex: 'workflow_type', title: () => t('workflowTemplate.list.table.applicableType'), render: (workflowType) => { - if (workflowType === WorkflowTemplateTypeEnum.data_export) { + if ( + workflowType === + WorkflowTemplateDetailResV1WorkflowTypeEnum.data_export + ) { return ( {t('workflowTemplate.list.type.dataExport')} diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx index e63a9ff08a..9548b01fd6 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx @@ -17,6 +17,9 @@ import WorkflowTemplateAuthInfo from './components/WorkflowTemplateAuthInfo'; import { WorkflowTemplateStyleWrapper } from './style'; import useUsername from '../../../hooks/useUsername'; import { EditOutlined } from '@ant-design/icons'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; + +type WorkflowTemplateDetailTab = 'workflow' | 'data_export'; const WorkflowTemplateDetail: React.FC = () => { const { t } = useTranslation(); @@ -25,7 +28,8 @@ const WorkflowTemplateDetail: React.FC = () => { const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.index); const initialTab = searchParams?.activeTab === 'data_export' ? 'data_export' : 'workflow'; - const [activeTab, setActiveTab] = useState(initialTab); + const [activeTab, setActiveTab] = + useState(initialTab); const { updateUsernameList, @@ -55,7 +59,7 @@ const WorkflowTemplateDetail: React.FC = () => { workflow .getWorkflowTemplateV1({ project_name: projectName, - workflow_type: 'workflow' + workflow_type: getWorkflowTemplateV1WorkflowTypeEnum.workflow }) .then((res) => { const stepList = res.data.data?.workflow_step_template_list ?? []; @@ -92,7 +96,7 @@ const WorkflowTemplateDetail: React.FC = () => { workflow .getWorkflowTemplateV1({ project_name: projectName, - workflow_type: 'data_export' + workflow_type: getWorkflowTemplateV1WorkflowTypeEnum.data_export }) .then((res) => { const stepList = res.data.data?.workflow_step_template_list ?? []; @@ -114,8 +118,7 @@ const WorkflowTemplateDetail: React.FC = () => { ); const renderEditButton = useCallback( - (workflowType: string, templateName?: string) => { - // #if [ee] + (workflowType: WorkflowTemplateDetailTab, templateName?: string) => { return ( { /> ); - // #endif - return null; }, [t, projectID] ); @@ -151,18 +152,6 @@ const WorkflowTemplateDetail: React.FC = () => { label: t('workflowTemplate.list.type.workflow'), children: ( -
    - {renderEditButton( - 'workflow', - workflowTemplate?.workflow_template_name - )} -
    { label: t('workflowTemplate.list.type.dataExport'), children: ( -
    - {renderEditButton( - 'data_export', - exportTemplate?.workflow_template_name - )} -
    { exportExecStep, usernameList, workflowTemplate, - exportTemplate, - renderEditButton + exportTemplate ] ); @@ -241,6 +217,15 @@ const WorkflowTemplateDetail: React.FC = () => { activeKey={activeTab} onChange={setActiveTab} items={tabItems} + // #if [ee] + segmentedRowClassName="flex-space-between" + segmentedRowExtraContent={renderEditButton( + activeTab, + activeTab === 'workflow' + ? workflowTemplate?.workflow_template_name + : exportTemplate?.workflow_template_name + )} + // #endif /> ); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts index 915f047a9a..6682b568f6 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts @@ -3,10 +3,6 @@ import { styled } from '@mui/material/styles'; export const WorkflowTemplateStyleWrapper = styled('div')` height: 100%; - .segmented-tabs-wrapper { - padding: 0 40px; - } - .workflow-template-wrapper { height: 100%; } @@ -17,3 +13,7 @@ export const WorkflowTemplateStyleWrapper = styled('div')` height: auto; } `; + +export const WorkflowTemplateStepInfoWrapper = styled('div')` + height: 100%; +`; From 9d171ebc1c25092e09129341089d7df1afcad4bf Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Mon, 27 Apr 2026 13:14:33 +0800 Subject: [PATCH 26/36] chore: restore version.ts --- packages/base/src/scripts/version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/base/src/scripts/version.ts b/packages/base/src/scripts/version.ts index 1320f2f7e2..6d5baaff06 100644 --- a/packages/base/src/scripts/version.ts +++ b/packages/base/src/scripts/version.ts @@ -1 +1 @@ -export const UI_VERSION = 'dms-ui/feat-784 a717d17e4'; +export const UI_VERSION = 'sync/data-masking 417b194dd'; From 5b27115aa756f23932e1eea70e5d80cb1b0e3e71 Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Mon, 27 Apr 2026 15:22:44 +0800 Subject: [PATCH 27/36] fix: code review --- .../__snapshots__/index.test.tsx.snap | 6 +- .../__tests__/index.test.tsx | 45 ++++++-------- .../ApprovalProcessPreview/index.data.ts | 10 +++ .../ApprovalProcessPreview/index.tsx | 31 ++++------ .../ApprovalProcessPreview/style.ts | 2 +- .../WorkflowRecordInfo/WorkflowSteps.tsx | 8 +-- .../WorkflowRecordInfo/index.type.ts | 5 ++ .../components/BasicInfo/index.tsx | 5 +- .../components/BasicInfo/index.type.ts | 3 +- .../components/ReviewNodeInfo/index.tsx | 4 +- .../components/ReviewNodeInfo/index.type.ts | 3 +- .../UpdateWorkflowTemplate/index.tsx | 29 +++++++-- .../WorkflowTemplateDetail/actions.tsx | 56 +++++++++++------ .../WorkflowTemplateDetail/column.tsx | 16 ++--- .../WorkflowTemplateDetail/index.ce.test.tsx | 1 + .../WorkflowTemplateDetail/index.test.tsx | 1 + .../WorkflowTemplateDetail/index.tsx | 61 ++++++++----------- .../WorkflowTemplateDetail/style.ts | 4 -- .../components/StepCard/stepInfo.tsx | 12 ++-- 19 files changed, 168 insertions(+), 134 deletions(-) create mode 100644 packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.data.ts diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap index 3ee435a6b3..2822c8ca42 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/__tests__/__snapshots__/index.test.tsx.snap @@ -4,7 +4,7 @@ exports[`base/DataExport/Create/ApprovalProcessPreview should render fallback er
    { + let mockGetWorkflowTemplateApi: jest.SpyInstance; beforeEach(() => { jest.useFakeTimers(); + mockGetWorkflowTemplateApi = MockWorkflowTemplateApi.getWorkflowTemplate(); }); afterEach(() => { @@ -26,28 +29,20 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { }; it('should render loading state', () => { - jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation( - () => - new Promise(() => { - /* never resolves to keep loading */ - }) - ); const { baseElement } = customRender(); expect(baseElement).toMatchSnapshot(); }); it('should render step list when data loaded successfully', async () => { - const getTemplateSpy = jest - .spyOn(workflow, 'getWorkflowTemplateV1') - .mockImplementation(() => - createSpySuccessResponse({ - data: cloneDeep(dataExportWorkflowTemplateData) - }) - ); + mockGetWorkflowTemplateApi.mockImplementation(() => + createSpySuccessResponse({ + data: cloneDeep(dataExportWorkflowTemplateData) + }) + ); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); - expect(getTemplateSpy).toHaveBeenCalledWith({ + expect(mockGetWorkflowTemplateApi).toHaveBeenCalledWith({ project_name: 'test-project', workflow_type: 'data_export' }); @@ -59,9 +54,9 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { }); it('should render fallback error state when request fails', async () => { - jest - .spyOn(workflow, 'getWorkflowTemplateV1') - .mockImplementation(() => createSpyErrorResponse({})); + mockGetWorkflowTemplateApi.mockImplementation(() => + createSpyErrorResponse({}) + ); const { baseElement } = customRender(); await act(async () => jest.advanceTimersByTime(3000)); @@ -87,9 +82,9 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { type: 'export_execute' } ]; - jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation(() => + mockGetWorkflowTemplateApi.mockImplementation(() => createSpySuccessResponse({ - data: multiStepData + data: cloneDeep(multiStepData) }) ); customRender(); @@ -110,9 +105,9 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { type: 'export_review' } ]; - jest.spyOn(workflow, 'getWorkflowTemplateV1').mockImplementation(() => + mockGetWorkflowTemplateApi.mockImplementation(() => createSpySuccessResponse({ - data: customData + data: cloneDeep(customData) }) ); customRender(); @@ -122,10 +117,10 @@ describe('base/DataExport/Create/ApprovalProcessPreview', () => { }); it('should not make API call when projectName is empty', () => { - const getTemplateSpy = jest - .spyOn(workflow, 'getWorkflowTemplateV1') - .mockImplementation(() => createSpySuccessResponse({ data: {} })); + mockGetWorkflowTemplateApi.mockImplementation(() => + createSpySuccessResponse({ data: {} }) + ); customRender(''); - expect(getTemplateSpy).not.toHaveBeenCalled(); + expect(mockGetWorkflowTemplateApi).not.toHaveBeenCalled(); }); }); diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.data.ts b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.data.ts new file mode 100644 index 0000000000..3783869ad3 --- /dev/null +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.data.ts @@ -0,0 +1,10 @@ +import { t } from '../../../../../../locale'; + +export const stepTypeNameMap: Record = { + export_review: t( + 'dmsDataExport.create.approvalProcess.stepType.export_review' + ), + export_execute: t( + 'dmsDataExport.create.approvalProcess.stepType.export_execute' + ) +}; diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx index 8729dcb7fb..1790abec1f 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/index.tsx @@ -2,21 +2,16 @@ import { useTranslation } from 'react-i18next'; import { useRequest } from 'ahooks'; import { Spin } from 'antd'; import { Result } from 'antd'; -import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; import { ApprovalProcessPreviewStyleWrapper } from './style'; -import { I18nKey } from '../../../../../../locale'; import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; +import { stepTypeNameMap } from './index.data'; +import { SqleApi } from '@actiontech/shared/lib/api'; interface ApprovalProcessPreviewProps { projectName: string; } -const stepTypeNameMap: Record = { - export_review: 'dmsDataExport.create.approvalProcess.stepType.export_review', - export_execute: 'dmsDataExport.create.approvalProcess.stepType.export_execute' -}; - const ApprovalProcessPreview: React.FC = ({ projectName }) => { @@ -28,14 +23,14 @@ const ApprovalProcessPreview: React.FC = ({ error } = useRequest( () => - workflow - .getWorkflowTemplateV1({ - project_name: projectName, - workflow_type: getWorkflowTemplateV1WorkflowTypeEnum.data_export - }) - .then((res) => res.data.data), + SqleApi.WorkflowService.getWorkflowTemplateV1({ + project_name: projectName, + workflow_type: getWorkflowTemplateV1WorkflowTypeEnum.data_export + }).then((res) => res.data.data), { - ready: !!projectName + ready: !!projectName, + // eslint-disable-next-line @typescript-eslint/no-empty-function + onError: () => {} } ); @@ -50,10 +45,10 @@ const ApprovalProcessPreview: React.FC = ({ }; const renderStepTypeName = (type?: string) => { - if (type && stepTypeNameMap[type]) { - return t(stepTypeNameMap[type]); + if (type) { + return stepTypeNameMap[type] ?? '-'; } - return type ?? '-'; + return '-'; }; if (error) { @@ -78,7 +73,7 @@ const ApprovalProcessPreview: React.FC = ({ {templateData?.workflow_step_template_list?.map((step, index) => (
    -
    {step.number ?? index + 1}
    +
    {step.number}
    diff --git a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts index 52b6645edf..53aa909904 100644 --- a/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts +++ b/packages/base/src/page/DataExportManagement/Create/components/SubmitWorkflow/ApprovalProcessPreview/style.ts @@ -47,7 +47,7 @@ export const ApprovalProcessPreviewStyleWrapper = styled('div')` height: 24px; border-radius: 50%; background: ${({ theme }) => theme.sharedTheme.uiToken.colorPrimary}; - color: #fff; + color: ${({ theme }) => theme.sharedTheme.basic.colorWhite}; font-size: 12px; font-weight: 600; display: flex; diff --git a/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx b/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx index e6f436ea93..fb6ed26d02 100644 --- a/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx +++ b/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/WorkflowSteps.tsx @@ -1,6 +1,6 @@ import { Divider, StepProps } from 'antd'; import { useTranslation } from 'react-i18next'; -import { WorkflowStepsProps } from './index.type'; +import { WorkflowStep, WorkflowStepsProps } from './index.type'; import { useCallback, useMemo } from 'react'; import { CustomSteps, WorkflowStepsItemStyleWrapper } from './style'; import { Space } from 'antd'; @@ -151,7 +151,7 @@ const WorkflowSteps: React.FC = ({ ] ); const renderOrderStepsItem = useCallback( - (title: string, step: any) => { + (title: string, step: WorkflowStep) => { return (
    {title}
    @@ -163,7 +163,7 @@ const WorkflowSteps: React.FC = ({ [renderOrderStepsItemContent] ); const renderOrderStepsItemIcon = useCallback( - (type?: string, step?: any) => { + (type?: string, step?: WorkflowStep) => { if (type === 'create') { return ; } @@ -203,7 +203,7 @@ const WorkflowSteps: React.FC = ({ } // Build dynamic steps: create + N approval nodes + execute - const allSteps: any[] = [ + const allSteps: WorkflowStep[] = [ { type: 'create', number: 1, diff --git a/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/index.type.ts b/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/index.type.ts index b586ed0304..c5212372ce 100644 --- a/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/index.type.ts +++ b/packages/base/src/page/DataExportManagement/Detail/components/WorkflowRecordInfo/index.type.ts @@ -23,3 +23,8 @@ export type WorkflowStepsProps = { export type WorkflowHistoryStepsProps = { recordHistoryList?: IWorkflowRecord[]; }; + +export type WorkflowStep = { + type: 'create' | 'approve' | 'execute'; + number: number; +} & IWorkflowStep; diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx index df97d96e7f..39ebf182e4 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.tsx @@ -7,11 +7,14 @@ import { BaseFormProps } from './index.type'; import useStaticStatus from '../../../../../hooks/useStaticStatus'; import StepButton from '../StepButton'; import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; + const BasicInfo: React.FC = (props) => { const { t } = useTranslation(); const { form, workflowType } = props; const { getAuditLevelStatusSelectOption } = useStaticStatus(); - const isDataExport = workflowType === 'data_export'; + const isDataExport = + workflowType === getWorkflowTemplateV1WorkflowTypeEnum.data_export; const nextStep = async () => { const value = await form.validateFields(); props.updateBaseInfo(value?.allowSubmitWhenLessAuditLevel); diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.type.ts b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.type.ts index e494757a21..02b134c709 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.type.ts +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/BasicInfo/index.type.ts @@ -1,5 +1,6 @@ import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; import { WorkflowTemplateDetailResV1AllowSubmitWhenLessAuditLevelEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; import { FormInstance } from 'antd'; export type BaseFormProps = { @@ -10,7 +11,7 @@ export type BaseFormProps = { info: BaseFormFields['allowSubmitWhenLessAuditLevel'] ) => void; totalStep: number; - workflowType?: string; + workflowType?: getWorkflowTemplateV1WorkflowTypeEnum; }; export type BaseFormFields = { diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx index 780eb3c183..e54441456e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.tsx @@ -15,12 +15,14 @@ import { import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; import StepButton from '../StepButton'; import { InfoCircleOutlined } from '@ant-design/icons'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; const MAX_USER_COUNT = 10; const ReviewAndExecNodeInfo: React.FC = (props) => { const { t } = useTranslation(); - const isDataExport = props.workflowType === 'data_export'; + const isDataExport = + props.workflowType === getWorkflowTemplateV1WorkflowTypeEnum.data_export; const [authorizedParam, setAuthorizedParam] = useState( props.type === NodeTypeEnum.review ? 'approved_by_authorized' diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts index 6eb21c3662..18c67ebc1a 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/components/ReviewNodeInfo/index.type.ts @@ -1,4 +1,5 @@ import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; import { FormInstance } from 'antd'; export enum NodeTypeEnum { @@ -29,5 +30,5 @@ export type ReviewAndExecNodeInfoProps = { updateReviewAndExecNodeInfo: (data: IWorkFlowStepTemplateResV1) => void; generateUsernameSelectOption: () => React.ReactNode; getUsernameListLoading: boolean; - workflowType?: string; + workflowType?: getWorkflowTemplateV1WorkflowTypeEnum; }; diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx index f8d700bd3b..5b2edc2a34 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx @@ -6,7 +6,7 @@ import { } from '@actiontech/shared'; import { ArrowLeftOutlined } from '@ant-design/icons'; import { Col, Row, Space, Spin } from 'antd'; -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import BasicInfo from './components/BasicInfo'; import StepInfo from './components/StepInfo'; @@ -51,11 +51,29 @@ const UpdateWorkflowTemplate: React.FC = () => { const urlParams = useTypedParams(); const { projectName, projectID } = useCurrentProject(); const extractQueries = useTypedQuery(); - const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.update); - const workflowType = searchParams?.workflowType; + const [workflowType, setWorkflowType] = useState< + getWorkflowTemplateV1WorkflowTypeEnum | undefined + >(undefined); + + useEffect(() => { + const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.update); + const isWorkflowType = ( + value: string + ): value is getWorkflowTemplateV1WorkflowTypeEnum => { + return Object.values(getWorkflowTemplateV1WorkflowTypeEnum).includes( + value as getWorkflowTemplateV1WorkflowTypeEnum + ); + }; + if ( + searchParams?.workflowType && + isWorkflowType(searchParams.workflowType) + ) { + setWorkflowType(searchParams.workflowType); + } + }, [extractQueries]); const pageTitle = - workflowType === updateWorkflowTemplateV1WorkflowTypeEnum.data_export + workflowType === getWorkflowTemplateV1WorkflowTypeEnum.data_export ? t('workflowTemplate.update.title.dataExport') : t('workflowTemplate.update.title.workflow'); @@ -102,7 +120,8 @@ const UpdateWorkflowTemplate: React.FC = () => { return workflow .updateWorkflowTemplateV1({ project_name: projectName, - workflow_type: workflowType as updateWorkflowTemplateV1WorkflowTypeEnum, + workflow_type: + workflowType as unknown as updateWorkflowTemplateV1WorkflowTypeEnum, workflow_step_template_list: templateList, allow_submit_when_less_audit_level: selectLevel as | UpdateWorkflowTemplateReqV1AllowSubmitWhenLessAuditLevelEnum diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx index ef92f7b9ab..4e61248dde 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/actions.tsx @@ -1,23 +1,39 @@ -import { t } from '../../../locale'; +import { ROUTE_PATHS } from '@actiontech/dms-kit'; import { - ActiontechTableActionsWithPermissions, - PERMISSIONS + PERMISSIONS, + PermissionControl } from '@actiontech/shared/lib/features'; -import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; +import { EditOutlined } from '@ant-design/icons'; +import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; +import { ActionButton } from '@actiontech/shared'; +import { t } from '../../../locale'; -export const WorkflowTemplateTableActions: ( - onEdit: (record: IWorkflowTemplateDetailResV1) => void -) => ActiontechTableActionsWithPermissions = ( - onEdit -) => ({ - buttons: [ - { - key: 'edit-workflow-template', - text: t('common.edit'), - buttonProps: (record) => ({ - onClick: () => onEdit(record ?? {}) - }), - permissions: PERMISSIONS.ACTIONS.SQLE.WORKFLOW_TEMPLATE.UPDATE - } - ] -}); +export const workflowTemplateDetailAction = (params: { + projectID: string; + templateName?: string; + workflowType: getWorkflowTemplateV1WorkflowTypeEnum; +}) => { + const { projectID, templateName, workflowType } = params; + return ( + + } + text={t('workflowTemplate.detail.updateTemplate')} + actionType="navigate-link" + link={{ + to: ROUTE_PATHS.SQLE.PROGRESS.update, + params: { + projectID, + workflowName: templateName ?? '' + }, + queries: { + workflowType + } + }} + /> + + ); +}; diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx index 8268a16d12..6b1f6e21f6 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/column.tsx @@ -2,20 +2,20 @@ import { ActiontechTableColumn } from '@actiontech/dms-kit/es/components/Actiont import { IWorkflowTemplateDetailResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; import { BasicTag } from '@actiontech/dms-kit'; import { formatTime } from '@actiontech/dms-kit'; -import { t, I18nKey } from '../../../locale'; +import { t } from '../../../locale'; import { WorkflowTemplateDetailResV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/common.enum'; -const stepTypeNameMap: Record = { - sql_review: 'workflowTemplate.progressConfig.review.title', - sql_execute: 'workflowTemplate.progressConfig.exec.title', - export_review: 'workflowTemplate.progressConfig.exportReview.title', - export_execute: 'workflowTemplate.progressConfig.exportExecute.title' +const stepTypeNameMap: Record = { + sql_review: t('workflowTemplate.progressConfig.review.title'), + sql_execute: t('workflowTemplate.progressConfig.exec.title'), + export_review: t('workflowTemplate.progressConfig.exportReview.title'), + export_execute: t('workflowTemplate.progressConfig.exportExecute.title') }; const getStepTypeName = (stepType?: string): string => { if (!stepType) return '-'; - const i18nKey = stepTypeNameMap[stepType]; - return i18nKey ? t(i18nKey) : stepType; + const name = stepTypeNameMap[stepType]; + return name ? name : stepType; }; export const WorkflowTemplateListColumn = diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx index 1991994caa..35d69a2c0e 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.ce.test.tsx @@ -50,5 +50,6 @@ describe('page/WorkflowTemplate CE', () => { expect(getTemplateRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); expect(screen.getByText('审批流程模板')).toBeInTheDocument(); + expect(screen.queryByText('修改当前审批流程模板')).not.toBeInTheDocument(); }); }); diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx index 5f9d3f3f7f..2c017746f9 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.test.tsx @@ -40,6 +40,7 @@ describe('page/WorkflowTemplate/WorkflowTemplateDetail', () => { expect(getTemplateRequest).toHaveBeenCalled(); expect(baseElement).toMatchSnapshot(); expect(screen.getByText('审批流程模板')).toBeInTheDocument(); + expect(screen.queryByText('修改当前审批流程模板')).toBeInTheDocument(); }); it('render segmented tab labels correctly', async () => { diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx index 9548b01fd6..40885f6891 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/index.tsx @@ -3,12 +3,8 @@ import { useRequest } from 'ahooks'; import { useTranslation } from 'react-i18next'; import { Col, Row, Spin } from 'antd'; import workflow from '@actiontech/shared/lib/api/sqle/service/workflow'; -import { - useCurrentProject, - PERMISSIONS, - PermissionControl -} from '@actiontech/shared/lib/features'; -import { ActionButton, useTypedQuery } from '@actiontech/shared'; +import { useCurrentProject } from '@actiontech/shared/lib/features'; +import { useTypedQuery } from '@actiontech/shared'; import { ROUTE_PATHS } from '@actiontech/dms-kit'; import { PageHeader, SegmentedTabs } from '@actiontech/dms-kit'; import { IWorkFlowStepTemplateResV1 } from '@actiontech/shared/lib/api/sqle/service/common'; @@ -16,20 +12,25 @@ import WorkflowTemplateStepInfo from './components/WorkflowTemplateStepInfo'; import WorkflowTemplateAuthInfo from './components/WorkflowTemplateAuthInfo'; import { WorkflowTemplateStyleWrapper } from './style'; import useUsername from '../../../hooks/useUsername'; -import { EditOutlined } from '@ant-design/icons'; import { getWorkflowTemplateV1WorkflowTypeEnum } from '@actiontech/shared/lib/api/sqle/service/workflow/index.enum'; - -type WorkflowTemplateDetailTab = 'workflow' | 'data_export'; +import { workflowTemplateDetailAction } from './actions'; const WorkflowTemplateDetail: React.FC = () => { const { t } = useTranslation(); const { projectName, projectID } = useCurrentProject(); const extractQueries = useTypedQuery(); const searchParams = extractQueries(ROUTE_PATHS.SQLE.PROGRESS.index); - const initialTab = - searchParams?.activeTab === 'data_export' ? 'data_export' : 'workflow'; + const [activeTab, setActiveTab] = - useState(initialTab); + useState(() => { + if ( + searchParams?.activeTab === + getWorkflowTemplateV1WorkflowTypeEnum.data_export + ) { + return getWorkflowTemplateV1WorkflowTypeEnum.data_export; + } + return getWorkflowTemplateV1WorkflowTypeEnum.workflow; + }); const { updateUsernameList, @@ -118,31 +119,17 @@ const WorkflowTemplateDetail: React.FC = () => { ); const renderEditButton = useCallback( - (workflowType: WorkflowTemplateDetailTab, templateName?: string) => { - return ( - - } - text={t('workflowTemplate.detail.updateTemplate')} - actionType="navigate-link" - link={{ - to: ROUTE_PATHS.SQLE.PROGRESS.update, - params: { - projectID, - workflowName: templateName ?? '' - }, - queries: { - workflowType - } - }} - /> - - ); + ( + workflowType: getWorkflowTemplateV1WorkflowTypeEnum, + templateName?: string + ) => { + return workflowTemplateDetailAction({ + projectID, + templateName: templateName, + workflowType + }); }, - [t, projectID] + [projectID] ); const tabItems = useMemo( @@ -221,7 +208,7 @@ const WorkflowTemplateDetail: React.FC = () => { segmentedRowClassName="flex-space-between" segmentedRowExtraContent={renderEditButton( activeTab, - activeTab === 'workflow' + activeTab === getWorkflowTemplateV1WorkflowTypeEnum.workflow ? workflowTemplate?.workflow_template_name : exportTemplate?.workflow_template_name )} diff --git a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts index 6682b568f6..392f85f8bd 100644 --- a/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts +++ b/packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/style.ts @@ -13,7 +13,3 @@ export const WorkflowTemplateStyleWrapper = styled('div')` height: auto; } `; - -export const WorkflowTemplateStepInfoWrapper = styled('div')` - height: 100%; -`; diff --git a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx index 236aa8725e..135dd135e6 100644 --- a/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/components/StepCard/stepInfo.tsx @@ -67,11 +67,13 @@ const renderReviewUser = ( height={18} /> - {t( - isDataExport - ? 'workflowTemplate.progressConfig.exportExec.executeUserType.matchExecute' - : 'workflowTemplate.progressConfig.exec.executeUserType.matchExecute' - )} + {isDataExport + ? t( + 'workflowTemplate.progressConfig.exportExec.executeUserType.matchExecute' + ) + : t( + 'workflowTemplate.progressConfig.exec.executeUserType.matchExecute' + )} ); From 72e5a22bc5409e2335c2bf502f5b1c13e2c5c43d Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Mon, 27 Apr 2026 17:03:01 +0800 Subject: [PATCH 28/36] fix: workflow_type is undefined --- .../src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx index 5b2edc2a34..82818363b4 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/index.tsx @@ -48,7 +48,6 @@ const UpdateWorkflowTemplate: React.FC = () => { const [submitLoading, { setTrue: startSubmit, setFalse: submitFinish }] = useBoolean(false); const [updateSuccess, setUpdateSuccess] = useState(false); - const urlParams = useTypedParams(); const { projectName, projectID } = useCurrentProject(); const extractQueries = useTypedQuery(); const [workflowType, setWorkflowType] = useState< @@ -159,7 +158,7 @@ const UpdateWorkflowTemplate: React.FC = () => { return res.data.data; }), { - ready: !!projectName && !!urlParams.workflowName + ready: !!projectName && !!workflowType } ); const [currentStep, setCurrentStep] = useState(0); From 730ab236b86f8a94098a7a1c71def6bcacf15e02 Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Tue, 28 Apr 2026 17:37:59 +0800 Subject: [PATCH 29/36] fix: makefile build error --- .github/workflows/main.yml | 1 - Makefile | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6b67d23586..181477df68 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -46,7 +46,6 @@ jobs: run: pnpm turbo run test:ci --filter=${{ matrix.package_name }} - name: Coverage report - if: always() uses: ArtiomTr/jest-coverage-report-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/Makefile b/Makefile index c07ec1a575..69e5770452 100644 --- a/Makefile +++ b/Makefile @@ -38,13 +38,13 @@ docker_clean: $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app -w /usr/src/app --rm $(DOCKER_IMAGE) sh -c "git config --global --add safe.directory /usr/src/app && git clean -dfx" docker_build_ce: pull_image docker_install_node_modules - $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app --user $(UID):$(GID) -w /usr/src/app --rm $(DOCKER_IMAGE) sh -c "pnpm build:release" + $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app --user $(UID):$(GID) -w /usr/src/app --rm $(DOCKER_IMAGE) sh -c "pnpm --filter base build:release" docker_build_ee: pull_image docker_install_node_modules - $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app --user $(UID):$(GID) -w /usr/src/app --rm $(DOCKER_IMAGE) sh -c "pnpm build:release:ee" + $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app --user $(UID):$(GID) -w /usr/src/app --rm $(DOCKER_IMAGE) sh -c "pnpm --filter base build:release:ee" docker_build_demo: pull_image docker_install_node_modules - $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app --user $(UID):$(GID) -w /usr/src/app --rm $(DOCKER_IMAGE) sh -c "pnpm build:release:demo" + $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app --user $(UID):$(GID) -w /usr/src/app --rm $(DOCKER_IMAGE) sh -c "pnpm --filter base build:release:demo" docker_dms_kit_publish: docker_install_node_modules $(DOCKER) run -v $(MAIN_MODULE):/usr/src/app --user $(UID):$(GID) -w /usr/src/app --rm \ From 489c7d7ab6db35bc6cf74c03e9076a66d045664f Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Tue, 28 Apr 2026 17:59:32 +0800 Subject: [PATCH 30/36] fix(ci): skip internal install and test in coverage action Avoid ArtiomTr/jest-coverage-report-action running npm install and npx jest for base coverage collection, which fails in pnpm workspace projects. Rely on the pre-generated per-package coverage report.json instead. Made-with: Cursor --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 181477df68..feead9a9dc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -50,3 +50,4 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} coverage-file: ${{ matrix.package_path }}/coverage/report.json + skip-step: all From 1f5ad7ae5a49120d4bee27a6c7e88f4f7b83854b Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Tue, 28 Apr 2026 18:32:38 +0800 Subject: [PATCH 31/36] fix(ci): github action --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index feead9a9dc..31a6dbedf1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -50,4 +50,5 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} coverage-file: ${{ matrix.package_path }}/coverage/report.json + base-coverage-file: ${{ matrix.package_path }}/coverage/report.json skip-step: all From 89352ca1f884915dd99896a1395367910b57b72c Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Tue, 28 Apr 2026 18:37:45 +0800 Subject: [PATCH 32/36] fix(ci): coverage report add custom title --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 31a6dbedf1..4d9700e192 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -49,6 +49,7 @@ jobs: uses: ArtiomTr/jest-coverage-report-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} + custom-title: 'Coverage report (${{ matrix.package_name }})' coverage-file: ${{ matrix.package_path }}/coverage/report.json base-coverage-file: ${{ matrix.package_path }}/coverage/report.json skip-step: all From 88def2d519de37ab99c04cc83e3f7dedc21093cb Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Wed, 29 Apr 2026 10:26:20 +0800 Subject: [PATCH 33/36] test: update snapshot --- .../List/__snapshots__/index.test.tsx.snap | 55 +++++++++++++++++++ .../__snapshots__/index.test.tsx.snap | 55 +++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/packages/sqle/src/page/SqlOptimization/List/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlOptimization/List/__snapshots__/index.test.tsx.snap index ae17059549..b9b13707a6 100644 --- a/packages/sqle/src/page/SqlOptimization/List/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlOptimization/List/__snapshots__/index.test.tsx.snap @@ -119,6 +119,7 @@ exports[`sqle/SqlOptimizationList render table data 1`] = ` >
    +
    + +
    diff --git a/packages/sqle/src/page/SqlOptimization/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/SqlOptimization/__snapshots__/index.test.tsx.snap index 1b3987d0e0..90736772a0 100644 --- a/packages/sqle/src/page/SqlOptimization/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/SqlOptimization/__snapshots__/index.test.tsx.snap @@ -120,6 +120,7 @@ exports[`sqle/SqlOptimization should render enterprise feature display with prop >
    +
    + +
    From ca401d96862e126229472b684713b26c6f338266 Mon Sep 17 00:00:00 2001 From: lizhensheng Date: Wed, 29 Apr 2026 16:46:59 +0800 Subject: [PATCH 34/36] fix(workflow-template): extract steps by type and add ordering tests for review nodes --- .../mockApi/sqle/workflowTemplate/data.ts | 61 ++ .../mockApi/sqle/workflowTemplate/index.ts | 13 +- .../__snapshots__/index.test.tsx.snap | 530 +++++++++++++++++- .../UpdateWorkflowTemplate/index.test.tsx | 77 +++ .../UpdateWorkflowTemplate/index.tsx | 31 +- .../WorkflowTemplateDetail/enum.ts | 6 + .../WorkflowTemplateDetail/index.test.tsx | 83 ++- .../WorkflowTemplateDetail/index.tsx | 33 +- 8 files changed, 819 insertions(+), 15 deletions(-) create mode 100644 packages/sqle/src/page/WorkflowTemplate/WorkflowTemplateDetail/enum.ts diff --git a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts index dea106eebc..49bd458775 100644 --- a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts +++ b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/data.ts @@ -60,6 +60,67 @@ export const dataExportWorkflowTemplateData: IWorkflowTemplateDetailResV1 = { workflow_type: WorkflowTemplateDetailResV1WorkflowTypeEnum.data_export }; +/** + * Steps returned from API in wrong order (sql_execute first, then sql_review by descending number). + * Used to verify that the frontend correctly extracts steps by type and sorts review steps by number. + * Expected result after processing: + * reviewSteps (sorted by number): [number:1 sql_review, number:2 sql_review] + * execStep: number:3 sql_execute + */ +export const workflowTemplateOutOfOrderData = { + ...workflowTemplateData, + workflow_step_template_list: [ + { + approved_by_authorized: false, + assignee_user_id_list: [], + execute_by_authorized: true, + number: 3, + type: 'sql_execute' + }, + { + approved_by_authorized: false, + assignee_user_id_list: ['1739544663515205632'], + desc: 'step desc', + execute_by_authorized: false, + number: 2, + type: 'sql_review' + }, + { + approved_by_authorized: true, + assignee_user_id_list: [], + execute_by_authorized: false, + number: 1, + type: 'sql_review' + } + ] +}; + +/** + * Export steps returned from API in wrong order (export_execute first). + * Expected result after processing: + * reviewSteps (sorted by number): [number:1 export_review] + * execStep: number:2 export_execute + */ +export const dataExportWorkflowTemplateOutOfOrderData: IWorkflowTemplateDetailResV1 = { + ...dataExportWorkflowTemplateData, + workflow_step_template_list: [ + { + approved_by_authorized: false, + assignee_user_id_list: [], + execute_by_authorized: true, + number: 2, + type: 'export_execute' + }, + { + approved_by_authorized: true, + assignee_user_id_list: [], + execute_by_authorized: false, + number: 1, + type: 'export_review' + } + ] +}; + export const workflowTemplateListData = [ workflowTemplateData, dataExportWorkflowTemplateData diff --git a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts index 819cf80a27..dbc452b7a7 100644 --- a/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts +++ b/packages/shared/lib/testUtil/mockApi/sqle/workflowTemplate/index.ts @@ -1,6 +1,10 @@ import workflow from '../../../../api/sqle/service/workflow'; import { MockSpyApy, createSpySuccessResponse } from '../../common'; -import { workflowTemplateData, workflowTemplateListData } from './data'; +import { + workflowTemplateData, + dataExportWorkflowTemplateData, + workflowTemplateListData +} from './data'; import { cloneDeep } from 'lodash'; class MockWorkflowTemplateApi implements MockSpyApy { @@ -19,7 +23,12 @@ class MockWorkflowTemplateApi implements MockSpyApy { public getWorkflowTemplate() { const spy = jest.spyOn(workflow, 'getWorkflowTemplateV1'); - spy.mockImplementation(() => { + spy.mockImplementation((params) => { + if (params.workflow_type === 'data_export') { + return createSpySuccessResponse({ + data: cloneDeep(dataExportWorkflowTemplateData) + }); + } return createSpySuccessResponse({ data: cloneDeep(workflowTemplateData) }); diff --git a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap index db6f251891..196c75ce8d 100644 --- a/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap +++ b/packages/sqle/src/page/WorkflowTemplate/UpdateWorkflowTemplate/__snapshots__/index.test.tsx.snap @@ -692,6 +692,532 @@ exports[`page/WorkflowTemplate/UpdateWorkflowTemplate change workflow template n `; +exports[`page/WorkflowTemplate/UpdateWorkflowTemplate data_export workflow type should correctly identify export_execute as exec step when API returns steps in wrong order 1`] = ` + +