Skip to content

Commit

Permalink
feat: educational material summary can show averages (#2017)
Browse files Browse the repository at this point in the history
see #2004 

---------

Co-authored-by: Sebastian <sebastian@aam-digital.com>
  • Loading branch information
brajesh-lab and sleidig authored Oct 12, 2023
1 parent cc92709 commit d00ce3a
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
>
</app-entity-subrecord>

<div
class="margin-top-large"
i18n="Total amount|Total amount of education material including a summary"
>
Total: {{ summary }}
<div class="margin-top-large">
<ng-container *ngIf="summary">
<strong i18n>Total:</strong> {{ summary }} <br>
</ng-container>
<ng-container *ngIf="avgSummary">
<strong i18n>Average:</strong> {{ avgSummary }} <br>
</ng-container>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ describe("EducationalMaterialComponent", () => {
fixture = TestBed.createComponent(EducationalMaterialComponent);
component = fixture.componentInstance;
component.entity = child;
component.summaries = {total: true, average: true};
fixture.detectChanges();
});

Expand All @@ -46,6 +47,7 @@ describe("EducationalMaterialComponent", () => {
component.records = [];
component.updateSummary();
expect(component.summary).toHaveSize(0);
expect(component.avgSummary).toHaveSize(0);
});

function setRecordsAndGenerateSummary(
Expand All @@ -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", () => {
Expand All @@ -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", () => {
Expand All @@ -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 () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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: [
Expand Down Expand Up @@ -83,15 +90,32 @@ export class EducationalMaterialComponent implements OnInit {
* human-readable format
*/
updateSummary() {
const summary = new Map<string, number>();
const summary = new Map<string, { count: number; sum: number }>();
const average = new Map<string, number>();

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(", ");
}
}
}
10 changes: 8 additions & 2 deletions src/app/core/config/config-fix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -712,8 +712,14 @@ export const defaultJsonConfig = {
"components": [
{
"title": "",
"component": "EducationalMaterial"
}
"component": "EducationalMaterial",
"config": {
"summaries": {
total: true,
average: true,
}
}
}
]
},
{
Expand Down

0 comments on commit d00ce3a

Please sign in to comment.