Commit 8b2a63e5 authored by StyleZhang's avatar StyleZhang

fix

parent ae9e7acd
...@@ -3,10 +3,51 @@ ...@@ -3,10 +3,51 @@
import { memo } from 'react' import { memo } from 'react'
import Workflow from '@/app/components/workflow' import Workflow from '@/app/components/workflow'
// export function createNodesAndEdges(xNodes = 10, yNodes = 10) {
// const nodes = []
// const edges = []
// let nodeId = 1
// let recentNodeId = null
// for (let y = 0; y < yNodes; y++) {
// for (let x = 0; x < xNodes; x++) {
// const position = { x: x * 200, y: y * 50 }
// const node = {
// id: `stress-${nodeId.toString()}`,
// type: 'custom',
// data: { type: 'start', title: '开始', variables: [] },
// position,
// }
// nodes.push(node)
// if (recentNodeId && nodeId <= xNodes * yNodes) {
// edges.push({
// id: `${x}-${y}`,
// type: 'custom',
// source: `stress-${recentNodeId.toString()}`,
// target: `stress-${nodeId.toString()}`,
// })
// }
// recentNodeId = nodeId
// nodeId++
// }
// }
// return { nodes, edges }
// }
const Page = () => { const Page = () => {
// const {
// nodes,
// edges,
// } = createNodesAndEdges()
return ( return (
<div className='w-full h-full overflow-x-auto'> <div className='w-full h-full overflow-x-auto'>
<Workflow /> <Workflow
// nodes={nodes}
// edges={edges}
/>
</div> </div>
) )
} }
......
...@@ -6,6 +6,7 @@ import type { ...@@ -6,6 +6,7 @@ import type {
} from 'reactflow' } from 'reactflow'
import { useStoreApi } from 'reactflow' import { useStoreApi } from 'reactflow'
import { useStore } from '../store' import { useStore } from '../store'
import type { Node } from '../types'
import { useNodesSyncDraft } from './use-nodes-sync-draft' import { useNodesSyncDraft } from './use-nodes-sync-draft'
export const useEdgesInteractions = () => { export const useEdgesInteractions = () => {
...@@ -55,14 +56,26 @@ export const useEdgesInteractions = () => { ...@@ -55,14 +56,26 @@ export const useEdgesInteractions = () => {
return return
const { const {
getNodes,
setNodes,
edges, edges,
setEdges, setEdges,
} = store.getState() } = store.getState()
const newEdges = produce(edges, (draft) => { const currentEdgeIndex = edges.findIndex(edge => edge.source === nodeId && edge.sourceHandle === branchId)
const index = draft.findIndex(edge => edge.source === nodeId && edge.sourceHandle === branchId) const currentEdge = edges[currentEdgeIndex]
const newNodes = produce(getNodes(), (draft: Node[]) => {
const sourceNode = draft.find(node => node.id === currentEdge.source)
const targetNode = draft.find(node => node.id === currentEdge.target)
if (sourceNode)
sourceNode.data._connectedSourceHandleIds = sourceNode.data._connectedSourceHandleIds?.filter(handleId => handleId !== currentEdge.sourceHandle)
if (index > -1) if (targetNode)
draft.splice(index, 1) targetNode.data._connectedTargetHandleIds = targetNode.data._connectedTargetHandleIds?.filter(handleId => handleId !== currentEdge.targetHandle)
})
setNodes(newNodes)
const newEdges = produce(edges, (draft) => {
draft.splice(currentEdgeIndex, 1)
}) })
setEdges(newEdges) setEdges(newEdges)
handleSyncWorkflowDraft() handleSyncWorkflowDraft()
...@@ -75,14 +88,26 @@ export const useEdgesInteractions = () => { ...@@ -75,14 +88,26 @@ export const useEdgesInteractions = () => {
return return
const { const {
getNodes,
setNodes,
edges, edges,
setEdges, setEdges,
} = store.getState() } = store.getState()
const newEdges = produce(edges, (draft) => { const currentEdgeIndex = edges.findIndex(edge => edge.selected)
const index = draft.findIndex(edge => edge.selected) const currentEdge = edges[currentEdgeIndex]
const newNodes = produce(getNodes(), (draft: Node[]) => {
const sourceNode = draft.find(node => node.id === currentEdge.source)
const targetNode = draft.find(node => node.id === currentEdge.target)
if (sourceNode)
sourceNode.data._connectedSourceHandleIds = sourceNode.data._connectedSourceHandleIds?.filter(handleId => handleId !== currentEdge.sourceHandle)
if (index > -1) if (targetNode)
draft.splice(index, 1) targetNode.data._connectedTargetHandleIds = targetNode.data._connectedTargetHandleIds?.filter(handleId => handleId !== currentEdge.targetHandle)
})
setNodes(newNodes)
const newEdges = produce(edges, (draft) => {
draft.splice(currentEdgeIndex, 1)
}) })
setEdges(newEdges) setEdges(newEdges)
handleSyncWorkflowDraft() handleSyncWorkflowDraft()
......
...@@ -260,9 +260,8 @@ export const useNodesInteractions = () => { ...@@ -260,9 +260,8 @@ export const useNodesInteractions = () => {
edges, edges,
setEdges, setEdges,
} = store.getState() } = store.getState()
const newEdges = produce(edges, (draft) => { const newEdges = produce(edges, (draft) => {
const filtered = draft.filter(edge => edge.source !== source && edge.target !== target) const filtered = draft.filter(edge => (edge.source !== source && edge.sourceHandle !== sourceHandle) || (edge.target !== target && edge.targetHandle !== targetHandle))
filtered.push({ filtered.push({
id: `${source}-${target}`, id: `${source}-${target}`,
...@@ -292,14 +291,25 @@ export const useNodesInteractions = () => { ...@@ -292,14 +291,25 @@ export const useNodesInteractions = () => {
setEdges, setEdges,
} = store.getState() } = store.getState()
const newNodes = produce(getNodes(), (draft) => { const nodes = getNodes()
const index = draft.findIndex(node => node.id === nodeId) const currentNodeIndex = nodes.findIndex(node => node.id === nodeId)
const currentNode = nodes[currentNodeIndex]
const incomersIds = getIncomers(currentNode, nodes, edges).map(incomer => incomer.id)
const outgoersIds = getOutgoers(currentNode, nodes, edges).map(outgoer => outgoer.id)
const connectedEdges = getConnectedEdges([{ id: nodeId } as Node], edges)
const sourceEdgesHandleIds = connectedEdges.filter(edge => edge.target === nodeId).map(edge => edge.sourceHandle)
const targetEdgesHandleIds = connectedEdges.filter(edge => edge.source === nodeId).map(edge => edge.targetHandle)
const newNodes = produce(nodes, (draft: Node[]) => {
draft.forEach((node) => {
if (incomersIds.includes(node.id))
node.data._connectedSourceHandleIds = node.data._connectedSourceHandleIds?.filter(handleId => !sourceEdgesHandleIds.includes(handleId))
if (index > -1) if (outgoersIds.includes(node.id))
draft.splice(index, 1) node.data._connectedTargetHandleIds = node.data._connectedTargetHandleIds?.filter(handleId => !targetEdgesHandleIds.includes(handleId))
})
draft.splice(currentNodeIndex, 1)
}) })
setNodes(newNodes) setNodes(newNodes)
const connectedEdges = getConnectedEdges([{ id: nodeId } as Node], edges)
const newEdges = produce(edges, (draft) => { const newEdges = produce(edges, (draft) => {
return draft.filter(edge => !connectedEdges.find(connectedEdge => connectedEdge.id === edge.id)) return draft.filter(edge => !connectedEdges.find(connectedEdge => connectedEdge.id === edge.id))
}) })
...@@ -325,7 +335,8 @@ export const useNodesInteractions = () => { ...@@ -325,7 +335,8 @@ export const useNodesInteractions = () => {
setEdges, setEdges,
} = store.getState() } = store.getState()
const nodes = getNodes() const nodes = getNodes()
const currentNode = nodes.find(node => node.id === currentNodeId)! const currentNodeIndex = nodes.findIndex(node => node.id === currentNodeId)
const currentNode = nodes[currentNodeIndex]
const outgoers = getOutgoers(currentNode, nodes, edges).sort((a, b) => a.position.y - b.position.y) const outgoers = getOutgoers(currentNode, nodes, edges).sort((a, b) => a.position.y - b.position.y)
const lastOutgoer = outgoers[outgoers.length - 1] const lastOutgoer = outgoers[outgoers.length - 1]
const nextNode: Node = { const nextNode: Node = {
...@@ -334,6 +345,7 @@ export const useNodesInteractions = () => { ...@@ -334,6 +345,7 @@ export const useNodesInteractions = () => {
data: { data: {
...nodesInitialData[nodeType], ...nodesInitialData[nodeType],
...(toolDefaultValue || {}), ...(toolDefaultValue || {}),
_connectedTargetHandleIds: ['target'],
selected: true, selected: true,
}, },
position: { position: {
...@@ -350,9 +362,12 @@ export const useNodesInteractions = () => { ...@@ -350,9 +362,12 @@ export const useNodesInteractions = () => {
target: nextNode.id, target: nextNode.id,
targetHandle: 'target', targetHandle: 'target',
} }
const newNodes = produce(nodes, (draft) => { const newNodes = produce(nodes, (draft: Node[]) => {
draft.forEach((node) => { draft.forEach((node, index) => {
node.data.selected = false node.data.selected = false
if (index === currentNodeIndex)
node.data._connectedSourceHandleIds?.push(sourceHandle)
}) })
draft.push(nextNode) draft.push(nextNode)
}) })
......
...@@ -182,7 +182,7 @@ const WorkflowWrap: FC<WorkflowProps> = ({ ...@@ -182,7 +182,7 @@ const WorkflowWrap: FC<WorkflowProps> = ({
return nodes return nodes
if (data) if (data)
return initialNodes(data.graph.nodes) return initialNodes(data.graph.nodes, data.graph.edges)
return [startNode] return [startNode]
}, [data, nodes, startNode]) }, [data, nodes, startNode])
......
import type { MouseEvent } from 'react' import type { MouseEvent } from 'react'
import { import {
memo,
useCallback, useCallback,
useEffect, useEffect,
useState, useState,
} from 'react' } from 'react'
import type { NodeProps } from 'reactflow'
import { import {
Handle, Handle,
Position, Position,
getConnectedEdges,
useEdges,
} from 'reactflow' } from 'reactflow'
import { BlockEnum } from '../../../types' import { BlockEnum } from '../../../types'
import type { Node } from '../../../types' import type { Node } from '../../../types'
...@@ -22,9 +20,9 @@ type NodeHandleProps = { ...@@ -22,9 +20,9 @@ type NodeHandleProps = {
handleId: string handleId: string
handleClassName?: string handleClassName?: string
nodeSelectorClassName?: string nodeSelectorClassName?: string
} & Pick<NodeProps, 'id' | 'data'> } & Pick<Node, 'id' | 'data'>
export const NodeTargetHandle = ({ export const NodeTargetHandle = memo(({
id, id,
data, data,
handleId, handleId,
...@@ -33,9 +31,7 @@ export const NodeTargetHandle = ({ ...@@ -33,9 +31,7 @@ export const NodeTargetHandle = ({
}: NodeHandleProps) => { }: NodeHandleProps) => {
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const { handleNodeAddPrev } = useNodesInteractions() const { handleNodeAddPrev } = useNodesInteractions()
const edges = useEdges() const connected = data._connectedTargetHandleIds?.includes(handleId)
const connectedEdges = getConnectedEdges([{ id } as Node], edges)
const connected = connectedEdges.find(edge => edge.targetHandle === handleId && edge.target === id)
const handleOpenChange = useCallback((v: boolean) => { const handleOpenChange = useCallback((v: boolean) => {
setOpen(v) setOpen(v)
...@@ -85,9 +81,10 @@ export const NodeTargetHandle = ({ ...@@ -85,9 +81,10 @@ export const NodeTargetHandle = ({
</Handle> </Handle>
</> </>
) )
} })
NodeTargetHandle.displayName = 'NodeTargetHandle'
export const NodeSourceHandle = ({ export const NodeSourceHandle = memo(({
id, id,
data, data,
handleId, handleId,
...@@ -97,9 +94,7 @@ export const NodeSourceHandle = ({ ...@@ -97,9 +94,7 @@ export const NodeSourceHandle = ({
const notInitialWorkflow = useStore(s => s.notInitialWorkflow) const notInitialWorkflow = useStore(s => s.notInitialWorkflow)
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const { handleNodeAddNext } = useNodesInteractions() const { handleNodeAddNext } = useNodesInteractions()
const edges = useEdges() const connected = data._connectedSourceHandleIds?.includes(handleId)
const connectedEdges = getConnectedEdges([{ id } as Node], edges)
const connected = connectedEdges.find(edge => edge.sourceHandle === handleId && edge.source === id)
const handleOpenChange = useCallback((v: boolean) => { const handleOpenChange = useCallback((v: boolean) => {
setOpen(v) setOpen(v)
}, []) }, [])
...@@ -150,4 +145,5 @@ export const NodeSourceHandle = ({ ...@@ -150,4 +145,5 @@ export const NodeSourceHandle = ({
</Handle> </Handle>
</> </>
) )
} })
NodeSourceHandle.displayName = 'NodeSourceHandle'
...@@ -47,6 +47,7 @@ const BaseNode: FC<BaseNodeProps> = ({ ...@@ -47,6 +47,7 @@ const BaseNode: FC<BaseNodeProps> = ({
${data._runningStatus === NodeRunningStatus.Running && '!border-primary-500'} ${data._runningStatus === NodeRunningStatus.Running && '!border-primary-500'}
${data._runningStatus === NodeRunningStatus.Succeeded && '!border-[#12B76A]'} ${data._runningStatus === NodeRunningStatus.Succeeded && '!border-[#12B76A]'}
${data._runningStatus === NodeRunningStatus.Failed && '!border-[#F04438]'} ${data._runningStatus === NodeRunningStatus.Failed && '!border-[#F04438]'}
${data._runningStatus === NodeRunningStatus.Waiting && 'opacity-70'}
`} `}
> >
{ {
......
...@@ -94,7 +94,10 @@ const ZoomInOut: FC = () => { ...@@ -94,7 +94,10 @@ const ZoomInOut: FC = () => {
placement='top-start' placement='top-start'
open={open} open={open}
onOpenChange={setOpen} onOpenChange={setOpen}
offset={4} offset={{
mainAxis: 4,
crossAxis: -2,
}}
> >
<PortalToFollowElemTrigger asChild onClick={handleTrigger}> <PortalToFollowElemTrigger asChild onClick={handleTrigger}>
<div className={` <div className={`
......
...@@ -25,6 +25,8 @@ export type Branch = { ...@@ -25,6 +25,8 @@ export type Branch = {
} }
export type CommonNodeType<T = {}> = { export type CommonNodeType<T = {}> = {
_connectedSourceHandleIds?: string[]
_connectedTargetHandleIds?: string[]
_targetBranches?: Branch[] _targetBranches?: Branch[]
_isSingleRun?: boolean _isSingleRun?: boolean
_runningStatus?: NodeRunningStatus _runningStatus?: NodeRunningStatus
......
...@@ -80,10 +80,14 @@ export const nodesLevelOrderTraverse = ( ...@@ -80,10 +80,14 @@ export const nodesLevelOrderTraverse = (
} }
} }
export const initialNodes = (nodes: Node[]) => { export const initialNodes = (nodes: Node[], edges: Edge[]) => {
return nodes.map((node) => { return nodes.map((node) => {
node.type = 'custom' node.type = 'custom'
const connectedEdges = getConnectedEdges([node], edges)
node.data._connectedSourceHandleIds = connectedEdges.filter(edge => edge.source === node.id).map(edge => edge.sourceHandle || 'source')
node.data._connectedTargetHandleIds = connectedEdges.filter(edge => edge.target === node.id).map(edge => edge.targetHandle || 'target')
if (node.data.type === BlockEnum.IfElse) { if (node.data.type === BlockEnum.IfElse) {
node.data._targetBranches = [ node.data._targetBranches = [
{ {
...@@ -170,3 +174,10 @@ export const canRunBySingle = (nodeType: BlockEnum) => { ...@@ -170,3 +174,10 @@ export const canRunBySingle = (nodeType: BlockEnum) => {
|| nodeType === BlockEnum.HttpRequest || nodeType === BlockEnum.HttpRequest
|| nodeType === BlockEnum.Tool || nodeType === BlockEnum.Tool
} }
type ConnectedSourceOrTargetNodesChange = {
type: 'add' | 'remove'
edge: Edge
}[]
export const getConnectedSourceOrTargetNodesChangeList = (changes: ConnectedSourceOrTargetNodesChange, nodes: Node[], edges: Edge[]) => {
}
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