diff --git a/src/app/teacher/teacher-tools.module.ts b/src/app/teacher/teacher-tools.module.ts index 06690d48c09..5ffa0b4a4c8 100644 --- a/src/app/teacher/teacher-tools.module.ts +++ b/src/app/teacher/teacher-tools.module.ts @@ -32,6 +32,7 @@ import { MilestoneReportService } from '../../assets/wise5/services/milestoneRep import { RouterModule } from '@angular/router'; import { TeacherToolsRoutingModule } from './teacher-tools-routing.module'; import { TeacherPauseScreenService } from '../../assets/wise5/services/teacherPauseScreenService'; +import { RunStatusService } from '../../assets/wise5/services/runStatusService'; @NgModule({ imports: [ @@ -56,6 +57,7 @@ import { TeacherPauseScreenService } from '../../assets/wise5/services/teacherPa MoveNodesService, { provide: NodeService, useExisting: TeacherNodeService }, ProjectAssetService, + RunStatusService, SpaceService, { provide: PeerGroupService, useExisting: TeacherPeerGroupService }, { provide: ProjectService, useExisting: TeacherProjectService }, diff --git a/src/app/teacher/teacher-tools.resolver.ts b/src/app/teacher/teacher-tools.resolver.ts index 7c3deeebf62..dead090cb95 100644 --- a/src/app/teacher/teacher-tools.resolver.ts +++ b/src/app/teacher/teacher-tools.resolver.ts @@ -9,6 +9,7 @@ import { NotificationService } from '../../assets/wise5/services/notificationSer import { TeacherWebSocketService } from '../../assets/wise5/services/teacherWebSocketService'; import { NotebookService } from '../../assets/wise5/services/notebookService'; import { AchievementService } from '../../assets/wise5/services/achievementService'; +import { RunStatusService } from '../../assets/wise5/services/runStatusService'; export const TeacherToolsResolver: ResolveFn = ( route: ActivatedRouteSnapshot, @@ -20,6 +21,7 @@ export const TeacherToolsResolver: ResolveFn = ( notebookService: NotebookService = inject(NotebookService), notificationService: NotificationService = inject(NotificationService), projectService: ProjectService = inject(ProjectService), + runStatusService: RunStatusService = inject(RunStatusService), websocketService: TeacherWebSocketService = inject(TeacherWebSocketService) ): Observable => configService @@ -27,7 +29,7 @@ export const TeacherToolsResolver: ResolveFn = ( .pipe(switchMap(() => projectService.retrieveProject())) .pipe(switchMap(() => classroomStatusService.retrieveStudentStatuses())) .pipe(switchMap(() => achievementService.retrieveStudentAchievements())) - .pipe(switchMap(() => dataService.retrieveRunStatus())) + .pipe(switchMap(() => runStatusService.retrieveRunStatus())) .pipe(switchMap(() => notificationService.retrieveNotifications())) .pipe(switchMap(() => dataService.retrieveAnnotations())) .pipe(switchMap(() => notebookService.retrieveNotebookItems())) diff --git a/src/assets/wise5/classroomMonitor/classroom-monitor-testing.module.ts b/src/assets/wise5/classroomMonitor/classroom-monitor-testing.module.ts index 095026a748e..4c43087a0c2 100644 --- a/src/assets/wise5/classroomMonitor/classroom-monitor-testing.module.ts +++ b/src/assets/wise5/classroomMonitor/classroom-monitor-testing.module.ts @@ -13,6 +13,7 @@ import { MatSnackBarModule } from '@angular/material/snack-bar'; import { MilestoneReportService } from '../services/milestoneReportService'; import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { TeacherPauseScreenService } from '../services/teacherPauseScreenService'; +import { RunStatusService } from '../services/runStatusService'; @NgModule({ imports: [ @@ -30,6 +31,7 @@ import { TeacherPauseScreenService } from '../services/teacherPauseScreenService TeacherPeerGroupService, TeacherProjectService, TeacherWebSocketService, + RunStatusService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting() ] diff --git a/src/assets/wise5/classroomMonitor/classroom-monitor.component.ts b/src/assets/wise5/classroomMonitor/classroom-monitor.component.ts index 957103d0f90..b11641d16c6 100644 --- a/src/assets/wise5/classroomMonitor/classroom-monitor.component.ts +++ b/src/assets/wise5/classroomMonitor/classroom-monitor.component.ts @@ -13,6 +13,7 @@ import { TeacherDataService } from '../services/teacherDataService'; import { TeacherProjectService } from '../services/teacherProjectService'; import { TeacherPauseScreenService } from '../services/teacherPauseScreenService'; import { NavigationEnd, Router } from '@angular/router'; +import { RunStatusService } from '../services/runStatusService'; @Component({ selector: 'classroom-monitor', @@ -46,6 +47,7 @@ export class ClassroomMonitorComponent implements OnInit { private pauseScreenService: TeacherPauseScreenService, private projectService: TeacherProjectService, private router: Router, + private runStatusService: RunStatusService, private sessionService: SessionService, private snackBar: MatSnackBar ) {} @@ -204,7 +206,7 @@ export class ClassroomMonitorComponent implements OnInit { @HostListener('window:beforeunload') protected unPauseAllPeriods(): void { - this.dataService.getRunStatus().periods.forEach((period) => { + this.runStatusService.getRunStatus().periods.forEach((period) => { if (period.periodId !== -1 && period.paused) { this.pauseScreenService.pauseScreensChanged(period.periodId, false); } diff --git a/src/assets/wise5/services/runStatusService.ts b/src/assets/wise5/services/runStatusService.ts new file mode 100644 index 00000000000..c79ce0cc02d --- /dev/null +++ b/src/assets/wise5/services/runStatusService.ts @@ -0,0 +1,89 @@ +import { HttpClient, HttpParams } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable, tap } from 'rxjs'; +import { ConfigService } from './configService'; +import { RunStatus } from '../common/RunStatus'; +import { TeacherDataService } from './teacherDataService'; + +@Injectable() +export class RunStatusService { + private runStatus: RunStatus; + + constructor( + private configService: ConfigService, + private dataService: TeacherDataService, + private http: HttpClient + ) { + this.configService.configRetrieved$.subscribe(() => { + if (this.configService.isClassroomMonitor()) { + this.retrieveRunStatus(); + } + }); + } + + retrieveRunStatus(): Observable { + const options = { + params: new HttpParams().set('runId', this.configService.getConfigParam('runId')), + headers: { 'Content-Type': 'application/x-www-form-urlencoded' } + }; + return this.http.get(this.configService.getConfigParam('runStatusURL'), options).pipe( + tap((runStatus: RunStatus) => { + this.runStatus = runStatus; + this.initializePeriods(); + }) + ); + } + + private initializePeriods(): void { + const periods = [...this.configService.getPeriods()]; + if (this.dataService.getCurrentPeriod() == null) { + this.dataService.setCurrentPeriod(periods[0]); + } + periods.unshift({ periodId: -1, periodName: $localize`All Periods` }); + let mergedPeriods = periods; + if (this.runStatus.periods != null) { + mergedPeriods = this.mergeConfigAndRunStatusPeriods(periods, this.runStatus.periods); + } + this.runStatus.periods = mergedPeriods; + this.dataService.setPeriods(mergedPeriods); + } + + private mergeConfigAndRunStatusPeriods(configPeriods: any[], runStatusPeriods: any[]): any[] { + const mergedPeriods = []; + configPeriods.forEach((configPeriod) => { + const runStatusPeriod = runStatusPeriods.find( + (runStatusPeriod) => runStatusPeriod.periodId === configPeriod.periodId + ); + mergedPeriods.push(runStatusPeriod != null ? runStatusPeriod : configPeriod); + }); + return mergedPeriods; + } + + getRunStatus(): RunStatus { + return this.runStatus; + } + + setRunStatus(runStatus: RunStatus): void { + this.runStatus = runStatus; + } + + saveRunStatus(): Observable { + const url = this.configService.getConfigParam('runStatusURL'); + const body = new HttpParams() + .set('runId', this.configService.getConfigParam('runId')) + .set('status', JSON.stringify(this.runStatus)); + const options = { + headers: { 'Content-Type': 'application/x-www-form-urlencoded' } + }; + return this.http.post(url, body, options); + } + + createRunStatus(): RunStatus { + const periods = this.configService.getPeriods(); + periods.forEach((period) => (period.paused = false)); + return { + runId: this.configService.getConfigParam('runId'), + periods: periods + }; + } +} diff --git a/src/assets/wise5/services/teacherDataService.ts b/src/assets/wise5/services/teacherDataService.ts index 842f6b903c4..bcd94fa7418 100644 --- a/src/assets/wise5/services/teacherDataService.ts +++ b/src/assets/wise5/services/teacherDataService.ts @@ -14,7 +14,6 @@ import { isMatchingPeriods } from '../common/period/period'; import { getIntersectOfArrays } from '../common/array/array'; import { serverSaveTimeComparator } from '../common/object/object'; import { Annotation } from '../common/Annotation'; -import { RunStatus } from '../common/RunStatus'; @Injectable() export class TeacherDataService extends DataService { @@ -23,7 +22,6 @@ export class TeacherDataService extends DataService { currentWorkgroup = null; currentStep = null; previousStep = null; - private runStatus: RunStatus = null; periods = []; nodeGradingSort = 'team'; studentGradingSort = 'step'; @@ -65,12 +63,6 @@ export class TeacherDataService extends DataService { this.addOrUpdateComponentState(studentWork); this.broadcastStudentWorkReceived({ studentWork: studentWork }); }); - - this.ConfigService.configRetrieved$.subscribe(() => { - if (this.ConfigService.isClassroomMonitor()) { - this.retrieveRunStatus(); - } - }); } private handleAnnotationReceived(annotation: Annotation): void { @@ -396,19 +388,6 @@ export class TeacherDataService extends DataService { return -1; } - retrieveRunStatus(): Observable { - const options = { - params: new HttpParams().set('runId', this.ConfigService.getConfigParam('runId')), - headers: { 'Content-Type': 'application/x-www-form-urlencoded' } - }; - return this.http.get(this.ConfigService.getConfigParam('runStatusURL'), options).pipe( - tap((runStatus: RunStatus) => { - this.runStatus = runStatus; - this.initializePeriods(); - }) - ); - } - getComponentStatesByWorkgroupId(workgroupId) { return this.studentData.componentStatesByWorkgroupId[workgroupId] || []; } @@ -569,31 +548,6 @@ export class TeacherDataService extends DataService { } } - private initializePeriods(): void { - const periods = [...this.ConfigService.getPeriods()]; - if (this.currentPeriod == null) { - this.setCurrentPeriod(periods[0]); - } - periods.unshift({ periodId: -1, periodName: $localize`All Periods` }); - let mergedPeriods = periods; - if (this.runStatus.periods != null) { - mergedPeriods = this.mergeConfigAndRunStatusPeriods(periods, this.runStatus.periods); - } - this.periods = mergedPeriods; - this.runStatus.periods = mergedPeriods; - } - - private mergeConfigAndRunStatusPeriods(configPeriods: any[], runStatusPeriods: any[]): any[] { - const mergedPeriods = []; - configPeriods.forEach((configPeriod) => { - const runStatusPeriod = runStatusPeriods.find( - (runStatusPeriod) => runStatusPeriod.periodId === configPeriod.periodId - ); - mergedPeriods.push(runStatusPeriod != null ? runStatusPeriod : configPeriod); - }); - return mergedPeriods; - } - setCurrentPeriod(period) { const previousPeriod = this.currentPeriod; this.currentPeriod = period; @@ -631,16 +585,12 @@ export class TeacherDataService extends DataService { return this.currentPeriod.periodId; } - getPeriods() { + getPeriods(): any[] { return this.periods; } - getRunStatus(): RunStatus { - return this.runStatus; - } - - setRunStatus(runStatus: RunStatus): void { - this.runStatus = runStatus; + setPeriods(periods: any[]): void { + this.periods = periods; } getVisiblePeriodsById(currentPeriodId: number): any { @@ -682,26 +632,6 @@ export class TeacherDataService extends DataService { return this.getPeriods().find((period) => period.periodId === periodId); } - saveRunStatus(): Observable { - const url = this.ConfigService.getConfigParam('runStatusURL'); - const body = new HttpParams() - .set('runId', this.ConfigService.getConfigParam('runId')) - .set('status', JSON.stringify(this.runStatus)); - const options = { - headers: { 'Content-Type': 'application/x-www-form-urlencoded' } - }; - return this.http.post(url, body, options); - } - - createRunStatus(): RunStatus { - const periods = this.ConfigService.getPeriods(); - periods.forEach((period) => (period.paused = false)); - return { - runId: this.ConfigService.getConfigParam('runId'), - periods: periods - }; - } - isWorkgroupShown(workgroup): boolean { return ( this.isWorkgroupInCurrentPeriod(workgroup) && diff --git a/src/assets/wise5/services/teacherPauseScreenService.ts b/src/assets/wise5/services/teacherPauseScreenService.ts index 5d13af037c8..818fcba4d17 100644 --- a/src/assets/wise5/services/teacherPauseScreenService.ts +++ b/src/assets/wise5/services/teacherPauseScreenService.ts @@ -1,11 +1,13 @@ import { Injectable } from '@angular/core'; import { TeacherDataService } from './teacherDataService'; import { TeacherWebSocketService } from './teacherWebSocketService'; +import { RunStatusService } from './runStatusService'; @Injectable() export class TeacherPauseScreenService { constructor( private dataService: TeacherDataService, + private runStatusService: RunStatusService, private webSocketService: TeacherWebSocketService ) {} @@ -28,7 +30,7 @@ export class TeacherPauseScreenService { } private saveRunStatusThenHandlePauseScreen(periodId: number, isPaused: boolean): void { - this.dataService.saveRunStatus().subscribe(() => { + this.runStatusService.saveRunStatus().subscribe(() => { if (isPaused) { this.webSocketService.pauseScreens(periodId); } else { @@ -43,8 +45,8 @@ export class TeacherPauseScreenService { * @param isPaused whether the period is paused or not */ private updatePausedRunStatusValue(periodId: number, isPaused: boolean): void { - if (this.dataService.getRunStatus() == null) { - this.dataService.setRunStatus(this.dataService.createRunStatus()); + if (this.runStatusService.getRunStatus() == null) { + this.runStatusService.setRunStatus(this.runStatusService.createRunStatus()); } if (periodId === -1) { this.updateAllPeriodsPausedValue(isPaused); @@ -54,13 +56,13 @@ export class TeacherPauseScreenService { } private updateAllPeriodsPausedValue(isPaused: boolean): void { - for (const period of this.dataService.getRunStatus().periods) { + for (const period of this.runStatusService.getRunStatus().periods) { period.paused = isPaused; } } private updatePeriodPausedValue(periodId: number, isPaused: boolean): void { - for (const period of this.dataService.getRunStatus().periods) { + for (const period of this.runStatusService.getRunStatus().periods) { if (period.periodId === periodId) { period.paused = isPaused; } diff --git a/src/messages.xlf b/src/messages.xlf index 615caa0e301..f4273c3564e 100644 --- a/src/messages.xlf +++ b/src/messages.xlf @@ -9954,7 +9954,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it. src/assets/wise5/classroomMonitor/classroom-monitor.component.ts - 86 + 88 src/assets/wise5/classroomMonitor/classroomMonitorComponents/shared/tool-bar/tool-bar.component.ts @@ -9983,7 +9983,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it. src/assets/wise5/classroomMonitor/classroom-monitor.component.ts - 149 + 151 src/assets/wise5/vle/vle.component.ts @@ -9998,7 +9998,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it. src/assets/wise5/classroomMonitor/classroom-monitor.component.ts - 150 + 152 src/assets/wise5/vle/vle.component.ts @@ -13218,14 +13218,14 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.Classroom Monitor src/assets/wise5/classroomMonitor/classroom-monitor.component.ts - 35 + 36 Grade by Step src/assets/wise5/classroomMonitor/classroom-monitor.component.ts - 93 + 95 src/assets/wise5/classroomMonitor/classroomMonitorComponents/shared/tool-bar/tool-bar.component.ts @@ -13236,7 +13236,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.Grade by Student src/assets/wise5/classroomMonitor/classroom-monitor.component.ts - 106 + 108 src/assets/wise5/classroomMonitor/classroomMonitorComponents/shared/tool-bar/tool-bar.component.ts @@ -13247,7 +13247,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.Manage Students src/assets/wise5/classroomMonitor/classroom-monitor.component.ts - 113 + 115 src/assets/wise5/classroomMonitor/classroomMonitorComponents/shared/tool-bar/tool-bar.component.ts @@ -13258,7 +13258,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.Student Notebooks src/assets/wise5/classroomMonitor/classroom-monitor.component.ts - 120 + 122 src/assets/wise5/classroomMonitor/classroomMonitorComponents/shared/tool-bar/tool-bar.component.ts @@ -13269,7 +13269,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.Data Export src/assets/wise5/classroomMonitor/classroom-monitor.component.ts - 127 + 129 src/assets/wise5/classroomMonitor/classroomMonitorComponents/shared/tool-bar/tool-bar.component.ts @@ -13280,7 +13280,7 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.Error: Data is not being saved! Check your internet connection. src/assets/wise5/classroomMonitor/classroom-monitor.component.ts - 192 + 194 @@ -14225,8 +14225,8 @@ Click "Cancel" to keep the invalid JSON open so you can fix it.96 - src/assets/wise5/services/teacherDataService.ts - 577 + src/assets/wise5/services/runStatusService.ts + 42