فهرست منبع

fix: workflow add next node from knowledge retrieval node (#4467)

zxhlyh 11 ماه پیش
والد
کامیت
de3a7603ac

+ 6 - 8
web/app/components/workflow/hooks/use-nodes-interactions.ts

@@ -466,8 +466,7 @@ export const useNodesInteractions = () => {
       const prevNode = nodes[prevNodeIndex]
       const outgoers = getOutgoers(prevNode, nodes, edges).sort((a, b) => a.position.y - b.position.y)
       const lastOutgoer = outgoers[outgoers.length - 1]
-      if (prevNode.data.type === BlockEnum.KnowledgeRetrieval)
-        targetHandle = prevNodeId
+
       newNode.data._connectedTargetHandleIds = [targetHandle]
       newNode.data._connectedSourceHandleIds = []
       newNode.position = {
@@ -593,8 +592,7 @@ export const useNodesInteractions = () => {
     if (prevNodeId && nextNodeId) {
       const prevNode = nodes.find(node => node.id === prevNodeId)!
       const nextNode = nodes.find(node => node.id === nextNodeId)!
-      if (prevNode.data.type === BlockEnum.KnowledgeRetrieval)
-        targetHandle = prevNodeId
+
       newNode.data._connectedTargetHandleIds = [targetHandle]
       newNode.data._connectedSourceHandleIds = [sourceHandle]
       newNode.position = {
@@ -925,10 +923,6 @@ export const useNodesInteractions = () => {
       edges,
     } = store.getState()
 
-    const edgeSelected = edges.some(edge => edge.selected)
-    if (edgeSelected)
-      return
-
     const nodes = getNodes()
     const bundledNodes = nodes.filter(node => node.data._isBundled && node.data.type !== BlockEnum.Start)
 
@@ -937,6 +931,10 @@ export const useNodesInteractions = () => {
       return
     }
 
+    const edgeSelected = edges.some(edge => edge.selected)
+    if (edgeSelected)
+      return
+
     const selectedNode = nodes.find(node => node.data.selected && node.data.type !== BlockEnum.Start)
 
     if (selectedNode)

+ 31 - 0
web/app/components/workflow/hooks/use-selection-interactions.ts

@@ -101,9 +101,40 @@ export const useSelectionInteractions = () => {
     setNodes(newNodes)
   }, [store, workflowStore])
 
+  const handleSelectionCancel = useCallback(() => {
+    const {
+      getNodes,
+      setNodes,
+      edges,
+      setEdges,
+    } = store.getState()
+
+    store.setState({
+      userSelectionRect: null,
+      userSelectionActive: true,
+    })
+
+    const nodes = getNodes()
+    const newNodes = produce(nodes, (draft) => {
+      draft.forEach((node) => {
+        if (node.data._isBundled)
+          node.data._isBundled = false
+      })
+    })
+    setNodes(newNodes)
+    const newEdges = produce(edges, (draft) => {
+      draft.forEach((edge) => {
+        if (edge.data._isBundled)
+          edge.data._isBundled = false
+      })
+    })
+    setEdges(newEdges)
+  }, [store])
+
   return {
     handleSelectionStart,
     handleSelectionChange,
     handleSelectionDrag,
+    handleSelectionCancel,
   }
 }

+ 44 - 3
web/app/components/workflow/operator/control.tsx

@@ -1,10 +1,13 @@
-import { memo } from 'react'
+import { memo, useCallback } from 'react'
 import { useTranslation } from 'react-i18next'
 import cn from 'classnames'
+import { useKeyPress } from 'ahooks'
 import {
   useNodesReadOnly,
+  useSelectionInteractions,
   useWorkflow,
 } from '../hooks'
+import { isEventTargetInputArea } from '../utils'
 import { useStore } from '../store'
 import AddBlock from './add-block'
 import TipPopup from './tip-popup'
@@ -27,6 +30,44 @@ const Control = () => {
     nodesReadOnly,
     getNodesReadOnly,
   } = useNodesReadOnly()
+  const { handleSelectionCancel } = useSelectionInteractions()
+
+  const handleModePointer = useCallback(() => {
+    if (getNodesReadOnly())
+      return
+    setControlMode('pointer')
+  }, [getNodesReadOnly, setControlMode])
+  const handleModeHand = useCallback(() => {
+    if (getNodesReadOnly())
+      return
+    setControlMode('hand')
+    handleSelectionCancel()
+  }, [getNodesReadOnly, setControlMode, handleSelectionCancel])
+
+  useKeyPress('h', (e) => {
+    if (getNodesReadOnly())
+      return
+
+    if (isEventTargetInputArea(e.target as HTMLElement))
+      return
+
+    e.preventDefault()
+    handleModeHand()
+  }, {
+    exactMatch: true,
+    useCapture: true,
+  })
+
+  useKeyPress('v', (e) => {
+    if (isEventTargetInputArea(e.target as HTMLElement))
+      return
+
+    e.preventDefault()
+    handleModePointer()
+  }, {
+    exactMatch: true,
+    useCapture: true,
+  })
 
   const goLayout = () => {
     if (getNodesReadOnly())
@@ -45,7 +86,7 @@ const Control = () => {
             controlMode === 'pointer' ? 'bg-primary-50 text-primary-600' : 'hover:bg-black/5 hover:text-gray-700',
             `${nodesReadOnly && '!cursor-not-allowed opacity-50'}`,
           )}
-          onClick={() => setControlMode('pointer')}
+          onClick={handleModePointer}
         >
           {
             controlMode === 'pointer' ? <Cursor02CSolid className='w-4 h-4' /> : <Cursor02C className='w-4 h-4' />
@@ -59,7 +100,7 @@ const Control = () => {
             controlMode === 'hand' ? 'bg-primary-50 text-primary-600' : 'hover:bg-black/5 hover:text-gray-700',
             `${nodesReadOnly && '!cursor-not-allowed opacity-50'}`,
           )}
-          onClick={() => setControlMode('hand')}
+          onClick={handleModeHand}
         >
           {
             controlMode === 'hand' ? <Hand02Solid className='w-4 h-4' /> : <Hand02 className='w-4 h-4' />