From f82e3551fde74fb861f0797806a4a26d6e6c05ac Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Tue, 21 May 2024 20:06:53 -0700 Subject: [PATCH 01/27] Remove tooltips --- .../post-decision/post-decision.component.html | 12 ++---------- .../post-decision/post-decision.component.html | 5 +---- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.html b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.html index 1669d45890..692dca7106 100644 --- a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.html +++ b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.html @@ -5,12 +5,7 @@

Post-Decision

Reconsideration Requests | Modification Requests -
- Reconsideration Requests - info_outline - -
+
Reconsideration Requests
No Reconsiderations
@@ -114,10 +109,7 @@
-
- Modification Requests - info_outline -
+
Modification Requests
No Requests
diff --git a/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.html b/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.html index 6d18d9b02d..9cc6aac01a 100644 --- a/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.html +++ b/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.html @@ -1,9 +1,6 @@

Post-Decision

-
- Modification Requests - info_outline -
+
Modification Requests
No Requests
From ebb93f9a26e344c128e982e85030b7e8b6f0de10 Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Mon, 27 May 2024 09:12:10 -0700 Subject: [PATCH 02/27] Clean up modification layout --- .../create-app-modification-dialog.component.scss | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.component.scss b/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.component.scss index 28abbc2e3f..390fbae9fb 100644 --- a/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.component.scss +++ b/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.component.scss @@ -1,9 +1,5 @@ @use '../../../../../../styles/colors'; -.content { - padding: 0 16px; -} - .two-item-row { display: grid; grid-template-columns: 1fr 1fr; @@ -66,3 +62,13 @@ mat-dialog-actions { margin-right: 16px; } } + +mat-dialog-content { + padding-top: 6px !important; /* Prevent labels being cut off */ + padding-bottom: 0 !important; +} + +mat-dialog-actions { + padding-inline: 24px; + padding-bottom: 24px; +} From 801c4deeecba0a688b97a059226ceb23427bbc81 Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Mon, 27 May 2024 17:06:08 -0700 Subject: [PATCH 03/27] Allow add app modi from post-decision page - Add button and handler to post-decision page - Cache and pass data for file no., applicant, local government, and region to dialog - Update dialog --- .../post-decision.component.html | 5 +- .../post-decision.component.scss | 12 +- .../post-decision/post-decision.component.ts | 36 +++++- ...reate-app-modification-dialog.component.ts | 108 ++++-------------- .../create-app-modification-dialog.html | 81 +++++-------- 5 files changed, 91 insertions(+), 151 deletions(-) diff --git a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.html b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.html index 692dca7106..3af1762ac1 100644 --- a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.html +++ b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.html @@ -109,7 +109,10 @@
Reconsideration Requests
-
Modification Requests
+
+ Modification Requests + +
No Requests
diff --git a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.scss b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.scss index 81b0597964..df290bf675 100644 --- a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.scss +++ b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.scss @@ -1,16 +1,12 @@ @use '../../../../styles/colors'; .post-decision-header { - margin: 24px 0 !important; + margin-top: 24px !important; display: flex; align-items: center; - - .icon { - margin-left: 8px; - height: 20px; - width: 20px; - font-size: 20px; - } + justify-content: space-between; + flex-wrap: wrap; + gap: 12px; } .post-decision { diff --git a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts index 00dde66ff5..73d2759d6f 100644 --- a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts +++ b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts @@ -12,6 +12,9 @@ import { BaseCodeDto } from '../../../shared/dto/base.dto'; import { formatDateForApi } from '../../../shared/utils/api-date-formatter'; import { EditModificationDialogComponent } from './edit-modification-dialog/edit-modification-dialog.component'; import { EditReconsiderationDialogComponent } from './edit-reconsideration-dialog/edit-reconsideration-dialog.component'; +import { CreateAppModificationDialogComponent } from '../../board/dialogs/app-modification/create/create-app-modification-dialog.component'; +import { ApplicationLocalGovernmentDto } from 'src/app/services/application/application-local-government/application-local-government.dto'; +import { ApplicationRegionDto } from 'src/app/services/application/application-code.dto'; type LoadingReconsiderations = ApplicationReconsiderationDetailedDto & { reconsidersDecisionsNumbers: string[]; @@ -28,6 +31,9 @@ type LoadingModifications = ApplicationModificationDto & { export class PostDecisionComponent implements OnInit, OnDestroy { $destroy = new Subject(); fileNumber: string = ''; + applicant: string = ''; + localGovernment: ApplicationLocalGovernmentDto | undefined = undefined; + region: ApplicationRegionDto | undefined = undefined; reconsiderations: LoadingReconsiderations[] = []; modifications: LoadingModifications[] = []; reconCodes: BaseCodeDto[] = []; @@ -38,7 +44,7 @@ export class PostDecisionComponent implements OnInit, OnDestroy { private applicationReconsiderationService: ApplicationReconsiderationService, private modificationService: ApplicationModificationService, private toastService: ToastService, - private confirmationDialogService: ConfirmationDialogService + private confirmationDialogService: ConfirmationDialogService, ) {} ngOnInit(): void { @@ -46,24 +52,27 @@ export class PostDecisionComponent implements OnInit, OnDestroy { .pipe( tap(() => { this.applicationReconsiderationService.fetchCodes(); - }) + }), ) .pipe( combineLatestWith( this.applicationReconsiderationService.$reconsiderations, this.applicationReconsiderationService.$codes, - this.modificationService.$modifications - ) + this.modificationService.$modifications, + ), ) .pipe(takeUntil(this.$destroy)) .subscribe(([application, reconsiderations, reconCodes, modifications]) => { if (application) { this.fileNumber = application.fileNumber; + this.applicant = application.applicant; + this.localGovernment = application.localGovernment; + this.region = application.region; this.reconsiderations = reconsiderations?.map((r) => ({ ...r, reconsidersDecisionsNumbers: r.reconsidersDecisions.flatMap( - (d) => `#${d.resolutionNumber}/${d.resolutionYear}` + (d) => `#${d.resolutionNumber}/${d.resolutionYear}`, ), })) ?? []; this.reconCodes = reconCodes; @@ -71,7 +80,7 @@ export class PostDecisionComponent implements OnInit, OnDestroy { modifications?.map((m) => ({ ...m, modifiesDecisionsNumbers: m.modifiesDecisions.flatMap( - (d) => `#${d.resolutionNumber}/${d.resolutionYear}` + (d) => `#${d.resolutionNumber}/${d.resolutionYear}`, ), })) ?? []; } @@ -100,6 +109,21 @@ export class PostDecisionComponent implements OnInit, OnDestroy { }); } + onCreateModification() { + const dialog = this.dialog.open(CreateAppModificationDialogComponent, { + minWidth: '600px', + maxWidth: '1100px', + maxHeight: '80vh', + width: '90%', + data: { + fileNumber: this.fileNumber, + applicant: this.applicant, + localGovernment: this.localGovernment, + region: this.region, + }, + }); + } + onEditModification(modification: ApplicationModificationDto) { this.dialog .open(EditModificationDialogComponent, { diff --git a/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.component.ts b/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.component.ts index 53623bd5f7..a728976b77 100644 --- a/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.component.ts +++ b/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.component.ts @@ -1,15 +1,11 @@ import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { FormControl, FormGroup, Validators } from '@angular/forms'; -import { MatOptionSelectionChange } from '@angular/material/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; -import { debounceTime, distinctUntilChanged, Observable, startWith, Subject, switchMap, takeUntil } from 'rxjs'; -import { ApplicationRegionDto, ApplicationTypeDto } from '../../../../../services/application/application-code.dto'; -import { ApplicationLocalGovernmentDto } from '../../../../../services/application/application-local-government/application-local-government.dto'; -import { ApplicationLocalGovernmentService } from '../../../../../services/application/application-local-government/application-local-government.service'; +import { Subject, takeUntil } from 'rxjs'; +import { ApplicationTypeDto } from '../../../../../services/application/application-code.dto'; import { ApplicationModificationCreateDto } from '../../../../../services/application/application-modification/application-modification.dto'; import { ApplicationModificationService } from '../../../../../services/application/application-modification/application-modification.service'; -import { ApplicationDto } from '../../../../../services/application/application.dto'; import { ApplicationService } from '../../../../../services/application/application.service'; import { ApplicationDecisionV2Service } from '../../../../../services/application/decision/application-decision-v2/application-decision-v2.service'; import { ToastService } from '../../../../../services/toast/toast.service'; @@ -22,22 +18,19 @@ import { ToastService } from '../../../../../services/toast/toast.service'; export class CreateAppModificationDialogComponent implements OnInit, OnDestroy { $destroy = new Subject(); applicationTypes: ApplicationTypeDto[] = []; - regions: ApplicationRegionDto[] = []; - localGovernments: ApplicationLocalGovernmentDto[] = []; isLoading = false; isDecisionDateEmpty = false; currentBoardCode: string = ''; decisions: { uuid: string; resolution: string }[] = []; - filteredApplications: Observable | undefined; - fileNumberControl = new FormControl('', [Validators.required]); - applicantControl = new FormControl('', [Validators.required]); + fileNumberControl = new FormControl({ value: '', disabled: true }, [Validators.required]); + applicantControl = new FormControl({ value: '', disabled: true }, [Validators.required]); descriptionControl = new FormControl(null, [Validators.required]); applicationTypeControl = new FormControl(null, [Validators.required]); - regionControl = new FormControl(null, [Validators.required]); + regionControl = new FormControl({ value: null, disabled: true }, [Validators.required]); submittedDateControl = new FormControl(undefined, [Validators.required]); - localGovernmentControl = new FormControl(null, [Validators.required]); + localGovernmentControl = new FormControl({ value: null, disabled: true }, [Validators.required]); isTimeExtensionControl = new FormControl('true', [Validators.required]); modifiesDecisions = new FormControl([], [Validators.required]); @@ -58,7 +51,6 @@ export class CreateAppModificationDialogComponent implements OnInit, OnDestroy { private dialogRef: MatDialogRef, private applicationService: ApplicationService, private modificationService: ApplicationModificationService, - private localGovernmentService: ApplicationLocalGovernmentService, private decisionService: ApplicationDecisionV2Service, private toastService: ToastService, private router: Router, @@ -67,64 +59,25 @@ export class CreateAppModificationDialogComponent implements OnInit, OnDestroy { ngOnInit(): void { this.currentBoardCode = this.data.currentBoardCode; - this.applicationService.$applicationTypes.pipe(takeUntil(this.$destroy)).subscribe((types) => { - this.applicationTypes = types; - }); - this.applicationService.$applicationRegions.pipe(takeUntil(this.$destroy)).subscribe((regions) => { - this.regions = regions; + this.createForm.patchValue({ + fileNumber: this.data.fileNumber, + applicant: this.data.applicant, + localGovernment: this.data.localGovernment?.name, + region: this.data.region?.label, }); - this.localGovernmentService.list().then((res) => { - this.localGovernments = res; + this.applicationService.fetchApplication(this.data.fileNumber).then((application) => { + if (!application.decisionDate) { + this.isDecisionDateEmpty = true; + } }); - this.initApplicationFileNumberAutocomplete(); - } - - initApplicationFileNumberAutocomplete() { - this.filteredApplications = this.fileNumberControl.valueChanges.pipe( - startWith(''), - debounceTime(400), - distinctUntilChanged(), - switchMap((val) => { - if (val && val.length > 1) { - return this.applicationService.searchApplicationsByNumber(val); - } - return []; - }), - ); - } - - autocompleteDisplay(application: ApplicationDto): string { - return application?.fileNumber ?? ''; - } - - async onApplicationSelected($event: MatOptionSelectionChange) { - if (!$event?.source?.value) { - return; - } - - const application = $event.source.value as ApplicationDto; - - this.fileNumberControl.disable(); - this.applicantControl.disable(); - this.regionControl.disable(); - this.applicationTypeControl.disable(); - this.localGovernmentControl.disable(); - - this.loadDecisions(application.fileNumber); - - this.createForm.patchValue({ - applicant: application.applicant, - region: application.region?.code, - applicationType: application.type.code, - localGovernment: this.localGovernments.find((g) => g.uuid === application.localGovernment?.uuid)?.uuid ?? null, + this.applicationService.$applicationTypes.pipe(takeUntil(this.$destroy)).subscribe((types) => { + this.applicationTypes = types; }); - if (!application.decisionDate) { - this.isDecisionDateEmpty = true; - } + this.loadDecisions(this.data.fileNumber); } async onSubmit() { @@ -140,7 +93,7 @@ export class CreateAppModificationDialogComponent implements OnInit, OnDestroy { localGovernmentUuid: formValues.localGovernment!, // modification details submittedDate: formValues.submittedDate!.valueOf(), - boardCode: this.currentBoardCode, + boardCode: 'ceo', isTimeExtension: formValues.isTimeExtension === 'true', modifiesDecisionUuids: formValues.modifiesDecisions!, description: formValues.description!, @@ -165,30 +118,13 @@ export class CreateAppModificationDialogComponent implements OnInit, OnDestroy { } } - onReset() { - this.fileNumberControl.reset(); - this.applicantControl.reset(); - this.regionControl.reset(); + onReset(event: MouseEvent) { + event.preventDefault(); + this.applicationTypeControl.reset(); this.submittedDateControl.reset(); this.modifiesDecisions.reset(); this.descriptionControl.reset(); - - this.fileNumberControl.enable(); - this.applicantControl.enable(); - this.regionControl.enable(); - this.applicationTypeControl.enable(); - this.localGovernmentControl.enable(); - this.modifiesDecisions.disable(); - - // clear warnings - this.isDecisionDateEmpty = false; - } - - onSelectGovernment(value: ApplicationLocalGovernmentDto) { - this.createForm.patchValue({ - region: value.preferredRegionCode, - }); } async loadDecisions(fileNumber: string) { diff --git a/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.html b/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.html index f0399fc453..737f90a0c7 100644 --- a/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.html +++ b/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.html @@ -1,5 +1,6 @@

Create Modification

+ This modification will be created on the CEO Board
@@ -9,9 +10,7 @@

Create Modification

Create Modification (createForm.get('fileNumber')!.dirty || createForm.get('fileNumber')!.touched) " /> - - - - {{ option.fileNumber }} - - - - - This field is required. - Applicant Name @@ -98,38 +80,37 @@

Create Modification

-
- + Local/First Nation Government + - -
{{ item.name }}
-
-
-
-
- + + + Region + - -
+ [class.valid]=" + createForm.get('region')!.valid && + (createForm.get('region')!.dirty || createForm.get('region')!.touched) + " + [class.invalid]=" + createForm.get('region')!.invalid && + (createForm.get('region')!.dirty || createForm.get('region')!.touched) + " + /> +
Resolutions to be Modified @@ -193,7 +174,7 @@

Create Modification

-
From cf9d96697fea3e3d5b1071ee2e0061f6b60b8381 Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Tue, 28 May 2024 09:28:08 -0700 Subject: [PATCH 04/27] Allow add app recon from post-decision page - Add button/handler to post-deicion page - Update create recon dialog --- .../post-decision.component.html | 5 +- .../post-decision/post-decision.component.ts | 16 +++ ...create-reconsideration-dialog.component.ts | 128 ++++++------------ .../create/create-reconsideration-dialog.html | 97 +++++++------ 4 files changed, 105 insertions(+), 141 deletions(-) diff --git a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.html b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.html index 3af1762ac1..d39ea7bc9f 100644 --- a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.html +++ b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.html @@ -5,7 +5,10 @@

Post-Decision

Reconsideration Requests | Modification Requests -
Reconsideration Requests
+
+ Reconsideration Requests + +
No Reconsiderations
diff --git a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts index 73d2759d6f..49d5551a50 100644 --- a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts +++ b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts @@ -15,6 +15,7 @@ import { EditReconsiderationDialogComponent } from './edit-reconsideration-dialo import { CreateAppModificationDialogComponent } from '../../board/dialogs/app-modification/create/create-app-modification-dialog.component'; import { ApplicationLocalGovernmentDto } from 'src/app/services/application/application-local-government/application-local-government.dto'; import { ApplicationRegionDto } from 'src/app/services/application/application-code.dto'; +import { CreateReconsiderationDialogComponent } from '../../board/dialogs/reconsiderations/create/create-reconsideration-dialog.component'; type LoadingReconsiderations = ApplicationReconsiderationDetailedDto & { reconsidersDecisionsNumbers: string[]; @@ -109,6 +110,21 @@ export class PostDecisionComponent implements OnInit, OnDestroy { }); } + onCreateReconsideration() { + const dialog = this.dialog.open(CreateReconsiderationDialogComponent, { + minWidth: '600px', + maxWidth: '1100px', + maxHeight: '80vh', + width: '90%', + data: { + fileNumber: this.fileNumber, + applicant: this.applicant, + localGovernment: this.localGovernment, + region: this.region, + }, + }); + } + onCreateModification() { const dialog = this.dialog.open(CreateAppModificationDialogComponent, { minWidth: '600px', diff --git a/alcs-frontend/src/app/features/board/dialogs/reconsiderations/create/create-reconsideration-dialog.component.ts b/alcs-frontend/src/app/features/board/dialogs/reconsiderations/create/create-reconsideration-dialog.component.ts index df05f4cefa..f34bbb88a9 100644 --- a/alcs-frontend/src/app/features/board/dialogs/reconsiderations/create/create-reconsideration-dialog.component.ts +++ b/alcs-frontend/src/app/features/board/dialogs/reconsiderations/create/create-reconsideration-dialog.component.ts @@ -1,23 +1,21 @@ import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { FormControl, FormGroup, Validators } from '@angular/forms'; -import { MatOptionSelectionChange } from '@angular/material/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; -import { debounceTime, distinctUntilChanged, Observable, startWith, Subject, switchMap, takeUntil } from 'rxjs'; -import { ApplicationRegionDto, ApplicationTypeDto } from '../../../../../services/application/application-code.dto'; -import { ApplicationLocalGovernmentDto } from '../../../../../services/application/application-local-government/application-local-government.dto'; -import { ApplicationLocalGovernmentService } from '../../../../../services/application/application-local-government/application-local-government.service'; +import { Subject, takeUntil } from 'rxjs'; +import { ApplicationTypeDto } from '../../../../../services/application/application-code.dto'; import { CreateApplicationReconsiderationDto, ReconsiderationTypeDto, } from '../../../../../services/application/application-reconsideration/application-reconsideration.dto'; import { ApplicationReconsiderationService } from '../../../../../services/application/application-reconsideration/application-reconsideration.service'; -import { ApplicationDto } from '../../../../../services/application/application.dto'; import { ApplicationService } from '../../../../../services/application/application.service'; import { ApplicationDecisionV2Service } from '../../../../../services/application/decision/application-decision-v2/application-decision-v2.service'; import { CardService } from '../../../../../services/card/card.service'; import { ToastService } from '../../../../../services/toast/toast.service'; import { parseStringToBoolean } from '../../../../../shared/utils/boolean-helper'; +import { MinimalBoardDto } from 'src/app/services/board/board.dto'; +import { BoardService } from 'src/app/services/board/board.service'; @Component({ selector: 'app-create', @@ -27,23 +25,21 @@ import { parseStringToBoolean } from '../../../../../shared/utils/boolean-helper export class CreateReconsiderationDialogComponent implements OnInit, OnDestroy { $destroy = new Subject(); applicationTypes: ApplicationTypeDto[] = []; - regions: ApplicationRegionDto[] = []; + boards: MinimalBoardDto[] = []; reconTypes: ReconsiderationTypeDto[] = []; - localGovernments: ApplicationLocalGovernmentDto[] = []; isLoading = false; isDecisionDateEmpty = false; - currentBoardCode: string = ''; decisions: { uuid: string; resolution: string }[] = []; - filteredApplications: Observable | undefined; - fileNumberControl = new FormControl('', [Validators.required]); - applicantControl = new FormControl('', [Validators.required]); + fileNumberControl = new FormControl({ value: '', disabled: true }, [Validators.required]); + applicantControl = new FormControl({ value: '', disabled: true }, [Validators.required]); applicationTypeControl = new FormControl(null, [Validators.required]); - regionControl = new FormControl(null, [Validators.required]); + boardControl = new FormControl(null, [Validators.required]); + regionControl = new FormControl({ value: null, disabled: true }, [Validators.required]); submittedDateControl = new FormControl(undefined, [Validators.required]); reconTypeControl = new FormControl(null, [Validators.required]); - localGovernmentControl = new FormControl(null, [Validators.required]); + localGovernmentControl = new FormControl({ value: null, disabled: true }, [Validators.required]); reconsidersDecisions = new FormControl([], [Validators.required]); descriptionControl = new FormControl('', [Validators.required]); isNewProposalControl = new FormControl(undefined, [Validators.required]); @@ -51,11 +47,12 @@ export class CreateReconsiderationDialogComponent implements OnInit, OnDestroy { isNewEvidenceControl = new FormControl(undefined, [Validators.required]); createForm: FormGroup = new FormGroup({ - applicationType: this.applicationTypeControl, fileNumber: this.fileNumberControl, applicant: this.applicantControl, region: this.regionControl, localGovernment: this.localGovernmentControl, + applicationType: this.applicationTypeControl, + board: this.boardControl, submittedDate: this.submittedDateControl, reconType: this.reconTypeControl, reconsidersDecisions: this.reconsidersDecisions, @@ -69,9 +66,9 @@ export class CreateReconsiderationDialogComponent implements OnInit, OnDestroy { @Inject(MAT_DIALOG_DATA) public data: any, private dialogRef: MatDialogRef, private applicationService: ApplicationService, + private boardService: BoardService, private cardService: CardService, private reconsiderationService: ApplicationReconsiderationService, - private localGovernmentService: ApplicationLocalGovernmentService, private toastService: ToastService, private decisionService: ApplicationDecisionV2Service, private router: Router, @@ -79,70 +76,37 @@ export class CreateReconsiderationDialogComponent implements OnInit, OnDestroy { ) {} ngOnInit(): void { - this.currentBoardCode = this.data.currentBoardCode; - this.cardService.fetchCodes(); - this.applicationService.$applicationTypes.pipe(takeUntil(this.$destroy)).subscribe((types) => { - this.applicationTypes = types; + this.createForm.patchValue({ + fileNumber: this.data.fileNumber, + applicant: this.data.applicant, + localGovernment: this.data.localGovernment.name, + region: this.data.region.label, }); - this.applicationService.$applicationRegions.pipe(takeUntil(this.$destroy)).subscribe((regions) => { - this.regions = regions; + this.applicationService.fetchApplication(this.data.fileNumber).then((application) => { + if (!application.decisionDate) { + this.isDecisionDateEmpty = true; + } }); - this.cardService.$cardReconTypes.pipe(takeUntil(this.$destroy)).subscribe((reconTypes) => { - this.reconTypes = reconTypes; + this.applicationService.$applicationTypes.pipe(takeUntil(this.$destroy)).subscribe((types) => { + this.applicationTypes = types; }); - this.localGovernmentService.list().then((res) => { - this.localGovernments = res; + this.boardService.$boards.subscribe((boards) => { + this.boards = boards.sort((a, b) => (a.title.toLowerCase() < b.title.toLowerCase() ? -1 : 1)); }); - this.initApplicationFileNumberAutocomplete(); - } - - initApplicationFileNumberAutocomplete() { - this.filteredApplications = this.fileNumberControl.valueChanges.pipe( - startWith(''), - debounceTime(400), - distinctUntilChanged(), - switchMap((val) => { - if (val && val.length > 1) { - return this.applicationService.searchApplicationsByNumber(val); - } - return []; - }), - ); - } - - autocompleteDisplay(application: ApplicationDto): string { - return application?.fileNumber ?? ''; - } - - async onApplicationSelected($event: MatOptionSelectionChange) { - if (!$event?.source?.value) { - return; - } - - const application = $event.source.value as ApplicationDto; - - this.fileNumberControl.disable(); - this.applicantControl.disable(); - this.regionControl.disable(); - this.applicationTypeControl.disable(); - this.localGovernmentControl.disable(); - - await this.loadDecisions(application.fileNumber); + this.applicationService.$applicationTypes.pipe(takeUntil(this.$destroy)).subscribe((types) => { + this.applicationTypes = types; + }); - this.createForm.patchValue({ - applicant: application.applicant, - region: application.region?.code, - applicationType: application.type.code, - localGovernment: this.localGovernments.find((g) => g.uuid === application.localGovernment?.uuid)?.uuid ?? null, + this.cardService.fetchCodes(); + this.cardService.$cardReconTypes.pipe(takeUntil(this.$destroy)).subscribe((reconTypes) => { + this.reconTypes = reconTypes; }); - if (!application.decisionDate) { - this.isDecisionDateEmpty = true; - } + this.loadDecisions(this.data.fileNumber); } async onSubmit() { @@ -160,7 +124,7 @@ export class CreateReconsiderationDialogComponent implements OnInit, OnDestroy { submittedDate: formValues.submittedDate!, reconTypeCode: formValues.reconType!, // card details - boardCode: this.currentBoardCode, + boardCode: formValues.board, reconsideredDecisionUuids: formValues.reconsidersDecisions!, description: formValues.description, isNewProposal: parseStringToBoolean(formValues.isNewProposal), @@ -187,11 +151,11 @@ export class CreateReconsiderationDialogComponent implements OnInit, OnDestroy { } } - onReset() { - this.fileNumberControl.reset(); - this.applicantControl.reset(); - this.regionControl.reset(); + onReset(event: MouseEvent) { + event.preventDefault(); + this.applicationTypeControl.reset(); + this.boardControl.reset(); this.submittedDateControl.reset(); this.reconTypeControl.reset(); this.reconsidersDecisions.reset(); @@ -199,22 +163,6 @@ export class CreateReconsiderationDialogComponent implements OnInit, OnDestroy { this.isIncorrectFalseInfoControl.reset(); this.isNewEvidenceControl.reset(); this.isNewProposalControl.reset(); - - this.fileNumberControl.enable(); - this.applicantControl.enable(); - this.regionControl.enable(); - this.applicationTypeControl.enable(); - this.localGovernmentControl.enable(); - this.reconsidersDecisions.disable(); - - // clear warnings - this.isDecisionDateEmpty = false; - } - - onSelectGovernment(value: ApplicationLocalGovernmentDto) { - this.createForm.patchValue({ - region: value.preferredRegionCode, - }); } async loadDecisions(fileNumber: string) { diff --git a/alcs-frontend/src/app/features/board/dialogs/reconsiderations/create/create-reconsideration-dialog.html b/alcs-frontend/src/app/features/board/dialogs/reconsiderations/create/create-reconsideration-dialog.html index 462d733b60..d49920ccc9 100644 --- a/alcs-frontend/src/app/features/board/dialogs/reconsiderations/create/create-reconsideration-dialog.html +++ b/alcs-frontend/src/app/features/board/dialogs/reconsiderations/create/create-reconsideration-dialog.html @@ -9,9 +9,7 @@

Create Reconsideration

Create Reconsideration (createForm.get('fileNumber')!.dirty || createForm.get('fileNumber')!.touched) " /> - - - - {{ option.fileNumber }} - - - - - This field is required. - Applicant Name @@ -55,14 +36,39 @@

Create Reconsideration

(createForm.get('applicant')!.dirty || createForm.get('applicant')!.touched) " /> - - This field is required. -
-
+ + Local Government + + + + Region + + +
Create Reconsideration
- -
{{ item.name }}
-
-
-
-
- + +
+ {{ item.title }} +
+
+ +
+ {{ item.title }} +
+
@@ -201,7 +198,7 @@

Create Reconsideration

-
From 1f032988e217897b4576c6c96aeb5549e467ce16 Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Tue, 28 May 2024 12:35:57 -0700 Subject: [PATCH 05/27] Remove unused `currentBoardCode` property --- .../create/create-app-modification-dialog.component.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.component.ts b/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.component.ts index a728976b77..7453d6bbe5 100644 --- a/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.component.ts +++ b/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.component.ts @@ -20,7 +20,6 @@ export class CreateAppModificationDialogComponent implements OnInit, OnDestroy { applicationTypes: ApplicationTypeDto[] = []; isLoading = false; isDecisionDateEmpty = false; - currentBoardCode: string = ''; decisions: { uuid: string; resolution: string }[] = []; @@ -58,8 +57,6 @@ export class CreateAppModificationDialogComponent implements OnInit, OnDestroy { ) {} ngOnInit(): void { - this.currentBoardCode = this.data.currentBoardCode; - this.createForm.patchValue({ fileNumber: this.data.fileNumber, applicant: this.data.applicant, From 8f15483305839a51d45ae023c849980575eeb086 Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Tue, 28 May 2024 12:36:25 -0700 Subject: [PATCH 06/27] Remove unnecessary error display --- .../create/create-app-modification-dialog.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.html b/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.html index 737f90a0c7..39ce7a6b08 100644 --- a/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.html +++ b/alcs-frontend/src/app/features/board/dialogs/app-modification/create/create-app-modification-dialog.html @@ -37,12 +37,6 @@

Create Modification

(createForm.get('applicant')!.dirty || createForm.get('applicant')!.touched) " /> - - This field is required. -
Date: Tue, 28 May 2024 12:39:47 -0700 Subject: [PATCH 07/27] Allow add NOI modi from post-decision page --- ...reate-noi-modification-dialog.component.ts | 106 ++++-------------- .../create-noi-modification-dialog.html | 86 +++++--------- .../post-decision.component.html | 5 +- .../post-decision.component.scss | 12 +- .../post-decision/post-decision.component.ts | 31 ++++- 5 files changed, 84 insertions(+), 156 deletions(-) diff --git a/alcs-frontend/src/app/features/board/dialogs/noi-modification/create/create-noi-modification-dialog.component.ts b/alcs-frontend/src/app/features/board/dialogs/noi-modification/create/create-noi-modification-dialog.component.ts index 23630927ec..d09235e396 100644 --- a/alcs-frontend/src/app/features/board/dialogs/noi-modification/create/create-noi-modification-dialog.component.ts +++ b/alcs-frontend/src/app/features/board/dialogs/noi-modification/create/create-noi-modification-dialog.component.ts @@ -1,17 +1,12 @@ import { Component, Inject, OnDestroy, OnInit } from '@angular/core'; import { FormControl, FormGroup, Validators } from '@angular/forms'; -import { MatOptionSelectionChange } from '@angular/material/core'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; -import { debounceTime, distinctUntilChanged, Observable, startWith, Subject, switchMap, takeUntil } from 'rxjs'; -import { ApplicationRegionDto, ApplicationTypeDto } from '../../../../../services/application/application-code.dto'; -import { ApplicationLocalGovernmentDto } from '../../../../../services/application/application-local-government/application-local-government.dto'; -import { ApplicationLocalGovernmentService } from '../../../../../services/application/application-local-government/application-local-government.service'; -import { ApplicationService } from '../../../../../services/application/application.service'; +import { Subject } from 'rxjs'; +import { ApplicationTypeDto } from '../../../../../services/application/application-code.dto'; import { NoticeOfIntentDecisionV2Service } from '../../../../../services/notice-of-intent/decision-v2/notice-of-intent-decision-v2.service'; import { NoticeOfIntentModificationCreateDto } from '../../../../../services/notice-of-intent/notice-of-intent-modification/notice-of-intent-modification.dto'; import { NoticeOfIntentModificationService } from '../../../../../services/notice-of-intent/notice-of-intent-modification/notice-of-intent-modification.service'; -import { NoticeOfIntentDto } from '../../../../../services/notice-of-intent/notice-of-intent.dto'; import { NoticeOfIntentService } from '../../../../../services/notice-of-intent/notice-of-intent.service'; import { ToastService } from '../../../../../services/toast/toast.service'; @@ -23,21 +18,17 @@ import { ToastService } from '../../../../../services/toast/toast.service'; export class CreateNoiModificationDialogComponent implements OnInit, OnDestroy { $destroy = new Subject(); applicationTypes: ApplicationTypeDto[] = []; - regions: ApplicationRegionDto[] = []; - localGovernments: ApplicationLocalGovernmentDto[] = []; isLoading = false; isDecisionDateEmpty = false; - currentBoardCode: string = ''; decisions: { uuid: string; resolution: string }[] = []; - filteredNOIs: Observable | undefined; - fileNumberControl = new FormControl('', [Validators.required]); - applicantControl = new FormControl('', [Validators.required]); + fileNumberControl = new FormControl({ value: '', disabled: true }, [Validators.required]); + applicantControl = new FormControl({ value: '', disabled: true }, [Validators.required]); descriptionControl = new FormControl('', [Validators.required]); - regionControl = new FormControl(null, [Validators.required]); + regionControl = new FormControl({ value: null, disabled: true }, [Validators.required]); submittedDateControl = new FormControl(undefined, [Validators.required]); - localGovernmentControl = new FormControl(null, [Validators.required]); + localGovernmentControl = new FormControl({ value: null, disabled: true }, [Validators.required]); modifiesDecisions = new FormControl([], [Validators.required]); createForm = new FormGroup({ @@ -54,9 +45,7 @@ export class CreateNoiModificationDialogComponent implements OnInit, OnDestroy { @Inject(MAT_DIALOG_DATA) public data: any, private dialogRef: MatDialogRef, private noticeOfIntentService: NoticeOfIntentService, - private applicationService: ApplicationService, private modificationService: NoticeOfIntentModificationService, - private localGovernmentService: ApplicationLocalGovernmentService, private decisionService: NoticeOfIntentDecisionV2Service, private toastService: ToastService, private router: Router, @@ -64,59 +53,20 @@ export class CreateNoiModificationDialogComponent implements OnInit, OnDestroy { ) {} ngOnInit(): void { - this.currentBoardCode = this.data.currentBoardCode; - - this.applicationService.$applicationRegions.pipe(takeUntil(this.$destroy)).subscribe((regions) => { - this.regions = regions; - }); - - this.localGovernmentService.list().then((res) => { - this.localGovernments = res; + this.createForm.patchValue({ + fileNumber: this.data.fileNumber, + applicant: this.data.applicant, + region: this.data.region.label, + localGovernment: this.data.localGovernment.name, }); - this.initFileNumberAutocomplete(); - } - - initFileNumberAutocomplete() { - this.filteredNOIs = this.fileNumberControl.valueChanges.pipe( - startWith(''), - debounceTime(400), - distinctUntilChanged(), - switchMap((val) => { - if (val && val.length > 1) { - return this.noticeOfIntentService.searchByFileNumber(val); - } - return []; - }), - ); - } - - autocompleteDisplay(application: NoticeOfIntentDto): string { - return application?.fileNumber ?? ''; - } - - async onNOISelected($event: MatOptionSelectionChange) { - if (!$event?.source?.value) { - return; - } - - const noticeOfIntent = $event.source.value as NoticeOfIntentDto; - this.fileNumberControl.disable(); - this.applicantControl.disable(); - this.regionControl.disable(); - this.localGovernmentControl.disable(); - - this.loadDecisions(noticeOfIntent.fileNumber); - - this.createForm.patchValue({ - applicant: noticeOfIntent.applicant, - region: noticeOfIntent.region.code, - localGovernment: this.localGovernments.find((g) => g.uuid === noticeOfIntent.localGovernment.uuid)?.uuid ?? null, + this.noticeOfIntentService.fetchByFileNumber(this.data.fileNumber).then((noi) => { + if (!noi?.decisionDate) { + this.isDecisionDateEmpty = true; + } }); - if (!noticeOfIntent.decisionDate) { - this.isDecisionDateEmpty = true; - } + this.loadDecisions(this.data.fileNumber); } async onSubmit() { @@ -129,7 +79,7 @@ export class CreateNoiModificationDialogComponent implements OnInit, OnDestroy { regionCode: formValues.region!, localGovernmentUuid: formValues.localGovernment!, submittedDate: formValues.submittedDate!.valueOf(), - boardCode: this.currentBoardCode, + boardCode: 'ceo', modifiesDecisionUuids: formValues.modifiesDecisions!, description: formValues.description!, }; @@ -154,28 +104,12 @@ export class CreateNoiModificationDialogComponent implements OnInit, OnDestroy { } } - onReset() { - this.fileNumberControl.reset(); - this.applicantControl.reset(); - this.regionControl.reset(); + onReset(event: MouseEvent) { + event.preventDefault(); + this.submittedDateControl.reset(); this.modifiesDecisions.reset(); this.descriptionControl.reset(); - - this.fileNumberControl.enable(); - this.applicantControl.enable(); - this.regionControl.enable(); - this.localGovernmentControl.enable(); - this.modifiesDecisions.disable(); - - // clear warnings - this.isDecisionDateEmpty = false; - } - - onSelectGovernment(value: ApplicationLocalGovernmentDto) { - this.createForm.patchValue({ - region: value.preferredRegionCode, - }); } async loadDecisions(fileNumber: string) { diff --git a/alcs-frontend/src/app/features/board/dialogs/noi-modification/create/create-noi-modification-dialog.html b/alcs-frontend/src/app/features/board/dialogs/noi-modification/create/create-noi-modification-dialog.html index 698ba99143..465ae9343d 100644 --- a/alcs-frontend/src/app/features/board/dialogs/noi-modification/create/create-noi-modification-dialog.html +++ b/alcs-frontend/src/app/features/board/dialogs/noi-modification/create/create-noi-modification-dialog.html @@ -9,9 +9,7 @@

Create Modification

Create Modification (createForm.get('fileNumber')!.dirty || createForm.get('fileNumber')!.touched) " /> - - - - {{ option.fileNumber }} - - - - - This field is required. - Applicant Name @@ -55,45 +36,38 @@

Create Modification

(createForm.get('applicant')!.dirty || createForm.get('applicant')!.touched) " /> - - This field is required. -
-
- + Local/First Nation Government + - -
{{ item.name }}
-
-
-
-
- + + + Region + - -
+ [class.valid]=" + createForm.get('region')!.valid && + (createForm.get('region')!.dirty || createForm.get('region')!.touched) + " + [class.invalid]=" + createForm.get('region')!.invalid && + (createForm.get('region')!.dirty || createForm.get('region')!.touched) + " + /> + Resolutions to be Modified @@ -150,7 +124,7 @@

Create Modification

-
diff --git a/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.html b/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.html index 9cc6aac01a..7ef619f269 100644 --- a/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.html +++ b/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.html @@ -1,6 +1,9 @@

Post-Decision

-
Modification Requests
+
+ Modification Requests + +
No Requests
diff --git a/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.scss b/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.scss index 77afb94fab..1d3619ac50 100644 --- a/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.scss +++ b/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.scss @@ -1,16 +1,12 @@ @use '../../../../styles/colors'; .post-decision-header { - margin: 24px 0 !important; + margin-top: 24px !important; display: flex; align-items: center; - - .icon { - margin-left: 8px; - height: 20px; - width: 20px; - font-size: 20px; - } + justify-content: space-between; + flex-wrap: wrap; + gap: 12px; } .post-decision { diff --git a/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.ts b/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.ts index 4fbe2f9219..0328993009 100644 --- a/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.ts +++ b/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.ts @@ -4,10 +4,11 @@ import { combineLatestWith, Subject, takeUntil } from 'rxjs'; import { NoticeOfIntentDetailService } from '../../../services/notice-of-intent/notice-of-intent-detail.service'; import { NoticeOfIntentModificationDto } from '../../../services/notice-of-intent/notice-of-intent-modification/notice-of-intent-modification.dto'; import { NoticeOfIntentModificationService } from '../../../services/notice-of-intent/notice-of-intent-modification/notice-of-intent-modification.service'; -import { ToastService } from '../../../services/toast/toast.service'; import { ConfirmationDialogService } from '../../../shared/confirmation-dialog/confirmation-dialog.service'; -import { formatDateForApi } from '../../../shared/utils/api-date-formatter'; import { EditModificationDialogComponent } from './edit-modification-dialog/edit-modification-dialog.component'; +import { CreateNoiModificationDialogComponent } from '../../board/dialogs/noi-modification/create/create-noi-modification-dialog.component'; +import { ApplicationLocalGovernmentDto } from 'src/app/services/application/application-local-government/application-local-government.dto'; +import { ApplicationRegionDto } from 'src/app/services/application/application-code.dto'; type LoadingModifications = NoticeOfIntentModificationDto & { modifiesDecisionsNumbers: string[]; @@ -20,14 +21,16 @@ type LoadingModifications = NoticeOfIntentModificationDto & { export class PostDecisionComponent implements OnInit, OnDestroy { $destroy = new Subject(); fileNumber: string = ''; + applicant: string = ''; + localGovernment: ApplicationLocalGovernmentDto | undefined = undefined; + region: ApplicationRegionDto | undefined = undefined; modifications: LoadingModifications[] = []; constructor( public dialog: MatDialog, private noticeOfIntentDetailService: NoticeOfIntentDetailService, private modificationService: NoticeOfIntentModificationService, - private toastService: ToastService, - private confirmationDialogService: ConfirmationDialogService + private confirmationDialogService: ConfirmationDialogService, ) {} ngOnInit(): void { @@ -37,17 +40,35 @@ export class PostDecisionComponent implements OnInit, OnDestroy { .subscribe(([application, modifications]) => { if (application) { this.fileNumber = application.fileNumber; + this.applicant = application.applicant; + this.localGovernment = application.localGovernment; + this.region = application.region; this.modifications = modifications?.map((m) => ({ ...m, modifiesDecisionsNumbers: m.modifiesDecisions.flatMap( - (d) => `#${d.resolutionNumber}/${d.resolutionYear}` + (d) => `#${d.resolutionNumber}/${d.resolutionYear}`, ), })) ?? []; } }); } + onCreateModification() { + this.dialog.open(CreateNoiModificationDialogComponent, { + minWidth: '600px', + maxWidth: '1100px', + maxHeight: '80vh', + width: '90%', + data: { + fileNumber: this.fileNumber, + applicant: this.applicant, + localGovernment: this.localGovernment, + region: this.region, + }, + }); + } + onEditModification(modification: NoticeOfIntentModificationDto) { this.dialog .open(EditModificationDialogComponent, { From 26ce589336d3c3b038dc5be2fb8d11f2bdb6328e Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Tue, 28 May 2024 12:47:39 -0700 Subject: [PATCH 08/27] Refresh `post-decision` after adding modi/recon --- .../post-decision/post-decision.component.ts | 62 ++++++++++++------- .../post-decision/post-decision.component.ts | 31 ++++++---- 2 files changed, 57 insertions(+), 36 deletions(-) diff --git a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts index 49d5551a50..8078ae43a5 100644 --- a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts +++ b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts @@ -111,33 +111,47 @@ export class PostDecisionComponent implements OnInit, OnDestroy { } onCreateReconsideration() { - const dialog = this.dialog.open(CreateReconsiderationDialogComponent, { - minWidth: '600px', - maxWidth: '1100px', - maxHeight: '80vh', - width: '90%', - data: { - fileNumber: this.fileNumber, - applicant: this.applicant, - localGovernment: this.localGovernment, - region: this.region, - }, - }); + this.dialog + .open(CreateReconsiderationDialogComponent, { + minWidth: '600px', + maxWidth: '1100px', + maxHeight: '80vh', + width: '90%', + data: { + fileNumber: this.fileNumber, + applicant: this.applicant, + localGovernment: this.localGovernment, + region: this.region, + }, + }) + .afterClosed() + .subscribe(async (answer) => { + if (answer) { + await this.applicationReconsiderationService.fetchByApplication(this.fileNumber); + } + }); } onCreateModification() { - const dialog = this.dialog.open(CreateAppModificationDialogComponent, { - minWidth: '600px', - maxWidth: '1100px', - maxHeight: '80vh', - width: '90%', - data: { - fileNumber: this.fileNumber, - applicant: this.applicant, - localGovernment: this.localGovernment, - region: this.region, - }, - }); + this.dialog + .open(CreateAppModificationDialogComponent, { + minWidth: '600px', + maxWidth: '1100px', + maxHeight: '80vh', + width: '90%', + data: { + fileNumber: this.fileNumber, + applicant: this.applicant, + localGovernment: this.localGovernment, + region: this.region, + }, + }) + .afterClosed() + .subscribe(async (answer) => { + if (answer) { + await this.modificationService.fetchByApplication(this.fileNumber); + } + }); } onEditModification(modification: ApplicationModificationDto) { diff --git a/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.ts b/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.ts index 0328993009..b07f075cc1 100644 --- a/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.ts +++ b/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.ts @@ -55,18 +55,25 @@ export class PostDecisionComponent implements OnInit, OnDestroy { } onCreateModification() { - this.dialog.open(CreateNoiModificationDialogComponent, { - minWidth: '600px', - maxWidth: '1100px', - maxHeight: '80vh', - width: '90%', - data: { - fileNumber: this.fileNumber, - applicant: this.applicant, - localGovernment: this.localGovernment, - region: this.region, - }, - }); + this.dialog + .open(CreateNoiModificationDialogComponent, { + minWidth: '600px', + maxWidth: '1100px', + maxHeight: '80vh', + width: '90%', + data: { + fileNumber: this.fileNumber, + applicant: this.applicant, + localGovernment: this.localGovernment, + region: this.region, + }, + }) + .afterClosed() + .subscribe(async (answer) => { + if (answer) { + await this.modificationService.fetchByFileNumber(this.fileNumber); + } + }); } onEditModification(modification: NoticeOfIntentModificationDto) { From 49707760fc446b1e953be441011e0b4f9cde28a5 Mon Sep 17 00:00:00 2001 From: Liam Stoddard Date: Tue, 28 May 2024 14:29:14 -0700 Subject: [PATCH 09/27] add document description to application, NOI, and SRW --- ...6916423632-map_optional_doc_description.ts | 44 +++++++++++++++++++ ...980113-map_optional_doc_description_NOI.ts | 44 +++++++++++++++++++ ...436980-map_optional_doc_description_SRW.ts | 44 +++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 services/apps/alcs/src/providers/typeorm/migrations/1716916423632-map_optional_doc_description.ts create mode 100644 services/apps/alcs/src/providers/typeorm/migrations/1716925980113-map_optional_doc_description_NOI.ts create mode 100644 services/apps/alcs/src/providers/typeorm/migrations/1716926436980-map_optional_doc_description_SRW.ts diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1716916423632-map_optional_doc_description.ts b/services/apps/alcs/src/providers/typeorm/migrations/1716916423632-map_optional_doc_description.ts new file mode 100644 index 0000000000..0e1ad8bb20 --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1716916423632-map_optional_doc_description.ts @@ -0,0 +1,44 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class MapOptionalDocDescription1716916423632 + implements MigrationInterface +{ + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DO $$ + BEGIN + IF EXISTS (SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'oats') THEN + WITH alcs_application_doc_to_update AS ( + SELECT + ad.oats_application_id, + ad.oats_document_id + FROM + alcs.application_document ad + WHERE + audit_created_by = 'oats_etl' + AND description IS NULL + ), + application_doc_description AS ( + SELECT + od.document_id, + od.description + FROM + oats.oats_documents od + JOIN alcs_application_doc_to_update AS alcs_docs ON + alcs_docs.oats_document_id::bigint = od.document_id + WHERE + od.description IS NOT NULL + ) + UPDATE alcs.application_document + SET description = COALESCE(application_doc_description.description, alcs.application_document.description) + FROM application_doc_description + WHERE alcs.application_document.oats_document_id = application_doc_description.document_id::TEXT; + END IF; + END $$; + `); + } + + public async down(queryRunner: QueryRunner): Promise { + //NONE + } +} diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1716925980113-map_optional_doc_description_NOI.ts b/services/apps/alcs/src/providers/typeorm/migrations/1716925980113-map_optional_doc_description_NOI.ts new file mode 100644 index 0000000000..1da8982325 --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1716925980113-map_optional_doc_description_NOI.ts @@ -0,0 +1,44 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class MapOptionalDocDescriptionNOI1716925980113 + implements MigrationInterface +{ + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DO $$ + BEGIN + IF EXISTS (SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'oats') THEN + WITH alcs_noi_doc_to_update AS ( + SELECT + ad.oats_application_id, + ad.oats_document_id + FROM + alcs.notice_of_intent_document ad + WHERE + audit_created_by = 'oats_etl' + AND description IS NULL + ), + noi_doc_description AS ( + SELECT + od.document_id, + od.description + FROM + oats.oats_documents od + JOIN alcs_noi_doc_to_update AS alcs_docs ON + alcs_docs.oats_document_id::bigint = od.document_id + WHERE + od.description IS NOT NULL + ) + UPDATE alcs.notice_of_intent_document + SET description = COALESCE(noi_doc_description.description, alcs.notice_of_intent_document.description) + FROM noi_doc_description + WHERE alcs.notice_of_intent_document.oats_document_id = noi_doc_description.document_id::TEXT; + END IF; + END $$; + `); + } + + public async down(queryRunner: QueryRunner): Promise { + //NONE + } +} diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1716926436980-map_optional_doc_description_SRW.ts b/services/apps/alcs/src/providers/typeorm/migrations/1716926436980-map_optional_doc_description_SRW.ts new file mode 100644 index 0000000000..210592937d --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1716926436980-map_optional_doc_description_SRW.ts @@ -0,0 +1,44 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class MapOptionalDocDescriptionSRW1716926436980 + implements MigrationInterface +{ + public async up(queryRunner: QueryRunner): Promise { + queryRunner.query(` + DO $$ + BEGIN + IF EXISTS (SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'oats') THEN + WITH alcs_srw_doc_to_update AS ( + SELECT + ad.oats_application_id, + ad.oats_document_id + FROM + alcs.notification_document ad + WHERE + audit_created_by = 'oats_etl' + AND description IS NULL + ), + srw_doc_description AS ( + SELECT + od.document_id, + od.description + FROM + oats.oats_documents od + JOIN alcs_srw_doc_to_update AS alcs_docs ON + alcs_docs.oats_document_id::bigint = od.document_id + WHERE + od.description IS NOT NULL + ) + UPDATE alcs.notification_document + SET description = COALESCE(srw_doc_description.description, alcs.notification_document.description) + FROM srw_doc_description + WHERE alcs.notification_document.oats_document_id = srw_doc_description.document_id::TEXT; + END IF; + END $$; + `); + } + + public async down(queryRunner: QueryRunner): Promise { + //NONE + } +} From ccdcb4ec8a8899417283263064c26221192b8546 Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Wed, 29 May 2024 10:11:40 -0700 Subject: [PATCH 10/27] Disable COV, MODI, NOIM, and RECON create card types --- .../board-management-dialog.component.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/alcs-frontend/src/app/features/admin/board-management/board-management-dialog/board-management-dialog.component.ts b/alcs-frontend/src/app/features/admin/board-management/board-management-dialog/board-management-dialog.component.ts index 388c5d1892..32f11db8b7 100644 --- a/alcs-frontend/src/app/features/admin/board-management/board-management-dialog/board-management-dialog.component.ts +++ b/alcs-frontend/src/app/features/admin/board-management/board-management-dialog/board-management-dialog.component.ts @@ -11,7 +11,16 @@ import { CardStatusService } from '../../../../services/card/card-status/card-st import { CardType } from '../../../../shared/card/card.component'; import { BaseCodeDto } from '../../../../shared/dto/base.dto'; -const DISABLED_CREATE_CARD_TYPES = [CardType.APP, CardType.NOI, CardType.NOTIFICATION]; +const DISABLED_CREATE_CARD_TYPES = [ + CardType.APP, + // Has been removed from `CardType`, but still exists in DB + 'COV', + CardType.MODI, + CardType.NOI, + CardType.NOI_MODI, + CardType.NOTIFICATION, + CardType.RECON, +]; @Component({ selector: 'app-decision-condition-types-dialog', From cc66d42b3aa3cfdd8897f78a63d6b84f6245b2df Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Wed, 29 May 2024 10:31:45 -0700 Subject: [PATCH 11/27] Remove disallowed create card types form boards --- ...move_disallowed_create_card_types_from_boards.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 services/apps/alcs/src/providers/typeorm/migrations/1717003331488-remove_disallowed_create_card_types_from_boards.ts diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1717003331488-remove_disallowed_create_card_types_from_boards.ts b/services/apps/alcs/src/providers/typeorm/migrations/1717003331488-remove_disallowed_create_card_types_from_boards.ts new file mode 100644 index 0000000000..7a07b7d9ef --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1717003331488-remove_disallowed_create_card_types_from_boards.ts @@ -0,0 +1,13 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class RemoveDisallowedCreateCardTypesFromBoards1717003331488 + implements MigrationInterface +{ + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `delete from alcs.board_create_card_types_card_type where card_type_code in ('COV', 'RECON', 'MODI', 'NOIM')`, + ); + } + + public async down(queryRunner: QueryRunner): Promise {} +} From b6f509126bbee8146c3f9b3eebcf1641460955ca Mon Sep 17 00:00:00 2001 From: Daniel Haselhan Date: Tue, 28 May 2024 16:59:30 -0700 Subject: [PATCH 12/27] Add created by me filter to Inbox Search --- .../features/home/inbox/inbox.component.html | 4 ++ .../features/home/inbox/inbox.component.ts | 11 +++-- .../authentication/authentication.dto.ts | 1 + .../src/app/services/inbox/inbox.dto.ts | 3 ++ .../app/services/inbox/inbox.service.spec.ts | 16 +++---- .../inbox-application.service.spec.ts | 1 + .../application/inbox-application.service.ts | 6 +-- .../src/portal/inbox/inbox.controller.spec.ts | 48 ++++++++----------- .../apps/alcs/src/portal/inbox/inbox.dto.ts | 4 ++ .../inbox-notice-of-intent.service.spec.ts | 1 + .../inbox-notice-of-intent.service.ts | 6 +-- .../inbox-notification.service.spec.ts | 1 + .../inbox-notification.service.ts | 6 +-- .../alcs/src/user/user.controller.spec.ts | 9 ++-- .../apps/alcs/src/user/user.controller.ts | 5 +- services/apps/alcs/src/user/user.dto.ts | 1 + .../search/application-search-filters.ts | 2 +- .../search/notice-of-intent-search-filters.ts | 2 +- .../search/notification-search-filters.ts | 2 +- 19 files changed, 71 insertions(+), 58 deletions(-) diff --git a/portal-frontend/src/app/features/home/inbox/inbox.component.html b/portal-frontend/src/app/features/home/inbox/inbox.component.html index 6bc02a84df..91bc7cc15e 100644 --- a/portal-frontend/src/app/features/home/inbox/inbox.component.html +++ b/portal-frontend/src/app/features/home/inbox/inbox.component.html @@ -11,6 +11,10 @@ /> +
+ Only show created by me +
+ {{ panel.expanded ? 'Less' : 'More' }} Search Options diff --git a/portal-frontend/src/app/features/home/inbox/inbox.component.ts b/portal-frontend/src/app/features/home/inbox/inbox.component.ts index 208f279f0b..6c3d01234c 100644 --- a/portal-frontend/src/app/features/home/inbox/inbox.component.ts +++ b/portal-frontend/src/app/features/home/inbox/inbox.component.ts @@ -1,9 +1,10 @@ -import { Component, HostListener, OnDestroy, OnInit, ViewChild, Input, SimpleChanges } from '@angular/core'; +import { Component, HostListener, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { FormControl, FormGroup } from '@angular/forms'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { MatTabGroup } from '@angular/material/tabs'; import { Title } from '@angular/platform-browser'; +import { ActivatedRoute, Router } from '@angular/router'; import { Subject, takeUntil } from 'rxjs'; import { ApplicationStatusDto, @@ -17,7 +18,6 @@ import { ToastService } from '../../../services/toast/toast.service'; import { MOBILE_BREAKPOINT } from '../../../shared/utils/breakpoints'; import { FileTypeFilterDropDownComponent } from '../../public/search/file-type-filter-drop-down/file-type-filter-drop-down.component'; import { TableChange } from '../../public/search/search.interface'; -import { ActivatedRoute, Router } from '@angular/router'; export interface InboxResultDto extends BaseInboxResultDto { statusType: ApplicationStatusDto; @@ -48,6 +48,7 @@ export class InboxComponent implements OnInit, OnDestroy { @ViewChild(MatPaginator) paginator!: MatPaginator; @ViewChild(MatSort) sort?: MatSort; + @ViewChild(MatTabGroup) set tab(tabGroup: MatTabGroup) { if (tabGroup) { @@ -58,6 +59,7 @@ export class InboxComponent implements OnInit, OnDestroy { } this.tabGroup = tabGroup; } + @ViewChild('fileTypeDropDown') fileTypeFilterDropDownComponent!: FileTypeFilterDropDownComponent; @Input() currentTabName: string = ''; @@ -82,6 +84,7 @@ export class InboxComponent implements OnInit, OnDestroy { nameControl = new FormControl(undefined); civicAddressControl = new FormControl(undefined); filterBy = new FormControl(undefined); + createdByMe = new FormControl(false); searchForm = new FormGroup({ fileNumber: new FormControl(undefined), name: this.nameControl, @@ -91,6 +94,7 @@ export class InboxComponent implements OnInit, OnDestroy { componentType: this.componentTypeControl, governmentFileNumber: this.governmentFileNumber, filterBy: this.filterBy, + createdByMe: this.createdByMe, }); previousFileTypes: string[] = []; @@ -130,7 +134,7 @@ export class InboxComponent implements OnInit, OnDestroy { private titleService: Title, private authenticationService: AuthenticationService, private router: Router, - private route: ActivatedRoute + private route: ActivatedRoute, ) { this.titleService.setTitle('ALC Portal | Inbox'); } @@ -230,6 +234,7 @@ export class InboxComponent implements OnInit, OnDestroy { governmentFileNumber: this.formatStringSearchParam(searchControls.governmentFileNumber.value), fileTypes: searchControls.componentType.value ? searchControls.componentType.value : [], filterBy: searchControls.filterBy.value ?? undefined, + createdByMe: searchControls.createdByMe.value ?? false, }; } diff --git a/portal-frontend/src/app/services/authentication/authentication.dto.ts b/portal-frontend/src/app/services/authentication/authentication.dto.ts index b5dd877157..5fd7f693b7 100644 --- a/portal-frontend/src/app/services/authentication/authentication.dto.ts +++ b/portal-frontend/src/app/services/authentication/authentication.dto.ts @@ -9,5 +9,6 @@ export interface UserDto { government?: string; isLocalGovernment: boolean; isFirstNationGovernment: boolean; + isBusiness: boolean; businessName?: string | null; } diff --git a/portal-frontend/src/app/services/inbox/inbox.dto.ts b/portal-frontend/src/app/services/inbox/inbox.dto.ts index e1045fc15d..e9e2ff9e10 100644 --- a/portal-frontend/src/app/services/inbox/inbox.dto.ts +++ b/portal-frontend/src/app/services/inbox/inbox.dto.ts @@ -10,7 +10,9 @@ export interface BaseInboxResultDto { } export interface ApplicationInboxResultDto extends BaseInboxResultDto {} + export interface NoticeOfIntentInboxResultDto extends BaseInboxResultDto {} + export interface NotificationInboxResultDto extends BaseInboxResultDto {} export interface InboxSearchResponseDto { @@ -41,4 +43,5 @@ export interface InboxRequestDto extends PagingRequestDto { governmentFileNumber?: string; fileTypes: string[]; filterBy?: string; + createdByMe: boolean; } diff --git a/portal-frontend/src/app/services/inbox/inbox.service.spec.ts b/portal-frontend/src/app/services/inbox/inbox.service.spec.ts index 8009dc6403..d040b8c87f 100644 --- a/portal-frontend/src/app/services/inbox/inbox.service.spec.ts +++ b/portal-frontend/src/app/services/inbox/inbox.service.spec.ts @@ -3,6 +3,7 @@ import { TestBed } from '@angular/core/testing'; import { createMock, DeepMocked } from '@golevelup/ts-jest'; import { of, throwError } from 'rxjs'; import { ToastService } from '../toast/toast.service'; +import { InboxRequestDto } from './inbox.dto'; import { InboxService } from './inbox.service'; describe('InboxService', () => { @@ -24,12 +25,11 @@ describe('InboxService', () => { totalNonApplications: 0, }; - const mockSearchRequestDto = { + const mockSearchRequestDto: InboxRequestDto = { pageSize: 1, page: 1, - sortField: '1', - sortDirection: 'ASC', fileTypes: [], + createdByMe: false, }; beforeEach(() => { @@ -72,7 +72,7 @@ describe('InboxService', () => { mockHttpClient.post.mockReturnValue( throwError(() => { new Error(''); - }) + }), ); const res = await service.search(mockSearchRequestDto); @@ -97,7 +97,7 @@ describe('InboxService', () => { mockHttpClient.post.mockReturnValue( throwError(() => { new Error(''); - }) + }), ); const res = await service.searchApplications(mockSearchRequestDto); @@ -122,7 +122,7 @@ describe('InboxService', () => { mockHttpClient.post.mockReturnValue( throwError(() => { new Error(''); - }) + }), ); const res = await service.searchNoticeOfIntents(mockSearchRequestDto); @@ -147,7 +147,7 @@ describe('InboxService', () => { mockHttpClient.post.mockReturnValue( throwError(() => { new Error(''); - }) + }), ); const res = await service.searchNotifications(mockSearchRequestDto); @@ -170,7 +170,7 @@ describe('InboxService', () => { mockHttpClient.get.mockReturnValue( throwError(() => { new Error(''); - }) + }), ); const res = await service.listStatuses(); diff --git a/services/apps/alcs/src/portal/inbox/application/inbox-application.service.spec.ts b/services/apps/alcs/src/portal/inbox/application/inbox-application.service.spec.ts index 3496e6a70c..ef83ad0e71 100644 --- a/services/apps/alcs/src/portal/inbox/application/inbox-application.service.spec.ts +++ b/services/apps/alcs/src/portal/inbox/application/inbox-application.service.spec.ts @@ -34,6 +34,7 @@ describe('InboxApplicationService', () => { fileTypes: ['type1', 'type2'], page: 1, pageSize: 10, + createdByMe: false, }; let mockQuery: any = {}; diff --git a/services/apps/alcs/src/portal/inbox/application/inbox-application.service.ts b/services/apps/alcs/src/portal/inbox/application/inbox-application.service.ts index b3ca949803..48a190e773 100644 --- a/services/apps/alcs/src/portal/inbox/application/inbox-application.service.ts +++ b/services/apps/alcs/src/portal/inbox/application/inbox-application.service.ts @@ -87,17 +87,17 @@ export class InboxApplicationService { //User Permissions let where = '"appSearch".created_by_uuid = :userUuid'; if (!searchDto.filterBy) { - if (bceidBusinessGuid) { + if (bceidBusinessGuid && !searchDto.createdByMe) { where += ' OR "appSearch".bceid_business_guid = :bceidBusinessGuid'; } - if (governmentUuid) { + if (governmentUuid && !searchDto.createdByMe) { where += ` OR ("appSearch".local_government_uuid = :governmentUuid AND ("appSearch".date_submitted_to_alc IS NOT NULL OR appSearch.status ->> 'status_type_code' IN ('REVG', 'SUBG', 'INCG')))`; } //Prevent someone without governmentUuid from using filterBy } else if (governmentUuid && bceidBusinessGuid) { if (searchDto.filterBy === 'submitted') { where = `"appSearch".local_government_uuid = :governmentUuid AND ("appSearch".date_submitted_to_alc IS NOT NULL OR appSearch.status ->> 'status_type_code' IN ('REVG', 'SUBG', 'INCG'))`; - } else { + } else if (!searchDto.createdByMe) { where = '("appSearch".created_by_uuid = :userUuid OR "appSearch".bceid_business_guid = :bceidBusinessGuid)'; } diff --git a/services/apps/alcs/src/portal/inbox/inbox.controller.spec.ts b/services/apps/alcs/src/portal/inbox/inbox.controller.spec.ts index f365f3e8f7..719ae0fbca 100644 --- a/services/apps/alcs/src/portal/inbox/inbox.controller.spec.ts +++ b/services/apps/alcs/src/portal/inbox/inbox.controller.spec.ts @@ -1,7 +1,7 @@ -import { classes } from 'automapper-classes'; -import { AutomapperModule } from 'automapper-nestjs'; import { createMock, DeepMocked } from '@golevelup/nestjs-testing'; import { Test, TestingModule } from '@nestjs/testing'; +import { classes } from 'automapper-classes'; +import { AutomapperModule } from 'automapper-nestjs'; import { ClsService } from 'nestjs-cls'; import { mockKeyCloakProviders } from '../../../test/mocks/mockTypes'; import { ApplicationSubmissionStatusService } from '../../alcs/application/application-submission-status/application-submission-status.service'; @@ -10,10 +10,10 @@ import { NotificationSubmissionStatusService } from '../../alcs/notification/not import { User } from '../../user/user.entity'; import { UserService } from '../../user/user.service'; import { InboxApplicationService } from './application/inbox-application.service'; -import { InboxNoticeOfIntentService } from './notice-of-intent/inbox-notice-of-intent.service'; -import { InboxNotificationService } from './notification/inbox-notification.service'; import { InboxController } from './inbox.controller'; import { InboxRequestDto } from './inbox.dto'; +import { InboxNoticeOfIntentService } from './notice-of-intent/inbox-notice-of-intent.service'; +import { InboxNotificationService } from './notification/inbox-notification.service'; describe('InboxController', () => { let controller: InboxController; @@ -26,6 +26,7 @@ describe('InboxController', () => { let mockUserService: DeepMocked; let mockRequest; + let mockSearchRequest; const mockUserId = 'fake-user-uuid'; beforeEach(async () => { @@ -108,6 +109,12 @@ describe('InboxController', () => { }), }, }; + + mockSearchRequest = { + pageSize: 1, + page: 1, + fileTypes: [], + }; }); it('should be defined', () => { @@ -116,10 +123,8 @@ describe('InboxController', () => { it('should call search to retrieve Applications, NOIs, Notifications', async () => { const mockSearchRequestDto: InboxRequestDto = { - pageSize: 1, - page: 1, name: 'test', - fileTypes: [], + ...mockSearchRequest, }; const result = await controller.search(mockSearchRequestDto, mockRequest); @@ -146,20 +151,14 @@ describe('InboxController', () => { }); it('should call applications advanced search to retrieve Applications', async () => { - const mockSearchRequestDto: InboxRequestDto = { - pageSize: 1, - page: 1, - fileTypes: [], - }; - const result = await controller.searchApplications( - mockSearchRequestDto, + mockSearchRequest, mockRequest, ); expect(mockAppPublicSearchService.searchApplications).toBeCalledTimes(1); expect(mockAppPublicSearchService.searchApplications).toBeCalledWith( - mockSearchRequestDto, + mockSearchRequest, mockUserId, null, null, @@ -169,20 +168,14 @@ describe('InboxController', () => { }); it('should call NOI advanced search to retrieve NOIs', async () => { - const mockSearchRequestDto: InboxRequestDto = { - pageSize: 1, - page: 1, - fileTypes: [], - }; - const result = await controller.searchNoticeOfIntents( - mockSearchRequestDto, + mockSearchRequest, mockRequest, ); expect(mockNOIPublicSearchService.searchNoticeOfIntents).toBeCalledTimes(1); expect(mockNOIPublicSearchService.searchNoticeOfIntents).toBeCalledWith( - mockSearchRequestDto, + mockSearchRequest, mockUserId, null, null, @@ -193,8 +186,7 @@ describe('InboxController', () => { it('should call search to retrieve Applications only when application file type selected', async () => { const mockSearchRequestDto: InboxRequestDto = { - pageSize: 1, - page: 1, + ...mockSearchRequest, fileTypes: ['NFUP'], }; @@ -213,8 +205,7 @@ describe('InboxController', () => { it('should call search to retrieve NOIs only when NOI file type selected', async () => { const mockSearchRequestDto: InboxRequestDto = { - pageSize: 1, - page: 1, + ...mockSearchRequest, fileTypes: ['NOI'], }; @@ -233,8 +224,7 @@ describe('InboxController', () => { it('should NOT call NOI search to retrieve if file type app specified', async () => { const mockSearchRequestDto: InboxRequestDto = { - pageSize: 1, - page: 1, + ...mockSearchRequest, fileTypes: ['NFUP'], }; diff --git a/services/apps/alcs/src/portal/inbox/inbox.dto.ts b/services/apps/alcs/src/portal/inbox/inbox.dto.ts index d8e44530e8..83586aaf55 100644 --- a/services/apps/alcs/src/portal/inbox/inbox.dto.ts +++ b/services/apps/alcs/src/portal/inbox/inbox.dto.ts @@ -1,5 +1,6 @@ import { IsArray, + IsBoolean, IsNumber, IsOptional, IsString, @@ -80,6 +81,9 @@ export class InboxRequestDto { @IsArray() fileTypes: string[]; + + @IsBoolean() + createdByMe: boolean; } // typeorm does not transform property names for the status diff --git a/services/apps/alcs/src/portal/inbox/notice-of-intent/inbox-notice-of-intent.service.spec.ts b/services/apps/alcs/src/portal/inbox/notice-of-intent/inbox-notice-of-intent.service.spec.ts index 69976b8d8f..25ce3742c5 100644 --- a/services/apps/alcs/src/portal/inbox/notice-of-intent/inbox-notice-of-intent.service.spec.ts +++ b/services/apps/alcs/src/portal/inbox/notice-of-intent/inbox-notice-of-intent.service.spec.ts @@ -29,6 +29,7 @@ describe('InboxNoticeOfIntentService', () => { fileTypes: ['NOI'], page: 1, pageSize: 10, + createdByMe: false, }; let mockQuery: any = {}; diff --git a/services/apps/alcs/src/portal/inbox/notice-of-intent/inbox-notice-of-intent.service.ts b/services/apps/alcs/src/portal/inbox/notice-of-intent/inbox-notice-of-intent.service.ts index fe71ab3fc6..b08c2178c3 100644 --- a/services/apps/alcs/src/portal/inbox/notice-of-intent/inbox-notice-of-intent.service.ts +++ b/services/apps/alcs/src/portal/inbox/notice-of-intent/inbox-notice-of-intent.service.ts @@ -82,10 +82,10 @@ export class InboxNoticeOfIntentService { //User Permissions let where = 'noiSearch.created_by_uuid = :userUuid'; if (!searchDto.filterBy) { - if (bceidBusinessGuid) { + if (bceidBusinessGuid && !searchDto.createdByMe) { where += ' OR noiSearch.bceid_business_guid = :bceidBusinessGuid'; } - if (governmentUuid) { + if (governmentUuid && !searchDto.createdByMe) { where += ' OR (noiSearch.local_government_uuid = :governmentUuid AND noiSearch.date_submitted_to_alc IS NOT NULL)'; } @@ -93,7 +93,7 @@ export class InboxNoticeOfIntentService { if (searchDto.filterBy === 'submitted') { where = 'noiSearch.local_government_uuid = :governmentUuid AND noiSearch.date_submitted_to_alc IS NOT NULL'; - } else { + } else if (!searchDto.createdByMe) { where = '(noiSearch.created_by_uuid = :userUuid OR noiSearch.bceid_business_guid = :bceidBusinessGuid)'; } diff --git a/services/apps/alcs/src/portal/inbox/notification/inbox-notification.service.spec.ts b/services/apps/alcs/src/portal/inbox/notification/inbox-notification.service.spec.ts index 7c3f432bcd..e6c1eb87ce 100644 --- a/services/apps/alcs/src/portal/inbox/notification/inbox-notification.service.spec.ts +++ b/services/apps/alcs/src/portal/inbox/notification/inbox-notification.service.spec.ts @@ -31,6 +31,7 @@ describe('InboxNotificationService', () => { fileTypes: ['SRW'], page: 1, pageSize: 10, + createdByMe: false, }; let mockQuery: any = {}; diff --git a/services/apps/alcs/src/portal/inbox/notification/inbox-notification.service.ts b/services/apps/alcs/src/portal/inbox/notification/inbox-notification.service.ts index 11d6e9498a..9ff5e26106 100644 --- a/services/apps/alcs/src/portal/inbox/notification/inbox-notification.service.ts +++ b/services/apps/alcs/src/portal/inbox/notification/inbox-notification.service.ts @@ -82,11 +82,11 @@ export class InboxNotificationService { //User Permissions let where = 'notificationSearch.created_by_uuid = :userUuid'; if (!searchDto.filterBy) { - if (bceidBusinessGuid) { + if (bceidBusinessGuid && !searchDto.createdByMe) { where += ' OR notificationSearch.bceid_business_guid = :bceidBusinessGuid'; } - if (governmentUuid) { + if (governmentUuid && !searchDto.createdByMe) { where += ' OR (notificationSearch.local_government_uuid = :governmentUuid AND notificationSearch.date_submitted_to_alc IS NOT NULL)'; } @@ -94,7 +94,7 @@ export class InboxNotificationService { if (searchDto.filterBy === 'submitted') { where = 'notificationSearch.local_government_uuid = :governmentUuid AND notificationSearch.date_submitted_to_alc IS NOT NULL'; - } else { + } else if (!searchDto.createdByMe) { where = '(notificationSearch.created_by_uuid = :userUuid OR notificationSearch.bceid_business_guid = :bceidBusinessGuid)'; } diff --git a/services/apps/alcs/src/user/user.controller.spec.ts b/services/apps/alcs/src/user/user.controller.spec.ts index c996b96c52..703bafd21c 100644 --- a/services/apps/alcs/src/user/user.controller.spec.ts +++ b/services/apps/alcs/src/user/user.controller.spec.ts @@ -1,15 +1,15 @@ -import { classes } from 'automapper-classes'; -import { AutomapperModule } from 'automapper-nestjs'; import { createMock, DeepMocked } from '@golevelup/nestjs-testing'; import { Test, TestingModule } from '@nestjs/testing'; +import { classes } from 'automapper-classes'; +import { AutomapperModule } from 'automapper-nestjs'; import { ClsService } from 'nestjs-cls'; -import { LocalGovernment } from '../alcs/local-government/local-government.entity'; -import { UserProfile } from '../common/automapper/user.automapper.profile'; import { initMockUserDto, initUserMockEntity, } from '../../test/mocks/mockEntities'; import { mockKeyCloakProviders } from '../../test/mocks/mockTypes'; +import { LocalGovernment } from '../alcs/local-government/local-government.entity'; +import { UserProfile } from '../common/automapper/user.automapper.profile'; import { UserController } from './user.controller'; import { UserDto } from './user.dto'; import { User } from './user.entity'; @@ -80,6 +80,7 @@ describe('UserController', () => { }, isFirstNationGovernment: false, isLocalGovernment: false, + isBusiness: false, }; controller = module.get(UserController); diff --git a/services/apps/alcs/src/user/user.controller.ts b/services/apps/alcs/src/user/user.controller.ts index 06d5073d88..8284aeb770 100644 --- a/services/apps/alcs/src/user/user.controller.ts +++ b/services/apps/alcs/src/user/user.controller.ts @@ -1,5 +1,3 @@ -import { Mapper } from 'automapper-core'; -import { InjectMapper } from 'automapper-nestjs'; import { Body, Controller, @@ -13,6 +11,8 @@ import { UseGuards, } from '@nestjs/common'; import { ApiOAuth2 } from '@nestjs/swagger'; +import { Mapper } from 'automapper-core'; +import { InjectMapper } from 'automapper-nestjs'; import * as config from 'config'; import { ANY_AUTH_ROLE, AUTH_ROLE } from '../common/authorization/roles'; import { RolesGuard } from '../common/authorization/roles-guard.service'; @@ -40,6 +40,7 @@ export class UserController { mappedUser.isLocalGovernment = !!government && !government.isFirstNation; mappedUser.isFirstNationGovernment = !!government && government.isFirstNation; + mappedUser.isBusiness = !!user.bceidBusinessGuid; return mappedUser; } diff --git a/services/apps/alcs/src/user/user.dto.ts b/services/apps/alcs/src/user/user.dto.ts index a49a9a176d..f856ba31cb 100644 --- a/services/apps/alcs/src/user/user.dto.ts +++ b/services/apps/alcs/src/user/user.dto.ts @@ -45,6 +45,7 @@ export class UserDto extends UpdateUserDto { government?: string; isLocalGovernment: boolean; isFirstNationGovernment: boolean; + isBusiness: boolean; } export class CreateUserDto { diff --git a/services/apps/alcs/src/utils/search/application-search-filters.ts b/services/apps/alcs/src/utils/search/application-search-filters.ts index 5dcfc93c9c..dfb248d58f 100644 --- a/services/apps/alcs/src/utils/search/application-search-filters.ts +++ b/services/apps/alcs/src/utils/search/application-search-filters.ts @@ -123,7 +123,7 @@ export const APP_SEARCH_FILTERS = { return query.getMany(); }, addFileTypeResults: ( - searchDto: InboxRequestDto, + searchDto: SearchRequestDto | InboxRequestDto, applicationRepository: Repository, ) => { const query = applicationRepository diff --git a/services/apps/alcs/src/utils/search/notice-of-intent-search-filters.ts b/services/apps/alcs/src/utils/search/notice-of-intent-search-filters.ts index 97f8e6feb2..28de3b3a94 100644 --- a/services/apps/alcs/src/utils/search/notice-of-intent-search-filters.ts +++ b/services/apps/alcs/src/utils/search/notice-of-intent-search-filters.ts @@ -126,7 +126,7 @@ export const NOI_SEARCH_FILTERS = { return query.getMany(); }, addFileTypeResults: ( - searchDto: InboxRequestDto, + searchDto: SearchRequestDto | InboxRequestDto, noiRepository: Repository, ) => { return noiRepository.find({ diff --git a/services/apps/alcs/src/utils/search/notification-search-filters.ts b/services/apps/alcs/src/utils/search/notification-search-filters.ts index 89de2ec9f8..7c35cc75f9 100644 --- a/services/apps/alcs/src/utils/search/notification-search-filters.ts +++ b/services/apps/alcs/src/utils/search/notification-search-filters.ts @@ -130,7 +130,7 @@ export const NOTIFICATION_SEARCH_FILTERS = { return query.getMany(); }, addFileTypeResults: ( - searchDto: InboxRequestDto, + searchDto: SearchRequestDto | InboxRequestDto, notificationRepository: Repository, ) => { return notificationRepository.find({ From d689ccebb23e52f951a7290eaaa6852e9bae01c0 Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Wed, 29 May 2024 12:08:02 -0700 Subject: [PATCH 13/27] Small fixes to make tests pass - Use relative imports - Catch undefined cases --- .../application/post-decision/post-decision.component.ts | 4 ++-- .../create/create-noi-modification-dialog.component.ts | 4 ++-- .../create/create-reconsideration-dialog.component.ts | 8 ++++---- .../post-decision/post-decision.component.ts | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts index 8078ae43a5..129e88e16c 100644 --- a/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts +++ b/alcs-frontend/src/app/features/application/post-decision/post-decision.component.ts @@ -13,8 +13,8 @@ import { formatDateForApi } from '../../../shared/utils/api-date-formatter'; import { EditModificationDialogComponent } from './edit-modification-dialog/edit-modification-dialog.component'; import { EditReconsiderationDialogComponent } from './edit-reconsideration-dialog/edit-reconsideration-dialog.component'; import { CreateAppModificationDialogComponent } from '../../board/dialogs/app-modification/create/create-app-modification-dialog.component'; -import { ApplicationLocalGovernmentDto } from 'src/app/services/application/application-local-government/application-local-government.dto'; -import { ApplicationRegionDto } from 'src/app/services/application/application-code.dto'; +import { ApplicationLocalGovernmentDto } from '../../../services/application/application-local-government/application-local-government.dto'; +import { ApplicationRegionDto } from '../../../services/application/application-code.dto'; import { CreateReconsiderationDialogComponent } from '../../board/dialogs/reconsiderations/create/create-reconsideration-dialog.component'; type LoadingReconsiderations = ApplicationReconsiderationDetailedDto & { diff --git a/alcs-frontend/src/app/features/board/dialogs/noi-modification/create/create-noi-modification-dialog.component.ts b/alcs-frontend/src/app/features/board/dialogs/noi-modification/create/create-noi-modification-dialog.component.ts index d09235e396..4807627d61 100644 --- a/alcs-frontend/src/app/features/board/dialogs/noi-modification/create/create-noi-modification-dialog.component.ts +++ b/alcs-frontend/src/app/features/board/dialogs/noi-modification/create/create-noi-modification-dialog.component.ts @@ -56,8 +56,8 @@ export class CreateNoiModificationDialogComponent implements OnInit, OnDestroy { this.createForm.patchValue({ fileNumber: this.data.fileNumber, applicant: this.data.applicant, - region: this.data.region.label, - localGovernment: this.data.localGovernment.name, + region: this.data.region?.label, + localGovernment: this.data.localGovernment?.name, }); this.noticeOfIntentService.fetchByFileNumber(this.data.fileNumber).then((noi) => { diff --git a/alcs-frontend/src/app/features/board/dialogs/reconsiderations/create/create-reconsideration-dialog.component.ts b/alcs-frontend/src/app/features/board/dialogs/reconsiderations/create/create-reconsideration-dialog.component.ts index f34bbb88a9..d2808a8277 100644 --- a/alcs-frontend/src/app/features/board/dialogs/reconsiderations/create/create-reconsideration-dialog.component.ts +++ b/alcs-frontend/src/app/features/board/dialogs/reconsiderations/create/create-reconsideration-dialog.component.ts @@ -14,8 +14,8 @@ import { ApplicationDecisionV2Service } from '../../../../../services/applicatio import { CardService } from '../../../../../services/card/card.service'; import { ToastService } from '../../../../../services/toast/toast.service'; import { parseStringToBoolean } from '../../../../../shared/utils/boolean-helper'; -import { MinimalBoardDto } from 'src/app/services/board/board.dto'; -import { BoardService } from 'src/app/services/board/board.service'; +import { MinimalBoardDto } from '../../../../../services/board/board.dto'; +import { BoardService } from '../../../../../services/board/board.service'; @Component({ selector: 'app-create', @@ -79,8 +79,8 @@ export class CreateReconsiderationDialogComponent implements OnInit, OnDestroy { this.createForm.patchValue({ fileNumber: this.data.fileNumber, applicant: this.data.applicant, - localGovernment: this.data.localGovernment.name, - region: this.data.region.label, + localGovernment: this.data.localGovernment?.name, + region: this.data.region?.label, }); this.applicationService.fetchApplication(this.data.fileNumber).then((application) => { diff --git a/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.ts b/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.ts index b07f075cc1..c1f4312cd8 100644 --- a/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.ts +++ b/alcs-frontend/src/app/features/notice-of-intent/post-decision/post-decision.component.ts @@ -7,8 +7,8 @@ import { NoticeOfIntentModificationService } from '../../../services/notice-of-i import { ConfirmationDialogService } from '../../../shared/confirmation-dialog/confirmation-dialog.service'; import { EditModificationDialogComponent } from './edit-modification-dialog/edit-modification-dialog.component'; import { CreateNoiModificationDialogComponent } from '../../board/dialogs/noi-modification/create/create-noi-modification-dialog.component'; -import { ApplicationLocalGovernmentDto } from 'src/app/services/application/application-local-government/application-local-government.dto'; -import { ApplicationRegionDto } from 'src/app/services/application/application-code.dto'; +import { ApplicationLocalGovernmentDto } from '../../../services/application/application-local-government/application-local-government.dto'; +import { ApplicationRegionDto } from '../../../services/application/application-code.dto'; type LoadingModifications = NoticeOfIntentModificationDto & { modifiesDecisionsNumbers: string[]; From def45480dbc9fb14ec4bdd3c3c51e1db9cc1b07b Mon Sep 17 00:00:00 2001 From: Daniel Haselhan Date: Wed, 29 May 2024 13:00:43 -0700 Subject: [PATCH 14/27] Missed No Datas -> Not Applicable --- .../cove-details/cove-details.component.html | 4 +++- .../proposal/cove-proposal/cove-proposal.component.html | 8 ++++---- .../proposal/cove-proposal/cove-proposal.component.scss | 1 - .../submission/submission-details.component.html | 4 +++- .../submission/submission-details.component.scss | 4 ++++ 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/alcs-frontend/src/app/features/application/applicant-info/application-details/cove-details/cove-details.component.html b/alcs-frontend/src/app/features/application/applicant-info/application-details/cove-details/cove-details.component.html index 9baa11c58f..5b053739c4 100644 --- a/alcs-frontend/src/app/features/application/applicant-info/application-details/cove-details/cove-details.component.html +++ b/alcs-frontend/src/app/features/application/applicant-info/application-details/cove-details/cove-details.component.html @@ -11,7 +11,9 @@
{{ transferee.displayName }}
{{ transferee.organizationName }} - +
+
Not Applicable
+
{{ transferee.phoneNumber | mask : '(000) 000-0000' }} diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/cove-proposal/cove-proposal.component.html b/portal-frontend/src/app/features/applications/edit-submission/proposal/cove-proposal/cove-proposal.component.html index 96798aa948..95092600b1 100644 --- a/portal-frontend/src/app/features/applications/edit-submission/proposal/cove-proposal/cove-proposal.component.html +++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/cove-proposal/cove-proposal.component.html @@ -61,7 +61,7 @@

Proposal

{{ element.organizationName }} - No Data + Not Applicable @@ -175,7 +175,7 @@

Proposal

>
- Do you have a draft copy of the covenant? + Do you have a draft copy of the covenant?
If yes, please attach the Draft in the section below.
Proposal 'error-outline': hasDraftCopy.invalid && (hasDraftCopy.dirty || hasDraftCopy.touched) }" value="true" - >Yes + >Yes Proposal 'error-outline': hasDraftCopy.invalid && (hasDraftCopy.dirty || hasDraftCopy.touched) }" value="false" - >No + >No
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/cove-proposal/cove-proposal.component.scss b/portal-frontend/src/app/features/applications/edit-submission/proposal/cove-proposal/cove-proposal.component.scss index 9b4478422a..e591f70bcb 100644 --- a/portal-frontend/src/app/features/applications/edit-submission/proposal/cove-proposal/cove-proposal.component.scss +++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/cove-proposal/cove-proposal.component.scss @@ -8,7 +8,6 @@ .no-data { color: colors.$grey-dark; text-align: center; - padding: rem(8); } .actions-cell { diff --git a/portal-frontend/src/app/features/public/notification/submission/submission-details.component.html b/portal-frontend/src/app/features/public/notification/submission/submission-details.component.html index 413772ce72..456aea94f3 100644 --- a/portal-frontend/src/app/features/public/notification/submission/submission-details.component.html +++ b/portal-frontend/src/app/features/public/notification/submission/submission-details.component.html @@ -11,7 +11,9 @@

Identify Transferee(s)

{{ transferee.displayName }}
{{ transferee.organizationName }} - +
+
Not Applicable
+
diff --git a/portal-frontend/src/app/features/public/notification/submission/submission-details.component.scss b/portal-frontend/src/app/features/public/notification/submission/submission-details.component.scss index 6cf9509069..0300a9f764 100644 --- a/portal-frontend/src/app/features/public/notification/submission/submission-details.component.scss +++ b/portal-frontend/src/app/features/public/notification/submission/submission-details.component.scss @@ -13,6 +13,10 @@ hyphens: auto; } +.no-data-text { + color: colors.$grey-dark; +} + :host::ng-deep { .view-grid-item { display: grid; From 4e2094976fe55ae141657890687b435d1fbb30e2 Mon Sep 17 00:00:00 2001 From: Daniel Haselhan Date: Wed, 29 May 2024 16:28:16 -0700 Subject: [PATCH 15/27] Use lowest decision date as minimum instead of highest * This means subsequent decisions will have to come after the first rather than requiring each decision to come after the ones already done --- .../decision-v2/decision-input/decision-input-v2.component.ts | 2 +- .../decision-v2/decision-input/decision-input-v2.component.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-input-v2.component.ts b/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-input-v2.component.ts index 618edd71ee..fe453c8750 100644 --- a/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-input-v2.component.ts +++ b/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-input-v2.component.ts @@ -206,7 +206,7 @@ export class DecisionInputV2Component implements OnInit, OnDestroy { minDate = decision.date; } - if (minDate && decision.date && decision.date > minDate) { + if (minDate && decision.date && decision.date < minDate) { minDate = decision.date; } diff --git a/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/decision-input/decision-input-v2.component.ts b/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/decision-input/decision-input-v2.component.ts index d54b52484b..c37f4e1e79 100644 --- a/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/decision-input/decision-input-v2.component.ts +++ b/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/decision-input/decision-input-v2.component.ts @@ -177,7 +177,7 @@ export class DecisionInputV2Component implements OnInit, OnDestroy { minDate = decision.date; } - if (minDate && decision.date && decision.date > minDate) { + if (minDate && decision.date && decision.date < minDate) { minDate = decision.date; } From 7d694df4f3414dfd58ee7c4b5f21096364cf1b9b Mon Sep 17 00:00:00 2001 From: Daniel Haselhan Date: Thu, 30 May 2024 10:16:15 -0700 Subject: [PATCH 16/27] Add sorting to ALCS Covenant Transferees --- .../application-submission/application-submission.service.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/apps/alcs/src/alcs/application/application-submission/application-submission.service.ts b/services/apps/alcs/src/alcs/application/application-submission/application-submission.service.ts index 74b03201b7..202108a3b9 100644 --- a/services/apps/alcs/src/alcs/application/application-submission/application-submission.service.ts +++ b/services/apps/alcs/src/alcs/application/application-submission/application-submission.service.ts @@ -66,6 +66,9 @@ export class ApplicationSubmissionService { relations: { type: true, }, + order: { + firstName: 'ASC', + }, }); } From 4976ca3e32965b3b16901fe8fbc7bf63e3a0a944 Mon Sep 17 00:00:00 2001 From: Daniel Haselhan Date: Thu, 30 May 2024 10:43:18 -0700 Subject: [PATCH 17/27] Fixes for changing Indv/Org in Dialogs * Update transferee to not clear org name * Update owners to properly clear files when switching to indv --- .../transferee-dialog/transferee-dialog.component.ts | 8 +++++--- .../owner-dialogs/owner-dialog/owner-dialog.component.ts | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/cove-proposal/transferee-dialog/transferee-dialog.component.ts b/portal-frontend/src/app/features/applications/edit-submission/proposal/cove-proposal/transferee-dialog/transferee-dialog.component.ts index 18b0e58aa6..559cbc1d1f 100644 --- a/portal-frontend/src/app/features/applications/edit-submission/proposal/cove-proposal/transferee-dialog/transferee-dialog.component.ts +++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/cove-proposal/transferee-dialog/transferee-dialog.component.ts @@ -67,7 +67,7 @@ export class CovenantTransfereeDialogComponent { this.organizationName.setValidators([Validators.required]); } else { this.organizationName.setValidators([]); - this.organizationName.reset(); + this.organizationName.updateValueAndValidity(); } } @@ -78,8 +78,9 @@ export class CovenantTransfereeDialogComponent { } this.isLoading = true; + const orgName = this.type.value === OWNER_TYPE.ORGANIZATION ? this.organizationName.getRawValue() : null; const createDto: CovenantTransfereeCreateDto = { - organizationName: this.organizationName.getRawValue() || undefined, + organizationName: orgName, firstName: this.firstName.getRawValue() || undefined, lastName: this.lastName.getRawValue() || undefined, email: this.email.getRawValue()!, @@ -97,8 +98,9 @@ export class CovenantTransfereeDialogComponent { } async onSave() { + const orgName = this.type.value === OWNER_TYPE.ORGANIZATION ? this.organizationName.getRawValue() : null; const updateDto: CovenantTransfereeUpdateDto = { - organizationName: this.organizationName.getRawValue(), + organizationName: orgName, firstName: this.firstName.getRawValue(), lastName: this.lastName.getRawValue(), email: this.email.getRawValue()!, diff --git a/portal-frontend/src/app/shared/owner-dialogs/owner-dialog/owner-dialog.component.ts b/portal-frontend/src/app/shared/owner-dialogs/owner-dialog/owner-dialog.component.ts index 58c228fd21..41c4069f55 100644 --- a/portal-frontend/src/app/shared/owner-dialogs/owner-dialog/owner-dialog.component.ts +++ b/portal-frontend/src/app/shared/owner-dialogs/owner-dialog/owner-dialog.component.ts @@ -99,6 +99,7 @@ export class OwnerDialogComponent { this.organizationName.setValidators([]); this.corporateSummary.setValidators([]); this.corporateSummary.reset(); + this.files = []; } this.corporateSummary.updateValueAndValidity(); this.organizationName.updateValueAndValidity(); From 1ef39f16dffec629eaeb04b8400e6af03f48de19 Mon Sep 17 00:00:00 2001 From: mhuseinov <61513701+mhuseinov@users.noreply.github.com> Date: Thu, 30 May 2024 14:01:31 -0700 Subject: [PATCH 18/27] Bugfix/alcs 1988 alr area component on decisions (#1735) do not reset all component fields on inline update of alr are in NOI update precision from 2 to 5 --- .../decision-component.component.ts | 2 +- .../pfrs-input/pfrs-input.component.html | 1 - .../pofo-input/pofo-input.component.html | 2 - .../roso-input/roso-input.component.html | 1 - ...ice-of-intent-decision-component.entity.ts | 2 +- ...ce-of-intent-decision-component.service.ts | 92 +++++++++++++------ ...crease_decimal_points_for_noi_component.ts | 19 ++++ 7 files changed, 87 insertions(+), 32 deletions(-) create mode 100644 services/apps/alcs/src/providers/typeorm/migrations/1717088700859-increase_decimal_points_for_noi_component.ts diff --git a/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/decision-input/decision-components/decision-component/decision-component.component.ts b/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/decision-input/decision-components/decision-component/decision-component.component.ts index d2b0029504..c38252bbad 100644 --- a/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/decision-input/decision-components/decision-component/decision-component.component.ts +++ b/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/decision-input/decision-components/decision-component/decision-component.component.ts @@ -13,7 +13,7 @@ import { ToastService } from '../../../../../../../services/toast/toast.service' import { AG_CAP_OPTIONS, AG_CAP_SOURCE_OPTIONS } from '../../../../../../../shared/dto/ag-cap.types.dto'; import { formatDateForApi } from '../../../../../../../shared/utils/api-date-formatter'; -const MIN_SOIL_FIELDS = 0.01; +const MIN_SOIL_FIELDS = 0.00001; @Component({ selector: 'app-decision-component', diff --git a/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/decision-input/decision-components/decision-component/pfrs-input/pfrs-input.component.html b/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/decision-input/decision-components/decision-component/pfrs-input/pfrs-input.component.html index d32065b36e..a63602db92 100644 --- a/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/decision-input/decision-components/decision-component/pfrs-input/pfrs-input.component.html +++ b/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/decision-input/decision-components/decision-component/pfrs-input/pfrs-input.component.html @@ -3,7 +3,6 @@ ALR Area Impacted (ha) ALR Area Impacted (ha) ALR Area Impacted (ha) { + await queryRunner.query( + `ALTER TABLE "alcs"."notice_of_intent_decision_component" ALTER COLUMN "alr_area" TYPE numeric(12,5)`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "alcs"."notice_of_intent_decision_component" ALTER COLUMN "alr_area" TYPE numeric(12,2)`, + ); + } +} From 5866dbb6e584aed8a04664f15ab31b18379a8d47 Mon Sep 17 00:00:00 2001 From: Liam Stoddard Date: Thu, 30 May 2024 15:08:23 -0700 Subject: [PATCH 19/27] update ETL documentation --- bin/migrate-oats-data/README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/bin/migrate-oats-data/README.md b/bin/migrate-oats-data/README.md index d0b7e41225..d65e8af878 100644 --- a/bin/migrate-oats-data/README.md +++ b/bin/migrate-oats-data/README.md @@ -49,7 +49,7 @@ Pre-launch ETL command has been changed to: `python migrate_1.py [action]` -Post-launch ETL command is `migrate_2.py` and imports everything post launch inclusive of SRWs +Post-launch ETL command is `migrate_2.py` and imports everything post launch inclusive of SRWs but not past SRW ETLs post SRWs take over migrate.py command and is used as before @@ -57,10 +57,21 @@ Commands for post-launch are stored in: `menu/post_launch_commands` +Actions are contained within the migrate file, not all actions are available for each version of `migrate.py`. `import` and `clean` are shared for all + ETLs created post launch are to be located in the post-launch folder of their directory i.e. `applications/post_launch` or `noi/post-launch` +`migrate_2.py` now contains the 2nd batch of ETL done + +`migrate.py` contains the latest and final ETL migration which includes Planning Reviews and Inquiries. + +### Future ETL +The rest of ETL / data fixes have been done with migrations, these can be found in `services/apps/alcs/src/providers/typeorm/migrations`. Going forward data fixes and other minor changes should be done with migrations. + +If a new major ETL is required it is advisable to create a new updated migrate.py file and perform the required updates. Ensure obfuscation keeps up with the new changes. Depending on the scope the ETL can be run on openshift or run on a secure machine locally then restore the database from there. + ## Prod data obfuscation From ad337800b0bc25b65f4d7385122bf3d9f5ee7f9e Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Mon, 3 Jun 2024 11:06:41 -0700 Subject: [PATCH 20/27] Improve E2E readme --- e2e/README.md | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/e2e/README.md b/e2e/README.md index 06bebfe6d1..a63b857b42 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -1,6 +1,5 @@ # End-to-End Testing -- [Writing Tests](#writing-tests) - [Running Tests](#running-tests) - [Local Setup](#local-setup) - [Installation](#installation) @@ -9,12 +8,11 @@ E2E test automation is implemented using the [Playwright](https://playwright.dev/). -> [!WARNING] -> When writing tests, make sure they do not contain any credentials _before_ committing to the repo. - -## Writing Tests +> [!NOTE] +> All instructions contained in this document assume `/e2e` is the current working directory. -- Write tests for a given project, i.e., tests for the portal go in `/e2e/tests/portal`. +> [!WARNING] +> When writing tests, make sure they do not contain any secrets _before_ committing to the repo. All secrets should be defined in the ignored `.env` file (see [Configure Secrets](#configure-secrets)). ## Running Tests @@ -24,29 +22,21 @@ To run tests: $ npx playwright test ``` +This will just run the tests in the background and show results in the console. This is the main way to run tests. + To run tests just for a specific browser: ```bash $ npx playwright test --project=[chromium] ``` -To run tests just for a specific frontend, specify by directory: +To run in debug mode: ```bash -$ npx playwright test portal/ -``` - -These can be combined: - -````bash -$ npx playwright test --project=chromium portal/ +$ npx playwright test --debug ``` -To run headed: - -```bash -$ npx playwright test --headed -```` +This opens the tests in a browser and lets you visually step through the actions and see what each command is doing. It also has a locator tool that lets you test out locators. To run in UI mode: @@ -54,18 +44,16 @@ To run in UI mode: $ npx playwright test --ui ``` -To run in debug mode: - -```bash -$ npx playwright test --debug -``` +This is a cool way to explore tests and see the results in realtime. To show a report: ```bash -$ npx playwright show-report REPORT_DIR +$ npx playwright show-report [REPORT_DIR] ``` +If `REPORT_DIR` is blank, it'll show the report of the most recently run test. + ## Local Setup ### Installation @@ -90,4 +78,4 @@ $ npx playwright install ## Known Issues - When signed in, navigation via URL always redirects to login page -- Parcel entry step UI is not fully functional, stick to single parcel for now +- Parcel entry step UI is not fully functional; stick to single parcel for now From 5f193c0af8cedb3ad969d310111bf7c9ae8a0bad Mon Sep 17 00:00:00 2001 From: abradat Date: Mon, 3 Jun 2024 11:51:52 -0700 Subject: [PATCH 21/27] Fix cursor remaining in pointer state after clicking on proposal summary text area. Cursor changes to text state after clicking on proposal summary text area and changes back to cursor on submission or cancelation. --- .../inline-textarea-edit/inline-textarea-edit.component.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alcs-frontend/src/app/shared/inline-editors/inline-textarea-edit/inline-textarea-edit.component.scss b/alcs-frontend/src/app/shared/inline-editors/inline-textarea-edit/inline-textarea-edit.component.scss index cc09826d94..d56cad7913 100644 --- a/alcs-frontend/src/app/shared/inline-editors/inline-textarea-edit/inline-textarea-edit.component.scss +++ b/alcs-frontend/src/app/shared/inline-editors/inline-textarea-edit/inline-textarea-edit.component.scss @@ -2,7 +2,7 @@ .editable { display: inline-block; - cursor: pointer; + cursor: auto; border: 2px solid colors.$primary-color-dark; padding: 8px; border-radius: 2px; From ab27bf26aec4a425cf50f735170aede72429bb88 Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Mon, 3 Jun 2024 12:14:25 -0700 Subject: [PATCH 22/27] Only show decision CC field if not already released --- .../release-dialog/release-dialog.component.html | 6 +++--- .../release-dialog/release-dialog.component.html | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/alcs-frontend/src/app/features/application/decision/decision-v2/release-dialog/release-dialog.component.html b/alcs-frontend/src/app/features/application/decision/decision-v2/release-dialog/release-dialog.component.html index f5bc8de3dc..2c930e9522 100644 --- a/alcs-frontend/src/app/features/application/decision/decision-v2/release-dialog/release-dialog.component.html +++ b/alcs-frontend/src/app/features/application/decision/decision-v2/release-dialog/release-dialog.component.html @@ -22,8 +22,8 @@

Confirm Release Decision

No auto-emails will be sent
-
-
+
+
CC additional recipients on decision release email (optional):
@@ -54,7 +54,7 @@

Confirm Release Decision

- +
diff --git a/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/release-dialog/release-dialog.component.html b/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/release-dialog/release-dialog.component.html index 5eca5da9d3..ccdb7a5013 100644 --- a/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/release-dialog/release-dialog.component.html +++ b/alcs-frontend/src/app/features/notice-of-intent/decision/decision-v2/release-dialog/release-dialog.component.html @@ -22,7 +22,7 @@

Confirm Release Decision

No auto-emails will be sent
-
+
CC additional recipients on decision release email (optional):
From 10eb9ad1a94291738e02c17b7904c0d4a22a4740 Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Mon, 3 Jun 2024 15:59:35 -0700 Subject: [PATCH 23/27] Migration to fix cancelled statuses --- ...717452186426-remove_canc_from_rffg_apps.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 services/apps/alcs/src/providers/typeorm/migrations/1717452186426-remove_canc_from_rffg_apps.ts diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1717452186426-remove_canc_from_rffg_apps.ts b/services/apps/alcs/src/providers/typeorm/migrations/1717452186426-remove_canc_from_rffg_apps.ts new file mode 100644 index 0000000000..3ec3f7684b --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1717452186426-remove_canc_from_rffg_apps.ts @@ -0,0 +1,20 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class RemoveCancFromRffgApps1717452186426 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + queryRunner.query(` + update alcs.application_submission_to_submission_status astss1 + set effective_date = null, email_sent_date = null + from alcs.application_submission_to_submission_status astss2 + where astss1.submission_uuid = astss2.submission_uuid + and astss1.status_type_code = 'CANC' + and astss2.status_type_code = 'RFFG' + and astss1.effective_date is not null + and astss2.effective_date is not null + `); + } + + public async down(queryRunner: QueryRunner): Promise { + // N/A + } +} From 9a9a19a1c13005c19588c207a4b1cb2349fd9f80 Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Mon, 3 Jun 2024 16:20:50 -0700 Subject: [PATCH 24/27] Align capitalization with other migrations --- .../1717452186426-remove_canc_from_rffg_apps.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1717452186426-remove_canc_from_rffg_apps.ts b/services/apps/alcs/src/providers/typeorm/migrations/1717452186426-remove_canc_from_rffg_apps.ts index 3ec3f7684b..cd93d26a68 100644 --- a/services/apps/alcs/src/providers/typeorm/migrations/1717452186426-remove_canc_from_rffg_apps.ts +++ b/services/apps/alcs/src/providers/typeorm/migrations/1717452186426-remove_canc_from_rffg_apps.ts @@ -3,14 +3,14 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class RemoveCancFromRffgApps1717452186426 implements MigrationInterface { public async up(queryRunner: QueryRunner): Promise { queryRunner.query(` - update alcs.application_submission_to_submission_status astss1 - set effective_date = null, email_sent_date = null - from alcs.application_submission_to_submission_status astss2 - where astss1.submission_uuid = astss2.submission_uuid - and astss1.status_type_code = 'CANC' - and astss2.status_type_code = 'RFFG' - and astss1.effective_date is not null - and astss2.effective_date is not null + UPDATE alcs.application_submission_to_submission_status astss1 + SET effective_date = NULL, email_sent_date = NULL + FROM alcs.application_submission_to_submission_status astss2 + WHERE astss1.submission_uuid = astss2.submission_uuid + AND astss1.status_type_code = 'CANC' + AND astss2.status_type_code = 'RFFG' + AND astss1.effective_date IS NOT NULL + AND astss2.effective_date IS NOT NULL; `); } From a295ceb6411ed14b50d7da85c234a3efc90715a6 Mon Sep 17 00:00:00 2001 From: abradat Date: Tue, 4 Jun 2024 10:55:36 -0700 Subject: [PATCH 25/27] fix ng-select border, dropdown, arrow, and placeholder colour to ALCS primary --- alcs-frontend/src/styles/ngselect.scss | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/alcs-frontend/src/styles/ngselect.scss b/alcs-frontend/src/styles/ngselect.scss index fe0fb471c4..624e89169c 100644 --- a/alcs-frontend/src/styles/ngselect.scss +++ b/alcs-frontend/src/styles/ngselect.scss @@ -6,9 +6,18 @@ font-size: 16px; } +.ng-select.ng-select-focused .ng-placeholder { + color: colors.$primary-color !important; +} + .ng-select.ng-select-focused .ng-select-container.ng-appearance-outline:after, -.ng-select.ng-select-focused .ng-select-container.ng-appearance-outline:hover:after { - border-color: colors.$primary-color; +.ng-select.ng-select-focused .ng-select-container.ng-appearance-outline:hover:after, +.ng-select.ng-select-focused .ng-select-container:after { + border-color: colors.$primary-color !important; +} + +.ng-select .ng-arrow { + color: colors.$primary-color !important; } .ng-select .ng-select-container.ng-appearance-outline { @@ -17,7 +26,7 @@ .ng-dropdown-panel .ng-dropdown-panel-items .ng-option.ng-option-selected { background-color: colors.$grey-light !important; - color: colors.$primary-color; + color: colors.$primary-color !important; &:hover { background-color: colors.$grey-light !important; From 5935958a9d4b6da86d4064922d6eacf4554ff7d9 Mon Sep 17 00:00:00 2001 From: abradat Date: Tue, 4 Jun 2024 11:07:53 -0700 Subject: [PATCH 26/27] Fix styling --- alcs-frontend/src/styles/ngselect.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/alcs-frontend/src/styles/ngselect.scss b/alcs-frontend/src/styles/ngselect.scss index 624e89169c..a909d29e2a 100644 --- a/alcs-frontend/src/styles/ngselect.scss +++ b/alcs-frontend/src/styles/ngselect.scss @@ -6,10 +6,6 @@ font-size: 16px; } -.ng-select.ng-select-focused .ng-placeholder { - color: colors.$primary-color !important; -} - .ng-select.ng-select-focused .ng-select-container.ng-appearance-outline:after, .ng-select.ng-select-focused .ng-select-container.ng-appearance-outline:hover:after, .ng-select.ng-select-focused .ng-select-container:after { @@ -20,6 +16,10 @@ color: colors.$primary-color !important; } +.ng-select.ng-select-focused .ng-placeholder { + color: colors.$primary-color !important; +} + .ng-select .ng-select-container.ng-appearance-outline { padding: 0 0.8em !important; } From f44dfc07cba408d7ce2b01deb2f57e719d749201 Mon Sep 17 00:00:00 2001 From: Tristan Slater <1631008+trslater@users.noreply.github.com> Date: Tue, 4 Jun 2024 11:42:16 -0700 Subject: [PATCH 27/27] Filter drafts from ALCS advanced search view --- .../application-search-view.entity.ts | 3 ++- ...449-filter_drafts_from_alcs_search_view.ts | 20 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 services/apps/alcs/src/providers/typeorm/migrations/1717525819449-filter_drafts_from_alcs_search_view.ts diff --git a/services/apps/alcs/src/alcs/search/application/application-search-view.entity.ts b/services/apps/alcs/src/alcs/search/application/application-search-view.entity.ts index 30d8c40a7a..e5657ecd3e 100644 --- a/services/apps/alcs/src/alcs/search/application/application-search-view.entity.ts +++ b/services/apps/alcs/src/alcs/search/application/application-search-view.entity.ts @@ -37,7 +37,8 @@ export class SearchApplicationSubmissionStatusType { LocalGovernment, 'localGovernment', 'app_sub.local_government_uuid = localGovernment.uuid', - ), + ) + .where(`app_sub.is_draft IS NOT TRUE`), }) export class ApplicationSubmissionSearchView { @ViewColumn() diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1717525819449-filter_drafts_from_alcs_search_view.ts b/services/apps/alcs/src/providers/typeorm/migrations/1717525819449-filter_drafts_from_alcs_search_view.ts new file mode 100644 index 0000000000..917fd6d3df --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1717525819449-filter_drafts_from_alcs_search_view.ts @@ -0,0 +1,20 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class FilterDraftsFromAlcsSearchView1717525819449 implements MigrationInterface { + name = 'FilterDraftsFromAlcsSearchView1717525819449' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DELETE FROM "alcs"."typeorm_metadata" WHERE "type" = $1 AND "name" = $2 AND "schema" = $3`, ["VIEW","application_submission_search_view","alcs"]); + await queryRunner.query(`DROP VIEW "alcs"."application_submission_search_view"`); + await queryRunner.query(`CREATE VIEW "alcs"."application_submission_search_view" AS SELECT "app_sub"."uuid" AS "uuid", "app_sub"."applicant" AS "applicant", "app"."uuid" AS "application_uuid", "localGovernment"."name" AS "local_government_name", "app_sub"."file_number" AS "file_number", "app"."type_code" AS "application_type_code", "app"."date_submitted_to_alc" AS "date_submitted_to_alc", "app"."decision_date" AS "decision_date", "app"."region_code" AS "application_region_code", alcs.get_current_status_for_application_submission_by_uuid("app_sub"."uuid") AS "status" FROM "alcs"."application_submission" "app_sub" INNER JOIN "alcs"."application" "app" ON "app"."file_number" = "app_sub"."file_number" AND "app"."audit_deleted_date_at" IS NULL LEFT JOIN "alcs"."local_government" "localGovernment" ON "app_sub"."local_government_uuid" = "localGovernment"."uuid" AND "localGovernment"."audit_deleted_date_at" IS NULL WHERE ( "app_sub"."is_draft" IS NOT TRUE ) AND ( "app_sub"."audit_deleted_date_at" IS NULL )`); + await queryRunner.query(`INSERT INTO "alcs"."typeorm_metadata"("database", "schema", "table", "type", "name", "value") VALUES (DEFAULT, $1, DEFAULT, $2, $3, $4)`, ["alcs","VIEW","application_submission_search_view","SELECT \"app_sub\".\"uuid\" AS \"uuid\", \"app_sub\".\"applicant\" AS \"applicant\", \"app\".\"uuid\" AS \"application_uuid\", \"localGovernment\".\"name\" AS \"local_government_name\", \"app_sub\".\"file_number\" AS \"file_number\", \"app\".\"type_code\" AS \"application_type_code\", \"app\".\"date_submitted_to_alc\" AS \"date_submitted_to_alc\", \"app\".\"decision_date\" AS \"decision_date\", \"app\".\"region_code\" AS \"application_region_code\", alcs.get_current_status_for_application_submission_by_uuid(\"app_sub\".\"uuid\") AS \"status\" FROM \"alcs\".\"application_submission\" \"app_sub\" INNER JOIN \"alcs\".\"application\" \"app\" ON \"app\".\"file_number\" = \"app_sub\".\"file_number\" AND \"app\".\"audit_deleted_date_at\" IS NULL LEFT JOIN \"alcs\".\"local_government\" \"localGovernment\" ON \"app_sub\".\"local_government_uuid\" = \"localGovernment\".\"uuid\" AND \"localGovernment\".\"audit_deleted_date_at\" IS NULL WHERE ( \"app_sub\".\"is_draft\" IS NOT TRUE ) AND ( \"app_sub\".\"audit_deleted_date_at\" IS NULL )"]); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DELETE FROM "alcs"."typeorm_metadata" WHERE "type" = $1 AND "name" = $2 AND "schema" = $3`, ["VIEW","application_submission_search_view","alcs"]); + await queryRunner.query(`DROP VIEW "alcs"."application_submission_search_view"`); + await queryRunner.query(`CREATE VIEW "alcs"."application_submission_search_view" AS SELECT "app_sub"."uuid" AS "uuid", "app_sub"."applicant" AS "applicant", "app"."uuid" AS "application_uuid", "localGovernment"."name" AS "local_government_name", "app_sub"."file_number" AS "file_number", "app"."type_code" AS "application_type_code", "app"."date_submitted_to_alc" AS "date_submitted_to_alc", "app"."decision_date" AS "decision_date", "app"."region_code" AS "application_region_code", alcs.get_current_status_for_application_submission_by_uuid("app_sub"."uuid") AS "status" FROM "alcs"."application_submission" "app_sub" INNER JOIN "alcs"."application" "app" ON "app"."file_number" = "app_sub"."file_number" AND "app"."audit_deleted_date_at" IS NULL LEFT JOIN "alcs"."local_government" "localGovernment" ON "app_sub"."local_government_uuid" = "localGovernment"."uuid" AND "localGovernment"."audit_deleted_date_at" IS NULL WHERE "app_sub"."audit_deleted_date_at" IS NULL`); + await queryRunner.query(`INSERT INTO "alcs"."typeorm_metadata"("database", "schema", "table", "type", "name", "value") VALUES (DEFAULT, $1, DEFAULT, $2, $3, $4)`, ["alcs","VIEW","application_submission_search_view","SELECT \"app_sub\".\"uuid\" AS \"uuid\", \"app_sub\".\"applicant\" AS \"applicant\", \"app\".\"uuid\" AS \"application_uuid\", \"localGovernment\".\"name\" AS \"local_government_name\", \"app_sub\".\"file_number\" AS \"file_number\", \"app\".\"type_code\" AS \"application_type_code\", \"app\".\"date_submitted_to_alc\" AS \"date_submitted_to_alc\", \"app\".\"decision_date\" AS \"decision_date\", \"app\".\"region_code\" AS \"application_region_code\", alcs.get_current_status_for_application_submission_by_uuid(\"app_sub\".\"uuid\") AS \"status\" FROM \"alcs\".\"application_submission\" \"app_sub\" INNER JOIN \"alcs\".\"application\" \"app\" ON \"app\".\"file_number\" = \"app_sub\".\"file_number\" AND \"app\".\"audit_deleted_date_at\" IS NULL LEFT JOIN \"alcs\".\"local_government\" \"localGovernment\" ON \"app_sub\".\"local_government_uuid\" = \"localGovernment\".\"uuid\" AND \"localGovernment\".\"audit_deleted_date_at\" IS NULL WHERE \"app_sub\".\"audit_deleted_date_at\" IS NULL"]); + } + +}