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

Extend educational material summary #2017

Merged
merged 16 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>Total:</strong> {{ summary }} <br>
</ng-container>
<ng-container *ngIf="avgSummary">
<strong>Average:</strong> {{ avgSummary }} <br>
</ng-container>
sleidig marked this conversation as resolved.
Show resolved Hide resolved
</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", () => {
setRecordsAndGenerateSummary(
{ materialType: PENCIL, materialAmount: 1 },
{ materialType: RULER, materialAmount: 1 },
{ materialType: PENCIL, materialAmount: 3 },
component.summaries =[{total: true, average: false}],
);

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", () => {
setRecordsAndGenerateSummary(
{ materialType: PENCIL, materialAmount: 1 },
{ materialType: RULER, materialAmount: 1 },
{ materialType: PENCIL, materialAmount: 3 },
component.summaries =[{total: false, average: true}],
);

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", () => {
setRecordsAndGenerateSummary(
{ materialType: PENCIL, materialAmount: 1 },
{ materialType: RULER, materialAmount: 1 },
{ materialType: PENCIL, materialAmount: 3 },
component.summaries =[{total: false, average: false}],
);

expect(component.summary).toEqual(``);
expect(component.avgSummary).toEqual(``);
});

it("produces summary of all records when both average and total are true", () => {
setRecordsAndGenerateSummary(
{ materialType: PENCIL, materialAmount: 1 },
{ materialType: RULER, materialAmount: 1 },
{ materialType: PENCIL, materialAmount: 3 },
component.summaries =[{total: true, average: true}],
);

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: any[];
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[0]?.total=== true) {
const summaryArray = Array.from(summary.entries(), ([label, { sum }]) => `${label}: ${sum}`);
this.summary = summaryArray.join(", ");
}

if(this.summaries[0]?.average=== true) {
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(", ");
}
}
}
12 changes: 10 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,16 @@ export const defaultJsonConfig = {
"components": [
{
"title": "",
"component": "EducationalMaterial"
}
"component": "EducationalMaterial",
"config": {
"summaries": [
{
total: true,
average: true,
}
]
sleidig marked this conversation as resolved.
Show resolved Hide resolved
}
}
]
},
{
Expand Down