diff --git a/docs/xflow/api.md b/docs/xflow/api.md index bdd2130e3..32fb46f0a 100644 --- a/docs/xflow/api.md +++ b/docs/xflow/api.md @@ -7,29 +7,30 @@ title: API ## XFlow -| 属性 | 描述 | 类型 | 默认值 | -| ----------------- | ------------------------------------------ | ----------------------------------------------------------- | ------ | -| initialValues | 初始的节点和边数据 | `{nodes:any[],edges:any[]}` | - | - | -| layout | 节点布局的方向 | `LR \| TB` | LR | - | -| widgets | 自定义组件 | `Record` | - | - | -| settings | 节点配置,定义页面中可拖动的节点配置 | ( [TNodeGroup](#tnodegroup) \| [TNodeItem](#tnodeitem) )[ ] | | -| nodeSelector | 节点选择器配置,可控制节点的可搜索性 | `TNodeSelector` | -| iconFontUrl | iconfont url,用于配置图标渲染 | `String` | | -| globalConfig | 全局的面板和节点配置 | {nodePanel:[TNodePanel](#tnodepanel),nodeView:[TNodeView](#tnodeview),edge:[TEdge](#tedge)} | | -| logPanel | 日志面板配置 | [TLogPanel](#tlogpanel) | | -| onNodeClick | 节点点击事件 | `NodeMouseHandler` | | -| antdVersion | antd 的版本 | `V4 \| V5` | `V5` | -| readOnly |只读模式 | `boolean` | `false` | +| 属性 | 描述 | 类型 | 默认值 | +| ------------- | ------------------------------------ | ------------------------------------------------------------------------------------------- | ------- | +| initialValues | 初始的节点和边数据 | `{nodes:any[],edges:any[]}` | - | - | +| layout | 节点布局的方向 | `LR \| TB` | LR | - | +| widgets | 自定义组件 | `Record` | - | - | +| settings | 节点配置,定义页面中可拖动的节点配置 | ( [TNodeGroup](#tnodegroup) \| [TNodeItem](#tnodeitem) )[ ] | | +| nodeSelector | 节点选择器配置,可控制节点的可搜索性 | `TNodeSelector` | +| iconFontUrl | iconfont url,用于配置图标渲染 | `String` | | +| globalConfig | 全局的面板和节点配置 | {nodePanel:[TNodePanel](#tnodepanel),nodeView:[TNodeView](#tnodeview),edge:[TEdge](#tedge)} | | +| logPanel | 日志面板配置 | [TLogPanel](#tlogpanel) | | +| onNodeClick | 节点点击事件 | `NodeMouseHandler` | | +| antdVersion | antd 的版本 | `V4 \| V5` | `V5` | +| readOnly | 只读模式 | `boolean` | `false` | +| onTesting | 单点调试方法 | `() => void` | | ## TNodePanel 面板相关配置 -| 属性 | 描述 | 类型 | 默认值 | -| ----- | ------------ | ------------- | ------ | -| width | 设置配置面板宽度 | `string \| number` | 400 | -| hideDesc | 是否在配置面板中显示节点的描述信息 | `boolean` | false | +| 属性 | 描述 | 类型 | 默认值 | +| -------- | ---------------------------------- | ------------------ | ------ | +| width | 设置配置面板宽度 | `string \| number` | 400 | +| hideDesc | 是否在配置面板中显示节点的描述信息 | `boolean` | false | @@ -37,18 +38,18 @@ title: API 节点相关配置 -| 属性 | 描述 | 类型 | 默认值 | -| ----- | ------------ | ------------- | ------ | -| hideTitleTips | 是否隐藏节点标题的tooltip描述信息提示 | `boolean` | false | -| status | 节点状态自定义配置,自定义节点不同状态的颜色展示。name:状态名称,color:颜色值。 | `Array<{name:string;color:string}>` | [] | +| 属性 | 描述 | 类型 | 默认值 | +| ------------- | ------------------------------------------------------------------------------ | ----------------------------------- | ------ | +| hideTitleTips | 是否隐藏节点标题的tooltip描述信息提示 | `boolean` | false | +| status | 节点状态自定义配置,自定义节点不同状态的颜色展示。name:状态名称,color:颜色值。 | `Array<{name:string;color:string}>` | [] | ## TEdge 边的全局配置 -| 属性 | 描述 | 类型 | 默认值 | -| ----- | ------------ | ------------- | ------ | -| hideEdgeAddBtn | 是否隐藏两个节点之间,连线上的增加节点按钮 | `boolean` | false | +| 属性 | 描述 | 类型 | 默认值 | +| -------------- | ------------------------------------------ | --------- | ------ | +| hideEdgeAddBtn | 是否隐藏两个节点之间,连线上的增加节点按钮 | `boolean` | false | ## TNodeGroup @@ -64,21 +65,21 @@ title: API 日志面板配置 -| 属性 | 描述 | 类型 | 默认值 | -| ----- | ------------ | ------------- | ------ | -| logList | 日志面板数据 | [TLogListItem](#tloglistitem) | | -| loading | 日志面板loading效果 | `boolean` | false | -| logWidget | 自定义日志面板展示 | `string` | | +| 属性 | 描述 | 类型 | 默认值 | +| --------- | ------------------- | ----------------------------- | ------ | +| logList | 日志面板数据 | [TLogListItem](#tloglistitem) | | +| loading | 日志面板loading效果 | `boolean` | false | +| logWidget | 自定义日志面板展示 | `string` | | ## TLogListItem 日志面板数据格式 -| 属性 | 描述 | 类型 | 默认值 | -| ----- | ------------ | ------------- | ------ | -| statusPanel | 日志面板数据,isBadge是否以badge形式展示状态 | `{status: Array<{ label: string; value?: string; isBadge?: boolean }>;extra?: string \| ReactNode}` | | -| codePanel | 代码面板数据渲染,如果没有 codePanel,则不渲染代码面板。title:代码面板标题,code:代码面板数据 | `Array<{ title: string; code: string }>` | | -| nodeId | 节点ID,必填 | `string` | | +| 属性 | 描述 | 类型 | 默认值 | +| ----------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | ------ | +| statusPanel | 日志面板数据,isBadge是否以badge形式展示状态 | `{status: Array<{ label: string; value?: string; isBadge?: boolean }>;extra?: string \| ReactNode}` | | +| codePanel | 代码面板数据渲染,如果没有 codePanel,则不渲染代码面板。title:代码面板标题,code:代码面板数据 | `Array<{ title: string; code: string }>` | | +| nodeId | 节点ID,必填 | `string` | | @@ -86,20 +87,22 @@ title: API 单个节点配置 -| 属性 | 描述 | 类型 | 默认值 | -| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | -| title | 节点名称 | `string` | | -| type | 节点类型 | `string` | | -| hidden | 是否在配置面板中显示节点 | `boolean` | false | -| targetHandleHidden | 是否隐藏左侧输入连接头 | `boolean` | false | -| sourceHandleHidden | 是否隐藏右侧输出连接头 | `boolean` | false | -| icon | 节点的图标配置 | `{type:string;bgColor:string}` | | -| iconSvg | 节点的图标配置Svg格式 | `SVGSVGElement` | | -| settingSchema | 节点的业务配置信息,详见[form-render 文档](/form-render/api-schema)。同时设置`settingSchema`和`settingWidget`只生效`settingWidget` | SchemaBase | | -| settingWidget | 自定义节点的业务配置组件,在弹窗中展示。同时设置`settingSchema`和`settingWidget`只生效`settingWidget`。定义之后需要在`widgets`中引入自定义组件。 | `string` | | -| settingWidgetProps | 用于向`settingWidget`自定义组件中传递自定义参数 | `object` | | -| nodeWidget | 自定义节点的业务配置信息展示组件,在节点内部展示业务配置信息。定义之后需要在`widgets`中引入自定义组件。 | `string` | | -| nodePanel | 自定义节点的面板配置信息 | [TNodePanel](#tnodepanel) | | +| 属性 | 描述 | 类型 | 默认值 | +| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | +| title | 节点名称 | `string` | | +| type | 节点类型 | `string` | | +| hidden | 是否在配置面板中显示节点 | `boolean` | false | +| targetHandleHidden | 是否隐藏左侧输入连接头 | `boolean` | false | +| sourceHandleHidden | 是否隐藏右侧输出连接头 | `boolean` | false | +| icon | 节点的图标配置 | `{type:string;bgColor:string}` | | +| iconSvg | 节点的图标配置Svg格式 | `SVGSVGElement` | | +| settingSchema | 节点的业务配置信息,详见[form-render 文档](/form-render/api-schema)。同时设置`settingSchema`和`settingWidget`只生效`settingWidget` | SchemaBase | | +| settingWidget | 自定义节点的业务配置组件,在弹窗中展示。同时设置`settingSchema`和`settingWidget`只生效`settingWidget`。定义之后需要在`widgets`中引入自定义组件。 | `string` | | +| settingWidgetProps | 用于向`settingWidget`自定义组件中传递自定义参数 | `object` | | +| nodeWidget | 自定义节点的业务配置信息展示组件,在节点内部展示业务配置信息。定义之后需要在`widgets`中引入自定义组件。 | `string` | | +| nodePanel | 自定义节点的面板配置信息 | [TNodePanel](#tnodepanel) | | +| switchExtra | 条件节几点属性配置 | [TSwitchExtra](#tswitchextra) | | + ## TNodeSelector @@ -107,3 +110,12 @@ title: API | ---------- | ---------------- | ----------------------------------------------------------- | ------ | | showSearch | 节点是否可被搜索 | `boolean` | false | | items | 节点配置 | ( [TNodeGroup](#tnodegroup) \| [TNodeItem](#tnodeitem) )[ ] | | + +## TSwitchExtra + +| 属性 | 描述 | 类型 | 默认值 | +| -------- | -------------------------------- | --------- | ------ | +| hideElse | 隐藏条件节点ELSE分支(默认分支) | `boolean` | false | +| valueKey | 自定义节点 value 的字段 | `string` | | +| titleKey | 自定义节点 title 的字段 | `string` | | + diff --git a/docs/xflow/demo/layout/LR/setting.tsx b/docs/xflow/demo/layout/LR/setting.tsx index 976edd3b9..5de7c4761 100644 --- a/docs/xflow/demo/layout/LR/setting.tsx +++ b/docs/xflow/demo/layout/LR/setting.tsx @@ -212,7 +212,7 @@ export const nodes = [ data: { list: [ { - _conditionId: 'iawoyh5niyi6zjob', + _id: 'iawoyh5niyi6zjob', }, ], }, @@ -259,8 +259,8 @@ export const edges = [ { type: 'buttonedge', source: 'b6zsd6w5ah2b209t', - sourceHandle: 'condition_else', + sourceHandle: 'id_else', target: '4', - id: 'xy-edge__b6zsd6w5ah2b209tcondition_else-4', + id: 'xy-edge__b6zsd6w5ah2b209tid_else-4', }, ]; diff --git a/docs/xflow/demo/layout/TB/setting.tsx b/docs/xflow/demo/layout/TB/setting.tsx index f07b58a57..775af2c55 100644 --- a/docs/xflow/demo/layout/TB/setting.tsx +++ b/docs/xflow/demo/layout/TB/setting.tsx @@ -217,7 +217,7 @@ export const nodes = [ data: { list: [ { - _conditionId: 'iawoyh5niyi6zjob', + _id: 'iawoyh5niyi6zjob', }, ], }, @@ -273,8 +273,8 @@ export const edges = [ { type: 'buttonedge', source: 'b6zsd6w5ah2b209t', - sourceHandle: 'condition_else', + sourceHandle: 'id_else', target: '4', - id: 'xy-edge__b6zsd6w5ah2b209tcondition_else-4', + id: 'xy-edge__b6zsd6w5ah2b209tid_else-4', }, ]; diff --git a/docs/xflow/demo/log/buildIn-log/index.tsx b/docs/xflow/demo/log/buildIn-log/index.tsx index d0c7d0034..956a6c677 100644 --- a/docs/xflow/demo/log/buildIn-log/index.tsx +++ b/docs/xflow/demo/log/buildIn-log/index.tsx @@ -46,11 +46,11 @@ export default () => { _status: 'warning', list: [ { - _parallelId: 'parallel_30ds0x3evus7ogo2', + _id: 'id_30ds0x3evus7ogo2', value: '事件1', }, { - _parallelId: 'parallel_m1l276eelcgn7s1p', + _id: 'id_m1l276eelcgn7s1p', value: '事件2', }, ], @@ -121,13 +121,13 @@ export default () => { id: 'ky0eedrd6t2hqq81', source: 'mcelcsg6pinydoy7', target: '4m9tee00n819nyyy', - sourceHandle: 'parallel_30ds0x3evus7ogo2', + sourceHandle: 'id_30ds0x3evus7ogo2', }, { id: '7tm5a339lj94ugtn', source: 'mcelcsg6pinydoy7', target: 'j0kufl0o4fca4ee9', - sourceHandle: 'parallel_m1l276eelcgn7s1p', + sourceHandle: 'id_m1l276eelcgn7s1p', }, { type: 'buttonedge', diff --git a/docs/xflow/demo/log/custom-log/index.tsx b/docs/xflow/demo/log/custom-log/index.tsx index 05067cfec..b9e4d2524 100644 --- a/docs/xflow/demo/log/custom-log/index.tsx +++ b/docs/xflow/demo/log/custom-log/index.tsx @@ -19,11 +19,11 @@ export default () => { _status: 'warning', list: [ { - _parallelId: 'parallel_30ds0x3evus7ogo2', + _id: 'id_30ds0x3evus7ogo2', value: '事件1', }, { - _parallelId: 'parallel_m1l276eelcgn7s1p', + _id: 'id_m1l276eelcgn7s1p', value: '事件2', }, ], @@ -81,13 +81,13 @@ export default () => { id: 'ky0eedrd6t2hqq81', source: 'mcelcsg6pinydoy7', target: '4m9tee00n819nyyy', - sourceHandle: 'parallel_30ds0x3evus7ogo2', + sourceHandle: 'id_30ds0x3evus7ogo2', }, { id: '7tm5a339lj94ugtn', source: 'mcelcsg6pinydoy7', target: 'j0kufl0o4fca4ee9', - sourceHandle: 'parallel_m1l276eelcgn7s1p', + sourceHandle: 'id_m1l276eelcgn7s1p', }, { type: 'buttonedge', diff --git a/docs/xflow/demo/log/index.tsx b/docs/xflow/demo/log/index.tsx index d0c7d0034..956a6c677 100644 --- a/docs/xflow/demo/log/index.tsx +++ b/docs/xflow/demo/log/index.tsx @@ -46,11 +46,11 @@ export default () => { _status: 'warning', list: [ { - _parallelId: 'parallel_30ds0x3evus7ogo2', + _id: 'id_30ds0x3evus7ogo2', value: '事件1', }, { - _parallelId: 'parallel_m1l276eelcgn7s1p', + _id: 'id_m1l276eelcgn7s1p', value: '事件2', }, ], @@ -121,13 +121,13 @@ export default () => { id: 'ky0eedrd6t2hqq81', source: 'mcelcsg6pinydoy7', target: '4m9tee00n819nyyy', - sourceHandle: 'parallel_30ds0x3evus7ogo2', + sourceHandle: 'id_30ds0x3evus7ogo2', }, { id: '7tm5a339lj94ugtn', source: 'mcelcsg6pinydoy7', target: 'j0kufl0o4fca4ee9', - sourceHandle: 'parallel_m1l276eelcgn7s1p', + sourceHandle: 'id_m1l276eelcgn7s1p', }, { type: 'buttonedge', diff --git a/docs/xflow/demo/nodeSetting/data.tsx b/docs/xflow/demo/nodeSetting/data.tsx index 9e321ab09..cb1603af5 100644 --- a/docs/xflow/demo/nodeSetting/data.tsx +++ b/docs/xflow/demo/nodeSetting/data.tsx @@ -177,7 +177,7 @@ export const nodes = [ data: { list: [ { - _conditionId: 'iawoyh5niyi6zjob', + _id: 'iawoyh5niyi6zjob', }, ], }, @@ -224,8 +224,8 @@ export const edges = [ { type: 'buttonedge', source: 'b6zsd6w5ah2b209t', - sourceHandle: 'condition_else', + sourceHandle: 'id_else', target: '4', - id: 'xy-edge__b6zsd6w5ah2b209tcondition_else-4', + id: 'xy-edge__b6zsd6w5ah2b209tid_else-4', }, ]; diff --git a/docs/xflow/demo/nodeSetting/index.tsx b/docs/xflow/demo/nodeSetting/index.tsx index cff756737..d5a944750 100644 --- a/docs/xflow/demo/nodeSetting/index.tsx +++ b/docs/xflow/demo/nodeSetting/index.tsx @@ -21,7 +21,7 @@ export const Flow = () => { nodeSelector={{ showSearch: true, }} - layout="TB" + // layout="TB" globalConfig={{ nodePanel: { width: '400px', diff --git a/docs/xflow/demo/parallelNode/custome/index.tsx b/docs/xflow/demo/parallelNode/custome/index.tsx index 278a84005..5f85366c1 100644 --- a/docs/xflow/demo/parallelNode/custome/index.tsx +++ b/docs/xflow/demo/parallelNode/custome/index.tsx @@ -16,12 +16,14 @@ export default () => { data: { list: [ { - _parallelId: 'parallel_30ds0x3evus7ogo2', + _id: 'id_30ds0x3evus7ogo2', value: '事件1', + title: "事件1" }, { - _parallelId: 'parallel_m1l276eelcgn7s1p', + _id: 'id_m1l276eelcgn7s1p', value: '事件2', + title: "事件1" }, ], }, @@ -71,13 +73,13 @@ export default () => { id: 'ky0eedrd6t2hqq81', source: 'mcelcsg6pinydoy7', target: '4m9tee00n819nyyy', - sourceHandle: 'parallel_30ds0x3evus7ogo2', + sourceHandle: 'id_30ds0x3evus7ogo2', }, { id: '7tm5a339lj94ugtn', source: 'mcelcsg6pinydoy7', target: 'j0kufl0o4fca4ee9', - sourceHandle: 'parallel_m1l276eelcgn7s1p', + sourceHandle: 'id_m1l276eelcgn7s1p', }, { type: 'buttonedge', diff --git a/docs/xflow/demo/parallelNode/index.tsx b/docs/xflow/demo/parallelNode/index.tsx index ba98d60b2..48d45d83e 100644 --- a/docs/xflow/demo/parallelNode/index.tsx +++ b/docs/xflow/demo/parallelNode/index.tsx @@ -10,12 +10,14 @@ export default () => { data: { list: [ { - _parallelId: 'parallel_30ds0x3evus7ogo2', + _id: 'id_30ds0x3evus7ogo2', value: '事件1', + title:"标题1" }, { - _parallelId: 'parallel_m1l276eelcgn7s1p', + _id: 'id_m1l276eelcgn7s1p', value: '事件2', + title: "标题2" }, ], }, @@ -65,13 +67,13 @@ export default () => { id: 'ky0eedrd6t2hqq81', source: 'mcelcsg6pinydoy7', target: '4m9tee00n819nyyy', - sourceHandle: 'parallel_30ds0x3evus7ogo2', + sourceHandle: 'id_30ds0x3evus7ogo2', }, { id: '7tm5a339lj94ugtn', source: 'mcelcsg6pinydoy7', target: 'j0kufl0o4fca4ee9', - sourceHandle: 'parallel_m1l276eelcgn7s1p', + sourceHandle: 'id_m1l276eelcgn7s1p', }, { type: 'buttonedge', diff --git a/docs/xflow/demo/switchNode/index.tsx b/docs/xflow/demo/switchNode/index.tsx index c6239afaa..6ae7350d9 100644 --- a/docs/xflow/demo/switchNode/index.tsx +++ b/docs/xflow/demo/switchNode/index.tsx @@ -1,6 +1,5 @@ import XFlow from '@xrenders/xflow'; import settings from './setting'; -import React from 'react'; export default () => { const nodes = [ @@ -22,16 +21,20 @@ export default () => { data: { list: [ { - _conditionId: 'condition_1nmzbhnbtv1se6sd', // 对应的 sourceHandle: 'condition_1nmzbhnbtv1se6sd'的边 + _id: 'id_1nmzbhnbtv1se6sd', // 对应的 sourceHandle: 'id_1nmzbhnbtv1se6sd'的边 value: '条件1', + name: "这里是条件一", + title:"默认title" }, { value: '条件2', - _conditionId: 'condition_enxhwfca1ebn55td', // 对应sourceHandle: 'condition_enxhwfca1ebn55td'的边 + _id: 'id_enxhwfca1ebn55td', // 对应sourceHandle: 'id_enxhwfca1ebn55td'的边 + name:"这里是条件一" }, { value: '条件3', - _conditionId: 'condition_z1f7b93zwbx1xycu',// 对应sourceHandle: 'condition_z1f7b93zwbx1xycu'的边 + _id: 'id_z1f7b93zwbx1xycu', // 对应sourceHandle: 'id_z1f7b93zwbx1xycu'的边 + name:'这里是条件一' }, ], desc: '', @@ -95,27 +98,27 @@ export default () => { }, { id: '5s6af77jbcqvzfod', - source: 'kshd2hp4vqm8ww19',// switch节点的边 + source: 'kshd2hp4vqm8ww19', // switch节点的边 target: 'ql61j2tdli4xage0', - sourceHandle: 'condition_1nmzbhnbtv1se6sd', // 对应 _conditionId为'condition_1nmzbhnbtv1se6sd'的条件 + sourceHandle: 'id_1nmzbhnbtv1se6sd', // 对应 _id为'id_1nmzbhnbtv1se6sd'的条件 }, { id: '6tw709qgc3mtazrv', - source: 'kshd2hp4vqm8ww19',// switch节点的边 + source: 'kshd2hp4vqm8ww19', // switch节点的边 target: 'fab1j735q8iow6u3', - sourceHandle: 'condition_enxhwfca1ebn55td', // 对应 _conditionId为'condition_enxhwfca1ebn55td'的条件 + sourceHandle: 'id_enxhwfca1ebn55td', // 对应 _id为'id_enxhwfca1ebn55td'的条件 }, { id: 'vzlvdo69ljcqegc8', - source: 'kshd2hp4vqm8ww19',// switch节点的边 + source: 'kshd2hp4vqm8ww19', // switch节点的边 target: '9mc5i628mfrxdow0', - sourceHandle: 'condition_z1f7b93zwbx1xycu',// 对应 _conditionId为'condition_z1f7b93zwbx1xycu'的条件 + sourceHandle: 'id_z1f7b93zwbx1xycu', // 对应 _id为'id_z1f7b93zwbx1xycu'的条件 }, { id: 'j8p8fnr5au9k25pb', - source: 'kshd2hp4vqm8ww19',// switch节点的边 + source: 'kshd2hp4vqm8ww19', // switch节点的边 target: 'anmv2kcadqxj4k63', - sourceHandle: 'condition_else',// condition_else 对应默认路径ELSE + sourceHandle: 'id_else', // id_else 对应默认路径ELSE }, { id: '0qfpkc9vcjdb31qp', diff --git a/docs/xflow/demo/switchNode/setting.tsx b/docs/xflow/demo/switchNode/setting.tsx index 10fbf6e33..0a3b892d9 100644 --- a/docs/xflow/demo/switchNode/setting.tsx +++ b/docs/xflow/demo/switchNode/setting.tsx @@ -7,6 +7,11 @@ export default [ type: 'icon-fenzhi', bgColor: '#06AED4', }, + switchExtra: { // 条件节点额外属性配置 + // hideElse: true, + valueKey: 'value', + titleKey: 'name' + } }, { title: '开始', diff --git a/docs/xflow/nodeBuildIn.md b/docs/xflow/nodeBuildIn.md index ac4e0e12e..549b46db5 100644 --- a/docs/xflow/nodeBuildIn.md +++ b/docs/xflow/nodeBuildIn.md @@ -11,14 +11,14 @@ group: ## 条件内置节点 内置条件节点,可以直接设置type为`Switch`使用。 -条件节点的数据格式为`data:{list:[{value:"条件1",_conditionId:"condition_${随机数}"}]}`,`_conditionId`为边数据的`sourceHandle`,以便条件和边一一对应。 -有条件参数value(可以通过自定义条件节点配置面板更改配置参数)的放入list数组里面作为`IF或者ELIF`渲染,没有条件参数的,为默认执行路径`ELSE`,`ELSE`路径的固定`_conditionId`为`condition_else`,即边数据的`sourceHandle`必须为`condition_else`才能链接`ELSE`链接头,比如: +条件节点的数据格式为`data:{list:[{value:"条件1",_id:"id_${随机数}"}]}`,`_id`为边数据的`sourceHandle`,以便条件和边一一对应。 +有条件参数value(可以通过自定义条件节点配置面板更改配置参数)的放入list数组里面作为`IF或者ELIF`渲染,没有条件参数的,为默认执行路径`ELSE`,`ELSE`路径的固定`_id`为`id_else`,即边数据的`sourceHandle`必须为`id_else`才能链接`ELSE`链接头,比如: ```js { id: 'j8p8fnr5au9k25pb', source: 'kshd2hp4vqm8ww19', target: 'anmv2kcadqxj4k63', - sourceHandle: 'condition_else', // else路径的边 + sourceHandle: 'id_else', // else路径的边 } ``` @@ -40,7 +40,7 @@ group: ## 并行节点 - 内置并行节点,可以直接设置type为`Parallel`使用,并行节点的数据格式为`data:{list:[{value:"条件1",_parallelId:"parallel_${随机数}"}]}`,`_parallelId`为边数据的`sourceHandle`,以便条件和边一一对应。 + 内置并行节点,可以直接设置type为`Parallel`使用,并行节点的数据格式为`data:{list:[{title:"事件一",value:"值1",_id:"id_${随机数}"}]}`,`_id`为边数据的`sourceHandle`,以便条件和边一一对应。 并行节点的每个连接头只能连接一个节点,不能连接多个节点,如果要更换节点,可以通过删除已连接节点或者在连接线上新增节点的方式更换目标节点。 diff --git a/packages/form-render-mobile/src/models/useForm.ts b/packages/form-render-mobile/src/models/useForm.ts index 14652d16f..07dbde683 100644 --- a/packages/form-render-mobile/src/models/useForm.ts +++ b/packages/form-render-mobile/src/models/useForm.ts @@ -73,7 +73,7 @@ const getFieldName = (_path: any): any => { const useForm = () => { const [form] = Form.useForm() as [FormInstance]; const flattenSchemaRef = useRef({}); - const storeRef: any = useRef(); + const storeRef: any = useRef(null); const schemaRef = useRef({}); const fieldRefs = useRef({}); diff --git a/packages/form-render-mobile/src/render-core/FieldItem/main.tsx b/packages/form-render-mobile/src/render-core/FieldItem/main.tsx index bf42dd4e5..9ea744b44 100644 --- a/packages/form-render-mobile/src/render-core/FieldItem/main.tsx +++ b/packages/form-render-mobile/src/render-core/FieldItem/main.tsx @@ -32,7 +32,7 @@ export default (props: any) => { const [needOnClick, setNeedOnClick] = useState(false); - const fieldRef: any = useRef(); + const fieldRef: any = useRef(null); const formCtx: any = useStore(store, (state: any) => state.context); const upperCtx: any = useContext(UpperContext); const configCtx = useContext(ConfigContext); diff --git a/packages/table-render/src/core/ToolbarView/InteriorTool/DensityIcon.tsx b/packages/table-render/src/core/ToolbarView/InteriorTool/DensityIcon.tsx index c46057bf5..c95ab432e 100644 --- a/packages/table-render/src/core/ToolbarView/InteriorTool/DensityIcon.tsx +++ b/packages/table-render/src/core/ToolbarView/InteriorTool/DensityIcon.tsx @@ -10,7 +10,7 @@ const DesityIcon = () => { const configCtx = useContext(ConfigProvider.ConfigContext); const t = translation(configCtx); - const dropRef = useRef(); // class组件用 React.createRef() + const dropRef = useRef(null); // class组件用 React.createRef() const tableSize = useTableStore((state) => state.tableSize); const setState = useTableStore((state) => state.setState); diff --git a/packages/table-render/src/index.tsx b/packages/table-render/src/index.tsx index 4d81e45c2..e0f6f9ac5 100644 --- a/packages/table-render/src/index.tsx +++ b/packages/table-render/src/index.tsx @@ -25,7 +25,7 @@ const TableRender = React.forwardRef((props, ref ...otherProps } = props; - const storeRef = React.useRef>>(); + const storeRef = React.useRef>>(null); if (!storeRef.current) { storeRef.current = createStore(); } diff --git a/packages/x-flow/package.json b/packages/x-flow/package.json index adf539e9a..9676b392c 100644 --- a/packages/x-flow/package.json +++ b/packages/x-flow/package.json @@ -1,6 +1,6 @@ { "name": "@xrenders/xflow", - "version": "1.0.2", + "version": "1.0.3-beta.1", "description": "一款功能强大、易用灵活的流程编辑器框架,帮助你轻松构建复杂的工作流和流程产品", "keywords": [ "xflow" diff --git a/packages/x-flow/src/XFlow.tsx b/packages/x-flow/src/XFlow.tsx index 9d2fa3687..96c452cf9 100644 --- a/packages/x-flow/src/XFlow.tsx +++ b/packages/x-flow/src/XFlow.tsx @@ -321,7 +321,7 @@ const XFlow: FC = memo(props => { onNodeClick={(event, node) => { onNodeClick && onNodeClick(event, node); }} - + deleteKeyCode={globalConfig?.deleteKeyCode} > diff --git a/packages/x-flow/src/components/CustomNode/index.tsx b/packages/x-flow/src/components/CustomNode/index.tsx index a0b003c08..fe9fa73d4 100644 --- a/packages/x-flow/src/components/CustomNode/index.tsx +++ b/packages/x-flow/src/components/CustomNode/index.tsx @@ -19,7 +19,8 @@ export default memo((props: any) => { const { widgets, settingMap, globalConfig, onMenuItemClick, antdVersion,readOnly } = useContext(ConfigContext); const deletable = globalConfig?.edge?.deletable ?? true; - + const disabledCopy = settingMap[type]?.disabledCopy ?? false + const disabledDelete = settingMap[type]?.disabledDelete ?? false // const isConnectableStart = globalConfig?.handle?.isConnectableStart ?? true; // const isConnectableEnd = globalConfig?.handle?.isConnectableEnd ?? true; @@ -146,7 +147,7 @@ export default memo((props: any) => { key: 'paste-' + i, index: i, id: id, - sourcehandle: r._conditionId, + sourcehandle: r._id, }; } else { return { @@ -154,7 +155,7 @@ export default memo((props: any) => { key: 'paste-' + i, id: id, index: i, - sourcehandle: r._conditionId, + sourcehandle: r._id, }; } }); @@ -166,7 +167,7 @@ export default memo((props: any) => { key: 'paste-' + (list.length + 1), id: id, index: list.length + 1, - sourcehandle: 'condition_else', + sourcehandle: 'id_else', }, ]; } @@ -184,11 +185,11 @@ export default memo((props: any) => { const menu = ( - 复制 + 复制 {menuItem.map((r: any) => { return {r.label}; })} - 删除 + 删除 ); @@ -200,12 +201,14 @@ export default memo((props: any) => { { label: '复制', key: 'copy', + disabled:disabledCopy }, ...menuItem, { label: '删除', key: 'delete', danger: true, + disabled:disabledDelete }, ], onClick: itemClick, diff --git a/packages/x-flow/src/components/FlowProvider/index.tsx b/packages/x-flow/src/components/FlowProvider/index.tsx index 8ca233099..5bbed34ac 100644 --- a/packages/x-flow/src/components/FlowProvider/index.tsx +++ b/packages/x-flow/src/components/FlowProvider/index.tsx @@ -4,28 +4,35 @@ import React, { memo, ReactNode, useContext, useEffect, useState } from 'react'; import { useStore } from '../../hooks/useStore'; import StoreContext, { Provider } from '../../models/context'; import { createStore } from '../../models/store'; -import { transformNodes } from '../../utils'; +import { transformNodes, transformSwitchNodes } from '../../utils'; export const FlowProvider = memo<{ initialNodes?: any[]; initialEdges?: any[]; children: ReactNode; layout?: 'LR' | 'TB'; -}>(({ initialNodes: nodes = [], initialEdges: edges = [], children, layout = 'LR' }) => { - const [store] = useState(() => - createStore({ - nodes, - edges, - layout - }) - ); +}>( + ({ + initialNodes: nodes = [], + initialEdges: edges = [], + children, + layout = 'LR', + }) => { + const [store] = useState(() => + createStore({ + nodes, + edges, + layout, + }) + ); - return ( - - {children} - - ); -}); + return ( + + {children} + + ); + } +); const InitialProvider = ({ nodes, edges, layout, children }) => { const { setNodes, setEdges, setLayout } = useStore(s => ({ @@ -54,19 +61,23 @@ export const FlowProviderWrapper = ({ nodes: any[]; edges: any[]; layout?: 'LR' | 'TB'; - }) => { +}) => { const isWrapped = useContext(StoreContext); if (isWrapped) { return ( - + {children} ); } return ( - + {children} ); diff --git a/packages/x-flow/src/components/NodeEditor/index.tsx b/packages/x-flow/src/components/NodeEditor/index.tsx index ccd6f2097..845947621 100644 --- a/packages/x-flow/src/components/NodeEditor/index.tsx +++ b/packages/x-flow/src/components/NodeEditor/index.tsx @@ -27,7 +27,7 @@ const NodeEditor: FC = (props: any) => { const [asyncSchema, setAsyncSchema] = useState({}); async function getSchema() { - const shema = await getSettingSchema(id, nodeType, form).catch(() => ({})); + const shema = await getSettingSchema(id, nodeType,nodeSetting,data,form).catch(() => ({})); setAsyncSchema(shema); } useEffect(() => { @@ -69,36 +69,22 @@ const NodeEditor: FC = (props: any) => { } if (node) { // 更新节点的 data - if (node?.data?._nodeType === 'Switch' && data?.list?.length) { + if ( + (node?.data?._nodeType === 'Switch' || + node?.data?._nodeType === 'Parallel') && + data?.list?.length + ) { data['list'] = (data?.list || [])?.map((item, index) => { - if (item?._conditionId) { + if (item?._id) { return item; } else { - if ( - node?.data?.list?.length && - node?.data?.list[index]?._conditionId - ) { + if (node?.data?.list?.length && node?.data?.list[index]?._id) { return { ...item, - _conditionId: node?.data?.list[index]?._conditionId, + _id: node?.data?.list[index]?._id, }; } else { - return { ...item, _conditionId: `condition_${uuid()}` }; - } - } - }); - } else if (node?.data?._nodeType === 'Parallel' && data?.list?.length) { - data['list'] = data?.list?.map((item, index) => { - if (item?._parallelId) { - return item; - } else { - if (node?.data?.list[index]?._parallelId) { - return { - ...item, - _parallelId: node?.data?.list[index]?._parallelId, - }; - } else { - return { ...item, _parallelId: `parallel_${uuid()}` }; + return { ...item, _id: `id_${uuid()}` }; } } }); @@ -139,7 +125,10 @@ const NodeEditor: FC = (props: any) => { readOnly={readOnly} /> ); - } else if (isFunction(getSettingSchema) && Object.keys(asyncSchema).length > 0) { + } else if ( + isFunction(getSettingSchema) && + Object.keys(asyncSchema).length > 0 + ) { return ( { const closeRef: any = useRef(null); const [open, setOpen] = useState(false); - const { settings, nodeSelector, antdVersion ,readOnly }: any = useContext(ConfigContext); + const { settings, nodeSelector, antdVersion ,readOnly ,clickAddNode,settingMap }: any = useContext(ConfigContext); const { showSearch, popoverProps = { placement: 'top' } } = nodeSelector || {}; @@ -41,13 +42,20 @@ export default forwardRef((props: any, popoverRef) => { }, ref); const handCreateNode = useCallback(({ type }) => { - if (type === 'Switch') { - addNode({ _nodeType: type, list: [{ '_conditionId':`${uuid()}`}] }); - } else if (type === 'Parallel') { - addNode({ _nodeType: type, list: [{ _parallelId: `parallel_${uuid()}` }, { _parallelId: `parallel_${uuid()}` }] }); - } else { - addNode({ _nodeType: type }); + if (isFunction(clickAddNode)) { + clickAddNode(type,settingMap[type],( data = {} )=>{ + addNode({ _nodeType: type, ...data }) + }); + }else{ + if (type === 'Switch') { + addNode({ _nodeType: type, list: [{ '_id':`${uuid()}`}] }); + } else if (type === 'Parallel') { + addNode({ _nodeType: type, list: [{ _id: `id_${uuid()}` }, { _id: `id_${uuid()}` }] }); + } else { + addNode({ _nodeType: type }); + } } + setOpen(false); onNodeSelectPopoverChange && onNodeSelectPopoverChange(false); }, []); @@ -56,7 +64,7 @@ export default forwardRef((props: any, popoverRef) => { setTimeout(() => { setIsAddingNode(true); closeRef.current = true; - if(!readOnly){ + if (!readOnly) { setOpen(true); } }, 50); diff --git a/packages/x-flow/src/components/PanelContainer/index.tsx b/packages/x-flow/src/components/PanelContainer/index.tsx index 50c02cf59..a0ababc98 100644 --- a/packages/x-flow/src/components/PanelContainer/index.tsx +++ b/packages/x-flow/src/components/PanelContainer/index.tsx @@ -5,7 +5,7 @@ import React, { FC, useContext, useEffect, useMemo, useState } from 'react'; import { shallow } from 'zustand/shallow'; import { useStore } from '../../hooks/useStore'; import { ConfigContext } from '../../models/context'; -import { safeJsonStringify } from '../../utils'; +import { safeJsonStringify } from '../../utils'; import createIconFont from '../../utils/createIconFont'; import IconView from '../IconView'; import './index.less'; @@ -41,8 +41,14 @@ const Panel: FC = (props: IPanelProps) => { openLogPanel, } = props; // 1.获取节点配置信息 - const { settingMap, iconFontUrl, globalConfig, antdVersion,readOnly }: any = - useContext(ConfigContext); + const { + settingMap, + iconFontUrl, + globalConfig, + antdVersion, + readOnly, + onTesting, + }: any = useContext(ConfigContext); const nodeSetting = settingMap[nodeType] || {}; const { nodes, setNodes } = useStore( (state: any) => ({ @@ -75,7 +81,7 @@ const Panel: FC = (props: IPanelProps) => { node.data = { ...node.data, ...data }; } }); - setNodes(newNodes,false); + setNodes(newNodes, false); }, 100); useEffect(() => { @@ -143,7 +149,7 @@ const Panel: FC = (props: IPanelProps) => {
- {!isDisabled && ( + {!isDisabled && onTesting && ( <> diff --git a/packages/x-flow/src/nodes/node-parallel/ParallelBuildInNodeWidget.tsx b/packages/x-flow/src/nodes/node-parallel/ParallelBuildInNodeWidget.tsx index 48778c689..a667622b8 100644 --- a/packages/x-flow/src/nodes/node-parallel/ParallelBuildInNodeWidget.tsx +++ b/packages/x-flow/src/nodes/node-parallel/ParallelBuildInNodeWidget.tsx @@ -33,6 +33,78 @@ export default memo((props: any) => { shallow ); + const renderTitle = (item, index) => ( +
+
+ {item?.title && ( + + document.getElementById('xflow-container'), + }, + }} + > + {item?.title} + + )} +
+ flow?.sourceHandle === item?._id) + ?.length === 0 + } + selected={selected} + isHovered={isHovered} + handleAddNode={data => { + handleAddNode(data, item?._id); + }} + id={item?._id} + className="item-handle" + /> +
+ ); + + const renderContent = (item, index) => ( +
+ {CustomNodeWidget ? ( + + ) : ( + <> + {item?.value && ( + + document.getElementById('xflow-container'), + }, + }} + > + {item?.value} + + )} + + )} +
+ ); + return ( { })} size={5} > - {( - data?.list || [ - { _parallelId: `parallel_${uuid()}` }, - { _parallelId: `parallel_${uuid()}` }, - ] - )?.map((item, index) => ( -
-
-
- {CustomNodeWidget ? ( - - ) : ( - <> - {item?.value && ( - - document.getElementById('xflow-container'), - }, - }} - > - {item?.value} - - )} - - )} -
- flow?.sourceHandle === item?._parallelId - )?.length === 0 - } - selected={selected} - isHovered={isHovered} - handleAddNode={data => { - handleAddNode(data, item?._parallelId); - }} - id={item?._parallelId} - className="item-handle" - /> + {(data?.list || [{ _id: `id_${uuid()}` }, { _id: `id_${uuid()}` }])?.map( + (item, index) => ( +
+ {isSwitchBottom ? ( + <> + {renderContent(item, index)} + {renderTitle(item, index)} + + ) : ( + <> + {renderTitle(item, index)} + {renderContent(item, index)} + + )}
-
- ))} + ) + )} ); }); diff --git a/packages/x-flow/src/nodes/node-parallel/index.less b/packages/x-flow/src/nodes/node-parallel/index.less index b7186d5c7..2c8f664f7 100644 --- a/packages/x-flow/src/nodes/node-parallel/index.less +++ b/packages/x-flow/src/nodes/node-parallel/index.less @@ -35,7 +35,7 @@ .item-title { text-align: right; font-weight: 600; - min-height: 30px; + min-height: 28px; .ant-typography { margin-bottom: 0; diff --git a/packages/x-flow/src/nodes/node-parallel/setting/index.tsx b/packages/x-flow/src/nodes/node-parallel/setting/index.tsx index 512d6ac0e..ebe3fe2f9 100644 --- a/packages/x-flow/src/nodes/node-parallel/setting/index.tsx +++ b/packages/x-flow/src/nodes/node-parallel/setting/index.tsx @@ -11,14 +11,14 @@ interface INodeSwitchSettingPorps { const schema: Schema = { type: 'object', - span: 24, - displayType: 'row', + displayType:'row', + // span: 24, properties: { list: { type: 'array', widget: 'simpleList', - display: 'block', - min: 2, + // display: 'block', + // min: 2, default:[{},{}], props: { hideCopy: true, @@ -27,9 +27,21 @@ const schema: Schema = { items: { type: 'object', properties: { + title: { + title: '标题', + type: 'string', + props: { + allowClear:true + }, + span:6 + }, value: { title: '事件', type: 'string', + props: { + allowClear: true + }, + span: 6 }, }, }, diff --git a/packages/x-flow/src/nodes/node-switch/SwitchBuildInNodeWidget.tsx b/packages/x-flow/src/nodes/node-switch/SwitchBuildInNodeWidget.tsx index 5c043742b..7e186316b 100644 --- a/packages/x-flow/src/nodes/node-switch/SwitchBuildInNodeWidget.tsx +++ b/packages/x-flow/src/nodes/node-switch/SwitchBuildInNodeWidget.tsx @@ -19,7 +19,9 @@ export default memo((props: any) => { handleAddNode, CustomNodeWidget, isSwitchBottom, + nodeSetting, } = props; + const { switchExtra } = nodeSetting; const { nodes, edges } = useStore( (state: any) => ({ @@ -31,55 +33,64 @@ export default memo((props: any) => { const renderTitle = (item, index) => (
-
{index === 0 ? 'IF' : 'ELIF'}
+
+ {switchExtra?.titleKey + ? item[switchExtra?.titleKey] + : item?.title || `条件${index}`} +
flow?.sourceHandle === item?._conditionId - )?.length === 0 + (edges || [])?.filter(flow => flow?.sourceHandle === item?._id) + ?.length === 0 } selected={selected} isHovered={isHovered} handleAddNode={data => { - handleAddNode(data, item?._conditionId); + handleAddNode(data, item?._id); }} - id={item?._conditionId} + id={item?._id} className="item-handle" />
); - const renderContent = (item, index) => ( -
- {CustomNodeWidget ? ( - - ) : ( - <> - {item?.value && ( - { + const value = switchExtra?.valueKey + ? item[switchExtra?.valueKey] + : item?.value; + + return ( +
+ {CustomNodeWidget ? ( + + ) : ( + <> + {value && ( + + document.getElementById('xflow-container'), }, - getPopupContainer: () => - document.getElementById('xflow-container'), - }, - }} - > - {item?.value} - - )} - - )} -
- ); + }} + > + {value} +
+ )} + + )} +
+ ); + }; return ( { })} size={5} > - {(data?.list || [{ _conditionId: `condition_${uuid()}` }])?.map( - (item, index) => ( -
- {isSwitchBottom ? ( - <> - {renderContent(item, index)} - {renderTitle(item, index)} - - ) : ( - <> - {renderTitle(item, index)} - {renderContent(item, index)} - - )} + {(data?.list || [{ _id: `id_${uuid()}` }])?.map((item, index) => ( +
+ {isSwitchBottom ? ( + <> + {renderContent(item, index)} + {renderTitle(item, index)} + + ) : ( + <> + {renderTitle(item, index)} + {renderContent(item, index)} + + )} +
+ ))} + {!switchExtra?.hideElse && ( +
+
+
默认
+ flow?.sourceHandle === 'id_else') + ?.length === 0 + } + selected={selected} + isHovered={isHovered} + handleAddNode={data => { + handleAddNode(data, 'id_else'); + }} + className="item-handle" + id={'id_else'} + />
- ) - )} -
-
-
ELSE
- flow?.sourceHandle === 'condition_else' - )?.length === 0 - } - selected={selected} - isHovered={isHovered} - handleAddNode={data => { - handleAddNode(data, 'condition_else'); - }} - className="item-handle" - id={'condition_else'} - />
-
+ )} ); }); diff --git a/packages/x-flow/src/nodes/node-switch/setting/index.tsx b/packages/x-flow/src/nodes/node-switch/setting/index.tsx index 671255651..f314651cf 100644 --- a/packages/x-flow/src/nodes/node-switch/setting/index.tsx +++ b/packages/x-flow/src/nodes/node-switch/setting/index.tsx @@ -40,7 +40,6 @@ const schema: Schema = { export default memo((props: INodeSwitchSettingPorps) => { const form = useForm(); const { onChange, value } = props; - console.log('%cprops', 'background-color: darkorange', props); const watch = { '#': (allValues: any) => { diff --git a/packages/x-flow/src/types.ts b/packages/x-flow/src/types.ts index f73041fbc..1f86bdc5c 100644 --- a/packages/x-flow/src/types.ts +++ b/packages/x-flow/src/types.ts @@ -22,7 +22,14 @@ export interface TNodeItem { width?: string | number; // 配置面板宽度 hideDesc?: boolean; // 配置面板描述 }; - getSettingSchema?:(nodeId:string,nodeType:string,form:ReturnType)=>Promise + getSettingSchema?: (nodeId: string, nodeType: string, nodeItem:TNodeItem,nodeData:any,form: ReturnType) => Promise; + switchExtra: { // 条件节点额外属性配置 + hideElse: boolean; + valueKey: string; + titleKey: string; + } + disabledCopy:boolean + disabledDelete:boolean } export interface TNodeGroup { @@ -119,12 +126,16 @@ export interface FlowProps { edge?: TEdge; controls?:TControl handle?:THandle + deleteKeyCode?:string | string[] | null }; logPanel?: TLogPanel; // 日志面板配置 readOnly?:boolean//只读模式 panel?:TPanel //表单配置面板 onNodeClick?: NodeMouseHandler; - onMenuItemClick: (itemInfo: ItemInfo,defaultAction:()=>void) => void; + onMenuItemClick?: (itemInfo: ItemInfo, defaultAction: () => void) => void; + clickAddNode?:(type:string,nodeItem:TNodeItem,addNode:(initData?:Record)=>void)=>void + // 单点调试方法 + onTesting?: () => void;// 单点调试方法 } interface ItemInfo { key: 'copy' | 'paste' | 'delete' | string; diff --git a/packages/x-flow/src/utils/index.ts b/packages/x-flow/src/utils/index.ts index ead26ec47..8c3c0ffdb 100644 --- a/packages/x-flow/src/utils/index.ts +++ b/packages/x-flow/src/utils/index.ts @@ -3,7 +3,18 @@ import tinycolor from 'tinycolor2'; export const uuid = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 16); export const uuid4 = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 4); -import { isMatch, some, set, get, cloneDeep, has as _has, merge, mergeWith, isUndefined, omitBy } from 'lodash-es'; +import { + has as _has, + cloneDeep, + get, + isMatch, + isUndefined, + merge, + mergeWith, + omitBy, + set, + some, +} from 'lodash-es'; export const _set = set; export const _get = get; @@ -160,14 +171,58 @@ export const capitalize = (string: string) => { export const transformNodes = (nodes: any[]) => { return nodes?.map(item => { const { type, data, ...rest } = item; - return { - type: 'custom', - data: { - ...data, - _nodeType: type, - }, - ...rest, - }; + + if (type === 'Switch' || type === 'Parallel') { + return { + type: 'custom', + data: { + ...data, + _nodeType: type, + ...(data?.list?.length && { + list: (data?.list || [])?.map(n => { + if (n?._id) { + return n; + } else { + return { ...n, _id: `id_${uuid()}` }; + } + }), + }), + }, + ...rest, + }; + } else { + return { + type: 'custom', + data: { + ...data, + _nodeType: type, + }, + ...rest, + }; + } + }); +}; + +export const transformSwitchNodes = (nodes: any[]) => { + return (nodes || [])?.map(item => { + if (item?.type === 'Switch' || item?.type === 'Parallel') { + const { list, ...rest } = item?.data; + return { + ...item, + data: { + ...rest, + list: (list || [])?.map(item => { + if (item?._id) { + return item; + } else { + return { ...item, _id: `id_${uuid()}` }; + } + }), + }, + }; + } else { + return item; + } }); }; @@ -222,33 +277,35 @@ export function safeJsonStringify(obj: Object) { } } -export * from './flow' +export * from './flow'; // 内置节点状态 export const NODE_STATUS = { success: { color: '#52c41a', - name:"成功" + name: '成功', }, error: { color: '#ff4d4f', - name:"失败" + name: '失败', }, warning: { color: '#faad14', - name:"告警" + name: '告警', }, }; export const transformNodeStatus = (statusList = []) => { const obj: Record = {}; - statusList?.forEach((status: { name: string; color: string; value: string; }) => { - if (status?.value && status?.color) - obj[status.value] = { - color: status.color, - name:status?.name - }; - }); + statusList?.forEach( + (status: { name: string; color: string; value: string }) => { + if (status?.value && status?.color) + obj[status.value] = { + color: status.color, + name: status?.name, + }; + } + ); return { ...NODE_STATUS, @@ -257,7 +314,7 @@ export const transformNodeStatus = (statusList = []) => { }; // 处理颜色值 -export function getTransparentColor(colorInput:string,alpha:number) { +export function getTransparentColor(colorInput: string, alpha: number) { const color = tinycolor(colorInput); const alphaNum = Number(alpha); if (!color.isValid()) { @@ -267,4 +324,3 @@ export function getTransparentColor(colorInput:string,alpha:number) { // 返回 RGBA 格式的颜色字符串 return color.toRgbString(); } - diff --git a/packages/x-flow/src/withProvider.tsx b/packages/x-flow/src/withProvider.tsx index 49d96b2e9..5a58a23a9 100644 --- a/packages/x-flow/src/withProvider.tsx +++ b/packages/x-flow/src/withProvider.tsx @@ -32,6 +32,8 @@ export default function withProvider( onMenuItemClick, antdVersion ='V5', readOnly, + clickAddNode, + onTesting, ...restProps } = props; const settingMap = useMemo(() => { @@ -59,10 +61,12 @@ export default function withProvider( antdVersion, onMenuItemClick, readOnly, + clickAddNode, widgets: { ...defaultWidgets, ...widgets, }, + onTesting }; return (