From 5d7aab138a7dd5f52221c5805a1a877965fc4168 Mon Sep 17 00:00:00 2001 From: hatim dinia Date: Thu, 8 Feb 2024 15:18:10 +0100 Subject: [PATCH] fix(ui-map): reload map data on study revisit --- webapp/src/redux/ducks/studies.ts | 5 +++ webapp/src/redux/hooks/useStudyMaps.ts | 60 ++++++++++++++++---------- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/webapp/src/redux/ducks/studies.ts b/webapp/src/redux/ducks/studies.ts index 5abb3cfd6d..4a7de30134 100644 --- a/webapp/src/redux/ducks/studies.ts +++ b/webapp/src/redux/ducks/studies.ts @@ -47,6 +47,7 @@ export interface StudiesSortConf { export interface StudiesState extends AsyncEntityState { current: string; + prevStudyId: string; scrollPosition: number; versionList: string[]; favorites: Array; @@ -73,6 +74,7 @@ const initialState = studiesAdapter.getInitialState({ status: FetchStatus.Idle, error: null as string | null, current: "", + prevStudyId: "", scrollPosition: 0, versionList: [] as string[], favorites: [], @@ -100,6 +102,8 @@ const n = makeActionName("study"); // Action Creators //////////////////////////////////////////////////////////////// +export const setPrevStudyId = createAction(n("SET_PREV_STUDY_ID")); + export const setCurrentStudy = createThunk< NonNullable, NonNullable @@ -297,6 +301,7 @@ export default createReducer(initialState, (builder) => { draftState.versionList = action.payload; }) .addCase(setCurrentStudy, (draftState, action) => { + draftState.prevStudyId = draftState.current; draftState.current = action.payload; }) .addCase(setStudyScrollPosition, (draftState, action) => { diff --git a/webapp/src/redux/hooks/useStudyMaps.ts b/webapp/src/redux/hooks/useStudyMaps.ts index 49652627ad..09dd2315f9 100644 --- a/webapp/src/redux/hooks/useStudyMaps.ts +++ b/webapp/src/redux/hooks/useStudyMaps.ts @@ -12,50 +12,64 @@ import { import useStudySynthesis from "./useStudySynthesis"; import { Response } from "../../components/common/utils/UsePromiseCond"; import usePromise, { PromiseStatus } from "../../hooks/usePromise"; +import { setPrevStudyId } from "../ducks/studies"; interface Props { studyId: StudyMetadata["id"]; - selector?: (state: AppState, studyId: StudyMetadata["id"]) => T; + selector: (state: AppState, studyId: StudyMetadata["id"]) => T; } -export default function useStudyMaps(props: Props): Response { - const { studyId, selector } = props; - const synthesisRes = useStudySynthesis({ studyId }); - const isMapsExist = useAppSelector((state) => !!getStudyMap(state, studyId)); - const data = useAppSelector((state) => - isMapsExist && selector ? selector(state, studyId) : undefined, - ); - const dispatch = useAppDispatch(); +export default function useStudyMaps({ + studyId, + selector, +}: Props): Response { const [status, setStatus] = useState(PromiseStatus.Idle); const [error, setError] = useState(); + const dispatch = useAppDispatch(); + const synthesis = useStudySynthesis({ studyId }); + const isMapsExists = useAppSelector((state) => !!getStudyMap(state, studyId)); + const data = useAppSelector((state) => selector(state, studyId) || undefined); + const prevStudyId = useAppSelector((state) => state.studies.prevStudyId); usePromise(async () => { - if (synthesisRes.status === PromiseStatus.Rejected) { - setError(synthesisRes.error); + if (synthesis.status === PromiseStatus.Rejected) { + setError(synthesis.error); setStatus(PromiseStatus.Rejected); return; } - if (synthesisRes.status !== PromiseStatus.Resolved) { + if (synthesis.status !== PromiseStatus.Resolved) { setStatus(PromiseStatus.Pending); return; } - if (!isMapsExist) { - setStatus(PromiseStatus.Pending); + setStatus(PromiseStatus.Pending); - try { - await dispatch(fetchStudyMapLayers(studyId)).unwrap(); - await dispatch(fetchStudyMapDistricts(studyId)).unwrap(); - await dispatch(createStudyMap(studyId)).unwrap(); - } catch (e) { - setError(e as Error); - setStatus(PromiseStatus.Rejected); + try { + /* + * Conditionally fetch study map data to address two scenarios: + * 1. The map data does not exist for the current study (isMapsExist is false). + * 2. The user has navigated to a different study than previously viewed (prevStudyId !== studyId). + * + * Particularly critical for accuracy when users return to a previously viewed study. + */ + if (!isMapsExists || prevStudyId !== studyId) { + await Promise.all([ + dispatch(fetchStudyMapLayers(studyId)).unwrap(), + dispatch(fetchStudyMapDistricts(studyId)).unwrap(), + dispatch(createStudyMap(studyId)).unwrap(), + ]); + + // Updates the previous study ID to track navigation between studies. + dispatch(setPrevStudyId(studyId)); } - } else { + setStatus(PromiseStatus.Resolved); + } catch (err) { + setError(err as Error); + setStatus(PromiseStatus.Rejected); } - }, [isMapsExist, studyId, synthesisRes.status]); + }, [isMapsExists, studyId, synthesis.status]); return { data, status, error }; }