diff --git a/web/app/components/base/select/index.tsx b/web/app/components/base/select/index.tsx index 53af9c45ff..362b56e0a4 100644 --- a/web/app/components/base/select/index.tsx +++ b/web/app/components/base/select/index.tsx @@ -37,6 +37,7 @@ export type ISelectProps = { bgClassName?: string placeholder?: string overlayClassName?: string + optionWrapClassName?: string optionClassName?: string renderOption?: ({ item, @@ -172,6 +173,7 @@ const SimpleSelect: FC = ({ disabled = false, onSelect, placeholder, + optionWrapClassName, optionClassName, renderOption, }) => { @@ -231,7 +233,7 @@ const SimpleSelect: FC = ({ leaveTo="opacity-0" > - + {items.map((item: Item) => ( { const { t } = useTranslation() @@ -72,7 +78,7 @@ const ConditionItem = ({ if (isSubVariableKey) onUpdateSubVariableCondition?.(caseId, conditionId, condition.id, newCondition) else - onUpdateCondition(caseId, condition.id, newCondition) + onUpdateCondition?.(caseId, condition.id, newCondition) }, [caseId, condition, conditionId, isSubVariableKey, onUpdateCondition, onUpdateSubVariableCondition]) const handleUpdateConditionOperator = useCallback((value: ComparisonOperator) => { @@ -97,8 +103,8 @@ const ConditionItem = ({ numberVarType, value: '', } - onUpdateCondition(caseId, condition.id, newCondition) - }, [caseId, condition, onUpdateCondition]) + doUpdateCondition(newCondition) + }, [condition, doUpdateCondition]) const isSelect = condition.comparison_operator && [ComparisonOperator.in, ComparisonOperator.notIn, ComparisonOperator.allOf].includes(condition.comparison_operator) const selectOptions = useMemo(() => { @@ -136,6 +142,13 @@ const ConditionItem = ({ onUpdateSubVariableCondition?.(caseId, conditionId, condition.id, newCondition) }, [caseId, condition, conditionId, onUpdateSubVariableCondition]) + const doRemoveCondition = useCallback(() => { + if (isSubVariableKey) + onRemoveSubVariableCondition?.(caseId, conditionId, condition.id) + else + onRemoveCondition?.(caseId, condition.id) + }, [caseId, condition, conditionId, isSubVariableKey, onRemoveCondition, onRemoveSubVariableCondition]) + return (
handleSubVarKeyChange(item.value as string)} @@ -218,19 +232,11 @@ const ConditionItem = ({ caseId={caseId} conditionId={conditionId} readOnly={!!disabled} - nodeId='' cases={condition.sub_variable_condition ? [condition.sub_variable_condition] : []} handleAddSubVariableCondition={onAddSubVariableCondition} - handleRemoveCase={() => { }} - handleAddCondition={() => { }} - handleUpdateCondition={onUpdateCondition} + handleRemoveSubVariableCondition={onRemoveSubVariableCondition} handleUpdateSubVariableCondition={onUpdateSubVariableCondition} - handleRemoveCondition={() => { }} - handleUpdateConditionLogicalOperator={() => { }} - nodesOutputVars={[]} - availableNodes={[]} - varsIsVarFileAttribute={{}} - filterVar={() => true} + handleToggleSubVariableConditionLogicalOperator={onToggleSubVariableConditionLogicalOperator} />
) @@ -240,7 +246,7 @@ const ConditionItem = ({ className='shrink-0 flex items-center justify-center ml-1 mt-1 w-6 h-6 rounded-lg cursor-pointer hover:bg-state-destructive-hover text-text-tertiary hover:text-text-destructive' onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} - onClick={() => onRemoveCondition(caseId, condition.id)} + onClick={doRemoveCondition} >
diff --git a/web/app/components/workflow/nodes/if-else/components/condition-list/index.tsx b/web/app/components/workflow/nodes/if-else/components/condition-list/index.tsx index 2eb27883ed..4eb95e8749 100644 --- a/web/app/components/workflow/nodes/if-else/components/condition-list/index.tsx +++ b/web/app/components/workflow/nodes/if-else/components/condition-list/index.tsx @@ -1,18 +1,21 @@ import { RiLoopLeftLine } from '@remixicon/react' -import { LogicalOperator } from '../../types' +import { useCallback } from 'react' import type { CaseItem, HandleAddSubVariableCondition, HandleRemoveCondition, + HandleToggleConditionLogicalOperator, + HandleToggleSubVariableConditionLogicalOperator, HandleUpdateCondition, - HandleUpdateConditionLogicalOperator, HandleUpdateSubVariableCondition, + handleRemoveSubVariableCondition, } from '../../types' import ConditionItem from './condition-item' import type { Node, NodeOutPutVar, } from '@/app/components/workflow/types' +import cn from '@/utils/classnames' type ConditionListProps = { isSubVariable?: boolean @@ -20,15 +23,17 @@ type ConditionListProps = { caseId: string conditionId?: string caseItem: CaseItem - onUpdateCondition: HandleUpdateCondition - onUpdateConditionLogicalOperator: HandleUpdateConditionLogicalOperator - onRemoveCondition: HandleRemoveCondition + onRemoveCondition?: HandleRemoveCondition + onUpdateCondition?: HandleUpdateCondition + onToggleConditionLogicalOperator?: HandleToggleConditionLogicalOperator nodesOutputVars: NodeOutPutVar[] availableNodes: Node[] numberVariables: NodeOutPutVar[] varsIsVarFileAttribute: Record onAddSubVariableCondition?: HandleAddSubVariableCondition + onRemoveSubVariableCondition?: handleRemoveSubVariableCondition onUpdateSubVariableCondition?: HandleUpdateSubVariableCondition + onToggleSubVariableConditionLogicalOperator?: HandleToggleSubVariableConditionLogicalOperator } const ConditionList = ({ isSubVariable, @@ -37,19 +42,28 @@ const ConditionList = ({ conditionId, caseItem, onUpdateCondition, - onUpdateConditionLogicalOperator, onRemoveCondition, + onToggleConditionLogicalOperator, + onAddSubVariableCondition, + onRemoveSubVariableCondition, + onUpdateSubVariableCondition, + onToggleSubVariableConditionLogicalOperator, nodesOutputVars, availableNodes, numberVariables, varsIsVarFileAttribute, - onAddSubVariableCondition, - onUpdateSubVariableCondition, }: ConditionListProps) => { const { conditions, logical_operator } = caseItem + const doToggleConditionLogicalOperator = useCallback(() => { + if (isSubVariable) + onToggleSubVariableConditionLogicalOperator?.(caseId!, conditionId!) + else + onToggleConditionLogicalOperator?.(caseId) + }, [caseId, conditionId, isSubVariable, onToggleConditionLogicalOperator, onToggleSubVariableConditionLogicalOperator]) + return ( -
+
{ conditions.length > 1 && (
@@ -57,9 +71,7 @@ const ConditionList = ({
{ - onUpdateConditionLogicalOperator(caseItem.case_id, caseItem.logical_operator === LogicalOperator.and ? LogicalOperator.or : LogicalOperator.and) - }} + onClick={doToggleConditionLogicalOperator} > {logical_operator.toUpperCase()} @@ -77,13 +89,15 @@ const ConditionList = ({ condition={condition} onUpdateCondition={onUpdateCondition} onRemoveCondition={onRemoveCondition} + onAddSubVariableCondition={onAddSubVariableCondition} + onRemoveSubVariableCondition={onRemoveSubVariableCondition} + onUpdateSubVariableCondition={onUpdateSubVariableCondition} + onToggleSubVariableConditionLogicalOperator={onToggleSubVariableConditionLogicalOperator} nodesOutputVars={nodesOutputVars} availableNodes={availableNodes} numberVariables={numberVariables} file={varsIsVarFileAttribute[condition.id] ? { key: (condition.variable_selector || []).slice(-1)[0] } : undefined} isSubVariableKey={isSubVariable} - onAddSubVariableCondition={onAddSubVariableCondition} - onUpdateSubVariableCondition={onUpdateSubVariableCondition} /> )) } diff --git a/web/app/components/workflow/nodes/if-else/components/condition-wrap.tsx b/web/app/components/workflow/nodes/if-else/components/condition-wrap.tsx index 1ce7ff5013..67a4f728d1 100644 --- a/web/app/components/workflow/nodes/if-else/components/condition-wrap.tsx +++ b/web/app/components/workflow/nodes/if-else/components/condition-wrap.tsx @@ -8,7 +8,7 @@ import { RiDeleteBinLine, RiDraggable, } from '@remixicon/react' -import type { CaseItem, HandleAddCondition, HandleAddSubVariableCondition, HandleRemoveCondition, HandleUpdateCondition, HandleUpdateConditionLogicalOperator, HandleUpdateSubVariableCondition } from '../types' +import type { CaseItem, HandleAddCondition, HandleAddSubVariableCondition, HandleRemoveCondition, HandleToggleConditionLogicalOperator, HandleToggleSubVariableConditionLogicalOperator, HandleUpdateCondition, HandleUpdateSubVariableCondition, handleRemoveSubVariableCondition } from '../types' import type { Node, NodeOutPutVar, Var } from '../../../types' import { VarType } from '../../../types' import { useGetAvailableVars } from '../../variable-assigner/hooks' @@ -21,28 +21,30 @@ type Props = { isSubVariable?: boolean caseId?: string conditionId?: string - nodeId: string cases: CaseItem[] readOnly: boolean handleSortCase?: (sortedCases: (CaseItem & { id: string })[]) => void - handleRemoveCase: (caseId: string) => void + handleRemoveCase?: (caseId: string) => void handleAddCondition?: HandleAddCondition + handleRemoveCondition?: HandleRemoveCondition + handleUpdateCondition?: HandleUpdateCondition + handleToggleConditionLogicalOperator?: HandleToggleConditionLogicalOperator handleAddSubVariableCondition?: HandleAddSubVariableCondition + handleRemoveSubVariableCondition?: handleRemoveSubVariableCondition handleUpdateSubVariableCondition?: HandleUpdateSubVariableCondition - handleUpdateCondition: HandleUpdateCondition - handleRemoveCondition: HandleRemoveCondition - handleUpdateConditionLogicalOperator: HandleUpdateConditionLogicalOperator - nodesOutputVars: NodeOutPutVar[] - availableNodes: Node[] - varsIsVarFileAttribute: Record - filterVar: (varPayload: Var) => boolean + handleToggleSubVariableConditionLogicalOperator?: HandleToggleSubVariableConditionLogicalOperator + nodeId?: string + nodesOutputVars?: NodeOutPutVar[] + availableNodes?: Node[] + varsIsVarFileAttribute?: Record + filterVar?: (varPayload: Var) => boolean } const ConditionWrap: FC = ({ isSubVariable, caseId, conditionId, - nodeId: id, + nodeId: id = '', cases = [], readOnly, handleSortCase = () => { }, @@ -50,13 +52,15 @@ const ConditionWrap: FC = ({ handleUpdateCondition, handleAddCondition, handleRemoveCondition, + handleToggleConditionLogicalOperator, handleAddSubVariableCondition, + handleRemoveSubVariableCondition, handleUpdateSubVariableCondition, - handleUpdateConditionLogicalOperator, - nodesOutputVars, - availableNodes, - varsIsVarFileAttribute, - filterVar, + handleToggleSubVariableConditionLogicalOperator, + nodesOutputVars = [], + availableNodes = [], + varsIsVarFileAttribute = {}, + filterVar = () => true, }) => { const { t } = useTranslation() @@ -122,13 +126,15 @@ const ConditionWrap: FC = ({ conditionId={conditionId} onUpdateCondition={handleUpdateCondition} onRemoveCondition={handleRemoveCondition} - onUpdateConditionLogicalOperator={handleUpdateConditionLogicalOperator} + onToggleConditionLogicalOperator={handleToggleConditionLogicalOperator} nodesOutputVars={nodesOutputVars} availableNodes={availableNodes} numberVariables={getAvailableVars(id, '', filterNumberVar)} varsIsVarFileAttribute={varsIsVarFileAttribute} onAddSubVariableCondition={handleAddSubVariableCondition} + onRemoveSubVariableCondition={handleRemoveSubVariableCondition} onUpdateSubVariableCondition={handleUpdateSubVariableCondition} + onToggleSubVariableConditionLogicalOperator={handleToggleSubVariableConditionLogicalOperator} isSubVariable={isSubVariable} />
@@ -168,7 +174,7 @@ const ConditionWrap: FC = ({ size='small' variant='ghost' disabled={readOnly} - onClick={() => handleRemoveCase(item.case_id)} + onClick={() => handleRemoveCase?.(item.case_id)} onMouseEnter={() => setWillDeleteCaseId(item.case_id)} onMouseLeave={() => setWillDeleteCaseId('')} > diff --git a/web/app/components/workflow/nodes/if-else/panel.tsx b/web/app/components/workflow/nodes/if-else/panel.tsx index c83e66954d..9de6ff05f6 100644 --- a/web/app/components/workflow/nodes/if-else/panel.tsx +++ b/web/app/components/workflow/nodes/if-else/panel.tsx @@ -30,9 +30,11 @@ const Panel: FC> = ({ handleAddCondition, handleUpdateCondition, handleRemoveCondition, + handleToggleConditionLogicalOperator, handleAddSubVariableCondition, + handleRemoveSubVariableCondition, handleUpdateSubVariableCondition, - handleUpdateConditionLogicalOperator, + handleToggleSubVariableConditionLogicalOperator, nodesOutputVars, availableNodes, varsIsVarFileAttribute, @@ -48,11 +50,13 @@ const Panel: FC> = ({ handleSortCase={handleSortCase} handleRemoveCase={handleRemoveCase} handleAddCondition={handleAddCondition} - handleUpdateCondition={handleUpdateCondition} handleRemoveCondition={handleRemoveCondition} - handleUpdateConditionLogicalOperator={handleUpdateConditionLogicalOperator} + handleUpdateCondition={handleUpdateCondition} + handleToggleConditionLogicalOperator={handleToggleConditionLogicalOperator} handleAddSubVariableCondition={handleAddSubVariableCondition} + handleRemoveSubVariableCondition={handleRemoveSubVariableCondition} handleUpdateSubVariableCondition={handleUpdateSubVariableCondition} + handleToggleSubVariableConditionLogicalOperator={handleToggleSubVariableConditionLogicalOperator} nodesOutputVars={nodesOutputVars} availableNodes={availableNodes} varsIsVarFileAttribute={varsIsVarFileAttribute} diff --git a/web/app/components/workflow/nodes/if-else/types.ts b/web/app/components/workflow/nodes/if-else/types.ts index 0530c32ed9..6fabe70d50 100644 --- a/web/app/components/workflow/nodes/if-else/types.ts +++ b/web/app/components/workflow/nodes/if-else/types.ts @@ -58,8 +58,11 @@ export type IfElseNodeType = CommonNodeType & { } export type HandleAddCondition = (caseId: string, valueSelector: ValueSelector, varItem: Var) => void -export type HandleAddSubVariableCondition = (caseId: string, conditionId: string) => void export type HandleRemoveCondition = (caseId: string, conditionId: string) => void export type HandleUpdateCondition = (caseId: string, conditionId: string, newCondition: Condition) => void +export type HandleToggleConditionLogicalOperator = (caseId: string) => void + +export type HandleAddSubVariableCondition = (caseId: string, conditionId: string) => void +export type handleRemoveSubVariableCondition = (caseId: string, conditionId: string, subConditionId: string) => void export type HandleUpdateSubVariableCondition = (caseId: string, conditionId: string, subConditionId: string, newSubCondition: Condition) => void -export type HandleUpdateConditionLogicalOperator = (caseId: string, value: LogicalOperator) => void +export type HandleToggleSubVariableConditionLogicalOperator = (caseId: string, conditionId: string) => void diff --git a/web/app/components/workflow/nodes/if-else/use-config.ts b/web/app/components/workflow/nodes/if-else/use-config.ts index b01295bbf2..e475a9a2b9 100644 --- a/web/app/components/workflow/nodes/if-else/use-config.ts +++ b/web/app/components/workflow/nodes/if-else/use-config.ts @@ -11,8 +11,9 @@ import type { HandleAddCondition, HandleAddSubVariableCondition, HandleRemoveCondition, + HandleToggleConditionLogicalOperator, + HandleToggleSubVariableConditionLogicalOperator, HandleUpdateCondition, - HandleUpdateConditionLogicalOperator, HandleUpdateSubVariableCondition, IfElseNodeType, } from './types' @@ -166,26 +167,18 @@ const useConfig = (id: string, payload: IfElseNodeType) => { }) setInputs(newInputs) }, [inputs, setInputs]) - // console.log(inputs.cases) - const handleUpdateSubVariableCondition = useCallback((caseId, conditionId, subConditionId, newSubCondition) => { + const handleToggleConditionLogicalOperator = useCallback((caseId) => { 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) - } - } + if (targetCase) + targetCase.logical_operator = targetCase.logical_operator === LogicalOperator.and ? LogicalOperator.or : LogicalOperator.and }) setInputs(newInputs) }, [inputs, setInputs]) const handleAddSubVariableCondition = useCallback((caseId: string, conditionId: string) => { const newInputs = produce(inputs, (draft) => { - // debugger const condition = draft.cases?.find(item => item.case_id === caseId)?.conditions.find(item => item.id === conditionId) if (!condition) return @@ -213,11 +206,43 @@ const useConfig = (id: string, payload: IfElseNodeType) => { setInputs(newInputs) }, [inputs, setInputs]) - const handleUpdateConditionLogicalOperator = useCallback((caseId, value) => { + 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((caseId, conditionId, subConditionId, newSubCondition) => { const newInputs = produce(inputs, (draft) => { const targetCase = draft.cases?.find(item => item.case_id === caseId) - if (targetCase) - targetCase.logical_operator = value + 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((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]) @@ -233,9 +258,11 @@ const useConfig = (id: string, payload: IfElseNodeType) => { handleAddCondition, handleRemoveCondition, handleUpdateCondition, + handleToggleConditionLogicalOperator, handleAddSubVariableCondition, handleUpdateSubVariableCondition, - handleUpdateConditionLogicalOperator, + handleRemoveSubVariableCondition, + handleToggleSubVariableConditionLogicalOperator, nodesOutputVars: availableVars, availableNodes: availableNodesWithParent, nodesOutputNumberVars: availableNumberVars,