From ec6e5abe23726fa9322346a5fd324d9a9168f23c Mon Sep 17 00:00:00 2001 From: xiamidaxia Date: Mon, 19 May 2025 15:52:36 +0800 Subject: [PATCH] docs: free-layout-simple docs error (#245) * chore: simple-layout-demo add cross-env * docs: free-layout-simple docs error --- apps/demo-free-layout-simple/package.json | 4 +- apps/demo-react-16/package.json | 4 +- .../fixed-layout-simple/preview.tsx | 8 +- .../components/free-layout-simple/preview.tsx | 4 +- .../free-layout/free-layout-simple.mdx | 322 ++++++++++------- .../free-layout/free-layout-simple.mdx | 325 +++++++++++------- config/eslint-config/package.json | 1 + config/ts-config/package.json | 1 + .../client/free-layout-editor/package.json | 2 +- .../src/preset/node-serialize.ts | 2 +- 10 files changed, 416 insertions(+), 257 deletions(-) diff --git a/apps/demo-free-layout-simple/package.json b/apps/demo-free-layout-simple/package.json index cac882ef..7dd686ce 100644 --- a/apps/demo-free-layout-simple/package.json +++ b/apps/demo-free-layout-simple/package.json @@ -19,10 +19,10 @@ "build:fast": "exit 0", "build:watch": "exit 0", "clean": "rimraf dist", - "dev": "MODE=app NODE_ENV=development rsbuild dev --open", + "dev": "cross-env MODE=app NODE_ENV=development rsbuild dev --open", "lint": "eslint ./src --cache", "lint:fix": "eslint ./src --fix", - "start": "NODE_ENV=development rsbuild dev --open", + "start": "cross-env NODE_ENV=development rsbuild dev --open", "test": "exit", "test:cov": "exit", "watch": "exit 0" diff --git a/apps/demo-react-16/package.json b/apps/demo-react-16/package.json index f8bd67d9..218e1d2f 100644 --- a/apps/demo-react-16/package.json +++ b/apps/demo-react-16/package.json @@ -19,10 +19,10 @@ "build:fast": "exit 0", "build:watch": "exit 0", "clean": "rimraf dist", - "dev": "MODE=app NODE_ENV=development rsbuild dev --open", + "dev": "cross-env MODE=app NODE_ENV=development rsbuild dev --open", "lint": "eslint ./src --cache", "lint:fix": "eslint ./src --fix", - "start": "NODE_ENV=development rsbuild dev --open", + "start": "cross-env NODE_ENV=development rsbuild dev --open", "test": "exit", "test:cov": "exit", "watch": "exit 0" diff --git a/apps/docs/components/fixed-layout-simple/preview.tsx b/apps/docs/components/fixed-layout-simple/preview.tsx index e6e172ff..76e97402 100644 --- a/apps/docs/components/fixed-layout-simple/preview.tsx +++ b/apps/docs/components/fixed-layout-simple/preview.tsx @@ -20,13 +20,7 @@ const indexCode = { export const FixedLayoutSimplePreview = () => ( { - return - } - export default App;`, - 'index.tsx': indexCode, + 'editor.tsx': indexCode, 'index.css': indexCssCode, 'initial-data.ts': initialDataCode, 'node-registries.ts': nodeRegistriesCode, diff --git a/apps/docs/components/free-layout-simple/preview.tsx b/apps/docs/components/free-layout-simple/preview.tsx index 5be86d7f..8051b23e 100644 --- a/apps/docs/components/free-layout-simple/preview.tsx +++ b/apps/docs/components/free-layout-simple/preview.tsx @@ -4,14 +4,14 @@ import { FreeLayoutSimple } from '.'; import nodeRegistriesCode from '!!raw-loader!@flowgram.ai/demo-free-layout-simple/src/node-registries.ts'; import dataCode from '!!raw-loader!@flowgram.ai/demo-free-layout-simple/src/initial-data.ts'; import useEditorPropsCode from '!!raw-loader!@flowgram.ai/demo-free-layout-simple/src/hooks/use-editor-props.tsx'; -import indexCode from '!!raw-loader!@flowgram.ai/demo-free-layout-simple/src/editor.tsx'; +import editorCode from '!!raw-loader!@flowgram.ai/demo-free-layout-simple/src/editor.tsx'; import toolsCode from '!!raw-loader!@flowgram.ai/demo-free-layout-simple/src/components/tools.tsx'; import nodeAddPanelCode from '!!raw-loader!@flowgram.ai/demo-free-layout-simple/src/components/node-add-panel.tsx'; import minimapCode from '!!raw-loader!@flowgram.ai/demo-free-layout-simple/src/components/minimap.tsx'; export const FreeLayoutSimplePreview = () => { const files = { - 'index.tsx': indexCode, + 'editor.tsx': editorCode, 'use-editor-props.tsx': useEditorPropsCode, 'initial-data.ts': dataCode, 'node-registries.ts': nodeRegistriesCode, diff --git a/apps/docs/src/en/examples/free-layout/free-layout-simple.mdx b/apps/docs/src/en/examples/free-layout/free-layout-simple.mdx index 081cd5a4..a404aa63 100644 --- a/apps/docs/src/en/examples/free-layout/free-layout-simple.mdx +++ b/apps/docs/src/en/examples/free-layout/free-layout-simple.mdx @@ -127,40 +127,33 @@ Next, we need to define the behavior and appearance of different types of nodes: // src/node-registries.ts import { WorkflowNodeRegistry } from '@flowgram.ai/free-layout-editor'; -export const nodeRegistries: Record = { - // Start node - start: { +/** + * You can customize your own node registry + */ +export const nodeRegistries: WorkflowNodeRegistry[] = [ + { type: 'start', meta: { - defaultWidth: 200, - defaultHeight: 100, - canDelete: false, // Prohibit deletion - backgroundColor: '#E6F7FF', - defaultExpanded: true, + isStart: true, // Mark as start + deleteDisable: true, // The start node cannot be deleted + copyDisable: true, // The start node cannot be copied + defaultPorts: [{ type: 'output' }], // Used to define the input and output ports, the start node only has the output port }, }, - // Custom node - custom: { - type: 'custom', - meta: { - defaultWidth: 200, - defaultHeight: 100, - backgroundColor: '#FFF7E6', - defaultExpanded: true, - }, - }, - // End node - end: { + { type: 'end', meta: { - defaultWidth: 200, - defaultHeight: 100, - canDelete: false, // Prohibit deletion - backgroundColor: '#FFF1F0', - defaultExpanded: true, + deleteDisable: true, + copyDisable: true, + defaultPorts: [{ type: 'input' }], }, }, -}; + { + type: 'custom', + meta: {}, + defaultPorts: [{ type: 'output' }, { type: 'input' }], // A normal node has two ports + }, +]; ``` #### Step 3: Create Editor Configuration @@ -260,14 +253,29 @@ export const useEditorProps = () => canvasStyle: { canvasWidth: 182, canvasHeight: 102, + canvasPadding: 50, canvasBackground: 'rgba(245, 245, 245, 1)', + canvasBorderRadius: 10, + viewportBackground: 'rgba(235, 235, 235, 1)', + viewportBorderRadius: 4, + viewportBorderColor: 'rgba(201, 201, 201, 1)', + viewportBorderWidth: 1, + viewportBorderDashLength: 2, + nodeColor: 'rgba(255, 255, 255, 1)', + nodeBorderRadius: 2, + nodeBorderWidth: 0.145, + nodeBorderColor: 'rgba(6, 7, 9, 0.10)', + overlayColor: 'rgba(255, 255, 255, 0)', }, + inactiveDebounceTime: 1, }), // Auto-alignment plugin createFreeSnapPlugin({ edgeColor: '#00B2B2', alignColor: '#00B2B2', edgeLineWidth: 1, + alignLineWidth: 1, + alignCrossWidth: 8, }), ], }), @@ -311,37 +319,76 @@ export const NodeAddPanel: React.FC = () => { #### Step 5: Create Toolbar and Minimap ```tsx -// src/components/tools.tsx import React from 'react'; import { usePlaygroundTools, useClientContext } from '@flowgram.ai/free-layout-editor'; export const Tools: React.FC = () => { - const { zoomIn, zoomOut, resetZoom, undo, redo } = usePlaygroundTools(); const { history } = useClientContext(); + const tools = usePlaygroundTools(); + const [canUndo, setCanUndo] = useState(false); + const [canRedo, setCanRedo] = useState(false); + + useEffect(() => { + const disposable = history.undoRedoService.onChange(() => { + setCanUndo(history.canUndo()); + setCanRedo(history.canRedo()); + }); + return () => disposable.dispose(); + }, [history]); return ( -
- - - - - +
+ + + + + + + {Math.floor(tools.zoom * 100)}%
); }; // src/components/minimap.tsx +import { FlowMinimapService, MinimapRender } from '@flowgram.ai/minimap-plugin'; import { useService } from '@flowgram.ai/free-layout-editor'; -import { MinimapService } from '@flowgram.ai/minimap-plugin'; - -export const Minimap: React.FC = () => { - const minimapService = useService(MinimapService); +export const Minimap = () => { + const minimapService = useService(FlowMinimapService); return (
+ style={{ + position: 'absolute', + left: 226, + bottom: 51, + zIndex: 100, + width: 198, + }} + > + +
); }; ``` @@ -380,85 +427,123 @@ export const Editor = () => { ```tsx // src/app.tsx +import React from 'react'; +import ReactDOM from 'react-dom'; + import { Editor } from './editor'; -export function App() { - return ( -
-

Free Layout Editor Example

- -
- ); -} +ReactDOM.render(, document.getElementById('root')) ``` #### Step 8: Add Styles ```css /* src/index.css */ -.demo-free-container { - position: relative; - width: 100%; - height: 600px; - border: 1px solid #eee; -} - -.demo-free-layout { - display: flex; - height: 100%; -} - -.demo-free-sidebar { - width: 200px; - padding: 16px; - border-right: 1px solid #eee; - overflow-y: auto; -} - -.demo-free-card { - margin-bottom: 8px; - padding: 8px 12px; - border: 1px solid #ddd; - border-radius: 4px; - cursor: grab; - background: #fff; -} - -.demo-free-editor { - flex: 1; - height: 100%; -} - -.demo-free-tools { - position: absolute; - top: 16px; - right: 16px; - display: flex; - gap: 8px; - z-index: 10; -} - -.demo-free-minimap { - position: absolute; - right: 16px; - bottom: 16px; - z-index: 10; -} - .demo-free-node { - background: #fff; - border-radius: 4px; - box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); + display: flex; + min-width: 300px; + min-height: 100px; + flex-direction: column; + align-items: flex-start; + box-sizing: border-box; + border-radius: 8px; + border: 1px solid var(--light-usage-border-color-border, rgba(28, 31, 35, 0.08)); + background: #fff; + box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1); } .demo-free-node-title { - padding: 8px 12px; - font-weight: bold; - border-bottom: 1px solid #eee; + background-color: #93bfe2; + width: 100%; + border-radius: 8px 8px 0 0; + padding: 4px 12px; +} +.demo-free-node-content { + padding: 4px 12px; + flex-grow: 1; + width: 100%; +} +.demo-free-node::before { + content: ''; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: -1; + background-color: white; + border-radius: 7px; } -.demo-free-node-content { - padding: 8px 12px; +.demo-free-node:hover:before { + -webkit-filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.3)) drop-shadow(0 4px 14px rgba(0, 0, 0, 0.1)); + filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.3)) drop-shadow(0 4px 14px rgba(0, 0, 0, 0.1)); +} + +.demo-free-node.activated:before, +.demo-free-node.selected:before { + outline: 2px solid var(--light-usage-primary-color-primary, #4d53e8); + -webkit-filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.3)) drop-shadow(0 4px 14px rgba(0, 0, 0, 0.1)); + filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.3)) drop-shadow(0 4px 14px rgba(0, 0, 0, 0.1)); +} + +.demo-free-sidebar { + height: 100%; + overflow-y: auto; + padding: 12px 16px 0; + box-sizing: border-box; + background: #f7f7fa; + border-right: 1px solid rgba(29, 28, 35, 0.08); +} + +.demo-free-right-top-panel { + position: fixed; + right: 10px; + top: 70px; + width: 300px; + z-index: 999; +} + +.demo-free-card { + width: 140px; + height: 60px; + display: flex; + align-items: center; + justify-content: center; + font-size: 20px; + background: #fff; + border-radius: 8px; + box-shadow: 0 6px 8px 0 rgba(28, 31, 35, 0.03); + cursor: -webkit-grab; + cursor: grab; + line-height: 16px; + margin-bottom: 12px; + overflow: hidden; + padding: 16px; + position: relative; + color: black; +} + +.demo-free-layout { + display: flex; + flex-direction: row; + flex-grow: 1; +} + +.demo-free-editor { + flex-grow: 1; + position: relative; + height: 100%; +} + +.demo-free-container { + position: absolute; + left: 0; + top: 0; + display: flex; + width: 100%; + height: 100%; + flex-direction: column; } ``` @@ -515,24 +600,19 @@ Use `nodeRegistries` to define the behavior and appearance of different types of // Node registration import { WorkflowNodeRegistry } from '@flowgram.ai/free-layout-editor'; -export const nodeRegistries: Record = { +export const nodeRegistries: WorkflowNodeRegistry[] = [ // Start node definition - start: { + { type: 'start', meta: { - defaultWidth: 200, - defaultHeight: 100, - canDelete: false, // Prohibit deletion - backgroundColor: '#fff', - defaultExpanded: true, // Default expanded + isStart: true, // Mark as start + deleteDisable: true, // The start node cannot be deleted + copyDisable: true, // The start node cannot be copied + defaultPorts: [{ type: 'output' }], // Used to define the input and output ports, the start node only has the output port }, - formMeta: { - // Node form definition - render: () => <>Form content - } }, // More node types... -}; +]; ``` ### 3. Editor Components @@ -549,7 +629,7 @@ const editorProps = { background: true, // Enable background grid readonly: false, // Non-readonly mode, allow editing initialData: {...}, // Initial data: definition of nodes and edges - nodeRegistries: {...}, // Node type registration + nodeRegistries: [...], // Node type registration nodeEngine: { enable: true, // Enable node form engine }, @@ -581,10 +661,10 @@ const dragService = useService(WorkflowDragService); dragService.startDragCard('nodeType', event, { data: {...} }); // Get editor context -const { document, services } = useClientContext(); +const { document, playground } = useClientContext(); // Manipulate canvas document.fitView(); // Fit view -document.zoomTo(1.5); // Zoom canvas +playground.config.zoomin(); // Zoom canvas document.fromJSON(newData); // Update data ``` diff --git a/apps/docs/src/zh/examples/free-layout/free-layout-simple.mdx b/apps/docs/src/zh/examples/free-layout/free-layout-simple.mdx index 41f0858b..c184d85c 100644 --- a/apps/docs/src/zh/examples/free-layout/free-layout-simple.mdx +++ b/apps/docs/src/zh/examples/free-layout/free-layout-simple.mdx @@ -127,40 +127,33 @@ export const initialData: WorkflowJSON = { // src/node-registries.ts import { WorkflowNodeRegistry } from '@flowgram.ai/free-layout-editor'; -export const nodeRegistries: Record = { - // 开始节点 - start: { +/** + * 你可以自定义节点的注册器 + */ +export const nodeRegistries: WorkflowNodeRegistry[] = [ + { type: 'start', meta: { - defaultWidth: 200, - defaultHeight: 100, - canDelete: false, // 禁止删除 - backgroundColor: '#E6F7FF', - defaultExpanded: true, + isStart: true, // 开始节点标记 + deleteDisable: true, // 开始节点不能被删除 + copyDisable: true, // 开始节点不能被 copy + defaultPorts: [{ type: 'output' }], // 定义 input 和 output 端口,开始节点只有 output 端口 }, }, - // 自定义节点 - custom: { - type: 'custom', - meta: { - defaultWidth: 200, - defaultHeight: 100, - backgroundColor: '#FFF7E6', - defaultExpanded: true, - }, - }, - // 结束节点 - end: { + { type: 'end', meta: { - defaultWidth: 200, - defaultHeight: 100, - canDelete: false, // 禁止删除 - backgroundColor: '#FFF1F0', - defaultExpanded: true, + deleteDisable: true, + copyDisable: true, + defaultPorts: [{ type: 'input' }], // 结束节点只有 input 端口 }, }, -}; + { + type: 'custom', + meta: {}, + defaultPorts: [{ type: 'output' }, { type: 'input' }], // 普通节点有两个端口 + }, +]; ``` #### 步骤三:创建编辑器配置 @@ -260,14 +253,29 @@ export const useEditorProps = () => canvasStyle: { canvasWidth: 182, canvasHeight: 102, + canvasPadding: 50, canvasBackground: 'rgba(245, 245, 245, 1)', + canvasBorderRadius: 10, + viewportBackground: 'rgba(235, 235, 235, 1)', + viewportBorderRadius: 4, + viewportBorderColor: 'rgba(201, 201, 201, 1)', + viewportBorderWidth: 1, + viewportBorderDashLength: 2, + nodeColor: 'rgba(255, 255, 255, 1)', + nodeBorderRadius: 2, + nodeBorderWidth: 0.145, + nodeBorderColor: 'rgba(6, 7, 9, 0.10)', + overlayColor: 'rgba(255, 255, 255, 0)', }, + inactiveDebounceTime: 1, }), // 自动对齐插件 createFreeSnapPlugin({ edgeColor: '#00B2B2', alignColor: '#00B2B2', edgeLineWidth: 1, + alignLineWidth: 1, + alignCrossWidth: 8, }), ], }), @@ -293,7 +301,7 @@ export const NodeAddPanel: React.FC = () => {
dragService.startDragCard('custom', e, { + onMouseDown={e => dragService.startDragCard(nodeType, e, { data: { title: nodeType, content: '拖拽创建的节点' @@ -313,35 +321,76 @@ export const NodeAddPanel: React.FC = () => { ```tsx // src/components/tools.tsx import React from 'react'; +import { useEffect, useState } from 'react'; import { usePlaygroundTools, useClientContext } from '@flowgram.ai/free-layout-editor'; export const Tools: React.FC = () => { - const { zoomIn, zoomOut, resetZoom, undo, redo } = usePlaygroundTools(); const { history } = useClientContext(); + const tools = usePlaygroundTools(); + const [canUndo, setCanUndo] = useState(false); + const [canRedo, setCanRedo] = useState(false); + + useEffect(() => { + const disposable = history.undoRedoService.onChange(() => { + setCanUndo(history.canUndo()); + setCanRedo(history.canRedo()); + }); + return () => disposable.dispose(); + }, [history]); return ( -
- - - - - +
+ + + + + + + {Math.floor(tools.zoom * 100)}%
); }; // src/components/minimap.tsx +import { FlowMinimapService, MinimapRender } from '@flowgram.ai/minimap-plugin'; import { useService } from '@flowgram.ai/free-layout-editor'; -import { MinimapService } from '@flowgram.ai/minimap-plugin'; - -export const Minimap: React.FC = () => { - const minimapService = useService(MinimapService); +export const Minimap = () => { + const minimapService = useService(FlowMinimapService); return (
+ style={{ + position: 'absolute', + left: 226, + bottom: 51, + zIndex: 100, + width: 198, + }} + > + +
); }; ``` @@ -380,86 +429,125 @@ export const Editor = () => { ```tsx // src/app.tsx +import React from 'react'; +import ReactDOM from 'react-dom'; + import { Editor } from './editor'; -export function App() { - return ( -
-

自由布局编辑器示例

- -
- ); -} +ReactDOM.render(, document.getElementById('root')) ``` #### 步骤八:添加样式 ```css /* src/index.css */ -.demo-free-container { - position: relative; - width: 100%; - height: 600px; - border: 1px solid #eee; -} - -.demo-free-layout { - display: flex; - height: 100%; -} - -.demo-free-sidebar { - width: 200px; - padding: 16px; - border-right: 1px solid #eee; - overflow-y: auto; -} - -.demo-free-card { - margin-bottom: 8px; - padding: 8px 12px; - border: 1px solid #ddd; - border-radius: 4px; - cursor: grab; - background: #fff; -} - -.demo-free-editor { - flex: 1; - height: 100%; -} - -.demo-free-tools { - position: absolute; - top: 16px; - right: 16px; - display: flex; - gap: 8px; - z-index: 10; -} - -.demo-free-minimap { - position: absolute; - right: 16px; - bottom: 16px; - z-index: 10; -} - .demo-free-node { - background: #fff; - border-radius: 4px; - box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); + display: flex; + min-width: 300px; + min-height: 100px; + flex-direction: column; + align-items: flex-start; + box-sizing: border-box; + border-radius: 8px; + border: 1px solid var(--light-usage-border-color-border, rgba(28, 31, 35, 0.08)); + background: #fff; + box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1); } .demo-free-node-title { - padding: 8px 12px; - font-weight: bold; - border-bottom: 1px solid #eee; + background-color: #93bfe2; + width: 100%; + border-radius: 8px 8px 0 0; + padding: 4px 12px; +} +.demo-free-node-content { + padding: 4px 12px; + flex-grow: 1; + width: 100%; +} +.demo-free-node::before { + content: ''; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: -1; + background-color: white; + border-radius: 7px; } -.demo-free-node-content { - padding: 8px 12px; +.demo-free-node:hover:before { + -webkit-filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.3)) drop-shadow(0 4px 14px rgba(0, 0, 0, 0.1)); + filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.3)) drop-shadow(0 4px 14px rgba(0, 0, 0, 0.1)); } + +.demo-free-node.activated:before, +.demo-free-node.selected:before { + outline: 2px solid var(--light-usage-primary-color-primary, #4d53e8); + -webkit-filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.3)) drop-shadow(0 4px 14px rgba(0, 0, 0, 0.1)); + filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.3)) drop-shadow(0 4px 14px rgba(0, 0, 0, 0.1)); +} + +.demo-free-sidebar { + height: 100%; + overflow-y: auto; + padding: 12px 16px 0; + box-sizing: border-box; + background: #f7f7fa; + border-right: 1px solid rgba(29, 28, 35, 0.08); +} + +.demo-free-right-top-panel { + position: fixed; + right: 10px; + top: 70px; + width: 300px; + z-index: 999; +} + +.demo-free-card { + width: 140px; + height: 60px; + display: flex; + align-items: center; + justify-content: center; + font-size: 20px; + background: #fff; + border-radius: 8px; + box-shadow: 0 6px 8px 0 rgba(28, 31, 35, 0.03); + cursor: -webkit-grab; + cursor: grab; + line-height: 16px; + margin-bottom: 12px; + overflow: hidden; + padding: 16px; + position: relative; + color: black; +} + +.demo-free-layout { + display: flex; + flex-direction: row; + flex-grow: 1; +} + +.demo-free-editor { + flex-grow: 1; + position: relative; + height: 100%; +} + +.demo-free-container { + position: absolute; + left: 0; + top: 0; + display: flex; + width: 100%; + height: 100%; + flex-direction: column; +} + ``` ### 4. 运行项目 @@ -515,24 +603,19 @@ const initialData: WorkflowJSON = { // 节点注册 import { WorkflowNodeRegistry } from '@flowgram.ai/free-layout-editor'; -export const nodeRegistries: Record = { +export const nodeRegistries: WorkflowNodeRegistry[] = [ // 开始节点定义 - start: { + { type: 'start', meta: { - defaultWidth: 200, - defaultHeight: 100, - canDelete: false, // 禁止删除 - backgroundColor: '#fff', - defaultExpanded: true, // 默认展开 + isStart: true, // Mark as start + deleteDisable: true, // The start node cannot be deleted + copyDisable: true, // The start node cannot be copied + defaultPorts: [{ type: 'output' }], // Used to define the input and output ports, the start node only has the output port }, - formMeta: { - // 节点表单定义 - render: () => <>表单内容 - } }, // 更多节点类型... -}; +]; ``` ### 3. 编辑器组件 @@ -549,7 +632,7 @@ const editorProps = { background: true, // 启用背景网格 readonly: false, // 非只读模式,允许编辑 initialData: {...}, // 初始化数据:节点和边的定义 - nodeRegistries: {...}, // 节点类型注册 + nodeRegistries: [...], // 节点类型注册 nodeEngine: { enable: true, // 启用节点表单引擎 }, @@ -581,10 +664,10 @@ const dragService = useService(WorkflowDragService); dragService.startDragCard('nodeType', event, { data: {...} }); // 获取编辑器上下文 -const { document, services } = useClientContext(); +const { document, playground } = useClientContext(); // 操作画布 document.fitView(); // 适应视图 -document.zoomTo(1.5); // 缩放画布 +playground.config.zoomin(); // 缩放画布 document.fromJSON(newData); // 更新数据 ``` diff --git a/config/eslint-config/package.json b/config/eslint-config/package.json index a04669a6..244a6c08 100644 --- a/config/eslint-config/package.json +++ b/config/eslint-config/package.json @@ -8,6 +8,7 @@ "build": "tsc -b --force", "dev": "npm run build -- -w", "lint": "eslint ./src --cache", + "watch": "exit", "test": "exit", "test:cov": "exit" }, diff --git a/config/ts-config/package.json b/config/ts-config/package.json index b2fe74ea..5cab1e6f 100644 --- a/config/ts-config/package.json +++ b/config/ts-config/package.json @@ -9,6 +9,7 @@ "build": "exit", "test": "exit", "lint": "exit", + "watch": "exit", "test:cov": "exit 0" }, "devDependencies": { diff --git a/packages/client/free-layout-editor/package.json b/packages/client/free-layout-editor/package.json index cd253bc9..610b7006 100644 --- a/packages/client/free-layout-editor/package.json +++ b/packages/client/free-layout-editor/package.json @@ -28,7 +28,7 @@ "build:watch": "npm run build:fast -- --dts-resolve", "clean": "rimraf dist", "test": "vitest run", - "test:cov": "exit 0", + "test:cov": "vitest run --coverage", "ts-check": "tsc --noEmit", "watch": "npm run build:fast -- --dts-resolve --watch --ignore-watch dist" }, diff --git a/packages/client/free-layout-editor/src/preset/node-serialize.ts b/packages/client/free-layout-editor/src/preset/node-serialize.ts index 0bc255f3..541d08c9 100644 --- a/packages/client/free-layout-editor/src/preset/node-serialize.ts +++ b/packages/client/free-layout-editor/src/preset/node-serialize.ts @@ -33,7 +33,7 @@ export function fromNodeJSON( return; } - return WorkflowDocumentOptionsDefault.fromNodeJSON?.(node, json, isFirstCreate); + return WorkflowDocumentOptionsDefault.fromNodeJSON!(node, json, isFirstCreate); } export function toNodeJSON(opts: FreeLayoutProps, node: FlowNodeEntity): FlowNodeJSON {