open node panel not affect others

This commit is contained in:
hjlarry 2025-09-18 17:42:02 +08:00
parent 3abe7850d6
commit 4bda1bd884
3 changed files with 50 additions and 12 deletions

View File

@ -430,6 +430,7 @@ export class CollaborationManager {
const oldNodesMap = new Map(oldNodes.map(node => [node.id, node]))
const newNodesMap = new Map(newNodes.map(node => [node.id, node]))
const shouldSyncDataKey = (key: string) => !key.startsWith('_') && key !== 'selected'
// Delete removed nodes
oldNodes.forEach((oldNode) => {
@ -456,7 +457,7 @@ export class CollaborationManager {
// Clone data properties, excluding private ones
Object.entries(newNode.data).forEach(([key, value]) => {
if (!key.startsWith('_') && value !== undefined)
if (shouldSyncDataKey(key) && value !== undefined)
nodeData.data[key] = JSON.parse(JSON.stringify(value))
})
@ -491,7 +492,7 @@ export class CollaborationManager {
// Only update changed properties in data
Object.entries(newData).forEach(([key, value]) => {
if (!key.startsWith('_')) {
if (shouldSyncDataKey(key)) {
const oldValue = (oldData as any)[key]
if (!isEqual(oldValue, value))
updatedNode.data[key] = JSON.parse(JSON.stringify(value))
@ -500,7 +501,7 @@ export class CollaborationManager {
// Remove deleted properties from data
Object.keys(oldData).forEach((key) => {
if (!key.startsWith('_') && !(key in newData))
if (shouldSyncDataKey(key) && !(key in newData))
delete updatedNode.data[key]
})
@ -522,7 +523,7 @@ export class CollaborationManager {
}
Object.entries(newNode.data).forEach(([key, value]) => {
if (!key.startsWith('_') && value !== undefined)
if (shouldSyncDataKey(key) && value !== undefined)
nodeData.data[key] = JSON.parse(JSON.stringify(value))
})

View File

@ -3,6 +3,38 @@ import { useStoreApi } from 'reactflow'
import type { Edge, Node } from '../types'
import { collaborationManager } from '../collaboration/core/collaboration-manager'
const sanitizeNodeForBroadcast = (node: Node): Node => {
if (!node.data)
return node
if (!Object.prototype.hasOwnProperty.call(node.data, 'selected'))
return node
const sanitizedData = { ...node.data }
delete (sanitizedData as Record<string, unknown>).selected
return {
...node,
data: sanitizedData,
}
}
const sanitizeEdgeForBroadcast = (edge: Edge): Edge => {
if (!edge.data)
return edge
if (!Object.prototype.hasOwnProperty.call(edge.data, '_connectedNodeIsSelected'))
return edge
const sanitizedData = { ...edge.data }
delete (sanitizedData as Record<string, unknown>)._connectedNodeIsSelected
return {
...edge,
data: sanitizedData,
}
}
export const useCollaborativeWorkflow = () => {
const store = useStoreApi()
const { setNodes: collabSetNodes, setEdges: collabSetEdges } = collaborationManager
@ -11,15 +43,22 @@ export const useCollaborativeWorkflow = () => {
const { getNodes, setNodes: reactFlowSetNodes } = store.getState()
if (shouldBroadcast) {
const oldNodes = getNodes()
collabSetNodes(oldNodes, newNodes)
collabSetNodes(
oldNodes.map(sanitizeNodeForBroadcast),
newNodes.map(sanitizeNodeForBroadcast),
)
}
reactFlowSetNodes(newNodes)
}, [store, collabSetNodes])
const setEdges = useCallback((newEdges: Edge[], shouldBroadcast: boolean = true) => {
const { edges, setEdges: reactFlowSetEdges } = store.getState()
if (shouldBroadcast)
collabSetEdges(edges, newEdges)
if (shouldBroadcast) {
collabSetEdges(
edges.map(sanitizeEdgeForBroadcast),
newEdges.map(sanitizeEdgeForBroadcast),
)
}
reactFlowSetEdges(newEdges)
}, [store, collabSetEdges])

View File

@ -312,7 +312,7 @@ export const useNodesInteractions = () => {
else node.data.selected = false
})
})
setNodes(newNodes)
setNodes(newNodes, false)
const connectedEdges = getConnectedEdges(
[{ id: nodeId } as Node],
@ -334,10 +334,8 @@ export const useNodesInteractions = () => {
}
})
})
setEdges(newEdges)
handleSyncWorkflowDraft()
}, [collaborativeWorkflow, handleSyncWorkflowDraft])
setEdges(newEdges, false)
}, [collaborativeWorkflow])
const handleNodeClick = useCallback<NodeMouseHandler>(
(_, node) => {