feat: can input json editor

This commit is contained in:
Joel
2025-06-10 14:58:03 +08:00
parent 1c44fb77af
commit b73e64b975
5 changed files with 33 additions and 11 deletions

View File

@ -75,7 +75,7 @@ const Base: FC<Props> = ({
return (
<Wrap className={cn(wrapClassName)} style={wrapStyle} isInNode={isInNode} isExpand={isExpand}>
<div ref={ref} className={cn(className, isExpand && 'h-full', 'rounded-lg border', isFocus ? 'border-transparent bg-components-input-bg-normal' : 'overflow-hidden border-components-input-border-hover bg-components-input-bg-hover')}>
<div ref={ref} className={cn(className, isExpand && 'h-full', 'rounded-lg border', !isFocus ? 'border-transparent bg-components-input-bg-normal' : 'overflow-hidden border-components-input-border-hover bg-components-input-bg-hover')}>
<div className='flex h-7 items-center justify-between pl-3 pr-2 pt-1'>
<div className='system-xs-semibold-uppercase text-text-secondary'>{title}</div>
<div className='flex items-center' onClick={(e) => {

View File

@ -22,7 +22,7 @@ export type Props = {
value?: string | object
placeholder?: React.JSX.Element | string
onChange?: (value: string) => void
title?: React.JSX.Element
title?: string | React.JSX.Element
language: CodeLanguage
headerRight?: React.JSX.Element
readOnly?: boolean

View File

@ -20,6 +20,8 @@ import AppSelector from '@/app/components/plugins/plugin-detail-panel/app-select
import ModelParameterModal from '@/app/components/plugins/plugin-detail-panel/model-selector'
import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker'
import cn from '@/utils/classnames'
import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor'
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
type Props = {
readOnly: boolean
@ -54,12 +56,15 @@ const FormInputItem: FC<Props> = ({
const isNumber = type === FormTypeEnum.textNumber
const isObject = type === FormTypeEnum.object
const isArray = type === FormTypeEnum.array
const isShowJSONEditor = isObject || isArray
const isBoolean = type === FormTypeEnum.boolean
const isSelect = type === FormTypeEnum.select
const isAppSelector = type === FormTypeEnum.appSelector
const isModelSelector = type === FormTypeEnum.modelSelector
const isFile = type === FormTypeEnum.file || type === FormTypeEnum.files
const showTypeSwitch = isNumber || isObject || isArray
const isVariable = varInput?.type === VarKindType.variable
const isConstant = varInput?.type === VarKindType.constant
const { availableVars, availableNodesWithParent } = useAvailableVarList(nodeId, {
onlyLeafNodeVar: false,
@ -168,9 +173,9 @@ const FormInputItem: FC<Props> = ({
}, [])
return (
<div className='flex gap-1'>
<div className={cn('gap-1', !(isShowJSONEditor && isConstant) && 'flex')}>
{showTypeSwitch && !hideTypeSwitch && (
<FormInputTypeSwitch value={varInput?.type} onChange={handleTypeChange}/>
<FormInputTypeSwitch value={varInput?.type || VarKindType.constant} onChange={handleTypeChange}/>
)}
{isString && (
<MixedInput
@ -185,7 +190,7 @@ const FormInputItem: FC<Props> = ({
placeholderClassName='!leading-[21px]'
/>
)}
{isNumber && varInput?.type === VarKindType.constant && (
{isNumber && isConstant && (
<Input
className='h-8 grow'
type='number'
@ -215,6 +220,20 @@ const FormInputItem: FC<Props> = ({
placeholder={placeholder?.[language] || placeholder?.en_US}
/>
)}
{isShowJSONEditor && isConstant && (
<div className='mt-1 w-full'>
<CodeEditor
title='JSON'
value={varInput?.value as any}
isExpand
height={100}
language={CodeLanguage.json}
onChange={handleValueChange}
className='w-full'
placeholder={<div className='whitespace-pre'>{placeholder?.[language] || placeholder?.en_US}</div>}
/>
</div>
)}
{isAppSelector && (
<AppSelector
disabled={readOnly}
@ -223,7 +242,7 @@ const FormInputItem: FC<Props> = ({
onSelect={handleValueChange}
/>
)}
{isModelSelector && (
{isModelSelector && isConstant && (
<ModelParameterModal
popupClassName='!w-[387px]'
isAdvancedMode
@ -234,7 +253,7 @@ const FormInputItem: FC<Props> = ({
scope={scope}
/>
)}
{varInput?.type === VarKindType.variable && (
{isVariable && (
<VarReferencePicker
className='h-8 grow'
readonly={readOnly}

View File

@ -10,8 +10,8 @@ import { VarType } from '@/app/components/workflow/nodes/tool/types'
import cn from '@/utils/classnames'
type Props = {
value: string
onChange: (value: string) => void
value: VarType
onChange: (value: VarType) => void
}
const FormInputTypeSwitch: FC<Props> = ({
@ -20,7 +20,7 @@ const FormInputTypeSwitch: FC<Props> = ({
}) => {
const { t } = useTranslation()
return (
<div className='flex h-8 shrink-0 gap-px rounded-[10px] bg-components-segmented-control-bg-normal p-0.5'>
<div className='inline-flex h-8 shrink-0 gap-px rounded-[10px] bg-components-segmented-control-bg-normal p-0.5'>
<Tooltip
popupContent={value === VarType.variable ? '' : t('workflow.nodes.common.typeSwitch.variable')}
>

View File

@ -178,8 +178,11 @@ const useConfig = (id: string, payload: ToolNodeType) => {
const res = produce(inputVarValues, (draft) => {
Object.keys(inputs.tool_parameters).forEach((key: string) => {
const { type, value } = inputs.tool_parameters[key]
if (type === VarType.constant && (value === undefined || value === null))
if (type === VarType.constant && (value === undefined || value === null)) {
if(!draft.tool_parameters || !draft.tool_parameters[key])
return
draft.tool_parameters[key].value = value
}
})
})
return res