From 3fec3d81605b6086da35817098f2b004389cea09 Mon Sep 17 00:00:00 2001
From: "jvanboxtel@wisc.edu" <jvanboxtel@wisc.edu>
Date: Fri, 7 Jun 2019 09:34:57 -0500
Subject: [PATCH] ROENROLL-1792

---
 src/app/core/actions.ts                       |  9 +++
 src/app/core/models/alert.ts                  |  9 +++
 src/app/core/models/user-preferences.ts       |  1 +
 .../dars/dars-view/dars-view.component.html   |  1 +
 src/app/dars/dars.module.ts                   |  1 +
 src/app/dars/store/actions.ts                 |  7 +++
 src/app/dars/store/effects.ts                 | 63 ++++++++++++++++---
 src/app/dars/store/state.ts                   |  3 +
 .../degree-planner/degree-planner.module.ts   |  4 +-
 .../store/actions/ui.actions.ts               | 10 +--
 src/app/degree-planner/store/reducer.ts       |  5 +-
 .../alert-container.component.html            |  0
 .../alert-container.component.scss            |  0
 .../alert-container.component.ts              |  2 +-
 src/app/shared/shared.module.ts               | 10 ++-
 src/assets/mock-data/metadata-response.json   | 17 +++++
 16 files changed, 123 insertions(+), 19 deletions(-)
 rename src/app/{degree-planner => shared/components}/alert-container/alert-container.component.html (100%)
 rename src/app/{degree-planner => shared/components}/alert-container/alert-container.component.scss (100%)
 rename src/app/{degree-planner => shared/components}/alert-container/alert-container.component.ts (93%)
 create mode 100644 src/assets/mock-data/metadata-response.json

diff --git a/src/app/core/actions.ts b/src/app/core/actions.ts
index 907f1ab..0b224cb 100644
--- a/src/app/core/actions.ts
+++ b/src/app/core/actions.ts
@@ -5,7 +5,16 @@ export enum UserPreferencesActionTypes {
   UpdateUserPreferences = '[User Preferences] Update',
 }
 
+export enum NotificationActionTypes {
+  DismissAlert = '[UI] Dismiss alert',
+}
+
 export class UpdateUserPreferences implements Action {
   public readonly type = UserPreferencesActionTypes.UpdateUserPreferences;
   constructor(public payload: Partial<UserPreferences>) {}
 }
+
+export class DismissAlert implements Action {
+  public readonly type = NotificationActionTypes.DismissAlert;
+  constructor(public payload: { key: string }) {}
+}
diff --git a/src/app/core/models/alert.ts b/src/app/core/models/alert.ts
index 1d78964..ad6cfe4 100644
--- a/src/app/core/models/alert.ts
+++ b/src/app/core/models/alert.ts
@@ -13,3 +13,12 @@ export class DisclaimerAlert implements Alert {
 
   constructor(public callback: Alert['callback']) {}
 }
+
+export class DarsDisclaimerAlert implements Alert {
+  public readonly key = 'disclaimerAlert';
+  public readonly title = 'This is a planning tool Dars.';
+  public readonly message =
+    'If you have questions about your plan or degree, please contact your advisor.';
+
+  constructor(public callback: Alert['callback']) {}
+}
diff --git a/src/app/core/models/user-preferences.ts b/src/app/core/models/user-preferences.ts
index cc01a77..a201713 100644
--- a/src/app/core/models/user-preferences.ts
+++ b/src/app/core/models/user-preferences.ts
@@ -3,4 +3,5 @@ export interface UserPreferences {
   degreePlannerSelectedPlan?: number;
   degreePlannerHasDismissedDisclaimer?: boolean;
   degreePlannerHasDismissedIEWarning?: boolean;
+  darsHasDismissedDisclaimer?: boolean;
 }
diff --git a/src/app/dars/dars-view/dars-view.component.html b/src/app/dars/dars-view/dars-view.component.html
index f296898..00ef9c9 100644
--- a/src/app/dars/dars-view/dars-view.component.html
+++ b/src/app/dars/dars-view/dars-view.component.html
@@ -20,6 +20,7 @@
 
     <!-- Main DARS Content -->
     <div id="dars-main">
+        <cse-alert-container></cse-alert-container>
         <h2 class="mat-h1">Completed Audit Requests</h2>
 
         <div id="dars-header-bar">
diff --git a/src/app/dars/dars.module.ts b/src/app/dars/dars.module.ts
index 08b9305..1a2b72c 100644
--- a/src/app/dars/dars.module.ts
+++ b/src/app/dars/dars.module.ts
@@ -7,6 +7,7 @@ import { DarsAuditComponent } from './audit/audit.component';
 import { DarsMetadataTableComponent } from './metadata-table/metadata-table.component';
 import { NewAuditOptionsComponent } from './dars-view/new-audit-options/new-audit-options.component';
 import { MatStepperModule } from '@angular/material';
+import { AlertContainerComponent } from '../shared/components/alert-container/alert-container.component';
 
 @NgModule({
   imports: [
diff --git a/src/app/dars/store/actions.ts b/src/app/dars/store/actions.ts
index 6124756..43d1a9c 100644
--- a/src/app/dars/store/actions.ts
+++ b/src/app/dars/store/actions.ts
@@ -1,3 +1,4 @@
+import { DARSState } from '@app/dars/store/state';
 import { Action } from '@ngrx/store';
 import { AuditMetadata } from '../models/audit-metadata';
 import { Audit } from '../models/audit';
@@ -5,6 +6,7 @@ import { Audit } from '../models/audit';
 export enum DarsActionTypes {
   ErrorLoadingMetadata = '[DARS] Error Loading Metadata',
   StartLoadingMetadata = '[DARS] Start Loading Metadata',
+  DoneLoadingMetadata = '[DARS] Done Loading Metadata',
   ErrorLoadingAudit = '[DARS] Error Loading Audit',
   AddAuditMetadata = '[DARS] Add Audit Metadata',
   StartLoadingAudit = '[DARS] Start Loading Audit',
@@ -21,6 +23,11 @@ export class StartLoadingMetadata implements Action {
   public readonly type = DarsActionTypes.StartLoadingMetadata;
 }
 
+export class DoneLoadingMetadata implements Action {
+  public readonly type = DarsActionTypes.DoneLoadingMetadata;
+  constructor(public payload: DARSState) {}
+}
+
 export class ErrorLoadingAudit implements Action {
   public readonly type = DarsActionTypes.ErrorLoadingAudit;
   constructor(public payload: { message: string }) {}
diff --git a/src/app/dars/store/effects.ts b/src/app/dars/store/effects.ts
index 150fe2a..ec73776 100644
--- a/src/app/dars/store/effects.ts
+++ b/src/app/dars/store/effects.ts
@@ -1,26 +1,73 @@
+import { visibleAudit } from './selectors';
+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 { flatMap, map, catchError, switchMap } from 'rxjs/operators';
 import { DarsApiService } from '../services/api.service';
 import { of } from 'rxjs';
+import { Alert, DarsDisclaimerAlert } from '@app/core/models/alert';
+import { DegreePlannerApiService } from '@app/degree-planner/services/api.service';
+import { INITIAL_DARS_STATE } from './state';
 
 @Injectable()
 export class DARSEffects {
-  constructor(private actions$: Actions, private api: DarsApiService) {}
+  constructor(
+    private actions$: Actions,
+    private api: DarsApiService,
+    private degreeAPI: DegreePlannerApiService,
+    private store$: Store<GlobalState>,
+  ) {}
 
   @Effect()
   load$ = this.actions$.pipe(
     ofType(DarsActionTypes.StartLoadingMetadata),
-    flatMap(() => this.api.getAudits()),
-    map(metadata => new darsActions.AddAuditMetadata({ metadata })),
-    catchError(() => {
-      return of(
-        new darsActions.ErrorLoadingMetadata({
-          message: 'Unable to load audit metadata. Please try again',
+
+    flatMap(() => {
+      return forkJoinWithKeys({
+        metadata: this.api.getAudits(),
+        userPreferences: this.degreeAPI.getUserPreferences(),
+      });
+    }),
+
+    flatMap(({ metadata, userPreferences }) => {
+      const alerts: Alert[] = [];
+      if (userPreferences.darsHasDismissedDisclaimer !== true) {
+        alerts.push(
+          new DarsDisclaimerAlert(() => {
+            this.store$.dispatch(
+              new UpdateUserPreferences({
+                darsHasDismissedDisclaimer: true,
+              }),
+            );
+          }),
+        );
+      }
+
+      return forkJoinWithKeys({
+        metadata: of(metadata),
+        visibleAudit: of({}),
+        alerts: of(alerts),
+      }).pipe(
+        switchMap(payload => {
+          return [
+            new darsActions.AddAuditMetadata({ metadata }),
+            new UpdateUserPreferences(userPreferences),
+          ];
         }),
       );
     }),
+
+    // catchError(() => {
+    //   return of(
+    //     new darsActions.ErrorLoadingMetadata({
+    //       message: 'Unable to load audit metadata. Please try again',
+    //     }),
+    //   );
+    // }),
   );
 }
diff --git a/src/app/dars/store/state.ts b/src/app/dars/store/state.ts
index 8986599..c299147 100644
--- a/src/app/dars/store/state.ts
+++ b/src/app/dars/store/state.ts
@@ -1,3 +1,4 @@
+import { Alert } from './../../core/models/alert';
 import { AuditMetadata } from '../models/audit-metadata';
 import { Audit } from '../models/audit';
 
@@ -11,9 +12,11 @@ export interface DARSState {
     | { status: 'NotLoaded' }
     | { status: 'Loading'; metadata: AuditMetadata }
     | { status: 'Loaded'; metadata: AuditMetadata; audit: Audit };
+  alerts: Alert[];
 }
 
 export const INITIAL_DARS_STATE: DARSState = {
   metadata: { status: 'Loading' },
   visibleAudit: { status: 'NotLoaded' },
+  alerts: [],
 };
diff --git a/src/app/degree-planner/degree-planner.module.ts b/src/app/degree-planner/degree-planner.module.ts
index a3d71e6..1a58879 100644
--- a/src/app/degree-planner/degree-planner.module.ts
+++ b/src/app/degree-planner/degree-planner.module.ts
@@ -10,7 +10,7 @@ import { DragDropModule } from '@angular/cdk/drag-drop';
 import { RemoveCourseConfirmDialogComponent } from './dialogs/remove-course-confirm-dialog/remove-course-confirm-dialog.component';
 import { YearContainerComponent } from '@app/degree-planner/year-container/year-container.component';
 import { CourseSearchComponent } from '@app/degree-planner/course-search/course-search.component';
-import { AlertContainerComponent } from './alert-container/alert-container.component';
+import { AlertContainerComponent } from '../shared/components/alert-container/alert-container.component';
 import { EffectsModule } from '@ngrx/effects';
 import { DegreePlanEffects } from './store/effects/plan.effects';
 import { NoteEffects } from './store/effects/note.effects';
@@ -38,7 +38,7 @@ import { ErrorEffects } from './store/effects/error.effects';
     NotesDialogComponent,
     RemoveCourseConfirmDialogComponent,
     YearContainerComponent,
-    AlertContainerComponent,
+    // AlertContainerComponent,
     CourseSearchComponent,
   ],
   entryComponents: [NotesDialogComponent, RemoveCourseConfirmDialogComponent],
diff --git a/src/app/degree-planner/store/actions/ui.actions.ts b/src/app/degree-planner/store/actions/ui.actions.ts
index 0600458..2fce691 100644
--- a/src/app/degree-planner/store/actions/ui.actions.ts
+++ b/src/app/degree-planner/store/actions/ui.actions.ts
@@ -16,7 +16,7 @@ export enum UIActionTypes {
   OpenSidenav = '[UI] Open Sidenav',
   CloseSidenav = '[UI] Close Sidenav',
 
-  DismissAlert = '[UI] Dismiss Disclaimer Alert',
+  //  DismissAlert = '[UI] Dismiss Disclaimer Alert',
 
   UpdateUserPreferences = '[UI] Update User Preferences',
 
@@ -66,10 +66,10 @@ export class CloseSidenav implements Action {
   public readonly type = UIActionTypes.CloseSidenav;
 }
 
-export class DismissAlert implements Action {
-  public readonly type = UIActionTypes.DismissAlert;
-  constructor(public payload: { key: string }) {}
-}
+// export class DismissAlert implements Action {
+//   public readonly type = UIActionTypes.DismissAlert;
+//   constructor(public payload: { key: string }) {}
+// }
 
 export class AddAcademicYear implements Action {
   public readonly type = UIActionTypes.AddAcademicYear;
diff --git a/src/app/degree-planner/store/reducer.ts b/src/app/degree-planner/store/reducer.ts
index 3b8f0f7..1770f8f 100644
--- a/src/app/degree-planner/store/reducer.ts
+++ b/src/app/degree-planner/store/reducer.ts
@@ -6,6 +6,7 @@ import * as planActions from '@app/degree-planner/store/actions/plan.actions';
 import * as courseActions from '@app/degree-planner/store/actions/course.actions';
 import * as noteActions from '@app/degree-planner/store/actions/note.actions';
 import * as uiActions from '@app/degree-planner/store/actions/ui.actions';
+import * as globalActions from '@app/core/actions';
 import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course';
 import { DegreePlan } from '@app/core/models/degree-plan';
 import { Year, YearMapping } from '@app/core/models/year';
@@ -41,7 +42,7 @@ type SupportedActions =
   | planActions.DeletePlanSuccess
   | uiActions.ExpandAcademicYear
   | uiActions.CollapseAcademicYear
-  | uiActions.DismissAlert
+  | globalActions.DismissAlert
   | uiActions.OpenCourseSearch
   | uiActions.CloseCourseSearch
   | uiActions.ToggleCourseSearch
@@ -143,7 +144,7 @@ export function degreePlannerReducer(
       return newState;
     }
 
-    case uiActions.UIActionTypes.DismissAlert: {
+    case globalActions.NotificationActionTypes.DismissAlert: {
       const keyToRemove = action.payload.key;
       const newAlerts = state.alerts.filter(({ key }) => key !== keyToRemove);
       return { ...state, alerts: newAlerts };
diff --git a/src/app/degree-planner/alert-container/alert-container.component.html b/src/app/shared/components/alert-container/alert-container.component.html
similarity index 100%
rename from src/app/degree-planner/alert-container/alert-container.component.html
rename to src/app/shared/components/alert-container/alert-container.component.html
diff --git a/src/app/degree-planner/alert-container/alert-container.component.scss b/src/app/shared/components/alert-container/alert-container.component.scss
similarity index 100%
rename from src/app/degree-planner/alert-container/alert-container.component.scss
rename to src/app/shared/components/alert-container/alert-container.component.scss
diff --git a/src/app/degree-planner/alert-container/alert-container.component.ts b/src/app/shared/components/alert-container/alert-container.component.ts
similarity index 93%
rename from src/app/degree-planner/alert-container/alert-container.component.ts
rename to src/app/shared/components/alert-container/alert-container.component.ts
index 8eabe02..53ed031 100644
--- a/src/app/degree-planner/alert-container/alert-container.component.ts
+++ b/src/app/shared/components/alert-container/alert-container.component.ts
@@ -4,7 +4,7 @@ import { GlobalState } from '@app/core/state';
 import * as selectors from '@app/degree-planner/store/selectors';
 import { Alert } from '@app/core/models/alert';
 import { Observable } from 'rxjs';
-import { DismissAlert } from '../store/actions/ui.actions';
+import { DismissAlert } from '@app/core/actions';
 
 @Component({
   selector: 'cse-alert-container',
diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts
index aeb5f72..b877a58 100644
--- a/src/app/shared/shared.module.ts
+++ b/src/app/shared/shared.module.ts
@@ -1,3 +1,4 @@
+import { AlertContainerComponent } from './components/alert-container/alert-container.component';
 import { NgModule } from '@angular/core';
 import { CommonModule } from '@angular/common';
 import { FormsModule, ReactiveFormsModule } from '@angular/forms';
@@ -85,7 +86,13 @@ const directives = [ClickStopPropagationDirective];
 
 @NgModule({
   imports: [modules],
-  exports: [modules, pipes, directives, CourseDetailsComponent],
+  exports: [
+    modules,
+    pipes,
+    directives,
+    CourseDetailsComponent,
+    AlertContainerComponent,
+  ],
   entryComponents: [ConfirmDialogComponent, PromptDialogComponent],
   declarations: [
     pipes,
@@ -97,6 +104,7 @@ const directives = [ClickStopPropagationDirective];
     IE11WarningDialogComponent,
     ConfirmDialogComponent,
     PromptDialogComponent,
+    AlertContainerComponent,
   ],
 })
 export class SharedModule {}
diff --git a/src/assets/mock-data/metadata-response.json b/src/assets/mock-data/metadata-response.json
new file mode 100644
index 0000000..9c59547
--- /dev/null
+++ b/src/assets/mock-data/metadata-response.json
@@ -0,0 +1,17 @@
+[
+  {
+    "darsJobId": "abc123",
+    "darsAuditRunDate": "2019-02-04T20:41:31Z",
+    "sisEmplId": "string",
+    "darsInstitutionCode": "L&S",
+    "darsInstitutionCodeDescription": "Letters & Science, College of",
+    "darsDegreeProgramCode": "BA  916",
+    "darsStatusOfDegreeAuditRequest": "new",
+    "darsHonorsOptionCode": "Z",
+    "darsHonorsOptionDescription": "Omit Major, Include Liberal Arts",
+    "darsDegreeAuditReportId": 0,
+    "darsCatalogYearTerm": "20121",
+    "whichEnrolledCoursesIncluded": "previous",
+    "degreePlannerPlanName": "string"
+  }
+]
-- 
GitLab