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 c8639052b62ab13f10970c3cd865f0f6804d88e0..125dc019188fdd5ccedc161daf44d7a5e1b407c6 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 fea706a1636b76060181ea35f7779c4b56edf8f7..53a4098e6975ed9d5f7b85d5de9e16420013e009 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 27b3b7cd6012144b4c9140af645213fbda1d16fe..5c6d97fc313b95d32ab6153fffe7950f322f2f98 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 39f3209813f5f049b3c3810edae6e262762728a5..5927ac1d28d36320eb3790b3ec75fd3db9de510b 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.