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 edecb26cdb..ddef0d4470 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, Var } from '@/app/components/workflow/types' +import type { NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflow/types' import type { VariableAssignerNodeType } from '@/app/components/workflow/nodes/variable-assigner/types' import { CHAT_QUESTION_CLASSIFIER_OUTPUT_STRUCT, @@ -21,24 +21,25 @@ const inputVarTypeToVarType = (type: InputVarType): VarType => { return VarType.string } -const findExceptVarInObject = (obj: any, filterVar: (payload: Var) => boolean): Var => { +const findExceptVarInObject = (obj: any, filterVar: (payload: Var, selector: ValueSelector) => boolean, value_selector: ValueSelector): Var => { const { children } = obj const res: Var = { variable: obj.variable, type: VarType.object, children: children.filter((item: Var) => { const { children } = item + const currSelector = [...value_selector, item.variable] if (!children) - return filterVar(item) + return filterVar(item, currSelector) - const obj = findExceptVarInObject(item, filterVar) + const obj = findExceptVarInObject(item, filterVar, currSelector) return obj.children && obj.children?.length > 0 }), } return res } -const formatItem = (item: any, isChatMode: boolean, filterVar: (payload: any) => boolean): NodeOutPutVar => { +const formatItem = (item: any, isChatMode: boolean, filterVar: (payload: Var, selector: ValueSelector) => boolean): NodeOutPutVar => { const { id, data } = item const res: NodeOutPutVar = { nodeId: id, @@ -127,24 +128,25 @@ const formatItem = (item: any, isChatMode: boolean, filterVar: (payload: any) => } } + const selector = [id] res.vars = res.vars.filter((v) => { const { children } = v if (!children) - return filterVar(v) + return filterVar(v, selector) - const obj = findExceptVarInObject(v, filterVar) + const obj = findExceptVarInObject(v, filterVar, selector) return obj?.children && obj?.children.length > 0 }).map((v) => { const { children } = v if (!children) return v - return findExceptVarInObject(v, filterVar) + return findExceptVarInObject(v, filterVar, selector) }) return res } -export const toNodeOutputVars = (nodes: any[], isChatMode: boolean, filterVar = (_payload: Var) => true): NodeOutPutVar[] => { +export const toNodeOutputVars = (nodes: any[], isChatMode: boolean, filterVar = (_payload: Var, _selector: ValueSelector) => true): NodeOutPutVar[] => { const res = nodes .filter(node => SUPPORT_OUTPUT_VARS_NODE.includes(node.data.type)) .map(node => formatItem(node, isChatMode, filterVar)) 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 bc562dafe1..c968a7955b 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 @@ -15,7 +15,7 @@ type Props = { onChange: (list: Variable[]) => void isSupportConstantValue?: boolean onlyLeafNodeVar?: boolean - filterVar?: (payload: Var) => boolean + filterVar?: (payload: Var, valueSelector: ValueSelector) => boolean } const VarList: FC = ({ 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 96af3a0ad2..60263fa540 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 @@ -32,10 +32,11 @@ type Props = { readonly: boolean value: ValueSelector | string onChange: (value: ValueSelector | string, varKindType: VarKindType) => void + onOpen?: () => void isSupportConstantValue?: boolean defaultVarKindType?: VarKindType onlyLeafNodeVar?: boolean - filterVar?: (payload: Var) => boolean + filterVar?: (payload: Var, valueSelector: ValueSelector) => boolean } export const getNodeInfoById = (nodes: any, id: string) => { @@ -52,6 +53,7 @@ const VarReferencePicker: FC = ({ className, isShowNodeName, value, + onOpen = () => { }, onChange, isSupportConstantValue, defaultVarKindType = VarKindType.static, @@ -67,6 +69,10 @@ const VarReferencePicker: FC = ({ const availableNodes = onlyLeafNodeVar ? getTreeLeafNodes(nodeId) : getBeforeNodesInSameBranch(nodeId) const outputVars = toNodeOutputVars(availableNodes, isChatMode, filterVar) const [open, setOpen] = useState(false) + useEffect(() => { + onOpen() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [open]) const hasValue = !isConstant && value.length > 0 const outputVarNodeId = hasValue ? value[0] : '' const outputVarNode = hasValue ? getNodeInfoById(availableNodes, outputVarNodeId)?.data : null diff --git a/web/app/components/workflow/nodes/end/use-config.ts b/web/app/components/workflow/nodes/end/use-config.ts index a0198cc356..81c9b19411 100644 --- a/web/app/components/workflow/nodes/end/use-config.ts +++ b/web/app/components/workflow/nodes/end/use-config.ts @@ -12,7 +12,6 @@ const useConfig = (id: string, payload: EndNodeType) => { }, varKey: 'outputs', }) - console.log(inputs) return { inputs, 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 553d75aa56..455686787c 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 @@ -12,8 +12,9 @@ type Props = { nodeId: string list: ValueSelector[] onChange: (list: ValueSelector[]) => void + onOpen?: (index: number) => void onlyLeafNodeVar?: boolean - filterVar?: (payload: Var) => boolean + filterVar?: (payload: Var, valueSelector: ValueSelector) => boolean } const VarList: FC = ({ @@ -21,6 +22,7 @@ const VarList: FC = ({ nodeId, list, onChange, + onOpen = () => { }, onlyLeafNodeVar, filterVar, }) => { @@ -43,6 +45,10 @@ const VarList: FC = ({ } }, [list, onChange]) + const handleOpen = useCallback((index: number) => { + return () => onOpen(index) + }, [onOpen]) + if (list.length === 0) { return (
@@ -62,6 +68,7 @@ const VarList: FC = ({ className='grow' value={item} onChange={handleVarReferenceChange(index)} + onOpen={handleOpen(index)} onlyLeafNodeVar={onlyLeafNodeVar} filterVar={filterVar} width={350} diff --git a/web/app/components/workflow/nodes/variable-assigner/panel.tsx b/web/app/components/workflow/nodes/variable-assigner/panel.tsx index b6199dd5ae..63bb4870d3 100644 --- a/web/app/components/workflow/nodes/variable-assigner/panel.tsx +++ b/web/app/components/workflow/nodes/variable-assigner/panel.tsx @@ -24,6 +24,7 @@ const Panel: FC> = ({ handleOutputTypeChange, handleVarListChange, handleAddVariable, + handleOnVarOpen, filterVar, } = useConfig(id, data) @@ -66,6 +67,7 @@ const Panel: FC> = ({ nodeId={id} list={inputs.variables} onChange={handleVarListChange} + onOpen={handleOnVarOpen} onlyLeafNodeVar 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 0b64870552..e25b43b059 100644 --- a/web/app/components/workflow/nodes/variable-assigner/use-config.ts +++ b/web/app/components/workflow/nodes/variable-assigner/use-config.ts @@ -1,9 +1,9 @@ -import { useCallback } from 'react' +import { useCallback, useState } from 'react' 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' +import type { ValueSelector, Var, VarType } from '@/app/components/workflow/types' const useConfig = (id: string, payload: VariableAssignerNodeType) => { const { inputs, setInputs } = useNodeCrud(id, payload) @@ -21,16 +21,33 @@ const useConfig = (id: string, payload: VariableAssignerNodeType) => { setInputs, }) - const filterVar = useCallback((varPayload: Var) => { + const { variables } = inputs + const [currVarIndex, setCurrVarIndex] = useState(-1) + const currVar = variables[currVarIndex] + const handleOnVarOpen = useCallback((index: number) => { + setCurrVarIndex(index) + }, []) + const filterVar = useCallback((varPayload: Var, valueSelector: ValueSelector) => { if (varPayload.type !== inputs.output_type) return false + + // can not choose the same node + if (!currVar) + return true + + const selectNodeId = valueSelector[0] + + if (selectNodeId !== currVar[0] && variables.find(v => v[0] === selectNodeId)) + return false + return true - }, [inputs]) + }, [currVar, inputs.output_type, variables]) return { inputs, handleOutputTypeChange, handleVarListChange, handleAddVariable, + handleOnVarOpen, filterVar, } }