From 25ef68599ffaa5d07f6120bbf149b281a81d6741 Mon Sep 17 00:00:00 2001 From: Michael Charfadi Date: Fri, 1 Dec 2023 17:21:10 +0100 Subject: [PATCH] [2728] Prevents unnecessary rerenders in DiagramPanel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: https://github.com/eclipse-sirius/sirius-web/issues/2728 Signed-off-by: Michaƫl Charfadi --- CHANGELOG.adoc | 1 + .../src/renderer/panel/DiagramPanel.tsx | 23 +++++++++---------- .../renderer/snap-to-grid/useSnapToGrid.tsx | 4 +--- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 2860649432c..a46db059273 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -138,6 +138,7 @@ The only way to export diagram as SVG image is to use the ReactFlow toolbar loca - https://github.com/eclipse-sirius/sirius-web/issues/2687[#2687] [diagram] Fix an issue where ConnectionHandles where rerendering too much - https://github.com/eclipse-sirius/sirius-web/issues/2698[#2698] [diagram] Fix an issue that prevents _imageNode_ to be resizable. - https://github.com/eclipse-sirius/sirius-web/issues/2684[#2684] [diagram] Fix an issue where the edges' arrows where not exported during the SVG export. +- https://github.com/eclipse-sirius/sirius-web/issues/2728[#2728] [diagram] Prevents unnecessary rerenders in DiagramPanel === New Features diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/panel/DiagramPanel.tsx b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/panel/DiagramPanel.tsx index 5cac7540bfd..5bdd392ddd2 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/panel/DiagramPanel.tsx +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/panel/DiagramPanel.tsx @@ -24,8 +24,8 @@ import TonalityIcon from '@material-ui/icons/Tonality'; import VisibilityOffIcon from '@material-ui/icons/VisibilityOff'; import ZoomInIcon from '@material-ui/icons/ZoomIn'; import ZoomOutIcon from '@material-ui/icons/ZoomOut'; -import { useState } from 'react'; -import { Node, Panel, useNodes, useReactFlow } from 'reactflow'; +import { memo, useState } from 'react'; +import { Panel, useReactFlow } from 'reactflow'; import { EdgeData, NodeData } from '../DiagramRenderer.types'; import { ShareDiagramDialog } from '../ShareDiagramDialog'; import { useFadeDiagramElements } from '../fade/useFadeDiagramElements'; @@ -34,17 +34,20 @@ import { useHideDiagramElements } from '../hide/useHideDiagramElements'; import { DiagramPanelProps, DiagramPanelState } from './DiagramPanel.types'; import { useExportToImage } from './useExportToImage'; -export const DiagramPanel = ({ snapToGrid, onSnapToGrid }: DiagramPanelProps) => { +export const DiagramPanel = memo(({ snapToGrid, onSnapToGrid }: DiagramPanelProps) => { const [state, setState] = useState({ dialogOpen: null, }); - const nodes = useNodes(); + const reactFlow = useReactFlow(); + const { getEdges, getNodes } = reactFlow; + + const getAllElementsIds = () => [...getNodes().map((elem) => elem.id), ...getEdges().map((elem) => elem.id)]; + const getSelectedNodes = () => getNodes().filter((node) => node.selected); + const { fullscreen, onFullscreen } = useFullscreen(); - const reactFlow = useReactFlow(); - const selectedNodes: Node[] = nodes.filter((node) => node.selected); - const handleFitToScreen = () => reactFlow.fitView({ duration: 200, nodes: selectedNodes }); + const handleFitToScreen = () => reactFlow.fitView({ duration: 200, nodes: getSelectedNodes() }); const handleZoomIn = () => reactFlow.zoomIn({ duration: 200 }); const handleZoomOut = () => reactFlow.zoomOut({ duration: 200 }); const handleShare = () => setState((prevState) => ({ ...prevState, dialogOpen: 'Share' })); @@ -58,10 +61,6 @@ export const DiagramPanel = ({ snapToGrid, onSnapToGrid }: DiagramPanelProps) => const { exportToImage } = useExportToImage(); - const getAllElementsIds = () => { - return [...reactFlow.getNodes().map((elem) => elem.id), ...reactFlow.getEdges().map((elem) => elem.id)]; - }; - return ( <> @@ -125,4 +124,4 @@ export const DiagramPanel = ({ snapToGrid, onSnapToGrid }: DiagramPanelProps) => {state.dialogOpen === 'Share' ? : null} ); -}; +}); diff --git a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/snap-to-grid/useSnapToGrid.tsx b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/snap-to-grid/useSnapToGrid.tsx index c1332f953dd..ce7e1c7a03e 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/snap-to-grid/useSnapToGrid.tsx +++ b/packages/diagrams/frontend/sirius-components-diagrams-reactflow/src/renderer/snap-to-grid/useSnapToGrid.tsx @@ -17,10 +17,8 @@ import { UseSnapToGridValue } from './useSnapToGrid.types'; export const useSnapToGrid = (): UseSnapToGridValue => { const [state, setState] = useState(false); - const onSnapToGrid = (snapToGrid: boolean) => setState(snapToGrid); - return { snapToGrid: state, - onSnapToGrid, + onSnapToGrid: setState, }; };