From 726d0cae8470a5ae57193727fa42f33af8576755 Mon Sep 17 00:00:00 2001
From: Scott Berg <saberg3@wisc.edu>
Date: Tue, 12 Feb 2019 16:03:11 -0600
Subject: [PATCH] ROENROLL-1358

---
 .../modify-plan-dialog.component.ts           | 10 ++++-
 .../store/actions/plan.actions.ts             | 19 ++++++++
 .../store/effects/plan.effects.ts             | 43 ++++++++++++++++++-
 src/app/degree-planner/store/reducer.ts       | 37 ++++++++++------
 4 files changed, 94 insertions(+), 15 deletions(-)

diff --git a/src/app/degree-planner/dialogs/modify-plan-dialog/modify-plan-dialog.component.ts b/src/app/degree-planner/dialogs/modify-plan-dialog/modify-plan-dialog.component.ts
index c863905..125dc01 100644
--- a/src/app/degree-planner/dialogs/modify-plan-dialog/modify-plan-dialog.component.ts
+++ b/src/app/degree-planner/dialogs/modify-plan-dialog/modify-plan-dialog.component.ts
@@ -1,5 +1,12 @@
 import { FormGroup, FormControl } from '@angular/forms';
 import { Component, OnInit } from '@angular/core';
+import { Store } from '@ngrx/store';
+
+// Models
+import { GlobalState } from '@app/core/state';
+
+// Actions
+import { ChangePlanName } from '@app/degree-planner/store/actions/plan.actions';
 
 @Component({
   selector: 'cse-course-details-dialog',
@@ -8,7 +15,7 @@ import { Component, OnInit } from '@angular/core';
 export class ModifyPlanDialogComponent implements OnInit {
   public form: FormGroup;
 
-  constructor() {
+  constructor(private store: Store<GlobalState>) {
     this.form = new FormGroup({
       planName: new FormControl(),
     });
@@ -17,6 +24,7 @@ export class ModifyPlanDialogComponent implements OnInit {
   ngOnInit() {}
 
   renamePlanSave() {
+    this.store.dispatch(new ChangePlanName(this.form.value.planName));
     console.log('PUT /degreePlan/<planId> { primary: <bool>, name: <string> }');
   }
   makePlanPrimarySave() {
diff --git a/src/app/degree-planner/store/actions/plan.actions.ts b/src/app/degree-planner/store/actions/plan.actions.ts
index fea706a..53a4098 100644
--- a/src/app/degree-planner/store/actions/plan.actions.ts
+++ b/src/app/degree-planner/store/actions/plan.actions.ts
@@ -14,6 +14,10 @@ export enum PlanActionTypes {
   MakePlanPrimary = '[Plan] Make Plan Primary',
   MakePlanPrimarySuccess = '[Plan] Make Plan Primary Success',
   MakePlanPrimaryFailure = '[Plan] Make Plan Primary Failure',
+
+  ChangePlanName = '[Plan] Change Plan Name',
+  ChangePlanNameSuccess = '[Plan] Change Plan Name Success',
+  ChangePlanNameFailure = '[Plan] Change Plan Name Failure',
 }
 
 export class InitialLoadSuccess implements Action {
@@ -55,3 +59,18 @@ export class MakePlanPrimaryFailure implements Action {
   public readonly type = PlanActionTypes.MakePlanPrimaryFailure;
   constructor() {}
 }
+
+export class ChangePlanName implements Action {
+  public readonly type = PlanActionTypes.ChangePlanName;
+  constructor(public name: string) {}
+}
+
+export class ChangePlanNameSuccess implements Action {
+  public readonly type = PlanActionTypes.ChangePlanNameSuccess;
+  constructor(public name: string) {}
+}
+
+export class ChangePlanNameFailure implements Action {
+  public readonly type = PlanActionTypes.ChangePlanNameFailure;
+  constructor(public name: string) {}
+}
diff --git a/src/app/degree-planner/store/effects/plan.effects.ts b/src/app/degree-planner/store/effects/plan.effects.ts
index 27b3b7c..5c6d97f 100644
--- a/src/app/degree-planner/store/effects/plan.effects.ts
+++ b/src/app/degree-planner/store/effects/plan.effects.ts
@@ -23,9 +23,10 @@ import {
   SwitchPlanSuccess,
   PlanActionTypes,
   PlanError,
-  MakePlanPrimary,
   MakePlanPrimarySuccess,
   MakePlanPrimaryFailure,
+  ChangePlanNameSuccess,
+  ChangePlanNameFailure,
 } from '@app/degree-planner/store/actions/plan.actions';
 
 // Models
@@ -149,6 +150,46 @@ export class DegreePlanEffects {
     }),
   );
 
+  @Effect()
+  ChangePlanName$ = this.actions$.pipe(
+    ofType<any>(PlanActionTypes.ChangePlanName),
+
+    withLatestFrom(this.store$.select(getDegreePlannerState)),
+    filter(([_, state]) => state.visibleDegreePlan !== undefined),
+
+    // Get term data for the degree plan specified by the roadmap ID.
+    flatMap(([action, state]) => {
+      console.log(action);
+      const { name } = action;
+
+      const {
+        roadmapId,
+        name: previousName,
+        primary,
+      } = state.visibleDegreePlan as DegreePlan;
+
+      action.previousName = previousName;
+      // TODO error handle the API calls
+      return this.api.updatePlan(roadmapId, name, primary).pipe(
+        map(response => {
+          return {
+            response,
+            action,
+          };
+        }),
+      );
+    }),
+
+    // // Wrap data in an Action for dispatch
+    map(({ response, action }) => {
+      if (response === 1) {
+        return new ChangePlanNameSuccess(action.name);
+      } else {
+        return new ChangePlanNameFailure(action.previousName);
+      }
+    }),
+  );
+
   private loadSavedForLaterCourses(subjects: SubjectMapping) {
     return this.api.getSavedForLaterCourses().pipe(
       map(courseBases => {
diff --git a/src/app/degree-planner/store/reducer.ts b/src/app/degree-planner/store/reducer.ts
index 39f3209..5927ac1 100644
--- a/src/app/degree-planner/store/reducer.ts
+++ b/src/app/degree-planner/store/reducer.ts
@@ -9,6 +9,8 @@ import {
   MakePlanPrimary,
   MakePlanPrimarySuccess,
   MakePlanPrimaryFailure,
+  ChangePlanNameSuccess,
+  ChangePlanNameFailure,
 } from '@app/degree-planner/store/actions/plan.actions';
 import {
   CourseActionTypes,
@@ -26,7 +28,7 @@ import {
 import {
   AddAcademicYearActionTypes,
   AddAcademicYearRequest,
- } from '@app/degree-planner/store/actions/addAcademicYear.actions';
+} from '@app/degree-planner/store/actions/addAcademicYear.actions';
 import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course';
 import { DegreePlan } from '@app/core/models/degree-plan';
 
@@ -43,7 +45,9 @@ type SupportedActions =
   | AddAcademicYearRequest
   | MakePlanPrimary
   | MakePlanPrimarySuccess
-  | MakePlanPrimaryFailure;
+  | MakePlanPrimaryFailure
+  | ChangePlanNameSuccess
+  | ChangePlanNameFailure;
 
 export function degreePlannerReducer(
   state = INITIAL_DEGREE_PLANNER_STATE,
@@ -72,9 +76,9 @@ export function degreePlannerReducer(
     /**
      * The `AddAcademicYearRequest` action is triggered after `addAcademicYear()`
      * function runs. A new academic year container with three terms will be created.
-    */
+     */
     case AddAcademicYearActionTypes.AddAcademicYearRequest: {
-      const originalTerms = state.visibleTerms.map( term => {
+      const originalTerms = state.visibleTerms.map(term => {
         return parseInt(term.termCode.substr(0, 3), 10);
       });
 
@@ -82,15 +86,9 @@ export function degreePlannerReducer(
 
       const newVisibleTerms = [
         ...state.visibleTerms,
-        { termCode: `${newAcademicYearCode}2`,
-          courses: []
-        },
-        { termCode: `${newAcademicYearCode}4`,
-          courses: []
-        },
-        { termCode: `${newAcademicYearCode}6`,
-          courses: []
-        }
+        { termCode: `${newAcademicYearCode}2`, courses: [] },
+        { termCode: `${newAcademicYearCode}4`, courses: [] },
+        { termCode: `${newAcademicYearCode}6`, courses: [] },
       ];
       return { ...state, visibleTerms: newVisibleTerms };
     }
@@ -290,6 +288,19 @@ export function degreePlannerReducer(
       return state;
     }
 
+    case PlanActionTypes.ChangePlanNameSuccess:
+    case PlanActionTypes.ChangePlanNameFailure: {
+      // TODO add global loading state
+
+      // Update the visible plan object
+      const newVisibleDegreePlan = {
+        ...(state.visibleDegreePlan as DegreePlan),
+        name: action.name,
+      };
+
+      return { ...state, visibleDegreePlan: newVisibleDegreePlan };
+    }
+
     /**
      * It's okay if the action didn't match any of the cases above. If that's
      * the case, just return the existing state object.
-- 
GitLab