mirror of https://github.com/langgenius/dify.git
hooks
This commit is contained in:
parent
d2d6904c9b
commit
e8921787b3
|
|
@ -3,9 +3,11 @@ import produce from 'immer'
|
|||
import type {
|
||||
EdgeMouseHandler,
|
||||
NodeMouseHandler,
|
||||
OnConnect,
|
||||
} from 'reactflow'
|
||||
import {
|
||||
getConnectedEdges,
|
||||
getIncomers,
|
||||
useStoreApi,
|
||||
} from 'reactflow'
|
||||
import type {
|
||||
|
|
@ -88,6 +90,33 @@ export const useWorkflow = () => {
|
|||
setNodes(newNodes)
|
||||
}, [store])
|
||||
|
||||
const handleConnectNode = useCallback<OnConnect>(({
|
||||
source,
|
||||
sourceHandle,
|
||||
target,
|
||||
targetHandle,
|
||||
}) => {
|
||||
const {
|
||||
edges,
|
||||
setEdges,
|
||||
} = store.getState()
|
||||
|
||||
const newEdges = produce(edges, (draft) => {
|
||||
const filtered = draft.filter(edge => edge.source !== source && edge.target !== target)
|
||||
|
||||
filtered.push({
|
||||
id: `${source}-${target}`,
|
||||
source: source!,
|
||||
target: target!,
|
||||
sourceHandle,
|
||||
targetHandle,
|
||||
})
|
||||
|
||||
return filtered
|
||||
})
|
||||
setEdges(newEdges)
|
||||
}, [store])
|
||||
|
||||
const handleEnterEdge = useCallback<EdgeMouseHandler>((_, edge) => {
|
||||
const {
|
||||
edges,
|
||||
|
|
@ -158,6 +187,7 @@ export const useWorkflow = () => {
|
|||
x: currentNode.position.x + 304,
|
||||
y: currentNode.position.y,
|
||||
},
|
||||
selected: true,
|
||||
}
|
||||
const newEdge = {
|
||||
id: `${currentNode.id}-${nextNode.id}`,
|
||||
|
|
@ -169,7 +199,7 @@ export const useWorkflow = () => {
|
|||
}
|
||||
const newNodes = produce(nodes, (draft) => {
|
||||
draft.forEach((node) => {
|
||||
node.data = { ...node.data, selected: false }
|
||||
node.selected = false
|
||||
})
|
||||
draft.push(nextNode)
|
||||
})
|
||||
|
|
@ -180,7 +210,7 @@ export const useWorkflow = () => {
|
|||
setEdges(newEdges)
|
||||
}, [store])
|
||||
|
||||
const handleChangeCurrentNode = useCallback((parentNodeId: string, currentNodeId: string, nodeType: BlockEnum, sourceHandle: string) => {
|
||||
const handleChangeCurrentNode = useCallback((currentNodeId: string, nodeType: BlockEnum, sourceHandle?: string) => {
|
||||
const {
|
||||
getNodes,
|
||||
setNodes,
|
||||
|
|
@ -189,6 +219,7 @@ export const useWorkflow = () => {
|
|||
} = store.getState()
|
||||
const nodes = getNodes()
|
||||
const currentNode = nodes.find(node => node.id === currentNodeId)!
|
||||
const incomers = getIncomers(currentNode, nodes, edges)
|
||||
const connectedEdges = getConnectedEdges([currentNode], edges)
|
||||
const newCurrentNode: Node = {
|
||||
id: `${Date.now()}`,
|
||||
|
|
@ -199,27 +230,32 @@ export const useWorkflow = () => {
|
|||
y: currentNode.position.y,
|
||||
},
|
||||
}
|
||||
const newEdge = {
|
||||
id: `${parentNodeId}-${newCurrentNode.id}`,
|
||||
type: 'custom',
|
||||
source: parentNodeId,
|
||||
sourceHandle,
|
||||
target: newCurrentNode.id,
|
||||
targetHandle: 'target',
|
||||
}
|
||||
const newNodes = produce(nodes, (draft) => {
|
||||
const index = draft.findIndex(node => node.id === currentNodeId)
|
||||
|
||||
draft.splice(index, 1, newCurrentNode)
|
||||
})
|
||||
setNodes(newNodes)
|
||||
const newEdges = produce(edges, (draft) => {
|
||||
const filtered = draft.filter(edge => !connectedEdges.find(connectedEdge => connectedEdge.id === edge.id))
|
||||
filtered.push(newEdge)
|
||||
if (incomers.length === 1) {
|
||||
const parentNodeId = incomers[0].id
|
||||
|
||||
return filtered
|
||||
})
|
||||
setEdges(newEdges)
|
||||
const newEdge = {
|
||||
id: `${parentNodeId}-${newCurrentNode.id}`,
|
||||
type: 'custom',
|
||||
source: parentNodeId,
|
||||
sourceHandle: sourceHandle || 'source',
|
||||
target: newCurrentNode.id,
|
||||
targetHandle: 'target',
|
||||
}
|
||||
|
||||
const newEdges = produce(edges, (draft) => {
|
||||
const filtered = draft.filter(edge => !connectedEdges.find(connectedEdge => connectedEdge.id === edge.id))
|
||||
filtered.push(newEdge)
|
||||
|
||||
return filtered
|
||||
})
|
||||
setEdges(newEdges)
|
||||
}
|
||||
}, [store])
|
||||
|
||||
const handleDeleteNode = useCallback((nodeId: string) => {
|
||||
|
|
@ -303,6 +339,7 @@ export const useWorkflow = () => {
|
|||
handleSelectNode,
|
||||
handleEnterEdge,
|
||||
handleLeaveEdge,
|
||||
handleConnectNode,
|
||||
handleDeleteEdge,
|
||||
handleUpdateNodeData,
|
||||
handleAddNextNode,
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ const Workflow: FC<WorkflowProps> = memo(({
|
|||
const {
|
||||
handleEnterNode,
|
||||
handleLeaveNode,
|
||||
handleConnectNode,
|
||||
handleEnterEdge,
|
||||
handleLeaveEdge,
|
||||
handleDeleteEdge,
|
||||
|
|
@ -58,6 +59,7 @@ const Workflow: FC<WorkflowProps> = memo(({
|
|||
edgeTypes={edgeTypes}
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onConnect={handleConnectNode}
|
||||
onNodeMouseEnter={handleEnterNode}
|
||||
onNodeMouseLeave={handleLeaveNode}
|
||||
onEdgeMouseEnter={handleEnterEdge}
|
||||
|
|
|
|||
|
|
@ -33,9 +33,7 @@ const NextStep = ({
|
|||
{
|
||||
!branches && !!outgoers.length && (
|
||||
<Item
|
||||
parentNodeId={selectedNode!.id}
|
||||
nodeId={outgoers[0].id}
|
||||
sourceHandle='source'
|
||||
data={outgoers[0].data}
|
||||
/>
|
||||
)
|
||||
|
|
@ -63,7 +61,6 @@ const NextStep = ({
|
|||
connected && (
|
||||
<Item
|
||||
data={target!.data!}
|
||||
parentNodeId={selectedNode!.id}
|
||||
nodeId={target!.id}
|
||||
sourceHandle={branch.id}
|
||||
branchName={branch.name}
|
||||
|
|
|
|||
|
|
@ -12,14 +12,12 @@ import { useWorkflow } from '../../../../hooks'
|
|||
import Button from '@/app/components/base/button'
|
||||
|
||||
type ItemProps = {
|
||||
parentNodeId: string
|
||||
nodeId: string
|
||||
sourceHandle: string
|
||||
sourceHandle?: string
|
||||
branchName?: string
|
||||
data: CommonNodeType
|
||||
}
|
||||
const Item = ({
|
||||
parentNodeId,
|
||||
nodeId,
|
||||
sourceHandle,
|
||||
branchName,
|
||||
|
|
@ -27,8 +25,8 @@ const Item = ({
|
|||
}: ItemProps) => {
|
||||
const { handleChangeCurrentNode } = useWorkflow()
|
||||
const handleSelect = useCallback((type: BlockEnum) => {
|
||||
handleChangeCurrentNode(parentNodeId, nodeId, type, sourceHandle)
|
||||
}, [parentNodeId, nodeId, sourceHandle, handleChangeCurrentNode])
|
||||
handleChangeCurrentNode(nodeId, type, sourceHandle)
|
||||
}, [nodeId, sourceHandle, handleChangeCurrentNode])
|
||||
const renderTrigger = useCallback((open: boolean) => {
|
||||
return (
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
import {
|
||||
memo,
|
||||
useCallback,
|
||||
} from 'react'
|
||||
import BlockSelector from '../../../../block-selector'
|
||||
import { useWorkflow } from '../../../../hooks'
|
||||
import type { BlockEnum } from '../../../../types'
|
||||
|
||||
type ChangeBlockProps = {
|
||||
nodeId: string
|
||||
}
|
||||
const ChangeBlock = ({
|
||||
nodeId,
|
||||
}: ChangeBlockProps) => {
|
||||
const { handleChangeCurrentNode } = useWorkflow()
|
||||
|
||||
const handleSelect = useCallback((type: BlockEnum) => {
|
||||
handleChangeCurrentNode(nodeId, type)
|
||||
}, [handleChangeCurrentNode, nodeId])
|
||||
|
||||
const renderTrigger = useCallback(() => {
|
||||
return (
|
||||
<div className='flex items-center px-3 w-[232px] h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50'>
|
||||
Change Block
|
||||
</div>
|
||||
)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<BlockSelector
|
||||
placement='bottom-end'
|
||||
offset={{
|
||||
mainAxis: -36,
|
||||
crossAxis: 4,
|
||||
}}
|
||||
onSelect={handleSelect}
|
||||
trigger={renderTrigger}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(ChangeBlock)
|
||||
|
|
@ -2,7 +2,8 @@ import {
|
|||
memo,
|
||||
useState,
|
||||
} from 'react'
|
||||
import { useWorkflow } from '../../../hooks'
|
||||
import { useWorkflow } from '../../../../hooks'
|
||||
import ChangeBlock from './change-block'
|
||||
import { DotsHorizontal } from '@/app/components/base/icons/src/vender/line/general'
|
||||
import {
|
||||
PortalToFollowElem,
|
||||
|
|
@ -43,7 +44,7 @@ const PanelOperator = ({
|
|||
<PortalToFollowElemContent className='z-[11]'>
|
||||
<div className='w-[240px] border-[0.5px] border-gray-200 rounded-2xl shadow-xl bg-white'>
|
||||
<div className='p-1'>
|
||||
<div className='flex items-center px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50'>Change Block</div>
|
||||
<ChangeBlock nodeId={nodeId} />
|
||||
<div className='flex items-center px-3 h-8 text-sm text-gray-700 rounded-lg cursor-pointer hover:bg-gray-50'>Help Link</div>
|
||||
</div>
|
||||
<div className='h-[1px] bg-gray-100'></div>
|
||||
Loading…
Reference in New Issue