diff --git a/src/app/core/models/planned-term.ts b/src/app/core/models/planned-term.ts index c29c4aadef34ad42fea8d1bb5ab181270f49327a..f6a334e2f36a4a931da0ee6781100fac18c3f2df 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 938ff3d31751ccaf0e3e33874170a5555561fd78..c8dcef8dcc2d366381735ee73721a7516ed72bb5 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 28f9d002e36d917f216384d10426c47bf4cac438..395a9711ad2feeaa61c07a9d261416d6e45f7602 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 075d5a98babacdb98e7e54f65d6b397a94b27dba..4858e43c5ffde65aca39971061420b2957aeb8cc 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 8c52be1a36fbe234d89cea368ee85d2d45fdd915..da06766b406645b5471c32704d1ace34f0ee1e57 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 34f09d6d1eeb6070bf93a002b750b44b88e06109..d0dc1ebccf59d1037ee92359cd8394c5364fa399 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 f9444bdb7358c2f5ccda0891976a704510ca5b06..a684d6ae62e04681198043443e21c9d3493c1f4e 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 59c69d36c00fc1049cafb1d13967d41f7c6156d2..7687b9dc95495a43b86855a630c3ebb5318c34ec 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 74b2686bf1a82f0cba5ebc57f876d9593ba82c92..1ab0783162a4dc145353c0c13dc04abb80b6fb2b 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 b40df41cdc99afca4a578b93c07a198bfa960bf8..7f6ec06e5168b0b98d390046d4dd0b8ff314c0b2 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 18a7003db1645ae3323145e5b51632cae9fb657c..7b6438a1d4a3cc89dd9b7ba0f038babfa5731413 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;