|
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 |
|
|