diff --git a/web/app/components/workflow/nodes/if-else/components/condition-list/condition-item.tsx b/web/app/components/workflow/nodes/if-else/components/condition-list/condition-item.tsx
index 3ce84dafc0..13f3f4bea2 100644
--- a/web/app/components/workflow/nodes/if-else/components/condition-list/condition-item.tsx
+++ b/web/app/components/workflow/nodes/if-else/components/condition-list/condition-item.tsx
@@ -5,19 +5,20 @@ import {
} from 'react'
import { useTranslation } from 'react-i18next'
import { RiDeleteBinLine } from '@remixicon/react'
+import produce from 'immer'
import type { VarType as NumberVarType } from '../../../tool/types'
import type {
Condition,
+ HandleAddSubVariableCondition,
HandleRemoveCondition,
HandleUpdateCondition,
} from '../../types'
import {
ComparisonOperator,
- LogicalOperator,
} from '../../types'
import { comparisonOperatorNotRequireValue } from '../../utils'
import ConditionNumberInput from '../condition-number-input'
-import { FILE_TYPE_OPTIONS, TRANSFER_METHOD } from '../../default'
+import { FILE_TYPE_OPTIONS, SUB_VARIABLES, TRANSFER_METHOD } from '../../default'
import ConditionWrap from '../condition-wrap'
import ConditionOperator from './condition-operator'
import ConditionInput from './condition-input'
@@ -29,7 +30,6 @@ import type {
import { VarType } from '@/app/components/workflow/types'
import cn from '@/utils/classnames'
import { SimpleSelect as Select } from '@/app/components/base/select'
-
const optionNameI18NPrefix = 'workflow.nodes.ifElse.optionName'
type ConditionItemProps = {
@@ -37,22 +37,26 @@ type ConditionItemProps = {
caseId: string
condition: Condition
file?: { key: string }
+ isSubVariableKey?: boolean
onRemoveCondition: HandleRemoveCondition
onUpdateCondition: HandleUpdateCondition
nodesOutputVars: NodeOutPutVar[]
availableNodes: Node[]
numberVariables: NodeOutPutVar[]
+ onAddSubVariableCondition?: HandleAddSubVariableCondition
}
const ConditionItem = ({
disabled,
caseId,
condition,
file,
+ isSubVariableKey,
onRemoveCondition,
onUpdateCondition,
nodesOutputVars,
availableNodes,
numberVariables,
+ onAddSubVariableCondition,
}: ConditionItemProps) => {
const { t } = useTranslation()
@@ -104,8 +108,21 @@ const ConditionItem = ({
}, [condition.comparison_operator, file?.key, isSelect, t])
const isSubVariable = condition.varType === VarType.arrayFile && [ComparisonOperator.contains, ComparisonOperator.notContains].includes(condition.comparison_operator!)
-
const isNotInput = isSelect || isSubVariable
+
+ const isSubVarSelect = isSubVariableKey
+ const subVarOptions = SUB_VARIABLES.map(item => ({
+ name: item,
+ value: item,
+ }))
+
+ const handleSubVarKeyChange = useCallback((key: string) => {
+ const newCondition = produce(condition, (draft) => {
+ draft.key = key
+ })
+ onUpdateCondition(caseId, condition.id, newCondition)
+ }, [caseId, condition, onUpdateCondition])
+
return (
-
+ {isSubVarSelect
+ ? (
+
{ }}
handleAddCondition={() => { }}
handleUpdateCondition={() => { }}
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 721f19de56..5bc0d53e60 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
@@ -2,6 +2,7 @@ import { RiLoopLeftLine } from '@remixicon/react'
import { LogicalOperator } from '../../types'
import type {
CaseItem,
+ HandleAddSubVariableCondition,
HandleRemoveCondition,
HandleUpdateCondition,
HandleUpdateConditionLogicalOperator,
@@ -13,6 +14,7 @@ import type {
} from '@/app/components/workflow/types'
type ConditionListProps = {
+ isSubVariable?: boolean
disabled?: boolean
caseItem: CaseItem
onUpdateCondition: HandleUpdateCondition
@@ -22,8 +24,10 @@ type ConditionListProps = {
availableNodes: Node[]
numberVariables: NodeOutPutVar[]
varsIsVarFileAttribute: Record
+ onAddSubVariableCondition?: HandleAddSubVariableCondition
}
const ConditionList = ({
+ isSubVariable,
disabled,
caseItem,
onUpdateCondition,
@@ -33,6 +37,7 @@ const ConditionList = ({
availableNodes,
numberVariables,
varsIsVarFileAttribute,
+ onAddSubVariableCondition,
}: ConditionListProps) => {
const { conditions, logical_operator } = caseItem
@@ -67,7 +72,9 @@ const ConditionList = ({
nodesOutputVars={nodesOutputVars}
availableNodes={availableNodes}
numberVariables={numberVariables}
- file={varsIsVarFileAttribute[condition.id] ? { key: condition.variable_selector.slice(-1)[0] } : undefined}
+ file={varsIsVarFileAttribute[condition.id] ? { key: (condition.variable_selector || []).slice(-1)[0] } : undefined}
+ isSubVariableKey={isSubVariable}
+ onAddSubVariableCondition={onAddSubVariableCondition}
/>
))
}
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 e5bb241beb..758f1f1b5d 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
@@ -4,10 +4,11 @@ import React, { useCallback, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { ReactSortable } from 'react-sortablejs'
import {
+ RiAddLine,
RiDeleteBinLine,
RiDraggable,
} from '@remixicon/react'
-import type { CaseItem, HandleAddCondition, HandleRemoveCondition, HandleUpdateCondition, HandleUpdateConditionLogicalOperator } from '../types'
+import type { CaseItem, HandleAddCondition, HandleAddSubVariableCondition, HandleRemoveCondition, HandleUpdateCondition, HandleUpdateConditionLogicalOperator } from '../types'
import type { Node, NodeOutPutVar, Var } from '../../../types'
import { VarType } from '../../../types'
import { useGetAvailableVars } from '../../variable-assigner/hooks'
@@ -18,12 +19,15 @@ import Button from '@/app/components/base/button'
type Props = {
isSubVariable?: boolean
+ conditionId?: string
+ caseId?: string
nodeId: string
cases: CaseItem[]
readOnly: boolean
handleSortCase?: (sortedCases: (CaseItem & { id: string })[]) => void
handleRemoveCase: (caseId: string) => void
- handleAddCondition: HandleAddCondition
+ handleAddCondition?: HandleAddCondition
+ handleAddSubVariableCondition?: HandleAddSubVariableCondition
handleUpdateCondition: HandleUpdateCondition
handleRemoveCondition: HandleRemoveCondition
handleUpdateConditionLogicalOperator: HandleUpdateConditionLogicalOperator
@@ -35,19 +39,22 @@ type Props = {
const ConditionWrap: FC = ({
isSubVariable,
+ conditionId: parentConditionId,
+ caseId: conditionParentCaseId,
nodeId: id,
- cases,
+ cases = [],
readOnly,
handleSortCase = () => { },
+ handleRemoveCase,
handleUpdateCondition,
+ handleAddCondition,
handleRemoveCondition,
+ handleAddSubVariableCondition,
handleUpdateConditionLogicalOperator,
nodesOutputVars,
availableNodes,
varsIsVarFileAttribute,
filterVar,
- handleAddCondition,
- handleRemoveCase,
}) => {
const { t } = useTranslation()
@@ -61,90 +68,130 @@ const ConditionWrap: FC = ({
}, [])
return (
- ({ ...caseItem, id: caseItem.case_id }))}
- setList={handleSortCase}
- handle='.handle'
- ghostClass='bg-components-panel-bg'
- animation={150}
- disabled={readOnly || isSubVariable}
- >
- {
- cases.map((item, index) => (
-
-
+
({ ...caseItem, id: caseItem.case_id }))}
+ setList={handleSortCase}
+ handle='.handle'
+ ghostClass='bg-components-panel-bg'
+ animation={150}
+ disabled={readOnly || isSubVariable}
+ >
+ {
+ cases.map((item, index) => (
+
+
+ {!isSubVariable && (
+ <>
+
1 && 'group-hover:block',
+ )} />
+
+ {
+ index === 0 ? 'IF' : 'ELIF'
+ }
+ {
+ casesLength > 1 && (
+
CASE {index + 1}
+ )
+ }
+
+ >
+ )}
+
+ {
+ !!item.conditions.length && (
+
+
+
+ )
+ }
+
+
+ {isSubVariable
+ ? (
+
+ )
+ : (
+
+ )}
+
+ {
+ ((index === 0 && casesLength > 1) || (index > 0)) && (
+
+ )
+ }
+
+
+ {!isSubVariable && (
+
)}
- >
-
1 && 'group-hover:block',
- )} />
-
- {
- index === 0 ? 'IF' : 'ELIF'
- }
- {
- casesLength > 1 && (
-
CASE {index + 1}
- )
- }
-
- {
- !!item.conditions.length && (
-
-
-
- )
- }
-
-
- {
- ((index === 0 && casesLength > 1) || (index > 0)) && (
-
- )
- }
-
-
-
- ))
- }
-
+ ))
+ }
+
+ {(cases.length === 0) && (
+
+ )}
+ >
)
}
export default React.memo(ConditionWrap)
diff --git a/web/app/components/workflow/nodes/if-else/default.ts b/web/app/components/workflow/nodes/if-else/default.ts
index 0e8ce7eb4c..ec3ff83075 100644
--- a/web/app/components/workflow/nodes/if-else/default.ts
+++ b/web/app/components/workflow/nodes/if-else/default.ts
@@ -74,3 +74,5 @@ export const TRANSFER_METHOD = [
{ value: TransferMethod.local_file, i18nKey: 'localUpload' },
{ value: TransferMethod.remote_url, i18nKey: 'url' },
]
+
+export const SUB_VARIABLES = ['type', 'size', 'name', 'url', 'extension', 'mime_type', 'transfer_method', 'url']
diff --git a/web/app/components/workflow/nodes/if-else/panel.tsx b/web/app/components/workflow/nodes/if-else/panel.tsx
index ba30f9be0d..77a1772761 100644
--- a/web/app/components/workflow/nodes/if-else/panel.tsx
+++ b/web/app/components/workflow/nodes/if-else/panel.tsx
@@ -30,6 +30,7 @@ const Panel: FC
> = ({
handleAddCondition,
handleUpdateCondition,
handleRemoveCondition,
+ handleAddSubVariableCondition,
handleUpdateConditionLogicalOperator,
nodesOutputVars,
availableNodes,
@@ -49,6 +50,7 @@ const Panel: FC> = ({
handleUpdateCondition={handleUpdateCondition}
handleRemoveCondition={handleRemoveCondition}
handleUpdateConditionLogicalOperator={handleUpdateConditionLogicalOperator}
+ handleAddSubVariableCondition={handleAddSubVariableCondition}
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 0216e6028c..d0b1aca4a0 100644
--- a/web/app/components/workflow/nodes/if-else/types.ts
+++ b/web/app/components/workflow/nodes/if-else/types.ts
@@ -33,23 +33,15 @@ export enum ComparisonOperator {
allOf = 'all of',
}
-export type SubVariableCondition = {
- id: string
- path: string
- type: VarType
- comparison_operator?: ComparisonOperator
- value: string
- numberVarType?: NumberVarType
-}
-
export type Condition = {
id: string
varType: VarType
- variable_selector: ValueSelector
+ variable_selector?: ValueSelector
+ key?: string // sub variable key
comparison_operator?: ComparisonOperator
value: string
numberVarType?: NumberVarType
- sub_variable_condition?: SubVariableCondition[]
+ sub_variable_condition?: CaseItem
}
export type CaseItem = {
@@ -66,6 +58,7 @@ 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 HandleUpdateConditionLogicalOperator = (caseId: string, value: LogicalOperator) => 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 99eeedca07..16911ca89b 100644
--- a/web/app/components/workflow/nodes/if-else/use-config.ts
+++ b/web/app/components/workflow/nodes/if-else/use-config.ts
@@ -9,6 +9,7 @@ import { LogicalOperator } from './types'
import type {
CaseItem,
HandleAddCondition,
+ HandleAddSubVariableCondition,
HandleRemoveCondition,
HandleUpdateCondition,
HandleUpdateConditionLogicalOperator,
@@ -58,7 +59,7 @@ const useConfig = (id: string, payload: IfElseNodeType) => {
const conditions: Record = {}
inputs.cases?.forEach((c) => {
c.conditions.forEach((condition) => {
- conditions[condition.id] = getIsVarFileAttribute(condition.variable_selector)
+ conditions[condition.id] = getIsVarFileAttribute(condition.variable_selector!)
})
})
return conditions
@@ -165,6 +166,36 @@ const useConfig = (id: string, payload: IfElseNodeType) => {
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
+ 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: '',
+ varType: VarType.string,
+ comparison_operator: undefined,
+ value: '',
+ })
+ }
+ })
+ setInputs(newInputs)
+ }, [inputs, setInputs])
+
const handleUpdateConditionLogicalOperator = useCallback((caseId, value) => {
const newInputs = produce(inputs, (draft) => {
const targetCase = draft.cases?.find(item => item.case_id === caseId)
@@ -185,6 +216,7 @@ const useConfig = (id: string, payload: IfElseNodeType) => {
handleAddCondition,
handleRemoveCondition,
handleUpdateCondition,
+ handleAddSubVariableCondition,
handleUpdateConditionLogicalOperator,
nodesOutputVars: availableVars,
availableNodes: availableNodesWithParent,
diff --git a/web/i18n/en-US/workflow.ts b/web/i18n/en-US/workflow.ts
index 3c2df8a743..780c95ad9e 100644
--- a/web/i18n/en-US/workflow.ts
+++ b/web/i18n/en-US/workflow.ts
@@ -434,6 +434,7 @@ const translation = {
addCondition: 'Add Condition',
conditionNotSetup: 'Condition NOT setup',
selectVariable: 'Select variable...',
+ addSubVariable: 'Sub Variable',
},
variableAssigner: {
title: 'Assign variables',
diff --git a/web/i18n/zh-Hans/workflow.ts b/web/i18n/zh-Hans/workflow.ts
index 03390de4cc..c07f7a5620 100644
--- a/web/i18n/zh-Hans/workflow.ts
+++ b/web/i18n/zh-Hans/workflow.ts
@@ -434,6 +434,7 @@ const translation = {
addCondition: '添加条件',
conditionNotSetup: '条件未设置',
selectVariable: '选择变量',
+ addSubVariable: '添加子变量',
},
variableAssigner: {
title: '变量赋值',