diff --git a/src/data/repositories/DiseaseOutbreakEventD2Repository.ts b/src/data/repositories/DiseaseOutbreakEventD2Repository.ts index 282014be..7803fea5 100644 --- a/src/data/repositories/DiseaseOutbreakEventD2Repository.ts +++ b/src/data/repositories/DiseaseOutbreakEventD2Repository.ts @@ -17,11 +17,9 @@ import { getProgramStage, getProgramTEAsMetadata } from "./utils/MetadataHelper" import { assertOrError } from "./utils/AssertOrError"; import { Future } from "../../domain/entities/generic/Future"; import { getAllTrackedEntitiesAsync } from "./utils/getAllTrackedEntities"; -import { TeamMember, TeamRole } from "../../domain/entities/incident-management-team/TeamMember"; -import { IncidentManagementTeam } from "../../domain/entities/incident-management-team/IncidentManagementTeam"; +import { TeamMember, TeamRole } from "../../domain/entities/TeamMember"; import { D2TrackerEvent } from "@eyeseetea/d2-api/api/trackerEvents"; import { - mapD2EventsToIncidentManagementTeam, mapD2EventsToIncidentManagementTeamInAggregateRoot, mapIncidentManagementTeamMemberToD2Event, } from "./utils/IncidentManagementTeamMapper"; @@ -142,50 +140,9 @@ export class DiseaseOutbreakEventD2Repository implements DiseaseOutbreakEventRep } getIncidentManagementTeam( - diseaseOutbreakId: Id, - teamMembers: TeamMember[] - ): FutureData { - return getProgramStage( - this.api, - RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_PROGRAM_STAGE_ID - ) - .flatMap(incidentManagementTeamBuilderResponse => - assertOrError( - incidentManagementTeamBuilderResponse.objects[0], - `Incident management team builder program stage not found` - ) - ) - .flatMap(programStageDataElementsMetadata => { - return apiToFuture( - this.api.tracker.events.get({ - program: RTSL_ZEBRA_PROGRAM_ID, - orgUnit: RTSL_ZEBRA_ORG_UNIT_ID, - trackedEntity: diseaseOutbreakId, - programStage: RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_PROGRAM_STAGE_ID, - fields: { - dataValues: { - dataElement: dataElementFields, - value: true, - }, - trackedEntity: true, - event: true, - }, - }) - ) - .flatMap(response => - assertOrError(response.instances, `Incident management team not found`) - ) - .flatMap(d2Events => { - return Future.success( - mapD2EventsToIncidentManagementTeam( - diseaseOutbreakId, - d2Events, - teamMembers, - programStageDataElementsMetadata.programStageDataElements - ) - ); - }); - }); + diseaseOutbreakId: Id + ): FutureData { + return this.getIncidentManagementTeamInAggregateRoot(diseaseOutbreakId); } saveIncidentManagementTeamMemberRole( diff --git a/src/data/repositories/RoleD2Repository.ts b/src/data/repositories/RoleD2Repository.ts index 42fd39fd..fa473cae 100644 --- a/src/data/repositories/RoleD2Repository.ts +++ b/src/data/repositories/RoleD2Repository.ts @@ -2,7 +2,7 @@ import { D2Api, MetadataPick } from "../../types/d2-api"; import { apiToFuture, FutureData } from "../api-futures"; import { assertOrError } from "./utils/AssertOrError"; import { Future } from "../../domain/entities/generic/Future"; -import { Role } from "../../domain/entities/incident-management-team/Role"; +import { Role } from "../../domain/entities/Role"; import { RoleRepository } from "../../domain/repositories/RoleRepository"; import { RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_PROGRAM_STAGE_ID } from "./consts/DiseaseOutbreakConstants"; import { RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_IDS_WITHOUT_ROLES } from "./consts/IncidentManagementTeamBuilderConstants"; diff --git a/src/data/repositories/TeamMemberD2Repository.ts b/src/data/repositories/TeamMemberD2Repository.ts index fd8dfe08..103427e3 100644 --- a/src/data/repositories/TeamMemberD2Repository.ts +++ b/src/data/repositories/TeamMemberD2Repository.ts @@ -1,5 +1,5 @@ import { D2Api, MetadataPick } from "../../types/d2-api"; -import { TeamMember } from "../../domain/entities/incident-management-team/TeamMember"; +import { TeamMember } from "../../domain/entities/TeamMember"; import { Id } from "../../domain/entities/Ref"; import { TeamMemberRepository } from "../../domain/repositories/TeamMemberRepository"; import { apiToFuture, FutureData } from "../api-futures"; diff --git a/src/data/repositories/test/DiseaseOutbreakEventTestRepository.ts b/src/data/repositories/test/DiseaseOutbreakEventTestRepository.ts index 17581881..e7f3286b 100644 --- a/src/data/repositories/test/DiseaseOutbreakEventTestRepository.ts +++ b/src/data/repositories/test/DiseaseOutbreakEventTestRepository.ts @@ -4,10 +4,12 @@ import { DiseaseOutbreakEventBaseAttrs, NationalIncidentStatus, } from "../../../domain/entities/disease-outbreak-event/DiseaseOutbreakEvent"; -import { DiseaseOutbreakEventAggregateRoot } from "../../../domain/entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot"; +import { + DiseaseOutbreakEventAggregateRoot, + IncidentManagementTeamInAggregateRoot, +} from "../../../domain/entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot"; import { Future } from "../../../domain/entities/generic/Future"; -import { IncidentManagementTeam } from "../../../domain/entities/incident-management-team/IncidentManagementTeam"; -import { TeamMember, TeamRole } from "../../../domain/entities/incident-management-team/TeamMember"; +import { TeamMember, TeamRole } from "../../../domain/entities/TeamMember"; import { Id } from "../../../domain/entities/Ref"; import { DiseaseOutbreakEventRepository } from "../../../domain/repositories/DiseaseOutbreakEventRepository"; import { FutureData } from "../../api-futures"; @@ -127,11 +129,10 @@ export class DiseaseOutbreakEventTestRepository implements DiseaseOutbreakEventR } getIncidentManagementTeam( - _diseaseOutbreakId: Id, - _teamMembers: TeamMember[] - ): FutureData { + _diseaseOutbreakId: Id + ): FutureData { return Future.success( - new IncidentManagementTeam({ + new IncidentManagementTeamInAggregateRoot({ teamHierarchy: [], lastUpdated: new Date(), }) diff --git a/src/data/repositories/test/RoleTestRepository.ts b/src/data/repositories/test/RoleTestRepository.ts index ad8ef9ca..0613c324 100644 --- a/src/data/repositories/test/RoleTestRepository.ts +++ b/src/data/repositories/test/RoleTestRepository.ts @@ -1,5 +1,5 @@ import { Future } from "../../../domain/entities/generic/Future"; -import { Role } from "../../../domain/entities/incident-management-team/Role"; +import { Role } from "../../../domain/entities/Role"; import { RoleRepository } from "../../../domain/repositories/RoleRepository"; import { FutureData } from "../../api-futures"; diff --git a/src/data/repositories/test/TeamMemberTestRepository.ts b/src/data/repositories/test/TeamMemberTestRepository.ts index f2b975b6..b41063a1 100644 --- a/src/data/repositories/test/TeamMemberTestRepository.ts +++ b/src/data/repositories/test/TeamMemberTestRepository.ts @@ -1,5 +1,5 @@ import { Future } from "../../../domain/entities/generic/Future"; -import { TeamMember } from "../../../domain/entities/incident-management-team/TeamMember"; +import { TeamMember } from "../../../domain/entities/TeamMember"; import { Id } from "../../../domain/entities/Ref"; import { TeamMemberRepository } from "../../../domain/repositories/TeamMemberRepository"; import { FutureData } from "../../api-futures"; diff --git a/src/data/repositories/utils/IncidentManagementTeamMapper.ts b/src/data/repositories/utils/IncidentManagementTeamMapper.ts index 6d7d9aec..0e28eea6 100644 --- a/src/data/repositories/utils/IncidentManagementTeamMapper.ts +++ b/src/data/repositories/utils/IncidentManagementTeamMapper.ts @@ -1,15 +1,13 @@ import { D2TrackerEvent, DataValue } from "@eyeseetea/d2-api/api/trackerEvents"; import _c from "../../../domain/entities/generic/Collection"; -import { Maybe } from "../../../utils/ts-utils"; -import { IncidentManagementTeam } from "../../../domain/entities/incident-management-team/IncidentManagementTeam"; import { getPopulatedDataElement, getValueById } from "./helpers"; import { RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_PROGRAM_STAGE_ID, RTSL_ZEBRA_ORG_UNIT_ID, RTSL_ZEBRA_PROGRAM_ID, } from "../consts/DiseaseOutbreakConstants"; -import { TeamMember, TeamRole } from "../../../domain/entities/incident-management-team/TeamMember"; +import { TeamMember, TeamRole } from "../../../domain/entities/TeamMember"; import { Id } from "../../../domain/entities/Ref"; import { incidentManagementTeamBuilderCodesWithoutRoles, @@ -22,112 +20,6 @@ import { } from "../../../domain/entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot"; import { getISODateAsLocaleDateString } from "./DateTimeHelper"; -export function mapD2EventsToIncidentManagementTeam( - diseaseOutbreakId: Id, - d2Events: D2TrackerEvent[], - teamMembers: TeamMember[], - incidentManagementTeamProgramStageDataElements: D2ProgramStageDataElementsMetadata[] -): IncidentManagementTeam { - const teamHierarchy: TeamMember[] = teamMembers.reduce( - (acc: TeamMember[], teamMember: TeamMember) => { - const memberRoleEvents = d2Events.filter(event => { - const teamMemberAssignedUsername = getValueById( - event.dataValues, - RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_IDS_WITHOUT_ROLES.teamMemberAssigned - ); - return teamMemberAssignedUsername === teamMember.username; - }); - - if (memberRoleEvents.length === 0) { - return acc; - } else { - const teamRoles = getTeamMemberIncidentManagementTeamRoles( - diseaseOutbreakId, - teamMember, - memberRoleEvents, - incidentManagementTeamProgramStageDataElements - ); - - return teamRoles.length === 0 - ? acc - : [...acc, new TeamMember({ ...teamMember, teamRoles: teamRoles })]; - } - }, - [] - ); - - const sortedByUpdatedDates = d2Events.sort(function (a, b) { - if (!a.updatedAt) return -1; - if (!b.updatedAt) return 1; - return a.updatedAt < b.updatedAt ? -1 : a.updatedAt > b.updatedAt ? 1 : 0; - }); - - return new IncidentManagementTeam({ - teamHierarchy: teamHierarchy, - lastUpdated: sortedByUpdatedDates[0]?.updatedAt - ? getISODateAsLocaleDateString(sortedByUpdatedDates[0]?.updatedAt) - : undefined, - }); -} - -function getTeamMemberIncidentManagementTeamRoles( - diseaseOutbreakId: Id, - teamMemberAssigned: TeamMember, - events: D2TrackerEvent[], - incidentManagementTeamProgramStageDataElements: D2ProgramStageDataElementsMetadata[] -): TeamRole[] { - return events.reduce((acc: TeamRole[], event: D2TrackerEvent) => { - if ( - teamMemberAssigned.username === - getValueById( - event.dataValues, - RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_IDS_WITHOUT_ROLES.teamMemberAssigned - ) - ) { - const teamRole = getTeamRole( - diseaseOutbreakId, - event.event, - event.dataValues, - incidentManagementTeamProgramStageDataElements - ); - - return teamRole ? [...acc, teamRole] : acc; - } - return acc; - }, []); -} - -function getTeamRole( - diseaseOutbreakId: Id, - eventId: Id, - dataValues: DataValue[], - incidentManagementTeamProgramStageDataElements: D2ProgramStageDataElementsMetadata[] -): Maybe { - const selectedRoleId = incidentManagementTeamProgramStageDataElements.find(programStage => { - const role = getValueById(dataValues, programStage.dataElement.id); - return role === "true"; - })?.dataElement.id; - - const roleSelected = incidentManagementTeamProgramStageDataElements.find( - programStage => programStage.dataElement.id === selectedRoleId - ); - - const reportsToUsername = getValueById( - dataValues, - RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_IDS_WITHOUT_ROLES.reportsToUsername - ); - - if (selectedRoleId && roleSelected) { - return { - id: eventId, - diseaseOutbreakId: diseaseOutbreakId, - roleId: selectedRoleId, - name: roleSelected?.dataElement.name, - reportsToUsername: reportsToUsername, - }; - } -} - export function mapIncidentManagementTeamMemberToD2Event( teamMemberRole: TeamRole, incidentManagementTeamMember: TeamMember, diff --git a/src/domain/entities/AppConfigurations.ts b/src/domain/entities/AppConfigurations.ts index ed997e43..a0740ae6 100644 --- a/src/domain/entities/AppConfigurations.ts +++ b/src/domain/entities/AppConfigurations.ts @@ -6,8 +6,8 @@ import { RiskAssessmentQuestionnaireOptions, RiskAssessmentSummaryOptions, } from "./ConfigurableForm"; -import { Role } from "./incident-management-team/Role"; -import { TeamMember } from "./incident-management-team/TeamMember"; +import { Role } from "./Role"; +import { TeamMember } from "./TeamMember"; import { LowPopulationAtRisk, diff --git a/src/domain/entities/ConfigurableForm.ts b/src/domain/entities/ConfigurableForm.ts index 2434d344..c6bfd224 100644 --- a/src/domain/entities/ConfigurableForm.ts +++ b/src/domain/entities/ConfigurableForm.ts @@ -1,5 +1,5 @@ import { Maybe } from "../../utils/ts-utils"; -import { TeamMember } from "./incident-management-team/TeamMember"; +import { TeamMember } from "./TeamMember"; import { Id, Option } from "./Ref"; import { Rule } from "./Rule"; import { @@ -12,8 +12,8 @@ import { RiskAssessmentSummary } from "./risk-assessment/RiskAssessmentSummary"; import { RiskAssessmentQuestionnaire } from "./risk-assessment/RiskAssessmentQuestionnaire"; import { ActionPlanAttrs } from "./incident-action-plan/ActionPlan"; import { ResponseAction } from "./incident-action-plan/ResponseAction"; -import { IncidentManagementTeam } from "./incident-management-team/IncidentManagementTeam"; -import { Role } from "./incident-management-team/Role"; +import { Role } from "./Role"; +import { IncidentManagementTeamInAggregateRoot } from "./disease-outbreak-event/DiseaseOutbreakEventAggregateRoot"; export type DiseaseOutbreakEventOptions = { dataSources: Option[]; @@ -124,7 +124,7 @@ export type IncidentManagementTeamMemberFormData = BaseFormData & { eventTrackerDetails: DiseaseOutbreakEvent; entity: Maybe; incidentManagementTeamRoleId: Maybe; - currentIncidentManagementTeam: Maybe; + currentIncidentManagementTeam: Maybe; options: IncidentManagementTeamRoleOptions; }; diff --git a/src/domain/entities/Role.ts b/src/domain/entities/Role.ts new file mode 100644 index 00000000..9b3f5693 --- /dev/null +++ b/src/domain/entities/Role.ts @@ -0,0 +1,3 @@ +import { CodedNamedRef } from "./Ref"; + +export type Role = CodedNamedRef; diff --git a/src/domain/entities/incident-management-team/TeamMember.ts b/src/domain/entities/TeamMember.ts similarity index 86% rename from src/domain/entities/incident-management-team/TeamMember.ts rename to src/domain/entities/TeamMember.ts index 0aa21f65..14a7789a 100644 --- a/src/domain/entities/incident-management-team/TeamMember.ts +++ b/src/domain/entities/TeamMember.ts @@ -1,6 +1,6 @@ -import { Maybe } from "../../../utils/ts-utils"; -import { Id, NamedRef } from "../Ref"; -import { Struct } from "../generic/Struct"; +import { Maybe } from "../../utils/ts-utils"; +import { Id, NamedRef } from "./Ref"; +import { Struct } from "./generic/Struct"; type PhoneNumber = string; type Email = string; diff --git a/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEvent.ts b/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEvent.ts index db870d27..6ff30b71 100644 --- a/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEvent.ts +++ b/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEvent.ts @@ -1,11 +1,11 @@ import { Struct } from "../generic/Struct"; import { IncidentActionPlan } from "../incident-action-plan/IncidentActionPlan"; -import { IncidentManagementTeam } from "../incident-management-team/IncidentManagementTeam"; -import { TeamMember } from "../incident-management-team/TeamMember"; +import { TeamMember } from "../TeamMember"; import { Code, NamedRef } from "../Ref"; import { RiskAssessment } from "../risk-assessment/RiskAssessment"; import { Maybe } from "../../../utils/ts-utils"; import { ValidationError } from "../ValidationError"; +import { IncidentManagementTeamInAggregateRoot } from "./DiseaseOutbreakEventAggregateRoot"; export const hazardTypes = [ "Biological:Human", @@ -79,7 +79,7 @@ export type DiseaseOutbreakEventAttrs = DiseaseOutbreakEventBaseAttrs & { incidentManager: Maybe; //TO DO : make mandatory once form rules applied. riskAssessment: Maybe; incidentActionPlan: Maybe; - incidentManagementTeam: Maybe; + incidentManagementTeam: Maybe; }; /** diff --git a/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot.ts b/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot.ts index cabd2fea..57497950 100644 --- a/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot.ts +++ b/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot.ts @@ -5,6 +5,7 @@ import { RiskAssessment } from "../risk-assessment/RiskAssessment"; import { Maybe } from "../../../utils/ts-utils"; import { ValidationError } from "../ValidationError"; import { DiseaseOutbreakEventBaseAttrs } from "./DiseaseOutbreakEvent"; +import { TEAM_ROLE_FIELD_ID } from "../../../webapp/pages/form-page/incident-management-team-member-assignment/mapIncidentManagementTeamMemberToInitialFormState"; export type DiseaseOutbreakEventAggregateRootBaseAttrs = DiseaseOutbreakEventBaseAttrs; @@ -14,7 +15,7 @@ export type IncidentManagementTeamRole = { reportsToUsername: Maybe; }; -type IncidentManagementTeamMember = { +export type IncidentManagementTeamMember = { username: string; teamRoles: IncidentManagementTeamRole[]; }; @@ -37,4 +38,63 @@ export class DiseaseOutbreakEventAggregateRoot extends Struct { + const initialMap = teamMembers.reduce((acc, member) => { + const entries = (member.teamRoles ?? []).map(role => ({ + parentUsername: role.reportsToUsername ?? "PARENT_ROOT", + username: member.username, + })); + + return entries.reduce((mapAcc, { parentUsername, username }) => { + return mapAcc.set(parentUsername, [...(mapAcc.get(parentUsername) ?? []), username]); + }, acc); + }, new Map()); + + const getDescendantUsernames = ( + parent: string, + processedParents = new Set() + ): string[] => { + if (processedParents.has(parent)) return []; + processedParents.add(parent); + + return (initialMap.get(parent) ?? []).flatMap(username => [ + username, + ...getDescendantUsernames(username, processedParents), + ]); + }; + + return Array.from(initialMap.keys()).reduce((descendantsMap, parent) => { + descendantsMap.set(parent, getDescendantUsernames(parent)); + return descendantsMap; + }, new Map()); } diff --git a/src/domain/entities/incident-action-plan/ResponseAction.ts b/src/domain/entities/incident-action-plan/ResponseAction.ts index 2c32d2a8..26926b8b 100644 --- a/src/domain/entities/incident-action-plan/ResponseAction.ts +++ b/src/domain/entities/incident-action-plan/ResponseAction.ts @@ -1,7 +1,7 @@ import { Maybe } from "../../../utils/ts-utils"; import { Id } from "../Ref"; import { Struct } from "../generic/Struct"; -import { TeamMember } from "../incident-management-team/TeamMember"; +import { TeamMember } from "../TeamMember"; export type ResponseActionStatusType = "Not done" | "Pending" | "In Progress" | "Complete"; export type ResponseActionVerificationType = "Verified" | "Unverified"; diff --git a/src/domain/entities/incident-management-team/IncidentManagementTeam.ts b/src/domain/entities/incident-management-team/IncidentManagementTeam.ts deleted file mode 100644 index a47ee380..00000000 --- a/src/domain/entities/incident-management-team/IncidentManagementTeam.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { Maybe } from "../../../utils/ts-utils"; -import { TEAM_ROLE_FIELD_ID } from "../../../webapp/pages/form-page/incident-management-team-member-assignment/mapIncidentManagementTeamMemberToInitialFormState"; -import { Struct } from "../generic/Struct"; -import { ValidationError } from "../ValidationError"; -import { TeamMember } from "./TeamMember"; - -interface IncidentManagementTeamAttrs { - lastUpdated: Maybe; - teamHierarchy: TeamMember[]; -} - -export class IncidentManagementTeam extends Struct() { - static validateNotCyclicalDependency( - teamMember: string | undefined, - reportsToUsername: string | undefined, - currentIncidentManagementTeamHierarchy: TeamMember[], - property: string - ): ValidationError[] { - const descendantsUsernamesByParentUsername = getAllDescendantsUsernamesByParentUsername( - currentIncidentManagementTeamHierarchy - ); - - const descendantsFromTeamMember = - descendantsUsernamesByParentUsername.get(teamMember ?? "") ?? []; - - const isCyclicalDependency = descendantsFromTeamMember.includes(reportsToUsername ?? ""); - - return property === TEAM_ROLE_FIELD_ID || !isCyclicalDependency - ? [] - : [ - { - property: property, - value: "", - errors: ["cannot_create_cyclycal_dependency"], - }, - ]; - } -} - -function getAllDescendantsUsernamesByParentUsername( - teamMembers: TeamMember[] -): Map { - const initialMap = teamMembers.reduce((acc, member) => { - const entries = (member.teamRoles ?? []).map(role => ({ - parentUsername: role.reportsToUsername ?? "PARENT_ROOT", - username: member.username, - })); - - return entries.reduce((mapAcc, { parentUsername, username }) => { - return mapAcc.set(parentUsername, [...(mapAcc.get(parentUsername) ?? []), username]); - }, acc); - }, new Map()); - - const getDescendantUsernames = ( - parent: string, - processedParents = new Set() - ): string[] => { - if (processedParents.has(parent)) return []; - processedParents.add(parent); - - return (initialMap.get(parent) ?? []).flatMap(username => [ - username, - ...getDescendantUsernames(username, processedParents), - ]); - }; - - return Array.from(initialMap.keys()).reduce((descendantsMap, parent) => { - descendantsMap.set(parent, getDescendantUsernames(parent)); - return descendantsMap; - }, new Map()); -} diff --git a/src/domain/entities/incident-management-team/Role.ts b/src/domain/entities/incident-management-team/Role.ts deleted file mode 100644 index f9bb7b9a..00000000 --- a/src/domain/entities/incident-management-team/Role.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CodedNamedRef } from "../Ref"; - -export type Role = CodedNamedRef; diff --git a/src/domain/entities/risk-assessment/RiskAssessmentSummary.ts b/src/domain/entities/risk-assessment/RiskAssessmentSummary.ts index 0ca40c4f..0eab7c09 100644 --- a/src/domain/entities/risk-assessment/RiskAssessmentSummary.ts +++ b/src/domain/entities/risk-assessment/RiskAssessmentSummary.ts @@ -1,6 +1,6 @@ import { Id, NamedRef } from "../Ref"; import { Struct } from "../generic/Struct"; -import { TeamMember } from "../incident-management-team/TeamMember"; +import { TeamMember } from "../TeamMember"; export interface RiskAssessmentSummaryAttrs { id: Id; diff --git a/src/domain/repositories/DiseaseOutbreakEventRepository.ts b/src/domain/repositories/DiseaseOutbreakEventRepository.ts index 4aeaf810..f04816b2 100644 --- a/src/domain/repositories/DiseaseOutbreakEventRepository.ts +++ b/src/domain/repositories/DiseaseOutbreakEventRepository.ts @@ -1,8 +1,10 @@ import { FutureData } from "../../data/api-futures"; import { DiseaseOutbreakEventBaseAttrs } from "../entities/disease-outbreak-event/DiseaseOutbreakEvent"; -import { DiseaseOutbreakEventAggregateRoot } from "../entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot"; -import { IncidentManagementTeam } from "../entities/incident-management-team/IncidentManagementTeam"; -import { TeamMember, TeamRole } from "../entities/incident-management-team/TeamMember"; +import { + DiseaseOutbreakEventAggregateRoot, + IncidentManagementTeamInAggregateRoot, +} from "../entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot"; +import { TeamMember, TeamRole } from "../entities/TeamMember"; import { Id } from "../entities/Ref"; export interface DiseaseOutbreakEventRepository { @@ -10,9 +12,8 @@ export interface DiseaseOutbreakEventRepository { getAll(): FutureData; save(diseaseOutbreak: DiseaseOutbreakEventBaseAttrs): FutureData; getIncidentManagementTeam( - diseaseOutbreakId: Id, - teamMembers: TeamMember[] - ): FutureData; + diseaseOutbreakId: Id + ): FutureData; saveIncidentManagementTeamMemberRole( teamMemberRole: TeamRole, incidentManagementTeamMember: TeamMember, diff --git a/src/domain/repositories/RoleRepository.ts b/src/domain/repositories/RoleRepository.ts index 9720a272..b5317ab8 100644 --- a/src/domain/repositories/RoleRepository.ts +++ b/src/domain/repositories/RoleRepository.ts @@ -1,5 +1,5 @@ import { FutureData } from "../../data/api-futures"; -import { Role } from "../entities/incident-management-team/Role"; +import { Role } from "../entities/Role"; export interface RoleRepository { getAll(): FutureData; diff --git a/src/domain/repositories/TeamMemberRepository.ts b/src/domain/repositories/TeamMemberRepository.ts index f490f266..8c301f41 100644 --- a/src/domain/repositories/TeamMemberRepository.ts +++ b/src/domain/repositories/TeamMemberRepository.ts @@ -1,5 +1,5 @@ import { FutureData } from "../../data/api-futures"; -import { TeamMember } from "../entities/incident-management-team/TeamMember"; +import { TeamMember } from "../entities/TeamMember"; import { Id } from "../entities/Ref"; export interface TeamMemberRepository { diff --git a/src/domain/usecases/GetConfigurationsUseCase.ts b/src/domain/usecases/GetConfigurationsUseCase.ts index ea4db870..c3c50b9c 100644 --- a/src/domain/usecases/GetConfigurationsUseCase.ts +++ b/src/domain/usecases/GetConfigurationsUseCase.ts @@ -1,8 +1,8 @@ import { FutureData } from "../../data/api-futures"; import { Configurations, SelectableOptions } from "../entities/AppConfigurations"; import { Future } from "../entities/generic/Future"; -import { Role } from "../entities/incident-management-team/Role"; -import { TeamMember } from "../entities/incident-management-team/TeamMember"; +import { Role } from "../entities/Role"; +import { TeamMember } from "../entities/TeamMember"; import { ConfigurationsRepository } from "../repositories/ConfigurationsRepository"; import { TeamMemberRepository } from "../repositories/TeamMemberRepository"; import { RoleRepository } from "../repositories/RoleRepository"; diff --git a/src/domain/usecases/GetDiseaseOutbreakByIdUseCase.ts b/src/domain/usecases/GetDiseaseOutbreakByIdUseCase.ts index c3c0acde..01ae1009 100644 --- a/src/domain/usecases/GetDiseaseOutbreakByIdUseCase.ts +++ b/src/domain/usecases/GetDiseaseOutbreakByIdUseCase.ts @@ -1,7 +1,9 @@ import { FutureData } from "../../data/api-futures"; +import { Maybe } from "../../utils/ts-utils"; import { Configurations } from "../entities/AppConfigurations"; import { DiseaseOutbreakEvent } from "../entities/disease-outbreak-event/DiseaseOutbreakEvent"; import { Future } from "../entities/generic/Future"; +import { TeamMember, TeamRole } from "../entities/TeamMember"; import { Id } from "../entities/Ref"; import { DiseaseOutbreakEventRepository } from "../repositories/DiseaseOutbreakEventRepository"; import { IncidentActionRepository } from "../repositories/IncidentActionRepository"; @@ -33,7 +35,7 @@ export class GetDiseaseOutbreakByIdUseCase { incidentManagerName, } = diseaseOutbreakEventBase; - const { selectableOptions } = configurations; + const { selectableOptions, teamMembers, roles } = configurations; const mainSyndrome = selectableOptions.eventTrackerConfigurations.mainSyndromes.find( @@ -57,23 +59,45 @@ export class GetDiseaseOutbreakByIdUseCase { this.options.riskAssessmentRepository, configurations ), - incidentManagementTeam: getIncidentManagementTeamById( - id, - configurations, - this.options - ), + incidentManagementTeam: getIncidentManagementTeamById(id, this.options), }).flatMap(({ riskAssessment, incidentManagementTeam }) => { const incidentManager = incidentManagementTeam?.teamHierarchy?.find( teamMember => teamMember.username === incidentManagerName ); + const teamRoles: TeamRole[] | undefined = incidentManager?.teamRoles + ? incidentManager.teamRoles.map((teamRole): TeamRole => { + const role = roles.find(role => role.id === teamRole.roleId); + return { + id: teamRole.id, + diseaseOutbreakId: id, + roleId: teamRole.roleId, + reportsToUsername: teamRole.reportsToUsername, + name: role?.name || "", + }; + }) + : undefined; + + const incidentManagerTeamMemberWithoutRoles = + teamMembers.incidentManagers?.find(teamMember => { + return teamMember.username === incidentManagerName; + }); + + const incidentManagerTeamMember: Maybe = + incidentManagerTeamMemberWithoutRoles + ? new TeamMember({ + ...incidentManagerTeamMemberWithoutRoles, + teamRoles: teamRoles, + }) + : undefined; + const diseaseOutbreakEvent: DiseaseOutbreakEvent = new DiseaseOutbreakEvent({ ...diseaseOutbreakEventBase, createdBy: undefined, //TO DO : FIXME populate once metadata change is done. mainSyndrome: mainSyndrome, suspectedDisease: suspectedDisease, notificationSource: notificationSource, - incidentManager: incidentManager, + incidentManager: incidentManagerTeamMember, riskAssessment: riskAssessment, incidentActionPlan: undefined, //IAP is fetched on menu click. It is not needed here. incidentManagementTeam: undefined, //IMT is fetched on menu click. It is not needed here. diff --git a/src/domain/usecases/utils/disease-outbreak/SaveDiseaseOutbreak.ts b/src/domain/usecases/utils/disease-outbreak/SaveDiseaseOutbreak.ts index 69ffc4cd..025ecf90 100644 --- a/src/domain/usecases/utils/disease-outbreak/SaveDiseaseOutbreak.ts +++ b/src/domain/usecases/utils/disease-outbreak/SaveDiseaseOutbreak.ts @@ -2,8 +2,12 @@ import { FutureData } from "../../../../data/api-futures"; import { INCIDENT_MANAGER_ROLE } from "../../../../data/repositories/consts/IncidentManagementTeamBuilderConstants"; import { Configurations } from "../../../entities/AppConfigurations"; import { DiseaseOutbreakEventBaseAttrs } from "../../../entities/disease-outbreak-event/DiseaseOutbreakEvent"; +import { + IncidentManagementTeamMember, + IncidentManagementTeamRole, +} from "../../../entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot"; import { Future } from "../../../entities/generic/Future"; -import { TeamMember, TeamRole } from "../../../entities/incident-management-team/TeamMember"; +import { TeamMember, TeamRole } from "../../../entities/TeamMember"; import { Id } from "../../../entities/Ref"; import { DiseaseOutbreakEventRepository } from "../../../repositories/DiseaseOutbreakEventRepository"; @@ -35,7 +39,7 @@ function saveIncidentManagerTeamMemberRole( ): FutureData { const teamMembers = configurations.teamMembers.all; return repositories.diseaseOutbreakEventRepository - .getIncidentManagementTeam(diseaseOutbreakEventBaseAttrs.id, teamMembers) + .getIncidentManagementTeam(diseaseOutbreakEventBaseAttrs.id) .flatMap(incidentManagementTeam => { const incidentManagerTeamMemberFound = incidentManagementTeam?.teamHierarchy?.find( teamMember => @@ -77,8 +81,8 @@ function changeIncidentManager( diseaseOutbreakEventRepository: DiseaseOutbreakEventRepository; }, diseaseOutbreakEventBaseAttrs: DiseaseOutbreakEventBaseAttrs, - oldIncidentManager: TeamMember, - oldIncidentManagerTeamRole: TeamRole, + oldIncidentManager: IncidentManagementTeamMember, + oldIncidentManagerTeamRole: IncidentManagementTeamRole, teamMembers: TeamMember[] ): FutureData { if (oldIncidentManager.username !== diseaseOutbreakEventBaseAttrs.incidentManagerName) { diff --git a/src/domain/usecases/utils/incident-management-team/GetIncidentManagementTeamById.ts b/src/domain/usecases/utils/incident-management-team/GetIncidentManagementTeamById.ts index 7e5c793e..92d680b8 100644 --- a/src/domain/usecases/utils/incident-management-team/GetIncidentManagementTeamById.ts +++ b/src/domain/usecases/utils/incident-management-team/GetIncidentManagementTeamById.ts @@ -1,19 +1,14 @@ import { FutureData } from "../../../../data/api-futures"; import { Maybe } from "../../../../utils/ts-utils"; -import { Configurations } from "../../../entities/AppConfigurations"; -import { IncidentManagementTeam } from "../../../entities/incident-management-team/IncidentManagementTeam"; +import { IncidentManagementTeamInAggregateRoot } from "../../../entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot"; import { Id } from "../../../entities/Ref"; import { DiseaseOutbreakEventRepository } from "../../../repositories/DiseaseOutbreakEventRepository"; export function getIncidentManagementTeamById( diseaseOutbreakId: Id, - configurations: Configurations, repositories: { diseaseOutbreakEventRepository: DiseaseOutbreakEventRepository; } -): FutureData> { - return repositories.diseaseOutbreakEventRepository.getIncidentManagementTeam( - diseaseOutbreakId, - configurations.teamMembers.all - ); +): FutureData> { + return repositories.diseaseOutbreakEventRepository.getIncidentManagementTeam(diseaseOutbreakId); } diff --git a/src/domain/usecases/utils/incident-management-team/GetIncidentManagementTeamConfigurableForm.ts b/src/domain/usecases/utils/incident-management-team/GetIncidentManagementTeamConfigurableForm.ts index 78dc72d8..cd53b05c 100644 --- a/src/domain/usecases/utils/incident-management-team/GetIncidentManagementTeamConfigurableForm.ts +++ b/src/domain/usecases/utils/incident-management-team/GetIncidentManagementTeamConfigurableForm.ts @@ -6,6 +6,7 @@ import { Configurations } from "../../../entities/AppConfigurations"; import { IncidentManagementTeamMemberFormData } from "../../../entities/ConfigurableForm"; import { DiseaseOutbreakEvent } from "../../../entities/disease-outbreak-event/DiseaseOutbreakEvent"; import { Future } from "../../../entities/generic/Future"; +import { TeamRole, TeamMember } from "../../../entities/TeamMember"; import { Id } from "../../../entities/Ref"; import { DiseaseOutbreakEventRepository } from "../../../repositories/DiseaseOutbreakEventRepository"; import { RoleRepository } from "../../../repositories/RoleRepository"; @@ -20,58 +21,82 @@ export function getIncidentManagementConfigurableForm( diseaseOutbreakEventRepository: DiseaseOutbreakEventRepository; } ): FutureData { - return getIncidentManagementTeamById( - eventTrackerDetails.id, - configurations, - repositories - ).flatMap(incidentManagementTeam => { - const { incidentManagementTeamRoleConfigurations } = configurations.selectableOptions; + return getIncidentManagementTeamById(eventTrackerDetails.id, repositories).flatMap( + incidentManagementTeam => { + const { teamMembers, roles } = configurations; + const { incidentManagementTeamRoleConfigurations } = configurations.selectableOptions; - const teamMemberSelected = incidentManagementTeam?.teamHierarchy.find(teamMember => - teamMember.teamRoles?.some(teamRole => teamRole.id === incidentManagementTeamRoleId) - ); + const teamMemberSelected = incidentManagementTeam?.teamHierarchy.find(teamMember => + teamMember.teamRoles?.some(teamRole => teamRole.id === incidentManagementTeamRoleId) + ); - const incidentManagementTeamMemberFormData: IncidentManagementTeamMemberFormData = { - type: "incident-management-team-member-assignment", - eventTrackerDetails: eventTrackerDetails, - entity: teamMemberSelected, - incidentManagementTeamRoleId: incidentManagementTeamRoleId, - currentIncidentManagementTeam: incidentManagementTeam, - options: { - roles: incidentManagementTeamRoleConfigurations.roles, - teamMembers: incidentManagementTeamRoleConfigurations.teamMembers.filter( - teamMembers => teamMembers.status === "Available" - ), - incidentManagers: incidentManagementTeamRoleConfigurations.incidentManagers.filter( - teamMembers => teamMembers.status === "Available" - ), - }, - labels: { - errors: { - field_is_required: "This field is required", - cannot_create_cyclycal_dependency: - "Cannot depend on itself in the team hierarchy", - }, - }, - rules: [ - { - type: "disableFieldOptionWithSameFieldValue", - fieldId: incidentManagementTeamBuilderCodesWithoutRoles.teamMemberAssigned, - fieldIdsToDisableOption: [ - incidentManagementTeamBuilderCodesWithoutRoles.reportsToUsername, - ], - sectionsWithFieldsToDisableOption: [SECTION_IDS.reportsTo], + const teamRoles: TeamRole[] | undefined = teamMemberSelected?.teamRoles + ? teamMemberSelected.teamRoles.map((teamRole): TeamRole => { + const role = roles.find(role => role.id === teamRole.roleId); + return { + id: teamRole.id, + diseaseOutbreakId: eventTrackerDetails.id, + roleId: teamRole.roleId, + reportsToUsername: teamRole.reportsToUsername, + name: role?.name || "", + }; + }) + : undefined; + + const teamMemberSelectedWithoutRoles = teamMembers.all?.find(teamMember => { + return teamMember.username === teamMemberSelected?.username; + }); + + const teamMember: Maybe = teamMemberSelectedWithoutRoles + ? new TeamMember({ + ...teamMemberSelectedWithoutRoles, + teamRoles: teamRoles, + }) + : undefined; + + const incidentManagementTeamMemberFormData: IncidentManagementTeamMemberFormData = { + type: "incident-management-team-member-assignment", + eventTrackerDetails: eventTrackerDetails, + entity: teamMember, + incidentManagementTeamRoleId: incidentManagementTeamRoleId, + currentIncidentManagementTeam: incidentManagementTeam, + options: { + roles: incidentManagementTeamRoleConfigurations.roles, + teamMembers: incidentManagementTeamRoleConfigurations.teamMembers.filter( + teamMembers => teamMembers.status === "Available" + ), + incidentManagers: + incidentManagementTeamRoleConfigurations.incidentManagers.filter( + teamMembers => teamMembers.status === "Available" + ), }, - { - type: "disableFieldOptionWithSameFieldValue", - fieldId: incidentManagementTeamBuilderCodesWithoutRoles.reportsToUsername, - fieldIdsToDisableOption: [ - incidentManagementTeamBuilderCodesWithoutRoles.teamMemberAssigned, - ], - sectionsWithFieldsToDisableOption: [SECTION_IDS.teamMemberAssigned], + labels: { + errors: { + field_is_required: "This field is required", + cannot_create_cyclycal_dependency: + "Cannot depend on itself in the team hierarchy", + }, }, - ], - }; - return Future.success(incidentManagementTeamMemberFormData); - }); + rules: [ + { + type: "disableFieldOptionWithSameFieldValue", + fieldId: incidentManagementTeamBuilderCodesWithoutRoles.teamMemberAssigned, + fieldIdsToDisableOption: [ + incidentManagementTeamBuilderCodesWithoutRoles.reportsToUsername, + ], + sectionsWithFieldsToDisableOption: [SECTION_IDS.reportsTo], + }, + { + type: "disableFieldOptionWithSameFieldValue", + fieldId: incidentManagementTeamBuilderCodesWithoutRoles.reportsToUsername, + fieldIdsToDisableOption: [ + incidentManagementTeamBuilderCodesWithoutRoles.teamMemberAssigned, + ], + sectionsWithFieldsToDisableOption: [SECTION_IDS.teamMemberAssigned], + }, + ], + }; + return Future.success(incidentManagementTeamMemberFormData); + } + ); } diff --git a/src/webapp/components/im-team-hierarchy/IMTeamHierarchyItem.tsx b/src/webapp/components/im-team-hierarchy/IMTeamHierarchyItem.tsx index e666fc9f..fb2a232e 100644 --- a/src/webapp/components/im-team-hierarchy/IMTeamHierarchyItem.tsx +++ b/src/webapp/components/im-team-hierarchy/IMTeamHierarchyItem.tsx @@ -5,7 +5,7 @@ import { IconUser24 } from "@dhis2/ui"; import { Maybe } from "../../../utils/ts-utils"; import { Checkbox } from "../checkbox/Checkbox"; -import { TeamMember } from "../../../domain/entities/incident-management-team/TeamMember"; +import { TeamMember } from "../../../domain/entities/TeamMember"; import { TeamMemberProfile } from "./TeamMemberProfile"; import { IMTeamHierarchyOption } from "./IMTeamHierarchyView"; import { Id } from "../../../domain/entities/Ref"; diff --git a/src/webapp/components/im-team-hierarchy/IMTeamHierarchyView.tsx b/src/webapp/components/im-team-hierarchy/IMTeamHierarchyView.tsx index 3f3b4574..45a43ccb 100644 --- a/src/webapp/components/im-team-hierarchy/IMTeamHierarchyView.tsx +++ b/src/webapp/components/im-team-hierarchy/IMTeamHierarchyView.tsx @@ -4,7 +4,7 @@ import styled from "styled-components"; import { ArrowDropDown, ArrowRight } from "@material-ui/icons"; import { Maybe } from "../../../utils/ts-utils"; -import { TeamMember } from "../../../domain/entities/incident-management-team/TeamMember"; +import { TeamMember } from "../../../domain/entities/TeamMember"; import { IMTeamHierarchyItem } from "./IMTeamHierarchyItem"; import { Id } from "../../../domain/entities/Ref"; import { SearchInput } from "../search-input/SearchInput"; diff --git a/src/webapp/components/im-team-hierarchy/TeamMemberProfile.tsx b/src/webapp/components/im-team-hierarchy/TeamMemberProfile.tsx index 0e378c96..1f6760be 100644 --- a/src/webapp/components/im-team-hierarchy/TeamMemberProfile.tsx +++ b/src/webapp/components/im-team-hierarchy/TeamMemberProfile.tsx @@ -4,7 +4,7 @@ import { Link } from "@material-ui/core"; import { IconEditItems24 } from "@dhis2/ui"; import i18n from "../../../utils/i18n"; -import { TeamMember } from "../../../domain/entities/incident-management-team/TeamMember"; +import { TeamMember } from "../../../domain/entities/TeamMember"; import { ProfileModal } from "../profile-modal/ProfileModal"; import { useAppContext } from "../../contexts/app-context"; import { Button } from "../button/Button"; diff --git a/src/webapp/components/incident-management-team/IncidentManagementTeam.ts b/src/webapp/components/incident-management-team/IncidentManagementTeam.ts new file mode 100644 index 00000000..7a2c0dc1 --- /dev/null +++ b/src/webapp/components/incident-management-team/IncidentManagementTeam.ts @@ -0,0 +1,7 @@ +import { Maybe } from "../../../utils/ts-utils"; +import { TeamMember } from "../../../domain/entities/TeamMember"; + +export type IncidentManagementTeam = { + lastUpdated: Maybe; + teamHierarchy: TeamMember[]; +}; diff --git a/src/webapp/components/incident-management-team/useIncidentManagementTeamView.ts b/src/webapp/components/incident-management-team/useIncidentManagementTeamView.ts index 3bb065dc..3680da7f 100644 --- a/src/webapp/components/incident-management-team/useIncidentManagementTeamView.ts +++ b/src/webapp/components/incident-management-team/useIncidentManagementTeamView.ts @@ -8,11 +8,11 @@ import { Maybe } from "../../../utils/ts-utils"; import { Id } from "../../../domain/entities/Ref"; import { useAppContext } from "../../contexts/app-context"; import { IMTeamHierarchyOption } from "../im-team-hierarchy/IMTeamHierarchyView"; -import { IncidentManagementTeam } from "../../../domain/entities/incident-management-team/IncidentManagementTeam"; -import { TeamMember, TeamRole } from "../../../domain/entities/incident-management-team/TeamMember"; +import { IncidentManagementTeam } from "./IncidentManagementTeam"; +import { TeamMember, TeamRole } from "../../../domain/entities/TeamMember"; import { TableColumn, TableRowType } from "../table/BasicTable"; import { IncidentManagementTeamInAggregateRoot } from "../../../domain/entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot"; -import { Role } from "../../../domain/entities/incident-management-team/Role"; +import { Role } from "../../../domain/entities/Role"; type State = { incidentManagementTeamHierarchyItems: Maybe; @@ -297,8 +297,9 @@ function buildIncidentManagementTeam( .compact() .toArray(); - return new IncidentManagementTeam({ + const incidentManagementTeam: IncidentManagementTeam = { teamHierarchy: imTeamMembers, lastUpdated: diseaseOutbreakEventIncidentManagementTeam.lastUpdated, - }); + }; + return incidentManagementTeam; } diff --git a/src/webapp/pages/form-page/disease-outbreak-event/mapDiseaseOutbreakEventToInitialFormState.ts b/src/webapp/pages/form-page/disease-outbreak-event/mapDiseaseOutbreakEventToInitialFormState.ts index 999e73c4..d324eac1 100644 --- a/src/webapp/pages/form-page/disease-outbreak-event/mapDiseaseOutbreakEventToInitialFormState.ts +++ b/src/webapp/pages/form-page/disease-outbreak-event/mapDiseaseOutbreakEventToInitialFormState.ts @@ -1,7 +1,7 @@ import i18n from "@eyeseetea/d2-ui-components/locales"; import { DiseaseOutbreakEventFormData } from "../../../../domain/entities/ConfigurableForm"; import { DataSource } from "../../../../domain/entities/disease-outbreak-event/DiseaseOutbreakEvent"; -import { TeamMember } from "../../../../domain/entities/incident-management-team/TeamMember"; +import { TeamMember } from "../../../../domain/entities/TeamMember"; import { getFieldIdFromIdsDictionary } from "../../../components/form/FormFieldsState"; import { FormSectionState } from "../../../components/form/FormSectionsState"; import { FormState } from "../../../components/form/FormState"; diff --git a/src/webapp/pages/form-page/incident-management-team-member-assignment/mapIncidentManagementTeamMemberToInitialFormState.ts b/src/webapp/pages/form-page/incident-management-team-member-assignment/mapIncidentManagementTeamMemberToInitialFormState.ts index 5ae99d1d..970199a7 100644 --- a/src/webapp/pages/form-page/incident-management-team-member-assignment/mapIncidentManagementTeamMemberToInitialFormState.ts +++ b/src/webapp/pages/form-page/incident-management-team-member-assignment/mapIncidentManagementTeamMemberToInitialFormState.ts @@ -7,6 +7,7 @@ import { INCIDENT_MANAGER_ROLE, incidentManagementTeamBuilderCodesWithoutRoles, } from "../../../../data/repositories/consts/IncidentManagementTeamBuilderConstants"; +import { TeamMember, TeamRole } from "../../../../domain/entities/TeamMember"; export const TEAM_ROLE_FIELD_ID = "team-role-field"; export const SECTION_IDS = { @@ -34,9 +35,35 @@ export function mapIncidentManagementTeamMemberToInitialFormState( ); const teamMemberOptions: User[] = teamMembers.map(tm => mapTeamMemberToUser(tm)); const incidentManagerOptions: User[] = incidentManagers.map(tm => mapTeamMemberToUser(tm)); + const currentIncidentManagementTeamOptions: User[] = ( currentIncidentManagementTeam?.teamHierarchy || [] - ).map(tm => mapTeamMemberToUser(tm)); + ) + .map(tm => { + const teamRoles: TeamRole[] | undefined = tm?.teamRoles + ? tm.teamRoles.map((teamRole): TeamRole => { + const role = roles.find(role => role.id === teamRole.roleId); + return { + id: teamRole.id, + diseaseOutbreakId: eventTrackerDetails.id, + roleId: teamRole.roleId, + reportsToUsername: teamRole.reportsToUsername, + name: role?.name || "", + }; + }) + : undefined; + + const teamMemberSelectedWithoutRoles = teamMembers?.find(teamMember => { + return teamMember.username === tm?.username; + }); + + const teamMember = teamMemberSelectedWithoutRoles + ? new TeamMember({ ...teamMemberSelectedWithoutRoles, teamRoles }) + : undefined; + return teamMember ? mapTeamMemberToUser(teamMember) : undefined; + }) + .filter((user): user is User => user !== undefined); + const teamRoleToAssing = incidentManagementTeamMember?.teamRoles?.find( teamRole => teamRole.id === incidentManagementTeamRoleId ); diff --git a/src/webapp/pages/form-page/mapEntityToFormState.ts b/src/webapp/pages/form-page/mapEntityToFormState.ts index 1513f837..60150092 100644 --- a/src/webapp/pages/form-page/mapEntityToFormState.ts +++ b/src/webapp/pages/form-page/mapEntityToFormState.ts @@ -3,7 +3,7 @@ import { DiseaseNames, HazardNames, } from "../../../domain/entities/disease-outbreak-event/PerformanceOverviewMetrics"; -import { TeamMember } from "../../../domain/entities/incident-management-team/TeamMember"; +import { TeamMember } from "../../../domain/entities/TeamMember"; import { Option } from "../../../domain/entities/Ref"; import { FormState } from "../../components/form/FormState"; import { User } from "../../components/user-selector/UserSelector"; diff --git a/src/webapp/pages/form-page/mapFormStateToEntityData.ts b/src/webapp/pages/form-page/mapFormStateToEntityData.ts index e1f636de..7c3cf9d9 100644 --- a/src/webapp/pages/form-page/mapFormStateToEntityData.ts +++ b/src/webapp/pages/form-page/mapFormStateToEntityData.ts @@ -47,7 +47,7 @@ import { Status, Verification, } from "../../../domain/entities/incident-action-plan/ResponseAction"; -import { TeamMember } from "../../../domain/entities/incident-management-team/TeamMember"; +import { TeamMember } from "../../../domain/entities/TeamMember"; import { TEAM_ROLE_FIELD_ID } from "./incident-management-team-member-assignment/mapIncidentManagementTeamMemberToInitialFormState"; import { incidentManagementTeamBuilderCodesWithoutRoles } from "../../../data/repositories/consts/IncidentManagementTeamBuilderConstants"; diff --git a/src/webapp/pages/form-page/utils/updateDiseaseOutbreakEventFormState.ts b/src/webapp/pages/form-page/utils/updateDiseaseOutbreakEventFormState.ts index 434e8835..aa5ac5a8 100644 --- a/src/webapp/pages/form-page/utils/updateDiseaseOutbreakEventFormState.ts +++ b/src/webapp/pages/form-page/utils/updateDiseaseOutbreakEventFormState.ts @@ -1,7 +1,7 @@ import { incidentManagementTeamBuilderCodesWithoutRoles } from "../../../../data/repositories/consts/IncidentManagementTeamBuilderConstants"; import { ConfigurableForm } from "../../../../domain/entities/ConfigurableForm"; import { DiseaseOutbreakEvent } from "../../../../domain/entities/disease-outbreak-event/DiseaseOutbreakEvent"; -import { IncidentManagementTeam } from "../../../../domain/entities/incident-management-team/IncidentManagementTeam"; +import { DiseaseOutbreakEventAggregateRoot } from "../../../../domain/entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot"; import { ValidationError } from "../../../../domain/entities/ValidationError"; import { FormFieldState } from "../../../components/form/FormFieldsState"; import { getFieldValueByIdFromSections } from "../../../components/form/FormSectionsState"; @@ -80,7 +80,7 @@ function validateFormState( incidentManagementTeamBuilderCodesWithoutRoles.teamMemberAssigned ) as string | undefined; - return IncidentManagementTeam.validateNotCyclicalDependency( + return DiseaseOutbreakEventAggregateRoot.validateNotCyclicalDependencyInIncidentManagementTeam( teamMemberAssigned, reportsToUsername, configurableForm?.currentIncidentManagementTeam?.teamHierarchy || [], diff --git a/src/webapp/pages/incident-management-team-builder/useIMTeamBuilder.ts b/src/webapp/pages/incident-management-team-builder/useIMTeamBuilder.ts index 725822bc..942cad8c 100644 --- a/src/webapp/pages/incident-management-team-builder/useIMTeamBuilder.ts +++ b/src/webapp/pages/incident-management-team-builder/useIMTeamBuilder.ts @@ -6,7 +6,7 @@ import { User } from "../../components/user-selector/UserSelector"; import { mapTeamMemberToUser } from "../form-page/mapEntityToFormState"; import { IMTeamHierarchyOption } from "../../components/im-team-hierarchy/IMTeamHierarchyView"; import { RouteName, useRoutes } from "../../hooks/useRoutes"; -import { TeamMember } from "../../../domain/entities/incident-management-team/TeamMember"; +import { TeamMember } from "../../../domain/entities/TeamMember"; import { INCIDENT_MANAGER_ROLE } from "../../../data/repositories/consts/IncidentManagementTeamBuilderConstants"; import _c from "../../../domain/entities/generic/Collection"; import { useIncidentManagementTeamView } from "../../components/incident-management-team/useIncidentManagementTeamView";