Skip to content
Snippets Groups Projects
effects.ts 5.22 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, withLatestFrom, tap } 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 { of } from 'rxjs';
import * as selectors from '@app/dars/store/selectors';
import { groupAuditMetadata } from './utils';
import { MatSnackBar } from '@angular/material';
import { TermCodeFactory } from '@app/degree-planner/services/termcode.factory';

@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>,
    private snackBar: MatSnackBar,
    private termCodeService: TermCodeFactory,
jvanboxtel@wisc.edu's avatar
jvanboxtel@wisc.edu committed
  ) {}

  @Effect()
  load$ = this.actions$.pipe(
    ofType(DarsActionTypes.StartLoadingDARSView),
    withLatestFrom(this.store$.select(selectors.getDARSState)),
    flatMap(([_, state]) => {
      if (state.hasLoaded) {
        return of(new darsActions.DoneLoadingDARSView(state));
      }
jvanboxtel@wisc.edu's avatar
jvanboxtel@wisc.edu committed

      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(),
        activeTermCodes: this.degreeAPI.getActiveTermCodes(),
      }).pipe(
        map(tuple => {
          if (this.termCodeService.isNotInitialized()) {
            this.termCodeService.setActiveTermCodes(tuple.activeTermCodes);
          }
          const alerts: Alert[] = [];
          if (tuple.userPreferences.darsHasDismissedDisclaimer !== true) {
            alerts.push(
              new DarsDisclaimerAlert(() => {
                this.store$.dispatch(
                  new UpdateUserPreferences({
                    darsHasDismissedDisclaimer: true,
                  }),
                );
jvanboxtel@wisc.edu's avatar
jvanboxtel@wisc.edu committed
              }),
            );
          return new darsActions.DoneLoadingDARSView({
            hasLoaded: true,
            degreePlans: tuple.degreePlans,
            degreePrograms: tuple.degreePrograms,
            metadata: {
              status: 'Loaded',
              outstanding: { program: 0, whatIf: 0 },
              pending: { program: 0, whatIf: 0 },
              ...groupAuditMetadata(tuple.metadata, tuple.degreePrograms),
            },
            audits: {},
            alerts,
          });
        }),
      );
    }),

    catchError(() => {
      return of(
        new darsActions.ErrorLoadingDARSView({
          message: 'Error loading DARS information. Please try again',
  @Effect()
  refreshMetadata$ = this.actions$.pipe(
    ofType<darsActions.RefreshMetadata>(DarsActionTypes.RefreshMetadata),
    flatMap(action =>
      this.api.getAudits().pipe(
        map(metadata => new darsActions.DoneRefreshingMetadata(metadata)),
        tap(() => action.payload && action.payload.callback()),
        catchError(() => {
          return of(
            new darsActions.ErrorRefreshingMetadata({
              message: 'Error loading metadata. Please try again',
            }),
          );
        }),
      ),
    ),
  );

    ofType<darsActions.StartLoadingAudit>(DarsActionTypes.StartLoadingAudit),
    withLatestFrom(this.store$.select(selectors.getAudits)),
    flatMap(([action, audits]) => {
      const darsDegreeAuditReportId = metadata.darsDegreeAuditReportId;
      const info = audits[darsDegreeAuditReportId];

      if (info !== undefined && info.status === 'Loaded') {
        return of(
          new darsActions.DoneLoadingAudit({ metadata, audit: info.audit }),
        );
      } else {
        return this.api.getAudit(darsDegreeAuditReportId).pipe(
          map(audit => {
            return new darsActions.DoneLoadingAudit({ metadata, audit });
          }),
        );
      }

  @Effect()
  newAudit$ = this.actions$.pipe(
    ofType(DarsActionTypes.StartSendingAudit),
    flatMap((action: darsActions.StartSendingAudit) => {
      const auditType = action.payload.auditType;
      return this.api.newAudit({ ...action.payload }).pipe(
        map(({ darsJobId }) => {
          return new darsActions.DoneSendingAudit({ auditType, darsJobId });
        }),
        catchError(_err => {
          this.snackBar.open('Unable to generate audit');
          return of(
            new darsActions.ErrorSendingAudit({
              auditType,
              message: 'Unable to generate audit',
            }),
          );
        }),
      );

  @Effect()
  updateAudits$ = this.actions$.pipe(
    ofType(DarsActionTypes.DoneSendingAudit),
    map(() => new darsActions.RefreshMetadata()),