From bc510838766fc25fa21cb588afac2b9dd324731e Mon Sep 17 00:00:00 2001 From: Michael Charfadi Date: Thu, 13 Feb 2025 16:41:49 +0100 Subject: [PATCH] [4571] Add debounce on synchronizeLayoutData MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug: https://github.com/eclipse-sirius/sirius-web/issues/4571 Signed-off-by: Florian ROUËNÉ --- CHANGELOG.adoc | 2 +- .../src/renderer/layout/useDebounce.ts | 29 +++++++++++++++++++ .../layout/useSynchronizeLayoutData.ts | 9 ++++-- 3 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 packages/diagrams/frontend/sirius-components-diagrams/src/renderer/layout/useDebounce.ts diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 3586aed6da..cf3f878db7 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -100,7 +100,7 @@ Now they are executed for some data if the data was coming from a studio too. - https://github.com/eclipse-sirius/sirius-web/issues/4522[#4522] [diagram] Fix an issue where custom tools were no longer contributed to the diagram palette - https://github.com/eclipse-sirius/sirius-web/issues/4549[#4549] [diagram] Fix an issue where edge tools could be shown in a palette tool section - https://github.com/eclipse-sirius/sirius-web/issues/4559[#4559] [diagram] Prevent list children positions to be set to (0,0) in certain random situations. - +- https://github.com/eclipse-sirius/sirius-web/issues/4571[#4571] [diagram] Prevent diagram crash when layoutData mutations are sent to quickly === New Features diff --git a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/layout/useDebounce.ts b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/layout/useDebounce.ts new file mode 100644 index 0000000000..0efd59e08a --- /dev/null +++ b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/layout/useDebounce.ts @@ -0,0 +1,29 @@ +/******************************************************************************* + * 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 { useRef, useCallback } from 'react'; + +export const useDebounce = (callback: (...args: any[]) => void, delay: number) => { + const timerRef = useRef | null>(null); + + return useCallback( + (...args: any[]) => { + if (timerRef.current) { + clearTimeout(timerRef.current); + } + timerRef.current = setTimeout(() => { + callback(...args); + }, delay); + }, + [callback, delay] + ); +}; diff --git a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/layout/useSynchronizeLayoutData.ts b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/layout/useSynchronizeLayoutData.ts index 30e38f0141..014c0b15bc 100644 --- a/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/layout/useSynchronizeLayoutData.ts +++ b/packages/diagrams/frontend/sirius-components-diagrams/src/renderer/layout/useSynchronizeLayoutData.ts @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2023, 2024 Obeo. + * Copyright (c) 2023, 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 @@ -17,6 +17,7 @@ import { useContext, useEffect } from 'react'; import { DiagramContext } from '../../contexts/DiagramContext'; import { DiagramContextValue } from '../../contexts/DiagramContext.types'; import { RawDiagram } from './layout.types'; +import { useDebounce } from './useDebounce'; import { GQLDiagramLayoutData, GQLErrorPayload, @@ -89,7 +90,7 @@ export const useSynchronizeLayoutData = (): UseSynchronizeLayoutDataValue => { position: { x, y }, } = node; const { resizedByUser } = node.data; - if (height && width) { + if (height && width && !isNaN(x) && !isNaN(y)) { nodeLayoutData.push({ id, position: { @@ -134,7 +135,9 @@ export const useSynchronizeLayoutData = (): UseSynchronizeLayoutDataValue => { layoutDiagram({ variables }); }; + const debouncedSynchronizeLayoutData = useDebounce(synchronizeLayoutData, 500); + return { - synchronizeLayoutData, + synchronizeLayoutData: debouncedSynchronizeLayoutData, }; };