-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[4376] Work around selection not being set at initial diagram rendering
There was an issue where when resolving a URL with a selection and an open diagram, the selection was not being applied graphically in the diagram because at the time the selection is applied, the diagram exists but has no nodes or edges. This is a workaround to make sure the selection gets applied during the first render *after* the nodes and edges have been created. Bug: #4376 Signed-off-by: Florent Latombe <[email protected]>
- Loading branch information
Showing
3 changed files
with
86 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
.../sirius-components-diagrams/src/renderer/selection/useApplyWorkbenchSelectionToDiagram.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2025 Obeo. | ||
* This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v2.0 | ||
* which accompanies this distribution, and is available at | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Obeo - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
import { Selection } from '@eclipse-sirius/sirius-components-core'; | ||
import { Edge, FitView, Node } from '@xyflow/react'; | ||
import { Dispatch, SetStateAction } from 'react'; | ||
import { EdgeData, NodeData } from '../DiagramRenderer.types'; | ||
|
||
export const useApplyWorkbenchSelectionToDiagram = ( | ||
selection: Selection, | ||
getNodes: () => Node<NodeData>[], | ||
setNodes: Dispatch<SetStateAction<Node<NodeData>[]>>, | ||
getEdges: () => Edge<EdgeData>[], | ||
setEdges: Dispatch<SetStateAction<Edge<EdgeData>[]>>, | ||
fitView: FitView | ||
) => { | ||
const allDiagramElements = [...getNodes(), ...getEdges()]; | ||
const displayedSemanticElements: Set<string> = new Set([ | ||
...getNodes().map((node) => node.data.targetObjectId), | ||
...getEdges().map((edge) => edge.data?.targetObjectId ?? ''), | ||
]); | ||
const displayedSemanticElementsToSelect = selection.entries | ||
.map((entry) => entry.id) | ||
.filter((id) => displayedSemanticElements.has(id)) | ||
.sort((id1: string, id2: string) => id1.localeCompare(id2)); | ||
|
||
const semanticElementsAlreadySelectedOnDiagram = allDiagramElements | ||
.filter((element) => element.selected) | ||
.map((element) => element.data?.targetObjectId ?? '') | ||
.sort((id1: string, id2: string) => id1.localeCompare(id2)); | ||
|
||
if (JSON.stringify(displayedSemanticElementsToSelect) !== JSON.stringify(semanticElementsAlreadySelectedOnDiagram)) { | ||
const nodesToReveal: Set<string> = new Set(); | ||
const newNodes = getNodes().map((node) => { | ||
const selected = displayedSemanticElementsToSelect.includes(node.data.targetObjectId); | ||
const newNode = { ...node, selected }; | ||
if (selected) { | ||
nodesToReveal.add(newNode.id); | ||
} | ||
return newNode; | ||
}); | ||
const newEdges = getEdges().map((edge) => { | ||
const selected = displayedSemanticElementsToSelect.includes(edge.data ? edge.data.targetObjectId : ''); | ||
const newEdge = { ...edge, selected }; | ||
if (selected) { | ||
// React Flow does not support "fit on edge", so include its source & target nodes | ||
// to ensure the edge is visible and in context | ||
nodesToReveal.add(newEdge.source); | ||
nodesToReveal.add(newEdge.target); | ||
} | ||
return newEdge; | ||
}); | ||
|
||
setEdges(newEdges); | ||
setNodes(newNodes); | ||
|
||
fitView({ nodes: getNodes().filter((node) => nodesToReveal.has(node.id)), maxZoom: 1.5, duration: 1000 }); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters