Skip to content
Snippets Groups Projects
Commit 75a72a46 authored by Isaac Evavold's avatar Isaac Evavold Committed by Joe Van Boxtel
Browse files

move user preferences to global state

parent 97d9a56e
No related branches found
No related tags found
No related merge requests found
...@@ -21,15 +21,20 @@ import { IE11WarningDialogComponent } from './degree-planner/dialogs/ie11-warnin ...@@ -21,15 +21,20 @@ import { IE11WarningDialogComponent } from './degree-planner/dialogs/ie11-warnin
import { darsReducer } from './dars/store/reducer'; import { darsReducer } from './dars/store/reducer';
import { DARSModule } from './dars/dars.module'; import { DARSModule } from './dars/dars.module';
import { DegreePlannerModule } from './degree-planner/degree-planner.module'; import { DegreePlannerModule } from './degree-planner/degree-planner.module';
import { preferencesReducer } from './core/reducer';
import { UserPreferencesEffects } from './core/effects';
import { EffectsModule } from '@ngrx/effects';
@NgModule({ @NgModule({
imports: [ imports: [
DARSModule, DARSModule,
DegreePlannerModule, DegreePlannerModule,
StoreModule.forRoot({ StoreModule.forRoot({
preferences: preferencesReducer,
degreePlanner: degreePlannerReducer, degreePlanner: degreePlannerReducer,
dars: darsReducer, dars: darsReducer,
}), }),
EffectsModule.forFeature([UserPreferencesEffects]),
BrowserModule, BrowserModule,
BrowserAnimationsModule, BrowserAnimationsModule,
HttpClientModule, HttpClientModule,
......
...@@ -4,6 +4,7 @@ import { UserPreferences } from '@app/core/models/user-preferences'; ...@@ -4,6 +4,7 @@ import { UserPreferences } from '@app/core/models/user-preferences';
export enum UserPreferencesActionTypes { export enum UserPreferencesActionTypes {
UpdateUserPreferences = '[User Preferences] Update', UpdateUserPreferences = '[User Preferences] Update',
} }
export class UpdateUserPreferences implements Action { export class UpdateUserPreferences implements Action {
public readonly type = UserPreferencesActionTypes.UpdateUserPreferences; public readonly type = UserPreferencesActionTypes.UpdateUserPreferences;
constructor(public payload: Partial<UserPreferences>) {} constructor(public payload: Partial<UserPreferences>) {}
......
...@@ -4,10 +4,8 @@ import { tap, withLatestFrom } from 'rxjs/operators'; ...@@ -4,10 +4,8 @@ import { tap, withLatestFrom } from 'rxjs/operators';
import { GlobalState } from '@app/core/state'; import { GlobalState } from '@app/core/state';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { DegreePlannerApiService } from '@app/degree-planner/services/api.service'; import { DegreePlannerApiService } from '@app/degree-planner/services/api.service';
import { import { UpdateUserPreferences, UserPreferencesActionTypes } from './actions';
UpdateUserPreferences, import { UserPreferences } from './models/user-preferences';
UserPreferencesActionTypes,
} from '@app/degree-planner/store/actions/userPreferences.actions';
@Injectable() @Injectable()
export class UserPreferencesEffects { export class UserPreferencesEffects {
...@@ -23,7 +21,7 @@ export class UserPreferencesEffects { ...@@ -23,7 +21,7 @@ export class UserPreferencesEffects {
), ),
withLatestFrom(this.store$), withLatestFrom(this.store$),
tap(([update, state]) => { tap(([update, state]) => {
const prefs = { ...state.degreePlanner.userPreferences }; const prefs: UserPreferences = { ...state.preferences };
// Remove properties who's value is undefined // Remove properties who's value is undefined
Object.entries(update.payload).forEach(([key, value]) => { Object.entries(update.payload).forEach(([key, value]) => {
......
import { UserPreferencesActionTypes, UpdateUserPreferences } from './actions';
import { INITIAL_PREFERENCES_STATE } from './state';
import { UserPreferences } from './models/user-preferences';
export function preferencesReducer(
state = INITIAL_PREFERENCES_STATE,
action: UpdateUserPreferences,
): UserPreferences {
switch (action.type) {
case UserPreferencesActionTypes.UpdateUserPreferences: {
const update: UserPreferences = { ...state };
// Remove properties who's value is undefined
Object.entries(action.payload).forEach(([key, value]) => {
if (value === undefined && update[key] !== undefined) {
delete update[key];
} else {
update[key] = value;
}
});
return update;
}
default:
return state;
}
}
import { createSelector } from '@ngrx/store';
import { GlobalState } from './state';
import { UserPreferences } from './models/user-preferences';
export const getUserPreference = createSelector(
(state: GlobalState) => state.preferences,
(preferences: UserPreferences, pref: keyof UserPreferences): unknown => {
return preferences[pref];
},
);
import { DARSState } from '@app/dars/store/state'; import { DARSState } from '@app/dars/store/state';
import { DegreePlannerState } from '@app/degree-planner/store/state'; import { DegreePlannerState } from '@app/degree-planner/store/state';
import { UserPreferences } from './models/user-preferences';
export interface GlobalState { export interface GlobalState {
preferences: UserPreferences;
dars: DARSState; dars: DARSState;
degreePlanner: DegreePlannerState; degreePlanner: DegreePlannerState;
} }
export const INITIAL_PREFERENCES_STATE: UserPreferences = {};
...@@ -41,7 +41,8 @@ import { YearCode } from '@app/degree-planner/shared/term-codes/yearcode'; ...@@ -41,7 +41,8 @@ import { YearCode } from '@app/degree-planner/shared/term-codes/yearcode';
import { ConstantsService } from '../services/constants.service'; import { ConstantsService } from '../services/constants.service';
import { TermCodeFactory } from '../services/termcode.factory'; import { TermCodeFactory } from '../services/termcode.factory';
import { IE11WarningDialogComponent } from '../dialogs/ie11-warning-dialog/ie11-warning-dialog.component'; import { IE11WarningDialogComponent } from '../dialogs/ie11-warning-dialog/ie11-warning-dialog.component';
import { UpdateUserPreferences } from '../store/actions/userPreferences.actions'; import { getUserPreference } from '@app/core/selectors';
import { UpdateUserPreferences } from '@app/core/actions';
// From: https://stackoverflow.com/a/21825207 // From: https://stackoverflow.com/a/21825207
const isIE11 = const isIE11 =
...@@ -91,7 +92,7 @@ export class DegreePlannerViewComponent implements OnInit { ...@@ -91,7 +92,7 @@ export class DegreePlannerViewComponent implements OnInit {
this.showGrades$ = this.store.pipe(select(selectors.selectGradeVisibility)); this.showGrades$ = this.store.pipe(select(selectors.selectGradeVisibility));
this.hasDismissedIEWarning$ = this.store.pipe( this.hasDismissedIEWarning$ = this.store.pipe(
select(selectors.getUserPreference, 'degreePlannerHasDismissedIEWarning'), select(getUserPreference, 'degreePlannerHasDismissedIEWarning'),
map(hasDismissedIEWarning => hasDismissedIEWarning === true), map(hasDismissedIEWarning => hasDismissedIEWarning === true),
); );
......
...@@ -16,7 +16,6 @@ import { DegreePlanEffects } from './store/effects/plan.effects'; ...@@ -16,7 +16,6 @@ import { DegreePlanEffects } from './store/effects/plan.effects';
import { NoteEffects } from './store/effects/note.effects'; import { NoteEffects } from './store/effects/note.effects';
import { CourseEffects } from './store/effects/course.effects'; import { CourseEffects } from './store/effects/course.effects';
import { ErrorEffects } from './store/effects/error.effects'; import { ErrorEffects } from './store/effects/error.effects';
import { UserPreferencesEffects } from './store/effects/userPreferences.effects';
@NgModule({ @NgModule({
imports: [ imports: [
...@@ -27,7 +26,6 @@ import { UserPreferencesEffects } from './store/effects/userPreferences.effects' ...@@ -27,7 +26,6 @@ import { UserPreferencesEffects } from './store/effects/userPreferences.effects'
NoteEffects, NoteEffects,
CourseEffects, CourseEffects,
ErrorEffects, ErrorEffects,
UserPreferencesEffects,
]), ]),
], ],
exports: [DragDropModule], exports: [DragDropModule],
......
...@@ -9,6 +9,7 @@ import { ...@@ -9,6 +9,7 @@ import {
withLatestFrom, withLatestFrom,
catchError, catchError,
filter, filter,
switchMap,
} from 'rxjs/operators'; } from 'rxjs/operators';
import { GlobalState } from '@app/core/state'; import { GlobalState } from '@app/core/state';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
...@@ -41,7 +42,7 @@ import { Note } from '@app/core/models/note'; ...@@ -41,7 +42,7 @@ import { Note } from '@app/core/models/note';
import { CourseBase, Course } from '@app/core/models/course'; import { CourseBase, Course } from '@app/core/models/course';
import { TermCode } from '@app/degree-planner/shared/term-codes/termcode'; import { TermCode } from '@app/degree-planner/shared/term-codes/termcode';
import { Alert, DisclaimerAlert } from '@app/core/models/alert'; import { Alert, DisclaimerAlert } from '@app/core/models/alert';
import { UpdateUserPreferences } from '../actions/userPreferences.actions'; import { UpdateUserPreferences } from '@app/core/actions';
import { TermCodeFactory } from '@app/degree-planner/services/termcode.factory'; import { TermCodeFactory } from '@app/degree-planner/services/termcode.factory';
@Injectable() @Injectable()
...@@ -107,15 +108,18 @@ export class DegreePlanEffects { ...@@ -107,15 +108,18 @@ export class DegreePlanEffects {
savedForLaterCourses, savedForLaterCourses,
allDegreePlans: of(allDegreePlans), allDegreePlans: of(allDegreePlans),
alerts: of(alerts), alerts: of(alerts),
userPreferences: of(userPreferences), }).pipe(
}); switchMap(payload => {
}), return [
map(payload => { new InitialLoadSuccess({
return new InitialLoadSuccess({ ...INITIAL_DEGREE_PLANNER_STATE,
...INITIAL_DEGREE_PLANNER_STATE, ...payload,
...payload, isLoadingPlan: false,
isLoadingPlan: false, }),
}); new UpdateUserPreferences(userPreferences),
];
}),
);
}), }),
catchError(error => { catchError(error => {
return of( return of(
......
...@@ -6,7 +6,6 @@ import * as planActions from '@app/degree-planner/store/actions/plan.actions'; ...@@ -6,7 +6,6 @@ import * as planActions from '@app/degree-planner/store/actions/plan.actions';
import * as courseActions from '@app/degree-planner/store/actions/course.actions'; import * as courseActions from '@app/degree-planner/store/actions/course.actions';
import * as noteActions from '@app/degree-planner/store/actions/note.actions'; import * as noteActions from '@app/degree-planner/store/actions/note.actions';
import * as uiActions from '@app/degree-planner/store/actions/ui.actions'; import * as uiActions from '@app/degree-planner/store/actions/ui.actions';
import * as userPrefsActions from './actions/userPreferences.actions';
import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course'; import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course';
import { DegreePlan } from '@app/core/models/degree-plan'; import { DegreePlan } from '@app/core/models/degree-plan';
import { Year, YearMapping } from '@app/core/models/year'; import { Year, YearMapping } from '@app/core/models/year';
...@@ -49,8 +48,7 @@ type SupportedActions = ...@@ -49,8 +48,7 @@ type SupportedActions =
| uiActions.OpenSidenav | uiActions.OpenSidenav
| uiActions.CloseSidenav | uiActions.CloseSidenav
| uiActions.UpdateSearchTermCode | uiActions.UpdateSearchTermCode
| planActions.ChangeGradeVisibility | planActions.ChangeGradeVisibility;
| userPrefsActions.UpdateUserPreferences;
export function degreePlannerReducer( export function degreePlannerReducer(
state = INITIAL_DEGREE_PLANNER_STATE, state = INITIAL_DEGREE_PLANNER_STATE,
...@@ -222,23 +220,6 @@ export function degreePlannerReducer( ...@@ -222,23 +220,6 @@ export function degreePlannerReducer(
}; };
} }
case userPrefsActions.UserPreferencesActionTypes.UpdateUserPreferences: {
const update = {
...state,
};
// Remove properties who's value is undefined
Object.entries(action.payload).forEach(([key, value]) => {
if (value === undefined && update.userPreferences[key] !== undefined) {
delete update.userPreferences[key];
} else {
update.userPreferences[key] = value;
}
});
return update;
}
case noteActions.NoteActionTypes.WriteNote: { case noteActions.NoteActionTypes.WriteNote: {
const { termCode, noteText } = action.payload; const { termCode, noteText } = action.payload;
const { yearCode, termName } = termCode; const { yearCode, termName } = termCode;
......
...@@ -66,13 +66,6 @@ export const selectGradeVisibility = createSelector( ...@@ -66,13 +66,6 @@ export const selectGradeVisibility = createSelector(
(state: DegreePlannerState) => state.showGrades, (state: DegreePlannerState) => state.showGrades,
); );
export const getUserPreference = createSelector(
getDegreePlannerState,
(state: DegreePlannerState, pref: keyof UserPreferences) => {
return state.userPreferences[pref] as unknown;
},
);
export const isCourseSearchOpen = createSelector( export const isCourseSearchOpen = createSelector(
getDegreePlannerState, getDegreePlannerState,
(state: DegreePlannerState) => { (state: DegreePlannerState) => {
......
...@@ -4,7 +4,6 @@ import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course'; ...@@ -4,7 +4,6 @@ import { SavedForLaterCourse } from '@app/core/models/saved-for-later-course';
import { SubjectCodesTo, SubjectDescription } from '@app/core/models/course'; import { SubjectCodesTo, SubjectDescription } from '@app/core/models/course';
import { TermCode } from '@app/degree-planner/shared/term-codes/termcode'; import { TermCode } from '@app/degree-planner/shared/term-codes/termcode';
import { Alert } from '@app/core/models/alert'; import { Alert } from '@app/core/models/alert';
import { UserPreferences } from '@app/core/models/user-preferences';
export interface DegreePlannerState { export interface DegreePlannerState {
visibleDegreePlan: DegreePlan | undefined; visibleDegreePlan: DegreePlan | undefined;
...@@ -17,7 +16,6 @@ export interface DegreePlannerState { ...@@ -17,7 +16,6 @@ export interface DegreePlannerState {
isSidenavOpen: 'defer' | boolean; isSidenavOpen: 'defer' | boolean;
alerts: Alert[]; alerts: Alert[];
showGrades: boolean; showGrades: boolean;
userPreferences: UserPreferences;
} }
export const INITIAL_DEGREE_PLANNER_STATE: DegreePlannerState = { export const INITIAL_DEGREE_PLANNER_STATE: DegreePlannerState = {
...@@ -31,7 +29,4 @@ export const INITIAL_DEGREE_PLANNER_STATE: DegreePlannerState = { ...@@ -31,7 +29,4 @@ export const INITIAL_DEGREE_PLANNER_STATE: DegreePlannerState = {
isSidenavOpen: 'defer', isSidenavOpen: 'defer',
alerts: [], alerts: [],
showGrades: true, showGrades: true,
userPreferences: {
degreePlannerGradesVisibility: 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