This commit is contained in:
zxhlyh 2025-08-14 15:58:50 +08:00
parent a5dfc09e90
commit 944b2ff22d
9 changed files with 262 additions and 298 deletions

View File

@ -64,7 +64,6 @@ const BaseField = ({
onChange,
} = formSchema
const type = typeof typeOrFn === 'function' ? typeOrFn(field.form) : typeOrFn
console.log('type', field.name, type)
const memorizedLabel = useMemo(() => {
if (isValidElement(label))
@ -120,13 +119,12 @@ const BaseField = ({
const show = useMemo(() => {
return (Array.isArray(show_on) ? show_on : show_on(field.form)).every((condition) => {
const conditionValue = values[condition.variable]
console.log('conditionValue', condition.value, field.name, conditionValue)
return Array.isArray(condition.value) ? condition.value.includes(conditionValue) : conditionValue === condition.value
})
}, [values, show_on, field.name])
const handleChange = useCallback((value: any) => {
field.handleChange(value)
onChange?.(field.form)
onChange?.(field.form, value)
}, [field, onChange])
if (!show)

View File

@ -69,7 +69,7 @@ export type FormSchema = {
inputClassName?: string
validators?: AnyValidators
selfFormProps?: (form: AnyFormApi) => Record<string, any>
onChange?: (form: AnyFormApi) => void
onChange?: (form: AnyFormApi, v: any) => void
}
export type FormValues = Record<string, any>

View File

@ -57,7 +57,9 @@ const ChatVariableModal = ({
const handleConfirm = useCallback(async () => {
const {
values,
} = formRef.current?.getFormValues({}) || { isCheckValidated: false, values: {} }
} = formRef.current?.getFormValues({
needCheckValidatedValues: true,
}) || { isCheckValidated: false, values: {} }
const {
name,
type,

View File

@ -0,0 +1,37 @@
import { ChatVarType } from './type'
export const objectPlaceholder = `# example
# {
# "name": "ray",
# "age": 20
# }`
export const arrayStringPlaceholder = `# example
# [
# "value1",
# "value2"
# ]`
export const arrayNumberPlaceholder = `# example
# [
# 100,
# 200
# ]`
export const arrayObjectPlaceholder = `# example
# [
# {
# "name": "ray",
# "age": 20
# },
# {
# "name": "lily",
# "age": 18
# }
# ]`
export const typeList = [
ChatVarType.String,
ChatVarType.Number,
ChatVarType.Object,
ChatVarType.ArrayString,
ChatVarType.ArrayNumber,
ChatVarType.ArrayObject,
'memory',
]

View File

@ -1,293 +0,0 @@
import { useTranslation } from 'react-i18next'
import type {
AnyFormApi,
} from '@tanstack/react-form'
import { ChatVarType } from '@/app/components/workflow/panel/chat-variable-panel/type'
import { useCallback, useMemo } from 'react'
// import { DEFAULT_OBJECT_VALUE } from '@/app/components/workflow/panel/chat-variable-panel/components/object-value-item'
// import type { ConversationVariable } from '@/app/components/workflow/types'
const objectPlaceholder = `# example
# {
# "name": "ray",
# "age": 20
# }`
const arrayStringPlaceholder = `# example
# [
# "value1",
# "value2"
# ]`
const arrayNumberPlaceholder = `# example
# [
# 100,
# 200
# ]`
const arrayObjectPlaceholder = `# example
# [
# {
# "name": "ray",
# "age": 20
# },
# {
# "name": "lily",
# "age": 18
# }
# ]`
const typeList = [
ChatVarType.String,
ChatVarType.Number,
ChatVarType.Object,
ChatVarType.ArrayString,
ChatVarType.ArrayNumber,
ChatVarType.ArrayObject,
'memory',
]
export const useForm = () => {
const { t } = useTranslation()
const getEditModeLabel = useCallback((form: AnyFormApi) => {
const {
type,
editInJSON,
} = form.state.values
const editModeLabelWhenFalse = t('workflow.chatVariable.modal.editInJSON')
let editModeLabelWhenTrue = t('workflow.chatVariable.modal.oneByOne')
if (type === ChatVarType.Object)
editModeLabelWhenTrue = t('workflow.chatVariable.modal.editInForm')
return {
editModeLabel: editInJSON ? editModeLabelWhenTrue : editModeLabelWhenFalse,
}
}, [t])
const handleTypeChange = useCallback((form: AnyFormApi) => {
const {
resetField,
} = form
resetField('editInJSON')
resetField('objectListValue')
resetField('arrayListValue')
resetField('jsonValue')
}, [])
const handleEditInJSONChange = useCallback((form: AnyFormApi) => {
const {
resetField,
} = form
resetField('objectListValue')
resetField('arrayListValue')
resetField('jsonValue')
}, [])
const getValueFormType = useCallback((form: AnyFormApi) => {
const {
type,
editInJSON,
} = form.state.values
if (type === ChatVarType.String) {
return 'textarea-input'
}
else if (type === ChatVarType.Number) {
return 'number-input'
}
else if (type === ChatVarType.Object) {
if (editInJSON)
return 'json-input'
else
return 'object-list'
}
else if (type === ChatVarType.ArrayString || type === ChatVarType.ArrayNumber) {
if (editInJSON)
return 'json-input'
else
return 'array-list'
}
else if (type === ChatVarType.ArrayObject) {
return 'json-input'
}
}, [])
const getSelfFormProps = useCallback((form: AnyFormApi) => {
const {
type,
editInJSON,
} = form.state.values
if (editInJSON || type === ChatVarType.ArrayObject) {
let minHeight = '120px'
if (type === ChatVarType.ArrayObject)
minHeight = '240px'
let placeholder = objectPlaceholder
if (type === ChatVarType.ArrayString)
placeholder = arrayStringPlaceholder
else if (type === ChatVarType.ArrayNumber)
placeholder = arrayNumberPlaceholder
else if (type === ChatVarType.ArrayObject)
placeholder = arrayObjectPlaceholder
return {
editorMinHeight: minHeight,
placeholder,
}
}
if (type === ChatVarType.ArrayString || type === ChatVarType.ArrayNumber) {
if (!editInJSON) {
return {
isString: type === ChatVarType.ArrayString,
}
}
}
}, [])
const formSchemas = useMemo(() => {
return [
{
name: 'name',
label: t('workflow.chatVariable.modal.name'),
type: 'text-input',
placeholder: t('workflow.chatVariable.modal.namePlaceholder'),
required: true,
},
{
name: 'type',
label: t('workflow.chatVariable.modal.type'),
type: 'select',
options: typeList.map(type => ({
label: type,
value: type,
})),
onChange: handleTypeChange,
required: true,
},
{
name: 'editInJSON',
label: '',
type: 'edit-mode',
show_on: [
{
variable: 'type',
value: [ChatVarType.Object, ChatVarType.ArrayString, ChatVarType.ArrayNumber],
},
],
selfFormProps: getEditModeLabel,
labelClassName: '-mb-9 justify-end',
onChange: handleEditInJSONChange,
},
{
name: 'value',
label: t('workflow.chatVariable.modal.value'),
type: getValueFormType,
placeholder: t('workflow.chatVariable.modal.valuePlaceholder'),
show_on: [
{
variable: 'type',
value: [ChatVarType.String, ChatVarType.Number, ChatVarType.Object, ChatVarType.ArrayString, ChatVarType.ArrayNumber, ChatVarType.ArrayObject],
},
],
selfFormProps: getSelfFormProps,
},
// {
// name: 'objectListValue',
// label: t('workflow.chatVariable.modal.value'),
// type: 'object-list',
// placeholder: t('workflow.chatVariable.modal.valuePlaceholder'),
// show_on: [
// {
// variable: 'type',
// value: ChatVarType.Object,
// },
// {
// variable: 'editInJSON',
// value: false,
// },
// ],
// },
// {
// name: 'arrayListValue',
// label: t('workflow.chatVariable.modal.value'),
// type: 'array-list',
// placeholder: t('workflow.chatVariable.modal.valuePlaceholder'),
// show_on: [
// {
// variable: 'type',
// value: [ChatVarType.ArrayString, ChatVarType.ArrayNumber],
// },
// {
// variable: 'editInJSON',
// value: false,
// },
// ],
// selfFormProps: getArrayListProps,
// },
// {
// name: 'jsonValue',
// label: t('workflow.chatVariable.modal.value'),
// type: 'json-input',
// placeholder: arrayObjectPlaceholder,
// show_on: getJsonEditorShowOn,
// selfFormProps: getJsonEditorProps,
// },
// {
// name: 'description',
// label: t('workflow.chatVariable.modal.description'),
// type: 'textarea-input',
// placeholder: t('workflow.chatVariable.modal.descriptionPlaceholder'),
// show_on: [
// {
// variable: 'type',
// value: [ChatVarType.String, ChatVarType.Number, ChatVarType.Object, ChatVarType.ArrayString, ChatVarType.ArrayNumber, ChatVarType.ArrayObject],
// },
// ],
// },
// {
// name: 'memoryTemplate',
// label: 'Memory template',
// type: 'prompt-input',
// },
// {
// name: 'updateTrigger',
// label: 'Update trigger',
// type: 'radio',
// required: true,
// fieldClassName: 'flex items-center justify-between',
// options: [
// {
// label: 'Every N turns',
// value: 'every_n_turns',
// },
// {
// label: 'Auto',
// value: 'auto',
// },
// ],
// },
// {
// name: 'moreSettings',
// label: 'More settings',
// type: 'collapse',
// },
// {
// name: 'memoryModel',
// label: 'Memory model',
// type: 'model-selector',
// show_on: [
// {
// variable: 'moreSettings',
// value: true,
// },
// ],
// },
]
}, [t, handleTypeChange, handleEditInJSONChange, getValueFormType, getSelfFormProps])
const defaultValues = useMemo(() => {
return {
type: ChatVarType.String,
value: '',
// textareaInputValue: '',
// numberInputValue: 0,
// objectListValue: [DEFAULT_OBJECT_VALUE],
// arrayListValue: [undefined],
editInJSON: false,
}
}, [])
return {
formSchemas,
defaultValues,
}
}

View File

@ -0,0 +1,41 @@
import { useTranslation } from 'react-i18next'
import { ChatVarType } from '@/app/components/workflow/panel/chat-variable-panel/type'
import { useMemo } from 'react'
import { useTypeSchema } from './use-type-schema'
import { useValueSchema } from './use-value-schema'
import { useEditInJSONSchema } from './use-edit-in-json-schema'
export const useForm = () => {
const { t } = useTranslation()
const typeSchema = useTypeSchema()
const valueSchema = useValueSchema()
const editInJSONSchema = useEditInJSONSchema()
const formSchemas = useMemo(() => {
return [
{
name: 'name',
label: t('workflow.chatVariable.modal.name'),
type: 'text-input',
placeholder: t('workflow.chatVariable.modal.namePlaceholder'),
required: true,
},
typeSchema,
editInJSONSchema,
valueSchema,
]
}, [t, valueSchema, typeSchema, editInJSONSchema])
const defaultValues = useMemo(() => {
return {
type: ChatVarType.String,
value: '',
editInJSON: false,
}
}, [])
return {
formSchemas,
defaultValues,
}
}

View File

@ -0,0 +1,47 @@
import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import type {
AnyFormApi,
} from '@tanstack/react-form'
import { ChatVarType } from '@/app/components/workflow/panel/chat-variable-panel/type'
export const useEditInJSONSchema = () => {
const { t } = useTranslation()
const getEditModeLabel = useCallback((form: AnyFormApi) => {
const {
type,
editInJSON,
} = form.state.values
const editModeLabelWhenFalse = t('workflow.chatVariable.modal.editInJSON')
let editModeLabelWhenTrue = t('workflow.chatVariable.modal.oneByOne')
if (type === ChatVarType.Object)
editModeLabelWhenTrue = t('workflow.chatVariable.modal.editInForm')
return {
editModeLabel: editInJSON ? editModeLabelWhenTrue : editModeLabelWhenFalse,
}
}, [t])
const handleEditInJSONChange = useCallback((form: AnyFormApi) => {
const {
resetField,
} = form
resetField('objectListValue')
resetField('arrayListValue')
resetField('jsonValue')
}, [])
return {
name: 'editInJSON',
label: '',
type: 'edit-mode',
show_on: [
{
variable: 'type',
value: [ChatVarType.Object, ChatVarType.ArrayString, ChatVarType.ArrayNumber],
},
],
selfFormProps: getEditModeLabel,
labelClassName: '-mb-9 justify-end',
onChange: handleEditInJSONChange,
}
}

View File

@ -0,0 +1,41 @@
import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import type {
AnyFormApi,
} from '@tanstack/react-form'
import { ChatVarType } from '@/app/components/workflow/panel/chat-variable-panel/type'
import { DEFAULT_OBJECT_VALUE } from '@/app/components/workflow/panel/chat-variable-panel/components/object-value-item'
import { typeList } from '@/app/components/workflow/panel/chat-variable-panel/constants'
export const useTypeSchema = () => {
const { t } = useTranslation()
const handleTypeChange = useCallback((form: AnyFormApi, v: string) => {
const {
setFieldValue,
} = form
if (v === ChatVarType.String)
setFieldValue('value', '')
else if (v === ChatVarType.Number)
setFieldValue('value', 0)
else if (v === ChatVarType.Object)
setFieldValue('value', [DEFAULT_OBJECT_VALUE])
else if (v === ChatVarType.ArrayString)
setFieldValue('value', [undefined])
else if (v === ChatVarType.ArrayNumber)
setFieldValue('value', [undefined])
else if (v === ChatVarType.ArrayObject)
setFieldValue('value', undefined)
}, [])
return {
name: 'type',
label: t('workflow.chatVariable.modal.type'),
type: 'select',
options: typeList.map(type => ({
label: type,
value: type,
})),
onChange: handleTypeChange,
required: true,
}
}

View File

@ -0,0 +1,91 @@
import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import type {
AnyFormApi,
} from '@tanstack/react-form'
import { ChatVarType } from '@/app/components/workflow/panel/chat-variable-panel/type'
import {
arrayNumberPlaceholder,
arrayObjectPlaceholder,
arrayStringPlaceholder,
objectPlaceholder,
} from '@/app/components/workflow/panel/chat-variable-panel/constants'
export const useValueSchema = () => {
const { t } = useTranslation()
const getValueFormType = useCallback((form: AnyFormApi) => {
const {
type,
editInJSON,
} = form.state.values
console.log(editInJSON, 'editInJSON', type, 'type')
if (type === ChatVarType.String) {
return 'textarea-input'
}
else if (type === ChatVarType.Number) {
return 'number-input'
}
else if (type === ChatVarType.Object) {
if (editInJSON)
return 'json-input'
else
return 'object-list'
}
else if (type === ChatVarType.ArrayString || type === ChatVarType.ArrayNumber) {
if (editInJSON)
return 'json-input'
else
return 'array-list'
}
else if (type === ChatVarType.ArrayObject) {
return 'json-input'
}
}, [])
const getSelfFormProps = useCallback((form: AnyFormApi) => {
const {
type,
editInJSON,
} = form.state.values
if (editInJSON || type === ChatVarType.ArrayObject) {
let minHeight = '120px'
if (type === ChatVarType.ArrayObject)
minHeight = '240px'
let placeholder = objectPlaceholder
if (type === ChatVarType.ArrayString)
placeholder = arrayStringPlaceholder
else if (type === ChatVarType.ArrayNumber)
placeholder = arrayNumberPlaceholder
else if (type === ChatVarType.ArrayObject)
placeholder = arrayObjectPlaceholder
return {
editorMinHeight: minHeight,
placeholder,
}
}
if (type === ChatVarType.ArrayString || type === ChatVarType.ArrayNumber) {
if (!editInJSON) {
return {
isString: type === ChatVarType.ArrayString,
}
}
}
}, [])
return {
name: 'value',
label: t('workflow.chatVariable.modal.value'),
type: getValueFormType,
placeholder: t('workflow.chatVariable.modal.valuePlaceholder'),
show_on: [
{
variable: 'type',
value: [ChatVarType.String, ChatVarType.Number, ChatVarType.Object, ChatVarType.ArrayString, ChatVarType.ArrayNumber, ChatVarType.ArrayObject],
},
{
variable: 'editInJSON',
value: [true, false],
},
],
selfFormProps: getSelfFormProps,
}
}