| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  | import { useCallback } from 'react' | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |   useNodes, | 
					
						
							|  |  |  |   useStoreApi, | 
					
						
							|  |  |  | } from 'reactflow' | 
					
						
							|  |  |  | import { uniqBy } from 'lodash-es' | 
					
						
							|  |  |  | import produce from 'immer' | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |   useIsChatMode, | 
					
						
							|  |  |  |   useNodeDataUpdate, | 
					
						
							|  |  |  |   useWorkflow, | 
					
						
							| 
									
										
										
										
											2024-07-22 15:29:39 +08:00
										 |  |  |   useWorkflowVariables, | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  | } 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() | 
					
						
							| 
									
										
										
										
											2024-05-30 18:54:58 +08:00
										 |  |  |   const { getBeforeNodesInSameBranchIncludeParent } = useWorkflow() | 
					
						
							| 
									
										
										
										
											2024-07-22 15:29:39 +08:00
										 |  |  |   const { getNodeAvailableVars } = useWorkflowVariables() | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |   const isChatMode = useIsChatMode() | 
					
						
							| 
									
										
										
										
											2024-07-22 15:29:39 +08:00
										 |  |  |   const getAvailableVars = useCallback((nodeId: string, handleId: string, filterVar: (v: Var) => boolean, hideEnv = false) => { | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |     const availableNodes: Node[] = [] | 
					
						
							|  |  |  |     const currentNode = nodes.find(node => node.id === nodeId)! | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!currentNode) | 
					
						
							|  |  |  |       return [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-30 18:54:58 +08:00
										 |  |  |     const beforeNodes = getBeforeNodesInSameBranchIncludeParent(nodeId) | 
					
						
							|  |  |  |     availableNodes.push(...beforeNodes) | 
					
						
							|  |  |  |     const parentNode = nodes.find(node => node.id === currentNode.parentId) | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-22 15:29:39 +08:00
										 |  |  |     if (hideEnv) { | 
					
						
							|  |  |  |       return getNodeAvailableVars({ | 
					
						
							|  |  |  |         parentNode, | 
					
						
							|  |  |  |         beforeNodes: uniqBy(availableNodes, 'id').filter(node => node.id !== nodeId), | 
					
						
							|  |  |  |         isChatMode, | 
					
						
							|  |  |  |         hideEnv, | 
					
						
							| 
									
										
										
										
											2024-08-13 14:44:10 +08:00
										 |  |  |         hideChatVar: hideEnv, | 
					
						
							| 
									
										
										
										
											2024-07-22 15:29:39 +08:00
										 |  |  |         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({ | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  |       parentNode, | 
					
						
							|  |  |  |       beforeNodes: uniqBy(availableNodes, 'id').filter(node => node.id !== nodeId), | 
					
						
							|  |  |  |       isChatMode, | 
					
						
							|  |  |  |       filterVar, | 
					
						
							|  |  |  |     }) | 
					
						
							| 
									
										
										
										
											2024-07-22 15:29:39 +08:00
										 |  |  |   }, [nodes, getBeforeNodesInSameBranchIncludeParent, getNodeAvailableVars, isChatMode]) | 
					
						
							| 
									
										
										
										
											2024-05-27 21:57:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return getAvailableVars | 
					
						
							|  |  |  | } |