Commit e8921787 authored by StyleZhang's avatar StyleZhang

hooks

parent d2d6904c
...@@ -3,9 +3,11 @@ import produce from 'immer' ...@@ -3,9 +3,11 @@ import produce from 'immer'
import type { import type {
EdgeMouseHandler, EdgeMouseHandler,
NodeMouseHandler, NodeMouseHandler,
OnConnect,
} from 'reactflow' } from 'reactflow'
import { import {
getConnectedEdges, getConnectedEdges,
getIncomers,
useStoreApi, useStoreApi,
} from 'reactflow' } from 'reactflow'
import type { import type {
...@@ -88,6 +90,33 @@ export const useWorkflow = () => { ...@@ -88,6 +90,33 @@ export const useWorkflow = () => {
setNodes(newNodes) setNodes(newNodes)
}, [store]) }, [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 handleEnterEdge = useCallback<EdgeMouseHandler>((_, edge) => {
const { const {
edges, edges,
...@@ -158,6 +187,7 @@ export const useWorkflow = () => { ...@@ -158,6 +187,7 @@ export const useWorkflow = () => {
x: currentNode.position.x + 304, x: currentNode.position.x + 304,
y: currentNode.position.y, y: currentNode.position.y,
}, },
selected: true,
} }
const newEdge = { const newEdge = {
id: `${currentNode.id}-${nextNode.id}`, id: `${currentNode.id}-${nextNode.id}`,
...@@ -169,7 +199,7 @@ export const useWorkflow = () => { ...@@ -169,7 +199,7 @@ export const useWorkflow = () => {
} }
const newNodes = produce(nodes, (draft) => { const newNodes = produce(nodes, (draft) => {
draft.forEach((node) => { draft.forEach((node) => {
node.data = { ...node.data, selected: false } node.selected = false
}) })
draft.push(nextNode) draft.push(nextNode)
}) })
...@@ -180,7 +210,7 @@ export const useWorkflow = () => { ...@@ -180,7 +210,7 @@ export const useWorkflow = () => {
setEdges(newEdges) setEdges(newEdges)
}, [store]) }, [store])
const handleChangeCurrentNode = useCallback((parentNodeId: string, currentNodeId: string, nodeType: BlockEnum, sourceHandle: string) => { const handleChangeCurrentNode = useCallback((currentNodeId: string, nodeType: BlockEnum, sourceHandle?: string) => {
const { const {
getNodes, getNodes,
setNodes, setNodes,
...@@ -189,6 +219,7 @@ export const useWorkflow = () => { ...@@ -189,6 +219,7 @@ export const useWorkflow = () => {
} = store.getState() } = store.getState()
const nodes = getNodes() const nodes = getNodes()
const currentNode = nodes.find(node => node.id === currentNodeId)! const currentNode = nodes.find(node => node.id === currentNodeId)!
const incomers = getIncomers(currentNode, nodes, edges)
const connectedEdges = getConnectedEdges([currentNode], edges) const connectedEdges = getConnectedEdges([currentNode], edges)
const newCurrentNode: Node = { const newCurrentNode: Node = {
id: `${Date.now()}`, id: `${Date.now()}`,
...@@ -199,27 +230,32 @@ export const useWorkflow = () => { ...@@ -199,27 +230,32 @@ export const useWorkflow = () => {
y: currentNode.position.y, 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 newNodes = produce(nodes, (draft) => {
const index = draft.findIndex(node => node.id === currentNodeId) const index = draft.findIndex(node => node.id === currentNodeId)
draft.splice(index, 1, newCurrentNode) draft.splice(index, 1, newCurrentNode)
}) })
setNodes(newNodes) setNodes(newNodes)
const newEdges = produce(edges, (draft) => { if (incomers.length === 1) {
const filtered = draft.filter(edge => !connectedEdges.find(connectedEdge => connectedEdge.id === edge.id)) const parentNodeId = incomers[0].id
filtered.push(newEdge)
return filtered const newEdge = {
}) id: `${parentNodeId}-${newCurrentNode.id}`,
setEdges(newEdges) 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]) }, [store])
const handleDeleteNode = useCallback((nodeId: string) => { const handleDeleteNode = useCallback((nodeId: string) => {
...@@ -303,6 +339,7 @@ export const useWorkflow = () => { ...@@ -303,6 +339,7 @@ export const useWorkflow = () => {
handleSelectNode, handleSelectNode,
handleEnterEdge, handleEnterEdge,
handleLeaveEdge, handleLeaveEdge,
handleConnectNode,
handleDeleteEdge, handleDeleteEdge,
handleUpdateNodeData, handleUpdateNodeData,
handleAddNextNode, handleAddNextNode,
......
...@@ -41,6 +41,7 @@ const Workflow: FC<WorkflowProps> = memo(({ ...@@ -41,6 +41,7 @@ const Workflow: FC<WorkflowProps> = memo(({
const { const {
handleEnterNode, handleEnterNode,
handleLeaveNode, handleLeaveNode,
handleConnectNode,
handleEnterEdge, handleEnterEdge,
handleLeaveEdge, handleLeaveEdge,
handleDeleteEdge, handleDeleteEdge,
...@@ -58,6 +59,7 @@ const Workflow: FC<WorkflowProps> = memo(({ ...@@ -58,6 +59,7 @@ const Workflow: FC<WorkflowProps> = memo(({
edgeTypes={edgeTypes} edgeTypes={edgeTypes}
nodes={nodes} nodes={nodes}
edges={edges} edges={edges}
onConnect={handleConnectNode}
onNodeMouseEnter={handleEnterNode} onNodeMouseEnter={handleEnterNode}
onNodeMouseLeave={handleLeaveNode} onNodeMouseLeave={handleLeaveNode}
onEdgeMouseEnter={handleEnterEdge} onEdgeMouseEnter={handleEnterEdge}
......
...@@ -33,9 +33,7 @@ const NextStep = ({ ...@@ -33,9 +33,7 @@ const NextStep = ({
{ {
!branches && !!outgoers.length && ( !branches && !!outgoers.length && (
<Item <Item
parentNodeId={selectedNode!.id}
nodeId={outgoers[0].id} nodeId={outgoers[0].id}
sourceHandle='source'
data={outgoers[0].data} data={outgoers[0].data}
/> />
) )
...@@ -63,7 +61,6 @@ const NextStep = ({ ...@@ -63,7 +61,6 @@ const NextStep = ({
connected && ( connected && (
<Item <Item
data={target!.data!} data={target!.data!}
parentNodeId={selectedNode!.id}
nodeId={target!.id} nodeId={target!.id}
sourceHandle={branch.id} sourceHandle={branch.id}
branchName={branch.name} branchName={branch.name}
......
...@@ -12,14 +12,12 @@ import { useWorkflow } from '../../../../hooks' ...@@ -12,14 +12,12 @@ import { useWorkflow } from '../../../../hooks'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
type ItemProps = { type ItemProps = {
parentNodeId: string
nodeId: string nodeId: string
sourceHandle: string sourceHandle?: string
branchName?: string branchName?: string
data: CommonNodeType data: CommonNodeType
} }
const Item = ({ const Item = ({
parentNodeId,
nodeId, nodeId,
sourceHandle, sourceHandle,
branchName, branchName,
...@@ -27,8 +25,8 @@ const Item = ({ ...@@ -27,8 +25,8 @@ const Item = ({
}: ItemProps) => { }: ItemProps) => {
const { handleChangeCurrentNode } = useWorkflow() const { handleChangeCurrentNode } = useWorkflow()
const handleSelect = useCallback((type: BlockEnum) => { const handleSelect = useCallback((type: BlockEnum) => {
handleChangeCurrentNode(parentNodeId, nodeId, type, sourceHandle) handleChangeCurrentNode(nodeId, type, sourceHandle)
}, [parentNodeId, nodeId, sourceHandle, handleChangeCurrentNode]) }, [nodeId, sourceHandle, handleChangeCurrentNode])
const renderTrigger = useCallback((open: boolean) => { const renderTrigger = useCallback((open: boolean) => {
return ( return (
<Button <Button
......
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 { ...@@ -2,7 +2,8 @@ import {
memo, memo,
useState, useState,
} from 'react' } 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 { DotsHorizontal } from '@/app/components/base/icons/src/vender/line/general'
import { import {
PortalToFollowElem, PortalToFollowElem,
...@@ -43,7 +44,7 @@ const PanelOperator = ({ ...@@ -43,7 +44,7 @@ const PanelOperator = ({
<PortalToFollowElemContent className='z-[11]'> <PortalToFollowElemContent className='z-[11]'>
<div className='w-[240px] border-[0.5px] border-gray-200 rounded-2xl shadow-xl bg-white'> <div className='w-[240px] border-[0.5px] border-gray-200 rounded-2xl shadow-xl bg-white'>
<div className='p-1'> <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 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>
<div className='h-[1px] bg-gray-100'></div> <div className='h-[1px] bg-gray-100'></div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment