From e8754100021917de9c8fe45bb0bf73f142a128d7 Mon Sep 17 00:00:00 2001 From: Roberto Fontanarosa Date: Tue, 17 Mar 2026 15:02:04 +0100 Subject: [PATCH 1/7] Fix errors caused by immutable.js v4 to v5 upgrade --- web/src/app/components/create-survey/create-survey.component.ts | 2 +- .../main-page/drawing-tools/drawing-tools.component.ts | 2 +- .../side-panel/submission-form/submission-form.component.ts | 2 +- web/src/app/converters/loi-data-converter.ts | 2 +- web/src/app/converters/submission-data-converter.ts | 2 +- web/src/app/models/loi.model.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/web/src/app/components/create-survey/create-survey.component.ts b/web/src/app/components/create-survey/create-survey.component.ts index 0623b1c80..0d77f1508 100644 --- a/web/src/app/components/create-survey/create-survey.component.ts +++ b/web/src/app/components/create-survey/create-survey.component.ts @@ -386,7 +386,7 @@ export class CreateSurveyComponent implements OnInit { await this.taskService.addOrUpdateTasks( survey.id, // Assume there is at least one job. - survey.jobs.first(), + survey.jobs.first()!, tasks! ); } diff --git a/web/src/app/components/main-page-container/main-page/drawing-tools/drawing-tools.component.ts b/web/src/app/components/main-page-container/main-page/drawing-tools/drawing-tools.component.ts index caa001c54..2b811a8b5 100644 --- a/web/src/app/components/main-page-container/main-page/drawing-tools/drawing-tools.component.ts +++ b/web/src/app/components/main-page-container/main-page/drawing-tools/drawing-tools.component.ts @@ -92,7 +92,7 @@ export class DrawingToolsComponent implements OnInit, OnDestroy { effect(() => { const survey = this.survey(); if (survey) { - this.selectedJobId = survey.jobs.keySeq().first(); + this.selectedJobId = survey.jobs.keySeq().first() ?? ''; this.drawingToolsService.setSelectedJobId(this.selectedJobId); } }); diff --git a/web/src/app/components/main-page-container/main-page/side-panel/submission-form/submission-form.component.ts b/web/src/app/components/main-page-container/main-page/side-panel/submission-form/submission-form.component.ts index 5ec76b708..481f44607 100644 --- a/web/src/app/components/main-page-container/main-page/side-panel/submission-form/submission-form.component.ts +++ b/web/src/app/components/main-page-container/main-page/side-panel/submission-form/submission-form.component.ts @@ -312,7 +312,7 @@ export class SubmissionFormComponent implements OnChanges { result?: Result ): void { const selectedOptionId = ( - (result?.value as MultipleSelection)?.values.first() as Option + (result?.value as MultipleSelection)?.values.first() as unknown as Option )?.id; group[task.id] = task.required ? new FormControl(selectedOptionId, Validators.required) diff --git a/web/src/app/converters/loi-data-converter.ts b/web/src/app/converters/loi-data-converter.ts index 37c0f120c..d17d6519a 100644 --- a/web/src/app/converters/loi-data-converter.ts +++ b/web/src/app/converters/loi-data-converter.ts @@ -36,7 +36,7 @@ function propertiesPbToModel(pb: { properties[k] = v; } } - return Map(properties); + return Map(properties) as unknown as Map; } export function loiDocToModel( diff --git a/web/src/app/converters/submission-data-converter.ts b/web/src/app/converters/submission-data-converter.ts index 8a8c80571..e1287e2df 100644 --- a/web/src/app/converters/submission-data-converter.ts +++ b/web/src/app/converters/submission-data-converter.ts @@ -57,7 +57,7 @@ function taskDataPbArrayToModel(pb: Pb.ITaskData[]): SubmissionData { } }); - return Map(submissionData); + return Map(submissionData) as unknown as SubmissionData; } function taskDataPbToModel(taskData: Pb.ITaskData): Result | null { diff --git a/web/src/app/models/loi.model.ts b/web/src/app/models/loi.model.ts index d4f0bcfd5..30c74b6fa 100644 --- a/web/src/app/models/loi.model.ts +++ b/web/src/app/models/loi.model.ts @@ -33,6 +33,6 @@ export class LocationOfInterest { .sort((a, b) => (a.geometry?.getArea() || 0) < (b.geometry?.getArea() || 0) ? -1 : 1 ) - .first(); + .first()!; } } From 29e7d22958f5b2933260e08e984ac7f0489a4207 Mon Sep 17 00:00:00 2001 From: Roberto Fontanarosa Date: Tue, 17 Mar 2026 15:41:00 +0100 Subject: [PATCH 2/7] fixed tests --- .../main-page/drawing-tools/drawing-tools.component.spec.ts | 2 +- .../shared/share-list/share-list.component.spec.ts | 2 +- web/src/app/services/survey/survey.service.spec.ts | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/web/src/app/components/main-page-container/main-page/drawing-tools/drawing-tools.component.spec.ts b/web/src/app/components/main-page-container/main-page/drawing-tools/drawing-tools.component.spec.ts index 2e4fee3c0..7e7501d66 100644 --- a/web/src/app/components/main-page-container/main-page/drawing-tools/drawing-tools.component.spec.ts +++ b/web/src/app/components/main-page-container/main-page/drawing-tools/drawing-tools.component.spec.ts @@ -182,7 +182,7 @@ describe('DrawingToolsComponent', () => { expect( authServiceSpy.canUserAddPointsToJob( mockSurvey, - mockSurvey.jobs.first() + mockSurvey.jobs.first()! ) ).toBe(false); diff --git a/web/src/app/components/shared/share-list/share-list.component.spec.ts b/web/src/app/components/shared/share-list/share-list.component.spec.ts index 2dfdfd12c..5a74022b8 100644 --- a/web/src/app/components/shared/share-list/share-list.component.spec.ts +++ b/web/src/app/components/shared/share-list/share-list.component.spec.ts @@ -85,7 +85,7 @@ describe('ShareListComponent', () => { 'title', 'description', Map(), - Map({ [user.email]: Role.VIEWER }), + Map({ [user.email]: Role.VIEWER }) as unknown as Map, 'owner-email', { type: DataSharingType.PRIVATE } ) diff --git a/web/src/app/services/survey/survey.service.spec.ts b/web/src/app/services/survey/survey.service.spec.ts index b59f881c1..a2bb3e7b0 100644 --- a/web/src/app/services/survey/survey.service.spec.ts +++ b/web/src/app/services/survey/survey.service.spec.ts @@ -221,7 +221,7 @@ describe('SurveyService', () => { 'title', 'desc', Map(), - Map({ [mockUser.email]: Role.SURVEY_ORGANIZER }), + Map({ [mockUser.email]: Role.SURVEY_ORGANIZER }) as unknown as Map, 'ownerId', { type: DataSharingType.PRIVATE } ); @@ -234,7 +234,7 @@ describe('SurveyService', () => { 'title', 'desc', Map(), - Map({ [mockUser.email]: Role.OWNER }), + Map({ [mockUser.email]: Role.OWNER }) as unknown as Map, 'ownerId', { type: DataSharingType.PRIVATE } ); @@ -247,7 +247,7 @@ describe('SurveyService', () => { 'title', 'desc', Map(), - Map({ [mockUser.email]: Role.VIEWER }), + Map({ [mockUser.email]: Role.VIEWER }) as unknown as Map, 'ownerId', { type: DataSharingType.PRIVATE } ); From 483c4dad42a5c880627058ba24dc69fb7897c360 Mon Sep 17 00:00:00 2001 From: Roberto Fontanarosa Date: Tue, 17 Mar 2026 16:44:41 +0100 Subject: [PATCH 3/7] removed unknown cast --- .../side-panel/submission-form/submission-form.component.ts | 4 +--- web/src/app/converters/loi-data-converter.ts | 2 +- web/src/app/converters/submission-data-converter.ts | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/web/src/app/components/main-page-container/main-page/side-panel/submission-form/submission-form.component.ts b/web/src/app/components/main-page-container/main-page/side-panel/submission-form/submission-form.component.ts index 481f44607..ca235b75e 100644 --- a/web/src/app/components/main-page-container/main-page/side-panel/submission-form/submission-form.component.ts +++ b/web/src/app/components/main-page-container/main-page/side-panel/submission-form/submission-form.component.ts @@ -311,9 +311,7 @@ export class SubmissionFormComponent implements OnChanges { task: Task, result?: Result ): void { - const selectedOptionId = ( - (result?.value as MultipleSelection)?.values.first() as unknown as Option - )?.id; + const selectedOptionId = (result?.value as MultipleSelection)?.values.first(); group[task.id] = task.required ? new FormControl(selectedOptionId, Validators.required) : new FormControl(selectedOptionId); diff --git a/web/src/app/converters/loi-data-converter.ts b/web/src/app/converters/loi-data-converter.ts index d17d6519a..7d42ce1ce 100644 --- a/web/src/app/converters/loi-data-converter.ts +++ b/web/src/app/converters/loi-data-converter.ts @@ -36,7 +36,7 @@ function propertiesPbToModel(pb: { properties[k] = v; } } - return Map(properties) as unknown as Map; + return Map(Object.entries(properties)); } export function loiDocToModel( diff --git a/web/src/app/converters/submission-data-converter.ts b/web/src/app/converters/submission-data-converter.ts index e1287e2df..6e0af0c18 100644 --- a/web/src/app/converters/submission-data-converter.ts +++ b/web/src/app/converters/submission-data-converter.ts @@ -57,7 +57,7 @@ function taskDataPbArrayToModel(pb: Pb.ITaskData[]): SubmissionData { } }); - return Map(submissionData) as unknown as SubmissionData; + return Map(Object.entries(submissionData)); } function taskDataPbToModel(taskData: Pb.ITaskData): Result | null { From 2a2b1239ef57f0ab2b0f317c5415556ae718bf4c Mon Sep 17 00:00:00 2001 From: Roberto Fontanarosa Date: Tue, 17 Mar 2026 16:49:10 +0100 Subject: [PATCH 4/7] removed unknown cast --- .../shared/share-list/share-list.component.spec.ts | 2 +- web/src/app/services/survey/survey.service.spec.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/web/src/app/components/shared/share-list/share-list.component.spec.ts b/web/src/app/components/shared/share-list/share-list.component.spec.ts index 5a74022b8..427a58f41 100644 --- a/web/src/app/components/shared/share-list/share-list.component.spec.ts +++ b/web/src/app/components/shared/share-list/share-list.component.spec.ts @@ -85,7 +85,7 @@ describe('ShareListComponent', () => { 'title', 'description', Map(), - Map({ [user.email]: Role.VIEWER }) as unknown as Map, + Map([[user.email, Role.VIEWER]]), 'owner-email', { type: DataSharingType.PRIVATE } ) diff --git a/web/src/app/services/survey/survey.service.spec.ts b/web/src/app/services/survey/survey.service.spec.ts index a2bb3e7b0..03ee3b917 100644 --- a/web/src/app/services/survey/survey.service.spec.ts +++ b/web/src/app/services/survey/survey.service.spec.ts @@ -221,7 +221,7 @@ describe('SurveyService', () => { 'title', 'desc', Map(), - Map({ [mockUser.email]: Role.SURVEY_ORGANIZER }) as unknown as Map, + Map([[mockUser.email, Role.SURVEY_ORGANIZER]]), 'ownerId', { type: DataSharingType.PRIVATE } ); @@ -234,7 +234,7 @@ describe('SurveyService', () => { 'title', 'desc', Map(), - Map({ [mockUser.email]: Role.OWNER }) as unknown as Map, + Map([[mockUser.email, Role.OWNER]]), 'ownerId', { type: DataSharingType.PRIVATE } ); @@ -247,7 +247,7 @@ describe('SurveyService', () => { 'title', 'desc', Map(), - Map({ [mockUser.email]: Role.VIEWER }) as unknown as Map, + Map([[mockUser.email, Role.VIEWER]]), 'ownerId', { type: DataSharingType.PRIVATE } ); From f0277d1a80968b0555ea7dcefa9da064310adb2d Mon Sep 17 00:00:00 2001 From: Roberto Fontanarosa Date: Tue, 17 Mar 2026 16:57:20 +0100 Subject: [PATCH 5/7] add job check --- .../create-survey/create-survey.component.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/web/src/app/components/create-survey/create-survey.component.ts b/web/src/app/components/create-survey/create-survey.component.ts index 0d77f1508..456f65256 100644 --- a/web/src/app/components/create-survey/create-survey.component.ts +++ b/web/src/app/components/create-survey/create-survey.component.ts @@ -383,12 +383,12 @@ export class CreateSurveyComponent implements OnInit { // Assume the survey exists. const survey = this.survey!; - await this.taskService.addOrUpdateTasks( - survey.id, - // Assume there is at least one job. - survey.jobs.first()!, - tasks! - ); + const job = survey.jobs.first(); + if (!job) { + console.error('Cannot save tasks: survey has no jobs', survey.id); + return; + } + await this.taskService.addOrUpdateTasks(survey.id, job, tasks!); } private async saveDataSharingTerms(): Promise { From 7d8c0c7a68bb19c6e8a32563f383d9ea1771d8dc Mon Sep 17 00:00:00 2001 From: Roberto Fontanarosa Date: Wed, 18 Mar 2026 20:29:01 +0100 Subject: [PATCH 6/7] removed null assertion operator --- web/src/app/models/loi.model.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/web/src/app/models/loi.model.ts b/web/src/app/models/loi.model.ts index 30c74b6fa..6c274aa08 100644 --- a/web/src/app/models/loi.model.ts +++ b/web/src/app/models/loi.model.ts @@ -28,11 +28,13 @@ export class LocationOfInterest { readonly predefined: boolean = true ) {} - static getSmallestByArea(lois: List): LocationOfInterest { + static getSmallestByArea( + lois: List + ): LocationOfInterest | undefined { return lois .sort((a, b) => (a.geometry?.getArea() || 0) < (b.geometry?.getArea() || 0) ? -1 : 1 ) - .first()!; + .first(); } } From 8bbe070d80434d2cd6ffe4f270f5f0f72be64fb5 Mon Sep 17 00:00:00 2001 From: Roberto Fontanarosa Date: Wed, 18 Mar 2026 20:35:14 +0100 Subject: [PATCH 7/7] removed nullish coalescing operator --- .../main-page/drawing-tools/drawing-tools.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/app/components/main-page-container/main-page/drawing-tools/drawing-tools.component.ts b/web/src/app/components/main-page-container/main-page/drawing-tools/drawing-tools.component.ts index 2b811a8b5..5e1c5fc28 100644 --- a/web/src/app/components/main-page-container/main-page/drawing-tools/drawing-tools.component.ts +++ b/web/src/app/components/main-page-container/main-page/drawing-tools/drawing-tools.component.ts @@ -61,7 +61,7 @@ export class DrawingToolsComponent implements OnInit, OnDestroy { polygonValue = 'polygon'; selectedValue = ''; private lastSelectedValue = ''; - selectedJobId = ''; + selectedJobId: string | undefined = ''; readonly jobs = computed(() => { const survey = this.survey(); @@ -92,7 +92,7 @@ export class DrawingToolsComponent implements OnInit, OnDestroy { effect(() => { const survey = this.survey(); if (survey) { - this.selectedJobId = survey.jobs.keySeq().first() ?? ''; + this.selectedJobId = survey.jobs.keySeq().first(); this.drawingToolsService.setSelectedJobId(this.selectedJobId); } });