From 6eed0d8d8aad6990ae1d875f43f7550b274d8258 Mon Sep 17 00:00:00 2001 From: ievavold <ievavold@wisc.edu> Date: Wed, 20 Mar 2019 10:25:27 -0500 Subject: [PATCH] mark state arrays as readonly --- src/app/core/models/planned-term.ts | 4 ++-- src/app/core/models/year.ts | 6 +++++- .../course-search/course-search.component.ts | 2 +- .../degree-planner/degree-planner.component.ts | 6 +++--- .../saved-for-later-container.component.ts | 2 +- .../shared/course-item/course-item.component.ts | 2 +- src/app/degree-planner/shared/utils.ts | 4 ++-- .../store/effects/plan.effects.ts | 17 ++++++++++------- src/app/degree-planner/store/reducer.ts | 15 +++++++++------ src/app/degree-planner/store/state.ts | 6 +++--- .../term-container/term-container.component.ts | 10 +++++----- 11 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/app/core/models/planned-term.ts b/src/app/core/models/planned-term.ts index c29c4aa..f6a334e 100644 --- a/src/app/core/models/planned-term.ts +++ b/src/app/core/models/planned-term.ts @@ -11,6 +11,6 @@ export interface PlannedTerm { termCode: TermCode; era: PlannedTermEra; note?: PlannedTermNote; - plannedCourses: Course[]; - enrolledCourses: Course[]; + plannedCourses: ReadonlyArray<Course>; + enrolledCourses: ReadonlyArray<Course>; } diff --git a/src/app/core/models/year.ts b/src/app/core/models/year.ts index 938ff3d..c8dcef8 100644 --- a/src/app/core/models/year.ts +++ b/src/app/core/models/year.ts @@ -9,6 +9,10 @@ export interface Year { summer: PlannedTerm; } -export interface YearMapping { +export interface MutableYearMapping { [yearCode: string]: Year; } + +export interface YearMapping { + readonly [yearCode: string]: Year; +} diff --git a/src/app/degree-planner/course-search/course-search.component.ts b/src/app/degree-planner/course-search/course-search.component.ts index 28f9d00..395a971 100644 --- a/src/app/degree-planner/course-search/course-search.component.ts +++ b/src/app/degree-planner/course-search/course-search.component.ts @@ -36,7 +36,7 @@ export class CourseSearchComponent implements OnInit, OnDestroy { // Observable used for drag and drop and for populating term select public dropZoneIds$: Observable<string[]>; - public activeTerms$: Observable<TermCode[]>; + public activeTerms$: Observable<ReadonlyArray<TermCode>>; public activeSelectedSearchTerm$: Observable<TermCode | undefined>; public isCourseSearchOpen$: Observable<boolean>; diff --git a/src/app/degree-planner/degree-planner.component.ts b/src/app/degree-planner/degree-planner.component.ts index 075d5a9..4858e43 100644 --- a/src/app/degree-planner/degree-planner.component.ts +++ b/src/app/degree-planner/degree-planner.component.ts @@ -45,10 +45,10 @@ export class DegreePlannerComponent implements OnInit, OnDestroy { public mobileView: MediaQueryList; public coursesData$: any; public degreePlan$: Observable<DegreePlan | undefined>; - public allDegreePlans$: Observable<DegreePlan[]>; + public allDegreePlans$: Observable<ReadonlyArray<DegreePlan>>; public firstActiveTermCode$: Observable<TermCode | undefined>; - public termsByYear$: Observable<Year[]>; - public yearCodes$: Observable<YearCode[]>; + public termsByYear$: Observable<ReadonlyArray<Year>>; + public yearCodes$: Observable<ReadonlyArray<YearCode>>; public isCourseSearchOpen$: Observable<boolean>; public isLoadingPlan$: Observable<boolean>; public activeTermSubscription: Subscription; diff --git a/src/app/degree-planner/saved-for-later-container/saved-for-later-container.component.ts b/src/app/degree-planner/saved-for-later-container/saved-for-later-container.component.ts index 8c52be1..da06766 100644 --- a/src/app/degree-planner/saved-for-later-container/saved-for-later-container.component.ts +++ b/src/app/degree-planner/saved-for-later-container/saved-for-later-container.component.ts @@ -23,7 +23,7 @@ import { MediaMatcher } from '@angular/cdk/layout'; styleUrls: ['./saved-for-later-container.component.scss'], }) export class SavedForLaterContainerComponent implements OnInit { - public courses$: Observable<SavedForLaterCourse[]>; + public courses$: Observable<ReadonlyArray<SavedForLaterCourse>>; public dropZoneIds$: Observable<string[]>; public mobileView: MediaQueryList; diff --git a/src/app/degree-planner/shared/course-item/course-item.component.ts b/src/app/degree-planner/shared/course-item/course-item.component.ts index 34f09d6..d0dc1eb 100644 --- a/src/app/degree-planner/shared/course-item/course-item.component.ts +++ b/src/app/degree-planner/shared/course-item/course-item.component.ts @@ -48,7 +48,7 @@ export class CourseItemComponent implements OnInit { public visibleTermCodes$: Observable<string[]>; public droppableTermCodes$: Observable<string[]>; public term$: Observable<PlannedTerm>; - public plannedCourses: Course[]; + public plannedCourses: ReadonlyArray<Course>; public toActiveTerm: boolean; public isStruckthrough = false; diff --git a/src/app/degree-planner/shared/utils.ts b/src/app/degree-planner/shared/utils.ts index f9444bd..a684d6a 100644 --- a/src/app/degree-planner/shared/utils.ts +++ b/src/app/degree-planner/shared/utils.ts @@ -24,7 +24,7 @@ export const pickTermName = (termOffset: string) => { export const pickTermEra = ( termCode: TermCode, - activeTermCodes: TermCode[], + activeTermCodes: ReadonlyArray<TermCode>, ): PlannedTermEra => { const noActiveTermCodes = activeTermCodes.length === 0; const isActiveTermCode = activeTermCodes.some(tc => tc.equals(termCode)); @@ -42,7 +42,7 @@ export const pickTermEra = ( export const pickYearEra = ( yearCode: YearCode, - activeTermCodes: TermCode[], + activeTermCodes: ReadonlyArray<TermCode>, ): PlannedTermEra => { const activeYearCodes = activeTermCodes.map(tc => tc.yearCode); const noActiveYearCodes = activeYearCodes.length === 0; diff --git a/src/app/degree-planner/store/effects/plan.effects.ts b/src/app/degree-planner/store/effects/plan.effects.ts index 59c69d3..7687b9d 100644 --- a/src/app/degree-planner/store/effects/plan.effects.ts +++ b/src/app/degree-planner/store/effects/plan.effects.ts @@ -47,7 +47,7 @@ import { DegreePlannerState, INITIAL_DEGREE_PLANNER_STATE, } from '@app/degree-planner/store/state'; -import { YearMapping } from '@app/core/models/year'; +import { YearMapping, MutableYearMapping } from '@app/core/models/year'; import { Note } from '@app/core/models/note'; import { CourseBase, Course } from '@app/core/models/course'; import { pickTermEra } from '@app/degree-planner/shared/utils'; @@ -382,10 +382,13 @@ const toYearCode = (termCode: string) => { const buildTerm = ( termCode: TermCode, - notes: Note[], + notes: ReadonlyArray<Note>, subjects: SubjectMapping, - courses: { termCode: string; courses: CourseBase[] }[], - activeTermCodes: TermCode[], + courses: ReadonlyArray<{ + termCode: string; + courses: ReadonlyArray<CourseBase>; + }>, + activeTermCodes: ReadonlyArray<TermCode>, ): PlannedTerm => { const baseNote = notes.find(matchesTermCode(termCode)); const note: PlannedTermNote | undefined = baseNote @@ -425,7 +428,7 @@ const loadPlanYears = ( api: DegreePlannerApiService, roadmapId: number, subjects: SubjectMapping, - activeTermCodes: TermCode[], + activeTermCodes: ReadonlyArray<TermCode>, ): Observable<YearMapping> => { const notesAndCourses$ = forkJoinWithKeys({ notes: api.getAllNotes(roadmapId), @@ -454,7 +457,7 @@ const loadPlanYears = ( const visibleYears$ = uniqueYearCodes$.pipe( map(({ uniqueYearCodes, notes, courses }) => { - const mapping: YearMapping = {}; + const mapping: MutableYearMapping = {}; uniqueYearCodes.forEach(yearCode => { mapping[yearCode.toString()] = { yearCode, @@ -483,7 +486,7 @@ const loadPlanYears = ( }; }); - return mapping; + return mapping as YearMapping; }), ); diff --git a/src/app/degree-planner/store/reducer.ts b/src/app/degree-planner/store/reducer.ts index 74b2686..1ab0783 100644 --- a/src/app/degree-planner/store/reducer.ts +++ b/src/app/degree-planner/store/reducer.ts @@ -580,7 +580,10 @@ const emptyTerm = (termCode: TermCode, era: PlannedTermEra): PlannedTerm => { return { termCode, era, plannedCourses: [], enrolledCourses: [] }; }; -const emptyYear = (yearCode: YearCode, activeTermCodes: TermCode[]): Year => { +const emptyYear = ( + yearCode: YearCode, + activeTermCodes: ReadonlyArray<TermCode>, +): Year => { return { yearCode, isExpanded: utils.pickYearEra(yearCode, activeTermCodes) !== 'past', @@ -598,7 +601,7 @@ const emptyYear = (yearCode: YearCode, activeTermCodes: TermCode[]): Year => { const generateYearForTermCode = ( termCode: TermCode, - activeTermCodes: TermCode[], + activeTermCodes: ReadonlyArray<TermCode>, ): Year => { return emptyYear(termCode.yearCode, activeTermCodes); }; @@ -606,7 +609,7 @@ const generateYearForTermCode = ( const createYearWithNote = ( termCode: TermCode, note: PlannedTermNote | undefined, - activeTermCodes: TermCode[], + activeTermCodes: ReadonlyArray<TermCode>, year = generateYearForTermCode(termCode, activeTermCodes), ): Year => { const term = year[termCode.termName]; @@ -615,7 +618,7 @@ const createYearWithNote = ( const createYearWithoutNote = ( termCode: TermCode, - activeTermCodes: TermCode[], + activeTermCodes: ReadonlyArray<TermCode>, year?: Year, ) => { return createYearWithNote(termCode, undefined, activeTermCodes, year); @@ -636,7 +639,7 @@ const findCourse = ( const createYearWithCourse = ( termCode: TermCode, course: Course, - activeTermCodes: TermCode[], + activeTermCodes: ReadonlyArray<TermCode>, year = generateYearForTermCode(termCode, activeTermCodes), newIndex?: number, ): Year => { @@ -652,7 +655,7 @@ const createYearWithCourse = ( const createYearWithoutCourse = ( termCode: TermCode, recordId: number, - activeTermCodes: TermCode[], + activeTermCodes: ReadonlyArray<TermCode>, year = generateYearForTermCode(termCode, activeTermCodes), ): Year => { const term = year[termCode.termName]; diff --git a/src/app/degree-planner/store/state.ts b/src/app/degree-planner/store/state.ts index b40df41..7f6ec06 100644 --- a/src/app/degree-planner/store/state.ts +++ b/src/app/degree-planner/store/state.ts @@ -8,9 +8,9 @@ import { TermCode } from '@app/core/models/termcode'; export interface DegreePlannerState { visibleDegreePlan: DegreePlan | undefined; visibleYears: YearMapping; - savedForLaterCourses: SavedForLaterCourse[]; - activeTermCodes: TermCode[]; - allDegreePlans: DegreePlan[]; + savedForLaterCourses: ReadonlyArray<SavedForLaterCourse>; + activeTermCodes: ReadonlyArray<TermCode>; + allDegreePlans: ReadonlyArray<DegreePlan>; subjects: SubjectMapping; subjectDescriptions: SubjectMapping; search: { visible: boolean; selectedTerm?: TermCode }; diff --git a/src/app/degree-planner/term-container/term-container.component.ts b/src/app/degree-planner/term-container/term-container.component.ts index 18a7003..7b6438a 100644 --- a/src/app/degree-planner/term-container/term-container.component.ts +++ b/src/app/degree-planner/term-container/term-container.component.ts @@ -48,14 +48,14 @@ export class TermContainerComponent implements OnInit, OnDestroy { public termSubscription: Subscription; public activeTermHasNotOffered: boolean; // List of courses pulled for the Observable - public plannedCourses: Course[]; - public enrolledCourses: Course[]; + public plannedCourses: ReadonlyArray<Course>; + public enrolledCourses: ReadonlyArray<Course>; public era: 'past' | 'active' | 'future'; public hasItemDraggedOver: boolean; public plannedCredits: string; public enrolledCredits: number; public visibleCredits: 'enrolled' | 'planned'; - public courseNotOfferedInTerm: Course[]; + public courseNotOfferedInTerm: ReadonlyArray<Course>; public mobileView: MediaQueryList; constructor( @@ -291,11 +291,11 @@ export class TermContainerComponent implements OnInit, OnDestroy { this.hasItemDraggedOver = false; } - sumEnrolledCredits(courses: Course[]): number { + sumEnrolledCredits(courses: ReadonlyArray<Course>): number { return courses.reduce((sum, course) => sum + course.credits, 0); } - sumPlannedCredits(courses: Course[]): string { + sumPlannedCredits(courses: ReadonlyArray<Course>): string { const credits = { min: 0, max: 0 }; courses.forEach(course => { credits.min = credits.min + course.creditMin; -- GitLab