Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] Remove added risk summary and response action options #41

Merged
merged 9 commits into from
Dec 4, 2024
4 changes: 2 additions & 2 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2024-11-22T15:21:43.931Z\n"
"PO-Revision-Date: 2024-11-22T15:21:43.931Z\n"
"POT-Creation-Date: 2024-11-27T21:40:09.970Z\n"
"PO-Revision-Date: 2024-11-27T21:40:09.970Z\n"

msgid "Low"
msgstr ""
Expand Down
2 changes: 1 addition & 1 deletion i18n/es.po
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
msgid ""
msgstr ""
"Project-Id-Version: i18next-conv\n"
"POT-Creation-Date: 2024-11-22T15:21:43.931Z\n"
"POT-Creation-Date: 2024-11-27T21:40:09.970Z\n"
"PO-Revision-Date: 2018-10-25T09:02:35.143Z\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
Expand Down
28 changes: 27 additions & 1 deletion src/data/repositories/IncidentActionD2Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ export class IncidentActionD2Repository implements IncidentActionRepository {

saveIncidentAction(
formData: ActionPlanFormData | ResponseActionFormData | SingleResponseActionFormData,
diseaseOutbreakId: Id
diseaseOutbreakId: Id,
formOptionsToDelete?: Id[]
): FutureData<void> {
const programStageId = this.getProgramStageByFormType(formData.type);

Expand Down Expand Up @@ -178,13 +179,38 @@ export class IncidentActionD2Repository implements IncidentActionRepository {
if (saveResponse.status === "ERROR" || !diseaseOutbreakId) {
return Future.error(new Error(`Error saving Incident Action`));
} else {
if (formOptionsToDelete && formOptionsToDelete.length > 0) {
return this.deleteIncidentResponseAction(formOptionsToDelete);
}

return Future.success(undefined);
}
});
});
});
}

private deleteIncidentResponseAction(events: Id[]): FutureData<void> {
const d2Events: D2TrackerEvent[] = events.map(event => ({
event: event,
status: "COMPLETED",
program: RTSL_ZEBRA_PROGRAM_ID,
orgUnit: RTSL_ZEBRA_ORG_UNIT_ID,
occurredAt: "",
dataValues: [],
}));

return apiToFuture(
this.api.tracker.post({ importStrategy: "DELETE" }, { events: d2Events })
).flatMap(response => {
if (response.status === "ERROR") {
return Future.error(new Error(`Error deleting Response Action`));
} else {
return Future.success(undefined);
}
});
}

updateIncidentResponseAction(options: UpdateIncidentResponseActionOptions): FutureData<void> {
const { diseaseOutbreakId, eventId, responseAction } = options;

Expand Down
35 changes: 32 additions & 3 deletions src/data/repositories/RiskAssessmentD2Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,8 @@ export class RiskAssessmentD2Repository implements RiskAssessmentRepository {
| RiskAssessmentGradingFormData
| RiskAssessmentSummaryFormData
| RiskAssessmentQuestionnaireFormData,
diseaseOutbreakId: Id
diseaseOutbreakId: Id,
formOptionsToDelete?: Id[]
): FutureData<void> {
if (formData.type === "risk-assessment-questionnaire") {
const { stdQuestionnaireStageId, customQuestionnaireStageId } =
Expand Down Expand Up @@ -295,7 +296,8 @@ export class RiskAssessmentD2Repository implements RiskAssessmentRepository {
customQuestionnaireDataElements,
formData,
diseaseOutbreakId,
customQuestionnaireStageId
customQuestionnaireStageId,
formOptionsToDelete
);
}
);
Expand Down Expand Up @@ -336,7 +338,8 @@ export class RiskAssessmentD2Repository implements RiskAssessmentRepository {
| RiskAssessmentSummaryFormData
| RiskAssessmentQuestionnaireFormData,
diseaseOutbreakId: Id,
programStageId: Id
programStageId: Id,
formOptionsToDelete?: Id[]
): FutureData<void> {
//Get the enrollment Id for the disease outbreak
return apiToFuture(
Expand Down Expand Up @@ -368,11 +371,37 @@ export class RiskAssessmentD2Repository implements RiskAssessmentRepository {
if (saveResponse.status === "ERROR" || !diseaseOutbreakId) {
return Future.error(new Error(`Error Risk Assessment Grading`));
} else {
if (formOptionsToDelete && formOptionsToDelete.length > 0) {
return this.deleteCustomQuestion(formOptionsToDelete);
}

return Future.success(undefined);
}
});
});
}

private deleteCustomQuestion(events: Id[]): FutureData<void> {
const d2Events: D2TrackerEvent[] = events.map(event => ({
event: event,
status: "COMPLETED",
program: RTSL_ZEBRA_PROGRAM_ID,
orgUnit: RTSL_ZEBRA_ORG_UNIT_ID,
occurredAt: "",
dataValues: [],
}));

return apiToFuture(
this.api.tracker.post({ importStrategy: "DELETE" }, { events: d2Events })
).flatMap(response => {
if (response.status === "ERROR") {
return Future.error(new Error(`Error deleting Custom Question`));
} else {
return Future.success(undefined);
}
});
}

private getProgramStageByFormType(formType: string) {
switch (formType) {
case "risk-assessment-grading":
Expand Down
6 changes: 5 additions & 1 deletion src/data/repositories/test/IncidentActionTestRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ export class IncidentActionTestRepository implements IncidentActionRepository {
throw new Error("Method not implemented.");
}

saveIncidentAction(_formData: any, _diseaseOutbreakId: Id): FutureData<void> {
saveIncidentAction(
_formData: any,
_diseaseOutbreakId: Id,
_formOptionsToDelete?: Id[]
): FutureData<void> {
throw new Error("Method not implemented.");
}

Expand Down
3 changes: 2 additions & 1 deletion src/domain/repositories/IncidentActionRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export interface IncidentActionRepository {
): FutureData<Maybe<IncidentResponseActionDataValues[]>>;
saveIncidentAction(
formData: ActionPlanFormData | ResponseActionFormData | SingleResponseActionFormData,
diseaseOutbreakId: Id
diseaseOutbreakId: Id,
formOptionsToDelete?: Id[]
): FutureData<void>;
updateIncidentResponseAction(options: UpdateIncidentResponseActionOptions): FutureData<void>;
}
Expand Down
3 changes: 2 additions & 1 deletion src/domain/repositories/RiskAssessmentRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface RiskAssessmentRepository {
| RiskAssessmentGradingFormData
| RiskAssessmentSummaryFormData
| RiskAssessmentQuestionnaireFormData,
diseaseOutbreakId: Id
diseaseOutbreakId: Id,
formOptionsToDelete?: Id[]
): FutureData<void>;
}
9 changes: 6 additions & 3 deletions src/domain/usecases/SaveEntityUseCase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export class SaveEntityUseCase {

public execute(
formData: ConfigurableForm,
configurations: Configurations
configurations: Configurations,
formOptionsToDelete?: Id[]
): FutureData<void | Id> {
if (!formData || !formData.entity) return Future.error(new Error("No form data found"));
switch (formData.type) {
Expand All @@ -49,14 +50,16 @@ export class SaveEntityUseCase {
case "risk-assessment-questionnaire":
return this.options.riskAssessmentRepository.saveRiskAssessment(
formData,
formData.eventTrackerDetails.id
formData.eventTrackerDetails.id,
formOptionsToDelete
);
case "incident-action-plan":
case "incident-response-actions":
case "incident-response-action":
return this.options.incidentActionRepository.saveIncidentAction(
formData,
formData.eventTrackerDetails.id
formData.eventTrackerDetails.id,
formOptionsToDelete
);
case "incident-management-team-member-assignment": {
const isIncidentManager = formData.entity.teamRoles?.find(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,19 +196,19 @@ function getRiskSummarySelections(
configurations.selectableOptions;

const riskAssessor1 = riskSummaryConfig.riskAssessors.find(
assessor => assessor.id === summaryDataValues?.riskAssessor1
assessor => assessor.username === summaryDataValues?.riskAssessor1
);
const riskAssessor2 = riskSummaryConfig.riskAssessors.find(
assessor => assessor.id === summaryDataValues?.riskAssessor2
assessor => assessor.username === summaryDataValues?.riskAssessor2
);
const riskAssessor3 = riskSummaryConfig.riskAssessors.find(
assessor => assessor.id === summaryDataValues?.riskAssessor3
assessor => assessor.username === summaryDataValues?.riskAssessor3
);
const riskAssessor4 = riskSummaryConfig.riskAssessors.find(
assessor => assessor.id === summaryDataValues?.riskAssessor4
assessor => assessor.username === summaryDataValues?.riskAssessor4
);
const riskAssessor5 = riskSummaryConfig.riskAssessors.find(
assessor => assessor.id === summaryDataValues?.riskAssessor5
assessor => assessor.username === summaryDataValues?.riskAssessor5
);
const overallRiskGlobal = riskSummaryConfig.overallRiskGlobal.find(
risk => risk.id === summaryDataValues?.overallRiskGlobal
Expand Down
6 changes: 5 additions & 1 deletion src/webapp/components/form/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ export type FormProps = {
onSave: () => void;
onCancel?: () => void;
handleAddNew?: () => void;
handleRemove?: (id: string) => void;
};

export const Form: React.FC<FormProps> = React.memo(props => {
const { formState, onFormChange, onSave, onCancel, errorLabels, handleAddNew } = props;
const { formState, onFormChange, onSave, onCancel, errorLabels, handleAddNew, handleRemove } =
props;
const { formLocalState, handleUpdateFormField } = useLocalForm(formState, onFormChange);

return (
Expand Down Expand Up @@ -49,6 +51,8 @@ export const Form: React.FC<FormProps> = React.memo(props => {
errorLabels={errorLabels}
handleAddNew={handleAddNew}
addNewField={section.addNewField}
handleRemove={handleRemove}
removeOption={section.removeOption}
/>
);
})}
Expand Down
17 changes: 17 additions & 0 deletions src/webapp/components/form/FormSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { FieldWidget } from "./FieldWidget";
import { AddNewFieldState, FormFieldState } from "./FormFieldsState";
import { FormSectionState } from "./FormSectionsState";
import { AddNewOption } from "../add-new-option/AddNewOption";
import { Button } from "../button/Button";

type FormSectionProps = {
id: string;
Expand All @@ -22,6 +23,8 @@ type FormSectionProps = {
errorLabels?: Record<string, string>;
handleAddNew?: () => void;
addNewField?: AddNewFieldState;
handleRemove?: (id: string) => void;
removeOption?: boolean;
};

export const FormSection: React.FC<FormSectionProps> = React.memo(
Expand All @@ -38,6 +41,8 @@ export const FormSection: React.FC<FormSectionProps> = React.memo(
errorLabels,
handleAddNew,
addNewField,
handleRemove,
removeOption = false,
}) => {
return (
<FormSectionContainer>
Expand Down Expand Up @@ -87,6 +92,12 @@ export const FormSection: React.FC<FormSectionProps> = React.memo(
</FieldContainer>
);
})}

{removeOption && handleRemove && (
<ButtonContainer>
<Button onClick={() => handleRemove(id)}>Remove</Button>
</ButtonContainer>
)}
</FormContainer>
) : null}

Expand Down Expand Up @@ -226,3 +237,9 @@ const FieldContainer = styled.div<{ width?: string; maxWidth?: string }>`
width: 100%;
}
`;

const ButtonContainer = styled.div`
width: 100%;
display: flex;
justify-content: end;
`;
1 change: 1 addition & 0 deletions src/webapp/components/form/FormSectionsState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type FormSectionState = {
subsections?: FormSectionState[];
onClickInfo?: (id: string) => void;
addNewField?: AddNewFieldState;
removeOption?: boolean;
};

// HELPERS:
Expand Down
2 changes: 2 additions & 0 deletions src/webapp/pages/form-page/FormPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const FormPage: React.FC = React.memo(() => {
onPrimaryButtonClick,
onCancelForm,
handleAddNew,
handleRemove,
} = useForm(formType, id);

useEffect(() => {
Expand All @@ -53,6 +54,7 @@ export const FormPage: React.FC = React.memo(() => {
onCancel={onCancelForm}
errorLabels={formLabels?.errors}
handleAddNew={handleAddNew}
handleRemove={handleRemove}
/>
) : (
formState.message && <ErrorMessageContainer>{formState.message}</ErrorMessageContainer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,16 +300,16 @@ export function mapSingleIncidentResponseActionToInitialFormState(
verificationOptions: verificationOptions,
},
isIncidentManager: isIncidentManager,
isSingleIncidentResponseAction: true,
index: 0,
});

return {
id: eventTrackerDetails.id ?? "",
title: "Incident Action Plan",
subtitle: eventTrackerDetails.name,
titleDescripton: "Step 2:",
subtitleDescripton: "Edit response action",
saveButtonLabel: "Save plan",
titleDescripton: "Edit response action",
saveButtonLabel: "Save response action",
isValid: incidentResponseAction ? true : false,
sections: [responseActionSection],
};
Expand All @@ -324,8 +324,15 @@ function getResponseActionSection(options: {
};
isIncidentManager: boolean;
index: number;
isSingleIncidentResponseAction?: boolean;
}) {
const { incidentResponseAction, options: formOptions, index, isIncidentManager } = options;
const {
incidentResponseAction,
options: formOptions,
index,
isIncidentManager,
isSingleIncidentResponseAction,
} = options;
const { searchAssignROOptions, statusOptions, verificationOptions } = formOptions;

const responseActionSection: FormSectionState = {
Expand Down Expand Up @@ -421,6 +428,7 @@ function getResponseActionSection(options: {
disabled: false,
},
],
removeOption: isSingleIncidentResponseAction ? false : true,
};

return responseActionSection;
Expand Down
Loading
Loading