feat: can edit and choose obj

This commit is contained in:
Joel
2025-08-21 14:47:29 +08:00
parent 76659843d7
commit 30775109fd
9 changed files with 65 additions and 4 deletions

View File

@ -0,0 +1,24 @@
export const jsonObjectWrap = {
type: 'object',
properties: {},
required: [],
additionalProperties: true,
}
export const jsonConfigPlaceHolder = JSON.stringify(
{
foo: {
type: 'string',
},
bar: {
type: 'object',
properties: {
sub: {
type: 'number',
},
},
required: [],
additionalProperties: true,
},
}, null, 2,
)

View File

@ -2,21 +2,28 @@
import type { FC } from 'react'
import React from 'react'
import cn from '@/utils/classnames'
import { useTranslation } from 'react-i18next'
type Props = {
className?: string
title: string
isOptional?: boolean
children: React.JSX.Element
}
const Field: FC<Props> = ({
className,
title,
isOptional,
children,
}) => {
const { t } = useTranslation()
return (
<div className={cn(className)}>
<div className='system-sm-semibold leading-8 text-text-secondary'>{title}</div>
<div className='system-sm-semibold leading-8 text-text-secondary'>
{title}
{isOptional && <span className='system-xs-regular ml-1 text-text-tertiary'>({t('appDebug.variableConfig.optional')})</span>}
</div>
<div>{children}</div>
</div>
)

View File

@ -22,6 +22,9 @@ import { DEFAULT_VALUE_MAX_LEN } from '@/config'
import type { Item as SelectItem } from './type-select'
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'
const TEXT_MAX_LENGTH = 256
@ -110,6 +113,10 @@ const ConfigModal: FC<IConfigModalProps> = ({
value: InputVarType.multiFiles,
},
] : []),
{
name: t('appDebug.variableConfig.json'),
value: InputVarType.jsonObject,
},
]
const handleTypeChange = useCallback((item: SelectItem) => {
@ -285,6 +292,21 @@ const ConfigModal: FC<IConfigModalProps> = ({
/>
)}
{type === InputVarType.jsonObject && (
<Field title={t('appDebug.variableConfig.jsonSchema')} isOptional>
<CodeEditor
language={CodeLanguage.json}
value={tempPayload.json_schema}
onChange={value => handlePayloadChange('json_schema')(value)}
noWrapper
className='bg h-[80px] overflow-y-auto rounded-[10px] bg-components-input-bg-normal p-1'
placeholder={
<div className='whitespace-pre'>{jsonConfigPlaceHolder}</div>
}
/>
</Field>
)}
<div className='!mt-5 flex h-6 items-center space-x-2'>
<Checkbox checked={tempPayload.required} disabled={tempPayload.hide} onCheck={() => handlePayloadChange('required')(!tempPayload.required)} />
<span className='system-sm-semibold text-text-secondary'>{t('appDebug.variableConfig.required')}</span>

View File

@ -2,7 +2,6 @@
import type { FC } from 'react'
import React, { useState } from 'react'
import { ChevronDownIcon } from '@heroicons/react/20/solid'
import { useTranslation } from 'react-i18next'
import classNames from '@/utils/classnames'
import {
PortalToFollowElem,
@ -36,7 +35,6 @@ const TypeSelector: FC<Props> = ({
popupInnerClassName,
readonly,
}) => {
const { t } = useTranslation()
const [open, setOpen] = useState(false)
const selectedItem = value ? items.find(item => item.value === value) : undefined

View File

@ -1,7 +1,7 @@
'use client'
import type { FC } from 'react'
import React from 'react'
import { RiAlignLeft, RiCheckboxLine, RiCheckboxMultipleLine, RiFileCopy2Line, RiFileList2Line, RiHashtag, RiTextSnippet } from '@remixicon/react'
import { RiAlignLeft, RiBracesLine, RiCheckboxLine, RiCheckboxMultipleLine, RiFileCopy2Line, RiFileList2Line, RiHashtag, RiTextSnippet } from '@remixicon/react'
import { InputVarType } from '../../../types'
type Props = {
@ -16,6 +16,7 @@ const getIcon = (type: InputVarType) => {
[InputVarType.select]: RiCheckboxMultipleLine,
[InputVarType.number]: RiHashtag,
[InputVarType.checkbox]: RiCheckboxLine,
[InputVarType.jsonObject]: RiBracesLine,
[InputVarType.singleFile]: RiFileList2Line,
[InputVarType.multiFiles]: RiFileCopy2Line,
} as any)[type] || RiTextSnippet

View File

@ -62,6 +62,7 @@ export const inputVarTypeToVarType = (type: InputVarType): VarType => {
[InputVarType.checkbox]: VarType.boolean,
[InputVarType.singleFile]: VarType.file,
[InputVarType.multiFiles]: VarType.arrayFile,
[InputVarType.jsonObject]: VarType.object,
} as any)[type] || VarType.string
}

View File

@ -184,6 +184,7 @@ export enum InputVarType {
url = 'url',
files = 'files',
json = 'json', // obj, array
jsonObject = 'json_object', // only object support define json schema
contexts = 'contexts', // knowledge retrieval
iterator = 'iterator', // iteration input
singleFile = 'file',
@ -209,6 +210,7 @@ export type InputVar = {
getVarValueFromDependent?: boolean
hide?: boolean
isFileItem?: boolean
json_schema?: string // for jsonObject type
} & Partial<UploadFileSetting>
export type ModelConfig = {

View File

@ -375,6 +375,9 @@ const translation = {
'select': 'Select',
'number': 'Number',
'checkbox': 'Checkbox',
'json': 'JSON Code',
'jsonSchema': 'JSON Schema',
'optional': 'optional',
'single-file': 'Single File',
'multi-files': 'File List',
'notSet': 'Not set, try typing {{input}} in the prefix prompt',

View File

@ -375,6 +375,9 @@ const translation = {
'checkbox': '复选框',
'single-file': '单文件',
'multi-files': '文件列表',
'json': 'JSON',
'jsonSchema': 'JSON Schema',
'optional': '可选',
'notSet': '未设置,在 Prompt 中输入 {{input}} 试试',
'stringTitle': '文本框设置',
'maxLength': '最大长度',