From 15e2ab920399e6a4b81a1a3ebe756446774f6cbd Mon Sep 17 00:00:00 2001 From: Joel Date: Tue, 19 Mar 2024 18:55:58 +0800 Subject: [PATCH] feat: ifelse not set var not change selector --- .../nodes/_base/components/variable/utils.ts | 38 +++++++++++++++++++ .../variable/var-reference-picker.tsx | 6 +-- .../if-else/components/condition-item.tsx | 29 ++++++++++---- .../if-else/components/condition-list.tsx | 7 +++- .../workflow/nodes/if-else/panel.tsx | 2 + .../workflow/nodes/if-else/use-config.ts | 14 +++++++ 6 files changed, 81 insertions(+), 15 deletions(-) diff --git a/web/app/components/workflow/nodes/_base/components/variable/utils.ts b/web/app/components/workflow/nodes/_base/components/variable/utils.ts index 98e6b5ed9a..666a340944 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/utils.ts +++ b/web/app/components/workflow/nodes/_base/components/variable/utils.ts @@ -161,3 +161,41 @@ export const toNodeOutputVars = (nodes: any[], isChatMode: boolean, filterVar = .filter(item => item.vars.length > 0) return res } + +export const isSystemVar = (valueSelector: ValueSelector) => { + return valueSelector[0] === 'sys' || valueSelector[1] === 'sys' +} + +export const getVarType = (value: ValueSelector, availableNodes: any[], isChatMode: boolean): VarType | undefined => { + const isSystem = isSystemVar(value) + const startNode = availableNodes.find((node: any) => { + return node.data.type === BlockEnum.Start + }) + const allOutputVars = toNodeOutputVars(availableNodes, isChatMode) + + const targetVarNodeId = isSystem ? startNode?.id : value[0] + const targetVar = allOutputVars.find(v => v.nodeId === targetVarNodeId) + + if (!targetVar) + return undefined + + let type: VarType = VarType.string + let curr: any = targetVar.vars + if (isSystem) { + return curr.find((v: any) => v.variable === (value as ValueSelector).join('.'))?.type + } + else { + (value as ValueSelector).slice(1).forEach((key, i) => { + const isLast = i === value.length - 2 + curr = curr.find((v: any) => v.variable === key) + if (isLast) { + type = curr?.type + } + else { + if (curr.type === VarType.object) + curr = curr.children + } + }) + return type + } +} diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx index a97f4beb8d..6e8edcb385 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-reference-picker.tsx @@ -6,7 +6,7 @@ import cn from 'classnames' import { isArray } from 'lodash-es' import produce from 'immer' import VarReferencePopup from './var-reference-popup' -import { toNodeOutputVars } from './utils' +import { isSystemVar, toNodeOutputVars } from './utils' import type { ValueSelector, Var } from '@/app/components/workflow/types' import { BlockEnum, VarType } from '@/app/components/workflow/types' import { VarBlockIcon } from '@/app/components/workflow/block-icon' @@ -47,10 +47,6 @@ const getNodeInfoById = (nodes: any, id: string) => { return nodes.find((node: any) => node.id === id) } -const isSystemVar = (valueSelector: ValueSelector) => { - return valueSelector[0] === 'sys' || valueSelector[1] === 'sys' -} - const VarReferencePicker: FC = ({ nodeId, width, diff --git a/web/app/components/workflow/nodes/if-else/components/condition-item.tsx b/web/app/components/workflow/nodes/if-else/components/condition-item.tsx index 9102bb3e68..e47163920e 100644 --- a/web/app/components/workflow/nodes/if-else/components/condition-item.tsx +++ b/web/app/components/workflow/nodes/if-else/components/condition-item.tsx @@ -5,12 +5,14 @@ import { useTranslation } from 'react-i18next' import cn from 'classnames' import VarReferencePicker from '../../_base/components/variable/var-reference-picker' import { isComparisonOperatorNeedTranslate } from '../utils' +import { VarType } from '../../../types' import type { Condition } from '@/app/components/workflow/nodes/if-else/types' import { ComparisonOperator, LogicalOperator } from '@/app/components/workflow/nodes/if-else/types' import type { ValueSelector, Var } from '@/app/components/workflow/types' import { Trash03 } from '@/app/components/base/icons/src/vender/line/general' import { RefreshCw05 } from '@/app/components/base/icons/src/vender/line/arrows' import Selector from '@/app/components/workflow/nodes/_base/components/selector' +import Toast from '@/app/components/base/toast' const i18nPrefix = 'workflow.nodes.ifElse' const Line = ( @@ -25,9 +27,9 @@ const Line = ( ) -const getOperators = (type: string) => { +const getOperators = (type?: VarType) => { switch (type) { - case 'string': + case VarType.string: return [ ComparisonOperator.contains, ComparisonOperator.notContains, @@ -38,7 +40,7 @@ const getOperators = (type: string) => { ComparisonOperator.empty, ComparisonOperator.notEmpty, ] - case 'number': + case VarType.number: return [ ComparisonOperator.equal, ComparisonOperator.notEqual, @@ -51,15 +53,13 @@ const getOperators = (type: string) => { ComparisonOperator.empty, ComparisonOperator.notEmpty, ] - case 'array': + default: return [ ComparisonOperator.is, ComparisonOperator.isNot, ComparisonOperator.empty, ComparisonOperator.notEmpty, ] - default: - return [] } } @@ -67,6 +67,7 @@ type ItemProps = { readonly: boolean nodeId: string payload: Condition + varType?: VarType onChange: (newItem: Condition) => void canRemove: boolean onRemove?: () => void @@ -80,6 +81,7 @@ const Item: FC = ({ readonly, nodeId, payload, + varType, onChange, canRemove, onRemove = () => { }, @@ -149,13 +151,24 @@ const Item: FC = ({ popupClassName='top-[34px]' itemClassName='capitalize' trigger={ -
+
{ + if (!varType) { + e.stopPropagation() + Toast.notify({ + message: 'please selector var first', // t(`${i18nPrefix}.selectVarType`) + type: 'error', + }) + } + }} + className='shrink-0 w-[100px] whitespace-nowrap flex items-center h-8 justify-between px-2.5 rounded-lg bg-gray-100 capitalize cursor-pointer' + >
{isComparisonOperatorNeedTranslate(payload.comparison_operator) ? t(`${i18nPrefix}.comparisonOperator.${payload.comparison_operator}`) : payload.comparison_operator}
} readonly={readonly} value={payload.comparison_operator} - options={getOperators('string').map((o) => { + options={getOperators(varType).map((o) => { return { label: isComparisonOperatorNeedTranslate(o) ? t(`${i18nPrefix}.comparisonOperator.${o}`) : o, value: o, diff --git a/web/app/components/workflow/nodes/if-else/components/condition-list.tsx b/web/app/components/workflow/nodes/if-else/components/condition-list.tsx index 2c1318c4df..d2ea197fca 100644 --- a/web/app/components/workflow/nodes/if-else/components/condition-list.tsx +++ b/web/app/components/workflow/nodes/if-else/components/condition-list.tsx @@ -3,7 +3,7 @@ import type { FC } from 'react' import React, { useCallback } from 'react' import produce from 'immer' import cn from 'classnames' -import type { Var } from '../../../types' +import type { Var, VarType } from '../../../types' import Item from './condition-item' import type { Condition, LogicalOperator } from '@/app/components/workflow/nodes/if-else/types' @@ -12,6 +12,7 @@ type Props = { className?: string readonly: boolean list: Condition[] + varTypesList: (VarType | undefined)[] onChange: (newList: Condition[]) => void logicalOperator: LogicalOperator onLogicalOperatorToggle: () => void @@ -23,6 +24,7 @@ const ConditionList: FC = ({ readonly, nodeId, list, + varTypesList, onChange, logicalOperator, onLogicalOperatorToggle, @@ -50,13 +52,13 @@ const ConditionList: FC = ({ if (list.length === 0) return null - return (
= ({ readonly={readonly} nodeId={nodeId} payload={item} + varType={varTypesList[i + 1]} onChange={handleItemChange(i + 1)} canRemove={canRemove} onRemove={handleItemRemove(i + 1)} diff --git a/web/app/components/workflow/nodes/if-else/panel.tsx b/web/app/components/workflow/nodes/if-else/panel.tsx index d3dd3be053..a44b559d75 100644 --- a/web/app/components/workflow/nodes/if-else/panel.tsx +++ b/web/app/components/workflow/nodes/if-else/panel.tsx @@ -22,6 +22,7 @@ const Panel: FC> = ({ handleConditionsChange, handleAddCondition, handleLogicalOperatorToggle, + varTypesList, filterVar, } = useConfig(id, data) return ( @@ -39,6 +40,7 @@ const Panel: FC> = ({ onChange={handleConditionsChange} logicalOperator={inputs.logical_operator} onLogicalOperatorToggle={handleLogicalOperatorToggle} + varTypesList={varTypesList} filterVar={filterVar} /> { + const { getBeforeNodesInSameBranch } = useWorkflow() + const isChatMode = useIsChatMode() + const availableNodes = getBeforeNodesInSameBranch(id) + const { inputs, setInputs } = useNodeCrud(id, payload) const handleConditionsChange = useCallback((newConditions: Condition[]) => { @@ -39,11 +48,16 @@ const useConfig = (id: string, payload: IfElseNodeType) => { return varPayload.type !== VarType.arrayFile }, []) + const varTypesList = (inputs.conditions || []).map((condition) => { + return getVarType(condition.variable_selector, availableNodes, isChatMode) + }) + return { inputs, handleConditionsChange, handleAddCondition, handleLogicalOperatorToggle, + varTypesList, filterVar, } }