| import { useCallback } from 'react' |
| import { |
| useNodes, |
| useStoreApi, |
| } from 'reactflow' |
| import { uniqBy } from 'lodash-es' |
| import produce from 'immer' |
| import { |
| useIsChatMode, |
| useNodeDataUpdate, |
| useWorkflow, |
| useWorkflowVariables, |
| } from '../../hooks' |
| import type { |
| Node, |
| ValueSelector, |
| Var, |
| } from '../../types' |
| import { useWorkflowStore } from '../../store' |
| import type { |
| VarGroupItem, |
| VariableAssignerNodeType, |
| } from './types' |
|
|
| export const useVariableAssigner = () => { |
| const store = useStoreApi() |
| const workflowStore = useWorkflowStore() |
| const { handleNodeDataUpdate } = useNodeDataUpdate() |
|
|
| const handleAssignVariableValueChange = useCallback((nodeId: string, value: ValueSelector, varDetail: Var, groupId?: string) => { |
| const { getNodes } = store.getState() |
| const nodes = getNodes() |
| const node: Node<VariableAssignerNodeType> = nodes.find(node => node.id === nodeId)! |
|
|
| let payload |
| if (groupId && groupId !== 'target') { |
| payload = { |
| advanced_settings: { |
| ...node.data.advanced_settings, |
| groups: node.data.advanced_settings?.groups.map((group: VarGroupItem & { groupId: string }) => { |
| if (group.groupId === groupId && !group.variables.some(item => item.join('.') === (value as ValueSelector).join('.'))) { |
| return { |
| ...group, |
| variables: [...group.variables, value], |
| output_type: varDetail.type, |
| } |
| } |
| return group |
| }), |
| }, |
| } |
| } |
| else { |
| if (node.data.variables.some(item => item.join('.') === (value as ValueSelector).join('.'))) |
| return |
| payload = { |
| variables: [...node.data.variables, value], |
| output_type: varDetail.type, |
| } |
| } |
| handleNodeDataUpdate({ |
| id: nodeId, |
| data: payload, |
| }) |
| }, [store, handleNodeDataUpdate]) |
|
|
| const handleAddVariableInAddVariablePopupWithPosition = useCallback(( |
| nodeId: string, |
| variableAssignerNodeId: string, |
| variableAssignerNodeHandleId: string, |
| value: ValueSelector, |
| varDetail: Var, |
| ) => { |
| const { |
| getNodes, |
| setNodes, |
| } = store.getState() |
| const { |
| setShowAssignVariablePopup, |
| } = workflowStore.getState() |
|
|
| const newNodes = produce(getNodes(), (draft) => { |
| draft.forEach((node) => { |
| if (node.id === nodeId || node.id === variableAssignerNodeId) { |
| node.data = { |
| ...node.data, |
| _showAddVariablePopup: false, |
| _holdAddVariablePopup: false, |
| } |
| } |
| }) |
| }) |
| setNodes(newNodes) |
| setShowAssignVariablePopup(undefined) |
| handleAssignVariableValueChange(variableAssignerNodeId, value, varDetail, variableAssignerNodeHandleId) |
| }, [store, workflowStore, handleAssignVariableValueChange]) |
|
|
| const handleGroupItemMouseEnter = useCallback((groupId: string) => { |
| const { |
| setHoveringAssignVariableGroupId, |
| } = workflowStore.getState() |
|
|
| setHoveringAssignVariableGroupId(groupId) |
| }, [workflowStore]) |
|
|
| const handleGroupItemMouseLeave = useCallback(() => { |
| const { |
| connectingNodePayload, |
| setHoveringAssignVariableGroupId, |
| } = workflowStore.getState() |
|
|
| if (connectingNodePayload) |
| setHoveringAssignVariableGroupId(undefined) |
| }, [workflowStore]) |
|
|
| return { |
| handleAddVariableInAddVariablePopupWithPosition, |
| handleGroupItemMouseEnter, |
| handleGroupItemMouseLeave, |
| handleAssignVariableValueChange, |
| } |
| } |
|
|
| export const useGetAvailableVars = () => { |
| const nodes: Node[] = useNodes() |
| const { getBeforeNodesInSameBranchIncludeParent } = useWorkflow() |
| const { getNodeAvailableVars } = useWorkflowVariables() |
| const isChatMode = useIsChatMode() |
| const getAvailableVars = useCallback((nodeId: string, handleId: string, filterVar: (v: Var) => boolean, hideEnv = false) => { |
| const availableNodes: Node[] = [] |
| const currentNode = nodes.find(node => node.id === nodeId)! |
|
|
| if (!currentNode) |
| return [] |
|
|
| const beforeNodes = getBeforeNodesInSameBranchIncludeParent(nodeId) |
| availableNodes.push(...beforeNodes) |
| const parentNode = nodes.find(node => node.id === currentNode.parentId) |
|
|
| if (hideEnv) { |
| return getNodeAvailableVars({ |
| parentNode, |
| beforeNodes: uniqBy(availableNodes, 'id').filter(node => node.id !== nodeId), |
| isChatMode, |
| hideEnv, |
| hideChatVar: hideEnv, |
| filterVar, |
| }) |
| .map(node => ({ |
| ...node, |
| vars: node.isStartNode ? node.vars.filter(v => !v.variable.startsWith('sys.')) : node.vars, |
| })) |
| .filter(item => item.vars.length > 0) |
| } |
|
|
| return getNodeAvailableVars({ |
| parentNode, |
| beforeNodes: uniqBy(availableNodes, 'id').filter(node => node.id !== nodeId), |
| isChatMode, |
| filterVar, |
| }) |
| }, [nodes, getBeforeNodesInSameBranchIncludeParent, getNodeAvailableVars, isChatMode]) |
|
|
| return getAvailableVars |
| } |
|
|