mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-05-17 13:06:58 +08:00
278 lines
9.8 KiB
TypeScript
278 lines
9.8 KiB
TypeScript
import { useCallback, useMemo } from 'react'
|
|
import produce from 'immer'
|
|
import { v4 as uuid4 } from 'uuid'
|
|
import { useUpdateNodeInternals } from 'reactflow'
|
|
import type {
|
|
Var,
|
|
} from '../../types'
|
|
import { VarType } from '../../types'
|
|
import { LogicalOperator } from './types'
|
|
import type {
|
|
CaseItem,
|
|
HandleAddCondition,
|
|
HandleAddSubVariableCondition,
|
|
HandleRemoveCondition,
|
|
HandleToggleConditionLogicalOperator,
|
|
HandleToggleSubVariableConditionLogicalOperator,
|
|
HandleUpdateCondition,
|
|
HandleUpdateSubVariableCondition,
|
|
IfElseNodeType,
|
|
} from './types'
|
|
import {
|
|
branchNameCorrect,
|
|
getOperators,
|
|
} from './utils'
|
|
import useIsVarFileAttribute from './use-is-var-file-attribute'
|
|
import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
|
|
import {
|
|
useEdgesInteractions,
|
|
useNodesReadOnly,
|
|
} from '@/app/components/workflow/hooks'
|
|
import useAvailableVarList from '@/app/components/workflow/nodes/_base/hooks/use-available-var-list'
|
|
|
|
const useConfig = (id: string, payload: IfElseNodeType) => {
|
|
const updateNodeInternals = useUpdateNodeInternals()
|
|
const { nodesReadOnly: readOnly } = useNodesReadOnly()
|
|
const { handleEdgeDeleteByDeleteBranch } = useEdgesInteractions()
|
|
const { inputs, setInputs } = useNodeCrud<IfElseNodeType>(id, payload)
|
|
|
|
const filterVar = useCallback(() => {
|
|
return true
|
|
}, [])
|
|
|
|
const {
|
|
availableVars,
|
|
availableNodesWithParent,
|
|
} = useAvailableVarList(id, {
|
|
onlyLeafNodeVar: false,
|
|
filterVar,
|
|
})
|
|
|
|
const filterNumberVar = useCallback((varPayload: Var) => {
|
|
return varPayload.type === VarType.number
|
|
}, [])
|
|
|
|
const {
|
|
getIsVarFileAttribute,
|
|
} = useIsVarFileAttribute({
|
|
nodeId: id,
|
|
isInIteration: payload.isInIteration,
|
|
})
|
|
|
|
const varsIsVarFileAttribute = useMemo(() => {
|
|
const conditions: Record<string, boolean> = {}
|
|
inputs.cases?.forEach((c) => {
|
|
c.conditions.forEach((condition) => {
|
|
conditions[condition.id] = getIsVarFileAttribute(condition.variable_selector!)
|
|
})
|
|
})
|
|
return conditions
|
|
}, [inputs.cases, getIsVarFileAttribute])
|
|
|
|
const {
|
|
availableVars: availableNumberVars,
|
|
availableNodesWithParent: availableNumberNodesWithParent,
|
|
} = useAvailableVarList(id, {
|
|
onlyLeafNodeVar: false,
|
|
filterVar: filterNumberVar,
|
|
})
|
|
|
|
const handleAddCase = useCallback(() => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
if (draft.cases) {
|
|
const case_id = uuid4()
|
|
draft.cases.push({
|
|
case_id,
|
|
logical_operator: LogicalOperator.and,
|
|
conditions: [],
|
|
})
|
|
if (draft._targetBranches) {
|
|
const elseCaseIndex = draft._targetBranches.findIndex(branch => branch.id === 'false')
|
|
if (elseCaseIndex > -1) {
|
|
draft._targetBranches = branchNameCorrect([
|
|
...draft._targetBranches.slice(0, elseCaseIndex),
|
|
{
|
|
id: case_id,
|
|
name: '',
|
|
},
|
|
...draft._targetBranches.slice(elseCaseIndex),
|
|
])
|
|
}
|
|
}
|
|
}
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
const handleRemoveCase = useCallback((caseId: string) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
draft.cases = draft.cases?.filter(item => item.case_id !== caseId)
|
|
|
|
if (draft._targetBranches)
|
|
draft._targetBranches = branchNameCorrect(draft._targetBranches.filter(branch => branch.id !== caseId))
|
|
|
|
handleEdgeDeleteByDeleteBranch(id, caseId)
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs, id, handleEdgeDeleteByDeleteBranch])
|
|
|
|
const handleSortCase = useCallback((newCases: (CaseItem & { id: string })[]) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
draft.cases = newCases.filter(Boolean).map(item => ({
|
|
id: item.id,
|
|
case_id: item.case_id,
|
|
logical_operator: item.logical_operator,
|
|
conditions: item.conditions,
|
|
}))
|
|
|
|
draft._targetBranches = branchNameCorrect([
|
|
...newCases.filter(Boolean).map(item => ({ id: item.case_id, name: '' })),
|
|
{ id: 'false', name: '' },
|
|
])
|
|
})
|
|
setInputs(newInputs)
|
|
updateNodeInternals(id)
|
|
}, [inputs, setInputs])
|
|
|
|
const handleAddCondition = useCallback<HandleAddCondition>((caseId, valueSelector, varItem) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
const targetCase = draft.cases?.find(item => item.case_id === caseId)
|
|
if (targetCase) {
|
|
targetCase.conditions.push({
|
|
id: uuid4(),
|
|
varType: varItem.type,
|
|
variable_selector: valueSelector,
|
|
comparison_operator: getOperators(varItem.type, getIsVarFileAttribute(valueSelector) ? { key: valueSelector.slice(-1)[0] } : undefined)[0],
|
|
value: '',
|
|
})
|
|
}
|
|
})
|
|
setInputs(newInputs)
|
|
}, [getIsVarFileAttribute, inputs, setInputs])
|
|
|
|
const handleRemoveCondition = useCallback<HandleRemoveCondition>((caseId, conditionId) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
const targetCase = draft.cases?.find(item => item.case_id === caseId)
|
|
if (targetCase)
|
|
targetCase.conditions = targetCase.conditions.filter(item => item.id !== conditionId)
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
const handleUpdateCondition = useCallback<HandleUpdateCondition>((caseId, conditionId, newCondition) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
const targetCase = draft.cases?.find(item => item.case_id === caseId)
|
|
if (targetCase) {
|
|
const targetCondition = targetCase.conditions.find(item => item.id === conditionId)
|
|
if (targetCondition)
|
|
Object.assign(targetCondition, newCondition)
|
|
}
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
const handleToggleConditionLogicalOperator = useCallback<HandleToggleConditionLogicalOperator>((caseId) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
const targetCase = draft.cases?.find(item => item.case_id === caseId)
|
|
if (targetCase)
|
|
targetCase.logical_operator = targetCase.logical_operator === LogicalOperator.and ? LogicalOperator.or : LogicalOperator.and
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
const handleAddSubVariableCondition = useCallback<HandleAddSubVariableCondition>((caseId: string, conditionId: string, key?: string) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
const condition = draft.cases?.find(item => item.case_id === caseId)?.conditions.find(item => item.id === conditionId)
|
|
if (!condition)
|
|
return
|
|
if (!condition?.sub_variable_condition) {
|
|
condition.sub_variable_condition = {
|
|
case_id: uuid4(),
|
|
logical_operator: LogicalOperator.and,
|
|
conditions: [],
|
|
}
|
|
}
|
|
const subVarCondition = condition.sub_variable_condition
|
|
if (subVarCondition) {
|
|
if (!subVarCondition.conditions)
|
|
subVarCondition.conditions = []
|
|
|
|
subVarCondition.conditions.push({
|
|
id: uuid4(),
|
|
key: key || '',
|
|
varType: VarType.string,
|
|
comparison_operator: undefined,
|
|
value: '',
|
|
})
|
|
}
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
const handleRemoveSubVariableCondition = useCallback((caseId: string, conditionId: string, subConditionId: string) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
const condition = draft.cases?.find(item => item.case_id === caseId)?.conditions.find(item => item.id === conditionId)
|
|
if (!condition)
|
|
return
|
|
if (!condition?.sub_variable_condition)
|
|
return
|
|
const subVarCondition = condition.sub_variable_condition
|
|
if (subVarCondition)
|
|
subVarCondition.conditions = subVarCondition.conditions.filter(item => item.id !== subConditionId)
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
const handleUpdateSubVariableCondition = useCallback<HandleUpdateSubVariableCondition>((caseId, conditionId, subConditionId, newSubCondition) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
const targetCase = draft.cases?.find(item => item.case_id === caseId)
|
|
if (targetCase) {
|
|
const targetCondition = targetCase.conditions.find(item => item.id === conditionId)
|
|
if (targetCondition && targetCondition.sub_variable_condition) {
|
|
const targetSubCondition = targetCondition.sub_variable_condition.conditions.find(item => item.id === subConditionId)
|
|
if (targetSubCondition)
|
|
Object.assign(targetSubCondition, newSubCondition)
|
|
}
|
|
}
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
const handleToggleSubVariableConditionLogicalOperator = useCallback<HandleToggleSubVariableConditionLogicalOperator>((caseId, conditionId) => {
|
|
const newInputs = produce(inputs, (draft) => {
|
|
const targetCase = draft.cases?.find(item => item.case_id === caseId)
|
|
if (targetCase) {
|
|
const targetCondition = targetCase.conditions.find(item => item.id === conditionId)
|
|
if (targetCondition && targetCondition.sub_variable_condition)
|
|
targetCondition.sub_variable_condition.logical_operator = targetCondition.sub_variable_condition.logical_operator === LogicalOperator.and ? LogicalOperator.or : LogicalOperator.and
|
|
}
|
|
})
|
|
setInputs(newInputs)
|
|
}, [inputs, setInputs])
|
|
|
|
return {
|
|
readOnly,
|
|
inputs,
|
|
filterVar,
|
|
filterNumberVar,
|
|
handleAddCase,
|
|
handleRemoveCase,
|
|
handleSortCase,
|
|
handleAddCondition,
|
|
handleRemoveCondition,
|
|
handleUpdateCondition,
|
|
handleToggleConditionLogicalOperator,
|
|
handleAddSubVariableCondition,
|
|
handleUpdateSubVariableCondition,
|
|
handleRemoveSubVariableCondition,
|
|
handleToggleSubVariableConditionLogicalOperator,
|
|
nodesOutputVars: availableVars,
|
|
availableNodes: availableNodesWithParent,
|
|
nodesOutputNumberVars: availableNumberVars,
|
|
availableNumberNodes: availableNumberNodesWithParent,
|
|
varsIsVarFileAttribute,
|
|
}
|
|
}
|
|
|
|
export default useConfig
|