diff --git a/src/app/degree-planner/degree-planner.component.html b/src/app/degree-planner/degree-planner.component.html index 98175f91db73df425b0204c55a776e1160f0ca4d..34a952fbded76f1257a71f83bab90ba5ced9beee 100644 --- a/src/app/degree-planner/degree-planner.component.html +++ b/src/app/degree-planner/degree-planner.component.html @@ -139,6 +139,11 @@ fxLayoutAlign="start stretch" style="margin:24px 24px 72px 24px"> <div id="year-mask" *ngIf="(isLoadingPlan$ | async)"></div> + <div id="accordion-controls"> + <button mat-button color="primary" (click)="toggleAllYears(true)" aria-label="Expand All Years">Expand All</button> + <span>|</span> + <button mat-button color="primary" (click)="toggleAllYears(false)" aria-label="Collapse All Years">Collapse All</button> + </div> <mat-accordion multi="true"> <cse-year-container *ngFor="let yearCode of yearCodes$ | async; trackBy: trackYearCodes" diff --git a/src/app/degree-planner/degree-planner.component.scss b/src/app/degree-planner/degree-planner.component.scss index 3be88ddb787797d48044711c0117b84fbef27c18..8b5f2b7aad08a0c153d9ce8d3066f49d72bff230 100644 --- a/src/app/degree-planner/degree-planner.component.scss +++ b/src/app/degree-planner/degree-planner.component.scss @@ -1,3 +1,5 @@ +@import 'assets/material-theme.scss'; + #plans-container { height: calc(100vh - 112px); @@ -103,3 +105,8 @@ mat-sidenav { #year-mask { display: none; } + +#accordion-controls { + text-align: right; + color: map-get($uw-primary, 500); +} diff --git a/src/app/degree-planner/degree-planner.component.ts b/src/app/degree-planner/degree-planner.component.ts index fa2374fb9a8480c6fedd96c70c20a57dfad44598..c149767fc8f13b7044b8c597918cd68cfb376479 100644 --- a/src/app/degree-planner/degree-planner.component.ts +++ b/src/app/degree-planner/degree-planner.component.ts @@ -31,6 +31,8 @@ import { CloseCourseSearch, CloseSidenav, OpenSidenav, + ExpandAcademicYear, + CollapseAcademicYear, } from './store/actions/ui.actions'; import { YearCode } from '@app/core/models/termcode'; import { ConstantsService } from './services/constants.service'; @@ -269,6 +271,13 @@ export class DegreePlannerComponent implements OnInit { public trackYearCodes(_index: number, yearCode: YearCode) { return yearCode.toString(); } + + public toggleAllYears(expand: boolean) { + const event = expand + ? new ExpandAcademicYear() + : new CollapseAcademicYear(); + this.store.dispatch(event); + } } const isntUndefined = <T>(anything: T | undefined): anything is T => { diff --git a/src/app/degree-planner/store/actions/ui.actions.ts b/src/app/degree-planner/store/actions/ui.actions.ts index 220b0b0e41174af7bd75d5de6e8c41d1f11db33d..1e208197b4e7753f99b00264e7484f39d31b7c60 100644 --- a/src/app/degree-planner/store/actions/ui.actions.ts +++ b/src/app/degree-planner/store/actions/ui.actions.ts @@ -23,12 +23,12 @@ export class ToggleAcademicYear implements Action { export class ExpandAcademicYear implements Action { public readonly type = UIActionTypes.ExpandAcademicYear; - constructor(public payload: { yearCode: YearCode }) {} + constructor(public payload?: { yearCode: YearCode }) {} } export class CollapseAcademicYear implements Action { public readonly type = UIActionTypes.CollapseAcademicYear; - constructor(public payload: { yearCode: YearCode }) {} + constructor(public payload?: { yearCode: YearCode }) {} } export class OpenCourseSearch implements Action { diff --git a/src/app/degree-planner/store/reducer.ts b/src/app/degree-planner/store/reducer.ts index fc23f03e04b32046d7965c6a791c60c4b111b5cf..16868620f5cb10ceabbf36f603786c4689e608ff 100644 --- a/src/app/degree-planner/store/reducer.ts +++ b/src/app/degree-planner/store/reducer.ts @@ -150,31 +150,33 @@ export function degreePlannerReducer( } case UIActionTypes.ExpandAcademicYear: { - const yearCode = action.payload.yearCode; - return { - ...state, - visibleYears: { - ...state.visibleYears, - [yearCode.toString()]: { - ...state.visibleYears[yearCode.toString()], - isExpanded: true, - }, - }, - }; + const yearCode = action.payload ? action.payload.yearCode : undefined; + const newState = { ...state }; + + if (yearCode) { + newState.visibleYears[yearCode.toString()].isExpanded = true; + } else { + Object.entries(newState.visibleYears).forEach(([code, year]) => { + newState.visibleYears[code].isExpanded = true; + }); + } + + return newState; } case UIActionTypes.CollapseAcademicYear: { - const yearCode = action.payload.yearCode; - return { - ...state, - visibleYears: { - ...state.visibleYears, - [yearCode.toString()]: { - ...state.visibleYears[yearCode.toString()], - isExpanded: false, - }, - }, - }; + const yearCode = action.payload ? action.payload.yearCode : undefined; + const newState = { ...state }; + + if (yearCode) { + newState.visibleYears[yearCode.toString()].isExpanded = false; + } else { + Object.entries(newState.visibleYears).forEach(([code, year]) => { + newState.visibleYears[code].isExpanded = false; + }); + } + + return newState; } /**