import { StartSendingAudit } from './../store/actions'; import { MediaMatcher } from '@angular/cdk/layout'; import { Component, OnInit, OnDestroy } from '@angular/core'; import { AuditMetadata, AuditMetadataMap } from '../models/audit-metadata'; import { MatDialog, MatSnackBar } from '@angular/material'; import { DARSState } from '../store/state'; import { Store } from '@ngrx/store'; import { GlobalState } from '@app/core/state'; import * as selectors from '../store/selectors'; import { Observable, Subscription } from 'rxjs'; import * as darsActions from '../store/actions'; import { Alert } from '@app/core/models/alert'; import { NewDegreeAuditDialogComponent, NewDegreeAuditFields, } from '../new-degree-audit-dialog/new-degree-audit-dialog.component'; import { NewWhatIfAuditDialogComponent, NewWhatIfAuditFields, } from '../new-what-if-audit-dialog/new-what-if-audit-dialog.component'; import { shareReplay, distinctUntilChanged, map } from 'rxjs/operators'; import { WebsocketService } from '@app/shared/services/websocket.service'; const flattenAndSortMetadataMap = (metadataMap: AuditMetadataMap) => { return (Object.values(metadataMap) as AuditMetadata[]).sort((a, b) => { if (a.darsAuditRunDate > b.darsAuditRunDate) { return 1; } else if (a.darsAuditRunDate < b.darsAuditRunDate) { return -1; } else { return 0; } }); }; @Component({ selector: 'cse-dars-view', templateUrl: './dars-view.component.html', styleUrls: ['./dars-view.component.scss'], }) export class DARSViewComponent implements OnInit, OnDestroy { public metadataStatus$: Observable<DARSState['metadata']['status']>; public programWaiting$: Observable<{ outstanding: number; pending: number }>; public programMetadata$: Observable<AuditMetadata[]>; public whatIfWaiting$: Observable<{ outstanding: number; pending: number }>; public whatIfMetadata$: Observable<AuditMetadata[]>; public mobileView: MediaQueryList; public alerts$: Observable<Alert[]>; public messageSub: Subscription; constructor( private store: Store<GlobalState>, public dialog: MatDialog, public mediaMatcher: MediaMatcher, websocketService: WebsocketService, private snackBar: MatSnackBar, ) { this.mobileView = mediaMatcher.matchMedia('(max-width: 959px)'); this.messageSub = websocketService.messages.subscribe(message => { const newMessage = JSON.parse(message); if (newMessage && newMessage.type === 'auditStatus') { this.store.dispatch( new darsActions.RefreshMetadata({ callback: () => this.snackBar.open('Audit Complete'), }), ); } }); } public ngOnInit() { this.store.dispatch(new darsActions.StartLoadingDARSView()); this.metadataStatus$ = this.store.select(selectors.metadataStatus); this.programWaiting$ = this.store.select( selectors.outstandingAndPendingPrograms, ); this.programMetadata$ = this.store.select(selectors.programMetadata).pipe( distinctUntilChanged(), map(flattenAndSortMetadataMap), shareReplay(), ); this.whatIfWaiting$ = this.store.select( selectors.outstandingAndPendingWhatIf, ); this.whatIfMetadata$ = this.store.select(selectors.whatIfMetadata).pipe( distinctUntilChanged(), map(flattenAndSortMetadataMap), shareReplay(), ); this.alerts$ = this.store.select(selectors.alerts); } public ngOnDestroy() { this.messageSub.unsubscribe(); } public onDismissAlert(key: string) { this.store.dispatch(new darsActions.DismissAlert({ key })); } public openDegreeAuditDialog() { const subscription = this.dialog .open<any, any, NewDegreeAuditFields>(NewDegreeAuditDialogComponent, { panelClass: this.mobileView.matches ? 'dialog-fullscreen' : '', }) .afterClosed() .subscribe(event => { subscription.unsubscribe(); if (event) { return this.store.dispatch( new StartSendingAudit({ auditType: 'program', darsInstitutionCode: event.darsInstitutionCode, darsDegreeProgramCode: event.darsDegreeProgramCode, degreePlannerPlanName: event.degreePlannerPlanName, whichEnrolledCoursesIncluded: event.whichEnrolledCoursesIncluded, darsHonorsOptionCode: event.darsHonorsOptionCode, }), ); } }); } public openWhatIfAuditDialog() { const subscription = this.dialog .open<any, any, NewWhatIfAuditFields>(NewWhatIfAuditDialogComponent, { panelClass: this.mobileView.matches ? 'dialog-fullscreen' : '', }) .afterClosed() .subscribe(event => { subscription.unsubscribe(); if (event) { return this.store.dispatch( new StartSendingAudit({ auditType: 'whatIf', darsInstitutionCode: event.darsInstitutionCode, darsDegreeProgramCode: event.darsDegreeProgramCode, degreePlannerPlanName: event.degreePlannerPlanName, whichEnrolledCoursesIncluded: event.whichEnrolledCoursesIncluded, darsHonorsOptionCode: event.darsHonorsOptionCode, }), ); } }); } }