Просмотр исходного кода

chore(demo): remove sync-variable-plugin in demo-nextjs-antd (#442)

Yiwei Mao 6 месяцев назад
Родитель
Сommit
522bc0770d
17 измененных файлов с 211 добавлено и 100 удалено
  1. 1 6
      apps/demo-nextjs-antd/src/editor/hooks/use-editor-props.tsx
  2. 4 2
      apps/demo-nextjs-antd/src/editor/nodes/default-form-meta.tsx
  3. 5 1
      apps/demo-nextjs-antd/src/editor/nodes/start/form-meta.tsx
  4. 0 1
      apps/demo-nextjs-antd/src/editor/plugins/index.ts
  5. 0 85
      apps/demo-nextjs-antd/src/editor/plugins/sync-variable-plugin/sync-variable-plugin.ts
  6. 2 0
      packages/materials/form-antd-materials/src/effects/index.ts
  7. 0 1
      packages/materials/form-antd-materials/src/effects/provide-batch-outputs/index.ts
  8. 8 0
      packages/materials/form-antd-materials/src/effects/provide-json-schema-outputs/config.json
  9. 28 0
      packages/materials/form-antd-materials/src/effects/provide-json-schema-outputs/index.ts
  10. 5 0
      packages/materials/form-antd-materials/src/effects/sync-variable-title/config.json
  11. 28 0
      packages/materials/form-antd-materials/src/effects/sync-variable-title/index.ts
  12. 7 0
      packages/materials/form-antd-materials/src/form-plugins/batch-outputs-plugin/config.json
  13. 104 0
      packages/materials/form-antd-materials/src/form-plugins/batch-outputs-plugin/index.ts
  14. 1 1
      packages/materials/form-antd-materials/src/form-plugins/index.ts
  15. 1 0
      packages/materials/form-antd-materials/src/index.ts
  16. 1 1
      packages/materials/form-antd-materials/src/utils/index.ts
  17. 16 2
      packages/materials/form-antd-materials/src/utils/json-schema/index.ts

+ 1 - 6
apps/demo-nextjs-antd/src/editor/hooks/use-editor-props.tsx

@@ -18,7 +18,7 @@ import { createContainerNodePlugin } from '@flowgram.ai/free-container-plugin';
 
 import { onDragLineEnd } from '@editor/utils';
 import { FlowNodeRegistry } from '@editor/typings';
-import { createContextMenuPlugin, createSyncVariablePlugin } from '@editor/plugins';
+import { createContextMenuPlugin } from '@editor/plugins';
 import { defaultFormMeta } from '@editor/nodes/default-form-meta';
 import { WorkflowNodeType } from '@editor/nodes';
 import { BaseNode } from '@editor/components/base-node';
@@ -156,11 +156,6 @@ export const useEditorProps = (initialData: WorkflowJSON, nodeRegistries: FlowNo
           },
           inactiveDebounceTime: 1,
         }),
-        /**
-         * Variable plugin
-         * 变量插件
-         */
-        createSyncVariablePlugin({}),
         /**
          * Snap plugin
          * 自动对齐及辅助线插件

+ 4 - 2
apps/demo-nextjs-antd/src/editor/nodes/default-form-meta.tsx

@@ -4,7 +4,7 @@
  */
 
 import { FormMeta, FormRenderProps, ValidateTrigger } from '@flowgram.ai/free-layout-editor';
-import { autoRenameRefEffect } from '@flowgram.ai/form-antd-materials';
+import { autoRenameRefEffect, syncVariableTitle, provideJsonSchemaOutputs } from '@flowgram.ai/form-antd-materials';
 
 import { FormContent, FormHeader, FormInputs, FormOutputs } from '@editor/form-components';
 import { FlowNodeJSON } from '../typings';
@@ -36,7 +36,9 @@ export const defaultFormMeta: FormMeta<FlowNodeJSON> = {
       return undefined;
     },
   },
-  effect: {
+   effect: {
+    title: syncVariableTitle,
+    outputs: provideJsonSchemaOutputs,
     inputsValues: autoRenameRefEffect,
   },
 };

+ 5 - 1
apps/demo-nextjs-antd/src/editor/nodes/start/form-meta.tsx

@@ -12,7 +12,7 @@ import {
   FormRenderProps,
   ValidateTrigger,
 } from '@flowgram.ai/free-layout-editor';
-import { JsonSchemaEditor } from '@flowgram.ai/form-antd-materials';
+import { JsonSchemaEditor, syncVariableTitle, provideJsonSchemaOutputs } from '@flowgram.ai/form-antd-materials';
 
 import { FlowNodeJSON, JsonSchema } from '@editor/typings';
 import { useIsSidebar } from '@editor/hooks';
@@ -57,4 +57,8 @@ export const formMeta: FormMeta<FlowNodeJSON> = {
   validate: {
     title: ({ value }: { value: string }) => (value ? undefined : 'Title is required'),
   },
+  effect: {
+    title: syncVariableTitle,
+    outputs: provideJsonSchemaOutputs,
+  },
 };

+ 0 - 1
apps/demo-nextjs-antd/src/editor/plugins/index.ts

@@ -3,5 +3,4 @@
  * SPDX-License-Identifier: MIT
  */
 
-export { createSyncVariablePlugin } from './sync-variable-plugin/sync-variable-plugin';
 export { createContextMenuPlugin } from './context-menu-plugin';

+ 0 - 85
apps/demo-nextjs-antd/src/editor/plugins/sync-variable-plugin/sync-variable-plugin.ts

@@ -1,85 +0,0 @@
-/**
- * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
- * SPDX-License-Identifier: MIT
- */
-
-'use client';
-
-import {
-  ASTFactory,
-  FlowNodeVariableData,
-  FreeLayoutPluginContext,
-  PluginCreator,
-  definePluginCreator,
-  getNodeForm,
-} from '@flowgram.ai/free-layout-editor';
-import { JsonSchemaUtils } from '@flowgram.ai/form-antd-materials';
-
-export interface SyncVariablePluginOptions {}
-
-/**
- * Creates a plugin to synchronize output data to the variable engine when nodes are created or updated.
- * @param ctx - The plugin context, containing the document and other relevant information.
- * @param options - Plugin options, currently an empty object.
- */
-export const createSyncVariablePlugin: PluginCreator<SyncVariablePluginOptions> =
-  definePluginCreator<SyncVariablePluginOptions, FreeLayoutPluginContext>({
-    onInit(ctx, options) {
-      const flowDocument = ctx.document;
-
-      // Listen for node creation events
-      flowDocument.onNodeCreate(({ node }) => {
-        const form = getNodeForm(node);
-        const variableData = node.getData(FlowNodeVariableData);
-
-        /**
-         * Synchronizes output data to the variable engine.
-         * @param value - The output data to synchronize.
-         */
-        const syncOutputs = (value: any) => {
-          if (!value) {
-            // If the output data is empty, clear the variable
-            variableData?.clearVar();
-            return;
-          }
-
-          // Create an Type AST from the output data's JSON schema
-          // NOTICE: You can create a new function to generate an AST based on YOUR CUSTOM DSL
-          const typeAST = JsonSchemaUtils.schemaToAST(value);
-
-          if (typeAST) {
-            // Use the node's title or its ID as the title for the variable
-            const title = form?.getValueIn('title') || node.id;
-
-            // Set the variable in the variable engine
-            variableData?.setVar(
-              ASTFactory.createVariableDeclaration({
-                meta: {
-                  title: `${title}`,
-                  icon: node.getNodeRegistry()?.info?.icon,
-                  // NOTICE: You can add more metadata here as needed
-                },
-                key: `${node.id}`,
-                type: typeAST,
-              })
-            );
-          } else {
-            // If the AST cannot be created, clear the variable
-            variableData?.clearVar();
-          }
-        };
-
-        if (form) {
-          // Initially synchronize the output data
-          syncOutputs(form.getValueIn('outputs'));
-
-          // Listen for changes in the form values and re-synchronize when outputs change
-          form.onFormValuesChange((props) => {
-            if (props.name.match(/^outputs/) || props.name.match(/^title/)) {
-              syncOutputs(form.getValueIn('outputs'));
-            }
-          });
-        }
-      });
-    },
-  });

+ 2 - 0
packages/materials/form-antd-materials/src/effects/index.ts

@@ -6,3 +6,5 @@
 export * from './provide-batch-input';
 export * from './provide-batch-outputs';
 export * from './auto-rename-ref';
+export * from './provide-json-schema-outputs';
+export * from './sync-variable-title';

+ 0 - 1
packages/materials/form-antd-materials/src/effects/provide-batch-outputs/index.ts

@@ -14,7 +14,6 @@ import {
 import { IFlowRefValue } from '../../typings';
 
 export const provideBatchOutputsEffect: EffectOptions[] = createEffectFromVariableProvider({
-  private: true,
   parse: (value: Record<string, IFlowRefValue>, ctx) => [
     ASTFactory.createVariableDeclaration({
       key: `${ctx.node.id}`,

+ 8 - 0
packages/materials/form-antd-materials/src/effects/provide-json-schema-outputs/config.json

@@ -0,0 +1,8 @@
+{
+  "name": "provide-json-schema-outputs",
+  "depMaterials": [
+    "typings/json-schema",
+    "utils/json-schema"
+  ],
+  "depPackages": []
+}

+ 28 - 0
packages/materials/form-antd-materials/src/effects/provide-json-schema-outputs/index.ts

@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
+ * SPDX-License-Identifier: MIT
+ */
+
+import {
+  ASTFactory,
+  EffectOptions,
+  FlowNodeRegistry,
+  createEffectFromVariableProvider,
+  getNodeForm,
+} from '@flowgram.ai/editor';
+
+import { JsonSchemaUtils } from '../../utils';
+import { IJsonSchema } from '../../typings';
+
+export const provideJsonSchemaOutputs: EffectOptions[] = createEffectFromVariableProvider({
+  parse: (value: IJsonSchema, ctx) => [
+    ASTFactory.createVariableDeclaration({
+      key: `${ctx.node.id}`,
+      meta: {
+        title: getNodeForm(ctx.node)?.getValueIn('title') || ctx.node.id,
+        icon: ctx.node.getNodeRegistry<FlowNodeRegistry>().info?.icon,
+      },
+      type: JsonSchemaUtils.schemaToAST(value),
+    }),
+  ],
+});

+ 5 - 0
packages/materials/form-antd-materials/src/effects/sync-variable-title/config.json

@@ -0,0 +1,5 @@
+{
+  "name": "sync-variable-title",
+  "depMaterials": [],
+  "depPackages": []
+}

+ 28 - 0
packages/materials/form-antd-materials/src/effects/sync-variable-title/index.ts

@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
+ * SPDX-License-Identifier: MIT
+ */
+
+import {
+  DataEvent,
+  Effect,
+  EffectOptions,
+  FlowNodeRegistry,
+  FlowNodeVariableData,
+} from '@flowgram.ai/editor';
+
+export const syncVariableTitle: EffectOptions[] = [
+  {
+    event: DataEvent.onValueChange,
+    effect: (({ value, context }) => {
+      context.node.getData(FlowNodeVariableData).allScopes.forEach((_scope) => {
+        _scope.output.variables.forEach((_var) => {
+          _var.updateMeta({
+            title: value || context.node.id,
+            icon: context.node.getNodeRegistry<FlowNodeRegistry>().info?.icon,
+          });
+        });
+      });
+    }) as Effect,
+  },
+];

+ 7 - 0
packages/materials/form-antd-materials/src/form-plugins/batch-outputs-plugin/config.json

@@ -0,0 +1,7 @@
+{
+  "name": "batch-outputs-plugin",
+  "depMaterials": [
+    "flow-value"
+  ],
+  "depPackages": []
+}

+ 104 - 0
packages/materials/form-antd-materials/src/form-plugins/batch-outputs-plugin/index.ts

@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
+ * SPDX-License-Identifier: MIT
+ */
+
+import {
+  ASTFactory,
+  createEffectFromVariableProvider,
+  defineFormPluginCreator,
+  FlowNodeRegistry,
+  getNodeForm,
+  getNodePrivateScope,
+  getNodeScope,
+  ScopeChainTransformService,
+  type EffectOptions,
+  type FormPluginCreator,
+  FlowNodeScopeType,
+} from '@flowgram.ai/editor';
+
+import { IFlowRefValue } from '../../typings';
+
+export const provideBatchOutputsEffect: EffectOptions[] = createEffectFromVariableProvider({
+  parse: (value: Record<string, IFlowRefValue>, ctx) => [
+    ASTFactory.createVariableDeclaration({
+      key: `${ctx.node.id}`,
+      meta: {
+        title: getNodeForm(ctx.node)?.getValueIn('title'),
+        icon: ctx.node.getNodeRegistry<FlowNodeRegistry>().info?.icon,
+      },
+      type: ASTFactory.createObject({
+        properties: Object.entries(value).map(([_key, value]) =>
+          ASTFactory.createProperty({
+            key: _key,
+            initializer: ASTFactory.createWrapArrayExpression({
+              wrapFor: ASTFactory.createKeyPathExpression({
+                keyPath: value?.content || [],
+              }),
+            }),
+          })
+        ),
+      }),
+    }),
+  ],
+});
+
+/**
+ * Free Layout only right now
+ */
+export const createBatchOutputsFormPlugin: FormPluginCreator<{ outputKey: string }> =
+  defineFormPluginCreator({
+    name: 'batch-outputs-plugin',
+    onSetupFormMeta({ mergeEffect }, { outputKey }) {
+      mergeEffect({
+        [outputKey]: provideBatchOutputsEffect,
+      });
+    },
+    onInit(ctx, { outputKey }) {
+      const chainTransformService = ctx.node.getService(ScopeChainTransformService);
+
+      const batchNodeType = ctx.node.flowNodeType;
+
+      const transformerId = `${batchNodeType}-outputs`;
+
+      if (chainTransformService.hasTransformer(transformerId)) {
+        return;
+      }
+
+      chainTransformService.registerTransformer(transformerId, {
+        transformCovers: (covers, ctx) => {
+          const node = ctx.scope.meta?.node;
+
+          // Child Node's variable can cover parent
+          if (node?.parent?.flowNodeType === batchNodeType) {
+            return [...covers, getNodeScope(node.parent)];
+          }
+
+          return covers;
+        },
+        transformDeps(scopes, ctx) {
+          const scopeMeta = ctx.scope.meta;
+
+          if (scopeMeta?.type === FlowNodeScopeType.private) {
+            return scopes;
+          }
+
+          const node = scopeMeta?.node;
+
+          // Public of Loop Node depends on child Node
+          if (node?.flowNodeType === batchNodeType) {
+            // Get all child blocks
+            const childBlocks = node.blocks;
+
+            // public scope of all child blocks
+            return [
+              getNodePrivateScope(node),
+              ...childBlocks.map((_childBlock) => getNodeScope(_childBlock)),
+            ];
+          }
+
+          return scopes;
+        },
+      });
+    },
+  });

+ 1 - 1
apps/demo-nextjs-antd/src/editor/plugins/sync-variable-plugin/index.ts → packages/materials/form-antd-materials/src/form-plugins/index.ts

@@ -3,4 +3,4 @@
  * SPDX-License-Identifier: MIT
  */
 
-export * from './sync-variable-plugin';
+export { createBatchOutputsFormPlugin } from './batch-outputs-plugin';

+ 1 - 0
packages/materials/form-antd-materials/src/index.ts

@@ -7,3 +7,4 @@ export * from './components';
 export * from './effects';
 export * from './utils';
 export * from './typings';
+export * from './form-plugins';

+ 1 - 1
packages/materials/form-antd-materials/src/utils/index.ts

@@ -4,5 +4,5 @@
  */
 
 export * from './format-legacy-refs';
-export * from './json-schema';
 export * from './svg-icon';
+export * from './json-schema';

+ 16 - 2
packages/materials/form-antd-materials/src/utils/json-schema/index.ts

@@ -42,7 +42,10 @@ export namespace JsonSchemaUtils {
             .map(([key, _property]) => ({
               key,
               type: schemaToAST(_property),
-              meta: { description: _property.description },
+              meta: {
+                title: _property.title,
+                description: _property.description,
+              },
             })),
         });
       case 'array':
@@ -114,7 +117,18 @@ export namespace JsonSchemaUtils {
         type: 'object',
         properties: drilldown
           ? Object.fromEntries(
-              Object.entries(typeAST.properties).map(([key, value]) => [key, astToSchema(value)!])
+              typeAST.properties.map((property) => {
+                const schema = astToSchema(property.type);
+
+                if (property.meta?.title && schema) {
+                  schema.title = property.meta.title;
+                }
+                if (property.meta?.description && schema) {
+                  schema.description = property.meta.description;
+                }
+
+                return [property.key, schema!];
+              })
             )
           : {},
       };