From 5adf94bd7df506c65bbf28443b3a039bfd23fe5d Mon Sep 17 00:00:00 2001 From: Joel Date: Fri, 15 Mar 2024 14:01:15 +0800 Subject: [PATCH] feat: support filter obj select type --- .../nodes/_base/components/variable/utils.ts | 42 ++++++++++++++++--- .../_base/components/variable/var-list.tsx | 8 ++-- .../variable/var-reference-picker.tsx | 8 ++-- .../variable/var-reference-popup.tsx | 2 +- .../components/var-list/index.tsx | 8 ++-- .../nodes/variable-assigner/panel.tsx | 3 +- .../nodes/variable-assigner/use-config.ts | 10 ++++- 7 files changed, 60 insertions(+), 21 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 bc0249f22f..edecb26cdb 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/utils.ts +++ b/web/app/components/workflow/nodes/_base/components/variable/utils.ts @@ -1,7 +1,7 @@ import type { CodeNodeType } from '../../../code/types' import { BlockEnum, InputVarType, VarType } from '@/app/components/workflow/types' import type { StartNodeType } from '@/app/components/workflow/nodes/start/types' -import type { NodeOutPutVar } from '@/app/components/workflow/types' +import type { NodeOutPutVar, Var } from '@/app/components/workflow/types' import type { VariableAssignerNodeType } from '@/app/components/workflow/nodes/variable-assigner/types' import { CHAT_QUESTION_CLASSIFIER_OUTPUT_STRUCT, @@ -21,7 +21,24 @@ const inputVarTypeToVarType = (type: InputVarType): VarType => { return VarType.string } -const formatItem = (item: any, isChatMode: boolean, varType?: VarType): NodeOutPutVar => { +const findExceptVarInObject = (obj: any, filterVar: (payload: Var) => boolean): Var => { + const { children } = obj + const res: Var = { + variable: obj.variable, + type: VarType.object, + children: children.filter((item: Var) => { + const { children } = item + if (!children) + return filterVar(item) + + const obj = findExceptVarInObject(item, filterVar) + return obj.children && obj.children?.length > 0 + }), + } + return res +} + +const formatItem = (item: any, isChatMode: boolean, filterVar: (payload: any) => boolean): NodeOutPutVar => { const { id, data } = item const res: NodeOutPutVar = { nodeId: id, @@ -109,15 +126,28 @@ const formatItem = (item: any, isChatMode: boolean, varType?: VarType): NodeOutP break } } - if (varType) - res.vars = res.vars.filter(v => v.type === varType) + + res.vars = res.vars.filter((v) => { + const { children } = v + if (!children) + return filterVar(v) + + const obj = findExceptVarInObject(v, filterVar) + return obj?.children && obj?.children.length > 0 + }).map((v) => { + const { children } = v + if (!children) + return v + + return findExceptVarInObject(v, filterVar) + }) return res } -export const toNodeOutputVars = (nodes: any[], isChatMode: boolean, varType?: VarType): NodeOutPutVar[] => { +export const toNodeOutputVars = (nodes: any[], isChatMode: boolean, filterVar = (_payload: Var) => true): NodeOutPutVar[] => { const res = nodes .filter(node => SUPPORT_OUTPUT_VARS_NODE.includes(node.data.type)) - .map(node => formatItem(node, isChatMode, varType)) + .map(node => formatItem(node, isChatMode, filterVar)) .filter(item => item.vars.length > 0) return res } diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx index de363d5cc8..bc562dafe1 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx @@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next' import produce from 'immer' import RemoveButton from '../remove-button' import VarReferencePicker from './var-reference-picker' -import { type ValueSelector, type VarType, type Variable } from '@/app/components/workflow/types' +import type { ValueSelector, Var, Variable } from '@/app/components/workflow/types' import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types' type Props = { @@ -15,7 +15,7 @@ type Props = { onChange: (list: Variable[]) => void isSupportConstantValue?: boolean onlyLeafNodeVar?: boolean - onlyVarType?: VarType + filterVar?: (payload: Var) => boolean } const VarList: FC = ({ @@ -25,7 +25,7 @@ const VarList: FC = ({ onChange, isSupportConstantValue, onlyLeafNodeVar, - onlyVarType, + filterVar, }) => { const { t } = useTranslation() @@ -90,7 +90,7 @@ const VarList: FC = ({ onChange={handleVarReferenceChange(index)} defaultVarKindType={item.variable_type} onlyLeafNodeVar={onlyLeafNodeVar} - onlyVarType={onlyVarType} + filterVar={filterVar} /> boolean } export const getNodeInfoById = (nodes: any, id: string) => { @@ -56,7 +56,7 @@ const VarReferencePicker: FC = ({ isSupportConstantValue, defaultVarKindType = VarKindType.static, onlyLeafNodeVar, - onlyVarType, + filterVar = () => true, }) => { const { t } = useTranslation() @@ -65,7 +65,7 @@ const VarReferencePicker: FC = ({ const isConstant = isSupportConstantValue && varKindType === VarKindType.static const { getTreeLeafNodes, getBeforeNodesInSameBranch } = useWorkflow() const availableNodes = onlyLeafNodeVar ? getTreeLeafNodes(nodeId) : getBeforeNodesInSameBranch(nodeId) - const outputVars = toNodeOutputVars(availableNodes, isChatMode, onlyVarType) + const outputVars = toNodeOutputVars(availableNodes, isChatMode, filterVar) const [open, setOpen] = useState(false) const hasValue = !isConstant && value.length > 0 const outputVarNodeId = hasValue ? value[0] : '' diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-reference-popup.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-reference-popup.tsx index cc995c74dd..032bb14d17 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-reference-popup.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-reference-popup.tsx @@ -86,7 +86,7 @@ const ObjectChildren: FC = ({ return (
{title}.{currObjPath.join('.')}
diff --git a/web/app/components/workflow/nodes/variable-assigner/components/var-list/index.tsx b/web/app/components/workflow/nodes/variable-assigner/components/var-list/index.tsx index 21b31c8d03..553d75aa56 100644 --- a/web/app/components/workflow/nodes/variable-assigner/components/var-list/index.tsx +++ b/web/app/components/workflow/nodes/variable-assigner/components/var-list/index.tsx @@ -5,7 +5,7 @@ import React, { useCallback } from 'react' import produce from 'immer' import RemoveButton from '../../../_base/components/remove-button' import VarReferencePicker from '@/app/components/workflow/nodes/_base/components/variable/var-reference-picker' -import type { ValueSelector, VarType } from '@/app/components/workflow/types' +import type { ValueSelector, Var } from '@/app/components/workflow/types' type Props = { readonly: boolean @@ -13,7 +13,7 @@ type Props = { list: ValueSelector[] onChange: (list: ValueSelector[]) => void onlyLeafNodeVar?: boolean - onlyVarType?: VarType + filterVar?: (payload: Var) => boolean } const VarList: FC = ({ @@ -22,7 +22,7 @@ const VarList: FC = ({ list, onChange, onlyLeafNodeVar, - onlyVarType, + filterVar, }) => { const { t } = useTranslation() const handleVarReferenceChange = useCallback((index: number) => { @@ -63,7 +63,7 @@ const VarList: FC = ({ value={item} onChange={handleVarReferenceChange(index)} onlyLeafNodeVar={onlyLeafNodeVar} - onlyVarType={onlyVarType} + filterVar={filterVar} width={350} /> > = ({ handleOutputTypeChange, handleVarListChange, handleAddVariable, + filterVar, } = useConfig(id, data) const typeOptions = [ @@ -66,7 +67,7 @@ const Panel: FC> = ({ list={inputs.variables} onChange={handleVarListChange} onlyLeafNodeVar - onlyVarType={inputs.output_type} + filterVar={filterVar} />
diff --git a/web/app/components/workflow/nodes/variable-assigner/use-config.ts b/web/app/components/workflow/nodes/variable-assigner/use-config.ts index 1aa26a49e0..0b64870552 100644 --- a/web/app/components/workflow/nodes/variable-assigner/use-config.ts +++ b/web/app/components/workflow/nodes/variable-assigner/use-config.ts @@ -3,13 +3,14 @@ import produce from 'immer' import useVarList from './components/var-list/use-var-list' import type { VariableAssignerNodeType } from './types' import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud' +import type { Var, VarType } from '@/app/components/workflow/types' const useConfig = (id: string, payload: VariableAssignerNodeType) => { const { inputs, setInputs } = useNodeCrud(id, payload) const handleOutputTypeChange = useCallback((outputType: string) => { const newInputs = produce(inputs, (draft: VariableAssignerNodeType) => { - draft.output_type = outputType + draft.output_type = outputType as VarType }) setInputs(newInputs) }, [inputs, setInputs]) @@ -19,11 +20,18 @@ const useConfig = (id: string, payload: VariableAssignerNodeType) => { inputs, setInputs, }) + + const filterVar = useCallback((varPayload: Var) => { + if (varPayload.type !== inputs.output_type) + return false + return true + }, [inputs]) return { inputs, handleOutputTypeChange, handleVarListChange, handleAddVariable, + filterVar, } }