From c3e4d5a0592236abb0b0149d7324842b0d8f9ccb Mon Sep 17 00:00:00 2001 From: Joel Date: Thu, 21 Aug 2025 15:31:34 +0800 Subject: [PATCH] feat: support choose and save deep obj --- .../config-var/config-modal/index.tsx | 33 ++++++++++++++++--- .../nodes/_base/components/variable/utils.ts | 17 ++++++++-- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/web/app/components/app/configuration/config-var/config-modal/index.tsx b/web/app/components/app/configuration/config-var/config-modal/index.tsx index 9f3944f3d4..af05c0fd57 100644 --- a/web/app/components/app/configuration/config-var/config-modal/index.tsx +++ b/web/app/components/app/configuration/config-var/config-modal/index.tsx @@ -1,6 +1,6 @@ 'use client' import type { ChangeEvent, FC } from 'react' -import React, { useCallback, useEffect, useRef, useState } from 'react' +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { useContext } from 'use-context-selector' import produce from 'immer' @@ -24,7 +24,7 @@ import TypeSelector from './type-select' import { SimpleSelect } from '@/app/components/base/select' import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor' import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' -import { jsonConfigPlaceHolder } from './config' +import { jsonConfigPlaceHolder, jsonObjectWrap } from './config' const TEXT_MAX_LENGTH = 256 @@ -51,6 +51,17 @@ const ConfigModal: FC = ({ const [tempPayload, setTempPayload] = useState(payload || getNewVarInWorkflow('') as any) const { type, label, variable, options, max_length } = tempPayload const modalRef = useRef(null) + const jsonSchemaStr = useMemo(() => { + const isJsonObject = type === InputVarType.jsonObject + if (!isJsonObject || !tempPayload.json_schema) + return '' + try { + return JSON.stringify(JSON.parse(tempPayload.json_schema).properties, null, 2) + } + catch (_e) { + return '' + } + }, [tempPayload.json_schema]) useEffect(() => { // To fix the first input element auto focus, then directly close modal will raise error if (isShow) @@ -82,6 +93,20 @@ const ConfigModal: FC = ({ } }, []) + const handleJSONSchemaChange = useCallback((value: string) => { + try { + const v = JSON.parse(value) + const res = { + ...jsonObjectWrap, + properties: v, + } + handlePayloadChange('json_schema')(JSON.stringify(res, null, 2)) + } + catch (_e) { + return null + } + }, [handlePayloadChange]) + const selectOptions: SelectItem[] = [ { name: t('appDebug.variableConfig.text-input'), @@ -296,8 +321,8 @@ const ConfigModal: FC = ({ handlePayloadChange('json_schema')(value)} + value={jsonSchemaStr} + onChange={handleJSONSchemaChange} noWrapper className='bg h-[80px] overflow-y-auto rounded-[10px] bg-components-input-bg-normal p-1' placeholder={ diff --git a/web/app/components/workflow/nodes/_base/components/variable/utils.ts b/web/app/components/workflow/nodes/_base/components/variable/utils.ts index e5c17f6c5c..fcba45eb83 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/utils.ts +++ b/web/app/components/workflow/nodes/_base/components/variable/utils.ts @@ -229,14 +229,27 @@ const formatItem = ( variables, } = data as StartNodeType res.vars = variables.map((v) => { - return { + const type = inputVarTypeToVarType(v.type) + const varRes: Var = { variable: v.variable, - type: inputVarTypeToVarType(v.type), + type, isParagraph: v.type === InputVarType.paragraph, isSelect: v.type === InputVarType.select, options: v.options, required: v.required, } + try { + if(type === VarType.object && v.json_schema) { + varRes.children = { + schema: JSON.parse(v.json_schema), + } + } + } + catch (error) { + console.error('Error formatting variable:', error) + } + + return varRes }) if (isChatMode) { res.vars.push({