diff --git a/src/app/child-dev-project/children/educational-material/educational-material-component/educational-material.component.html b/src/app/child-dev-project/children/educational-material/educational-material-component/educational-material.component.html
index 289052eca4..abfd833c5c 100644
--- a/src/app/child-dev-project/children/educational-material/educational-material-component/educational-material.component.html
+++ b/src/app/child-dev-project/children/educational-material/educational-material-component/educational-material.component.html
@@ -5,9 +5,11 @@
>
-
- Total: {{ summary }}
+
+
+ Total: {{ summary }}
+
+
+ Average: {{ avgSummary }}
+
diff --git a/src/app/child-dev-project/children/educational-material/educational-material-component/educational-material.component.spec.ts b/src/app/child-dev-project/children/educational-material/educational-material-component/educational-material.component.spec.ts
index 2e8e639b56..9068e33c8e 100644
--- a/src/app/child-dev-project/children/educational-material/educational-material-component/educational-material.component.spec.ts
+++ b/src/app/child-dev-project/children/educational-material/educational-material-component/educational-material.component.spec.ts
@@ -35,6 +35,7 @@ describe("EducationalMaterialComponent", () => {
fixture = TestBed.createComponent(EducationalMaterialComponent);
component = fixture.componentInstance;
component.entity = child;
+ component.summaries = {total: true, average: true};
fixture.detectChanges();
});
@@ -46,6 +47,7 @@ describe("EducationalMaterialComponent", () => {
component.records = [];
component.updateSummary();
expect(component.summary).toHaveSize(0);
+ expect(component.avgSummary).toHaveSize(0);
});
function setRecordsAndGenerateSummary(
@@ -58,6 +60,7 @@ describe("EducationalMaterialComponent", () => {
it("produces a singleton summary when there is a single record", () => {
setRecordsAndGenerateSummary({ materialType: PENCIL, materialAmount: 1 });
expect(component.summary).toEqual(`${PENCIL.label}: 1`);
+ expect(component.avgSummary).toEqual(`${PENCIL.label}: 1`);
});
it("produces a summary of all records when they are all different", () => {
@@ -66,6 +69,7 @@ describe("EducationalMaterialComponent", () => {
{ materialType: RULER, materialAmount: 1 },
);
expect(component.summary).toEqual(`${PENCIL.label}: 2, ${RULER.label}: 1`);
+ expect(component.avgSummary).toEqual(`${PENCIL.label}: 2, ${RULER.label}: 1`);
});
it("produces a summary of all records when there are duplicates", () => {
@@ -74,7 +78,57 @@ describe("EducationalMaterialComponent", () => {
{ materialType: RULER, materialAmount: 1 },
{ materialType: PENCIL, materialAmount: 3 },
);
+
+ expect(component.summary).toEqual(`${PENCIL.label}: 4, ${RULER.label}: 1`);
+ expect(component.avgSummary).toEqual(`${PENCIL.label}: 2, ${RULER.label}: 1`);
+ });
+
+ it("produces summary of all records when average is false and total is true", () => {
+ component.summaries = { total: true, average: false }
+ setRecordsAndGenerateSummary(
+ { materialType: PENCIL, materialAmount: 1 },
+ { materialType: RULER, materialAmount: 1 },
+ { materialType: PENCIL, materialAmount: 3 },
+ );
+
+ expect(component.summary).toEqual(`${PENCIL.label}: 4, ${RULER.label}: 1`);
+ expect(component.avgSummary).toEqual(``);
+ });
+
+ it("produces summary of all records when average is true and total is false", () => {
+ component.summaries = { total: false, average: true };
+ setRecordsAndGenerateSummary(
+ { materialType: PENCIL, materialAmount: 1 },
+ { materialType: RULER, materialAmount: 1 },
+ { materialType: PENCIL, materialAmount: 3 },
+ );
+
+ expect(component.summary).toEqual(``);
+ expect(component.avgSummary).toEqual(`${PENCIL.label}: 2, ${RULER.label}: 1`);
+ });
+
+ it("does not produces summary of all records when both average and total are false", () => {
+ component.summaries = { total: false, average: false };
+ setRecordsAndGenerateSummary(
+ { materialType: PENCIL, materialAmount: 1 },
+ { materialType: RULER, materialAmount: 1 },
+ { materialType: PENCIL, materialAmount: 3 },
+ );
+
+ expect(component.summary).toEqual(``);
+ expect(component.avgSummary).toEqual(``);
+ });
+
+ it("produces summary of all records when both average and total are true", () => {
+ component.summaries = { total: true, average: true };
+ setRecordsAndGenerateSummary(
+ { materialType: PENCIL, materialAmount: 1 },
+ { materialType: RULER, materialAmount: 1 },
+ { materialType: PENCIL, materialAmount: 3 },
+ );
+
expect(component.summary).toEqual(`${PENCIL.label}: 4, ${RULER.label}: 1`);
+ expect(component.avgSummary).toEqual(`${PENCIL.label}: 2, ${RULER.label}: 1`);
});
it("loads all education data associated with a child and updates the summary", async () => {
diff --git a/src/app/child-dev-project/children/educational-material/educational-material-component/educational-material.component.ts b/src/app/child-dev-project/children/educational-material/educational-material-component/educational-material.component.ts
index feba170e3e..5a065632c3 100644
--- a/src/app/child-dev-project/children/educational-material/educational-material-component/educational-material.component.ts
+++ b/src/app/child-dev-project/children/educational-material/educational-material-component/educational-material.component.ts
@@ -1,4 +1,5 @@
import { Component, Input, OnInit } from "@angular/core";
+import { NgFor, NgIf } from "@angular/common";
import { EducationalMaterial } from "../model/educational-material";
import { Child } from "../../model/child";
import { FormFieldConfig } from "../../../../core/common-components/entity-form/entity-form/FormConfig";
@@ -18,13 +19,19 @@ import { EntitySubrecordComponent } from "../../../../core/common-components/ent
@Component({
selector: "app-educational-material",
templateUrl: "./educational-material.component.html",
- imports: [EntitySubrecordComponent],
+ imports: [
+ EntitySubrecordComponent,
+ NgIf,
+ NgFor
+ ],
standalone: true,
})
export class EducationalMaterialComponent implements OnInit {
@Input() entity: Child;
+ @Input() summaries: { total?: boolean; average?: boolean } = { total: true };
records: EducationalMaterial[] = [];
summary = "";
+ avgSummary = "";
@Input() config: { columns: FormFieldConfig[] } = {
columns: [
@@ -83,15 +90,32 @@ export class EducationalMaterialComponent implements OnInit {
* human-readable format
*/
updateSummary() {
- const summary = new Map
();
+ const summary = new Map();
+ const average = new Map();
+
this.records.forEach((m) => {
- const previousValue = summary.has(m.materialType.label)
- ? summary.get(m.materialType.label)
- : 0;
- summary.set(m.materialType.label, previousValue + m.materialAmount);
+ const { materialType, materialAmount } = m;
+ const label = materialType?.label;
+
+ if (label) {
+ summary.set(label, (summary.get(label) || { count: 0, sum: 0 }));
+ summary.get(label)!.count++;
+ summary.get(label)!.sum += materialAmount;
+ }
});
- this.summary = [...summary]
- .map(([key, value]) => key + ": " + value)
- .join(", ");
+
+ if(this.summaries.total) {
+ const summaryArray = Array.from(summary.entries(), ([label, { sum }]) => `${label}: ${sum}`);
+ this.summary = summaryArray.join(", ");
+ }
+
+ if(this.summaries.average) {
+ const avgSummaryArray = Array.from(summary.entries(), ([label, { count, sum }]) => {
+ const avg = parseFloat((sum / count).toFixed(2));
+ average.set(label, avg);
+ return `${label}: ${avg}`;
+ });
+ this.avgSummary = avgSummaryArray.join(", ");
+ }
}
}
diff --git a/src/app/core/config/config-fix.ts b/src/app/core/config/config-fix.ts
index b179821a6d..afdb7f9881 100644
--- a/src/app/core/config/config-fix.ts
+++ b/src/app/core/config/config-fix.ts
@@ -712,8 +712,14 @@ export const defaultJsonConfig = {
"components": [
{
"title": "",
- "component": "EducationalMaterial"
- }
+ "component": "EducationalMaterial",
+ "config": {
+ "summaries": {
+ total: true,
+ average: true,
+ }
+ }
+ }
]
},
{