瀏覽代碼

fix(materials): editor-with-variables bugs (#708)

* fix(material): {{{xxx}} render in editor-with-variables

* fix(material): prompt-with-inputs from inputs-values-tree
Yiwei Mao 4 月之前
父節點
當前提交
3adc1cff1b

+ 6 - 1
apps/demo-free-layout/src/nodes/default-form-meta.tsx

@@ -3,7 +3,12 @@
  * SPDX-License-Identifier: MIT
  */
 
-import { FormRenderProps, FormMeta, ValidateTrigger } from '@flowgram.ai/free-layout-editor';
+import {
+  FormRenderProps,
+  FormMeta,
+  ValidateTrigger,
+  getNodeScope,
+} from '@flowgram.ai/free-layout-editor';
 import {
   autoRenameRefEffect,
   provideJsonSchemaOutputs,

+ 1 - 1
packages/materials/form-materials/src/components/json-editor-with-variables/extensions/variable-tag.tsx

@@ -134,7 +134,7 @@ export function VariableTagInject() {
   // 基于 {{var}} 的正则进行匹配,匹配后进行自定义渲染
   useLayoutEffect(() => {
     const atMatcher = new MatchDecorator({
-      regexp: /\{\{([^\}]+)\}\}/g,
+      regexp: /\{\{([^\}\{]+)\}\}/g,
       decoration: (match) =>
         Decoration.replace({
           widget: new VariableTagWidget({

+ 1 - 2
packages/materials/form-materials/src/components/prompt-editor-with-inputs/index.tsx

@@ -5,13 +5,12 @@
 
 import React from 'react';
 
-import { IFlowValue } from '@/typings';
 import { PromptEditor, PromptEditorPropsType } from '@/components/prompt-editor';
 
 import { InputsTree } from './extensions/inputs-tree';
 
 interface PropsType extends PromptEditorPropsType {
-  inputsValues: Record<string, IFlowValue>;
+  inputsValues: any;
 }
 
 export function PromptEditorWithInputs({ inputsValues, ...restProps }: PropsType) {

+ 34 - 17
packages/materials/form-materials/src/components/prompt-editor-with-inputs/inputs-picker.tsx

@@ -5,7 +5,7 @@
 
 import React, { useMemo } from 'react';
 
-import { last } from 'lodash';
+import { isPlainObject, last } from 'lodash';
 import {
   type ArrayType,
   ASTMatch,
@@ -16,7 +16,7 @@ import {
 import { TreeNodeData } from '@douyinfe/semi-ui/lib/es/tree';
 import { Tree } from '@douyinfe/semi-ui';
 
-import { IFlowValue } from '@/typings';
+import { FlowValueUtils } from '@/shared';
 
 type VariableField = BaseVariableField<{ icon?: string | JSX.Element; title?: string }>;
 
@@ -24,7 +24,7 @@ export function InputsPicker({
   inputsValues,
   onSelect,
 }: {
-  inputsValues: Record<string, IFlowValue>;
+  inputsValues: any;
   onSelect: (v: string) => void;
 }) {
   const available = useScopeAvailable();
@@ -76,23 +76,40 @@ export function InputsPicker({
     };
   };
 
-  const treeData: TreeNodeData[] = useMemo(
-    () =>
-      Object.entries(inputsValues).map(([key, value]) => {
-        if (value?.type === 'ref') {
-          const variable = available.getByKeyPath(value.content || []);
+  const getTreeData = (value: any, keyPath: string[]): TreeNodeData | undefined => {
+    const currKey = keyPath.join('.');
 
-          if (variable) {
-            return renderVariable(variable, [key]);
-          }
+    if (FlowValueUtils.isFlowValue(value)) {
+      if (FlowValueUtils.isRef(value)) {
+        const variable = available.getByKeyPath(value.content || []);
+        if (variable) {
+          return renderVariable(variable, keyPath);
         }
+      }
+      return {
+        key: currKey,
+        value: currKey,
+        label: last(keyPath),
+      };
+    }
 
-        return {
-          key,
-          value: key,
-          label: key,
-        };
-      }),
+    if (isPlainObject(value)) {
+      return {
+        key: currKey,
+        value: currKey,
+        label: last(keyPath),
+        children: Object.entries(value)
+          .map(([key, value]) => getTreeData(value, [...keyPath, key])!)
+          .filter(Boolean),
+      };
+    }
+  };
+
+  const treeData: TreeNodeData[] = useMemo(
+    () =>
+      Object.entries(inputsValues)
+        .map(([key, value]) => getTreeData(value, [key])!)
+        .filter(Boolean),
     []
   );
 

+ 1 - 1
packages/materials/form-materials/src/components/prompt-editor-with-variables/extensions/variable-tag.tsx

@@ -143,7 +143,7 @@ export function VariableTagInject() {
   // 基于 {{var}} 的正则进行匹配,匹配后进行自定义渲染
   useLayoutEffect(() => {
     const atMatcher = new MatchDecorator({
-      regexp: /\{\{([^\}]+)\}\}/g,
+      regexp: /\{\{([^\}\{]+)\}\}/g,
       decoration: (match) =>
         Decoration.replace({
           widget: new VariableTagWidget({

+ 1 - 1
packages/materials/form-materials/src/shared/flow-value/utils.ts

@@ -121,7 +121,7 @@ export namespace FlowValueUtils {
    */
   export function getTemplateKeyPaths(value: IFlowTemplateValue) {
     // find all keyPath wrapped in {{}}
-    const keyPathReg = /{{(.*?)}}/g;
+    const keyPathReg = /\{\{([^\}\{]+)\}\}/g;
     return uniq(value.content?.match(keyPathReg) || []).map((_keyPath) =>
       _keyPath.slice(2, -2).split('.')
     );

+ 4 - 16
packages/materials/form-materials/src/validate/validate-flow-value/index.tsx

@@ -3,10 +3,11 @@
  * SPDX-License-Identifier: MIT
  */
 
-import { isNil, uniq } from 'lodash';
+import { isNil } from 'lodash';
 import { FeedbackLevel, FlowNodeEntity, getNodeScope } from '@flowgram.ai/editor';
 
-import { IFlowTemplateValue, IFlowValue } from '@/typings';
+import { IFlowValue } from '@/typings';
+import { FlowValueUtils } from '@/shared';
 
 interface Context {
   node: FlowNodeEntity;
@@ -43,7 +44,7 @@ export function validateFlowValue(value: IFlowValue | undefined, ctx: Context) {
   }
 
   if (value?.type === 'template') {
-    const allRefs = getTemplateKeyPaths(value);
+    const allRefs = FlowValueUtils.getTemplateKeyPaths(value);
 
     for (const ref of allRefs) {
       const variable = getNodeScope(node).available.getByKeyPath(ref);
@@ -58,16 +59,3 @@ export function validateFlowValue(value: IFlowValue | undefined, ctx: Context) {
 
   return undefined;
 }
-
-/**
- * get template key paths
- * @param value
- * @returns
- */
-function getTemplateKeyPaths(value: IFlowTemplateValue) {
-  // find all keyPath wrapped in {{}}
-  const keyPathReg = /{{(.*?)}}/g;
-  return uniq(value.content?.match(keyPathReg) || []).map((_keyPath) =>
-    _keyPath.slice(2, -2).split('.')
-  );
-}