From dc687db156b8b91c32ca772919bbf3c4d1eeb107 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mi=C5=82osz=20Grocholewski?= <m.grocholewski@atcomp.pl>
Date: Wed, 27 Nov 2024 16:12:51 +0100
Subject: [PATCH] feat(vector-map): avoid multiple loading overlays

---
 .../Drawer/OverlaysDrawer/hooks/useOverlay.ts | 17 +++++++++++++---
 .../reactionsLayer/useOlMapReactionsLayer.ts  |  3 +--
 .../overlayBioEntity.reducers.ts              | 20 ++++++++++++++++++-
 .../overlayBioEntity.selector.ts              |  5 +++++
 .../overlayBioEntity.slice.ts                 | 10 +++++++++-
 5 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/src/components/Map/Drawer/OverlaysDrawer/hooks/useOverlay.ts b/src/components/Map/Drawer/OverlaysDrawer/hooks/useOverlay.ts
index 6fde317a..084877fd 100644
--- a/src/components/Map/Drawer/OverlaysDrawer/hooks/useOverlay.ts
+++ b/src/components/Map/Drawer/OverlaysDrawer/hooks/useOverlay.ts
@@ -1,15 +1,19 @@
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import { useAppSelector } from '@/redux/hooks/useAppSelector';
 import {
+  areOverlayBioEntitiesLoadedSelector,
   isOverlayActiveSelector,
   isOverlayLoadingSelector,
 } from '@/redux/overlayBioEntity/overlayBioEntity.selector';
-import { removeOverlayBioEntityForGivenOverlay } from '@/redux/overlayBioEntity/overlayBioEntity.slice';
 import { getOverlayBioEntityForAllModels } from '@/redux/overlayBioEntity/overlayBioEntity.thunk';
 import { BASE_API_URL } from '@/constants';
 import { apiPath } from '@/redux/apiPath';
 import { PluginsEventBus } from '@/services/pluginsManager/pluginsEventBus';
 import { overlaySelector, userOverlaySelector } from '@/redux/overlays/overlays.selectors';
+import {
+  addOverlayToOverlaysId,
+  removeOverlayFromOverlaysId,
+} from '@/redux/overlayBioEntity/overlayBioEntity.slice';
 import { useEmptyBackground } from './useEmptyBackground';
 
 type UseOverlay = {
@@ -25,6 +29,9 @@ export const useOverlay = (overlayId: number): UseOverlay => {
   const isOverlayLoading = useAppSelector(state => isOverlayLoadingSelector(state, overlayId));
   const { setBackgroundtoEmptyIfAvailable } = useEmptyBackground();
   const overlay = useAppSelector(state => overlaySelector(state, overlayId));
+  const areOverlayBioEntitiesLoaded = useAppSelector(state =>
+    areOverlayBioEntitiesLoadedSelector(state, overlayId),
+  );
   const userOverlay = useAppSelector(state => userOverlaySelector(state, overlayId));
 
   const dispatchPluginEvents = (): void => {
@@ -41,9 +48,13 @@ export const useOverlay = (overlayId: number): UseOverlay => {
 
   const toggleOverlay = async (): Promise<void> => {
     if (isOverlayActive) {
-      dispatch(removeOverlayBioEntityForGivenOverlay({ overlayId }));
+      dispatch(removeOverlayFromOverlaysId(overlayId));
     } else {
-      await dispatch(getOverlayBioEntityForAllModels({ overlayId }));
+      if (areOverlayBioEntitiesLoaded) {
+        dispatch(addOverlayToOverlaysId(overlayId));
+      } else {
+        await dispatch(getOverlayBioEntityForAllModels({ overlayId }));
+      }
       setBackgroundtoEmptyIfAvailable();
     }
 
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts b/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
index 658e2a5d..af770b84 100644
--- a/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
@@ -59,8 +59,7 @@ export const useOlMapReactionsLayer = ({
   const currentMarkers = useAppSelector(markersSufraceOfCurrentMapDataSelector);
   const markersRender = parseSurfaceMarkersToBioEntityRender(currentMarkers);
   const bioEntities = useAppSelector(overlayBioEntitiesForCurrentModelSelector);
-  const debouncedBioEntities = useDebouncedValue(bioEntities, 2000);
-
+  const debouncedBioEntities = useDebouncedValue(bioEntities, 1000);
   const { getOverlayBioEntityColorByAvailableProperties } = useGetOverlayColor();
 
   const pointToProjection = usePointToProjection();
diff --git a/src/redux/overlayBioEntity/overlayBioEntity.reducers.ts b/src/redux/overlayBioEntity/overlayBioEntity.reducers.ts
index 797bacd7..ed2f81d3 100644
--- a/src/redux/overlayBioEntity/overlayBioEntity.reducers.ts
+++ b/src/redux/overlayBioEntity/overlayBioEntity.reducers.ts
@@ -1,4 +1,4 @@
-import { ActionReducerMapBuilder } from '@reduxjs/toolkit';
+import { ActionReducerMapBuilder, PayloadAction } from '@reduxjs/toolkit';
 import { getOverlayBioEntity, getOverlayBioEntityForAllModels } from './overlayBioEntity.thunk';
 import {
   OverlaysBioEntityState,
@@ -41,3 +41,21 @@ export const removeOverlayBioEntityForGivenOverlayReducer = (
   state.overlaysId = state.overlaysId.filter(id => id !== overlayId);
   delete state.data[overlayId];
 };
+
+export const removeOverlayFromOverlaysIdReducer = (
+  state: OverlaysBioEntityState,
+  action: PayloadAction<number>,
+): void => {
+  const overlayId = action.payload;
+  state.overlaysId = state.overlaysId.filter(id => id !== overlayId);
+};
+
+export const addOverlayToOverlaysIdReducer = (
+  state: OverlaysBioEntityState,
+  action: PayloadAction<number>,
+): void => {
+  const overlayId = action.payload;
+  if (!state.overlaysId.includes(overlayId)) {
+    state.overlaysId.push(overlayId);
+  }
+};
diff --git a/src/redux/overlayBioEntity/overlayBioEntity.selector.ts b/src/redux/overlayBioEntity/overlayBioEntity.selector.ts
index b1276a7c..94616fd8 100644
--- a/src/redux/overlayBioEntity/overlayBioEntity.selector.ts
+++ b/src/redux/overlayBioEntity/overlayBioEntity.selector.ts
@@ -86,6 +86,11 @@ export const isOverlayActiveSelector = createSelector(
   (overlaysId, overlayId) => overlaysId.includes(overlayId),
 );
 
+export const areOverlayBioEntitiesLoadedSelector = createSelector(
+  [overlayBioEntityDataSelector, (_, overlayId: number): number => overlayId],
+  (bioEntities, overlayId) => Boolean(bioEntities[overlayId]),
+);
+
 export const isOverlayLoadingSelector = createSelector(
   [overlayBioEntitySelector, mapModelIdSelector, (_, overlayId: number): number => overlayId],
   ({ overlaysId, data }, mapId, overlayId) => {
diff --git a/src/redux/overlayBioEntity/overlayBioEntity.slice.ts b/src/redux/overlayBioEntity/overlayBioEntity.slice.ts
index ae21322c..89b0bcd1 100644
--- a/src/redux/overlayBioEntity/overlayBioEntity.slice.ts
+++ b/src/redux/overlayBioEntity/overlayBioEntity.slice.ts
@@ -1,8 +1,10 @@
 import { createSlice } from '@reduxjs/toolkit';
 import {
+  addOverlayToOverlaysIdReducer,
   getOverlayBioEntityForAllModelsReducer,
   getOverlayBioEntityReducer,
   removeOverlayBioEntityForGivenOverlayReducer,
+  removeOverlayFromOverlaysIdReducer,
 } from './overlayBioEntity.reducers';
 import { OverlaysBioEntityState } from './overlayBioEntity.types';
 
@@ -16,6 +18,8 @@ export const overlayBioEntitySlice = createSlice({
   initialState,
   reducers: {
     removeOverlayBioEntityForGivenOverlay: removeOverlayBioEntityForGivenOverlayReducer,
+    removeOverlayFromOverlaysId: removeOverlayFromOverlaysIdReducer,
+    addOverlayToOverlaysId: addOverlayToOverlaysIdReducer,
   },
   extraReducers: builder => {
     getOverlayBioEntityReducer(builder);
@@ -23,5 +27,9 @@ export const overlayBioEntitySlice = createSlice({
   },
 });
 
-export const { removeOverlayBioEntityForGivenOverlay } = overlayBioEntitySlice.actions;
+export const {
+  removeOverlayBioEntityForGivenOverlay,
+  removeOverlayFromOverlaysId,
+  addOverlayToOverlaysId,
+} = overlayBioEntitySlice.actions;
 export default overlayBioEntitySlice.reducer;
-- 
GitLab