feat: add input field variables change sync

This commit is contained in:
twwu 2025-05-28 16:38:49 +08:00
parent 769b5e185a
commit cc7ad5ac97
6 changed files with 63 additions and 14 deletions

View File

@ -6,11 +6,12 @@ import { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import type { InputVar } from '@/models/pipeline'
import type { FormData } from './form/types'
import type { MoreInfo } from '@/app/components/workflow/types'
type InputFieldEditorProps = {
show: boolean
onClose: () => void
onSubmit: (data: InputVar) => void
onSubmit: (data: InputVar, moreInfo?: MoreInfo) => void
initialData?: InputVar
}
@ -23,9 +24,9 @@ const InputFieldEditor = ({
const { t } = useTranslation()
const formData = convertToInputFieldFormData(initialData)
const handleSubmit = useCallback((value: FormData) => {
const handleSubmit = useCallback((value: FormData, moreInfo?: MoreInfo) => {
const inputFieldData = convertFormDataToINputField(value)
onSubmit(inputFieldData)
onSubmit(inputFieldData, moreInfo)
onClose()
}, [onSubmit, onClose])

View File

@ -18,13 +18,15 @@ import ActionButton from '@/app/components/base/action-button'
type FieldItemProps = {
readonly?: boolean
payload: InputVar
index: number
onClickEdit: (id: string) => void
onRemove: (id: string) => void
onRemove: (index: number) => void
}
const FieldItem = ({
readonly,
payload,
index,
onClickEdit,
onRemove,
}: FieldItemProps) => {
@ -40,8 +42,8 @@ const FieldItem = ({
const handleRemove = useCallback(() => {
if (readonly) return
onRemove(payload.variable)
}, [onRemove, payload.variable, readonly])
onRemove(index)
}, [index, onRemove, readonly])
return (
<div

View File

@ -12,7 +12,7 @@ type FieldListContainerProps = {
className?: string
inputFields: InputVar[]
onListSortChange: (list: SortableItem[]) => void
onRemoveField: (id: string) => void
onRemoveField: (index: number) => void
onEditField: (id: string) => void
readonly?: boolean
}
@ -46,6 +46,7 @@ const FieldListContainer = ({
{inputFields?.map((item, index) => (
<FieldItem
key={index}
index={index}
readonly={readonly}
payload={item}
onRemove={onRemoveField}

View File

@ -6,13 +6,28 @@ import {
import { produce } from 'immer'
import type { InputVar } from '@/models/pipeline'
import type { SortableItem } from './types'
import type { MoreInfo, ValueSelector } from '@/app/components/workflow/types'
import { ChangeType } from '@/app/components/workflow/types'
import { useWorkflow } from '@/app/components/workflow/hooks'
import { useBoolean } from 'ahooks'
export const useFieldList = (
initialInputFields: InputVar[],
onInputFieldsChange: (value: InputVar[]) => void,
nodeId: string,
) => {
const [inputFields, setInputFields] = useState<InputVar[]>(initialInputFields)
const inputFieldsRef = useRef<InputVar[]>(inputFields)
const [removedVar, setRemovedVar] = useState<ValueSelector>([])
const [removedIndex, setRemoveIndex] = useState(0)
const { handleOutVarRenameChange, isVarUsedInNodes, removeUsedVarInNodes } = useWorkflow()
const [isShowRemoveVarConfirm, {
setTrue: showRemoveVarConfirm,
setFalse: hideRemoveVarConfirm,
}] = useBoolean(false)
const handleInputFieldsChange = useCallback((newInputFields: InputVar[]) => {
setInputFields(newInputFields)
inputFieldsRef.current = newInputFields
@ -38,12 +53,27 @@ export const useFieldList = (
setEditingField(undefined)
}, [])
const handleRemoveField = useCallback((id: string) => {
const newInputFields = inputFieldsRef.current.filter(field => field.variable !== id)
const handleRemoveField = useCallback((index: number) => {
const itemToRemove = inputFieldsRef.current[index]
// Check if the variable is used in other nodes
if (isVarUsedInNodes([nodeId, itemToRemove.variable || ''])) {
showRemoveVarConfirm()
setRemovedVar([nodeId, itemToRemove.variable || ''])
setRemoveIndex(index as number)
return
}
const newInputFields = inputFieldsRef.current.splice(index, 1)
handleInputFieldsChange(newInputFields)
}, [handleInputFieldsChange])
}, [handleInputFieldsChange, isVarUsedInNodes, nodeId, showRemoveVarConfirm])
const handleSubmitField = useCallback((data: InputVar) => {
const onRemoveVarConfirm = useCallback(() => {
const newInputFields = inputFieldsRef.current.splice(removedIndex, 1)
handleInputFieldsChange(newInputFields)
removeUsedVarInNodes(removedVar)
hideRemoveVarConfirm()
}, [removedIndex, handleInputFieldsChange, removeUsedVarInNodes, removedVar, hideRemoveVarConfirm])
const handleSubmitField = useCallback((data: InputVar, moreInfo?: MoreInfo) => {
const newInputFields = produce(inputFieldsRef.current, (draft) => {
const currentIndex = draft.findIndex(field => field.variable === data.variable)
if (currentIndex === -1) {
@ -53,7 +83,10 @@ export const useFieldList = (
draft[currentIndex] = data
})
handleInputFieldsChange(newInputFields)
}, [handleInputFieldsChange])
// Update variable name in nodes if it has changed
if (moreInfo?.type === ChangeType.changeVarName)
handleOutVarRenameChange(nodeId, [nodeId, moreInfo.payload?.beforeKey || ''], [nodeId, moreInfo.payload?.afterKey || ''])
}, [handleInputFieldsChange, handleOutVarRenameChange, nodeId])
return {
inputFields,
@ -65,5 +98,8 @@ export const useFieldList = (
showInputFieldEditor,
handleOpenInputFieldEditor,
handleCancelInputFieldEditor,
isShowRemoveVarConfirm,
hideRemoveVarConfirm,
onRemoveVarConfirm,
}
}

View File

@ -6,6 +6,7 @@ import type { InputVar } from '@/models/pipeline'
import ActionButton from '@/app/components/base/action-button'
import { useFieldList } from './hooks'
import FieldListContainer from './field-list-container'
import RemoveEffectVarConfirm from '@/app/components/workflow/nodes/_base/components/remove-effect-var-confirm'
type FieldListProps = {
nodeId: string
@ -37,7 +38,10 @@ const FieldList = ({
handleOpenInputFieldEditor,
showInputFieldEditor,
editingField,
} = useFieldList(initialInputFields, onInputFieldsChange)
isShowRemoveVarConfirm,
hideRemoveVarConfirm,
onRemoveVarConfirm,
} = useFieldList(initialInputFields, onInputFieldsChange, nodeId)
return (
<div className='flex flex-col'>
@ -70,6 +74,11 @@ const FieldList = ({
onClose={handleCancelInputFieldEditor}
/>
)}
<RemoveEffectVarConfirm
isShow={isShowRemoveVarConfirm}
onCancel={hideRemoveVarConfirm}
onConfirm={onRemoveVarConfirm}
/>
</div>
)
}

View File

@ -37,7 +37,7 @@ const Panel: FC<NodePanelProps<DataSourceNodeType>> = ({ id, data }) => {
editingField,
handleSubmitField,
handleCancelInputFieldEditor,
} = useFieldList(variables, handleInputFieldVariablesChange)
} = useFieldList(variables, handleInputFieldVariablesChange, id)
return (
<div >