From 3a6b912785907d3690677b5713eaf3b4af2c733a Mon Sep 17 00:00:00 2001 From: yangpei <2517625275@qq.com> Date: Wed, 20 Jan 2021 20:46:47 +0800 Subject: [PATCH] fix: modify eslint configuration and add pre-commit --- .eslintrc.js | 21 +- package.json | 14 +- packages/cli/src/cmd/dev/index.js | 5 +- packages/cli/src/cmd/dev/mergePkg.js | 9 +- packages/cli/src/utils/server/index.js | 5 +- packages/compile-code/src/addPlugins.ts | 7 +- packages/compile-code/src/compileForOnline.ts | 88 ++--- .../compile-code/src/compileForProject.ts | 12 +- packages/compile-code/src/extractNodeFns.ts | 8 +- packages/compile-code/src/index.ts | 5 +- packages/compile-code/src/simplifyDSL.ts | 13 +- .../compile-code/src/template/runOnline.ts | 9 +- packages/core/package.json | 1 - packages/core/src/api/index.ts | 5 +- packages/core/src/common/shortcuts.ts | 41 ++- .../core/src/components/codeEditor/index.tsx | 12 +- .../components/codeEditor/theme-monokai.ts | 166 ++++----- .../core/src/components/codeRun/index.tsx | 22 +- .../components/codeRun/inputPanel/index.tsx | 45 ++- .../core/src/components/colorPicker/index.tsx | 8 +- .../core/src/components/console/index.tsx | 84 ++--- .../core/src/components/schemaForm/index.tsx | 168 +++++---- packages/core/src/hooks/useClickAway.ts | 6 +- .../mods/flowChart/codeEditorModel/index.tsx | 23 +- .../src/mods/flowChart/codeRunModal/index.tsx | 9 +- .../src/mods/flowChart/contextMenu/index.tsx | 64 ++-- .../contextMenu/menuConfig/blank.tsx | 6 +- .../flowChart/contextMenu/menuConfig/index.ts | 5 +- .../flowChart/contextMenu/menuConfig/node.tsx | 16 +- .../src/mods/flowChart/createFlowChart.ts | 39 ++- packages/core/src/mods/flowChart/index.tsx | 24 +- .../mods/flowChart/registerServerStorage.ts | 20 +- .../mods/header/connectStatus/editModal.tsx | 12 +- .../src/mods/header/export/exportModal.tsx | 29 +- .../core/src/mods/header/export/index.tsx | 11 +- .../core/src/mods/header/guide/guideModal.tsx | 321 +++++++++++------- packages/core/src/mods/header/guide/index.tsx | 12 +- .../core/src/mods/header/importDSL/index.tsx | 11 +- .../settingBar/components/checkbox/index.tsx | 7 +- .../settingBar/components/input/index.tsx | 7 +- .../mods/settingBar/components/json/index.tsx | 163 +++++---- .../mods/settingBar/components/json/json.ts | 194 +++++------ packages/core/src/mods/settingBar/index.tsx | 12 +- .../src/mods/settingBar/mods/basic/index.tsx | 12 +- .../mods/settingBar/mods/testCase/index.tsx | 14 +- packages/core/src/mods/sideBar/index.tsx | 11 +- .../core/src/mods/toolBar/widgets/bgColor.tsx | 14 +- .../src/mods/toolBar/widgets/borderColor.tsx | 18 +- .../widgets/common/makeDropdownWidget.tsx | 6 +- .../src/mods/toolBar/widgets/fontSize.tsx | 4 +- .../mods/toolBar/widgets/horizontalAlign.tsx | 15 +- .../src/mods/toolBar/widgets/lineStyle.tsx | 9 +- .../src/mods/toolBar/widgets/nodeAlign.tsx | 90 +++-- .../src/mods/toolBar/widgets/textColor.tsx | 18 +- .../src/mods/toolBar/widgets/underline.tsx | 4 +- .../mods/toolBar/widgets/verticalAlign.tsx | 9 +- packages/core/src/typings.d.ts | 5 +- packages/core/src/utils/analyzeDeps.ts | 25 +- packages/core/src/utils/flowChartUtils.ts | 20 +- packages/core/src/utils/index.ts | 2 +- .../src/components/add-node.tsx | 19 +- .../src/components/schema-form.tsx | 5 +- .../src/components/schema-head.tsx | 12 +- .../src/components/schema-item.tsx | 22 +- .../json-schema-editor/src/model/schema.ts | 8 +- .../json-schema-editor/src/reducer/schema.ts | 38 ++- .../json-schema-editor/src/utils/schema.ts | 14 +- 67 files changed, 1261 insertions(+), 872 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 595c2eb..f4e5ed0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,22 +1,23 @@ module.exports = { extends: [ - 'standard', - 'plugin:import/typescript', - 'prettier', - 'prettier/react', + "prettier/@typescript-eslint", + "plugin:react/recommended", + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended" ], - plugins: ['prettier', 'react'], env: { node: true, browser: true, }, + settings: { + react: { + version: "detect" + } + }, rules: { 'import/no-extraneous-dependencies': ['error', { peerDependencies: true }], 'prettier/prettier': 'error', - // 修复 tsx 文件引用 tsx 文件报错的问题 - 'react/jsx-filename-extension': ['warn', { extensions: ['.ts', '.tsx'] }], - "semi": [2, "always"],//语句强制分号结尾 - "semi-spacing": [0, { "before": false, "after": true }],//分号前后空格 + 'react/jsx-filename-extension': ['warn', { extensions: ['.ts', '.tsx'] }], // 修复 tsx 文件引用 tsx 文件报错的问题 "no-var": 0,//禁用var,用let和const代替 "no-use-before-define": 2,//未定义前不能使用 "no-unused-expressions": 2,//禁止无用的表达式 @@ -42,4 +43,4 @@ module.exports = { '@typescript-eslint/explicit-function-return-type': 0, }, },], -}; \ No newline at end of file +}; diff --git a/package.json b/package.json index 64fdbcf..ba2edcd 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,9 @@ "example": "concurrently \"lerna run watch --parallel\" \"cross-env APP_ROOT=example umi dev\" \"imove -d\"", "postinstall": "lerna init && lerna bootstrap && npm link packages/cli" }, + "pre-commit": [ + "lint" + ], "jest": { "projects": [ "config/cli.jest.config.js", @@ -24,27 +27,28 @@ "@rollup/plugin-node-resolve": "^7.1.3", "@rollup/plugin-strip": "^1.3.2", "@types/jest": "^26.0.16", - "@typescript-eslint/eslint-plugin": "^2.29.0", + "@typescript-eslint/eslint-plugin": "^4.14.0", "@typescript-eslint/parser": "^2.29.0", "concurrently": "^5.3.0", "cross-env": "^7.0.3", "cypress": "^6.2.0", "dumi": "^1.0.38", "eslint": "^6.8.0", - "eslint-config-standard": "^14.1.1", - "eslint-plugin-prettier": "^3.3.0", - "eslint-plugin-standard": "^5.0.0", + "eslint-config-prettier": "^7.2.0", + "eslint-plugin-prettier": "^3.3.1", + "eslint-plugin-react": "^7.22.0", "lerna": "^3.22.1", "less": "^3.12.2", "lowdb": "^1.0.0", "ora": "^4.1.1", "postcss": "^8.2.1", + "pre-commit": "^1.2.2", + "prettier": "^2.2.1", "rollup": "^2.6.1", "rollup-plugin-postcss": "^4.0.0", "rollup-plugin-size-snapshot": "^0.11.0", "rollup-plugin-typescript": "^1.0.1", "snazzy": "^9.0.0", - "standard": "^16.0.3", "ts-jest": "^26.4.4", "typescript": "^4.1.3", "umi": "^3.3.3", diff --git a/packages/cli/src/cmd/dev/index.js b/packages/cli/src/cmd/dev/index.js index 349b53e..34e932d 100644 --- a/packages/cli/src/cmd/dev/index.js +++ b/packages/cli/src/cmd/dev/index.js @@ -10,11 +10,10 @@ const CACHE_PATH = path.join(process.cwd(), './.cache'); const CACHE_DSL_FILE = path.join(CACHE_PATH, 'imove.dsl.json'); class Dev extends Base { - async writeOutputIntoFiles(curPath, output) { - for(let key in output) { + for (const key in output) { const newPath = path.join(curPath, key); - if(path.extname(newPath)) { + if (path.extname(newPath)) { await fs.writeFile(newPath, output[key]); } else { await fs.ensureDir(newPath); diff --git a/packages/cli/src/cmd/dev/mergePkg.js b/packages/cli/src/cmd/dev/mergePkg.js index 1086bf6..ea13dcb 100644 --- a/packages/cli/src/cmd/dev/mergePkg.js +++ b/packages/cli/src/cmd/dev/mergePkg.js @@ -14,9 +14,14 @@ const extractDep = (dsl) => { const { dependencies } = cell.data || {}; try { const json = JSON.parse(dependencies); - Object.keys(json).forEach((key) => (mergedDependencies[key] = json[key])); + Object.keys(json).forEach( + (key) => (mergedDependencies[key] = json[key]), + ); } catch (error) { - console.log('extract dependencies failed, the error is:', error.message); + console.log( + 'extract dependencies failed, the error is:', + error.message, + ); } }); return mergedDependencies; diff --git a/packages/cli/src/utils/server/index.js b/packages/cli/src/utils/server/index.js index afa4a76..3dec508 100644 --- a/packages/cli/src/utils/server/index.js +++ b/packages/cli/src/utils/server/index.js @@ -7,7 +7,10 @@ const createServer = (port = 3500) => { app.use(bodyParser.urlencoded({ extended: false })); app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); - res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); + res.header( + 'Access-Control-Allow-Headers', + 'Origin, X-Requested-With, Content-Type, Accept', + ); next(); }); app.listen(port, () => { diff --git a/packages/compile-code/src/addPlugins.ts b/packages/compile-code/src/addPlugins.ts index 234ff93..0ffc374 100644 --- a/packages/compile-code/src/addPlugins.ts +++ b/packages/compile-code/src/addPlugins.ts @@ -1,11 +1,12 @@ - const INSERT_IMPORT_PLUGINS_COMMENT = '// import plugins here'; const INSERT_USE_PLUGINS_COMMENT = '// use plugins here'; -const addPlugins = (originalCode: string = '', plugins: string[] = []): string => { +const addPlugins = (originalCode = '', plugins: string[] = []): string => { const modifiedContent: string = originalCode .replace(new RegExp(INSERT_IMPORT_PLUGINS_COMMENT), () => { - return plugins.map((plugin, index) => `import plugin${index} from '${plugin}';`).join('\n'); + return plugins + .map((plugin, index) => `import plugin${index} from '${plugin}';`) + .join('\n'); }) .replace(new RegExp(INSERT_USE_PLUGINS_COMMENT), () => { return plugins.map((_, index) => `logic.use(plugin${index});`).join('\n'); diff --git a/packages/compile-code/src/compileForOnline.ts b/packages/compile-code/src/compileForOnline.ts index ee9d5d9..fed8c5a 100644 --- a/packages/compile-code/src/compileForOnline.ts +++ b/packages/compile-code/src/compileForOnline.ts @@ -1,4 +1,4 @@ -import {Cell} from '@antv/x6'; +import { Cell } from '@antv/x6'; import makeCode from './template/runOnline'; import simplifyDSL from './simplifyDSL'; @@ -8,61 +8,61 @@ interface DSL { /** * Solution - * + * * 1. find the source node form dsl, and if it is not imove-start, * then insert a vitural imove-start at first. - * + * * 2. transform node funciton, follows should be noted: * - import statement should be replaced with import('packge/from/network') * - export statement should be replace with return function * - each node function should be wrapped within a new function to avoid duplicate declaration global variable - * + * * 3. assemble Logic, Context, simplyfied dsl and nodeFns map into one file - * + * */ const INSERT_DSL_COMMENT = '// define dsl here'; const INSERT_NODE_FNS_COMMENT = '// define nodeFns here'; -const importRegex = /import\s+([\s\S]*?)\s+from\s+(?:('[@\.\/\-\w]+')|("[@\.\/\-\w]+"))\s*;?/mg; +const importRegex = /import\s+([\s\S]*?)\s+from\s+(?:('[@\.\/\-\w]+')|("[@\.\/\-\w]+"))\s*;?/gm; const virtualSourceNode = { id: 'virtual-imove-start', shape: 'imove-start', data: { trigger: 'virtual-imove-start', configData: {}, - code: 'export default async function(ctx) {\n \n}' - } + code: 'export default async function(ctx) {\n \n}', + }, }; const findStartNode = (dsl: DSL): Cell.Properties => { + const nodes = dsl.cells.filter((cell) => cell.shape !== 'edge'); + const edges = dsl.cells.filter((cell) => cell.shape === 'edge'); - const nodes = dsl.cells.filter(cell => cell.shape !== 'edge'); - const edges = dsl.cells.filter(cell => cell.shape === 'edge'); - - if(nodes.length === 0) { + if (nodes.length === 0) { throw new Error('Compile failed, no node is selected'); } let foundEdge = null; let startNode = nodes[0]; - while(foundEdge = edges.find(edge => edge.target.cell === startNode.id)) { + while ( + (foundEdge = edges.find((edge) => edge.target.cell === startNode.id)) + ) { const newSourceId = foundEdge.source.cell; - startNode = nodes.find(node => node.id === newSourceId) as Cell.Properties; + startNode = nodes.find( + (node) => node.id === newSourceId, + ) as Cell.Properties; } - if(startNode.shape !== 'imove-start') { - dsl.cells.push( - virtualSourceNode, - { - shape: "edge", - source: { - cell: 'virtual-imove-start', - }, - target: { - cell: startNode.id - } - } - ); + if (startNode.shape !== 'imove-start') { + dsl.cells.push(virtualSourceNode, { + shape: 'edge', + source: { + cell: 'virtual-imove-start', + }, + target: { + cell: startNode.id, + }, + }); startNode = virtualSourceNode; } @@ -70,13 +70,12 @@ const findStartNode = (dsl: DSL): Cell.Properties => { }; const getNextNode = (curNode: Cell.Properties, dsl: DSL) => { + const nodes = dsl.cells.filter((cell) => cell.shape !== 'edge'); + const edges = dsl.cells.filter((cell) => cell.shape === 'edge'); - const nodes = dsl.cells.filter(cell => cell.shape !== 'edge'); - const edges = dsl.cells.filter(cell => cell.shape === 'edge'); - - const foundEdge = edges.find(edge => edge.source.cell === curNode.id); - if(foundEdge) { - return nodes.find(node => node.id === foundEdge.target.cell); + const foundEdge = edges.find((edge) => edge.source.cell === curNode.id); + if (foundEdge) { + return nodes.find((node) => node.id === foundEdge.target.cell); } }; @@ -86,11 +85,18 @@ const compileSimplifiedDSL = (dsl: DSL): string => { }; const compileNodeFn = (node: Cell.Properties): string => { - const {data: {label, code}} = node; - const newCode = code.replace(importRegex, (match: string, p1: string, p2: string, p3: string) => { - const pkgName = (p2 || p3).replace(/('|")/g, ''); - return `const ${p1} = (await import('https://jspm.dev/${pkgName}')).default;`; - }).replace(/export\s+default/, 'return'); + const { + data: { label, code }, + } = node; + const newCode = code + .replace( + importRegex, + (match: string, p1: string, p2: string, p3: string) => { + const pkgName = (p2 || p3).replace(/('|")/g, ''); + return `const ${p1} = (await import('https://jspm.dev/${pkgName}')).default;`; + }, + ) + .replace(/export\s+default/, 'return'); return `await (async function() { ${newCode} @@ -98,9 +104,9 @@ const compileNodeFn = (node: Cell.Properties): string => { }; const compileNodeFnsMap = (dsl: DSL): string => { - const nodes = dsl.cells.filter(cell => cell.shape !== 'edge'); - const kvs = nodes.map(node => { - const {id} = node; + const nodes = dsl.cells.filter((cell) => cell.shape !== 'edge'); + const kvs = nodes.map((node) => { + const { id } = node; return `'${id}': ${compileNodeFn(node)}`; }); diff --git a/packages/compile-code/src/compileForProject.ts b/packages/compile-code/src/compileForProject.ts index 2d48d3a..214a40d 100644 --- a/packages/compile-code/src/compileForProject.ts +++ b/packages/compile-code/src/compileForProject.ts @@ -1,4 +1,4 @@ -import {Cell} from '@antv/x6'; +import { Cell } from '@antv/x6'; import addPlugins from './addPlugins'; import simplifyDSL from './simplifyDSL'; import extractNodeFns from './extractNodeFns'; @@ -11,8 +11,8 @@ interface DSL { } interface IOutput { - 'nodeFns': { - [fileName: string]: string + nodeFns: { + [fileName: string]: string; }; 'context.js': string; 'dsl.json': string; @@ -22,11 +22,11 @@ interface IOutput { const compile = (dsl: DSL, plugins = []): IOutput => { const output: IOutput = { - 'nodeFns': extractNodeFns(dsl), - "context.js": contextTpl, + nodeFns: extractNodeFns(dsl), + 'context.js': contextTpl, 'dsl.json': JSON.stringify(simplifyDSL(dsl), null, 2), 'index.js': addPlugins(indexTpl, plugins), - 'logic.js': logicTpl + 'logic.js': logicTpl, }; return output; }; diff --git a/packages/compile-code/src/extractNodeFns.ts b/packages/compile-code/src/extractNodeFns.ts index 1cbb194..f374af8 100644 --- a/packages/compile-code/src/extractNodeFns.ts +++ b/packages/compile-code/src/extractNodeFns.ts @@ -1,4 +1,4 @@ -import {Cell} from '@antv/x6'; +import { Cell } from '@antv/x6'; interface DSL { cells: Cell.Properties[]; @@ -34,8 +34,8 @@ const genNodeFns = (dsl: DSL): INodesFns => { data: { label, code }, } of nodes) { const fileName: string = id + '.js'; - const descData: string = `// ${shape}: ${label}\n`; - const saveData: string = `${descData}\n${code}`; + const descData = `// ${shape}: ${label}\n`; + const saveData = `${descData}\n${code}`; nodeFns[fileName] = saveData; } return nodeFns; @@ -43,7 +43,7 @@ const genNodeFns = (dsl: DSL): INodesFns => { const extract = (dsl: DSL): INodesFns => { const nodeFns = genNodeFns(dsl); - const nodeIds = Object.keys(nodeFns).map(fileName => fileName.slice(0, -3)); + const nodeIds = Object.keys(nodeFns).map((fileName) => fileName.slice(0, -3)); const entryFileContent = genEntryFile(nodeIds); nodeFns['index.js'] = entryFileContent; return nodeFns; diff --git a/packages/compile-code/src/index.ts b/packages/compile-code/src/index.ts index 70d3ddb..3063822 100644 --- a/packages/compile-code/src/index.ts +++ b/packages/compile-code/src/index.ts @@ -1,7 +1,4 @@ import compileForOnline from './compileForOnline'; import compileForProject from './compileForProject'; -export { - compileForOnline, - compileForProject -}; +export { compileForOnline, compileForProject }; diff --git a/packages/compile-code/src/simplifyDSL.ts b/packages/compile-code/src/simplifyDSL.ts index 197ded9..db2d71d 100644 --- a/packages/compile-code/src/simplifyDSL.ts +++ b/packages/compile-code/src/simplifyDSL.ts @@ -1,10 +1,13 @@ -import {Cell} from '@antv/x6'; +import { Cell } from '@antv/x6'; interface DSL { cells: Cell.Properties[]; } -const extractObj = (obj: Cell.Properties = {}, keys: string[] = []): Cell.Properties => { +const extractObj = ( + obj: Cell.Properties = {}, + keys: string[] = [], +): Cell.Properties => { const ret: Cell.Properties = {}; keys.forEach((key) => { if (obj[key]) { @@ -22,7 +25,11 @@ const simplifyDSL = (dsl: DSL): Cell.Properties => { return extractObj(cell, ['id', 'shape', 'source', 'target']); } else { const newCell = extractObj(cell, ['id', 'shape', 'data']); - newCell.data = extractObj(cell.data, ['trigger', 'configData', 'ports']); + newCell.data = extractObj(cell.data, [ + 'trigger', + 'configData', + 'ports', + ]); return newCell; } }), diff --git a/packages/compile-code/src/template/runOnline.ts b/packages/compile-code/src/template/runOnline.ts index 7ba812f..8ec5968 100644 --- a/packages/compile-code/src/template/runOnline.ts +++ b/packages/compile-code/src/template/runOnline.ts @@ -9,14 +9,15 @@ const makeCode = (mockNode: any, mockInput: any) => ` // Logic ${logic .split('\n') - .filter(line => !line.match(/import nodeFns/) && !line.match(/import Context/)) + .filter( + (line) => !line.match(/import nodeFns/) && !line.match(/import Context/), + ) .join('\n') .replace(/export\s+default/, '') .replace( `import EventEmitter from 'eventemitter3';`, - `const EventEmitter = (await import('https://jspm.dev/eventemitter3')).default;` - ) - } + `const EventEmitter = (await import('https://jspm.dev/eventemitter3')).default;`, + )} // DSL // define dsl here diff --git a/packages/core/package.json b/packages/core/package.json index 3640f1c..b99747d 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -42,7 +42,6 @@ "@monaco-editor/react": "^3.7.4", "antd": "^4.5.3", "axios": "^0.21.0", - "form-render": "^0.9.5", "fr-generator": "^1.0.0", "jszip": "^3.5.0", "lodash.merge": "^4.6.2", diff --git a/packages/core/src/api/index.ts b/packages/core/src/api/index.ts index 2e21445..be9dd98 100644 --- a/packages/core/src/api/index.ts +++ b/packages/core/src/api/index.ts @@ -86,7 +86,10 @@ export const queryGraph = (projectId: string) => { }); }; -export const modifyGraph = (projectId: string, actions: IModifyGraphAction[]) => { +export const modifyGraph = ( + projectId: string, + actions: IModifyGraphAction[], +) => { return request({ url: '/api/modifyGraph', params: { diff --git a/packages/core/src/common/shortcuts.ts b/packages/core/src/common/shortcuts.ts index ea250c0..77a0994 100644 --- a/packages/core/src/common/shortcuts.ts +++ b/packages/core/src/common/shortcuts.ts @@ -77,10 +77,18 @@ const shortcuts: { [key: string]: Shortcut } = { const onEdgeDel = (edge: Edge) => { const srcNode = edge.getSourceNode() as Node; const isSrcNodeInDelCells = !!toDelCells.find((c) => c === srcNode); - if (srcNode && srcNode.shape === 'imove-branch' && !isSrcNodeInDelCells) { + if ( + srcNode && + srcNode.shape === 'imove-branch' && + !isSrcNodeInDelCells + ) { const portId = edge.getSourcePortId(); if (portId === 'right' || portId === 'bottom') { - const edgeLabel = safeGet(edge.getLabelAt(0), 'attrs.label.text', ''); + const edgeLabel = safeGet( + edge.getLabelAt(0), + 'attrs.label.text', + '', + ); srcNode.setPortProp(portId, 'attrs/text/text', edgeLabel); } } @@ -109,9 +117,12 @@ const shortcuts: { [key: string]: Shortcut } = { handler(flowChart: Graph) { const cells = flowChart.getSelectedCells(); if (cells.length > 0) { - const isAlreadyBold = safeGet(cells, '0.attrs.label.fontWeight', 'normal') === 'bold'; + const isAlreadyBold = + safeGet(cells, '0.attrs.label.fontWeight', 'normal') === 'bold'; cells.forEach((cell) => { - cell.setAttrs({ label: { fontWeight: isAlreadyBold ? 'normal' : 'bold' } }); + cell.setAttrs({ + label: { fontWeight: isAlreadyBold ? 'normal' : 'bold' }, + }); }); flowChart.trigger('toolBar:forceUpdate'); } @@ -123,9 +134,12 @@ const shortcuts: { [key: string]: Shortcut } = { handler(flowChart: Graph) { const cells = flowChart.getSelectedCells(); if (cells.length > 0) { - const isAlreadyItalic = safeGet(cells, '0.attrs.label.fontStyle', 'normal') === 'italic'; + const isAlreadyItalic = + safeGet(cells, '0.attrs.label.fontStyle', 'normal') === 'italic'; cells.forEach((cell) => { - cell.setAttrs({ label: { fontStyle: isAlreadyItalic ? 'normal' : 'italic' } }); + cell.setAttrs({ + label: { fontStyle: isAlreadyItalic ? 'normal' : 'italic' }, + }); }); flowChart.trigger('toolBar:forceUpdate'); } @@ -138,9 +152,14 @@ const shortcuts: { [key: string]: Shortcut } = { const cells = flowChart.getSelectedCells(); if (cells.length > 0) { const isAlreadyUnderline = - safeGet(cells, '0.attrs.label.textDecoration', 'none') === 'underline'; + safeGet(cells, '0.attrs.label.textDecoration', 'none') === + 'underline'; cells.forEach((cell) => { - cell.setAttrs({ label: { textDecoration: isAlreadyUnderline ? 'none' : 'underline' } }); + cell.setAttrs({ + label: { + textDecoration: isAlreadyUnderline ? 'none' : 'underline', + }, + }); }); flowChart.trigger('toolBar:forceUpdate'); } @@ -151,14 +170,14 @@ const shortcuts: { [key: string]: Shortcut } = { keys: 'meta + ]', handler(flowChart: Graph) { getSelectedNodes(flowChart).forEach((node) => node.toFront()); - } + }, }, bringToBack: { keys: 'meta + [', handler(flowChart: Graph) { getSelectedNodes(flowChart).forEach((node) => node.toBack()); - } - } + }, + }, }; export default shortcuts; diff --git a/packages/core/src/components/codeEditor/index.tsx b/packages/core/src/components/codeEditor/index.tsx index f0c56f4..5528422 100644 --- a/packages/core/src/components/codeEditor/index.tsx +++ b/packages/core/src/components/codeEditor/index.tsx @@ -1,14 +1,10 @@ -import React, { - useMemo, - useState, - useEffect -} from 'react'; +import React, { useMemo, useState, useEffect } from 'react'; import { monaco, EditorDidMount, ControlledEditor, - ControlledEditorProps + ControlledEditorProps, } from '@monaco-editor/react'; import monokaiTheme from './theme-monokai'; @@ -22,7 +18,7 @@ monaco.init().then((monaco) => { }); const CODE_EDITOR_OPTIONS = { - fontSize: 14 + fontSize: 14, }; interface IProps extends ControlledEditorProps { @@ -30,7 +26,7 @@ interface IProps extends ControlledEditorProps { } export const CodeEditor: React.FC = (props) => { - const {options, editorDidMount, onSave, ...rest} = props; + const { options, editorDidMount, onSave, ...rest } = props; const [editorInst, setEditorInst] = useState(); const editorOptions = useMemo(() => { diff --git a/packages/core/src/components/codeEditor/theme-monokai.ts b/packages/core/src/components/codeEditor/theme-monokai.ts index 0747db9..4d2e0d0 100644 --- a/packages/core/src/components/codeEditor/theme-monokai.ts +++ b/packages/core/src/components/codeEditor/theme-monokai.ts @@ -1,144 +1,144 @@ export default { - "base": "vs-dark", - "inherit": true, - "rules": [ + base: 'vs-dark', + inherit: true, + rules: [ { - "background": "272822", - "token": "" + background: '272822', + token: '', }, { - "foreground": "75715e", - "token": "comment" + foreground: '75715e', + token: 'comment', }, { - "foreground": "e6db74", - "token": "string" + foreground: 'e6db74', + token: 'string', }, { - "foreground": "ae81ff", - "token": "constant.numeric" + foreground: 'ae81ff', + token: 'constant.numeric', }, { - "foreground": "ae81ff", - "token": "constant.language" + foreground: 'ae81ff', + token: 'constant.language', }, { - "foreground": "ae81ff", - "token": "constant.character" + foreground: 'ae81ff', + token: 'constant.character', }, { - "foreground": "ae81ff", - "token": "constant.other" + foreground: 'ae81ff', + token: 'constant.other', }, { - "foreground": "f92672", - "token": "keyword" + foreground: 'f92672', + token: 'keyword', }, { - "foreground": "f92672", - "token": "storage" + foreground: 'f92672', + token: 'storage', }, { - "foreground": "66d9ef", - "fontStyle": "italic", - "token": "storage.type" + foreground: '66d9ef', + fontStyle: 'italic', + token: 'storage.type', }, { - "foreground": "a6e22e", - "fontStyle": "underline", - "token": "entity.name.class" + foreground: 'a6e22e', + fontStyle: 'underline', + token: 'entity.name.class', }, { - "foreground": "a6e22e", - "fontStyle": "italic underline", - "token": "entity.other.inherited-class" + foreground: 'a6e22e', + fontStyle: 'italic underline', + token: 'entity.other.inherited-class', }, { - "foreground": "a6e22e", - "token": "entity.name.function" + foreground: 'a6e22e', + token: 'entity.name.function', }, { - "foreground": "fd971f", - "fontStyle": "italic", - "token": "variable.parameter" + foreground: 'fd971f', + fontStyle: 'italic', + token: 'variable.parameter', }, { - "foreground": "f92672", - "token": "entity.name.tag" + foreground: 'f92672', + token: 'entity.name.tag', }, { - "foreground": "a6e22e", - "token": "entity.other.attribute-name" + foreground: 'a6e22e', + token: 'entity.other.attribute-name', }, { - "foreground": "66d9ef", - "token": "support.function" + foreground: '66d9ef', + token: 'support.function', }, { - "foreground": "66d9ef", - "token": "support.constant" + foreground: '66d9ef', + token: 'support.constant', }, { - "foreground": "66d9ef", - "fontStyle": "italic", - "token": "support.type" + foreground: '66d9ef', + fontStyle: 'italic', + token: 'support.type', }, { - "foreground": "66d9ef", - "fontStyle": "italic", - "token": "support.class" + foreground: '66d9ef', + fontStyle: 'italic', + token: 'support.class', }, { - "foreground": "f8f8f0", - "background": "f92672", - "token": "invalid" + foreground: 'f8f8f0', + background: 'f92672', + token: 'invalid', }, { - "foreground": "f8f8f0", - "background": "ae81ff", - "token": "invalid.deprecated" + foreground: 'f8f8f0', + background: 'ae81ff', + token: 'invalid.deprecated', }, { - "foreground": "cfcfc2", - "token": "meta.structure.dictionary.json string.quoted.double.json" + foreground: 'cfcfc2', + token: 'meta.structure.dictionary.json string.quoted.double.json', }, { - "foreground": "75715e", - "token": "meta.diff" + foreground: '75715e', + token: 'meta.diff', }, { - "foreground": "75715e", - "token": "meta.diff.header" + foreground: '75715e', + token: 'meta.diff.header', }, { - "foreground": "f92672", - "token": "markup.deleted" + foreground: 'f92672', + token: 'markup.deleted', }, { - "foreground": "a6e22e", - "token": "markup.inserted" + foreground: 'a6e22e', + token: 'markup.inserted', }, { - "foreground": "e6db74", - "token": "markup.changed" + foreground: 'e6db74', + token: 'markup.changed', }, { - "foreground": "ae81ffa0", - "token": "constant.numeric.line-number.find-in-files - match" + foreground: 'ae81ffa0', + token: 'constant.numeric.line-number.find-in-files - match', }, { - "foreground": "e6db74", - "token": "entity.name.filename.find-in-files" - } + foreground: 'e6db74', + token: 'entity.name.filename.find-in-files', + }, ], - "colors": { - "editor.foreground": "#F8F8F2", - "editor.background": "#272822", - "editor.selectionBackground": "#49483E", - "editor.lineHighlightBackground": "#3E3D32", - "editorCursor.foreground": "#F8F8F0", - "editorWhitespace.foreground": "#3B3A32", - "editorIndentGuide.activeBackground": "#9D550FB0", - "editor.selectionHighlightBorder": "#222218" - } -} + colors: { + 'editor.foreground': '#F8F8F2', + 'editor.background': '#272822', + 'editor.selectionBackground': '#49483E', + 'editor.lineHighlightBackground': '#3E3D32', + 'editorCursor.foreground': '#F8F8F0', + 'editorWhitespace.foreground': '#3B3A32', + 'editorIndentGuide.activeBackground': '#9D550FB0', + 'editor.selectionHighlightBorder': '#222218', + }, +}; diff --git a/packages/core/src/components/codeRun/index.tsx b/packages/core/src/components/codeRun/index.tsx index a03d9d8..715d246 100644 --- a/packages/core/src/components/codeRun/index.tsx +++ b/packages/core/src/components/codeRun/index.tsx @@ -1,8 +1,4 @@ -import React, { - useState, - useEffect, - useCallback, -} from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; import styles from './index.module.less'; @@ -26,7 +22,7 @@ const defaultInput = { pipe: {}, context: {}, payload: {}, - config: {} + config: {}, }; interface ICardProps { @@ -39,9 +35,7 @@ const Card: React.FC = (props) => { return (
{title}
-
- {props.children} -
+
{props.children}
); }; @@ -51,8 +45,7 @@ interface ICodeRunProps { } const CodeRun: React.FC = (props) => { - - const {flowChart} = props; + const { flowChart } = props; const [isRunning, setIsRunning] = useState(false); const [input, setInput] = useState(defaultInput); const [output, setOutput] = useState({}); @@ -98,10 +91,7 @@ const CodeRun: React.FC = (props) => { )} - + @@ -124,6 +114,6 @@ const CodeRun: React.FC = (props) => { ); -} +}; export default CodeRun; diff --git a/packages/core/src/components/codeRun/inputPanel/index.tsx b/packages/core/src/components/codeRun/inputPanel/index.tsx index 3aa47cd..38269d7 100644 --- a/packages/core/src/components/codeRun/inputPanel/index.tsx +++ b/packages/core/src/components/codeRun/inputPanel/index.tsx @@ -1,7 +1,4 @@ -import React, { - useRef, - useEffect, -} from 'react'; +import React, { useRef, useEffect } from 'react'; import styles from './index.module.less'; @@ -33,7 +30,7 @@ const VisualFormItem: React.FC = (props) => { {(fields, { add, remove }) => ( - {fields.map(field => ( + {fields.map((field) => ( = (props) => { interface IVisualPanelProps { data: any; - onChange: (value: object) => void + onChange: (value: object) => void; } const VisualPanel: React.FC = (props) => { @@ -84,7 +81,10 @@ const VisualPanel: React.FC = (props) => { const filedsValue: { [key: string]: any } = {}; for (const { type } of inputItems) { const mockValue = data[type] || {}; - filedsValue[type] = Object.keys(mockValue).map(key => ({ key, value: mockValue[key] })); + filedsValue[type] = Object.keys(mockValue).map((key) => ({ + key, + value: mockValue[key], + })); } form.setFieldsValue(filedsValue); }, [data]); @@ -94,28 +94,23 @@ const VisualPanel: React.FC = (props) => { const filedsValue = form.getFieldsValue(); for (const { type } of inputItems) { const mockValue = filedsValue[type] || []; - input[type] = mockValue.reduce((prev: any, cur: { key: string, value: any }) => { - const { key, value } = cur; - prev[key] = value; - return prev; - }, {}); + input[type] = mockValue.reduce( + (prev: any, cur: { key: string; value: any }) => { + const { key, value } = cur; + prev[key] = value; + return prev; + }, + {}, + ); } onChange(input); }; return (
-
+ {inputItems.map(({ type, desc }, index) => ( - + ))}
@@ -148,7 +143,11 @@ const InputPanel: React.FC = (props) => { return ( - + diff --git a/packages/core/src/components/colorPicker/index.tsx b/packages/core/src/components/colorPicker/index.tsx index f652a36..b4bb7fc 100644 --- a/packages/core/src/components/colorPicker/index.tsx +++ b/packages/core/src/components/colorPicker/index.tsx @@ -18,7 +18,13 @@ const ColorPicker: React.FC = (props) => { const onChange = (color: ColorResult): void => setCurColor(color.hex); const onChangeComplete = (color: ColorResult): void => changeCb(color.hex); - return ; + return ( + + ); }; export default ColorPicker; diff --git a/packages/core/src/components/console/index.tsx b/packages/core/src/components/console/index.tsx index ce470b9..7213583 100644 --- a/packages/core/src/components/console/index.tsx +++ b/packages/core/src/components/console/index.tsx @@ -3,7 +3,7 @@ import React, { useState, useEffect, useCallback, - ChangeEvent + ChangeEvent, } from 'react'; import styles from './index.module.less'; @@ -14,7 +14,7 @@ import { BugOutlined, CloseCircleOutlined, ClearOutlined, - FilterOutlined + FilterOutlined, } from '@ant-design/icons'; import JsonView from 'react-json-view'; import { Button, Input, Select, Tabs } from 'antd'; @@ -38,15 +38,17 @@ const Helper = { return typeof value === 'object' && value !== null; }, getArgsToString(args: any[]): string { - return args.map(o => { - if (Helper.isPlainObject(o)) { - return JSON.stringify(o); - } else { - return o; - } - }).join(' '); - } -} + return args + .map((o) => { + if (Helper.isPlainObject(o)) { + return JSON.stringify(o); + } else { + return o; + } + }) + .join(' '); + }, +}; const hijackMap: { [key: string]: any } = { log: { @@ -54,62 +56,63 @@ const hijackMap: { [key: string]: any } = { textColor: '#ffffff', borderColor: 'rgba(128, 128, 128, 0.35)', icon:
, - originMethod: console.log + originMethod: console.log, }, info: { bgColor: '#272823', textColor: '#ffffff', borderColor: 'rgba(128, 128, 128, 0.35)', icon: , - originMethod: console.info + originMethod: console.info, }, warn: { bgColor: 'rgb(51, 42, 0)', textColor: 'rgb(245, 211, 150)', borderColor: 'rgb(102, 85, 0)', icon: , - originMethod: console.warn + originMethod: console.warn, }, debug: { bgColor: '#272823', textColor: 'rgb(77, 136, 255)', borderColor: 'rgba(128, 128, 128, 0.35)', icon: , - originMethod: console.debug + originMethod: console.debug, }, error: { bgColor: 'rgb(40, 0, 0)', textColor: 'rgb(254, 127, 127)', borderColor: 'rgb(91, 0, 0)', icon: , - originMethod: console.error - } -} + originMethod: console.error, + }, +}; const LogLine: React.FC = (props) => { - const { type, data } = props; const renderLink = (data: string) => { - return {data} + return ( + + {data} + + ); }; const renderText = (data: any) => { - if(typeof data !== 'string') { + if (typeof data !== 'string') { return data; } else { const arr = data.split(linkRegex); return arr.map((str, index) => { return ( - - {Helper.isLink(str) ? renderLink(str) : str} - + {Helper.isLink(str) ? renderLink(str) : str} ); - }) + }); } }; - const renderJson = (data: Object) => { + const renderJson = (data: Record) => { return ( = (props) => { ); }; - const { - icon, - textColor, - bgColor, - borderColor - } = hijackMap[type]; + const { icon, textColor, bgColor, borderColor } = hijackMap[type]; const logLineStyle = { color: textColor, backgroundColor: bgColor, borderTopColor: borderColor, - borderBottomColor: borderColor + borderBottomColor: borderColor, }; return ( @@ -176,36 +174,36 @@ const MyConsole: React.FC = () => { useEffect(() => { const filteredLogs = cache.current.allLogs - .filter(log => { + .filter((log) => { if (level === 'all') { return true; } else { return log.type === level; } }) - .filter(log => { + .filter((log) => { return log.strVal.indexOf(filter) > -1; }); setLogList(filteredLogs); }, [filter, level]); const hijackConsole = () => { - Object.keys(hijackMap).forEach(method => { + Object.keys(hijackMap).forEach((method) => { // @ts-ignore window.console[method] = (...args: any[]) => { hijackMap[method].originMethod(...args); cache.current.allLogs = cache.current.allLogs.concat({ type: method, data: args, - strVal: Helper.getArgsToString(args) + strVal: Helper.getArgsToString(args), }); setLogList(cache.current.allLogs); }; }); - } + }; const resetConsole = () => { - Object.keys(hijackMap).forEach(method => { + Object.keys(hijackMap).forEach((method) => { // @ts-ignore window.console[method] = hijackMap[method].originMethod; }); @@ -233,8 +231,12 @@ const MyConsole: React.FC = () => { prefix={} onChange={onChangeFilter} /> - + {['all', 'info', 'warn', 'error', 'debug'].map((method) => ( {method} diff --git a/packages/core/src/components/schemaForm/index.tsx b/packages/core/src/components/schemaForm/index.tsx index 3e35240..8e693e4 100644 --- a/packages/core/src/components/schemaForm/index.tsx +++ b/packages/core/src/components/schemaForm/index.tsx @@ -1,109 +1,153 @@ import React from 'react'; -import { Form, Input, Switch, Select, Checkbox, DatePicker, TimePicker, Empty, Button, message } from 'antd'; +import { + Form, + Input, + Switch, + Select, + Checkbox, + DatePicker, + TimePicker, + Empty, + Button, + message, +} from 'antd'; import moment from 'moment'; -import styles from './index.module.less' -const FormItem = Form.Item +import styles from './index.module.less'; +const FormItem = Form.Item; const { RangePicker } = DatePicker; const { Option } = Select; interface INum { - label: string, - value: string + label: string; + value: string; } interface IConfigData { - [key: string]: any + [key: string]: any; } interface IProps { schema: { - type: string, - properties: { [key: string]: any } - }, - configData: IConfigData, - changeConfigData: (data: IConfigData) => void + type: string; + properties: { [key: string]: any }; + }; + configData: IConfigData; + changeConfigData: (data: IConfigData) => void; } const formLayout = { labelCol: { span: 8 }, - wrapperCol: { span: 16 } + wrapperCol: { span: 16 }, }; const SchemaForm: React.FC = (props) => { - const { schema, configData, changeConfigData } = props - const [form] = Form.useForm() + const { schema, configData, changeConfigData } = props; + const [form] = Form.useForm(); const onClickSave = (): void => { - changeConfigData(form.getFieldsValue()) - message.success('保存成功!') - } + changeConfigData(form.getFieldsValue()); + message.success('保存成功!'); + }; - return ( - schema && Object.keys(schema).length > 0 ? -
- {schema?.properties && Object.keys(schema.properties).map((key: string) => { - const obj = schema.properties[key] - const options: INum[] = obj.enum ? obj.enum.map((item: string, idx: number) => { - return { label: item, value: obj.enumNames[idx] } - }) : [] - let ele = null + return schema && Object.keys(schema).length > 0 ? ( + + {schema?.properties && + Object.keys(schema.properties).map((key: string) => { + const obj = schema.properties[key]; + const options: INum[] = obj.enum + ? obj.enum.map((item: string, idx: number) => { + return { label: item, value: obj.enumNames[idx] }; + }) + : []; + let ele = null; // 输入框 - if (obj.type === 'string' && !obj.hasOwnProperty('format') && !obj.hasOwnProperty('enum')) { - ele = + if ( + obj.type === 'string' && + !obj.hasOwnProperty('format') && + !obj.hasOwnProperty('enum') + ) { + ele = ; } // 编辑框 if (obj.type === 'string' && obj.format === 'textarea') { - ele = + ele = ; } // switch if (obj.type === 'boolean' && obj['ui:widget'] === 'switch') { - ele = + ele = ; } // 下拉单选 - if (obj.type === 'string' && obj.hasOwnProperty('enum') && !obj.hasOwnProperty('ui:widget')) { - ele = + if ( + obj.type === 'string' && + obj.hasOwnProperty('enum') && + !obj.hasOwnProperty('ui:widget') + ) { + ele = ( + + ); } // 下拉多选 - if (obj.type === 'array' && obj.hasOwnProperty('enum') && obj['ui:widget'] === 'multiSelect') { - ele = + if ( + obj.type === 'array' && + obj.hasOwnProperty('enum') && + obj['ui:widget'] === 'multiSelect' + ) { + ele = ( + + ); } // 点击多选 - if (obj.type === 'array' && obj.hasOwnProperty('enum') && !obj.hasOwnProperty('ui:widget')) { - ele = + if ( + obj.type === 'array' && + obj.hasOwnProperty('enum') && + !obj.hasOwnProperty('ui:widget') + ) { + ele = ; } // 时间选择 if (obj.type === 'string' && obj.format === 'time') { - ele = + ele = ; } // 日期范围 if (obj.type === 'range' && obj.format === 'date') { - ele = + ele = ; } // 日期选择 if (obj.type === 'string' && obj.format === 'date') { - ele = + ele = ; } - return - {ele} - + return ( + + {ele} + + ); })} -
- -
- : - +
+ +
+ + ) : ( + ); }; -export default SchemaForm +export default SchemaForm; diff --git a/packages/core/src/hooks/useClickAway.ts b/packages/core/src/hooks/useClickAway.ts index d1a3366..2768597 100644 --- a/packages/core/src/hooks/useClickAway.ts +++ b/packages/core/src/hooks/useClickAway.ts @@ -1,8 +1,4 @@ -import { - useRef, - useEffect, - MutableRefObject -} from 'react'; +import { useRef, useEffect, MutableRefObject } from 'react'; type EventType = MouseEvent | TouchEvent; type TargetElement = HTMLElement | Element | Document | Window; diff --git a/packages/core/src/mods/flowChart/codeEditorModel/index.tsx b/packages/core/src/mods/flowChart/codeEditorModel/index.tsx index b82fb55..8dec646 100644 --- a/packages/core/src/mods/flowChart/codeEditorModel/index.tsx +++ b/packages/core/src/mods/flowChart/codeEditorModel/index.tsx @@ -1,7 +1,4 @@ -import React, { - useState, - useEffect -} from 'react'; +import React, { useState, useEffect } from 'react'; import 'antd/es/modal/style'; import styles from './index.module.less'; @@ -19,16 +16,14 @@ interface IProps { } const CodeEditModal: React.FC = (props) => { - const { title = '编辑代码', flowChart } = props; const [code, setCode] = useState(''); const [visible, setVisible] = useState(false); const updateNodeCode = (code: string): void => { - const cell = flowChart.getSelectedCells()[0]; const { code: oldCode, dependencies } = cell.getData(); - if(code === oldCode) { + if (code === oldCode) { return; } @@ -55,7 +50,7 @@ const CodeEditModal: React.FC = (props) => { const newDeps = { ...excludeDeps, ...deps }; cell.setData({ code, - dependencies: JSON.stringify(newDeps, null, 2) + dependencies: JSON.stringify(newDeps, null, 2), }); // NOTE: notify basic panel to update dependency flowChart.trigger('settingBar.basicPanel:forceUpdate'); @@ -110,9 +105,15 @@ const CodeEditModal: React.FC = (props) => { visible={visible} onCancel={onCancel} footer={[ - , - , - , + , + , + , ]} > = (props): JSX.Element => { - const { title = '执行代码', flowChart } = props; const [visible, setVisible] = useState(false); @@ -42,7 +37,7 @@ const CodeRunModal: React.FC = (props): JSX.Element => { footer={null} onCancel={onClose} > - + ); }; diff --git a/packages/core/src/mods/flowChart/contextMenu/index.tsx b/packages/core/src/mods/flowChart/contextMenu/index.tsx index dc22fb3..7400b65 100644 --- a/packages/core/src/mods/flowChart/contextMenu/index.tsx +++ b/packages/core/src/mods/flowChart/contextMenu/index.tsx @@ -1,7 +1,4 @@ -import React, { - useRef, - useCallback -} from 'react'; +import React, { useRef, useCallback } from 'react'; import styles from '../index.module.less'; @@ -30,25 +27,31 @@ interface IMenuConfig { const menuConfigMap: { [scene: string]: IMenuConfig[] } = { node: nodeMenuConfig, - blank: blankMenuConfig + blank: blankMenuConfig, }; -const FlowChartContextMenu: React.FC = props => { +const FlowChartContextMenu: React.FC = (props) => { const menuRef = useRef(null); const { x, y, scene, visible, flowChart } = props; const menuConfig = menuConfigMap[scene]; useClickAway(() => onClickAway(), menuRef); - const onClickAway = useCallback(() => flowChart.trigger('graph:hideContextMenu'), [flowChart]); - const onClickMenu = useCallback(({ key }) => { - const handlerMap = Helper.makeMenuHandlerMap(menuConfig); - const handler = handlerMap[key]; - if (handler) { - onClickAway(); - handler(flowChart); - } - }, [flowChart, menuConfig]); + const onClickAway = useCallback( + () => flowChart.trigger('graph:hideContextMenu'), + [flowChart], + ); + const onClickMenu = useCallback( + ({ key }) => { + const handlerMap = Helper.makeMenuHandlerMap(menuConfig); + const handler = handlerMap[key]; + if (handler) { + onClickAway(); + handler(flowChart); + } + }, + [flowChart, menuConfig], + ); return !visible ? null : (
= props => { className={styles.contextMenu} style={{ left: x, top: y }} > - + {Helper.makeMenuContent(flowChart, menuConfig)}
@@ -83,15 +82,27 @@ const Helper = { }, makeMenuContent(flowChart: Graph, menuConfig: IMenuConfig[]) { const loop = (config: IMenuConfig[]) => { - return config.map(item => { + return config.map((item) => { let content = null; - let { key, title, icon, children, disabled = false, showDividerBehind } = item; + let { + key, + title, + icon, + children, + disabled = false, + showDividerBehind, + } = item; if (typeof disabled === 'function') { disabled = disabled(flowChart); } if (children && children.length > 0) { content = ( - + {loop(children)} ); @@ -102,14 +113,11 @@ const Helper = { ); } - return [ - content, - showDividerBehind && - ]; + return [content, showDividerBehind && ]; }); }; return loop(menuConfig); - } + }, }; export default FlowChartContextMenu; diff --git a/packages/core/src/mods/flowChart/contextMenu/menuConfig/blank.tsx b/packages/core/src/mods/flowChart/contextMenu/menuConfig/blank.tsx index 3a3eea8..3e9f080 100644 --- a/packages/core/src/mods/flowChart/contextMenu/menuConfig/blank.tsx +++ b/packages/core/src/mods/flowChart/contextMenu/menuConfig/blank.tsx @@ -10,15 +10,15 @@ const blankMenuConfig = [ key: 'selectAll', title: '全选', icon: , - handler: shortcuts.selectAll.handler + handler: shortcuts.selectAll.handler, }, { key: 'paste', title: '粘贴', icon: , disabled: (flowChart: Graph) => flowChart.isClipboardEmpty(), - handler: shortcuts.paste.handler - } + handler: shortcuts.paste.handler, + }, ]; export default blankMenuConfig; diff --git a/packages/core/src/mods/flowChart/contextMenu/menuConfig/index.ts b/packages/core/src/mods/flowChart/contextMenu/menuConfig/index.ts index e32bd3d..9d21d05 100644 --- a/packages/core/src/mods/flowChart/contextMenu/menuConfig/index.ts +++ b/packages/core/src/mods/flowChart/contextMenu/menuConfig/index.ts @@ -1,7 +1,4 @@ import nodeMenuConfig from './node'; import blankMenuConfig from './blank'; -export { - nodeMenuConfig, - blankMenuConfig -}; +export { nodeMenuConfig, blankMenuConfig }; diff --git a/packages/core/src/mods/flowChart/contextMenu/menuConfig/node.tsx b/packages/core/src/mods/flowChart/contextMenu/menuConfig/node.tsx index 75f39a5..bd2767e 100644 --- a/packages/core/src/mods/flowChart/contextMenu/menuConfig/node.tsx +++ b/packages/core/src/mods/flowChart/contextMenu/menuConfig/node.tsx @@ -18,13 +18,13 @@ const nodeMenuConfig = [ key: 'copy', title: '复制', icon: , - handler: shortcuts.copy.handler + handler: shortcuts.copy.handler, }, { key: 'delete', title: '删除', icon: , - handler: shortcuts.delete.handler + handler: shortcuts.delete.handler, }, { key: 'rename', @@ -33,20 +33,20 @@ const nodeMenuConfig = [ showDividerBehind: true, handler() { // TODO - } + }, }, { key: 'bringToTop', title: '置于顶层', icon: , - handler: shortcuts.bringToTop.handler + handler: shortcuts.bringToTop.handler, }, { key: 'bringToBack', title: '置于底层', icon: , showDividerBehind: true, - handler: shortcuts.bringToBack.handler + handler: shortcuts.bringToBack.handler, }, { key: 'editCode', @@ -57,7 +57,7 @@ const nodeMenuConfig = [ }, handler(flowChart: Graph) { flowChart.trigger('graph:editCode'); - } + }, }, { key: 'executeCode', @@ -68,8 +68,8 @@ const nodeMenuConfig = [ }, handler(flowChart: Graph) { flowChart.trigger('graph:runCode'); - } - } + }, + }, ]; export default nodeMenuConfig; diff --git a/packages/core/src/mods/flowChart/createFlowChart.ts b/packages/core/src/mods/flowChart/createFlowChart.ts index 1f8cd62..396a3bd 100644 --- a/packages/core/src/mods/flowChart/createFlowChart.ts +++ b/packages/core/src/mods/flowChart/createFlowChart.ts @@ -12,7 +12,7 @@ import MiniMapSimpleNode from '../../components/miniMapSimpleNode'; Object.values(schemas).forEach((schema) => { const { base, ...rest } = schema; base.define(rest); - }) + }), ); const registerEvents = (flowChart: Graph): void => { @@ -59,18 +59,31 @@ const registerEvents = (flowChart: Graph): void => { flowChart.trigger('graph:editCode'); }); flowChart.on('blank:contextmenu', (args) => { - const { e: { clientX, clientY } } = args; + const { + e: { clientX, clientY }, + } = args; flowChart.cleanSelection(); - flowChart.trigger('graph:showContextMenu', { x: clientX, y: clientY, scene: 'blank' }); + flowChart.trigger('graph:showContextMenu', { + x: clientX, + y: clientY, + scene: 'blank', + }); }); flowChart.on('node:contextmenu', (args) => { - const { e: { clientX, clientY }, node } = args; + const { + e: { clientX, clientY }, + node, + } = args; // NOTE: if the clicked node is not in the selected nodes, then clear selection - if(!flowChart.getSelectedCells().includes(node)) { + if (!flowChart.getSelectedCells().includes(node)) { flowChart.cleanSelection(); flowChart.select(node); } - flowChart.trigger('graph:showContextMenu', { x: clientX, y: clientY, scene: 'node' }); + flowChart.trigger('graph:showContextMenu', { + x: clientX, + y: clientY, + scene: 'node', + }); }); }; @@ -81,7 +94,10 @@ const registerShortcuts = (flowChart: Graph): void => { }); }; -const createFlowChart = (container: HTMLDivElement, miniMapContainer: HTMLDivElement): Graph => { +const createFlowChart = ( + container: HTMLDivElement, + miniMapContainer: HTMLDivElement, +): Graph => { const flowChart = new Graph({ container, rotating: false, @@ -101,7 +117,12 @@ const createFlowChart = (container: HTMLDivElement, miniMapContainer: HTMLDivEle router: { name: 'manhattan', }, - validateConnection({ sourceView, targetView, sourceMagnet, targetMagnet }) { + validateConnection({ + sourceView, + targetView, + sourceMagnet, + targetMagnet, + }) { if (!sourceMagnet) { return false; } else if (!targetMagnet) { @@ -126,7 +147,7 @@ const createFlowChart = (container: HTMLDivElement, miniMapContainer: HTMLDivEle rubberband: true, movable: true, strict: true, - showNodeSelectionBox: true + showNodeSelectionBox: true, }, // https://x6.antv.vision/zh/docs/tutorial/basic/snapline snapline: { diff --git a/packages/core/src/mods/flowChart/index.tsx b/packages/core/src/mods/flowChart/index.tsx index f534bfe..6d06b3c 100644 --- a/packages/core/src/mods/flowChart/index.tsx +++ b/packages/core/src/mods/flowChart/index.tsx @@ -1,8 +1,4 @@ -import React, { - useRef, - useState, - useEffect -} from 'react'; +import React, { useRef, useState, useEffect } from 'react'; import styles from './index.module.less'; @@ -29,7 +25,7 @@ const defaultMenuInfo = { x: 0, y: 0, scene: 'blank', - visible: false + visible: false, }; const FlowChart: React.FC = (props) => { @@ -38,7 +34,9 @@ const FlowChart: React.FC = (props) => { const graphRef = useRef(null); const miniMapRef = useRef(null); const [flowChart, setFlowChart] = useState(); - const [contextMenuInfo, setContextMenuInfo] = useState(defaultMenuInfo); + const [contextMenuInfo, setContextMenuInfo] = useState( + defaultMenuInfo, + ); useEffect(() => { if (graphRef.current && miniMapRef.current) { @@ -53,7 +51,7 @@ const FlowChart: React.FC = (props) => { useEffect(() => { const handler = () => { requestAnimationFrame(() => { - if(flowChart && wrapperRef && wrapperRef.current) { + if (flowChart && wrapperRef && wrapperRef.current) { const width = wrapperRef.current.clientWidth; const height = wrapperRef.current.clientHeight; flowChart.resize(width, height); @@ -85,7 +83,7 @@ const FlowChart: React.FC = (props) => { flowChart.off('graph:showContextMenu', showHandler); flowChart.off('graph:hideContextMenu', hideHandler); } - } + }; }, [flowChart]); const fetchData = (flowChart: Graph) => { @@ -104,9 +102,11 @@ const FlowChart: React.FC = (props) => {
- {flowChart && } - {flowChart && } - {flowChart && } + {flowChart && } + {flowChart && } + {flowChart && ( + + )}
); }; diff --git a/packages/core/src/mods/flowChart/registerServerStorage.ts b/packages/core/src/mods/flowChart/registerServerStorage.ts index 2e9816b..8e55de0 100644 --- a/packages/core/src/mods/flowChart/registerServerStorage.ts +++ b/packages/core/src/mods/flowChart/registerServerStorage.ts @@ -22,11 +22,12 @@ const enqueue = (cellType: string, actionType: ActionType, data: any) => { return; } - const foundIndex = memQueue.findIndex((item) => ( - item.type === cellType && - item.actionType === actionType && - item.data.id === data.id - )); + const foundIndex = memQueue.findIndex( + (item) => + item.type === cellType && + item.actionType === actionType && + item.data.id === data.id, + ); if (foundIndex > -1) { const deleted = memQueue.splice(foundIndex, 1)[0]; merge(deleted.data, data); @@ -34,8 +35,13 @@ const enqueue = (cellType: string, actionType: ActionType, data: any) => { memQueue.push({ type: cellType, actionType, data }); }; -let modifyActionTimer: number = -1; -const save = (flowChart: Graph, cellType: string, actionType: ActionType, data: any) => { +let modifyActionTimer = -1; +const save = ( + flowChart: Graph, + cellType: string, + actionType: ActionType, + data: any, +) => { enqueue(cellType, actionType, data); clearTimeout(modifyActionTimer); modifyActionTimer = window.setTimeout(() => { diff --git a/packages/core/src/mods/header/connectStatus/editModal.tsx b/packages/core/src/mods/header/connectStatus/editModal.tsx index e94e968..8c9914e 100644 --- a/packages/core/src/mods/header/connectStatus/editModal.tsx +++ b/packages/core/src/mods/header/connectStatus/editModal.tsx @@ -56,10 +56,18 @@ const EditModal: React.FC = (props) => { onCancel={onCancel} >
- + - + diff --git a/packages/core/src/mods/header/export/exportModal.tsx b/packages/core/src/mods/header/export/exportModal.tsx index b1c2e8e..dd4d721 100644 --- a/packages/core/src/mods/header/export/exportModal.tsx +++ b/packages/core/src/mods/header/export/exportModal.tsx @@ -15,7 +15,6 @@ interface IExportModalProps { } const ExportModal: React.FC = (props) => { - const { flowChart, visible, onClose } = props; const onExportDSL = () => { const dsl = JSON.stringify(flowChart.toJSON(), null, 2); @@ -32,9 +31,12 @@ const ExportModal: React.FC = (props) => { }); }; const onExportFlowChart = () => { - flowChart.toPNG((dataUri: string) => { - DataUri.downloadDataUri(dataUri, 'flowChart.png'); - }, { padding: 50, ratio: '3.0' }); + flowChart.toPNG( + (dataUri: string) => { + DataUri.downloadDataUri(dataUri, 'flowChart.png'); + }, + { padding: 50, ratio: '3.0' }, + ); }; return ( @@ -48,15 +50,24 @@ const ExportModal: React.FC = (props) => { >
- + DSL
- + 代码
- + 流程图
@@ -78,7 +89,7 @@ const Helper = { Helper.recursiveZip(dir, val); } } - } -} + }, +}; export default ExportModal; diff --git a/packages/core/src/mods/header/export/index.tsx b/packages/core/src/mods/header/export/index.tsx index 7621bd1..8dbcabb 100644 --- a/packages/core/src/mods/header/export/index.tsx +++ b/packages/core/src/mods/header/export/index.tsx @@ -1,4 +1,4 @@ -import React, {useState} from 'react'; +import React, { useState } from 'react'; import styles from './index.module.less'; @@ -10,9 +10,8 @@ interface IProps { flowChart: Graph; } -const Export: React.FC = props => { - - const {flowChart} = props; +const Export: React.FC = (props) => { + const { flowChart } = props; const [modalVisible, setModalVisible] = useState(false); const onOpenModal = () => setModalVisible(true); @@ -20,7 +19,9 @@ const Export: React.FC = props => { return (
- + void; } const renderCode = (code: any) => { - return
{code}
-} + return
{code}
; +}; const QuickStart: React.FC = () => { - return
-

启动项目

- {renderCode(`$ git clone git@github.com:imgcook/imove.git\n + return ( +
+

启动项目

+ {renderCode(`$ git clone git@github.com:imgcook/imove.git\n $ cd imove\n $ npm install\n $ npm run example`)} - - 打开 http://localhost:8000/ - - -

绘制流程图、编写代码

-

根据你的业务逻辑绘制流程图。双击各节点,完成每个节点的函数编写。

- - - -

在项目中使用

-

这时有两种方式:

-
    -
  1. 在线打包出码
  2. -
  3. 本地启动开发模式
  4. -
- -

1. 在线打包出码

- -

点击页面右上方的导出按钮后,可以在弹窗内选择导出 代码,此时流程图编译后的代码将以 zip 包的形式下载到本地,你可以解压后再引入项目中使用。

- -

2. 本地命令行出码

-

安装 CLI

-
-      $ npm install -g @imove/cli
-    
-

进入项目根目录,imove 初始化

-
-      $ cd yourProject
-      $ imove --init # 或 imove -i
-    
-

本地启动开发模式

-
-      $ imove --dev # 或 imove -d
-    
- -

本地启动成功之后,可以看到原来的页面右上角会显示连接成功。

- - -

此时页面上触发 保存快捷键 Ctrl + S 时,可以看到当前项目的 src 目录下会多出一个 logic 目录,这就是 imove 编译生成的代码,此时你只要在你的组件中调用它即可。

- - 如上代码所示,需要注意两点: -
    -
  1. 通过 logic.on 方法监听事件,事件名和参数与流程图中节点代码的 ctx.emit 相对应
  2. -
  3. 通过 logic.invoke 方法调用逻辑,事件名与流程图中的开始节点的 逻辑触发名称 相对应,不然会调用失败
  4. -
-
-} + 打开 http://localhost:8000/ + +

绘制流程图、编写代码

+

根据你的业务逻辑绘制流程图。双击各节点,完成每个节点的函数编写。

+ + +

在项目中使用

+

这时有两种方式:

+
    +
  1. 在线打包出码
  2. +
  3. 本地启动开发模式
  4. +
+

1. 在线打包出码

+ +

+ 点击页面右上方的导出按钮后,可以在弹窗内选择导出 + 代码,此时流程图编译后的代码将以 zip + 包的形式下载到本地,你可以解压后再引入项目中使用。 +

+

2. 本地命令行出码

+

安装 CLI

+
$ npm install -g @imove/cli
+

进入项目根目录,imove 初始化

+
$ cd yourProject $ imove --init # 或 imove -i
+

本地启动开发模式

+
$ imove --dev # 或 imove -d
+

本地启动成功之后,可以看到原来的页面右上角会显示连接成功。

+ +

+ 此时页面上触发 保存快捷键 Ctrl + S 时,可以看到当前项目的 src + 目录下会多出一个 logic 目录,这就是 imove + 编译生成的代码,此时你只要在你的组件中调用它即可。 +

+ 如上代码所示,需要注意两点: +
    +
  1. + 通过 logic.on 方法监听事件,事件名和参数与流程图中节点代码的 ctx.emit + 相对应 +
  2. +
  3. + 通过 logic.invoke 方法调用逻辑,事件名与流程图中的开始节点的 + 逻辑触发名称 相对应,不然会调用失败 +
  4. +
+
+ ); +}; const CreateNode: React.FC = () => { return (

创建节点

-

项目启动成功后,可以从左侧面板中依次拖动节点至中间的画布,从而完成流程图的绘制工作

- 创建节点 +

+ 项目启动成功后,可以从左侧面板中依次拖动节点至中间的画布,从而完成流程图的绘制工作 +

+ 创建节点
- ) -} + ); +}; const NodeType: React.FC = () => { return ( @@ -84,99 +105,140 @@ const NodeType: React.FC = () => {

节点类型

在 iMove 中,我们将流程图的节点一共分为以下 3 种类型:

    -
  1. 开始节点:逻辑起始,是所有流程的开始,可以是一次生命周期初始化/一次点击
  2. +
  3. + 开始节点:逻辑起始,是所有流程的开始,可以是一次生命周期初始化/一次点击 +
  4. 行为节点:逻辑执行,可以是一次网络请求/一次改变状态/发送埋点等
  5. 分支节点:逻辑路由,根据不同的逻辑执行结果跳转到不同的节点
(注:一条逻辑流程必须以 开始节点 为起始) -

根据上述的规范描述,我们可以绘制出各种各样的逻辑流程图,例如获取个人数据的逻辑流程图如下所示:

- 节点类型 +

+ 根据上述的规范描述,我们可以绘制出各种各样的逻辑流程图,例如 + 获取个人数据的逻辑流程图如下所示: +

+ 节点类型
- ) -} + ); +}; const ConfigNode: React.FC = () => { return (

配置节点

依次选中图中的节点,完成右边面板中的基础配置信息填写

- 配置节点 + 配置节点

通常来说,基础信息配置使用频率最高的有:

  • 显示名称:更改节点名称
  • 代码:编辑节点代码
  • -
  • 逻辑触发名称:开始节点类型专属配置,项目代码使用时根据这个值触发逻辑调用
  • +
  • + 逻辑触发名称:开始节点类型专属配置,项目代码使用时根据这个值触发逻辑调用 +
- ) -} + ); +}; const CodeStyle: React.FC = () => { return (

节点代码规范

点击编辑按钮,可打开代码编辑器

- 节点代码规范 -

每个节点的代码等价于一个 js 文件,因此你不用担心全局变量的命名污染问题,甚至可以 import 现有的 npm 包,但最后必须 export 出一个函数。需要注意的是,由于 iMove 天生支持节点代码的异步调用,因此 export 出的函数默认是一个 promise。

-

就拿 是否登录 这个分支节点为例,我们来看下节点代码该如何编写:

+ 节点代码规范 +

+ 每个节点的代码等价于一个 js + 文件,因此你不用担心全局变量的命名污染问题,甚至可以 import 现有的 npm + 包,但最后必须 export 出一个函数。需要注意的是,由于 iMove + 天生支持节点代码的异步调用,因此 export 出的函数默认是一个 promise。 +

+

+ 就拿 是否登录 这个分支节点为例,我们来看下节点代码该如何编写: +

{renderCode(`export default async function() {\n return fetch('/api/isLogin')\n .then(res => res.json())\n .then(res => {\n - const {success, data: {isLogin} = {}} = res;\n - return success && isLogin;\n + const {success, data: {isLogin} = {}} = res\n + return success && isLogin\n }).catch(err => {\n - console.log('fetch /api/isLogin failed, the err is:', err);\n - return false;\n - });\n + console.log('fetch /api/isLogin failed, the err is:', err)\n + return false\n + })\n }\n `)} -

注:由于该节点是分支节点,因此其 boolean 返回值决定了整个流程的走向

+

+ 注:由于该节点是分支节点,因此其 boolean + 返回值决定了整个流程的走向 +

- ) -} + ); +}; const NodeConnect: React.FC = () => { return (

节点间数据通信

-

在 iMove 中,数据是以流(pipe)的形式从前往后进行流动的,也就是说前一个节点的返回值会是下一个节点的输入。不过也有一个例外,由于分支节点的返回值会是 boolean 类型,因此它的下游节点拿到的输入必将是一个 boolean 类型值,从而造成数据流的中断。为此,我们进行了一定的改造,分支节点的作用只负责数据流的转发,就像一个开关一样,只决定数据流的走向,但不改变流向下游的数据流值。

-

因此,前文例子中的请求profile接口返回数据两个节点会成为数据流的上下游关系。我们再来看下他们之间是如何进行数据通信的:

+

+ 在 iMove + 中,数据是以流(pipe)的形式从前往后进行流动的,也就是说前一个节点的返回值会是下一个节点的输入。不过也有一个例外,由于 + 分支节点的返回值会是 boolean + 类型,因此它的下游节点拿到的输入必将是一个 boolean + 类型值,从而造成数据流的中断。为此,我们进行了一定的改造,分支节点的作用只负责数据流的转发,就像一个开关一样,只决定数据流的走向,但不改变流向下游的数据流值。 +

+

+ 因此,前文例子中的请求profile接口返回数据 + 两个节点会成为数据流的上下游关系。我们再来看下他们之间是如何进行数据通信的: +

{renderCode(`// 节点: 请求profile接口\n export default async function() {\n return fetch('/api/profile')\n .then(res => res.json())\n .then(res => {\n - const {success, data} = res;\n - return {success, data};\n + const {success, data} = res\n + return {success, data}\n }).catch(err => {\n - console.log('fetch /api/isLogin failed, the err is:', err);\n - return {success: false};\n - });\n + console.log('fetch /api/isLogin failed, the err is:', err)\n + return {success: false}\n + })\n }\n `)} {renderCode(`// 节点: 接口成功\n export default async function(ctx) {\n // 获取上游数据\n - const pipe = ctx.getPipe() || {};\n - return pipe.success;\n + const pipe = ctx.getPipe() || {}\n + return pipe.success\n }\n `)} {renderCode(`// 节点: 返回数据\n const doSomething = (data) => {\n // TODO: 数据加工处理\n - return data;\n -};\n + return data\n +}\n export default async function(ctx) {\n // 这里获取到的上游数据,不是"接口成功"这个分支节点的返回值,而是"请求profile接口"这个节点的返回值\n - const pipe = ctx.getPipe() || {};\n - ctx.emit('updateUI', {profileData: doSomething(pipe.data)});\n + const pipe = ctx.getPipe() || {}\n + ctx.emit('updateUI', {profileData: doSomething(pipe.data)})\n }\n `)} - 如上代码所述,每个下游节点可以调用 ctx.getPipe 方法获取上游节点返回的数据流。另外,需要注意的是 返回数据 节点的最后一行代码 ctx.emit('eventName', data) 需要和你项目中的代码配合使用。 + 如上代码所述,每个下游节点可以调用 ctx.getPipe{' '} + 方法获取上游节点返回的数据流。另外,需要注意的是 返回数据{' '} + 节点的最后一行代码 ctx.emit('eventName', data){' '} + 需要和你项目中的代码配合使用。
- ) -} + ); +}; const HowToUse: React.FC = () => { return ( @@ -189,47 +251,71 @@ const HowToUse: React.FC = () => {

1. 在线打包出码

- -

点击页面右上方的导出按钮后,可以在弹窗内选择导出 代码,此时流程图编译后的代码将以 zip 包的形式下载到本地,你可以解压后再引入项目中使用。

+ +

+ 点击页面右上方的导出按钮后,可以在弹窗内选择导出 + 代码,此时流程图编译后的代码将以 zip + 包的形式下载到本地,你可以解压后再引入项目中使用。 +

2. 本地命令行出码

安装 CLI

-
-        $ npm install -g @imove/cli
-    
+
$ npm install -g @imove/cli

进入项目根目录,imove 初始化

-
-        $ cd yourProject
-        $ imove --init # 或 imove -i
-    
+
$ cd yourProject $ imove --init # 或 imove -i

本地启动开发模式

-
-        $ imove --dev # 或 imove -d
-    
+
$ imove --dev # 或 imove -d

本地启动成功之后,可以看到原来的页面右上角会显示连接成功。

- + -

此时页面上触发 保存快捷键 Ctrl + S 时,可以看到当前项目的 src 目录下会多出一个 logic 目录,这就是 imove 编译生成的代码,此时你只要在你的组件中调用它即可。

+

+ 此时页面上触发 保存快捷键 Ctrl + S 时,可以看到当前项目的 src + 目录下会多出一个 logic 目录,这就是 imove + 编译生成的代码,此时你只要在你的组件中调用它即可。 +

如上代码所示,需要注意两点:
    -
  1. 通过 logic.on 方法监听事件,事件名和参数与流程图中节点代码的 ctx.emit 相对应
  2. -
  3. 通过 logic.invoke 方法调用逻辑,事件名与流程图中的开始节点的 逻辑触发名称 相对应,不然会调用失败
  4. +
  5. + 通过 logic.on 方法监听事件,事件名和参数与流程图中节点代码的 ctx.emit + 相对应 +
  6. +
  7. + 通过 logic.invoke 方法调用逻辑,事件名与流程图中的开始节点的 + 逻辑触发名称 相对应,不然会调用失败 +
- ) -} + ); +}; const Document: React.FC = () => { return ( - ) -} + ); +}; const GuideModal: React.FC = (props) => { const { visible, onClose } = props; @@ -244,7 +330,7 @@ const GuideModal: React.FC = (props) => { onCancel={onClose} >
- + @@ -270,7 +356,6 @@ const GuideModal: React.FC = (props) => { -
); diff --git a/packages/core/src/mods/header/guide/index.tsx b/packages/core/src/mods/header/guide/index.tsx index ddb76bd..5c4c885 100644 --- a/packages/core/src/mods/header/guide/index.tsx +++ b/packages/core/src/mods/header/guide/index.tsx @@ -3,8 +3,7 @@ import React, { useState } from 'react'; import { Button } from 'antd'; import GuideModal from './guideModal'; -const Export: React.FC = props => { - +const Export: React.FC = (props) => { const [modalVisible, setModalVisible] = useState(false); const onOpenModal = () => setModalVisible(true); @@ -12,11 +11,10 @@ const Export: React.FC = props => { return (
- - + +
); }; diff --git a/packages/core/src/mods/header/importDSL/index.tsx b/packages/core/src/mods/header/importDSL/index.tsx index d9e1416..97e99ff 100644 --- a/packages/core/src/mods/header/importDSL/index.tsx +++ b/packages/core/src/mods/header/importDSL/index.tsx @@ -9,16 +9,15 @@ interface IProps { flowChart: Graph; } -const ImportDSL: React.FC = props => { - - const {flowChart} = props; +const ImportDSL: React.FC = (props) => { + const { flowChart } = props; const [disabled, setDisabled] = useState(false); const beforeUpload = (file: any) => { setDisabled(true); const reader = new FileReader(); reader.onload = (evt) => { setDisabled(false); - if(!evt.target) { + if (!evt.target) { message.error('加载文件失败!'); } else { const dsl = evt.target.result as string; @@ -41,7 +40,9 @@ const ImportDSL: React.FC = props => { showUploadList={false} beforeUpload={beforeUpload} > - + ); }; diff --git a/packages/core/src/mods/settingBar/components/checkbox/index.tsx b/packages/core/src/mods/settingBar/components/checkbox/index.tsx index 6fc89c7..59ad647 100644 --- a/packages/core/src/mods/settingBar/components/checkbox/index.tsx +++ b/packages/core/src/mods/settingBar/components/checkbox/index.tsx @@ -25,7 +25,12 @@ const Checkbox: React.FC = (props) => { return (

{title}

- +
); }; diff --git a/packages/core/src/mods/settingBar/components/input/index.tsx b/packages/core/src/mods/settingBar/components/input/index.tsx index 8153cee..6f5e272 100644 --- a/packages/core/src/mods/settingBar/components/input/index.tsx +++ b/packages/core/src/mods/settingBar/components/input/index.tsx @@ -24,7 +24,12 @@ const Input: React.FC = (props) => { return (

{title}

- +
); }; diff --git a/packages/core/src/mods/settingBar/components/json/index.tsx b/packages/core/src/mods/settingBar/components/json/index.tsx index e9eb3a4..d885e91 100644 --- a/packages/core/src/mods/settingBar/components/json/index.tsx +++ b/packages/core/src/mods/settingBar/components/json/index.tsx @@ -7,13 +7,13 @@ import JsonView from 'react-json-view'; import { Button, Tabs, Modal, Card, message } from 'antd'; import { safeParse } from '../../../../utils'; import CodeEditor from '../../../../components/codeEditor'; -import SchemaForm from '../../../../components/schemaForm' -import { compData } from './json' +import SchemaForm from '../../../../components/schemaForm'; +import { compData } from './json'; import styles from './index.module.less'; const { TabPane } = Tabs; -const JSON_TAB = 'JsonTab' -const VISUAL_TAB = 'VisualTab' +const JSON_TAB = 'JsonTab'; +const VISUAL_TAB = 'VisualTab'; interface IJsonProps { value: any; @@ -25,38 +25,39 @@ interface IJsonProps { } interface IConfigData { - [key: string]: any + [key: string]: any; } interface ISchemaProps { - type: string, - properties: { [key: string]: any } + type: string; + properties: { [key: string]: any }; } const Json: React.FC = (props) => { const { title, value, isConfig, onValueChange, selectedCell } = props; const [visible, setVisible] = useState(false); - const [schema, setSchema] = useState({ type: '', properties: {} }) - const [configData, setConfigData] = useState({}); + const [schema, setSchema] = useState({ + type: '', + properties: {}, + }); const defaultSchema = useMemo(() => { if (selectedCell) { const { configSchema } = selectedCell.getData(); if (configSchema) { - const schema = JSON.parse(configSchema).schema - setSchema(schema) - return schema + const schema = JSON.parse(configSchema).schema; + setSchema(schema); + return schema; } } - }, [selectedCell]) + }, [selectedCell]); const defaultConfigData = useMemo(() => { if (selectedCell) { const { configData = {} } = selectedCell.getData(); - setConfigData(configData); - return configData + return configData; } - }, [selectedCell]) + }, [selectedCell]); const onClickEdit = (): void => { setVisible(true); @@ -71,27 +72,38 @@ const Json: React.FC = (props) => { const changeSchema = (schema: ISchemaProps) => { setVisible(false); setSchema(schema); - } + }; const changeConfigData = (configData: IConfigData) => { selectedCell && selectedCell.setData({ configData }); - } + }; return ( - 编辑}> - {!isConfig && } - - {isConfig && + + 编辑 + } + > + {!isConfig && ( + + )} + + {isConfig && ( + + )} void; onCancel: () => void; - changeSchema: (val: ISchemaProps) => void + changeSchema: (val: ISchemaProps) => void; } interface FormInstance { setValue: (val: object) => void; getValue: () => { - schema: ISchemaProps - } + schema: ISchemaProps; + }; } const EditModal: React.FC = (props) => { const { visible, title, value, onOk, onCancel, defaultSchema } = props; const [json, setJson] = useState(''); - const [tab, setTab] = useState(VISUAL_TAB) + const [tab, setTab] = useState(VISUAL_TAB); const formRef = useRef(null); const defaultValue = useMemo(() => { if (defaultSchema && Object.keys(defaultSchema).length > 0) { - let codeObj = { - "schema": Object.assign({}, defaultSchema), - "displayType": "row", - "showDescIcon": true - } - return codeObj + const codeObj = { + schema: Object.assign({}, defaultSchema), + displayType: 'row', + showDescIcon: true, + }; + return codeObj; } - }, [defaultSchema]) + }, [defaultSchema]); const tabChange = (tab: string) => { if (tab === JSON_TAB) { - setTab(JSON_TAB) - form2code() + setTab(JSON_TAB); + form2code(); } if (tab === VISUAL_TAB) { - setTab(VISUAL_TAB) - code2form() + setTab(VISUAL_TAB); + code2form(); } - } + }; const form2code = () => { - const formSchema = formRef.current && formRef.current.getValue() - setJson(JSON.stringify(formSchema, null, 2)) - } + const formSchema = formRef.current && formRef.current.getValue(); + setJson(JSON.stringify(formSchema, null, 2)); + }; const code2form = () => { try { - const codeObj = JSON.parse(json) - formRef.current && formRef.current.setValue(codeObj) + const codeObj = JSON.parse(json); + formRef.current && formRef.current.setValue(codeObj); } catch (error) { - console.log('can\'t parse code string to form schema, the error is:', error.message); + console.log( + "can't parse code string to form schema, the error is:", + error.message, + ); } - } + }; const onJsonChange = (ev: any, newJson: string | undefined = ''): void => { - setJson(newJson) - props.isConfig && code2form() - } + setJson(newJson); + props.isConfig && code2form(); + }; // life useEffect(() => { @@ -186,12 +201,12 @@ const EditModal: React.FC = (props) => { try { if (props.isConfig) { if (tab === VISUAL_TAB && formRef.current) { - const value = formRef.current.getValue() - props.changeSchema(formRef.current.getValue().schema) - setJson(JSON.stringify(value, null, 2)) + const value = formRef.current.getValue(); + props.changeSchema(formRef.current.getValue().schema); + setJson(JSON.stringify(value, null, 2)); onOk(JSON.stringify(value)); } else { - props.changeSchema(JSON.parse(json).schema) + props.changeSchema(JSON.parse(json).schema); onOk(json); } } else { @@ -215,22 +230,29 @@ const EditModal: React.FC = (props) => { onOk={onClickOk} onCancel={onCancel} > - {props.isConfig ? + {props.isConfig ? (
@@ -245,7 +267,8 @@ const EditModal: React.FC = (props) => { />
- : + + ) : ( = (props) => { language={'json'} onChange={onJsonChange} /> - } + )} ); }; diff --git a/packages/core/src/mods/settingBar/components/json/json.ts b/packages/core/src/mods/settingBar/components/json/json.ts index 7904d4e..7da0bc9 100644 --- a/packages/core/src/mods/settingBar/components/json/json.ts +++ b/packages/core/src/mods/settingBar/components/json/json.ts @@ -1,133 +1,103 @@ const compData = [ { - "text": 'Input', - "name": 'input', - "schema": { - "title": "Input", - "type": "string", - "description": "输入框" - } + text: 'Input', + name: 'input', + schema: { + title: 'Input', + type: 'string', + description: '输入框', + }, }, { - "text": 'Textarea', - "name": 'textarea', - "schema": { - "title": "Textarea", - "type": "string", - "format": "textarea", - "description": "文本编辑框" - } + text: 'Textarea', + name: 'textarea', + schema: { + title: 'Textarea', + type: 'string', + format: 'textarea', + description: '文本编辑框', + }, }, { - "text": 'Switch', - "name": 'allBoolean', - "schema": { - "title": "Switch", - "type": "boolean", - "ui:widget": "switch", - "description": "开关控制" - } + text: 'Switch', + name: 'allBoolean', + schema: { + title: 'Switch', + type: 'boolean', + 'ui:widget': 'switch', + description: '开关控制', + }, }, { - "text": 'Select', - "name": 'select', - "schema": { - "title": "Select", - "type": "string", - "enum": [ - "a", - "b", - "c" - ], - "enumNames": [ - "早", - "中", - "晚" - ], - "description": "下拉单选" - } + text: 'Select', + name: 'select', + schema: { + title: 'Select', + type: 'string', + enum: ['a', 'b', 'c'], + enumNames: ['早', '中', '晚'], + description: '下拉单选', + }, }, { - "text": 'MultiSelect', - "name": 'multiSelect', - "schema": { - "title": "MultiSelect", - "description": "下拉多选", - "type": "array", - "items": { - "type": "string" + text: 'MultiSelect', + name: 'multiSelect', + schema: { + title: 'MultiSelect', + description: '下拉多选', + type: 'array', + items: { + type: 'string', }, - "enum": [ - "A", - "B", - "C", - "D" - ], - "enumNames": [ - "1", - "2", - "3", - "4" - ], - "ui:widget": "multiSelect" - } + enum: ['A', 'B', 'C', 'D'], + enumNames: ['1', '2', '3', '4'], + 'ui:widget': 'multiSelect', + }, }, { - "text": 'Checkbox', - "name": 'checkbox', - "schema": { - "title": "Checkbox", - "description": "点击多选", - "type": "array", - "items": { - "type": "string" + text: 'Checkbox', + name: 'checkbox', + schema: { + title: 'Checkbox', + description: '点击多选', + type: 'array', + items: { + type: 'string', }, - "enum": [ - "A", - "B", - "C", - "D" - ], - "enumNames": [ - "1", - "2", - "3", - "4" - ] - } + enum: ['A', 'B', 'C', 'D'], + enumNames: ['1', '2', '3', '4'], + }, }, { - "text": 'TimePicker', - "name": 'timeSelect', - "schema": { - "title": "TimePicker", - "type": "string", - "format": "time", - "description": "时间选择" - } + text: 'TimePicker', + name: 'timeSelect', + schema: { + title: 'TimePicker', + type: 'string', + format: 'time', + description: '时间选择', + }, }, { - "text": 'DatePicker', - "name": 'dateSelect', - "schema": { - "title": "DatePicker", - "type": "string", - "format": "date", - "description": "日期选择" - } + text: 'DatePicker', + name: 'dateSelect', + schema: { + title: 'DatePicker', + type: 'string', + format: 'date', + description: '日期选择', + }, }, { - "text": 'DateRange', - "name": 'dateRangeSelect', - "schema": { - "title": "DateRange", - "type": "range", - "format": "date", - "description": "日期范围选择" - } - } -] + text: 'DateRange', + name: 'dateRangeSelect', + schema: { + title: 'DateRange', + type: 'range', + format: 'date', + description: '日期范围选择', + }, + }, +]; -export { - compData -} +export { compData }; diff --git a/packages/core/src/mods/settingBar/index.tsx b/packages/core/src/mods/settingBar/index.tsx index de4a3b0..e64c2f6 100644 --- a/packages/core/src/mods/settingBar/index.tsx +++ b/packages/core/src/mods/settingBar/index.tsx @@ -33,7 +33,12 @@ const SettingBar: React.FC = (props) => { @@ -47,7 +52,10 @@ const SettingBar: React.FC = (props) => { } else { return (
- +
); } diff --git a/packages/core/src/mods/settingBar/mods/basic/index.tsx b/packages/core/src/mods/settingBar/mods/basic/index.tsx index b6811d9..4b96732 100644 --- a/packages/core/src/mods/settingBar/mods/basic/index.tsx +++ b/packages/core/src/mods/settingBar/mods/basic/index.tsx @@ -1,7 +1,4 @@ -import React, { - useState, - useEffect, -} from 'react'; +import React, { useState, useEffect } from 'react'; import styles from './index.module.less'; @@ -64,7 +61,12 @@ const Basic: React.FC = (props) => { return (
- + {selectedCell.shape === 'imove-start' && (
= (props) => { const closeModal = useCallback(() => setVisible(false), []); return ( - + ); }; @@ -55,7 +47,7 @@ const EditModal: React.FC = (props): JSX.Element => { footer={null} onCancel={onClose} > - + ); }; diff --git a/packages/core/src/mods/sideBar/index.tsx b/packages/core/src/mods/sideBar/index.tsx index e39d87d..22eaffa 100644 --- a/packages/core/src/mods/sideBar/index.tsx +++ b/packages/core/src/mods/sideBar/index.tsx @@ -14,7 +14,11 @@ const CELL_SCALE = 0.7; const GENERAL_GROUP = { key: 'general', name: '通用元件', - cells: ['imove-start-preview', 'imove-branch-preview', 'imove-behavior-preview'], + cells: [ + 'imove-start-preview', + 'imove-branch-preview', + 'imove-behavior-preview', + ], }; const SHAPE_REFLECT_MAP: { [key: string]: string } = { 'imove-start-preview': 'imove-start', @@ -47,7 +51,10 @@ const SideBar: React.FC = (props) => { return (
{dnd && ( - + {groups.map((group) => ( diff --git a/packages/core/src/mods/toolBar/widgets/bgColor.tsx b/packages/core/src/mods/toolBar/widgets/bgColor.tsx index 316c932..61f296e 100644 --- a/packages/core/src/mods/toolBar/widgets/bgColor.tsx +++ b/packages/core/src/mods/toolBar/widgets/bgColor.tsx @@ -8,7 +8,10 @@ import { safeGet } from '../../../utils'; import XIcon from '../../../components/xIcon'; import ColorPicker from '../../../components/colorPicker'; import makeDropdownWidget from './common/makeDropdownWidget'; -import { hasNodeSelected, getSelectedNodes } from '../../../utils/flowChartUtils'; +import { + hasNodeSelected, + getSelectedNodes, +} from '../../../utils/flowChartUtils'; interface IProps { flowChart: Graph; @@ -29,7 +32,10 @@ const options = { return (
-
+
); }, @@ -39,7 +45,9 @@ const options = { return ; }, handler: (flowChart: Graph, value: any) => { - getSelectedNodes(flowChart).forEach((node) => node.setAttrs({ body: { fill: value } })); + getSelectedNodes(flowChart).forEach((node) => + node.setAttrs({ body: { fill: value } }), + ); }, disabled(flowChart: Graph) { return !hasNodeSelected(flowChart); diff --git a/packages/core/src/mods/toolBar/widgets/borderColor.tsx b/packages/core/src/mods/toolBar/widgets/borderColor.tsx index daf9837..c04bedb 100644 --- a/packages/core/src/mods/toolBar/widgets/borderColor.tsx +++ b/packages/core/src/mods/toolBar/widgets/borderColor.tsx @@ -8,7 +8,10 @@ import { safeGet } from '../../../utils'; import { HighlightOutlined } from '@ant-design/icons'; import ColorPicker from '../../../components/colorPicker'; import makeDropdownWidget from './common/makeDropdownWidget'; -import { hasNodeSelected, getSelectedNodes } from '../../../utils/flowChartUtils'; +import { + hasNodeSelected, + getSelectedNodes, +} from '../../../utils/flowChartUtils'; interface IProps { flowChart: Graph; @@ -29,17 +32,24 @@ const options = { return (
-
+
); }, getOverlay(flowChart: Graph, onChange: (data: any) => void) { const borderColor = options.getCurBorderColor(flowChart); const onChangeComplete = (color: string) => onChange(color); - return ; + return ( + + ); }, handler: (flowChart: Graph, value: any) => { - getSelectedNodes(flowChart).forEach((node) => node.setAttrs({ body: { stroke: value } })); + getSelectedNodes(flowChart).forEach((node) => + node.setAttrs({ body: { stroke: value } }), + ); }, disabled(flowChart: Graph) { return !hasNodeSelected(flowChart); diff --git a/packages/core/src/mods/toolBar/widgets/common/makeDropdownWidget.tsx b/packages/core/src/mods/toolBar/widgets/common/makeDropdownWidget.tsx index 0e282fc..8e503df 100644 --- a/packages/core/src/mods/toolBar/widgets/common/makeDropdownWidget.tsx +++ b/packages/core/src/mods/toolBar/widgets/common/makeDropdownWidget.tsx @@ -37,7 +37,11 @@ const makeDropdownWidget = (options: IOptions) => { }; return ( - +
{getIcon(flowChart)}
diff --git a/packages/core/src/mods/toolBar/widgets/fontSize.tsx b/packages/core/src/mods/toolBar/widgets/fontSize.tsx index 89cebce..29b3138 100644 --- a/packages/core/src/mods/toolBar/widgets/fontSize.tsx +++ b/packages/core/src/mods/toolBar/widgets/fontSize.tsx @@ -36,7 +36,9 @@ const FontSize: React.FC = makeDropdownWidget({ ); }, handler: (flowChart: Graph, value: any) => { - flowChart.getSelectedCells().forEach((cell) => cell.setAttrs({ label: { fontSize: value } })); + flowChart + .getSelectedCells() + .forEach((cell) => cell.setAttrs({ label: { fontSize: value } })); }, disabled(flowChart: Graph) { return flowChart.getSelectedCellCount() === 0; diff --git a/packages/core/src/mods/toolBar/widgets/horizontalAlign.tsx b/packages/core/src/mods/toolBar/widgets/horizontalAlign.tsx index c0ee6bb..ac57474 100644 --- a/packages/core/src/mods/toolBar/widgets/horizontalAlign.tsx +++ b/packages/core/src/mods/toolBar/widgets/horizontalAlign.tsx @@ -6,8 +6,15 @@ import { Menu } from 'antd'; import { Graph } from '@antv/x6'; import { safeGet } from '../../../utils'; import makeDropdownWidget from './common/makeDropdownWidget'; -import { hasNodeSelected, getSelectedNodes } from '../../../utils/flowChartUtils'; -import { AlignLeftOutlined, AlignCenterOutlined, AlignRightOutlined } from '@ant-design/icons'; +import { + hasNodeSelected, + getSelectedNodes, +} from '../../../utils/flowChartUtils'; +import { + AlignLeftOutlined, + AlignCenterOutlined, + AlignRightOutlined, +} from '@ant-design/icons'; interface IProps { flowChart: Graph; @@ -89,7 +96,9 @@ const HorizontalAlign: React.FC = makeDropdownWidget({ ); }, handler: (flowChart: Graph, value: any) => { - getSelectedNodes(flowChart).forEach((node) => node.setAttrs({ label: value })); + getSelectedNodes(flowChart).forEach((node) => + node.setAttrs({ label: value }), + ); }, disabled(flowChart: Graph) { return !hasNodeSelected(flowChart); diff --git a/packages/core/src/mods/toolBar/widgets/lineStyle.tsx b/packages/core/src/mods/toolBar/widgets/lineStyle.tsx index 1b2b0a6..2f25c2e 100644 --- a/packages/core/src/mods/toolBar/widgets/lineStyle.tsx +++ b/packages/core/src/mods/toolBar/widgets/lineStyle.tsx @@ -7,7 +7,10 @@ import { Graph } from '@antv/x6'; import { safeGet } from '../../../utils'; import XIcon from '../../../components/xIcon'; import makeDropdownWidget from './common/makeDropdownWidget'; -import { hasEdgeSelected, getSelectedEdges } from '../../../utils/flowChartUtils'; +import { + hasEdgeSelected, + getSelectedEdges, +} from '../../../utils/flowChartUtils'; interface IProps { flowChart: Graph; @@ -65,7 +68,9 @@ const LineStyle: React.FC = makeDropdownWidget({ ); }, handler: (flowChart: Graph, value: any) => { - getSelectedEdges(flowChart).forEach((edge) => edge.setAttrs({ line: value })); + getSelectedEdges(flowChart).forEach((edge) => + edge.setAttrs({ line: value }), + ); }, disabled(flowChart: Graph) { return !hasEdgeSelected(flowChart); diff --git a/packages/core/src/mods/toolBar/widgets/nodeAlign.tsx b/packages/core/src/mods/toolBar/widgets/nodeAlign.tsx index 78a25f8..2047e4d 100644 --- a/packages/core/src/mods/toolBar/widgets/nodeAlign.tsx +++ b/packages/core/src/mods/toolBar/widgets/nodeAlign.tsx @@ -25,14 +25,16 @@ const ALIGN_MAP: { [key: string]: AlignItem } = { icon: , handler(selectedNodes: Cell[]) { let minLeftValue = Infinity; - selectedNodes.forEach(node => { - const { x } = node.getProp<{ x: number, y: number }>('position'); + selectedNodes.forEach((node) => { + const { x } = node.getProp<{ x: number; y: number }>('position'); if (x < minLeftValue) { minLeftValue = x; } }); - selectedNodes.forEach(node => node.setProp({ position: { x: minLeftValue } })); - } + selectedNodes.forEach((node) => + node.setProp({ position: { x: minLeftValue } }), + ); + }, }, horizontalCenter: { text: '水平居中', @@ -40,9 +42,11 @@ const ALIGN_MAP: { [key: string]: AlignItem } = { handler(selectedNodes: Cell[]) { let minLeftValue = Infinity; let maxRightValue = -Infinity; - selectedNodes.forEach(node => { - const { x } = node.getProp<{ x: number, y: number }>('position'); - const { width } = node.getProp<{ width: number, height: number }>('size'); + selectedNodes.forEach((node) => { + const { x } = node.getProp<{ x: number; y: number }>('position'); + const { width } = node.getProp<{ width: number; height: number }>( + 'size', + ); if (x < minLeftValue) { minLeftValue = x; } @@ -51,43 +55,51 @@ const ALIGN_MAP: { [key: string]: AlignItem } = { } }); const centerValue = (minLeftValue + maxRightValue) / 2; - selectedNodes.forEach(node => { - const { width } = node.getProp<{ width: number, height: number }>('size'); + selectedNodes.forEach((node) => { + const { width } = node.getProp<{ width: number; height: number }>( + 'size', + ); node.setProp({ position: { x: centerValue - width / 2 } }); }); - } + }, }, right: { text: '右对齐', icon: , handler(selectedNodes: Cell[]) { let maxRightValue = -Infinity; - selectedNodes.forEach(node => { - const { x } = node.getProp<{ x: number, y: number }>('position'); - const { width } = node.getProp<{ width: number, height: number }>('size'); + selectedNodes.forEach((node) => { + const { x } = node.getProp<{ x: number; y: number }>('position'); + const { width } = node.getProp<{ width: number; height: number }>( + 'size', + ); if (x + width > maxRightValue) { maxRightValue = x + width; } }); - selectedNodes.forEach(node => { - const { width } = node.getProp<{ width: number, height: number }>('size'); - node.setProp({ position: { x: maxRightValue - width } }) + selectedNodes.forEach((node) => { + const { width } = node.getProp<{ width: number; height: number }>( + 'size', + ); + node.setProp({ position: { x: maxRightValue - width } }); }); - } + }, }, top: { text: '顶部对齐', icon: , handler(selectedNodes: Cell[]) { let minTopValue = Infinity; - selectedNodes.forEach(node => { - const { y } = node.getProp<{ x: number, y: number }>('position'); + selectedNodes.forEach((node) => { + const { y } = node.getProp<{ x: number; y: number }>('position'); if (y < minTopValue) { minTopValue = y; } }); - selectedNodes.forEach(node => node.setProp({ position: { y: minTopValue } })); - } + selectedNodes.forEach((node) => + node.setProp({ position: { y: minTopValue } }), + ); + }, }, verticalCenter: { text: '垂直居中', @@ -95,9 +107,11 @@ const ALIGN_MAP: { [key: string]: AlignItem } = { handler(selectedNodes: Cell[]) { let minTopValue = Infinity; let maxBottomValue = -Infinity; - selectedNodes.forEach(node => { - const { y } = node.getProp<{ x: number, y: number }>('position'); - const { height } = node.getProp<{ width: number, height: number }>('size'); + selectedNodes.forEach((node) => { + const { y } = node.getProp<{ x: number; y: number }>('position'); + const { height } = node.getProp<{ width: number; height: number }>( + 'size', + ); if (y < minTopValue) { minTopValue = y; } @@ -106,30 +120,36 @@ const ALIGN_MAP: { [key: string]: AlignItem } = { } }); const centerValue = (minTopValue + maxBottomValue) / 2; - selectedNodes.forEach(node => { - const { height } = node.getProp<{ width: number, height: number }>('size'); + selectedNodes.forEach((node) => { + const { height } = node.getProp<{ width: number; height: number }>( + 'size', + ); node.setProp({ position: { y: centerValue - height / 2 } }); }); - } + }, }, bottom: { text: '底部对齐', icon: , handler(selectedNodes: Cell[]) { let maxTopValue = -Infinity; - selectedNodes.forEach(node => { - const { y } = node.getProp<{ x: number, y: number }>('position'); - const { height } = node.getProp<{ width: number, height: number }>('size'); + selectedNodes.forEach((node) => { + const { y } = node.getProp<{ x: number; y: number }>('position'); + const { height } = node.getProp<{ width: number; height: number }>( + 'size', + ); if (y + height > maxTopValue) { maxTopValue = y + height; } }); - selectedNodes.forEach(node => { - const { height } = node.getProp<{ width: number, height: number }>('size'); - node.setProp({ position: { y: maxTopValue - height } }) + selectedNodes.forEach((node) => { + const { height } = node.getProp<{ width: number; height: number }>( + 'size', + ); + node.setProp({ position: { y: maxTopValue - height } }); }); - } - } + }, + }, }; const NodeAlign: React.FC = makeDropdownWidget({ diff --git a/packages/core/src/mods/toolBar/widgets/textColor.tsx b/packages/core/src/mods/toolBar/widgets/textColor.tsx index 10cb638..bd43b2a 100644 --- a/packages/core/src/mods/toolBar/widgets/textColor.tsx +++ b/packages/core/src/mods/toolBar/widgets/textColor.tsx @@ -8,7 +8,10 @@ import { safeGet } from '../../../utils'; import XIcon from '../../../components/xIcon'; import ColorPicker from '../../../components/colorPicker'; import makeDropdownWidget from './common/makeDropdownWidget'; -import { hasNodeSelected, getSelectedNodes } from '../../../utils/flowChartUtils'; +import { + hasNodeSelected, + getSelectedNodes, +} from '../../../utils/flowChartUtils'; interface IProps { flowChart: Graph; @@ -29,17 +32,24 @@ const options = { return (
-
+
); }, getOverlay(flowChart: Graph, onChange: (data: any) => void) { const textColor = options.getCurTextColor(flowChart); const onChangeComplete = (color: string) => onChange(color); - return ; + return ( + + ); }, handler: (flowChart: Graph, value: any) => { - flowChart.getSelectedCells().forEach((node) => node.setAttrs({ label: { fill: value } })); + flowChart + .getSelectedCells() + .forEach((node) => node.setAttrs({ label: { fill: value } })); }, disabled(flowChart: Graph) { return !hasNodeSelected(flowChart); diff --git a/packages/core/src/mods/toolBar/widgets/underline.tsx b/packages/core/src/mods/toolBar/widgets/underline.tsx index c5600bf..7258db6 100644 --- a/packages/core/src/mods/toolBar/widgets/underline.tsx +++ b/packages/core/src/mods/toolBar/widgets/underline.tsx @@ -22,7 +22,9 @@ const Underline: React.FC = makeBtnWidget({ selected(flowChart: Graph) { const cells = flowChart.getSelectedCells(); if (cells.length > 0) { - return safeGet(cells, '0.attrs.label.textDecoration', 'none') === 'underline'; + return ( + safeGet(cells, '0.attrs.label.textDecoration', 'none') === 'underline' + ); } else { return false; } diff --git a/packages/core/src/mods/toolBar/widgets/verticalAlign.tsx b/packages/core/src/mods/toolBar/widgets/verticalAlign.tsx index 4bc9228..c696eb2 100644 --- a/packages/core/src/mods/toolBar/widgets/verticalAlign.tsx +++ b/packages/core/src/mods/toolBar/widgets/verticalAlign.tsx @@ -6,7 +6,10 @@ import { Menu } from 'antd'; import { Graph } from '@antv/x6'; import { safeGet } from '../../../utils'; import makeDropdownWidget from './common/makeDropdownWidget'; -import { hasNodeSelected, getSelectedNodes } from '../../../utils/flowChartUtils'; +import { + hasNodeSelected, + getSelectedNodes, +} from '../../../utils/flowChartUtils'; import { VerticalAlignTopOutlined, VerticalAlignMiddleOutlined, @@ -93,7 +96,9 @@ const VerticalAlign: React.FC = makeDropdownWidget({ ); }, handler: (flowChart: Graph, value: any) => { - getSelectedNodes(flowChart).forEach((node) => node.setAttrs({ label: value })); + getSelectedNodes(flowChart).forEach((node) => + node.setAttrs({ label: value }), + ); }, disabled(flowChart: Graph) { return !hasNodeSelected(flowChart); diff --git a/packages/core/src/typings.d.ts b/packages/core/src/typings.d.ts index d00bbf6..6cc3d45 100644 --- a/packages/core/src/typings.d.ts +++ b/packages/core/src/typings.d.ts @@ -8,12 +8,11 @@ declare module '*.less' { export default classes; } - declare module 'fr-generator' { import React from 'react'; export interface FRProps { - settings?: object + settings?: object; } - class FormRender extends React.Component { } + class FormRender extends React.Component {} export default FRGenerator; } diff --git a/packages/core/src/utils/analyzeDeps.ts b/packages/core/src/utils/analyzeDeps.ts index c2ae7c4..019dd86 100644 --- a/packages/core/src/utils/analyzeDeps.ts +++ b/packages/core/src/utils/analyzeDeps.ts @@ -1,13 +1,13 @@ import axios from 'axios'; import { safeGet } from './index'; -const regex = /import\s([\s\S]*?)\sfrom\s(?:('[@\.\/\-\w]+')|("[@\.\/\-\w]+"))/mg; +const regex = /import\s([\s\S]*?)\sfrom\s(?:('[@\.\/\-\w]+')|("[@\.\/\-\w]+"))/gm; const extractPkgs = (code: string, excludePkgs?: string[]): string[] => { let matchRet = null; const pkgNames: string[] = []; while ((matchRet = regex.exec(code)) != null) { - let pkgName = (matchRet[2] || matchRet[3]); + let pkgName = matchRet[2] || matchRet[3]; pkgName = pkgName.slice(1, pkgName.length - 1); // NOTE: ignore relative path (./ and ../) and excludePkgs if ( @@ -22,26 +22,31 @@ const extractPkgs = (code: string, excludePkgs?: string[]): string[] => { }; const getPkgLatestVersion = (pkg: string): Promise => { - return axios.get(`https://registry.npm.taobao.org/${pkg}`) - .then(res => { + return axios + .get(`https://registry.npm.taobao.org/${pkg}`) + .then((res) => { return [pkg, safeGet(res, 'data.dist-tags.latest', '*')]; - }).catch(err => { + }) + .catch((err) => { console.log(`get package ${pkg} info failed, the error is:`, err); return [pkg, '*']; }); }; -const analyzeDeps = (code: string, excludePkgs?: string[]): Promise<{ [pkgName: string]: string }> => { +const analyzeDeps = ( + code: string, + excludePkgs?: string[], +): Promise<{ [pkgName: string]: string }> => { const pkgs = extractPkgs(code, excludePkgs); - return Promise - .all(pkgs.map(pkg => getPkgLatestVersion(pkg))) - .then(pkgResults => { + return Promise.all(pkgs.map((pkg) => getPkgLatestVersion(pkg))) + .then((pkgResults) => { const map: any = {}; pkgResults.forEach(([pkg, version]) => { map[pkg] = version; }); return map; - }).catch(err => { + }) + .catch((err) => { console.log('analyze deps failed, the error is:', err); }); }; diff --git a/packages/core/src/utils/flowChartUtils.ts b/packages/core/src/utils/flowChartUtils.ts index 0a67488..f35ca8d 100644 --- a/packages/core/src/utils/flowChartUtils.ts +++ b/packages/core/src/utils/flowChartUtils.ts @@ -5,11 +5,17 @@ export const hasCellSelected = (flowChart: Graph): boolean => { }; export const hasNodeSelected = (flowChart: Graph): boolean => { - return flowChart.getSelectedCells().filter((cell: Cell) => cell.isNode()).length > 0; + return ( + flowChart.getSelectedCells().filter((cell: Cell) => cell.isNode()).length > + 0 + ); }; export const hasEdgeSelected = (flowChart: Graph): boolean => { - return flowChart.getSelectedCells().filter((cell: Cell) => cell.isEdge()).length > 0; + return ( + flowChart.getSelectedCells().filter((cell: Cell) => cell.isEdge()).length > + 0 + ); }; export const getSelectedNodes = (flowChart: Graph): Cell[] => { @@ -20,10 +26,14 @@ export const getSelectedEdges = (flowChart: Graph): Cell[] => { return flowChart.getSelectedCells().filter((cell: Cell) => cell.isEdge()); }; -export const toSelectedCellsJSON = (flowChart: Graph): {cells: Cell.Properties[]} => { +export const toSelectedCellsJSON = ( + flowChart: Graph, +): { cells: Cell.Properties[] } => { const json = flowChart.toJSON(); const selectedCells = flowChart.getSelectedCells(); return { - cells: json.cells.filter(cell => selectedCells.find(o => o.id === cell.id)) + cells: json.cells.filter((cell) => + selectedCells.find((o) => o.id === cell.id), + ), }; -} \ No newline at end of file +}; diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts index c134e24..056d7ce 100644 --- a/packages/core/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -37,7 +37,7 @@ export const parseQuery = (): { [key: string]: any } => { return parse(location.search, parseConfig); }; -export const executeScript = (code: string, type: string = 'module') => { +export const executeScript = (code: string, type = 'module') => { const script = document.createElement('script'); script.type = type; script.text = code; diff --git a/packages/json-schema-editor/src/components/add-node.tsx b/packages/json-schema-editor/src/components/add-node.tsx index ea0960e..144c8e5 100644 --- a/packages/json-schema-editor/src/components/add-node.tsx +++ b/packages/json-schema-editor/src/components/add-node.tsx @@ -8,17 +8,30 @@ interface AddNodeProps { addSiblingField: () => void; } -function AddNodeIcon({ addChildField, addSiblingField }: AddNodeProps): JSX.Element { +function AddNodeIcon({ + addChildField, + addSiblingField, +}: AddNodeProps): JSX.Element { const { t } = useTranslation(); const menu = ( -
+
{t('child_node')}
-
+
{t('sibling_node')}
diff --git a/packages/json-schema-editor/src/components/schema-form.tsx b/packages/json-schema-editor/src/components/schema-form.tsx index 6f382da..3c5e765 100644 --- a/packages/json-schema-editor/src/components/schema-form.tsx +++ b/packages/json-schema-editor/src/components/schema-form.tsx @@ -29,7 +29,10 @@ function SchemaForm({ data, keyRoute }: SchemaFormProps): JSX.Element { keyRoute={fieldKeyRoute} > {itemData.type === 'object' && !isUndefined(itemData.properties) ? ( - + ) : null} ); diff --git a/packages/json-schema-editor/src/components/schema-head.tsx b/packages/json-schema-editor/src/components/schema-head.tsx index d3843d8..1aba5fa 100644 --- a/packages/json-schema-editor/src/components/schema-head.tsx +++ b/packages/json-schema-editor/src/components/schema-head.tsx @@ -79,10 +79,18 @@ function EditorHead(): JSX.Element { - } /> + } + /> - } /> + } + /> diff --git a/packages/json-schema-editor/src/components/schema-item.tsx b/packages/json-schema-editor/src/components/schema-item.tsx index b191b72..ee39500 100644 --- a/packages/json-schema-editor/src/components/schema-item.tsx +++ b/packages/json-schema-editor/src/components/schema-item.tsx @@ -51,7 +51,10 @@ function SchemaFormItem(props: SchemaItemProps): JSX.Element { }; const addChildField = (): void => { - schemaDispatch({ type: 'ADD_CHILD_FIELD', keyRoute: keyRoute.concat('properties') }); + schemaDispatch({ + type: 'ADD_CHILD_FIELD', + keyRoute: keyRoute.concat('properties'), + }); }; const addSiblingField = (): void => { @@ -84,8 +87,12 @@ function SchemaFormItem(props: SchemaItemProps): JSX.Element { - {data.type === 'object' && visible && } - {data.type === 'object' && !visible && } + {data.type === 'object' && visible && ( + + )} + {data.type === 'object' && !visible && ( + + )} {data.type === 'object' ? ( - + ) : ( @@ -136,7 +146,9 @@ function SchemaFormItem(props: SchemaItemProps): JSX.Element { )} - {visible && children ?
{children}
: null} + {visible && children ? ( +
{children}
+ ) : null}
); } diff --git a/packages/json-schema-editor/src/model/schema.ts b/packages/json-schema-editor/src/model/schema.ts index be9c86d..bbcbf60 100644 --- a/packages/json-schema-editor/src/model/schema.ts +++ b/packages/json-schema-editor/src/model/schema.ts @@ -1,4 +1,10 @@ -export type SchemaType = 'string' | 'number' | 'object' | 'array' | 'boolean' | 'integer'; +export type SchemaType = + | 'string' + | 'number' + | 'object' + | 'array' + | 'boolean' + | 'integer'; type basicSchemaType = 'string' | 'number' | 'boolean' | 'integer'; diff --git a/packages/json-schema-editor/src/reducer/schema.ts b/packages/json-schema-editor/src/reducer/schema.ts index e14118b..2d76bf4 100644 --- a/packages/json-schema-editor/src/reducer/schema.ts +++ b/packages/json-schema-editor/src/reducer/schema.ts @@ -1,6 +1,12 @@ import produce, { Draft } from 'immer'; import { get, set, unset, remove } from 'lodash-es'; -import { SchemaType, SchemaItem, SchemaState, SchemaAction, KeyRoute } from '../model'; +import { + SchemaType, + SchemaItem, + SchemaState, + SchemaAction, + KeyRoute, +} from '../model'; import { defaultSchema, setAllFieldRequired } from '../utils/schema'; let fieldNum = 0; @@ -25,7 +31,11 @@ const removeRequired = (state: SchemaState, keyRoute: KeyRoute): void => { set(state, requiredKeyRoute, required); }; -const changeRequiredField = (state: SchemaState, oldKeyRoute: KeyRoute, newField: string): void => { +const changeRequiredField = ( + state: SchemaState, + oldKeyRoute: KeyRoute, + newField: string, +): void => { const oldField = oldKeyRoute.slice(-1)[0]; const requiredKeyRoute = oldKeyRoute.slice(0, -2).concat('required'); const required = get(state, requiredKeyRoute) || []; @@ -76,7 +86,11 @@ const removeField = (state: SchemaState, keyRoute: KeyRoute): void => { removeRequired(state, keyRoute); }; -const changeField = (state: SchemaState, keyRoute: KeyRoute, newField: string): void => { +const changeField = ( + state: SchemaState, + keyRoute: KeyRoute, + newField: string, +): void => { const oldField = keyRoute.slice(-1)[0]; const parentKeyRoute = keyRoute.slice(0, -1); const properties = get(state, parentKeyRoute); @@ -99,18 +113,30 @@ const changeField = (state: SchemaState, keyRoute: KeyRoute, newField: string): changeRequiredField(state, keyRoute, newField); }; -const changeType = (state: SchemaState, keyRoute: KeyRoute, fieldType: SchemaType): void => { +const changeType = ( + state: SchemaState, + keyRoute: KeyRoute, + fieldType: SchemaType, +): void => { // set field new value set(state, keyRoute, defaultSchema[fieldType]); }; -const changeTitle = (state: SchemaState, keyRoute: KeyRoute, title: string): void => { +const changeTitle = ( + state: SchemaState, + keyRoute: KeyRoute, + title: string, +): void => { // point to title and set new value const titleKeyRoute = keyRoute.concat('title'); set(state, titleKeyRoute, title); }; -const changeDesc = (state: SchemaState, keyRoute: KeyRoute, desc: string): void => { +const changeDesc = ( + state: SchemaState, + keyRoute: KeyRoute, + desc: string, +): void => { // point to desc and set new value const descKeyRoute = keyRoute.concat('description'); set(state, descKeyRoute, desc); diff --git a/packages/json-schema-editor/src/utils/schema.ts b/packages/json-schema-editor/src/utils/schema.ts index d94685b..c3f4149 100644 --- a/packages/json-schema-editor/src/utils/schema.ts +++ b/packages/json-schema-editor/src/utils/schema.ts @@ -25,9 +25,19 @@ export const defaultSchema = { }, }; -export const schemaType = ['string', 'number', 'array', 'object', 'boolean', 'integer']; +export const schemaType = [ + 'string', + 'number', + 'array', + 'object', + 'boolean', + 'integer', +]; -export const setAllFieldRequired = (schema: SchemaItem, checked: boolean): void => { +export const setAllFieldRequired = ( + schema: SchemaItem, + checked: boolean, +): void => { if (schema.type === 'object') { const { properties } = schema; const fields = Object.keys(properties);