diff --git a/src/app/core/models/year.ts b/src/app/core/models/year.ts index ed4cef95deb26833217eddd4cf9d55607b00d8ea..f462c4f62b19cbba6f3118c50a50decc2ef76c8a 100644 --- a/src/app/core/models/year.ts +++ b/src/app/core/models/year.ts @@ -1,9 +1,10 @@ import { PlannedTerm } from '@app/core/models/planned-term'; export interface Year { - century: 0 | 1; - twoDigitYearCode: number; - fall: PlannedTerm; - spring: PlannedTerm; - summer: PlannedTerm; + century: 0 | 1; + twoDigitYearCode: number; + fall: PlannedTerm; + spring: PlannedTerm; + summer: PlannedTerm; + expandedState: boolean; } diff --git a/src/app/degree-planner/degree-planner.component.html b/src/app/degree-planner/degree-planner.component.html index 6aec034b5c00b82c04daad38058073064f841c50..5c0face0792555d1cb3a4f624073b10e92057c07 100644 --- a/src/app/degree-planner/degree-planner.component.html +++ b/src/app/degree-planner/degree-planner.component.html @@ -45,7 +45,7 @@ <div fxLayout="column" fxLayoutGap="20px" fxLayoutAlign="start stretch" style="margin: 24px"> <mat-accordion multi="true" *ngIf="(firstActiveTermCode$ | async) as cutoffTermCode"> <ng-container *ngFor="let year of termsByYear$ | async"> - <mat-expansion-panel class="year-container"[expanded]="true"> + <mat-expansion-panel class="year-container" [expanded]="year.expandedState" (opened)="handleAcademicYearToggle(year)" (closed)="handleAcademicYearToggle(year)"> <mat-expansion-panel-header> <mat-panel-title> {{ year.twoDigitYearCode | academicYearState:cutoffTermCode }} diff --git a/src/app/degree-planner/degree-planner.component.ts b/src/app/degree-planner/degree-planner.component.ts index ebfa23d9d0d868f073a1ac043f93270b83b3731b..1226c10021af6660be21ffe070033eb5b262cfe0 100644 --- a/src/app/degree-planner/degree-planner.component.ts +++ b/src/app/degree-planner/degree-planner.component.ts @@ -1,9 +1,14 @@ +import { tap } from 'rxjs/operators'; // Libraries import { OnInit } from '@angular/core'; import { Observable } from 'rxjs'; import { select } from '@ngrx/store'; import { Component } from '@angular/core'; -import { MatSelectChange } from '@angular/material'; +import { + MatSelectChange, + MatExpansionPanelState, + MatExpansionPanel, +} from '@angular/material'; import { MatDialog } from '@angular/material'; import { Store } from '@ngrx/store'; import { MediaMatcher } from '@angular/cdk/layout'; @@ -30,6 +35,7 @@ import { } from '@app/degree-planner/store/actions/plan.actions'; import { ModifyPlanDialogComponent } from './dialogs/modify-plan-dialog/modify-plan-dialog.component'; +import { ToggleAcademicYear } from './store/actions/ui.actions'; @Component({ selector: 'cse-degree-planner', @@ -65,6 +71,12 @@ export class DegreePlannerComponent implements OnInit { this.termsByYear$ = this.store.pipe(select(getAllVisibleTermsByYear)); } + public handleAcademicYearToggle(year: Year): void { + // this.store.dispatch( + // new ToggleAcademicYear({ year: year.twoDigitYearCode.toString() }), + // ); + } + public handleDegreePlanChange(event: MatSelectChange): void { if (typeof event.value === 'number') { this.store.dispatch(new SwitchPlan({ newVisibleRoadmapId: event.value })); diff --git a/src/app/degree-planner/store/actions/ui.actions.ts b/src/app/degree-planner/store/actions/ui.actions.ts new file mode 100644 index 0000000000000000000000000000000000000000..21964d32eabe4a0f698ef68849a1eea84ab31977 --- /dev/null +++ b/src/app/degree-planner/store/actions/ui.actions.ts @@ -0,0 +1,10 @@ +import { Action } from '@ngrx/store'; + +export enum UIActionTypes { + ToggleAcademicYear = '[UI] Toggle Academic Year', +} + +export class ToggleAcademicYear implements Action { + public readonly type = UIActionTypes.ToggleAcademicYear; + constructor(public payload: { year: string }) {} +} diff --git a/src/app/degree-planner/store/effects/plan.effects.ts b/src/app/degree-planner/store/effects/plan.effects.ts index 5c6d97fc313b95d32ab6153fffe7950f322f2f98..c590aae968e3fcf9eaf61a7f96850650a5213718 100644 --- a/src/app/degree-planner/store/effects/plan.effects.ts +++ b/src/app/degree-planner/store/effects/plan.effects.ts @@ -1,3 +1,4 @@ +import { tap } from 'rxjs/operators'; // Libraries import { Injectable } from '@angular/core'; import { ROOT_EFFECTS_INIT, Actions, Effect, ofType } from '@ngrx/effects'; @@ -81,6 +82,18 @@ export class DegreePlanEffects { }); }), + map(payload => { + const allTerms = payload.visibleTerms.map(term => term.termCode); + const currentIndex = allTerms.indexOf(payload.activeTermCodes[0]); + const expandedTerms = allTerms.slice(currentIndex - allTerms.length); + const expandedYearsDups = expandedTerms.map(term => term.substr(1, 2)); + const expandedYears = expandedYearsDups.filter(function(item, pos, self) { + return self.indexOf(item) === pos; + }); + + return { ...payload, expandedYears }; + }), + map(payload => new InitialLoadSuccess(payload)), catchError(error => { @@ -278,3 +291,7 @@ const pickPrimaryDegreePlan = (plans: DegreePlan[]): DegreePlan => { const primary = plans.find(plan => plan.primary); return primary ? primary : plans[0]; }; + +const checkExpanded = (activeTermCodes, visibleTerms) => { + console.log(visibleTerms); +}; diff --git a/src/app/degree-planner/store/reducer.ts b/src/app/degree-planner/store/reducer.ts index 5927ac1d28d36320eb3790b3ec75fd3db9de510b..08e3c4615786ec5d83ae96247138c5b40ed1534e 100644 --- a/src/app/degree-planner/store/reducer.ts +++ b/src/app/degree-planner/store/reducer.ts @@ -1,3 +1,4 @@ +import { UIActionTypes } from './actions/ui.actions'; import { DegreePlannerState, INITIAL_DEGREE_PLANNER_STATE, @@ -29,6 +30,7 @@ import { AddAcademicYearActionTypes, AddAcademicYearRequest, } from '@app/degree-planner/store/actions/addAcademicYear.actions'; +import { ToggleAcademicYear } from '@app/degree-planner/store/actions/ui.actions'; import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course'; import { DegreePlan } from '@app/core/models/degree-plan'; @@ -47,7 +49,8 @@ type SupportedActions = | MakePlanPrimarySuccess | MakePlanPrimaryFailure | ChangePlanNameSuccess - | ChangePlanNameFailure; + | ChangePlanNameFailure + | ToggleAcademicYear; export function degreePlannerReducer( state = INITIAL_DEGREE_PLANNER_STATE, @@ -93,6 +96,13 @@ export function degreePlannerReducer( return { ...state, visibleTerms: newVisibleTerms }; } + /** + * The `ToggleAcademicYear` action toggles the expand/collapse UI state + */ + case UIActionTypes.ToggleAcademicYear: { + return { ...state }; + } + /** * The `WriteNoteResponse` action is dispatched by the `Note.write$` effect * upon a successful response from the `updateNote` or `createNote` API diff --git a/src/app/degree-planner/store/selectors.ts b/src/app/degree-planner/store/selectors.ts index 0ff6c63842368ce7b1ab4e9ddb329a762ab032cb..bbfa1571da8c87df1a500a50c247058a32b8141f 100644 --- a/src/app/degree-planner/store/selectors.ts +++ b/src/app/degree-planner/store/selectors.ts @@ -76,6 +76,8 @@ export const getAllVisibleTermsByYear = createSelector( fall: getTermForCode(`${year}2`, state.visibleTerms), spring: getTermForCode(`${year}4`, state.visibleTerms), summer: getTermForCode(`${year}6`, state.visibleTerms), + expandedState: + state.expandedYears.indexOf(twoDigitYearCode.toString()) > -1, }; }); }, diff --git a/src/app/degree-planner/store/state.ts b/src/app/degree-planner/store/state.ts index 9cc6a2adaa8412d56aafaabcfe1d1e42b096c66d..89d40628b7783de0e6887b83733ce3a1b2b7b709 100644 --- a/src/app/degree-planner/store/state.ts +++ b/src/app/degree-planner/store/state.ts @@ -11,6 +11,7 @@ export interface DegreePlannerState { activeTermCodes: string[]; allDegreePlans: DegreePlan[]; subjects: SubjectMapping; + expandedYears: string[]; } export const INITIAL_DEGREE_PLANNER_STATE: DegreePlannerState = { @@ -20,4 +21,5 @@ export const INITIAL_DEGREE_PLANNER_STATE: DegreePlannerState = { activeTermCodes: [], allDegreePlans: [], subjects: {}, + expandedYears: [], };