From 4bda1bd88464127f83ec520a7cc3c464e3166832 Mon Sep 17 00:00:00 2001 From: hjlarry Date: Thu, 18 Sep 2025 17:42:02 +0800 Subject: [PATCH] open node panel not affect others --- .../core/collaboration-manager.ts | 9 ++-- .../hooks/use-collaborative-workflow.ts | 45 +++++++++++++++++-- .../workflow/hooks/use-nodes-interactions.ts | 8 ++-- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/web/app/components/workflow/collaboration/core/collaboration-manager.ts b/web/app/components/workflow/collaboration/core/collaboration-manager.ts index e3b06dabe1..004d595a1f 100644 --- a/web/app/components/workflow/collaboration/core/collaboration-manager.ts +++ b/web/app/components/workflow/collaboration/core/collaboration-manager.ts @@ -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)) }) diff --git a/web/app/components/workflow/hooks/use-collaborative-workflow.ts b/web/app/components/workflow/hooks/use-collaborative-workflow.ts index 39ad3ccf33..fe032d22bc 100644 --- a/web/app/components/workflow/hooks/use-collaborative-workflow.ts +++ b/web/app/components/workflow/hooks/use-collaborative-workflow.ts @@ -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).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)._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]) diff --git a/web/app/components/workflow/hooks/use-nodes-interactions.ts b/web/app/components/workflow/hooks/use-nodes-interactions.ts index fe43637937..6275de33f3 100644 --- a/web/app/components/workflow/hooks/use-nodes-interactions.ts +++ b/web/app/components/workflow/hooks/use-nodes-interactions.ts @@ -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( (_, node) => {