mirror of
https://gitee.com/ByteDance/flowgram.ai.git
synced 2025-07-07 17:43:29 +08:00
feat(docs): add custom layer docs (#383)
This commit is contained in:
parent
fd423d9cb5
commit
77d8a893cb
@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
|
|
||||||
import { WorkflowDragService, useService } from '@flowgram.ai/free-layout-editor';
|
import { WorkflowDragService, useService } from '@flowgram.ai/free-layout-editor';
|
||||||
|
|
||||||
const cardkeys = ['Node1', 'Node2'];
|
const cardkeys = ['Node1', 'Node2', 'Condition'];
|
||||||
|
|
||||||
export const NodeAddPanel: React.FC = (props) => {
|
export const NodeAddPanel: React.FC = (props) => {
|
||||||
const startDragSerivce = useService<WorkflowDragService>(WorkflowDragService);
|
const startDragSerivce = useService<WorkflowDragService>(WorkflowDragService);
|
||||||
@ -14,7 +14,7 @@ export const NodeAddPanel: React.FC = (props) => {
|
|||||||
key={nodeType}
|
key={nodeType}
|
||||||
className="demo-free-card"
|
className="demo-free-card"
|
||||||
onMouseDown={(e) =>
|
onMouseDown={(e) =>
|
||||||
startDragSerivce.startDragCard(nodeType, e, {
|
startDragSerivce.startDragCard(nodeType.toLowerCase(), e, {
|
||||||
data: {
|
data: {
|
||||||
title: `New ${nodeType}`,
|
title: `New ${nodeType}`,
|
||||||
content: 'xxxx',
|
content: 'xxxx',
|
||||||
|
|||||||
@ -86,10 +86,24 @@ export const useEditorProps = () =>
|
|||||||
* Render Node
|
* Render Node
|
||||||
*/
|
*/
|
||||||
renderDefaultNode: (props: WorkflowNodeProps) => {
|
renderDefaultNode: (props: WorkflowNodeProps) => {
|
||||||
const { form } = useNodeRender();
|
const { form, node } = useNodeRender();
|
||||||
return (
|
return (
|
||||||
<WorkflowNodeRenderer className="demo-free-node" node={props.node}>
|
<WorkflowNodeRenderer className="demo-free-node" node={props.node}>
|
||||||
{form?.render()}
|
{form?.render()}
|
||||||
|
{node.flowNodeType === 'condition' && (
|
||||||
|
<div
|
||||||
|
data-port-id="if"
|
||||||
|
data-port-type="output"
|
||||||
|
style={{ position: 'absolute', right: 0, top: '33%' }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{node.flowNodeType === 'condition' && (
|
||||||
|
<div
|
||||||
|
data-port-id="else"
|
||||||
|
data-port-type="output"
|
||||||
|
style={{ position: 'absolute', right: 0, top: '66%' }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</WorkflowNodeRenderer>
|
</WorkflowNodeRenderer>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -98,7 +112,7 @@ export const useEditorProps = () =>
|
|||||||
* Content change
|
* Content change
|
||||||
*/
|
*/
|
||||||
onContentChange(ctx, event) {
|
onContentChange(ctx, event) {
|
||||||
// console.log('Auto Save: ', event, ctx.document.toJSON());
|
console.log('Auto Save: ', event, ctx.document.toJSON());
|
||||||
},
|
},
|
||||||
// /**
|
// /**
|
||||||
// * Node engine enable, you can configure formMeta in the FlowNodeRegistry
|
// * Node engine enable, you can configure formMeta in the FlowNodeRegistry
|
||||||
|
|||||||
@ -6,7 +6,10 @@ export const initialData: WorkflowJSON = {
|
|||||||
id: 'start_0',
|
id: 'start_0',
|
||||||
type: 'start',
|
type: 'start',
|
||||||
meta: {
|
meta: {
|
||||||
position: { x: 0, y: 0 },
|
position: {
|
||||||
|
x: 150,
|
||||||
|
y: 100,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
title: 'Start',
|
title: 'Start',
|
||||||
@ -15,26 +18,60 @@ export const initialData: WorkflowJSON = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'node_0',
|
id: 'node_0',
|
||||||
type: 'custom',
|
type: 'condition',
|
||||||
meta: {
|
meta: {
|
||||||
position: { x: 400, y: 0 },
|
position: {
|
||||||
|
x: 550,
|
||||||
|
y: 100,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
title: 'Custom',
|
title: 'Condition',
|
||||||
content: 'Custom node content',
|
content: 'Condition node content',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'end_0',
|
id: 'end_0',
|
||||||
type: 'end',
|
type: 'end',
|
||||||
meta: {
|
meta: {
|
||||||
position: { x: 800, y: 0 },
|
position: {
|
||||||
|
x: 1350,
|
||||||
|
y: 100,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data: {
|
data: {
|
||||||
title: 'End',
|
title: 'End',
|
||||||
content: 'End content',
|
content: 'End content',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: '144150',
|
||||||
|
type: 'node1',
|
||||||
|
meta: {
|
||||||
|
position: {
|
||||||
|
x: 950,
|
||||||
|
y: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
title: 'New Node1',
|
||||||
|
content: 'xxxx',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '118937',
|
||||||
|
type: 'node2',
|
||||||
|
meta: {
|
||||||
|
position: {
|
||||||
|
x: 950,
|
||||||
|
y: 200,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
title: 'New Node2',
|
||||||
|
content: 'xxxx',
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
edges: [
|
edges: [
|
||||||
{
|
{
|
||||||
@ -43,6 +80,20 @@ export const initialData: WorkflowJSON = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
sourceNodeID: 'node_0',
|
sourceNodeID: 'node_0',
|
||||||
|
targetNodeID: '144150',
|
||||||
|
sourcePortID: 'if',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sourceNodeID: 'node_0',
|
||||||
|
targetNodeID: '118937',
|
||||||
|
sourcePortID: 'else',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sourceNodeID: '118937',
|
||||||
|
targetNodeID: 'end_0',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sourceNodeID: '144150',
|
||||||
targetNodeID: 'end_0',
|
targetNodeID: 'end_0',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@ -14,6 +14,13 @@ export const nodeRegistries: WorkflowNodeRegistry[] = [
|
|||||||
defaultPorts: [{ type: 'output' }], // Used to define the input and output ports, the start node only has the output port
|
defaultPorts: [{ type: 'output' }], // Used to define the input and output ports, the start node only has the output port
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'condition',
|
||||||
|
meta: {
|
||||||
|
defaultPorts: [{ type: 'input' }],
|
||||||
|
useDynamicPort: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'end',
|
type: 'end',
|
||||||
meta: {
|
meta: {
|
||||||
|
|||||||
@ -6286,14 +6286,14 @@ url: /guide/advanced/free-layout/port.md
|
|||||||
|
|
||||||
* 动态端口
|
* 动态端口
|
||||||
|
|
||||||
节点声明添加 `dynamicPorts` , 当设置为 true 则会到节点dom 上寻找 data-port-id 和 data-port-type 属性的 dom 作为端口
|
节点声明添加 `useDynamicPort` , 当设置为 true 则会到节点dom 上寻找 data-port-id 和 data-port-type 属性的 dom 作为端口
|
||||||
|
|
||||||
```ts pure title="node-registries.ts"
|
```ts pure title="node-registries.ts"
|
||||||
{
|
{
|
||||||
type: 'condition',
|
type: 'condition',
|
||||||
meta: {
|
meta: {
|
||||||
defaultPorts: [{ type: 'input'}]
|
defaultPorts: [{ type: 'input'}]
|
||||||
dynamicPort: true
|
useDynamicPort: true
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7528,7 +7528,7 @@ export const useEditorProps = () => {
|
|||||||
return {
|
return {
|
||||||
// ...
|
// ...
|
||||||
nodeEngine: {
|
nodeEngine: {
|
||||||
enable: false, // 不开启节点引擎,则无法使用 from
|
enable: false, // 不开启节点引擎,则无法使用 form
|
||||||
},
|
},
|
||||||
history: {
|
history: {
|
||||||
enable: true,
|
enable: true,
|
||||||
@ -8745,7 +8745,7 @@ export const nodeRegistries: WorkflowNodeRegistry[] = [
|
|||||||
deleteDisable: true, // 开始节点不能删除
|
deleteDisable: true, // 开始节点不能删除
|
||||||
copyDisable: true, // 开始节点不能复制
|
copyDisable: true, // 开始节点不能复制
|
||||||
defaultPorts: [{ type: 'output' }], // 用于定义节点的输入和输出端口, 开始节点只有输出端口
|
defaultPorts: [{ type: 'output' }], // 用于定义节点的输入和输出端口, 开始节点只有输出端口
|
||||||
// dynamicPort: true, // 用于动态端口,会寻找 data-port-id 和 data-port-type 属性的 dom 作为端口
|
// useDynamicPort: true, // 用于动态端口,会寻找 data-port-id 和 data-port-type 属性的 dom 作为端口
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 配置节点表单的校验及渲染,
|
* 配置节点表单的校验及渲染,
|
||||||
|
|||||||
@ -21,5 +21,6 @@
|
|||||||
"minimap",
|
"minimap",
|
||||||
"custom-plugin",
|
"custom-plugin",
|
||||||
"custom-service",
|
"custom-service",
|
||||||
|
"custom-layer",
|
||||||
"form-materials"
|
"form-materials"
|
||||||
]
|
]
|
||||||
|
|||||||
113
apps/docs/src/en/guide/advanced/custom-layer.mdx
Normal file
113
apps/docs/src/en/guide/advanced/custom-layer.mdx
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
# Custom Layer
|
||||||
|
|
||||||
|
We split the canvas into multiple Layers, implementing the concept of interaction layering for better plugin management. For more details, see [Canvas Engine](guide/concepts/canvas-engine.html)
|
||||||
|
|
||||||
|
1. Use `observeEntityDatas`, `observeEntities`, and `observeEntity` to monitor updates to any data module of canvas nodes
|
||||||
|
2. Use `onZoom`, `onScroll`, `onViewportChange`, etc. to monitor canvas zooming or scrolling
|
||||||
|
3. Use `render` to insert React elements into the canvas, such as drawing SVG lines
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Creating a Layer
|
||||||
|
|
||||||
|
```tsx pure
|
||||||
|
import { FreeLayoutPluginContext, inject, injectable, FlowNodeEntity, FlowNodeTransformData, FlowNodeFormData } from '@flowgram.ai/free-layout-editor'
|
||||||
|
|
||||||
|
@injectable()
|
||||||
|
export class MyLayer extends Layer {
|
||||||
|
@inject(FreeLayoutPluginContext) ctx: FreeLayoutPluginContext
|
||||||
|
// Can monitor node width, height, and position changes
|
||||||
|
@observeEntityDatas(FlowNodeEntity, FlowNodeTransformData) transformDatas: FlowNodeTransformData[];
|
||||||
|
// Can monitor form data changes, connection data can be stored in forms
|
||||||
|
@observeEntityDatas(FlowNodeEntity, FlowNodeFormData) formDatas: FlowNodeFormData[];
|
||||||
|
onReady() {
|
||||||
|
// Can also add styles
|
||||||
|
// zIndex controls whether to overlay nodes, nodes default to 10, greater than 10 will be above nodes
|
||||||
|
this.node.style.zIndex = 11;
|
||||||
|
}
|
||||||
|
onZoom(scale) {
|
||||||
|
// Scale with canvas
|
||||||
|
this.node.style.transform = `scale(${scale})`;
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return <div>{...}</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adding to Canvas
|
||||||
|
|
||||||
|
- Through use-editor-props
|
||||||
|
|
||||||
|
```ts pure
|
||||||
|
{
|
||||||
|
onInit: (ctx) => {
|
||||||
|
ctx.playground.registerLayer(MyLayer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Through plugin
|
||||||
|
|
||||||
|
```tsx pure
|
||||||
|
import { FreeLayoutPluginContext } from '@flowgram.ai/free-layout-editor'
|
||||||
|
|
||||||
|
export const createMyPlugin = definePluginCreator<{}, FreeLayoutPluginContext>({
|
||||||
|
onInit: (ctx, opts) => {
|
||||||
|
ctx.playground.registerLayer(MyLayer)
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Layer Lifecycle Description
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface Layer {
|
||||||
|
/**
|
||||||
|
* Triggered during initialization
|
||||||
|
*/
|
||||||
|
onReady?(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggered when playground size changes
|
||||||
|
*/
|
||||||
|
onResize?(size: PipelineDimension): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggered when playground is focused
|
||||||
|
*/
|
||||||
|
onFocus?(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggered when playground loses focus
|
||||||
|
*/
|
||||||
|
onBlur?(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor zoom
|
||||||
|
*/
|
||||||
|
onZoom?(scale: number): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitor scroll
|
||||||
|
*/
|
||||||
|
onScroll?(scroll: { scrollX: number; scrollY: number }): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggered when viewport updates
|
||||||
|
*/
|
||||||
|
onViewportChange?(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggered when readonly or disabled state changes
|
||||||
|
* @param state
|
||||||
|
*/
|
||||||
|
onReadonlyOrDisabledChange?(state: { disabled: boolean; readonly: boolean }): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data updates automatically trigger React render, if not provided React rendering won't be called
|
||||||
|
*/
|
||||||
|
render?(): JSX.Element
|
||||||
|
}
|
||||||
|
```
|
||||||
@ -22,7 +22,7 @@ Add `defaultPorts` to node declaration, such as `{ type: 'input' }`, which will
|
|||||||
|
|
||||||
- Dynamic Ports
|
- Dynamic Ports
|
||||||
|
|
||||||
Add `dynamicPorts` to node declaration, when set to true it will look for DOM elements with `data-port-id` and `data-port-type` attributes as ports
|
Add `useDynamicPort` to node declaration, when set to true it will look for DOM elements with `data-port-id` and `data-port-type` attributes as ports
|
||||||
|
|
||||||
|
|
||||||
```ts pure title="node-registries.ts"
|
```ts pure title="node-registries.ts"
|
||||||
@ -30,7 +30,7 @@ Add `dynamicPorts` to node declaration, when set to true it will look for DOM el
|
|||||||
type: 'condition',
|
type: 'condition',
|
||||||
meta: {
|
meta: {
|
||||||
defaultPorts: [{ type: 'input'}]
|
defaultPorts: [{ type: 'input'}]
|
||||||
dynamicPort: true
|
useDynamicPort: true
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -220,7 +220,7 @@ export const nodeRegistries: WorkflowNodeRegistry[] = [
|
|||||||
deleteDisable: true, // Start node cannot be deleted
|
deleteDisable: true, // Start node cannot be deleted
|
||||||
copyDisable: true, // Start node cannot be copied
|
copyDisable: true, // Start node cannot be copied
|
||||||
defaultPorts: [{ type: 'output' }], // Define node input and output ports, start node only has output port
|
defaultPorts: [{ type: 'output' }], // Define node input and output ports, start node only has output port
|
||||||
// dynamicPort: true, // For dynamic ports, will look for DOM with data-port-id and data-port-type attributes as ports
|
// useDynamicPort: true, // For dynamic ports, will look for DOM with data-port-id and data-port-type attributes as ports
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Configure node form validation and rendering
|
* Configure node form validation and rendering
|
||||||
|
|||||||
@ -21,5 +21,6 @@
|
|||||||
"minimap",
|
"minimap",
|
||||||
"custom-plugin",
|
"custom-plugin",
|
||||||
"custom-service",
|
"custom-service",
|
||||||
|
"custom-layer",
|
||||||
"form-materials"
|
"form-materials"
|
||||||
]
|
]
|
||||||
|
|||||||
113
apps/docs/src/zh/guide/advanced/custom-layer.mdx
Normal file
113
apps/docs/src/zh/guide/advanced/custom-layer.mdx
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
# 自定义 Layer
|
||||||
|
|
||||||
|
我们将画布拆分成多个 Layer,实现交互分层的思想,便于插件化管理,详细见 [画布引擎](guide/concepts/canvas-engine.html)
|
||||||
|
|
||||||
|
1. 通过 `observeEntityDatas` `observeEntities` `observeEntity` 监听画布节点任意数据模块的更新
|
||||||
|
2. 通过 `onZoom` `onScroll` `onViewportChange` 等监听画布的缩放或者滚动
|
||||||
|
3. 通过 `render` 往画布中插入 react 元素, 如绘制 svg 线条
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 创建 Layer
|
||||||
|
|
||||||
|
```tsx pure
|
||||||
|
import { FreeLayoutPluginContext, inject, injectable, FlowNodeEntity, FlowNodeTransformData, FlowNodeFormData } from '@flowgram.ai/free-layout-editor'
|
||||||
|
|
||||||
|
@injectable()
|
||||||
|
export class MyLayer extends Layer {
|
||||||
|
@inject(FreeLayoutPluginContext) ctx: FreeLayoutPluginContext
|
||||||
|
// 可以监听节点的宽高位置变化
|
||||||
|
@observeEntityDatas(FlowNodeEntity, FlowNodeTransformData) transformDatas: FlowNodeTransformData[];
|
||||||
|
// 可以监听表单数据变化,连线数据可以存在表单里
|
||||||
|
@observeEntityDatas(FlowNodeEntity, FlowNodeFormData) formDatas: FlowNodeFormData[];
|
||||||
|
onReady() {
|
||||||
|
// 也可以添加样式
|
||||||
|
// zIndex可以控制是否要盖在节点, 节点默认是 10,大于 10 则在节点上边
|
||||||
|
this.node.style.zIndex = 11;
|
||||||
|
}
|
||||||
|
onZoom(scale) {
|
||||||
|
// 跟着画布缩放
|
||||||
|
this.node.style.transform = `scale(${scale})`;
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return <div>{...}</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 加入到画布
|
||||||
|
|
||||||
|
- 通过 use-editor-props
|
||||||
|
|
||||||
|
```ts pure
|
||||||
|
{
|
||||||
|
onInit: (ctx) => {
|
||||||
|
ctx.playground.registerLayer(MyLayer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- 通过插件添加
|
||||||
|
|
||||||
|
```tsx pure
|
||||||
|
import { FreeLayoutPluginContext } from '@flowgram.ai/free-layout-editor'
|
||||||
|
|
||||||
|
export const createMyPlugin = definePluginCreator<{}, FreeLayoutPluginContext>({
|
||||||
|
onInit: (ctx, opts) => {
|
||||||
|
ctx.playground.registerLayer(MyLayer)
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Layer 生命周期说明
|
||||||
|
|
||||||
|
```ts
|
||||||
|
interface Layer {
|
||||||
|
/**
|
||||||
|
* 初始化时候触发
|
||||||
|
*/
|
||||||
|
onReady?(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* playground 大小变化时候会触发
|
||||||
|
*/
|
||||||
|
onResize?(size: PipelineDimension): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* playground focus 时候触发
|
||||||
|
*/
|
||||||
|
onFocus?(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* playground blur 时候触发
|
||||||
|
*/
|
||||||
|
onBlur?(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听缩放
|
||||||
|
*/
|
||||||
|
onZoom?(scale: number): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听滚动
|
||||||
|
*/
|
||||||
|
onScroll?(scroll: { scrollX: number; scrollY: number }): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* viewport 更新触发
|
||||||
|
*/
|
||||||
|
onViewportChange?(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* readonly 或 disable 状态变化
|
||||||
|
* @param state
|
||||||
|
*/
|
||||||
|
onReadonlyOrDisabledChange?(state: { disabled: boolean; readonly: boolean }): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据更新自动触发react render,如果不提供则不会调用react渲染
|
||||||
|
*/
|
||||||
|
render?(): JSX.Element
|
||||||
|
}
|
||||||
|
```
|
||||||
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
- 动态端口
|
- 动态端口
|
||||||
|
|
||||||
节点声明添加 `dynamicPorts` , 当设置为 true 则会到节点dom 上寻找 data-port-id 和 data-port-type 属性的 dom 作为端口
|
节点声明添加 `useDynamicPort` , 当设置为 true 则会到节点dom 上寻找 data-port-id 和 data-port-type 属性的 dom 作为端口
|
||||||
|
|
||||||
|
|
||||||
```ts pure title="node-registries.ts"
|
```ts pure title="node-registries.ts"
|
||||||
@ -30,7 +30,7 @@
|
|||||||
type: 'condition',
|
type: 'condition',
|
||||||
meta: {
|
meta: {
|
||||||
defaultPorts: [{ type: 'input'}]
|
defaultPorts: [{ type: 'input'}]
|
||||||
dynamicPort: true
|
useDynamicPort: true
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ export const useEditorProps = () => {
|
|||||||
return {
|
return {
|
||||||
// ...
|
// ...
|
||||||
nodeEngine: {
|
nodeEngine: {
|
||||||
enable: false, // 不开启节点引擎,则无法使用 from
|
enable: false, // 不开启节点引擎,则无法使用 form
|
||||||
},
|
},
|
||||||
history: {
|
history: {
|
||||||
enable: true,
|
enable: true,
|
||||||
|
|||||||
@ -229,7 +229,7 @@ export const nodeRegistries: WorkflowNodeRegistry[] = [
|
|||||||
deleteDisable: true, // 开始节点不能删除
|
deleteDisable: true, // 开始节点不能删除
|
||||||
copyDisable: true, // 开始节点不能复制
|
copyDisable: true, // 开始节点不能复制
|
||||||
defaultPorts: [{ type: 'output' }], // 用于定义节点的输入和输出端口, 开始节点只有输出端口
|
defaultPorts: [{ type: 'output' }], // 用于定义节点的输入和输出端口, 开始节点只有输出端口
|
||||||
// dynamicPort: true, // 用于动态端口,会寻找 data-port-id 和 data-port-type 属性的 dom 作为端口
|
// useDynamicPort: true, // 用于动态端口,会寻找 data-port-id 和 data-port-type 属性的 dom 作为端口
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* 配置节点表单的校验及渲染,
|
* 配置节点表单的校验及渲染,
|
||||||
|
|||||||
@ -1,3 +1,25 @@
|
|||||||
|
# 注意事项及常见问题
|
||||||
|
|
||||||
|
# 注意事项
|
||||||
|
|
||||||
|
1. 画布的 editor 版本及导入的插件版本必须一致,如果出现以下错误都是这个问题造成
|
||||||
|
|
||||||
|
|
||||||
|
2. 画布的事件监听,在 react 中使用都要配套写销毁逻辑,防止无限注册导致内存泄漏
|
||||||
|
|
||||||
|
```tsx pure
|
||||||
|
function SomeReactComp() {
|
||||||
|
useEffect(() => {
|
||||||
|
const toDispose = ctx.document.onContentChange(() => {
|
||||||
|
// DO Something
|
||||||
|
})
|
||||||
|
return () => toDispose.dispose() // Destroy Event
|
||||||
|
}, [])
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 常见问题
|
# 常见问题
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user