Skip to content
Snippets Groups Projects
effects.ts 4.07 KiB
Newer Older
jvanboxtel@wisc.edu's avatar
jvanboxtel@wisc.edu committed
import { UpdateUserPreferences } from './../../core/actions';
import { GlobalState } from '@app/core/state';
import { Store } from '@ngrx/store';
import { forkJoinWithKeys } from '@app/degree-planner/shared/utils';
import { Injectable } from '@angular/core';
import { Actions, Effect, ofType } from '@ngrx/effects';
import { DarsActionTypes } from '@app/dars/store/actions';
import * as darsActions from '@app/dars/store/actions';
import { flatMap, map, catchError } from 'rxjs/operators';
import { DarsApiService } from '../services/api.service';
jvanboxtel@wisc.edu's avatar
jvanboxtel@wisc.edu committed
import { Alert, DarsDisclaimerAlert } from '@app/core/models/alert';
import { DegreePlannerApiService } from '@app/degree-planner/services/api.service';
import { AuditMetadata } from '../models/audit-metadata';
import { SingleAuditRequest } from '../models/single-audit-request';
import { StudentDegreeProgram } from '../models/student-degree-program';
import { of } from 'rxjs';

const isFromDegreePlan = (md: AuditMetadata, pg: StudentDegreeProgram) => {
  return (
    md.darsDegreeProgramCode === pg.darsDegreeProgramCode &&
    md.darsInstitutionCode === pg.darsInstitutionCode
  );
};

@Injectable()
export class DARSEffects {
jvanboxtel@wisc.edu's avatar
jvanboxtel@wisc.edu committed
  constructor(
    private actions$: Actions,
    private api: DarsApiService,
    private degreeAPI: DegreePlannerApiService,
    private store$: Store<GlobalState>,
  ) {}

  @Effect()
  load$ = this.actions$.pipe(
    ofType(DarsActionTypes.StartLoadingMetadata),
jvanboxtel@wisc.edu's avatar
jvanboxtel@wisc.edu committed

    flatMap(() => {
      return forkJoinWithKeys({
        degreePlans: this.degreeAPI.getAllDegreePlans(),
        degreePrograms: this.api.getStudentDegreePrograms(),
jvanboxtel@wisc.edu's avatar
jvanboxtel@wisc.edu committed
        metadata: this.api.getAudits(),
        userPreferences: this.degreeAPI.getUserPreferences(),
      });
    }),

    map(({ degreePlans, degreePrograms, metadata, userPreferences }) => {
jvanboxtel@wisc.edu's avatar
jvanboxtel@wisc.edu committed
      const alerts: Alert[] = [];
      if (userPreferences.darsHasDismissedDisclaimer !== true) {
        alerts.push(
          new DarsDisclaimerAlert(() => {
            this.store$.dispatch(
              new UpdateUserPreferences({
                darsHasDismissedDisclaimer: true,
              }),
            );
          }),
        );
      }

      const programMetadata: AuditMetadata[] = [];
      const whatIfMetadata: AuditMetadata[] = [];

      metadata.forEach(md => {
        if (degreePrograms.some(dp => isFromDegreePlan(md, dp))) {
          programMetadata.push(md);
        } else {
          whatIfMetadata.push(md);
        }
      });

      return new darsActions.PopulateDarsState({
        degreePlans,
        metadata: {
          status: 'Loaded',
          programMetadata,
          whatIfMetadata,
        },
        alerts,
      });
    }),

    catchError(() => {
      return of(
        new darsActions.ErrorLoadingMetadata({
          message: 'Error loading metadata. Please try again',
        }),
      );

  @Effect()
  getAudit$ = this.actions$.pipe(
    ofType(DarsActionTypes.StartLoadingAudit),
    flatMap((action: darsActions.StartLoadingAudit) => {
      const metadata = action.payload;
      return this.api.getAudit(metadata.darsDegreeAuditReportId).pipe(
        map(audit => {
          return new darsActions.DoneLoadingAudit({ metadata, audit });
        }),
      );
    }),
  );

  @Effect()
  newAudit$ = this.actions$.pipe(
    ofType(DarsActionTypes.StartSendingAudit),
    flatMap((action: darsActions.StartSendingAudit) => {
      const metadata = action.payload;
      return this.api
        .newAudit(
          metadata.darsInstitutionCode,
          metadata.darsDegreeProgramCode,
          metadata.degreePlannerPlanName,
          metadata.whichEnrolledCoursesIncluded,
        )
        .pipe(
          map(audit => {
            return new darsActions.DoneSendingAudit(action.payload);
          }),
        );
    }),

    catchError(error => {
      return of(
        new darsActions.ErrorSendingAudit({
          message: 'Unable to add course',
        }),
      );
    }),
  );

  @Effect()
  updateAudits$ = this.actions$.pipe(
    ofType(DarsActionTypes.DoneSendingAudit),
    map(() => {
      return new darsActions.StartLoadingMetadata();
    }),
  );