mirror of
https://github.com/langgenius/dify.git
synced 2025-09-03 22:33:55 +00:00
feat: add input field variables change sync
This commit is contained in:
parent
769b5e185a
commit
cc7ad5ac97
@ -6,11 +6,12 @@ import { useCallback } from 'react'
|
|||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import type { InputVar } from '@/models/pipeline'
|
import type { InputVar } from '@/models/pipeline'
|
||||||
import type { FormData } from './form/types'
|
import type { FormData } from './form/types'
|
||||||
|
import type { MoreInfo } from '@/app/components/workflow/types'
|
||||||
|
|
||||||
type InputFieldEditorProps = {
|
type InputFieldEditorProps = {
|
||||||
show: boolean
|
show: boolean
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
onSubmit: (data: InputVar) => void
|
onSubmit: (data: InputVar, moreInfo?: MoreInfo) => void
|
||||||
initialData?: InputVar
|
initialData?: InputVar
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,9 +24,9 @@ const InputFieldEditor = ({
|
|||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const formData = convertToInputFieldFormData(initialData)
|
const formData = convertToInputFieldFormData(initialData)
|
||||||
|
|
||||||
const handleSubmit = useCallback((value: FormData) => {
|
const handleSubmit = useCallback((value: FormData, moreInfo?: MoreInfo) => {
|
||||||
const inputFieldData = convertFormDataToINputField(value)
|
const inputFieldData = convertFormDataToINputField(value)
|
||||||
onSubmit(inputFieldData)
|
onSubmit(inputFieldData, moreInfo)
|
||||||
onClose()
|
onClose()
|
||||||
}, [onSubmit, onClose])
|
}, [onSubmit, onClose])
|
||||||
|
|
||||||
|
@ -18,13 +18,15 @@ import ActionButton from '@/app/components/base/action-button'
|
|||||||
type FieldItemProps = {
|
type FieldItemProps = {
|
||||||
readonly?: boolean
|
readonly?: boolean
|
||||||
payload: InputVar
|
payload: InputVar
|
||||||
|
index: number
|
||||||
onClickEdit: (id: string) => void
|
onClickEdit: (id: string) => void
|
||||||
onRemove: (id: string) => void
|
onRemove: (index: number) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const FieldItem = ({
|
const FieldItem = ({
|
||||||
readonly,
|
readonly,
|
||||||
payload,
|
payload,
|
||||||
|
index,
|
||||||
onClickEdit,
|
onClickEdit,
|
||||||
onRemove,
|
onRemove,
|
||||||
}: FieldItemProps) => {
|
}: FieldItemProps) => {
|
||||||
@ -40,8 +42,8 @@ const FieldItem = ({
|
|||||||
|
|
||||||
const handleRemove = useCallback(() => {
|
const handleRemove = useCallback(() => {
|
||||||
if (readonly) return
|
if (readonly) return
|
||||||
onRemove(payload.variable)
|
onRemove(index)
|
||||||
}, [onRemove, payload.variable, readonly])
|
}, [index, onRemove, readonly])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -12,7 +12,7 @@ type FieldListContainerProps = {
|
|||||||
className?: string
|
className?: string
|
||||||
inputFields: InputVar[]
|
inputFields: InputVar[]
|
||||||
onListSortChange: (list: SortableItem[]) => void
|
onListSortChange: (list: SortableItem[]) => void
|
||||||
onRemoveField: (id: string) => void
|
onRemoveField: (index: number) => void
|
||||||
onEditField: (id: string) => void
|
onEditField: (id: string) => void
|
||||||
readonly?: boolean
|
readonly?: boolean
|
||||||
}
|
}
|
||||||
@ -46,6 +46,7 @@ const FieldListContainer = ({
|
|||||||
{inputFields?.map((item, index) => (
|
{inputFields?.map((item, index) => (
|
||||||
<FieldItem
|
<FieldItem
|
||||||
key={index}
|
key={index}
|
||||||
|
index={index}
|
||||||
readonly={readonly}
|
readonly={readonly}
|
||||||
payload={item}
|
payload={item}
|
||||||
onRemove={onRemoveField}
|
onRemove={onRemoveField}
|
||||||
|
@ -6,13 +6,28 @@ import {
|
|||||||
import { produce } from 'immer'
|
import { produce } from 'immer'
|
||||||
import type { InputVar } from '@/models/pipeline'
|
import type { InputVar } from '@/models/pipeline'
|
||||||
import type { SortableItem } from './types'
|
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 = (
|
export const useFieldList = (
|
||||||
initialInputFields: InputVar[],
|
initialInputFields: InputVar[],
|
||||||
onInputFieldsChange: (value: InputVar[]) => void,
|
onInputFieldsChange: (value: InputVar[]) => void,
|
||||||
|
nodeId: string,
|
||||||
) => {
|
) => {
|
||||||
const [inputFields, setInputFields] = useState<InputVar[]>(initialInputFields)
|
const [inputFields, setInputFields] = useState<InputVar[]>(initialInputFields)
|
||||||
const inputFieldsRef = useRef<InputVar[]>(inputFields)
|
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[]) => {
|
const handleInputFieldsChange = useCallback((newInputFields: InputVar[]) => {
|
||||||
setInputFields(newInputFields)
|
setInputFields(newInputFields)
|
||||||
inputFieldsRef.current = newInputFields
|
inputFieldsRef.current = newInputFields
|
||||||
@ -38,12 +53,27 @@ export const useFieldList = (
|
|||||||
setEditingField(undefined)
|
setEditingField(undefined)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const handleRemoveField = useCallback((id: string) => {
|
const handleRemoveField = useCallback((index: number) => {
|
||||||
const newInputFields = inputFieldsRef.current.filter(field => field.variable !== id)
|
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(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 newInputFields = produce(inputFieldsRef.current, (draft) => {
|
||||||
const currentIndex = draft.findIndex(field => field.variable === data.variable)
|
const currentIndex = draft.findIndex(field => field.variable === data.variable)
|
||||||
if (currentIndex === -1) {
|
if (currentIndex === -1) {
|
||||||
@ -53,7 +83,10 @@ export const useFieldList = (
|
|||||||
draft[currentIndex] = data
|
draft[currentIndex] = data
|
||||||
})
|
})
|
||||||
handleInputFieldsChange(newInputFields)
|
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 {
|
return {
|
||||||
inputFields,
|
inputFields,
|
||||||
@ -65,5 +98,8 @@ export const useFieldList = (
|
|||||||
showInputFieldEditor,
|
showInputFieldEditor,
|
||||||
handleOpenInputFieldEditor,
|
handleOpenInputFieldEditor,
|
||||||
handleCancelInputFieldEditor,
|
handleCancelInputFieldEditor,
|
||||||
|
isShowRemoveVarConfirm,
|
||||||
|
hideRemoveVarConfirm,
|
||||||
|
onRemoveVarConfirm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import type { InputVar } from '@/models/pipeline'
|
|||||||
import ActionButton from '@/app/components/base/action-button'
|
import ActionButton from '@/app/components/base/action-button'
|
||||||
import { useFieldList } from './hooks'
|
import { useFieldList } from './hooks'
|
||||||
import FieldListContainer from './field-list-container'
|
import FieldListContainer from './field-list-container'
|
||||||
|
import RemoveEffectVarConfirm from '@/app/components/workflow/nodes/_base/components/remove-effect-var-confirm'
|
||||||
|
|
||||||
type FieldListProps = {
|
type FieldListProps = {
|
||||||
nodeId: string
|
nodeId: string
|
||||||
@ -37,7 +38,10 @@ const FieldList = ({
|
|||||||
handleOpenInputFieldEditor,
|
handleOpenInputFieldEditor,
|
||||||
showInputFieldEditor,
|
showInputFieldEditor,
|
||||||
editingField,
|
editingField,
|
||||||
} = useFieldList(initialInputFields, onInputFieldsChange)
|
isShowRemoveVarConfirm,
|
||||||
|
hideRemoveVarConfirm,
|
||||||
|
onRemoveVarConfirm,
|
||||||
|
} = useFieldList(initialInputFields, onInputFieldsChange, nodeId)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col'>
|
<div className='flex flex-col'>
|
||||||
@ -70,6 +74,11 @@ const FieldList = ({
|
|||||||
onClose={handleCancelInputFieldEditor}
|
onClose={handleCancelInputFieldEditor}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<RemoveEffectVarConfirm
|
||||||
|
isShow={isShowRemoveVarConfirm}
|
||||||
|
onCancel={hideRemoveVarConfirm}
|
||||||
|
onConfirm={onRemoveVarConfirm}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ const Panel: FC<NodePanelProps<DataSourceNodeType>> = ({ id, data }) => {
|
|||||||
editingField,
|
editingField,
|
||||||
handleSubmitField,
|
handleSubmitField,
|
||||||
handleCancelInputFieldEditor,
|
handleCancelInputFieldEditor,
|
||||||
} = useFieldList(variables, handleInputFieldVariablesChange)
|
} = useFieldList(variables, handleInputFieldVariablesChange, id)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div >
|
<div >
|
||||||
|
Loading…
x
Reference in New Issue
Block a user