From 63e4fec72924851d1eae5b93341940eb577d3c64 Mon Sep 17 00:00:00 2001 From: 9sneha-n <9sneha.n@gmail.com> Date: Wed, 17 Apr 2024 11:45:00 +0530 Subject: [PATCH 1/4] feat: non-admin workflow for Prevalence --- src/domain/usecases/GetAllSurveysUseCase.ts | 3 +- src/domain/utils/menuHelper.ts | 11 +++- src/webapp/hooks/useSurveys.ts | 28 +++++++- .../pages/survey-list/SurveyListPage.tsx | 45 ++----------- .../pages/survey-list/useRedirectHome.ts | 65 +++++++++++++++++++ 5 files changed, 108 insertions(+), 44 deletions(-) create mode 100644 src/webapp/pages/survey-list/useRedirectHome.ts diff --git a/src/domain/usecases/GetAllSurveysUseCase.ts b/src/domain/usecases/GetAllSurveysUseCase.ts index 09148b5f..727dce97 100644 --- a/src/domain/usecases/GetAllSurveysUseCase.ts +++ b/src/domain/usecases/GetAllSurveysUseCase.ts @@ -26,7 +26,8 @@ export class GetAllSurveysUseCase { const filteredSurveys = surveyFormType === "PPSSurveyForm" || (surveyFormType === "PPSHospitalForm" && !parentSurveyId) || - surveyFormType === "PrevalenceSurveyForm" + surveyFormType === "PrevalenceSurveyForm" || + (surveyFormType === "PrevalenceFacilityLevelForm" && !parentSurveyId) ? surveys : _( surveys.map(survey => { diff --git a/src/domain/utils/menuHelper.ts b/src/domain/utils/menuHelper.ts index b470f507..4777ac5f 100644 --- a/src/domain/utils/menuHelper.ts +++ b/src/domain/utils/menuHelper.ts @@ -38,7 +38,16 @@ export const getBaseSurveyFormType = ( ); } case "Prevalence": { - return "PrevalenceSurveyForm"; + const { hasReadAccess, hasCaptureAccess, hasAdminAccess } = getUserAccess( + module, + currentUserGroups + ); + if (hasAdminAccess) return "PrevalenceSurveyForm"; + else if (hasReadAccess || hasCaptureAccess) return "PrevalenceFacilityLevelForm"; + else + throw new Error( + "You dont have the neccessary permissions. Please contact your system administrator." + ); } default: throw new Error("Unknown Module type"); diff --git a/src/webapp/hooks/useSurveys.ts b/src/webapp/hooks/useSurveys.ts index e236ce48..efdbffbc 100644 --- a/src/webapp/hooks/useSurveys.ts +++ b/src/webapp/hooks/useSurveys.ts @@ -3,6 +3,9 @@ import { Survey, SURVEY_FORM_TYPES } from "../../domain/entities/Survey"; import { useAppContext } from "../contexts/app-context"; import { useCurrentSurveys } from "../contexts/current-surveys-context"; import { isPaginatedSurveyList } from "../../domain/utils/PPSProgramsHelper"; +import { getUserAccess } from "../../domain/utils/menuHelper"; +import { useCurrentModule } from "../contexts/current-module-context"; +import { useHospitalContext } from "../contexts/hospital-context"; const PAGE_SIZE = 10; export function useSurveys(surveyFormType: SURVEY_FORM_TYPES) { @@ -23,7 +26,25 @@ export function useSurveys(surveyFormType: SURVEY_FORM_TYPES) { currentFacilityLevelForm, } = useCurrentSurveys(); + const { currentModule } = useCurrentModule(); + + const { + currentUser: { userGroups }, + } = useAppContext(); + + const { userHospitalsAccess } = useHospitalContext(); + const getOrgUnitByFormType = useCallback(() => { + //TO DO : make chunked calls as user may have large number of hospitals. + //TO DO : do not make call for PrevalenceFacilityLevelForm until userHospitalsAccess data is loaded. + const currentUserHospitals = userHospitalsAccess + .filter(hospitals => hospitals.readAccess === true) + .map(hospital => hospital.orgUnitId) + .join(";"); + const hasAdminAccess = currentModule + ? getUserAccess(currentModule, userGroups).hasAdminAccess + : false; + switch (surveyFormType) { case "PPSHospitalForm": return currentCountryQuestionnaire?.orgUnitId ?? ""; @@ -32,7 +53,9 @@ export function useSurveys(surveyFormType: SURVEY_FORM_TYPES) { return currentHospitalForm?.orgUnitId ?? ""; case "PrevalenceFacilityLevelForm": - return currentPrevalenceSurveyForm?.orgUnitId ?? ""; + return hasAdminAccess + ? currentPrevalenceSurveyForm?.orgUnitId ?? "" + : currentUserHospitals; case "PrevalenceCaseReportForm": case "PrevalenceCentralRefLabForm": case "PrevalencePathogenIsolatesLog": @@ -46,8 +69,11 @@ export function useSurveys(surveyFormType: SURVEY_FORM_TYPES) { currentCountryQuestionnaire?.orgUnitId, currentFacilityLevelForm?.orgUnitId, currentHospitalForm?.orgUnitId, + currentModule, currentPrevalenceSurveyForm?.orgUnitId, surveyFormType, + userGroups, + userHospitalsAccess, ]); useEffect(() => { diff --git a/src/webapp/pages/survey-list/SurveyListPage.tsx b/src/webapp/pages/survey-list/SurveyListPage.tsx index 4c2c1b01..a7a6413a 100644 --- a/src/webapp/pages/survey-list/SurveyListPage.tsx +++ b/src/webapp/pages/survey-list/SurveyListPage.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from "react"; +import React, { useEffect } from "react"; import { useHistory, useParams } from "react-router-dom"; import styled from "styled-components"; import { SURVEY_FORM_TYPES } from "../../../domain/entities/Survey"; @@ -6,53 +6,16 @@ import { SurveyList } from "../../components/survey-list/SurveyList"; import { useCurrentSurveys } from "../../contexts/current-surveys-context"; import { SurveyListBreadCrumb } from "../../components/survey-list/SurveyListBreadCrumb"; import { useCurrentModule } from "../../contexts/current-module-context"; +import { useRedirectHome } from "./useRedirectHome"; export const SurveyListPage: React.FC = React.memo(() => { const { formType } = useParams<{ formType: SURVEY_FORM_TYPES }>(); - const { - currentPPSSurveyForm, - currentPrevalenceSurveyForm, - currentCountryQuestionnaire, - currentHospitalForm, - currentWardRegister, - currentFacilityLevelForm, - currentCaseReportForm, - resetCurrentPPSSurveyForm, - resetCurrentPrevalenceSurveyForm, - } = useCurrentSurveys(); + const { resetCurrentPPSSurveyForm, resetCurrentPrevalenceSurveyForm } = useCurrentSurveys(); const { currentModule } = useCurrentModule(); + const { shouldRedirectToHome } = useRedirectHome(); const history = useHistory(); - const shouldRedirectToHome = useCallback( - (formType: SURVEY_FORM_TYPES): boolean => { - if ( - (formType === "PPSCountryQuestionnaire" && !currentPPSSurveyForm) || - (formType === "PPSHospitalForm" && !currentCountryQuestionnaire) || - (formType === "PPSWardRegister" && !currentHospitalForm) || - (formType === "PPSPatientRegister" && !currentWardRegister) || - (formType === "PrevalenceFacilityLevelForm" && !currentPrevalenceSurveyForm) || - (formType === "PrevalenceCaseReportForm" && !currentFacilityLevelForm) || - ((formType === "PrevalenceCentralRefLabForm" || - formType === "PrevalencePathogenIsolatesLog" || - formType === "PrevalenceSampleShipTrackForm" || - formType === "PrevalenceSupranationalRefLabForm") && - !currentCaseReportForm) - ) - return true; - else return false; - }, - [ - currentPPSSurveyForm, - currentPrevalenceSurveyForm, - currentCountryQuestionnaire, - currentHospitalForm, - currentWardRegister, - currentFacilityLevelForm, - currentCaseReportForm, - ] - ); - //reset all current survey context when root form of either module is listed. useEffect(() => { if (formType === "PPSSurveyForm" || formType === "PrevalenceSurveyForm") { diff --git a/src/webapp/pages/survey-list/useRedirectHome.ts b/src/webapp/pages/survey-list/useRedirectHome.ts new file mode 100644 index 00000000..5bba2750 --- /dev/null +++ b/src/webapp/pages/survey-list/useRedirectHome.ts @@ -0,0 +1,65 @@ +import { useCallback } from "react"; +import { SURVEY_FORM_TYPES } from "../../../domain/entities/Survey"; +import { useCurrentSurveys } from "../../contexts/current-surveys-context"; +import { getUserAccess } from "../../../domain/utils/menuHelper"; +import { useCurrentModule } from "../../contexts/current-module-context"; +import { useAppContext } from "../../contexts/app-context"; + +export function useRedirectHome() { + const { + currentPPSSurveyForm, + currentPrevalenceSurveyForm, + currentCountryQuestionnaire, + currentHospitalForm, + currentWardRegister, + currentFacilityLevelForm, + currentCaseReportForm, + } = useCurrentSurveys(); + + const { currentModule } = useCurrentModule(); + + const { + currentUser: { userGroups }, + } = useAppContext(); + + const shouldRedirectToHome = useCallback( + (formType: SURVEY_FORM_TYPES): boolean => { + const hasAdminAccess = currentModule + ? getUserAccess(currentModule, userGroups).hasAdminAccess + : false; + + if ( + (formType === "PPSCountryQuestionnaire" && !currentPPSSurveyForm) || + (hasAdminAccess && + formType === "PPSHospitalForm" && + !currentCountryQuestionnaire) || + (formType === "PPSWardRegister" && !currentHospitalForm) || + (formType === "PPSPatientRegister" && !currentWardRegister) || + (hasAdminAccess && + formType === "PrevalenceFacilityLevelForm" && + !currentPrevalenceSurveyForm) || + (formType === "PrevalenceCaseReportForm" && !currentFacilityLevelForm) || + ((formType === "PrevalenceCentralRefLabForm" || + formType === "PrevalencePathogenIsolatesLog" || + formType === "PrevalenceSampleShipTrackForm" || + formType === "PrevalenceSupranationalRefLabForm") && + !currentCaseReportForm) + ) + return true; + else return false; + }, + [ + currentModule, + userGroups, + currentPPSSurveyForm, + currentCountryQuestionnaire, + currentHospitalForm, + currentWardRegister, + currentPrevalenceSurveyForm, + currentFacilityLevelForm, + currentCaseReportForm, + ] + ); + + return { shouldRedirectToHome }; +} From cacc4031bc2cf6ed156efa09c70a2d02afb64c0b Mon Sep 17 00:00:00 2001 From: 9sneha-n <9sneha.n@gmail.com> Date: Wed, 17 Apr 2024 11:45:34 +0530 Subject: [PATCH 2/4] chore: translation update --- i18n/es.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/i18n/es.po b/i18n/es.po index 9b230835..4b065356 100644 --- a/i18n/es.po +++ b/i18n/es.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2024-01-15T12:42:39.990Z\n" +"POT-Creation-Date: 2024-04-01T18:30:50.736Z\n" "PO-Revision-Date: 2018-10-25T09:02:35.143Z\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -17,6 +17,9 @@ msgstr "" msgid "Log Out" msgstr "" +msgid "Stage - Profile" +msgstr "" + msgid "Cancel" msgstr "" @@ -41,9 +44,6 @@ msgstr "" msgid "Patients" msgstr "" -msgid "Add new" -msgstr "" - msgid "Submission Success!" msgstr "" From 973b0bb1e4cc5c9eefd261aafdc49e854fd82610 Mon Sep 17 00:00:00 2001 From: 9sneha-n <9sneha.n@gmail.com> Date: Wed, 17 Apr 2024 13:05:28 +0530 Subject: [PATCH 3/4] fix: reset parent on return to survey list from survey page --- .../survey-list/hook/useSurveyListActions.ts | 8 ++++++-- src/webapp/hooks/useSurveys.ts | 20 +++++++++++-------- .../pages/survey-list/SurveyListPage.tsx | 15 +++++++++++++- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/webapp/components/survey-list/hook/useSurveyListActions.ts b/src/webapp/components/survey-list/hook/useSurveyListActions.ts index 393d52a0..02e62abd 100644 --- a/src/webapp/components/survey-list/hook/useSurveyListActions.ts +++ b/src/webapp/components/survey-list/hook/useSurveyListActions.ts @@ -11,6 +11,7 @@ import { useAppContext } from "../../../contexts/app-context"; import { OptionType } from "../../../../domain/utils/optionsHelper"; import useReadOnlyAccess from "../../survey/hook/useReadOnlyAccess"; import useCaptureAccess from "../../survey/hook/useCaptureAccess"; +import { GLOBAL_OU_ID } from "../../../../domain/usecases/SaveFormDataUseCase"; export type SortDirection = "asc" | "desc"; export function useSurveyListActions(surveyFormType: SURVEY_FORM_TYPES) { @@ -180,9 +181,12 @@ export function useSurveyListActions(surveyFormType: SURVEY_FORM_TYPES) { } else if (surveyFormType === "PPSWardRegister") changeCurrentWardRegister(survey); else if (surveyFormType === "PrevalenceSurveyForm") changeCurrentPrevalenceSurveyForm(survey.id, survey.name, orgUnitId); - else if (surveyFormType === "PrevalenceFacilityLevelForm") + else if (surveyFormType === "PrevalenceFacilityLevelForm") { + if (!isAdmin) { + changeCurrentPrevalenceSurveyForm(rootSurvey.id, rootSurvey.name, GLOBAL_OU_ID); + } changeCurrentFacilityLevelForm(survey.id, survey.name, orgUnitId); - else if (surveyFormType === "PrevalenceCaseReportForm") + } else if (surveyFormType === "PrevalenceCaseReportForm") changeCurrentCaseReportForm({ id: survey.id, name: survey.name }); }; diff --git a/src/webapp/hooks/useSurveys.ts b/src/webapp/hooks/useSurveys.ts index efdbffbc..6ee696dd 100644 --- a/src/webapp/hooks/useSurveys.ts +++ b/src/webapp/hooks/useSurveys.ts @@ -27,12 +27,11 @@ export function useSurveys(surveyFormType: SURVEY_FORM_TYPES) { } = useCurrentSurveys(); const { currentModule } = useCurrentModule(); - const { currentUser: { userGroups }, } = useAppContext(); - const { userHospitalsAccess } = useHospitalContext(); + const isAdmin = currentModule ? getUserAccess(currentModule, userGroups).hasAdminAccess : false; const getOrgUnitByFormType = useCallback(() => { //TO DO : make chunked calls as user may have large number of hospitals. @@ -80,12 +79,16 @@ export function useSurveys(surveyFormType: SURVEY_FORM_TYPES) { setLoadingSurveys(true); const parentSurveyId = - surveyFormType === "PrevalenceFacilityLevelForm" || - surveyFormType === "PrevalenceCaseReportForm" || - surveyFormType === "PrevalenceCentralRefLabForm" || - surveyFormType === "PrevalencePathogenIsolatesLog" || - surveyFormType === "PrevalenceSampleShipTrackForm" || - surveyFormType === "PrevalenceSupranationalRefLabForm" + !isAdmin && + (surveyFormType === "PrevalenceFacilityLevelForm" || + surveyFormType === "PPSHospitalForm") //Non admin users , do not have parent survey form. + ? undefined + : surveyFormType === "PrevalenceFacilityLevelForm" || + surveyFormType === "PrevalenceCaseReportForm" || + surveyFormType === "PrevalenceCentralRefLabForm" || + surveyFormType === "PrevalencePathogenIsolatesLog" || + surveyFormType === "PrevalenceSampleShipTrackForm" || + surveyFormType === "PrevalenceSupranationalRefLabForm" ? currentPrevalenceSurveyForm?.id : currentPPSSurveyForm?.id; @@ -139,6 +142,7 @@ export function useSurveys(surveyFormType: SURVEY_FORM_TYPES) { shouldRefreshSurveys, page, getOrgUnitByFormType, + isAdmin, ]); return { diff --git a/src/webapp/pages/survey-list/SurveyListPage.tsx b/src/webapp/pages/survey-list/SurveyListPage.tsx index a7a6413a..ea02e959 100644 --- a/src/webapp/pages/survey-list/SurveyListPage.tsx +++ b/src/webapp/pages/survey-list/SurveyListPage.tsx @@ -7,18 +7,30 @@ import { useCurrentSurveys } from "../../contexts/current-surveys-context"; import { SurveyListBreadCrumb } from "../../components/survey-list/SurveyListBreadCrumb"; import { useCurrentModule } from "../../contexts/current-module-context"; import { useRedirectHome } from "./useRedirectHome"; +import { getUserAccess } from "../../../domain/utils/menuHelper"; +import { useAppContext } from "../../contexts/app-context"; export const SurveyListPage: React.FC = React.memo(() => { const { formType } = useParams<{ formType: SURVEY_FORM_TYPES }>(); const { resetCurrentPPSSurveyForm, resetCurrentPrevalenceSurveyForm } = useCurrentSurveys(); const { currentModule } = useCurrentModule(); + const { + currentUser: { userGroups }, + } = useAppContext(); const { shouldRedirectToHome } = useRedirectHome(); const history = useHistory(); + const isAdmin = currentModule ? getUserAccess(currentModule, userGroups).hasAdminAccess : false; + //reset all current survey context when root form of either module is listed. useEffect(() => { - if (formType === "PPSSurveyForm" || formType === "PrevalenceSurveyForm") { + if ( + formType === "PPSSurveyForm" || + formType === "PrevalenceSurveyForm" || + (!isAdmin && + (formType === "PrevalenceFacilityLevelForm" || formType === "PPSHospitalForm")) + ) { resetCurrentPPSSurveyForm(); resetCurrentPrevalenceSurveyForm(); } else if (shouldRedirectToHome(formType)) { @@ -31,6 +43,7 @@ export const SurveyListPage: React.FC = React.memo(() => { resetCurrentPPSSurveyForm, resetCurrentPrevalenceSurveyForm, shouldRedirectToHome, + isAdmin, ]); return ( From b0095b3790495c6dec1e9219e0103a47bf4149a2 Mon Sep 17 00:00:00 2001 From: 9sneha-n <9sneha.n@gmail.com> Date: Fri, 19 Apr 2024 01:19:07 +0530 Subject: [PATCH 4/4] feat: chunk calls for non admin prevalance user --- .../repositories/SurveyFormD2Repository.ts | 46 ++++++++++++++++++- src/domain/repositories/SurveyRepository.ts | 3 +- src/domain/usecases/GetAllSurveysUseCase.ts | 5 +- src/domain/utils/PPSProgramsHelper.ts | 3 +- src/webapp/contexts/hospital-context.ts | 1 + src/webapp/hooks/useSurveys.ts | 28 ++++++----- src/webapp/pages/app/App.tsx | 8 +++- 7 files changed, 75 insertions(+), 19 deletions(-) diff --git a/src/data/repositories/SurveyFormD2Repository.ts b/src/data/repositories/SurveyFormD2Repository.ts index ee97c1dd..6e253b53 100644 --- a/src/data/repositories/SurveyFormD2Repository.ts +++ b/src/data/repositories/SurveyFormD2Repository.ts @@ -37,6 +37,7 @@ import { import { mapEventToSurvey, mapTrackedEntityToSurvey } from "../utils/surveyListMappers"; import { Questionnaire } from "../../domain/entities/Questionnaire/Questionnaire"; +const OU_CHUNK_SIZE = 500; export class SurveyD2Repository implements SurveyRepository { constructor(private api: D2Api) {} @@ -183,15 +184,27 @@ export class SurveyD2Repository implements SurveyRepository { getSurveys( surveyFormType: SURVEY_FORM_TYPES, programId: Id, - orgUnitId: Id + orgUnitId: Id, + chunked = false ): FutureData { return isTrackerProgram(programId) - ? this.getTrackerProgramSurveys(surveyFormType, programId, orgUnitId) + ? this.getTrackerProgramSurveys(surveyFormType, programId, orgUnitId, chunked) : this.getEventProgramSurveys(surveyFormType, programId, orgUnitId); } //Currently tracker programs are only in Prevalence module private getTrackerProgramSurveys( + surveyFormType: SURVEY_FORM_TYPES, + programId: Id, + orgUnitId: Id, + chunked = false + ): FutureData { + return chunked + ? this.getTrackerProgramSurveysChunked(surveyFormType, programId, orgUnitId) + : this.getTrackerProgramSurveysUnchunked(surveyFormType, programId, orgUnitId); + } + + private getTrackerProgramSurveysUnchunked( surveyFormType: SURVEY_FORM_TYPES, programId: Id, orgUnitId: Id @@ -214,6 +227,35 @@ export class SurveyD2Repository implements SurveyRepository { }); } + private getTrackerProgramSurveysChunked( + surveyFormType: SURVEY_FORM_TYPES, + programId: Id, + orgUnits: string + ): FutureData { + const orgUnitIds = orgUnits.split(";"); + const chunkedOUs = _(orgUnitIds).chunk(OU_CHUNK_SIZE).value(); + + return Future.sequential( + chunkedOUs.flatMap(ouChunk => { + return apiToFuture( + this.api.tracker.trackedEntities.get({ + fields: { + attributes: true, + enrollments: true, + trackedEntity: true, + orgUnit: true, + }, + program: programId, + orgUnit: ouChunk.join(";"), + }) + ).flatMap((trackedEntities: TrackedEntitiesGetResponse) => { + const surveys = mapTrackedEntityToSurvey(trackedEntities, surveyFormType); + return Future.success(surveys); + }); + }) + ).flatMap(listOfSurveys => Future.success(_(listOfSurveys).flatten().value())); + } + private getEventProgramSurveys( surveyFormType: SURVEY_FORM_TYPES, programId: Id, diff --git a/src/domain/repositories/SurveyRepository.ts b/src/domain/repositories/SurveyRepository.ts index 96a9a59a..17230b6c 100644 --- a/src/domain/repositories/SurveyRepository.ts +++ b/src/domain/repositories/SurveyRepository.ts @@ -20,7 +20,8 @@ export interface SurveyRepository { getSurveys( surveyFormType: SURVEY_FORM_TYPES, programId: Id, - orgUnitId: Id + orgUnitId: Id, + chunked: boolean ): FutureData; getPopulatedSurveyById( eventId: Id, diff --git a/src/domain/usecases/GetAllSurveysUseCase.ts b/src/domain/usecases/GetAllSurveysUseCase.ts index 727dce97..71969fc2 100644 --- a/src/domain/usecases/GetAllSurveysUseCase.ts +++ b/src/domain/usecases/GetAllSurveysUseCase.ts @@ -13,7 +13,8 @@ export class GetAllSurveysUseCase { public execute( surveyFormType: SURVEY_FORM_TYPES, orgUnitId: Id, - parentSurveyId: Id | undefined + parentSurveyId: Id | undefined, + chunked = false ): FutureData { const programId = getProgramId(surveyFormType); @@ -21,7 +22,7 @@ export class GetAllSurveysUseCase { const ouId = surveyFormType === "PPSSurveyForm" ? GLOBAL_OU_ID : orgUnitId; return this.surveyReporsitory - .getSurveys(surveyFormType, programId, ouId) + .getSurveys(surveyFormType, programId, ouId, chunked) .flatMap(surveys => { const filteredSurveys = surveyFormType === "PPSSurveyForm" || diff --git a/src/domain/utils/PPSProgramsHelper.ts b/src/domain/utils/PPSProgramsHelper.ts index e6a44fd3..904a6eb2 100644 --- a/src/domain/utils/PPSProgramsHelper.ts +++ b/src/domain/utils/PPSProgramsHelper.ts @@ -221,7 +221,8 @@ export const hideCreateNewButton = ( (surveyFormType === "PPSCountryQuestionnaire" && currentPPSFormType === "NATIONAL" && surveys !== undefined && - surveys.length >= 1) + surveys.length >= 1) || + (surveyFormType === "PrevalenceFacilityLevelForm" && !isAdmin) ); }; diff --git a/src/webapp/contexts/hospital-context.ts b/src/webapp/contexts/hospital-context.ts index 7f5c5190..d6dc9f4c 100644 --- a/src/webapp/contexts/hospital-context.ts +++ b/src/webapp/contexts/hospital-context.ts @@ -2,6 +2,7 @@ import React, { useContext } from "react"; import { OrgUnitAccess } from "../../domain/entities/User"; export interface HospitalContextState { + hospitalState: "loading" | "error" | "loaded"; userHospitalsAccess: OrgUnitAccess[]; } diff --git a/src/webapp/hooks/useSurveys.ts b/src/webapp/hooks/useSurveys.ts index 6ee696dd..2bbfcd0a 100644 --- a/src/webapp/hooks/useSurveys.ts +++ b/src/webapp/hooks/useSurveys.ts @@ -30,19 +30,14 @@ export function useSurveys(surveyFormType: SURVEY_FORM_TYPES) { const { currentUser: { userGroups }, } = useAppContext(); - const { userHospitalsAccess } = useHospitalContext(); + const { hospitalState, userHospitalsAccess } = useHospitalContext(); const isAdmin = currentModule ? getUserAccess(currentModule, userGroups).hasAdminAccess : false; const getOrgUnitByFormType = useCallback(() => { - //TO DO : make chunked calls as user may have large number of hospitals. - //TO DO : do not make call for PrevalenceFacilityLevelForm until userHospitalsAccess data is loaded. const currentUserHospitals = userHospitalsAccess - .filter(hospitals => hospitals.readAccess === true) + .filter(hospitals => hospitals.readAccess && hospitals.captureAccess) .map(hospital => hospital.orgUnitId) .join(";"); - const hasAdminAccess = currentModule - ? getUserAccess(currentModule, userGroups).hasAdminAccess - : false; switch (surveyFormType) { case "PPSHospitalForm": @@ -52,7 +47,7 @@ export function useSurveys(surveyFormType: SURVEY_FORM_TYPES) { return currentHospitalForm?.orgUnitId ?? ""; case "PrevalenceFacilityLevelForm": - return hasAdminAccess + return isAdmin ? currentPrevalenceSurveyForm?.orgUnitId ?? "" : currentUserHospitals; case "PrevalenceCaseReportForm": @@ -68,16 +63,24 @@ export function useSurveys(surveyFormType: SURVEY_FORM_TYPES) { currentCountryQuestionnaire?.orgUnitId, currentFacilityLevelForm?.orgUnitId, currentHospitalForm?.orgUnitId, - currentModule, currentPrevalenceSurveyForm?.orgUnitId, + isAdmin, surveyFormType, - userGroups, userHospitalsAccess, ]); useEffect(() => { setLoadingSurveys(true); + if ( + !isAdmin && + surveyFormType === "PrevalenceFacilityLevelForm" && + hospitalState === "loading" + ) { + console.debug("Ensure hospital context is loaded before fetching surveys."); + return; + } + const parentSurveyId = !isAdmin && (surveyFormType === "PrevalenceFacilityLevelForm" || @@ -118,9 +121,11 @@ export function useSurveys(surveyFormType: SURVEY_FORM_TYPES) { } ); } else { + const makeChunkedCall: boolean = + surveyFormType === "PrevalenceFacilityLevelForm" && !isAdmin; //Other forms are not paginated. compositionRoot.surveys.getSurveys - .execute(surveyFormType, orgUnitId, parentSurveyId) + .execute(surveyFormType, orgUnitId, parentSurveyId, makeChunkedCall) .run( surveys => { setSurveys(surveys); @@ -143,6 +148,7 @@ export function useSurveys(surveyFormType: SURVEY_FORM_TYPES) { page, getOrgUnitByFormType, isAdmin, + hospitalState, ]); return { diff --git a/src/webapp/pages/app/App.tsx b/src/webapp/pages/app/App.tsx index dba82437..7f1b6df6 100644 --- a/src/webapp/pages/app/App.tsx +++ b/src/webapp/pages/app/App.tsx @@ -36,18 +36,22 @@ function App(props: AppProps) { setAppContext({ currentUser, compositionRoot, api }); //set some default value for hospital context until its loaded. - setHospitalContext({ userHospitalsAccess: [] }); + setHospitalContext({ hospitalState: "loading", userHospitalsAccess: [] }); setShowShareButton(isShareButtonVisible); compositionRoot.users.getAccessibleOUByLevel .execute(currentUser.organisationUnits, currentUser.dataViewOrganisationUnits) .run( hospitalData => { - setHospitalContext({ userHospitalsAccess: hospitalData }); + setHospitalContext({ + hospitalState: "loaded", + userHospitalsAccess: hospitalData, + }); console.debug("Hospital data fetched successfully, hospital data set"); }, err => { console.debug(` No hospital data could be fetched : ${err}`); + setHospitalContext({ hospitalState: "error", userHospitalsAccess: [] }); } );