diff --git a/src/assets/wise5/common/ComponentContent.ts b/src/assets/wise5/common/ComponentContent.ts index a9b7e3789b9..c9f3fd6ea3d 100644 --- a/src/assets/wise5/common/ComponentContent.ts +++ b/src/assets/wise5/common/ComponentContent.ts @@ -4,6 +4,7 @@ import { DynamicPrompt } from '../directives/dynamic-prompt/DynamicPrompt'; export interface ComponentContent { id: string; + anonymizeResponses?: boolean; connectedComponents?: any[]; constraints?: any[]; cRaterRubric?: CRaterRubric; diff --git a/src/assets/wise5/components/discussion/Anonymizer.spec.ts b/src/assets/wise5/components/discussion/Anonymizer.spec.ts new file mode 100644 index 00000000000..a12118e4d38 --- /dev/null +++ b/src/assets/wise5/components/discussion/Anonymizer.spec.ts @@ -0,0 +1,55 @@ +import { Anonymizer } from './Anonymizer'; + +describe('Anonymizer', () => { + it('should assign a valid anonymous name based on the index of the provided id', () => { + const ids = [100, 200, 300]; + + const anonymizer100 = new Anonymizer(100, ids); + // Since 100 is at index 0, it should be mapped to the first animal (Tiger) + expect(anonymizer100.getName()).toEqual('Anonymous Tiger'); + + const anonymizer200 = new Anonymizer(200, ids); + // 200 is at index 1 -> Lion + expect(anonymizer200.getName()).toEqual('Anonymous Lion'); + + const anonymizer300 = new Anonymizer(300, ids); + // 300 is at index 2 -> Fox + expect(anonymizer300.getName()).toEqual('Anonymous Fox'); + }); + + it('should append numeric suffixes when the number of ids exceeds the available name options (86)', () => { + // There are 86 predefined internal names, so we create 87 ids to trigger the suffix logic. + const manyIds = Array.from({ length: 87 }, (_, i) => i); + + // The very first user (index 0) will now be "Tiger 1" instead of "Tiger" + const firstAnonymizer = new Anonymizer(0, manyIds); + expect(firstAnonymizer.getName()).toEqual('Anonymous Tiger 1'); + + // The 86th user (index 85, the last of the first batch) will be "Yeti 1" + const endOfFirstBatch = new Anonymizer(85, manyIds); + expect(endOfFirstBatch.getName()).toEqual('Anonymous Yeti 1'); + + // The 87th user (index 86) overflows into the second batch and becomes "Tiger 2" + const overflowAnonymizer = new Anonymizer(86, manyIds); + expect(overflowAnonymizer.getName()).toEqual('Anonymous Tiger 2'); + }); + + it('should append higher numeric suffixes dynamically if ids continue to increase vastly', () => { + // Let's create an array of 200 ids (which will overflow into the 3rd batch since 86 * 2 = 172) + const massiveIds = Array.from({ length: 200 }, (_, i) => i); + + // Index 171 is the end of the second batch (Yeti 2) + const endOfSecondBatch = new Anonymizer(171, massiveIds); + expect(endOfSecondBatch.getName()).toEqual('Anonymous Yeti 2'); + + // Index 172 starts the third batch (Tiger 3) + const startOfThirdBatch = new Anonymizer(172, massiveIds); + expect(startOfThirdBatch.getName()).toEqual('Anonymous Tiger 3'); + }); + + it('should support a custom prefix name', () => { + const ids = [10, 20]; + const anonymizer = new Anonymizer(10, ids); + expect(anonymizer.getName('Participant')).toEqual('Participant Tiger'); + }); +}); diff --git a/src/assets/wise5/components/discussion/Anonymizer.ts b/src/assets/wise5/components/discussion/Anonymizer.ts new file mode 100644 index 00000000000..397a224fb44 --- /dev/null +++ b/src/assets/wise5/components/discussion/Anonymizer.ts @@ -0,0 +1,113 @@ +/** + * Generates an anonymous student name using a list of predefined names. + * Maps a specific ID against a list of IDs to consistently assign a name based on its index. + * If the number of IDs exceeds the available names, numeric suffixes are appended (e.g., "Student Tiger 1", "Student Tiger 2"). + */ +export class Anonymizer { + private nameOptions = [ + $localize`Tiger`, + $localize`Lion`, + $localize`Fox`, + $localize`Owl`, + $localize`Panda`, + $localize`Hawk`, + $localize`Mole`, + $localize`Falcon`, + $localize`Orca`, + $localize`Eagle`, + $localize`Manta`, + $localize`Otter`, + $localize`Cat`, + $localize`Zebra`, + $localize`Flea`, + $localize`Wolf`, + $localize`Dragon`, + $localize`Seal`, + $localize`Cobra`, + $localize`Bug`, + $localize`Gecko`, + $localize`Fish`, + $localize`Koala`, + $localize`Mouse`, + $localize`Wombat`, + $localize`Shark`, + $localize`Whale`, + $localize`Sloth`, + $localize`Slug`, + $localize`Ant`, + $localize`Mantis`, + $localize`Bat`, + $localize`Rhino`, + $localize`Gator`, + $localize`Monkey`, + $localize`Swan`, + $localize`Ray`, + $localize`Crow`, + $localize`Goat`, + $localize`Marmot`, + $localize`Dog`, + $localize`Finch`, + $localize`Puffin`, + $localize`Fly`, + $localize`Camel`, + $localize`Kiwi`, + $localize`Spider`, + $localize`Lizard`, + $localize`Robin`, + $localize`Bear`, + $localize`Boa`, + $localize`Cow`, + $localize`Crab`, + $localize`Mule`, + $localize`Moth`, + $localize`Lynx`, + $localize`Moose`, + $localize`Skunk`, + $localize`Mako`, + $localize`Liger`, + $localize`Llama`, + $localize`Shrimp`, + $localize`Parrot`, + $localize`Pig`, + $localize`Clam`, + $localize`Urchin`, + $localize`Toucan`, + $localize`Frog`, + $localize`Toad`, + $localize`Turtle`, + $localize`Viper`, + $localize`Trout`, + $localize`Hare`, + $localize`Bee`, + $localize`Krill`, + $localize`Dodo`, + $localize`Tuna`, + $localize`Loon`, + $localize`Leech`, + $localize`Python`, + $localize`Wasp`, + $localize`Yak`, + $localize`Snake`, + $localize`Duck`, + $localize`Worm`, + $localize`Yeti` + ]; + + constructor( + private id: number, + private ids: number[] + ) {} + + getName(prefix: string = $localize`Anonymous`): string { + let names = this.nameOptions; + if (this.ids.length > this.nameOptions.length) { + names = this.nameOptions.map((name) => name + ' ' + 1); + let i = 2; + while (this.ids.length > names.length) { + names = names.concat(this.nameOptions.map((name) => name + ' ' + i)); + i++; + } + } + return `${prefix} ${names.at(this.ids.indexOf(this.id))}`; + } +} diff --git a/src/assets/wise5/components/discussion/DiscussionInfo.ts b/src/assets/wise5/components/discussion/DiscussionInfo.ts index add74f7d8cf..44a2389ad45 100644 --- a/src/assets/wise5/components/discussion/DiscussionInfo.ts +++ b/src/assets/wise5/components/discussion/DiscussionInfo.ts @@ -15,6 +15,7 @@ export class DiscussionInfo extends ComponentInfo { showSubmitButton: false, isStudentAttachmentEnabled: true, gateClassmateResponses: true, + anonymizeResponses: false, constraints: [] } } diff --git a/src/assets/wise5/components/discussion/discussion-authoring/discussion-authoring.component.html b/src/assets/wise5/components/discussion/discussion-authoring/discussion-authoring.component.html index a5d926973be..08ced33e1a0 100644 --- a/src/assets/wise5/components/discussion/discussion-authoring/discussion-authoring.component.html +++ b/src/assets/wise5/components/discussion/discussion-authoring/discussion-authoring.component.html @@ -18,3 +18,11 @@ > Students must create a post before viewing classmates' posts + + Anonymize (students cannot see classmates' names) + diff --git a/src/assets/wise5/components/discussion/discussion-show-work/discussion-show-work.component.ts b/src/assets/wise5/components/discussion/discussion-show-work/discussion-show-work.component.ts index 0bdf1f23b15..95c4c34387e 100644 --- a/src/assets/wise5/components/discussion/discussion-show-work/discussion-show-work.component.ts +++ b/src/assets/wise5/components/discussion/discussion-show-work/discussion-show-work.component.ts @@ -78,6 +78,7 @@ export class DiscussionShowWorkComponent extends ComponentShowWorkDirective { const classResponses = this.discussionService.getClassResponses( componentStates, annotations, + this.workgroupId, isStudentMode ); const isGradingMode = true; diff --git a/src/assets/wise5/components/discussion/discussion-student/discussion-student.component.ts b/src/assets/wise5/components/discussion/discussion-student/discussion-student.component.ts index a20b8b6bf31..22f20baac00 100644 --- a/src/assets/wise5/components/discussion/discussion-student/discussion-student.component.ts +++ b/src/assets/wise5/components/discussion/discussion-student/discussion-student.component.ts @@ -457,12 +457,18 @@ export class DiscussionStudent extends ComponentStudent { return this.componentContent.gateClassmateResponses; } + protected isAnonymizeResponses(): boolean { + return this.componentContent.anonymizeResponses; + } + setClassResponses(componentStates: any[], annotations: any[] = []): void { const isStudentMode = true; this.classResponses = this.discussionService.getClassResponses( componentStates, annotations, - isStudentMode + this.workgroupId, + isStudentMode, + this.isAnonymizeResponses() ); this.responsesMap = this.discussionService.getResponsesMap(this.classResponses); this.topLevelResponses = this.discussionService.getLevel1Responses( @@ -475,7 +481,11 @@ export class DiscussionStudent extends ComponentStudent { addClassResponse(componentState: any): void { if (componentState.studentData.isSubmit) { - this.discussionService.setUsernames(componentState); + this.discussionService.setUsernames( + componentState, + this.workgroupId, + this.isAnonymizeResponses() + ); componentState.replies = []; this.classResponses.push(componentState); this.addResponseToResponsesMap(this.responsesMap, componentState); diff --git a/src/assets/wise5/components/discussion/discussion-teacher/discussion-teacher.component.ts b/src/assets/wise5/components/discussion/discussion-teacher/discussion-teacher.component.ts index d503c0cb630..ffeccd8e3fc 100644 --- a/src/assets/wise5/components/discussion/discussion-teacher/discussion-teacher.component.ts +++ b/src/assets/wise5/components/discussion/discussion-teacher/discussion-teacher.component.ts @@ -33,6 +33,7 @@ import { DiscussionStudent } from '../discussion-student/discussion-student.comp }) export class DiscussionTeacherComponent extends DiscussionStudent { @Input() periodId: number; + @Input() anonymizeResponses: boolean; ngOnChanges(changes: SimpleChanges): void { if (changes.component) { @@ -55,4 +56,8 @@ export class DiscussionTeacherComponent extends DiscussionStudent { disableComponentIfNecessary(): void { // no need to disable the component for teacher } + + protected isAnonymizeResponses(): boolean { + return this.anonymizeResponses; + } } diff --git a/src/assets/wise5/components/discussion/discussionService.ts b/src/assets/wise5/components/discussion/discussionService.ts index 726ffc9f103..a4691ac14d0 100644 --- a/src/assets/wise5/components/discussion/discussionService.ts +++ b/src/assets/wise5/components/discussion/discussionService.ts @@ -5,6 +5,7 @@ import { HttpClient } from '@angular/common/http'; import { forkJoin, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { serverSaveTimeComparator } from '../../common/object/object'; +import { Anonymizer } from './Anonymizer'; @Injectable() export class DiscussionService extends ComponentService { @@ -25,6 +26,7 @@ export class DiscussionService extends ComponentService { component.prompt = ''; component.isStudentAttachmentEnabled = true; component.gateClassmateResponses = true; + component.anonymizeResponses = false; return component; } @@ -211,14 +213,16 @@ export class DiscussionService extends ComponentService { getClassResponses( componentStates: any[], annotations = [], - isStudentMode: boolean = false + myWorkgroupId: number, + isStudentMode: boolean = false, + anonymizeResponses: boolean = false ): any[] { const classResponses = []; componentStates = componentStates.sort(serverSaveTimeComparator); for (const componentState of componentStates) { if (componentState.studentData.isSubmit) { componentState.replies = []; - this.setUsernames(componentState); + this.setUsernames(componentState, myWorkgroupId, anonymizeResponses); const latestInappropriateFlagAnnotation = this.getLatestInappropriateFlagAnnotationByStudentWorkId(annotations, componentState.id); if (isStudentMode) { @@ -243,8 +247,16 @@ export class DiscussionService extends ComponentService { return annotation.data.action === 'Delete'; } - setUsernames(componentState: any): void { - const workgroupId = componentState.workgroupId; + setUsernames( + componentState: any, + myWorkgroupId: number, + anonymizeResponses: boolean = false + ): void { + const { workgroupId } = componentState; + if (anonymizeResponses && workgroupId !== myWorkgroupId) { + this.setAnonymousUsername(componentState); + return; + } const usernames = this.configService.getUsernamesByWorkgroupId(workgroupId); if (usernames.length > 0) { componentState.usernames = this.configService.getUsernamesStringByWorkgroupId(workgroupId); @@ -259,6 +271,16 @@ export class DiscussionService extends ComponentService { } } + private setAnonymousUsername(componentState: any): void { + const { workgroupId, periodId } = componentState; + const workgroupIds = this.configService + .getClassmateUserInfos() + .filter((userInfo) => userInfo.periodId === periodId) + .map((userInfo) => userInfo.workgroupId) + .concat(workgroupId); + componentState.usernames = new Anonymizer(workgroupId, workgroupIds).getName(); + } + getResponsesMap(componentStates: any[]): any { const responsesMap: any = {}; for (const componentState of componentStates) { diff --git a/src/assets/wise5/directives/teacher-summary-display/discussion-summary/discussion-summary.component.ts b/src/assets/wise5/directives/teacher-summary-display/discussion-summary/discussion-summary.component.ts index 47baa1d3ec7..d51f4afe846 100644 --- a/src/assets/wise5/directives/teacher-summary-display/discussion-summary/discussion-summary.component.ts +++ b/src/assets/wise5/directives/teacher-summary-display/discussion-summary/discussion-summary.component.ts @@ -1,35 +1,58 @@ import { CommonModule } from '@angular/common'; -import { Component, Input, OnInit } from '@angular/core'; +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Component as WISEComponent } from '../../../common/Component'; import { TeacherSummaryDisplayComponent } from '../teacher-summary-display.component'; import { ComponentFactory } from '../../../common/ComponentFactory'; import { DiscussionTeacherComponent } from '../../../components/discussion/discussion-teacher/discussion-teacher.component'; +import { MatSlideToggle } from '@angular/material/slide-toggle'; +import { FormsModule } from '@angular/forms'; @Component({ - imports: [CommonModule, DiscussionTeacherComponent], + imports: [CommonModule, DiscussionTeacherComponent, FormsModule, MatSlideToggle], selector: 'discussion-summary', styleUrl: '../../summary-display/summary-display.component.scss', template: `

Class Discussion

+
+ + Hide student names + + @if (component.content.anonymizeResponses) { + Note: Students do not see each other's names in this activity. + } +
` }) export class DiscussionSummaryComponent extends TeacherSummaryDisplayComponent implements OnInit { + @Input() anonymizeResponses: boolean; protected component: WISEComponent; @Input() expanded: boolean; + @Output() anonymizeResponsesChange = new EventEmitter(); ngOnInit(): void { let content = this.projectService.getComponent(this.nodeId, this.componentId); content = this.projectService.injectAssetPaths(content); this.component = new ComponentFactory().getComponent(content, this.nodeId); } + + protected anonymizeResponsesChanged() { + this.anonymizeResponsesChange.emit(this.anonymizeResponses); + } } diff --git a/src/messages.xlf b/src/messages.xlf index be1317b7438..cba0709afeb 100644 --- a/src/messages.xlf +++ b/src/messages.xlf @@ -18126,6 +18126,615 @@ Category Name: 97,100 + + Tiger + + src/assets/wise5/components/discussion/Anonymizer.ts + 8 + + + + Lion + + src/assets/wise5/components/discussion/Anonymizer.ts + 9 + + + + Fox + + src/assets/wise5/components/discussion/Anonymizer.ts + 10 + + + + Owl + + src/assets/wise5/components/discussion/Anonymizer.ts + 11 + + + + Panda + + src/assets/wise5/components/discussion/Anonymizer.ts + 12 + + + + Hawk + + src/assets/wise5/components/discussion/Anonymizer.ts + 13 + + + + Mole + + src/assets/wise5/components/discussion/Anonymizer.ts + 14 + + + + Falcon + + src/assets/wise5/components/discussion/Anonymizer.ts + 15 + + + + Orca + + src/assets/wise5/components/discussion/Anonymizer.ts + 16 + + + + Eagle + + src/assets/wise5/components/discussion/Anonymizer.ts + 17 + + + + Manta + + src/assets/wise5/components/discussion/Anonymizer.ts + 18 + + + + Otter + + src/assets/wise5/components/discussion/Anonymizer.ts + 19 + + + + Cat + + src/assets/wise5/components/discussion/Anonymizer.ts + 20 + + + + Zebra + + src/assets/wise5/components/discussion/Anonymizer.ts + 21 + + + + Flea + + src/assets/wise5/components/discussion/Anonymizer.ts + 22 + + + + Wolf + + src/assets/wise5/components/discussion/Anonymizer.ts + 23 + + + + Dragon + + src/assets/wise5/components/discussion/Anonymizer.ts + 24 + + + + Seal + + src/assets/wise5/components/discussion/Anonymizer.ts + 25 + + + + Cobra + + src/assets/wise5/components/discussion/Anonymizer.ts + 26 + + + + Bug + + src/assets/wise5/components/discussion/Anonymizer.ts + 27 + + + + Gecko + + src/assets/wise5/components/discussion/Anonymizer.ts + 28 + + + + Fish + + src/assets/wise5/components/discussion/Anonymizer.ts + 29 + + + + Koala + + src/assets/wise5/components/discussion/Anonymizer.ts + 30 + + + + Mouse + + src/assets/wise5/components/discussion/Anonymizer.ts + 31 + + + + Wombat + + src/assets/wise5/components/discussion/Anonymizer.ts + 32 + + + + Shark + + src/assets/wise5/components/discussion/Anonymizer.ts + 33 + + + + Whale + + src/assets/wise5/components/discussion/Anonymizer.ts + 34 + + + + Sloth + + src/assets/wise5/components/discussion/Anonymizer.ts + 35 + + + + Slug + + src/assets/wise5/components/discussion/Anonymizer.ts + 36 + + + + Ant + + src/assets/wise5/components/discussion/Anonymizer.ts + 37 + + + + Mantis + + src/assets/wise5/components/discussion/Anonymizer.ts + 38 + + + + Bat + + src/assets/wise5/components/discussion/Anonymizer.ts + 39 + + + + Rhino + + src/assets/wise5/components/discussion/Anonymizer.ts + 40 + + + + Gator + + src/assets/wise5/components/discussion/Anonymizer.ts + 41 + + + + Monkey + + src/assets/wise5/components/discussion/Anonymizer.ts + 42 + + + + Swan + + src/assets/wise5/components/discussion/Anonymizer.ts + 43 + + + + Ray + + src/assets/wise5/components/discussion/Anonymizer.ts + 44 + + + + Crow + + src/assets/wise5/components/discussion/Anonymizer.ts + 45 + + + + Goat + + src/assets/wise5/components/discussion/Anonymizer.ts + 46 + + + + Marmot + + src/assets/wise5/components/discussion/Anonymizer.ts + 47 + + + + Dog + + src/assets/wise5/components/discussion/Anonymizer.ts + 48 + + + + Finch + + src/assets/wise5/components/discussion/Anonymizer.ts + 49 + + + + Puffin + + src/assets/wise5/components/discussion/Anonymizer.ts + 50 + + + + Fly + + src/assets/wise5/components/discussion/Anonymizer.ts + 51 + + + + Camel + + src/assets/wise5/components/discussion/Anonymizer.ts + 52 + + + + Kiwi + + src/assets/wise5/components/discussion/Anonymizer.ts + 53 + + + + Spider + + src/assets/wise5/components/discussion/Anonymizer.ts + 54 + + + + Lizard + + src/assets/wise5/components/discussion/Anonymizer.ts + 55 + + + + Robin + + src/assets/wise5/components/discussion/Anonymizer.ts + 56 + + + + Bear + + src/assets/wise5/components/discussion/Anonymizer.ts + 57 + + + + Boa + + src/assets/wise5/components/discussion/Anonymizer.ts + 58 + + + + Cow + + src/assets/wise5/components/discussion/Anonymizer.ts + 59 + + + + Crab + + src/assets/wise5/components/discussion/Anonymizer.ts + 60 + + + + Mule + + src/assets/wise5/components/discussion/Anonymizer.ts + 61 + + + + Moth + + src/assets/wise5/components/discussion/Anonymizer.ts + 62 + + + + Lynx + + src/assets/wise5/components/discussion/Anonymizer.ts + 63 + + + + Moose + + src/assets/wise5/components/discussion/Anonymizer.ts + 64 + + + + Skunk + + src/assets/wise5/components/discussion/Anonymizer.ts + 65 + + + + Mako + + src/assets/wise5/components/discussion/Anonymizer.ts + 66 + + + + Liger + + src/assets/wise5/components/discussion/Anonymizer.ts + 67 + + + + Llama + + src/assets/wise5/components/discussion/Anonymizer.ts + 68 + + + + Shrimp + + src/assets/wise5/components/discussion/Anonymizer.ts + 69 + + + + Parrot + + src/assets/wise5/components/discussion/Anonymizer.ts + 70 + + + + Pig + + src/assets/wise5/components/discussion/Anonymizer.ts + 71 + + + + Clam + + src/assets/wise5/components/discussion/Anonymizer.ts + 72 + + + + Urchin + + src/assets/wise5/components/discussion/Anonymizer.ts + 73 + + + + Toucan + + src/assets/wise5/components/discussion/Anonymizer.ts + 74 + + + + Frog + + src/assets/wise5/components/discussion/Anonymizer.ts + 75 + + + + Toad + + src/assets/wise5/components/discussion/Anonymizer.ts + 76 + + + + Turtle + + src/assets/wise5/components/discussion/Anonymizer.ts + 77 + + + + Viper + + src/assets/wise5/components/discussion/Anonymizer.ts + 78 + + + + Trout + + src/assets/wise5/components/discussion/Anonymizer.ts + 79 + + + + Hare + + src/assets/wise5/components/discussion/Anonymizer.ts + 80 + + + + Bee + + src/assets/wise5/components/discussion/Anonymizer.ts + 81 + + + + Krill + + src/assets/wise5/components/discussion/Anonymizer.ts + 82 + + + + Dodo + + src/assets/wise5/components/discussion/Anonymizer.ts + 83 + + + + Tuna + + src/assets/wise5/components/discussion/Anonymizer.ts + 84 + + + + Loon + + src/assets/wise5/components/discussion/Anonymizer.ts + 85 + + + + Leech + + src/assets/wise5/components/discussion/Anonymizer.ts + 86 + + + + Python + + src/assets/wise5/components/discussion/Anonymizer.ts + 87 + + + + Wasp + + src/assets/wise5/components/discussion/Anonymizer.ts + 88 + + + + Yak + + src/assets/wise5/components/discussion/Anonymizer.ts + 89 + + + + Snake + + src/assets/wise5/components/discussion/Anonymizer.ts + 90 + + + + Duck + + src/assets/wise5/components/discussion/Anonymizer.ts + 91 + + + + Worm + + src/assets/wise5/components/discussion/Anonymizer.ts + 92 + + + + Yeti + + src/assets/wise5/components/discussion/Anonymizer.ts + 93 + + + + Anonymous + + src/assets/wise5/components/discussion/Anonymizer.ts + 101 + + Students post messages for the whole class to see and can reply to other students' posts. @@ -18145,7 +18754,7 @@ Category Name: src/assets/wise5/components/discussion/discussionService.ts - 19 + 20 @@ -18254,7 +18863,15 @@ Category Name: src/assets/wise5/components/discussion/discussion-authoring/discussion-authoring.component.html - 19,21 + 19,23 + + + + Anonymize (students cannot see classmates' names) + + + src/assets/wise5/components/discussion/discussion-authoring/discussion-authoring.component.html + 27,29 @@ -21941,7 +22558,21 @@ If this problem continues, let your teacher know and move on to the next activit Class Discussion src/assets/wise5/directives/teacher-summary-display/discussion-summary/discussion-summary.component.ts - 14,16 + 16,17 + + + + Hide student names + + src/assets/wise5/directives/teacher-summary-display/discussion-summary/discussion-summary.component.ts + 23,25 + + + + Note: Students do not see each other's names in this activity. + + src/assets/wise5/directives/teacher-summary-display/discussion-summary/discussion-summary.component.ts + 27,32