+
inventory_2
-
-
+
+
person{{ bucketDataPoint.getCount() }}
-
+
}
} @else {
-
-
do_not_disturb
-
Not moved by any students
+
+ do_not_disturb
+ Not moved by any students
}
-
Bucket Frequency
-
- @if (choiceData.length > 0) {
+
Choice Frequency
+ @if (choiceData.length > 0) {
+
Number of times each item crop_16_9 was moved
into the different buckets inventory_2.
+
+ Organize by:
+
+
+ crop_16_9
+ Item
+
+
+ inventory_2
+ Bucket
+
+
+
+
+
- @for (choice of choiceData; track $index) {
-
-
-
+ @if (viewMode === 'choice') {
+ @for (choice of choiceData; track $index) {
+
+
+
+ }
+ } @else {
+ @for (bucket of bucketData; track $index) {
+
+
+
+ }
}
- } @else {
-
- Your students' choices will show up here when they complete the activity.
-
- }
-
+
+ } @else {
+
+ Your students' choices will show up here when they complete the activity.
+
+ }
diff --git a/src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.scss b/src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.scss
index 9fd95b7f60d..63daaa2cf85 100644
--- a/src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.scss
+++ b/src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.scss
@@ -1,16 +1,24 @@
@reference "tailwindcss";
+:host {
+ --mat-button-toggle-divider-color: transparent;
+ --mat-button-toggle-height: 32px;
+ .mat-button-toggle-group-appearance-standard, .mat-button-toggle-appearance-standard {
+ @apply rounded-md;
+ }
+}
+
h3,
.mat-subtitle-1 {
margin-bottom: 8px;
margin-top: 0;
}
-.choice {
+.choice-card, .bucket-card {
@apply p-2 mb-2 rounded-md;
}
-.bucket {
+.choice-row, .bucket-row {
@apply flex gap-1 px-2 py-1 mt-1 rounded-md bg-white border border-neutral-200 text-sm items-start justify-between;
}
diff --git a/src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.spec.ts b/src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.spec.ts
index 69a031f0963..a14b1085961 100644
--- a/src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.spec.ts
+++ b/src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.spec.ts
@@ -51,40 +51,66 @@ describe('MatchSummaryDisplayComponent', () => {
expect(component).toBeTruthy();
});
- it('should display one card per unique choice', () => {
- expect(fixtureQueryAll(fixture, '.choice').length).toEqual(5);
- });
+ describe('Choice view', () => {
+ it('should display one card per unique choice', () => {
+ expect(fixtureQueryAll(fixture, '.choice-card').length).toEqual(5);
+ });
- it('should order choices by total count descending then alphabetically', () => {
- const cards = fixtureQueryAll(fixture, '.choice');
- const labels = Array.from(cards).map((el) => el.querySelector('h3')?.textContent?.trim());
- expect(labels[0]).toContain('Choice B');
- expect(labels[1]).toContain('Choice D');
- expect(labels[2]).toContain('Choice C');
- expect(labels[3]).toContain('Choice E');
- expect(labels[4]).toContain('Choice A');
- });
+ it('should order choices by total count descending then alphabetically', () => {
+ const cards = fixtureQueryAll(fixture, '.choice-card');
+ const labels = Array.from(cards).map((el) => el.querySelector('h3')?.textContent?.trim());
+ expect(labels[0]).toContain('Choice B');
+ expect(labels[1]).toContain('Choice D');
+ expect(labels[2]).toContain('Choice C');
+ expect(labels[3]).toContain('Choice E');
+ expect(labels[4]).toContain('Choice A');
+ });
- it('should show bucket rows sorted by count within each choice', () => {
- const cards = fixtureQueryAll(fixture, '.choice');
- const choiceDCard = cards[1];
- const bucketRows = choiceDCard.querySelectorAll('.bucket');
- expect(bucketRows.length).toEqual(2);
- expect(bucketRows[0].textContent).toContain('Bucket 2');
- expect(bucketRows[0].textContent).toContain('2');
- });
+ it('should show bucket rows sorted by count within each choice', () => {
+ const cards = fixtureQueryAll(fixture, '.choice-card');
+ const choiceDCard = cards[1];
+ const bucketRows = choiceDCard.querySelectorAll('.bucket-row');
+ expect(bucketRows.length).toEqual(2);
+ expect(bucketRows[0].textContent).toContain('Bucket 2');
+ expect(bucketRows[0].textContent).toContain('2');
+ });
+
+ it('should show the correct count for Choice B in Bucket 1', () => {
+ const cards = fixtureQueryAll(fixture, '.choice-card');
+ const choiceBCard = cards[0];
+ expect(choiceBCard.textContent).toContain('3');
+ });
- it('should show the correct count for Choice B in Bucket 1', () => {
- const cards = fixtureQueryAll(fixture, '.choice');
- const choiceBCard = cards[0];
- expect(choiceBCard.textContent).toContain('3');
+ it('should show "Not moved by any students" for choices left in the source bucket', () => {
+ const cards = fixtureQueryAll(fixture, '.choice-card');
+ const choiceACard = cards[4];
+ expect(choiceACard.textContent).toContain('Not moved by any students');
+ expect(choiceACard.querySelectorAll('.bucket-row').length).toEqual(1);
+ });
});
- it('should show "Not moved by any students" for choices left in the source bucket', () => {
- const cards = fixtureQueryAll(fixture, '.choice');
- const choiceACard = cards[4];
- expect(choiceACard.textContent).toContain('Not moved by any students');
- expect(choiceACard.querySelectorAll('.bucket').length).toEqual(1);
+ describe('Bucket view', () => {
+ beforeEach(() => {
+ component.viewMode = 'bucket';
+ fixture.detectChanges();
+ });
+
+ it('should display one card per unique non-source bucket', () => {
+ expect(fixtureQueryAll(fixture, '.bucket-card').length).toBe(2);
+ });
+
+ it('should show choices sorted by count within each bucket', () => {
+ const cards = fixtureQueryAll(fixture, '.bucket-card');
+ const bucket1Card = cards[0];
+ const choiceRows = bucket1Card.querySelectorAll('.choice-row');
+ expect(choiceRows.length).toBe(3);
+ expect(choiceRows[0].textContent).toContain('Choice B');
+ expect(choiceRows[0].textContent).toContain('3');
+ expect(choiceRows[1].textContent).toContain('Choice C');
+ expect(choiceRows[1].textContent).toContain('2');
+ expect(choiceRows[2].textContent).toContain('Choice D');
+ expect(choiceRows[2].textContent).toContain('1');
+ });
});
});
diff --git a/src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.ts b/src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.ts
index ddb2039f1de..0d36012a0df 100644
--- a/src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.ts
+++ b/src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.ts
@@ -1,12 +1,16 @@
import { CommonModule } from '@angular/common';
import { Component, Input, OnInit } from '@angular/core';
-import { ChoiceData, MatchSummaryData } from '../summary-data/MatchSummaryData';
+import { MatchContent } from '../../../components/match/MatchContent';
+import { BucketData, ChoiceData, MatchSummaryData } from '../summary-data/MatchSummaryData';
import { MatchSummaryDataPoint } from '../summary-data/MatchSummaryDataPoint';
+import { MatButtonToggleModule } from '@angular/material/button-toggle';
import { MatIconModule } from '@angular/material/icon';
import { TeacherSummaryDisplayComponent } from '../teacher-summary-display.component';
+export type SummaryViewMode = 'choice' | 'bucket';
+
@Component({
- imports: [CommonModule, MatIconModule],
+ imports: [CommonModule, MatButtonToggleModule, MatIconModule],
selector: 'match-summary-display',
styleUrls: [
'./match-summary-display.component.scss',
@@ -15,21 +19,33 @@ import { TeacherSummaryDisplayComponent } from '../teacher-summary-display.compo
templateUrl: './match-summary-display.component.html'
})
export class MatchSummaryDisplayComponent extends TeacherSummaryDisplayComponent implements OnInit {
+ protected bucketData: { value: string; choices: MatchSummaryDataPoint[] }[] = [];
protected choiceData: ChoiceData[] = [];
@Input() expanded: boolean;
+ protected isChoiceReuseMatch: boolean;
private matchSummaryData: MatchSummaryData;
+ viewMode: SummaryViewMode = 'choice';
ngOnInit(): void {
+ this.setIsChoiceReuseMatch();
this.generateSummary();
}
+ private setIsChoiceReuseMatch(): void {
+ this.isChoiceReuseMatch = (
+ this.projectService.getComponent(this.nodeId, this.componentId) as MatchContent
+ ).choiceReuseEnabled;
+ }
+
private generateSummary(): void {
this.getLatestWork().subscribe((componentStates) => {
+ this.bucketData = [];
this.choiceData = [];
this.matchSummaryData = new MatchSummaryData(
this.projectService.injectAssetPaths(componentStates)
);
this.setChoiceData();
+ this.setBucketData();
});
}
@@ -37,7 +53,7 @@ export class MatchSummaryDisplayComponent extends TeacherSummaryDisplayComponent
this.matchSummaryData.getChoicesData().forEach((choice) => {
this.choiceData.push({
choiceValue: choice.choiceValue,
- choiceDataPoints: choice.choiceDataPoints.sort(this.sortBuckets)
+ choiceDataPoints: choice.choiceDataPoints.sort(this.sortByCount)
});
});
this.choiceData.sort(this.sortChoices);
@@ -52,7 +68,16 @@ export class MatchSummaryDisplayComponent extends TeacherSummaryDisplayComponent
return countDiff !== 0 ? countDiff : a.choiceValue.localeCompare(b.choiceValue);
};
- private sortBuckets(a: MatchSummaryDataPoint, b: MatchSummaryDataPoint): number {
+ protected setBucketData(): void {
+ this.matchSummaryData.getBucketsData().forEach((bucket: BucketData) => {
+ this.bucketData.push({
+ value: bucket.bucketValue,
+ choices: bucket.bucketDataPoints.sort(this.sortByCount)
+ });
+ });
+ }
+
+ private sortByCount(a: MatchSummaryDataPoint, b: MatchSummaryDataPoint): number {
return b.getCount() - a.getCount();
}
diff --git a/src/assets/wise5/directives/teacher-summary-display/summary-data/MatchSummaryData.ts b/src/assets/wise5/directives/teacher-summary-display/summary-data/MatchSummaryData.ts
index 46c6c122c79..be1050073cc 100644
--- a/src/assets/wise5/directives/teacher-summary-display/summary-data/MatchSummaryData.ts
+++ b/src/assets/wise5/directives/teacher-summary-display/summary-data/MatchSummaryData.ts
@@ -3,6 +3,7 @@ import { MatchSummaryDataPoint } from './MatchSummaryDataPoint';
import { SummaryData } from '../../summary-display/summary-data/SummaryData';
export type ChoiceData = { choiceValue: string; choiceDataPoints: MatchSummaryDataPoint[] };
+export type BucketData = { bucketValue: string; bucketDataPoints: MatchSummaryDataPoint[] };
/**
* Summary data for all choices, each with a breakdown per bucket
@@ -19,14 +20,34 @@ export class MatchSummaryData extends SummaryData {
return this.choicesData;
}
+ getBucketsData(): BucketData[] {
+ const bucketsMap = new Map
();
+ this.choicesData.forEach((choice) => {
+ choice.choiceDataPoints.forEach((point) => {
+ const bucketValue = point.getBucketValue();
+ if (!bucketsMap.has(bucketValue)) {
+ bucketsMap.set(bucketValue, { bucketValue, bucketDataPoints: [] });
+ }
+ bucketsMap.get(bucketValue).bucketDataPoints.push(point);
+ });
+ });
+ return Array.from(bucketsMap.values()).sort(
+ (a, b) => this.getTotalCount(b) - this.getTotalCount(a)
+ );
+ }
+
+ private getTotalCount(bucket: BucketData): number {
+ return bucket.bucketDataPoints.reduce((sum, point) => sum + point.getCount(), 0);
+ }
+
private extractChoiceData(componentStates: ComponentState[]): void {
componentStates.forEach((componentState) => {
componentState.studentData.buckets.forEach((bucketStudentData, index) => {
if (index === 0) {
- bucketStudentData.items.forEach((item) => this.registerChoice(item.value));
+ bucketStudentData.items.forEach((choice) => this.registerChoice(choice.value));
} else {
- bucketStudentData.items.forEach((item) => {
- this.extractBucketDataPerChoice(item.value, bucketStudentData.value);
+ bucketStudentData.items.forEach((choice) => {
+ this.extractBucketDataPerChoice(choice.value, bucketStudentData.value);
});
}
});
diff --git a/src/messages.xlf b/src/messages.xlf
index 33e39bf173f..7a72054bf24 100644
--- a/src/messages.xlf
+++ b/src/messages.xlf
@@ -16263,7 +16263,15 @@ Are you sure you want to proceed?
src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.html
- 4,5
+ 11,14
+
+
+ src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.html
+ 33,34
+
+
+ src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.html
+ 81,83
@@ -23256,42 +23264,71 @@ If this problem continues, let your teacher know and move on to the next activit
Bucket
src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.html
- 12,15
+ 4,5
-
-
- Not moved
src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.html
- 26,27
+ 41,44
+
+
+ src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.html
+ 85,88
Not moved by any students
src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.html
- 27,33
+ 56,62
-
- Bucket Frequency
+
+ Choice Frequency
src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.html
- 34,35
+ 63,65
Number of times each item crop_16_9 was moved into the different buckets inventory_2.
src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.html
- 38,41
+ 67,70
+
+
+
+ Organize by:
+
+ src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.html
+ 71,73
+
+
+
+ Organize by
+
+ src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.html
+ 76,79
+
+
+
+ Organize by choice
+
+ src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.html
+ 79,80
+
+
+
+ Organize by bucket
+
+ src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.html
+ 83,84
Your students' choices will show up here when they complete the activity.
src/assets/wise5/directives/teacher-summary-display/match-summary-display/match-summary-display.component.html
- 53,58
+ 115,119