From 493d3084f5b8f5e00918571263dd2f2d3a738e4c Mon Sep 17 00:00:00 2001 From: YuanHeDx Date: Fri, 14 Mar 2025 18:07:27 +0800 Subject: [PATCH] doc(node): init node form demo --- apps/demo-node-form/.eslintrc.js | 15 ++ apps/demo-node-form/index.html | 12 ++ apps/demo-node-form/package.json | 55 ++++++ apps/demo-node-form/rspack.config.js | 46 +++++ apps/demo-node-form/src/app.tsx | 7 + apps/demo-node-form/src/editor.tsx | 27 +++ .../src/hooks/use-editor-props.tsx | 165 ++++++++++++++++++ apps/demo-node-form/src/index.css | 107 ++++++++++++ apps/demo-node-form/src/index.tsx | 1 + apps/demo-node-form/src/initial-data.ts | 18 ++ apps/demo-node-form/src/node-registries.tsx | 23 +++ apps/demo-node-form/tsconfig.json | 23 +++ apps/docs/components/form-basic/index.tsx | 10 ++ apps/docs/components/form-basic/preview.tsx | 42 +++++ apps/docs/components/index.ts | 1 + apps/docs/package.json | 1 + apps/docs/src/zh/examples/_meta.json | 5 + .../docs/src/zh/examples/node-form/_meta.json | 3 + apps/docs/src/zh/examples/node-form/basic.mdx | 10 ++ common/config/rush/pnpm-lock.yaml | 58 ++++++ .../node-engine/node/src/form-model-v2.ts | 4 + packages/node-engine/node/src/types.ts | 10 +- rush.json | 10 ++ 23 files changed, 652 insertions(+), 1 deletion(-) create mode 100644 apps/demo-node-form/.eslintrc.js create mode 100644 apps/demo-node-form/index.html create mode 100644 apps/demo-node-form/package.json create mode 100644 apps/demo-node-form/rspack.config.js create mode 100644 apps/demo-node-form/src/app.tsx create mode 100644 apps/demo-node-form/src/editor.tsx create mode 100644 apps/demo-node-form/src/hooks/use-editor-props.tsx create mode 100644 apps/demo-node-form/src/index.css create mode 100644 apps/demo-node-form/src/index.tsx create mode 100644 apps/demo-node-form/src/initial-data.ts create mode 100644 apps/demo-node-form/src/node-registries.tsx create mode 100644 apps/demo-node-form/tsconfig.json create mode 100644 apps/docs/components/form-basic/index.tsx create mode 100644 apps/docs/components/form-basic/preview.tsx create mode 100644 apps/docs/src/zh/examples/node-form/_meta.json create mode 100644 apps/docs/src/zh/examples/node-form/basic.mdx diff --git a/apps/demo-node-form/.eslintrc.js b/apps/demo-node-form/.eslintrc.js new file mode 100644 index 00000000..9f8bd759 --- /dev/null +++ b/apps/demo-node-form/.eslintrc.js @@ -0,0 +1,15 @@ +const { defineConfig } = require('@flowgram.ai/eslint-config'); + +module.exports = defineConfig({ + preset: 'web', + packageRoot: __dirname, + rules: { + 'no-console': 'off', + 'react/prop-types': 'off', + }, + settings: { + react: { + version: 'detect', // 自动检测 React 版本 + }, + }, +}); diff --git a/apps/demo-node-form/index.html b/apps/demo-node-form/index.html new file mode 100644 index 00000000..7327a045 --- /dev/null +++ b/apps/demo-node-form/index.html @@ -0,0 +1,12 @@ + + + + + + + Flow FreeLayoutEditor Demo + + +
+ + diff --git a/apps/demo-node-form/package.json b/apps/demo-node-form/package.json new file mode 100644 index 00000000..b582fb1b --- /dev/null +++ b/apps/demo-node-form/package.json @@ -0,0 +1,55 @@ +{ + "name": "@flowgram.ai/demo-node-form", + "version": "0.1.0", + "description": "", + "keywords": [], + "license": "MIT", + "main": "./src/index.tsx", + "files": [ + "src/", + ".eslintrc.js", + ".gitignore", + "index.html", + "package.json", + "rspack.config.js", + "tsconfig.json" + ], + "scripts": { + "build": "exit 0", + "build:fast": "exit 0", + "build:watch": "exit 0", + "clean": "rimraf dist", + "dev": "MODE=app NODE_ENV=development rspack serve", + "lint": "eslint ./src --cache", + "lint:fix": "eslint ./src --fix", + "start": "NODE_ENV=development rspack serve", + "test": "exit", + "test:cov": "exit", + "watch": "exit 0" + }, + "dependencies": { + "@douyinfe/semi-icons": "^2.72.3", + "@douyinfe/semi-ui": "^2.72.3", + "@flowgram.ai/free-layout-editor": "workspace:*", + "@flowgram.ai/free-snap-plugin": "workspace:*", + "@flowgram.ai/minimap-plugin": "workspace:*", + "react": "^18", + "react-dom": "^18" + }, + "devDependencies": { + "@flowgram.ai/ts-config": "workspace:*", + "@flowgram.ai/eslint-config": "workspace:*", + "@rspack/cli": "0.2.1", + "@types/lodash-es": "^4.17.12", + "@types/node": "^18", + "@types/react": "^18", + "@types/react-dom": "^18", + "@types/styled-components": "^5", + "@typescript-eslint/parser": "^6.10.0", + "eslint": "^8.54.0" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + } +} diff --git a/apps/demo-node-form/rspack.config.js b/apps/demo-node-form/rspack.config.js new file mode 100644 index 00000000..e2f05408 --- /dev/null +++ b/apps/demo-node-form/rspack.config.js @@ -0,0 +1,46 @@ +const path = require('path'); + +const isCI = process.env.CI === 'true'; +const isSCM = !!process.env.BUILD_BRANCH; +const isProd = process.env.NODE_ENV === 'production'; +/** + * @type {import('@rspack/cli').Configuration} + */ +module.exports = { + mode: process.env.NODE_ENV, + context: __dirname, + target: ['web'], + entry: { + main: './src/app.tsx', + }, + builtins: { + // https://www.rspack.dev/config/builtins.html#builtinshtml + html: [ + { + template: './index.html', + }, + ], + progress: !isSCM ? {} : false, + treeShaking: isProd, + }, + module: { + // https://www.rspack.dev/config/module.html#rule + rules: [ + { + test: /\.(png|gif|jpg|jpeg|svg|woff2)$/, + type: 'asset', + }, + ], + }, + plugins: [], + /** module is too large now, we may need better way to tackle this in the future */ + stats: isCI + ? { all: false, modules: true, assets: true, chunks: true, warnings: true, errors: true } + : { + modules: false, + all: false, + warnings: false, + errors: true, + timings: true, + }, +}; diff --git a/apps/demo-node-form/src/app.tsx b/apps/demo-node-form/src/app.tsx new file mode 100644 index 00000000..150c56b5 --- /dev/null +++ b/apps/demo-node-form/src/app.tsx @@ -0,0 +1,7 @@ +import { createRoot } from 'react-dom/client'; + +import { Editor } from './editor'; + +const app = createRoot(document.getElementById('root')!); + +app.render(); diff --git a/apps/demo-node-form/src/editor.tsx b/apps/demo-node-form/src/editor.tsx new file mode 100644 index 00000000..16d8e870 --- /dev/null +++ b/apps/demo-node-form/src/editor.tsx @@ -0,0 +1,27 @@ +import { + EditorRenderer, + FlowNodeRegistry, + FreeLayoutEditorProvider, + WorkflowJSON, +} from '@flowgram.ai/free-layout-editor'; + +import { useEditorProps } from './hooks/use-editor-props'; +import '@flowgram.ai/free-layout-editor/index.css'; +import './index.css'; +interface EditorProps { + registry: FlowNodeRegistry; + initialData: WorkflowJSON; +} + +export const Editor = ({ registry, initialData }: EditorProps) => { + const editorProps = useEditorProps({ registry, initialData }); + return ( + +
+
+ +
+
+
+ ); +}; diff --git a/apps/demo-node-form/src/hooks/use-editor-props.tsx b/apps/demo-node-form/src/hooks/use-editor-props.tsx new file mode 100644 index 00000000..5184355b --- /dev/null +++ b/apps/demo-node-form/src/hooks/use-editor-props.tsx @@ -0,0 +1,165 @@ +import { useMemo } from 'react'; + +import { createMinimapPlugin } from '@flowgram.ai/minimap-plugin'; +import { createFreeSnapPlugin } from '@flowgram.ai/free-snap-plugin'; +import { + FreeLayoutProps, + WorkflowNodeProps, + WorkflowNodeRenderer, + Field, + useNodeRender, + FlowNodeRegistry, + WorkflowJSON, +} from '@flowgram.ai/free-layout-editor'; + +import { DEFAULT_DEMO_REGISTRY } from '../node-registries'; +import { DEFAULT_INITIAL_DATA } from '../initial-data'; + +interface EditorProps { + registries: FlowNodeRegistry[]; + initialData: WorkflowJSON; +} + +export const useEditorProps = ({ + registries = [DEFAULT_DEMO_REGISTRY], + initialData = DEFAULT_INITIAL_DATA, +}: EditorProps) => + useMemo( + () => ({ + /** + * Whether to enable the background + */ + background: true, + /** + * Whether it is read-only or not, the node cannot be dragged in read-only mode + */ + readonly: false, + /** + * Initial data + * 初始化数据 + */ + initialData, + /** + * Node registries + * 节点注册 + */ + nodeRegistries: registries, + /** + * Get the default node registry, which will be merged with the 'nodeRegistries' + * 提供默认的节点注册,这个会和 nodeRegistries 做合并 + */ + getNodeDefaultRegistry(type) { + return { + type, + meta: { + defaultExpanded: true, + }, + formMeta: { + /** + * Render form + */ + render: () => ( + <> + name="title"> + {({ field }) =>
{field.value}
} + +
+ name="content"> + + +
+ + ), + }, + }; + }, + materials: { + /** + * Render Node + */ + renderDefaultNode: (props: WorkflowNodeProps) => { + const { form } = useNodeRender(); + return ( + + {form?.render()} + + ); + }, + }, + /** + * Content change + */ + onContentChange(ctx, event) { + // console.log('Auto Save: ', event, ctx.document.toJSON()); + }, + // /** + // * Node engine enable, you can configure formMeta in the FlowNodeRegistry + // */ + nodeEngine: { + enable: true, + }, + /** + * Redo/Undo enable + */ + history: { + enable: true, + enableChangeNode: true, // Listen Node engine data change + }, + /** + * Playground init + */ + onInit: (ctx) => {}, + /** + * Playground render + */ + onAllLayersRendered(ctx) { + // Fitview + ctx.document.fitView(false); + }, + /** + * Playground dispose + */ + onDispose() { + console.log('---- Playground Dispose ----'); + }, + plugins: () => [ + /** + * Minimap plugin + * 缩略图插件 + */ + createMinimapPlugin({ + disableLayer: true, + 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, + }), + /** + * Snap plugin + * 自动对齐及辅助线插件 + */ + createFreeSnapPlugin({ + edgeColor: '#00B2B2', + alignColor: '#00B2B2', + edgeLineWidth: 1, + alignLineWidth: 1, + alignCrossWidth: 8, + }), + ], + }), + [] + ); diff --git a/apps/demo-node-form/src/index.css b/apps/demo-node-form/src/index.css new file mode 100644 index 00000000..c76cebfb --- /dev/null +++ b/apps/demo-node-form/src/index.css @@ -0,0 +1,107 @@ +.demo-free-node { + 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 { + 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: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; +} + diff --git a/apps/demo-node-form/src/index.tsx b/apps/demo-node-form/src/index.tsx new file mode 100644 index 00000000..2f6832bf --- /dev/null +++ b/apps/demo-node-form/src/index.tsx @@ -0,0 +1 @@ +export { Editor } from './editor'; diff --git a/apps/demo-node-form/src/initial-data.ts b/apps/demo-node-form/src/initial-data.ts new file mode 100644 index 00000000..b2e76742 --- /dev/null +++ b/apps/demo-node-form/src/initial-data.ts @@ -0,0 +1,18 @@ +import { WorkflowJSON } from '@flowgram.ai/free-layout-editor'; + +export const DEFAULT_INITIAL_DATA: WorkflowJSON = { + nodes: [ + { + id: 'node_0', + type: 'custom', + meta: { + position: { x: 400, y: 0 }, + }, + data: { + title: 'Custom', + content: 'Custom node content', + }, + }, + ], + edges: [], +}; diff --git a/apps/demo-node-form/src/node-registries.tsx b/apps/demo-node-form/src/node-registries.tsx new file mode 100644 index 00000000..21edbcbd --- /dev/null +++ b/apps/demo-node-form/src/node-registries.tsx @@ -0,0 +1,23 @@ +import { WorkflowNodeRegistry, Field } from '@flowgram.ai/free-layout-editor'; +import { Input, TextArea } from '@douyinfe/semi-ui'; + +export const DEFAULT_DEMO_REGISTRY: WorkflowNodeRegistry = { + type: 'custom', + meta: {}, + defaultPorts: [{ type: 'output' }, { type: 'input' }], + formMeta: { + render: () => ( +
+
Basic Node
+

name

+ + + +

city

+ + + +
+ ), + }, +}; diff --git a/apps/demo-node-form/tsconfig.json b/apps/demo-node-form/tsconfig.json new file mode 100644 index 00000000..171a60f5 --- /dev/null +++ b/apps/demo-node-form/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "@flowgram.ai/ts-config/tsconfig.flow.path.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "experimentalDecorators": true, + "target": "es2020", + "module": "esnext", + "strictPropertyInitialization": false, + "strict": true, + "esModuleInterop": true, + "moduleResolution": "node", + "skipLibCheck": true, + "noUnusedLocals": true, + "noImplicitAny": true, + "allowJs": true, + "resolveJsonModule": true, + "types": ["node"], + "jsx": "react-jsx", + "lib": ["es6", "dom", "es2020", "es2019.Array"] + }, + "include": ["./src"], +} diff --git a/apps/docs/components/form-basic/index.tsx b/apps/docs/components/form-basic/index.tsx new file mode 100644 index 00000000..24153819 --- /dev/null +++ b/apps/docs/components/form-basic/index.tsx @@ -0,0 +1,10 @@ +import React from 'react'; + +// https://github.com/web-infra-dev/rspress/issues/553 +const Editor = React.lazy(() => + import('@flowgram.ai/demo-node-form').then((module) => ({ + default: module.Editor, + })) +); + +export { Editor }; diff --git a/apps/docs/components/form-basic/preview.tsx b/apps/docs/components/form-basic/preview.tsx new file mode 100644 index 00000000..aa21182d --- /dev/null +++ b/apps/docs/components/form-basic/preview.tsx @@ -0,0 +1,42 @@ +import { PreviewEditor } from '../preview-editor'; +import { Editor } from '.'; + +const indexCode = { + code: `import { + EditorRenderer, + FreeLayoutEditorProvider, +} from '@flowgram.ai/free-layout-editor'; + +import { useEditorProps } from './hooks/use-editor-props' +import '@flowgram.ai/free-layout-editor/index.css'; +import './index.css'; + +export const App = () => { + const editorProps = useEditorProps() + return ( + +
+
+ + +
+ + +
+
+ ) +}; + `, + active: true, +}; + +export const NodeFormBasicPreview = () => { + const files = { + 'index.tsx': indexCode, + }; + return ( + + + + ); +}; diff --git a/apps/docs/components/index.ts b/apps/docs/components/index.ts index 1ef1ecbd..e6e21c6a 100644 --- a/apps/docs/components/index.ts +++ b/apps/docs/components/index.ts @@ -5,3 +5,4 @@ export { FreeLayoutSimple } from './free-layout-simple'; export { FreeLayoutSimplePreview } from './free-layout-simple/preview'; export { FixedLayoutSimple } from './fixed-layout-simple'; export { FixedLayoutSimplePreview } from './fixed-layout-simple/preview'; +export { NodeFormBasicPreview } from './form-basic/preview.tsx'; diff --git a/apps/docs/package.json b/apps/docs/package.json index b9a4f66a..cab3a7ef 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -19,6 +19,7 @@ "@flowgram.ai/demo-free-layout": "workspace:*", "@flowgram.ai/demo-free-layout-simple": "workspace:*", "@flowgram.ai/demo-fixed-layout-simple": "workspace:*", + "@flowgram.ai/demo-node-form": "workspace:*", "@flowgram.ai/fixed-layout-editor": "workspace:*", "@flowgram.ai/fixed-semi-materials": "workspace:*", "@flowgram.ai/free-layout-editor": "workspace:*", diff --git a/apps/docs/src/zh/examples/_meta.json b/apps/docs/src/zh/examples/_meta.json index 4bed1a45..009f1f8b 100644 --- a/apps/docs/src/zh/examples/_meta.json +++ b/apps/docs/src/zh/examples/_meta.json @@ -13,5 +13,10 @@ "type": "dir", "name": "free-layout", "label": "自由布局" + }, + { + "type": "dir", + "name": "node-form", + "label": "节点表单" } ] diff --git a/apps/docs/src/zh/examples/node-form/_meta.json b/apps/docs/src/zh/examples/node-form/_meta.json new file mode 100644 index 00000000..99cba57d --- /dev/null +++ b/apps/docs/src/zh/examples/node-form/_meta.json @@ -0,0 +1,3 @@ +[ + "basic" +] diff --git a/apps/docs/src/zh/examples/node-form/basic.mdx b/apps/docs/src/zh/examples/node-form/basic.mdx new file mode 100644 index 00000000..07d8cc30 --- /dev/null +++ b/apps/docs/src/zh/examples/node-form/basic.mdx @@ -0,0 +1,10 @@ +--- +outline: false +--- + + +# 基础用法 + +import { NodeFormBasicPreview } from '../../../../components'; + + diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 10981df2..51f69125 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -310,6 +310,61 @@ importers: specifier: ^8.54.0 version: 8.57.1 + ../../apps/demo-node-form: + dependencies: + '@douyinfe/semi-icons': + specifier: ^2.72.3 + version: 2.72.3(react@18.3.1) + '@douyinfe/semi-ui': + specifier: ^2.72.3 + version: 2.72.3(acorn@8.14.0)(react-dom@18.3.1)(react@18.3.1) + '@flowgram.ai/free-layout-editor': + specifier: workspace:* + version: link:../../packages/client/free-layout-editor + '@flowgram.ai/free-snap-plugin': + specifier: workspace:* + version: link:../../packages/plugins/free-snap-plugin + '@flowgram.ai/minimap-plugin': + specifier: workspace:* + version: link:../../packages/plugins/minimap-plugin + react: + specifier: ^18 + version: 18.3.1 + react-dom: + specifier: ^18 + version: 18.3.1(react@18.3.1) + devDependencies: + '@flowgram.ai/eslint-config': + specifier: workspace:* + version: link:../../config/eslint-config + '@flowgram.ai/ts-config': + specifier: workspace:* + version: link:../../config/ts-config + '@rspack/cli': + specifier: 0.2.1 + version: 0.2.1(react-refresh@0.16.0)(webpack@5.76.0) + '@types/lodash-es': + specifier: ^4.17.12 + version: 4.17.12 + '@types/node': + specifier: ^18 + version: 18.19.68 + '@types/react': + specifier: ^18 + version: 18.3.16 + '@types/react-dom': + specifier: ^18 + version: 18.3.5(@types/react@18.3.16) + '@types/styled-components': + specifier: ^5 + version: 5.1.34 + '@typescript-eslint/parser': + specifier: ^6.10.0 + version: 6.21.0(eslint@8.57.1)(typescript@5.0.4) + eslint: + specifier: ^8.54.0 + version: 8.57.1 + ../../apps/docs: dependencies: '@codesandbox/sandpack-react': @@ -333,6 +388,9 @@ importers: '@flowgram.ai/demo-free-layout-simple': specifier: workspace:* version: link:../demo-free-layout-simple + '@flowgram.ai/demo-node-form': + specifier: workspace:* + version: link:../demo-node-form '@flowgram.ai/fixed-layout-editor': specifier: workspace:* version: link:../../packages/client/fixed-layout-editor diff --git a/packages/node-engine/node/src/form-model-v2.ts b/packages/node-engine/node/src/form-model-v2.ts index 7c457131..5f66b32e 100644 --- a/packages/node-engine/node/src/form-model-v2.ts +++ b/packages/node-engine/node/src/form-model-v2.ts @@ -21,6 +21,7 @@ import { Glob, IField, IFieldArray, + toForm, } from '@flowgram.ai/form'; import { FlowNodeEntity } from '@flowgram.ai/document'; import { PlaygroundContext } from '@flowgram.ai/core'; @@ -256,6 +257,7 @@ export class FormModelV2 extends FormModel implements Disposable { value: get(values, currentName), prevValue: get(prevValues, currentName), formValues: values, + form: toForm(this.nativeFormModel!), context: this.nodeContext, }); @@ -298,6 +300,7 @@ export class FormModelV2 extends FormModel implements Disposable { value: get(values, path), formValues: values, prevValue: get(prevValues, path), + form: toForm(this.nativeFormModel!), context: this.nodeContext, }); @@ -332,6 +335,7 @@ export class FormModelV2 extends FormModel implements Disposable { effect({ ...props, formValues: nativeFormModel.values, + form: toForm(this.nativeFormModel!), context: this.nodeContext, }) ); diff --git a/packages/node-engine/node/src/types.ts b/packages/node-engine/node/src/types.ts index e885ac5d..b0e88e75 100644 --- a/packages/node-engine/node/src/types.ts +++ b/packages/node-engine/node/src/types.ts @@ -2,7 +2,12 @@ import * as React from 'react'; import { FormModel, IFormMeta, NodeFormContext } from '@flowgram.ai/form-core'; import { FieldName, FieldValue } from '@flowgram.ai/form/src/types'; -import { FormRenderProps, Validate as FormValidate, ValidateTrigger } from '@flowgram.ai/form'; +import { + FormRenderProps, + IForm, + Validate as FormValidate, + ValidateTrigger, +} from '@flowgram.ai/form'; import { FormPlugin } from './form-plugin'; import { FormModelV2 } from './form-model-v2'; @@ -51,6 +56,7 @@ export type Effect = (props: { value: TFieldValue; prevValue?: TFieldValue; formValues: TFormValues; + form: IForm; context: NodeContext; }) => void | EffectReturn; @@ -59,6 +65,7 @@ export type ArrayAppendEffect = (props: { value: TFieldValue; arrayValues: Array; formValues: TFormValues; + form: IForm; context: NodeContext; }) => void | EffectReturn; @@ -66,6 +73,7 @@ export type ArrayDeleteEffect = (props: { index: number; arrayValue: Array; formValues: TFormValues; + form: IForm; context: NodeContext; }) => void | EffectReturn; diff --git a/rush.json b/rush.json index 866c9a58..531eec28 100644 --- a/rush.json +++ b/rush.json @@ -774,6 +774,16 @@ "team-flow", "demo" ] + }, + { + "packageName": "@flowgram.ai/demo-node-form", + "projectFolder": "apps/demo-node-form", + "versionPolicyName": "appPolicy", + "tags": [ + "level-1", + "team-flow", + "demo" + ] } ] }