Skip to content
Snippets Groups Projects
Commit 33d8f3fb authored by Isaac Evavold's avatar Isaac Evavold
Browse files

fade plan ui while degree plans are loading

parent 94be3488
No related branches found
No related tags found
No related merge requests found
<mat-sidenav-container hasBackdrop="false" *ngIf="(degreePlan$ | async) as degreePlan"> <mat-sidenav-container hasBackdrop="false">
<mat-sidenav #addMenu position="end" mode="over" [opened]="isCourseSearchOpen$ | async"> <mat-sidenav #addMenu position="end" mode="over" [opened]="isCourseSearchOpen$ | async">
<mat-toolbar color="primary" class="dialog-toolbar"> <mat-toolbar color="primary" class="dialog-toolbar">
<span class="dialog-toolbar-title">Course Search</span> <span class="dialog-toolbar-title">Course Search</span>
...@@ -9,16 +9,18 @@ ...@@ -9,16 +9,18 @@
</mat-sidenav> </mat-sidenav>
<mat-sidenav-content> <mat-sidenav-content>
<mat-progress-bar id="loading-plan-progress" mode="indeterminate" *ngIf="isLoadingPlan$ | async"></mat-progress-bar>
<mat-sidenav-container id="plans-container"> <mat-sidenav-container id="plans-container">
<!-- Menu side nav --> <!-- Menu side nav -->
<mat-sidenav #rightMenu position="end" [mode]="mobileView.matches ? 'over' : 'side'" [opened]="mobileView.matches ? false : true"> <mat-sidenav #rightMenu position="end" [mode]="mobileView.matches ? 'over' : 'side'" [opened]="mobileView.matches ? false : true">
<cse-sidenav-menu-item></cse-sidenav-menu-item> <cse-sidenav-menu-item></cse-sidenav-menu-item>
</mat-sidenav> </mat-sidenav>
<mat-sidenav-content id="degree-plan-wrapper"> <mat-sidenav-content id="degree-plan-wrapper" [ngClass]="{ isLoadingPlan: (isLoadingPlan$ | async) }" *ngIf="(degreePlan$ | async) as degreePlan">
<div fxLayout="row" fxLayout.lt-sm="column" fxLayoutGap="20px" fxLayoutAlign="start center" style="margin: 24px 0px 24px 24px;"> <div fxLayout="row" fxLayout.lt-sm="column" fxLayoutGap="20px" fxLayoutAlign="start center" style="margin: 24px 0px 24px 24px;">
<mat-form-field> <mat-form-field>
<mat-select <mat-select
[disabled]="isLoadingPlan$ | async"
placeholder="Degree Plans" placeholder="Degree Plans"
class="degree-plan-selector" class="degree-plan-selector"
[value]="degreePlan.roadmapId" [value]="degreePlan.roadmapId"
...@@ -40,7 +42,7 @@ ...@@ -40,7 +42,7 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<button mat-icon-button [matMenuTriggerFor]="degreePlanMenu"> <button mat-icon-button [matMenuTriggerFor]="degreePlanMenu" [disabled]="isLoadingPlan$ | async">
<mat-icon>settings</mat-icon> <mat-icon>settings</mat-icon>
</button> </button>
<mat-menu #degreePlanMenu="matMenu"> <mat-menu #degreePlanMenu="matMenu">
...@@ -54,7 +56,8 @@ ...@@ -54,7 +56,8 @@
</mat-menu> </mat-menu>
</div> </div>
<div fxLayout="column" fxLayoutGap="20px" fxLayoutAlign="start stretch" style="margin: 24px"> <div id="year-wrapper" fxLayout="column" fxLayoutGap="20px" fxLayoutAlign="start stretch" style="margin: 24px">
<div id="year-mask" *ngIf="isLoadingPlan$ | async"></div>
<mat-accordion multi="true"> <mat-accordion multi="true">
<ng-container *ngFor="let yearCode of (yearCodes$ | async)"> <ng-container *ngFor="let yearCode of (yearCodes$ | async)">
<cse-year-container [yearCode]="yearCode"></cse-year-container> <cse-year-container [yearCode]="yearCode"></cse-year-container>
......
...@@ -48,3 +48,35 @@ mat-sidenav { ...@@ -48,3 +48,35 @@ mat-sidenav {
padding: 12px; padding: 12px;
} }
} }
// Course search
.search-input-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
}
#loading-plan-progress {
position: absolute;
z-index: 1000;
}
#degree-plan-wrapper.isLoadingPlan {
overflow: hidden;
#year-wrapper {
opacity: 0.5;
}
#year-mask {
width: 100%;
height: 100%;
display: block;
position: absolute;
z-index: 9000;
}
}
#year-mask {
display: none;
}
...@@ -4,8 +4,8 @@ import { ...@@ -4,8 +4,8 @@ import {
withLatestFrom, withLatestFrom,
distinctUntilChanged, distinctUntilChanged,
} from 'rxjs/operators'; } from 'rxjs/operators';
import { OnInit, ViewChild } from '@angular/core'; import { OnInit } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable, of } from 'rxjs';
import { select } from '@ngrx/store'; import { select } from '@ngrx/store';
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { MatSelectChange } from '@angular/material'; import { MatSelectChange } from '@angular/material';
...@@ -51,6 +51,7 @@ export class DegreePlannerComponent implements OnInit { ...@@ -51,6 +51,7 @@ export class DegreePlannerComponent implements OnInit {
public termsByYear$: Observable<Year[]>; public termsByYear$: Observable<Year[]>;
public yearCodes$: Observable<string[]>; public yearCodes$: Observable<string[]>;
public isCourseSearchOpen$: Observable<boolean>; public isCourseSearchOpen$: Observable<boolean>;
public isLoadingPlan$: Observable<boolean>;
constructor( constructor(
private store: Store<GlobalState>, private store: Store<GlobalState>,
...@@ -76,6 +77,8 @@ export class DegreePlannerComponent implements OnInit { ...@@ -76,6 +77,8 @@ export class DegreePlannerComponent implements OnInit {
select(selectors.isCourseSearchOpen), select(selectors.isCourseSearchOpen),
); );
this.isLoadingPlan$ = this.store.pipe(select(selectors.isLoadingPlan));
this.yearCodes$ = this.store.pipe( this.yearCodes$ = this.store.pipe(
select(selectors.selectAllVisibleYears), select(selectors.selectAllVisibleYears),
map(years => Object.keys(years)), map(years => Object.keys(years)),
......
...@@ -122,6 +122,7 @@ export class DegreePlanEffects { ...@@ -122,6 +122,7 @@ export class DegreePlanEffects {
return new InitialLoadSuccess({ return new InitialLoadSuccess({
...INITIAL_DEGREE_PLANNER_STATE, ...INITIAL_DEGREE_PLANNER_STATE,
...payload, ...payload,
isLoadingPlan: false,
}); });
}), }),
catchError(error => { catchError(error => {
......
...@@ -7,6 +7,7 @@ import { ...@@ -7,6 +7,7 @@ import {
import { import {
PlanActionTypes, PlanActionTypes,
InitialLoadSuccess, InitialLoadSuccess,
SwitchPlan,
SwitchPlanSuccess, SwitchPlanSuccess,
MakePlanPrimary, MakePlanPrimary,
MakePlanPrimarySuccess, MakePlanPrimarySuccess,
...@@ -15,6 +16,7 @@ import { ...@@ -15,6 +16,7 @@ import {
ChangePlanNameFailure, ChangePlanNameFailure,
CreatePlanSuccess, CreatePlanSuccess,
DeletePlanSuccess, DeletePlanSuccess,
PlanError,
} from '@app/degree-planner/store/actions/plan.actions'; } from '@app/degree-planner/store/actions/plan.actions';
import { import {
MoveCourseInsideTerm, MoveCourseInsideTerm,
...@@ -24,6 +26,7 @@ import { ...@@ -24,6 +26,7 @@ import {
AddCourseSuccess, AddCourseSuccess,
RemoveSaveForLater, RemoveSaveForLater,
AddSaveForLater, AddSaveForLater,
CourseError,
} from '@app/degree-planner/store/actions/course.actions'; } from '@app/degree-planner/store/actions/course.actions';
import { import {
NoteActionTypes, NoteActionTypes,
...@@ -51,7 +54,9 @@ import { PlannedTerm, PlannedTermEra } from '@app/core/models/planned-term'; ...@@ -51,7 +54,9 @@ import { PlannedTerm, PlannedTermEra } from '@app/core/models/planned-term';
import * as utils from '@app/degree-planner/shared/utils'; import * as utils from '@app/degree-planner/shared/utils';
type SupportedActions = type SupportedActions =
| PlanError
| InitialLoadSuccess | InitialLoadSuccess
| SwitchPlan
| SwitchPlanSuccess | SwitchPlanSuccess
| WriteNoteSuccess | WriteNoteSuccess
| DeleteNoteSuccess | DeleteNoteSuccess
...@@ -81,6 +86,10 @@ export function degreePlannerReducer( ...@@ -81,6 +86,10 @@ export function degreePlannerReducer(
action: SupportedActions, action: SupportedActions,
): DegreePlannerState { ): DegreePlannerState {
switch (action.type) { switch (action.type) {
case PlanActionTypes.PlanError: {
return { ...state, isLoadingPlan: false };
}
/** /**
* The `InitialPlanLoadResponse` action is triggered on initial Degree * The `InitialPlanLoadResponse` action is triggered on initial Degree
* Planner app load. It downloads a list of the user's degree plans and * Planner app load. It downloads a list of the user's degree plans and
...@@ -90,6 +99,10 @@ export function degreePlannerReducer( ...@@ -90,6 +99,10 @@ export function degreePlannerReducer(
return { ...action.payload }; return { ...action.payload };
} }
case PlanActionTypes.SwitchPlan: {
return { ...state, isLoadingPlan: true };
}
/** /**
* The `SwitchPlanSuccess` action is triggered whenever the UI needs * The `SwitchPlanSuccess` action is triggered whenever the UI needs
* to switch which degree plan is being shown and load the data associated * to switch which degree plan is being shown and load the data associated
...@@ -97,7 +110,7 @@ export function degreePlannerReducer( ...@@ -97,7 +110,7 @@ export function degreePlannerReducer(
* action payload and builds a new state using that data. * action payload and builds a new state using that data.
*/ */
case PlanActionTypes.SwitchPlanSuccess: { case PlanActionTypes.SwitchPlanSuccess: {
return { ...state, ...action.payload }; return { ...state, ...action.payload, isLoadingPlan: false };
} }
/** /**
......
...@@ -122,6 +122,10 @@ export const isPastTerm = (termCode: string) => ...@@ -122,6 +122,10 @@ export const isPastTerm = (termCode: string) =>
return termCode < currentTermCode; return termCode < currentTermCode;
}, },
); );
export const isLoadingPlan = createSelector(
getDegreePlannerState,
(state: DegreePlannerState) => state.isLoadingPlan,
);
const getTermForCode = (termCode: string, terms: PlannedTerm[]) => { const getTermForCode = (termCode: string, terms: PlannedTerm[]) => {
const foundTerm = terms.find(term => term.termCode === termCode); const foundTerm = terms.find(term => term.termCode === termCode);
......
...@@ -14,6 +14,7 @@ export interface DegreePlannerState { ...@@ -14,6 +14,7 @@ export interface DegreePlannerState {
subjectDescriptions: SubjectMapping; subjectDescriptions: SubjectMapping;
expandedYears: string[]; expandedYears: string[];
search: { visible: boolean; selectedTerm: string }; search: { visible: boolean; selectedTerm: string };
isLoadingPlan: boolean;
} }
export const INITIAL_DEGREE_PLANNER_STATE: DegreePlannerState = { export const INITIAL_DEGREE_PLANNER_STATE: DegreePlannerState = {
...@@ -26,4 +27,5 @@ export const INITIAL_DEGREE_PLANNER_STATE: DegreePlannerState = { ...@@ -26,4 +27,5 @@ export const INITIAL_DEGREE_PLANNER_STATE: DegreePlannerState = {
subjectDescriptions: {}, subjectDescriptions: {},
expandedYears: [], expandedYears: [],
search: { visible: false, selectedTerm: '0000' }, search: { visible: false, selectedTerm: '0000' },
isLoadingPlan: true,
}; };
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment