From 0ec0f6d380419ad18037768b9a32d9b3e814f32b Mon Sep 17 00:00:00 2001 From: 9sneha-n <9sneha.n@gmail.com> Date: Mon, 6 Nov 2023 20:51:58 +0530 Subject: [PATCH] fix: review comments - move dhis specific entities to data layer --- .../repositories/SurveyFormD2Repository.ts | 93 ++++++++++++++++--- .../SurveyFormTestRepository.ts | 17 +++- src/domain/entities/EventProgram.ts | 5 - src/domain/entities/Survey.ts | 3 +- src/domain/repositories/ModuleRepository.ts | 2 +- src/domain/repositories/SurveyRepository.ts | 11 ++- .../usecases/GetAllAccesibleModulesUseCase.ts | 3 +- src/domain/usecases/GetAllSurveysUseCase.ts | 2 +- .../usecases/GetPopulatedSurveyUseCase.ts | 5 +- src/domain/usecases/SaveFormDataUseCase.ts | 67 ++----------- .../components/custom-card/CustomCard.tsx | 1 - .../components/left-nav/LeftNavMenu.tsx | 1 - .../orgunit-selector/OrgUnitSelector.tsx | 3 +- .../components/survey/hook/useSurveyForm.ts | 2 +- 14 files changed, 118 insertions(+), 97 deletions(-) diff --git a/src/data/repositories/SurveyFormD2Repository.ts b/src/data/repositories/SurveyFormD2Repository.ts index 4072d83e..7d945c98 100644 --- a/src/data/repositories/SurveyFormD2Repository.ts +++ b/src/data/repositories/SurveyFormD2Repository.ts @@ -19,9 +19,9 @@ import { EventProgramMetadata, ImportStrategy, Option, - TrackerEventsPostRequest, } from "../../domain/entities/EventProgram"; import { Survey } from "../../domain/entities/Survey"; +import { DataValue } from "@eyeseetea/d2-api"; export const PPS_SURVEY_FORM_ID = "OGOw5Kt3ytv"; export const PPS_COUNTRY_QUESTIONNAIRE_ID = "a4aYe2Eoaul"; @@ -209,23 +209,86 @@ export class SurveyD2Repository implements SurveyRepository { return questions; } - saveFormData(events: TrackerEventsPostRequest, action: ImportStrategy): FutureData { - return apiToFuture(this.api.tracker.postAsync({ importStrategy: action }, events)).flatMap( - response => { + saveFormData( + questionnaire: Questionnaire, + action: ImportStrategy, + orgUnitId: Id, + eventId: string | undefined, + programId: Id + ): FutureData { + return this.mapQuestionnaireToEvent(questionnaire, orgUnitId, programId, eventId).flatMap( + event => { return apiToFuture( - // eslint-disable-next-line testing-library/await-async-utils - this.api.system.waitFor("TRACKER_IMPORT_JOB", response.response.id) - ).flatMap(result => { - if (result) { - return Future.success(undefined); - } else { - return Future.error(new Error("An error occured while saving the survey")); - } + this.api.tracker.postAsync({ importStrategy: action }, { events: [event] }) + ).flatMap(response => { + return apiToFuture( + // eslint-disable-next-line testing-library/await-async-utils + this.api.system.waitFor("TRACKER_IMPORT_JOB", response.response.id) + ).flatMap(result => { + if (result) { + return Future.success(undefined); + } else { + return Future.error( + new Error("An error occured while saving the survey") + ); + } + }); }); } ); } + private mapQuestionnaireToEvent( + questionnaire: Questionnaire, + orgUnitId: string, + programId: Id, + eventId: string | undefined = undefined + ): FutureData { + const questions = questionnaire.sections.flatMap(section => section.questions); + + const dataValues = _( + questions.map(q => { + if (q) { + if (q.type === "select" && q.value) { + return { + dataElement: q.id, + value: q.value.code, + }; + } else { + return { + dataElement: q.id, + value: q.value, + }; + } + } + }) + ) + .compact() + .value(); + + if (eventId) { + return this.getSurveyById(eventId).flatMap(event => { + const updatedEvent: D2TrackerEvent = { + ...event, + + dataValues: dataValues as DataValue[], + }; + return Future.success(updatedEvent); + }); + } else { + const event: D2TrackerEvent = { + event: "", + orgUnit: orgUnitId, + program: programId, + status: "ACTIVE", + occurredAt: new Date().toISOString().split("T")?.at(0) || "", + //@ts-ignore + dataValues: dataValues, + }; + return Future.success(event); + } + } + getSurveys(programId: Id, orgUnitId: Id): FutureData { return apiToFuture( this.api.tracker.events.get({ @@ -277,6 +340,12 @@ export class SurveyD2Repository implements SurveyRepository { }); } + getPopulatedSurveyById(eventId: Id, programId: Id): FutureData { + return this.getSurveyById(eventId).flatMap(event => { + return this.getForm(programId, event); + }); + } + getSurveyById(eventId: string): FutureData { return apiToFuture( this.api.tracker.events.getById(eventId, { diff --git a/src/data/repositories/testRepositories/SurveyFormTestRepository.ts b/src/data/repositories/testRepositories/SurveyFormTestRepository.ts index fd0a669b..b5f98bd7 100644 --- a/src/data/repositories/testRepositories/SurveyFormTestRepository.ts +++ b/src/data/repositories/testRepositories/SurveyFormTestRepository.ts @@ -1,13 +1,18 @@ import { D2TrackerEvent } from "@eyeseetea/d2-api/api/trackerEvents"; -import { ImportStrategy, TrackerEventsPostRequest } from "../../../domain/entities/EventProgram"; +import { ImportStrategy } from "../../../domain/entities/EventProgram"; import { Future } from "../../../domain/entities/generic/Future"; import { Questionnaire } from "../../../domain/entities/Questionnaire"; +import { Id } from "../../../domain/entities/Ref"; import { Survey } from "../../../domain/entities/Survey"; import { SurveyRepository } from "../../../domain/repositories/SurveyRepository"; import { FutureData } from "../../api-futures"; import { PPS_SURVEY_FORM_ID } from "../SurveyFormD2Repository"; export class SurveyTestRepository implements SurveyRepository { + getPopulatedSurveyById(eventId: string, programId: string): FutureData { + console.debug(eventId, programId); + throw new Error("Method not implemented."); + } getForm(programId: string): FutureData { const questionnaire: Questionnaire = { id: programId, @@ -30,8 +35,14 @@ export class SurveyTestRepository implements SurveyRepository { return Future.success(questionnaire); } - saveFormData(events: TrackerEventsPostRequest, action: ImportStrategy): FutureData { - if (events && action) return Future.success(undefined); + saveFormData( + events: Questionnaire, + action: ImportStrategy, + orgUnitId: Id, + eventId: string | undefined, + programId: Id + ): FutureData { + if (events && action && orgUnitId && eventId && programId) return Future.success(undefined); else return Future.error(new Error("An error occured while saving the survey")); } diff --git a/src/domain/entities/EventProgram.ts b/src/domain/entities/EventProgram.ts index b27560c5..b19376a7 100644 --- a/src/domain/entities/EventProgram.ts +++ b/src/domain/entities/EventProgram.ts @@ -1,8 +1,3 @@ -import { D2TrackerEvent } from "@eyeseetea/d2-api/api/trackerEvents"; - -export interface TrackerEventsPostRequest { - events: D2TrackerEvent[]; -} export type ImportStrategy = "CREATE" | "UPDATE" | "CREATE_AND_UPDATE" | "DELETE"; export interface EventProgram { diff --git a/src/domain/entities/Survey.ts b/src/domain/entities/Survey.ts index ca2ef569..e6935f31 100644 --- a/src/domain/entities/Survey.ts +++ b/src/domain/entities/Survey.ts @@ -1,5 +1,4 @@ -import { Ref } from "@eyeseetea/d2-api"; -import { NamedRef } from "./Ref"; +import { NamedRef, Ref } from "./Ref"; export type SURVEY_FORM_TYPES = | "PPSSurveyForm" diff --git a/src/domain/repositories/ModuleRepository.ts b/src/domain/repositories/ModuleRepository.ts index 8d5aaf92..9ed9ee40 100644 --- a/src/domain/repositories/ModuleRepository.ts +++ b/src/domain/repositories/ModuleRepository.ts @@ -1,6 +1,6 @@ -import { Id } from "@eyeseetea/d2-api"; import { FutureData } from "../../data/api-futures"; import { AMRSurveyModule } from "../entities/AMRSurveyModule"; +import { Id } from "../entities/Ref"; export interface ModuleRepository { getAll(): FutureData; diff --git a/src/domain/repositories/SurveyRepository.ts b/src/domain/repositories/SurveyRepository.ts index be11deaf..cba9c4bd 100644 --- a/src/domain/repositories/SurveyRepository.ts +++ b/src/domain/repositories/SurveyRepository.ts @@ -1,13 +1,20 @@ import { D2TrackerEvent } from "@eyeseetea/d2-api/api/trackerEvents"; import { FutureData } from "../../data/api-futures"; -import { ImportStrategy, TrackerEventsPostRequest } from "../entities/EventProgram"; +import { ImportStrategy } from "../entities/EventProgram"; import { Questionnaire } from "../entities/Questionnaire"; import { Id } from "../entities/Ref"; import { Survey } from "../entities/Survey"; export interface SurveyRepository { getForm(programId: Id, event: D2TrackerEvent | undefined): FutureData; - saveFormData(events: TrackerEventsPostRequest, action: ImportStrategy): FutureData; + saveFormData( + events: Questionnaire, + action: ImportStrategy, + orgUnitId: Id, + eventId: string | undefined, + programId: Id + ): FutureData; getSurveys(programId: Id, orgUnitId: Id): FutureData; getSurveyById(eventId: string): FutureData; + getPopulatedSurveyById(eventId: Id, programId: Id): FutureData; } diff --git a/src/domain/usecases/GetAllAccesibleModulesUseCase.ts b/src/domain/usecases/GetAllAccesibleModulesUseCase.ts index acc13b52..40a37aa1 100644 --- a/src/domain/usecases/GetAllAccesibleModulesUseCase.ts +++ b/src/domain/usecases/GetAllAccesibleModulesUseCase.ts @@ -3,8 +3,7 @@ import { AMRSurveyModule } from "../entities/AMRSurveyModule"; import { ModuleRepository } from "../repositories/ModuleRepository"; import _ from "../../domain/entities/generic/Collection"; import { Future } from "../entities/generic/Future"; -import { NamedRef } from "../entities/Ref"; -import { Id } from "@eyeseetea/d2-api"; +import { NamedRef, Id } from "../entities/Ref"; export class GetAllAccesibleModulesUseCase { constructor(private moduleRepository: ModuleRepository) {} diff --git a/src/domain/usecases/GetAllSurveysUseCase.ts b/src/domain/usecases/GetAllSurveysUseCase.ts index d1fd997b..d4ab7ba4 100644 --- a/src/domain/usecases/GetAllSurveysUseCase.ts +++ b/src/domain/usecases/GetAllSurveysUseCase.ts @@ -1,7 +1,7 @@ -import { Id } from "@eyeseetea/d2-api"; import { FutureData } from "../../data/api-futures"; import { PPS_SURVEY_FORM_ID } from "../../data/repositories/SurveyFormD2Repository"; import { Future } from "../entities/generic/Future"; +import { Id } from "../entities/Ref"; import { Survey, SURVEY_FORM_TYPES } from "../entities/Survey"; import { SurveyRepository } from "../repositories/SurveyRepository"; diff --git a/src/domain/usecases/GetPopulatedSurveyUseCase.ts b/src/domain/usecases/GetPopulatedSurveyUseCase.ts index 8f7094b4..3fed4ccb 100644 --- a/src/domain/usecases/GetPopulatedSurveyUseCase.ts +++ b/src/domain/usecases/GetPopulatedSurveyUseCase.ts @@ -19,9 +19,6 @@ export class GetPopulatedSurveyUseCase { default: return Future.error(new Error("Unknown survey type")); } - - return this.surveyReporsitory.getSurveyById(eventId).flatMap(event => { - return this.surveyReporsitory.getForm(programId, event); - }); + return this.surveyReporsitory.getPopulatedSurveyById(eventId, programId); } } diff --git a/src/domain/usecases/SaveFormDataUseCase.ts b/src/domain/usecases/SaveFormDataUseCase.ts index a1cc05c5..e86ab6ba 100644 --- a/src/domain/usecases/SaveFormDataUseCase.ts +++ b/src/domain/usecases/SaveFormDataUseCase.ts @@ -1,5 +1,3 @@ -import { DataValue, Id } from "@eyeseetea/d2-api"; -import { D2TrackerEvent } from "@eyeseetea/d2-api/api/trackerEvents"; import { FutureData } from "../../data/api-futures"; import { Future } from "../entities/generic/Future"; import { Questionnaire } from "../entities/Questionnaire"; @@ -7,6 +5,7 @@ import { SURVEY_FORM_TYPES } from "../entities/Survey"; import { SurveyRepository } from "../repositories/SurveyRepository"; import _ from "../../domain/entities/generic/Collection"; import { PPS_SURVEY_FORM_ID } from "../../data/repositories/SurveyFormD2Repository"; +import { Id } from "../entities/Ref"; export class SaveFormDataUseCase { constructor(private surveyReporsitory: SurveyRepository) {} @@ -26,64 +25,12 @@ export class SaveFormDataUseCase { return Future.error(new Error("Unknown survey type")); } - return this.mapQuestionnaireToEvent(questionnaire, orgUnitId, programId, eventId).flatMap( - event => { - return this.surveyReporsitory.saveFormData( - { events: [event] }, - "CREATE_AND_UPDATE" - ); - } + return this.surveyReporsitory.saveFormData( + questionnaire, + "CREATE_AND_UPDATE", + orgUnitId, + eventId, + programId ); } - - private mapQuestionnaireToEvent( - questionnaire: Questionnaire, - orgUnitId: string, - programId: Id, - eventId: string | undefined = undefined - ): FutureData { - const questions = questionnaire.sections.flatMap(section => section.questions); - - const dataValues = _( - questions.map(q => { - if (q) { - if (q.type === "select" && q.value) { - return { - dataElement: q.id, - value: q.value.code, - }; - } else { - return { - dataElement: q.id, - value: q.value, - }; - } - } - }) - ) - .compact() - .value(); - - if (eventId) { - return this.surveyReporsitory.getSurveyById(eventId).flatMap(event => { - const updatedEvent: D2TrackerEvent = { - ...event, - - dataValues: dataValues as DataValue[], - }; - return Future.success(updatedEvent); - }); - } else { - const event: D2TrackerEvent = { - event: "", - orgUnit: orgUnitId, - program: programId, - status: "ACTIVE", - occurredAt: new Date().toISOString().split("T")?.at(0) || "", - //@ts-ignore - dataValues: dataValues, - }; - return Future.success(event); - } - } } diff --git a/src/webapp/components/custom-card/CustomCard.tsx b/src/webapp/components/custom-card/CustomCard.tsx index 5f2be04e..6adc8a5c 100644 --- a/src/webapp/components/custom-card/CustomCard.tsx +++ b/src/webapp/components/custom-card/CustomCard.tsx @@ -2,7 +2,6 @@ import React, { PropsWithChildren } from "react"; import { Box, Typography } from "@material-ui/core"; import { Paper } from "material-ui"; import styled from "styled-components"; - import i18n from "@eyeseetea/d2-ui-components/locales"; import { palette } from "../../pages/app/themes/dhis2.theme"; diff --git a/src/webapp/components/left-nav/LeftNavMenu.tsx b/src/webapp/components/left-nav/LeftNavMenu.tsx index ffade5a5..bc140c8e 100644 --- a/src/webapp/components/left-nav/LeftNavMenu.tsx +++ b/src/webapp/components/left-nav/LeftNavMenu.tsx @@ -1,6 +1,5 @@ import i18n from "@eyeseetea/feedback-component/locales"; import { Button, colors, ListItem, makeStyles, Theme, Typography } from "@material-ui/core"; - import { NavLink } from "react-router-dom"; import { MenuLeaf } from "../../hooks/useMenu"; import { palette } from "../../pages/app/themes/dhis2.theme"; diff --git a/src/webapp/components/orgunit-selector/OrgUnitSelector.tsx b/src/webapp/components/orgunit-selector/OrgUnitSelector.tsx index 738db2ea..1160d590 100644 --- a/src/webapp/components/orgunit-selector/OrgUnitSelector.tsx +++ b/src/webapp/components/orgunit-selector/OrgUnitSelector.tsx @@ -1,13 +1,12 @@ import { MenuItem, Select } from "@material-ui/core"; import React, { useState } from "react"; - import SearchInput from "./SearchInput"; import styled from "styled-components"; - import { useAppContext } from "../../contexts/app-context"; import { OrgUnitAccess } from "../../../domain/entities/User"; import { useCurrentOrgUnitContext } from "../../contexts/current-org-unit-context/current-orgUnit-context"; import i18n from "@eyeseetea/feedback-component/locales"; + interface OrgUnitProps { fullWidth?: boolean; } diff --git a/src/webapp/components/survey/hook/useSurveyForm.ts b/src/webapp/components/survey/hook/useSurveyForm.ts index 432ca0f0..c2d5d4c7 100644 --- a/src/webapp/components/survey/hook/useSurveyForm.ts +++ b/src/webapp/components/survey/hook/useSurveyForm.ts @@ -3,7 +3,7 @@ import { useSnackbar } from "@eyeseetea/d2-ui-components"; import { useAppContext } from "../../../contexts/app-context"; import { Questionnaire } from "../../../../domain/entities/Questionnaire"; import { SURVEY_FORM_TYPES } from "../../../../domain/entities/Survey"; -import { Id } from "@eyeseetea/d2-api"; +import { Id } from "../../../../domain/entities/Ref"; export function useSurveyForm( formType: SURVEY_FORM_TYPES,