From 13945d8f36f18cb71005bbcbddd33381b67f4589 Mon Sep 17 00:00:00 2001 From: Daniel Haselhan Date: Thu, 5 Oct 2023 16:27:30 -0700 Subject: [PATCH] Finish Public App View * Add ALC Tab and L/FNG Tab * Add DTOs for Parcel and Document to minimize exposed data --- .../alc-review/alc-review.component.html | 44 +---- .../alc-review/alc-review.component.spec.ts | 24 +-- .../alc-review/alc-review.component.ts | 48 ++--- .../decisions/decisions.component.html | 5 +- .../decisions/decisions.component.spec.ts | 12 +- .../decisions/decisions.component.ts | 24 +-- .../submission-documents.component.spec.ts | 22 +-- .../submission-documents.component.ts | 25 ++- .../lfng-review/lfng-review.component.html | 167 +++--------------- .../lfng-review/lfng-review.component.spec.ts | 45 ++--- .../lfng-review/lfng-review.component.ts | 131 ++------------ .../public-application.component.html | 22 ++- .../public-application.component.ts | 20 ++- .../excl-details/excl-details.component.ts | 10 +- .../incl-details/incl-details.component.ts | 10 +- .../naru-details/naru-details.component.ts | 8 +- .../nfu-details/nfu-details.component.ts | 8 +- .../submission/parcel/parcel.component.scss | 14 -- .../submission/parcel/parcel.component.ts | 9 +- .../pfrs-details/pfrs-details.component.ts | 11 +- .../pofo-details/pofo-details.component.ts | 10 +- .../roso-details/roso-details.component.ts | 10 +- .../subd-details/subd-details.component.ts | 8 +- .../submission-details.component.ts | 14 +- .../tur-details/tur-details.component.ts | 7 +- .../src/app/features/public/public.module.ts | 8 + .../src/app/services/public/public.dto.ts | 58 +++++- .../automapper/public.automapper.profile.ts | 98 +++++++++- .../application-submission-review.service.ts | 8 + .../application-parcel.dto.ts | 1 - .../portal/public/public.controller.spec.ts | 21 +++ .../src/portal/public/public.controller.ts | 56 +++++- .../apps/alcs/src/portal/public/public.dto.ts | 112 ++++++++++++ .../alcs/src/portal/public/public.module.ts | 5 +- 34 files changed, 533 insertions(+), 542 deletions(-) diff --git a/portal-frontend/src/app/features/public/application/alc-review/alc-review.component.html b/portal-frontend/src/app/features/public/application/alc-review/alc-review.component.html index 4ea1d813f6..936712c82c 100644 --- a/portal-frontend/src/app/features/public/application/alc-review/alc-review.component.html +++ b/portal-frontend/src/app/features/public/application/alc-review/alc-review.component.html @@ -1,45 +1,9 @@ -
+

ALC Review and Decision

-
- - -
-
- This section will update after the application is submitted to the ALC. -
-
- Application not subject to Agricultural Land Commission review. -
-
- - +
+ +
diff --git a/portal-frontend/src/app/features/public/application/alc-review/alc-review.component.spec.ts b/portal-frontend/src/app/features/public/application/alc-review/alc-review.component.spec.ts index 62a72d72d0..3a515a8c48 100644 --- a/portal-frontend/src/app/features/public/application/alc-review/alc-review.component.spec.ts +++ b/portal-frontend/src/app/features/public/application/alc-review/alc-review.component.spec.ts @@ -1,28 +1,18 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { createMock, DeepMocked } from '@golevelup/ts-jest'; -import { ApplicationSubmissionReviewService } from '../../../../services/application-submission-review/application-submission-review.service'; -import { AlcReviewComponent } from './alc-review.component'; +import { PublicAlcReviewComponent } from './alc-review.component'; -describe('AlcsReviewComponent', () => { - let component: AlcReviewComponent; - let fixture: ComponentFixture; - let mockAppReviewService: DeepMocked; +describe('PublicAlcReviewComponent', () => { + let component: PublicAlcReviewComponent; + let fixture: ComponentFixture; beforeEach(async () => { - mockAppReviewService = createMock(); - await TestBed.configureTestingModule({ - providers: [ - { - provide: ApplicationSubmissionReviewService, - useValue: mockAppReviewService, - }, - ], - declarations: [AlcReviewComponent], + providers: [], + declarations: [PublicAlcReviewComponent], }).compileComponents(); - fixture = TestBed.createComponent(AlcReviewComponent); + fixture = TestBed.createComponent(PublicAlcReviewComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/portal-frontend/src/app/features/public/application/alc-review/alc-review.component.ts b/portal-frontend/src/app/features/public/application/alc-review/alc-review.component.ts index ced2da29b9..e1c8c5b643 100644 --- a/portal-frontend/src/app/features/public/application/alc-review/alc-review.component.ts +++ b/portal-frontend/src/app/features/public/application/alc-review/alc-review.component.ts @@ -1,47 +1,19 @@ -import { Component, Input, OnDestroy, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; -import { BehaviorSubject, Subject, takeUntil } from 'rxjs'; -import { ApplicationDocumentDto } from '../../../../services/application-document/application-document.dto'; -import { ApplicationSubmissionReviewService } from '../../../../services/application-submission-review/application-submission-review.service'; -import { - SUBMISSION_STATUS, - ApplicationSubmissionDetailedDto, -} from '../../../../services/application-submission/application-submission.dto'; +import { Component, Input } from '@angular/core'; +import { ApplicationPortalDecisionDto } from '../../../../services/application-decision/application-decision.dto'; +import { SUBMISSION_STATUS } from '../../../../services/application-submission/application-submission.dto'; +import { PublicApplicationSubmissionDto, PublicDocumentDto } from '../../../../services/public/public.dto'; @Component({ - selector: 'app-alc-review', + selector: 'app-public-alc-review', templateUrl: './alc-review.component.html', styleUrls: ['./alc-review.component.scss'], }) -export class AlcReviewComponent implements OnInit, OnDestroy { - private $destroy = new Subject(); +export class PublicAlcReviewComponent { + @Input() applicationSubmission!: PublicApplicationSubmissionDto; + @Input() applicationDocuments!: PublicDocumentDto[]; + @Input() applicationDecisions!: ApplicationPortalDecisionDto[]; - @Input() $application = new BehaviorSubject(undefined); - @Input() $applicationDocuments = new BehaviorSubject([]); - - application: ApplicationSubmissionDetailedDto | undefined; SUBMISSION_STATUS = SUBMISSION_STATUS; - constructor(private applicationReviewService: ApplicationSubmissionReviewService, private router: Router) {} - - ngOnInit(): void { - this.$application.pipe(takeUntil(this.$destroy)).subscribe((application) => { - this.application = application; - }); - } - - ngOnDestroy(): void { - this.$destroy.next(); - this.$destroy.complete(); - } - - async onReview(fileId: string) { - if (this.application?.status.code === SUBMISSION_STATUS.SUBMITTED_TO_LG) { - const review = await this.applicationReviewService.startReview(fileId); - if (!review) { - return; - } - } - await this.router.navigateByUrl(`application/${fileId}/review`); - } + constructor() {} } diff --git a/portal-frontend/src/app/features/public/application/alc-review/decisions/decisions.component.html b/portal-frontend/src/app/features/public/application/alc-review/decisions/decisions.component.html index ee4d949dba..7657271cf1 100644 --- a/portal-frontend/src/app/features/public/application/alc-review/decisions/decisions.component.html +++ b/portal-frontend/src/app/features/public/application/alc-review/decisions/decisions.component.html @@ -1,5 +1,5 @@ -
-

Decision #{{ decisions.length - index }}

+
+

Decision #{{ applicationDecisions.length - index }}

Decision Date
@@ -15,7 +15,6 @@

Decision #{{ decisions.length - index }}

Decision Outcome
{{ decision.outcome.label }} {{ decision.isSubjectToConditions ? '- Subject to Conditions' : '' }}
-
Decision Document
diff --git a/portal-frontend/src/app/features/public/application/alc-review/decisions/decisions.component.spec.ts b/portal-frontend/src/app/features/public/application/alc-review/decisions/decisions.component.spec.ts index f56a7194b9..ce78e37c19 100644 --- a/portal-frontend/src/app/features/public/application/alc-review/decisions/decisions.component.spec.ts +++ b/portal-frontend/src/app/features/public/application/alc-review/decisions/decisions.component.spec.ts @@ -2,18 +2,18 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { createMock } from '@golevelup/ts-jest'; import { ApplicationDecisionService } from '../../../../../services/application-decision/application-decision.service'; -import { DecisionsComponent } from './decisions.component'; +import { PublicDecisionsComponent } from './decisions.component'; -describe('DecisionsComponent', () => { - let component: DecisionsComponent; - let fixture: ComponentFixture; +describe('PublicDecisionsComponent', () => { + let component: PublicDecisionsComponent; + let fixture: ComponentFixture; let mockDecisionService: ApplicationDecisionService; beforeEach(async () => { mockDecisionService = createMock(); await TestBed.configureTestingModule({ - declarations: [DecisionsComponent], + declarations: [PublicDecisionsComponent], providers: [ { provide: ApplicationDecisionService, @@ -22,7 +22,7 @@ describe('DecisionsComponent', () => { ], }).compileComponents(); - fixture = TestBed.createComponent(DecisionsComponent); + fixture = TestBed.createComponent(PublicDecisionsComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/portal-frontend/src/app/features/public/application/alc-review/decisions/decisions.component.ts b/portal-frontend/src/app/features/public/application/alc-review/decisions/decisions.component.ts index 1280cc0118..ebf506417a 100644 --- a/portal-frontend/src/app/features/public/application/alc-review/decisions/decisions.component.ts +++ b/portal-frontend/src/app/features/public/application/alc-review/decisions/decisions.component.ts @@ -3,37 +3,19 @@ import { ApplicationPortalDecisionDto } from '../../../../../services/applicatio import { ApplicationDecisionService } from '../../../../../services/application-decision/application-decision.service'; @Component({ - selector: 'app-decisions[fileNumber]', + selector: 'app-public-decisions', templateUrl: './decisions.component.html', styleUrls: ['./decisions.component.scss'], }) -export class DecisionsComponent implements OnInit, OnChanges { - @Input() fileNumber = ''; - decisions: ApplicationPortalDecisionDto[] = []; +export class PublicDecisionsComponent { + @Input() applicationDecisions: ApplicationPortalDecisionDto[] = []; constructor(private decisionService: ApplicationDecisionService) {} - ngOnInit(): void { - this.loadDecisions(); - } - - ngOnChanges(changes: SimpleChanges): void { - this.loadDecisions(); - } - async openFile(uuid: string) { const res = await this.decisionService.openFile(uuid); if (res) { window.open(res.url, '_blank'); } } - - private async loadDecisions() { - if (this.fileNumber) { - const decisions = await this.decisionService.getByFileId(this.fileNumber); - if (decisions) { - this.decisions = decisions; - } - } - } } diff --git a/portal-frontend/src/app/features/public/application/alc-review/submission-documents/submission-documents.component.spec.ts b/portal-frontend/src/app/features/public/application/alc-review/submission-documents/submission-documents.component.spec.ts index 09eb1292d3..a2f54298d3 100644 --- a/portal-frontend/src/app/features/public/application/alc-review/submission-documents/submission-documents.component.spec.ts +++ b/portal-frontend/src/app/features/public/application/alc-review/submission-documents/submission-documents.component.spec.ts @@ -1,30 +1,30 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { createMock, DeepMocked } from '@golevelup/ts-jest'; -import { ApplicationDocumentService } from '../../../../../services/application-document/application-document.service'; +import { PublicService } from '../../../../../services/public/public.service'; -import { SubmissionDocumentsComponent } from './submission-documents.component'; +import { PublicSubmissionDocumentsComponent } from './submission-documents.component'; -describe('SubmissionDocumentsComponent', () => { - let component: SubmissionDocumentsComponent; - let fixture: ComponentFixture; - let mockAppDocService: DeepMocked; +describe('PublicSubmissionDocumentsComponent', () => { + let component: PublicSubmissionDocumentsComponent; + let fixture: ComponentFixture; + let mockPublicService: DeepMocked; beforeEach(async () => { - mockAppDocService = createMock(); + mockPublicService = createMock(); await TestBed.configureTestingModule({ - declarations: [SubmissionDocumentsComponent], + declarations: [PublicSubmissionDocumentsComponent], providers: [ { - provide: ApplicationDocumentService, - useValue: mockAppDocService, + provide: PublicService, + useValue: mockPublicService, }, ], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); - fixture = TestBed.createComponent(SubmissionDocumentsComponent); + fixture = TestBed.createComponent(PublicSubmissionDocumentsComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/portal-frontend/src/app/features/public/application/alc-review/submission-documents/submission-documents.component.ts b/portal-frontend/src/app/features/public/application/alc-review/submission-documents/submission-documents.component.ts index 027fbdbfea..0dc940477e 100644 --- a/portal-frontend/src/app/features/public/application/alc-review/submission-documents/submission-documents.component.ts +++ b/portal-frontend/src/app/features/public/application/alc-review/submission-documents/submission-documents.component.ts @@ -1,43 +1,42 @@ import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; -import { BehaviorSubject, Subject, takeUntil } from 'rxjs'; -import { ApplicationDocumentDto } from '../../../../../services/application-document/application-document.dto'; -import { ApplicationDocumentService } from '../../../../../services/application-document/application-document.service'; +import { Subject } from 'rxjs'; +import { PublicApplicationSubmissionDto, PublicDocumentDto } from '../../../../../services/public/public.dto'; +import { PublicService } from '../../../../../services/public/public.service'; @Component({ selector: 'app-submission-documents', templateUrl: './submission-documents.component.html', styleUrls: ['./submission-documents.component.scss'], }) -export class SubmissionDocumentsComponent implements OnInit, OnDestroy { +export class PublicSubmissionDocumentsComponent implements OnInit, OnDestroy { private $destroy = new Subject(); displayedColumns: string[] = ['type', 'fileName', 'source', 'uploadedAt', 'actions']; - documents: ApplicationDocumentDto[] = []; + documents: PublicDocumentDto[] = []; - @Input() $applicationDocuments = new BehaviorSubject([]); + @Input() applicationDocuments!: PublicDocumentDto[]; + @Input() applicationSubmission!: PublicApplicationSubmissionDto; @ViewChild(MatSort) sort!: MatSort; - dataSource: MatTableDataSource = new MatTableDataSource(); + dataSource: MatTableDataSource = new MatTableDataSource(); - constructor(private applicationDocumentService: ApplicationDocumentService) {} + constructor(private publicService: PublicService) {} ngOnInit(): void { - this.$applicationDocuments.pipe(takeUntil(this.$destroy)).subscribe((documents) => { - this.dataSource = new MatTableDataSource(documents); - }); + this.dataSource = new MatTableDataSource(this.applicationDocuments); } async openFile(uuid: string) { - const res = await this.applicationDocumentService.openFile(uuid); + const res = await this.publicService.getApplicationFileUrl(this.applicationSubmission.fileNumber, uuid); if (res) { window.open(res.url, '_blank'); } } async downloadFile(uuid: string) { - const res = await this.applicationDocumentService.downloadFile(uuid); + const res = await this.publicService.getApplicationFileUrl(this.applicationSubmission.fileNumber, uuid); if (res) { const downloadLink = document.createElement('a'); downloadLink.href = res.url; diff --git a/portal-frontend/src/app/features/public/application/lfng-review/lfng-review.component.html b/portal-frontend/src/app/features/public/application/lfng-review/lfng-review.component.html index 2ae5a57c31..a43a85fd09 100644 --- a/portal-frontend/src/app/features/public/application/lfng-review/lfng-review.component.html +++ b/portal-frontend/src/app/features/public/application/lfng-review/lfng-review.component.html @@ -1,70 +1,11 @@ -
+

Local/First Nation Gov Review

-
- - - - -
-
- infoThis section will update after the application is submitted. -
-
+
infoApplication not subject to Local/First Nation Government review.
-
- infoPending Local/First Nation Government review. -
-
-
Comment for Applicant
- {{ application.returnedComment }} - No comment added -
-
+

Contact Information

@@ -103,32 +44,17 @@

Contact Information

-
-
Phone Number
-
- {{ applicationReview.phoneNumber }} - -
-
-
-
Email
-
- {{ applicationReview.email }} - -
-
-
+

Plans & Bylaws: OCP

-
Is the application parcel(s) subject to a Local Government OCP designation?
+
+ Is the applicationSubmission parcel(s) subject to a Local Government OCP designation? +
- {{ - applicationReview.isOCPDesignation ? 'Yes' : 'No' - }} - + {{ applicationReview.isOCPDesignation ? 'Yes' : 'No' }}
@@ -156,16 +82,15 @@

Plans & Bylaws: OCP

-
+

Plans & Bylaws: Zoning

-
Is the application parcel(s) subject to a Local Government zoning designation?
+
+ Is the applicationSubmission parcel(s) subject to a Local Government zoning designation? +
- {{ - applicationReview.isSubjectToZoning ? 'Yes' : 'No' - }} - + {{ applicationReview.isSubjectToZoning ? 'Yes' : 'No' }}
@@ -203,81 +128,29 @@

Plans & Bylaws: Zoning

Resolution

-
- Please complete both Step 2 Plans & Bylaws: OCP and Step 3 Plans & Bylaws: Zoning to continue with this step. -
-
+
By indicating that the parcel(s) is not subject to Local Government OCP or Zoning, no authorizing resolution is required as per S. 25 (3) or S. 29 (4) of the ALC Act. - The only option available is to forward this application on to the ALC. + The only option available is to forward this Application on to the ALC.
-
+
Resolution for Application to Proceed to the ALC
- {{ - applicationReview.isAuthorized ? 'Authorized' : 'Refuse to Authorize' - }} - + {{ applicationReview.isAuthorized ? 'Authorized' : 'Refuse to Authorize' }}
-
+

Attachments

-
-
- Please complete Step 2 Plans & Bylaws: OCP, Step 3 Plans & Bylaws: Zoning and Step 4 Resolution to continue - with this step. -
-
-
-
+
+
Resolution Document
- -
-
-
- Staff Report (optional) -
- - -
-
-
Other Attachments (optional):
-
diff --git a/portal-frontend/src/app/features/public/application/lfng-review/lfng-review.component.spec.ts b/portal-frontend/src/app/features/public/application/lfng-review/lfng-review.component.spec.ts index d1556cc200..a14d258152 100644 --- a/portal-frontend/src/app/features/public/application/lfng-review/lfng-review.component.spec.ts +++ b/portal-frontend/src/app/features/public/application/lfng-review/lfng-review.component.spec.ts @@ -1,52 +1,31 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { createMock, DeepMocked } from '@golevelup/ts-jest'; -import { BehaviorSubject } from 'rxjs'; -import { ApplicationDocumentDto } from '../../../../services/application-document/application-document.dto'; -import { ApplicationDocumentService } from '../../../../services/application-document/application-document.service'; -import { ApplicationSubmissionReviewDto } from '../../../../services/application-submission-review/application-submission-review.dto'; -import { ApplicationSubmissionReviewService } from '../../../../services/application-submission-review/application-submission-review.service'; -import { ApplicationSubmissionDetailedDto } from '../../../../services/application-submission/application-submission.dto'; -import { PdfGenerationService } from '../../../../services/pdf-generation/pdf-generation.service'; +import { PublicService } from '../../../../services/public/public.service'; -import { LfngReviewComponent } from './lfng-review.component'; +import { PublicLfngReviewComponent } from './lfng-review.component'; -describe('LfngReviewComponent', () => { - let component: LfngReviewComponent; - let fixture: ComponentFixture; +describe('PublicLfngReviewComponent', () => { + let component: PublicLfngReviewComponent; + let fixture: ComponentFixture; - let mockAppSubReviewService: DeepMocked; - let mockPdfGenerationService: DeepMocked; - let mockAppDocumentService: DeepMocked; + let mockPublicService: DeepMocked; beforeEach(async () => { - mockAppSubReviewService = createMock(); - mockPdfGenerationService = createMock(); - mockAppDocumentService = createMock(); - - mockAppSubReviewService.$applicationReview = new BehaviorSubject( - undefined - ); + mockPublicService = createMock(); await TestBed.configureTestingModule({ providers: [ { - provide: ApplicationSubmissionReviewService, - useValue: mockAppSubReviewService, - }, - { - provide: PdfGenerationService, - useValue: mockPdfGenerationService, - }, - { - provide: ApplicationDocumentService, - useValue: mockAppDocumentService, + provide: PublicService, + useValue: mockPublicService, }, ], - declarations: [LfngReviewComponent], + declarations: [PublicLfngReviewComponent], }).compileComponents(); - fixture = TestBed.createComponent(LfngReviewComponent); + fixture = TestBed.createComponent(PublicLfngReviewComponent); component = fixture.componentInstance; + component.applicationDocuments = []; fixture.detectChanges(); }); diff --git a/portal-frontend/src/app/features/public/application/lfng-review/lfng-review.component.ts b/portal-frontend/src/app/features/public/application/lfng-review/lfng-review.component.ts index e80935380e..e21492882c 100644 --- a/portal-frontend/src/app/features/public/application/lfng-review/lfng-review.component.ts +++ b/portal-frontend/src/app/features/public/application/lfng-review/lfng-review.component.ts @@ -1,131 +1,38 @@ -import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; -import { Router } from '@angular/router'; -import { BehaviorSubject, Subject, takeUntil } from 'rxjs'; -import { ApplicationDocumentDto } from '../../../../services/application-document/application-document.dto'; -import { ApplicationDocumentService } from '../../../../services/application-document/application-document.service'; -import { ApplicationSubmissionReviewDto } from '../../../../services/application-submission-review/application-submission-review.dto'; -import { ApplicationSubmissionReviewService } from '../../../../services/application-submission-review/application-submission-review.service'; +import { Component, Input, OnInit } from '@angular/core'; +import { SUBMISSION_STATUS } from '../../../../services/application-submission/application-submission.dto'; import { - ApplicationSubmissionDetailedDto, - SUBMISSION_STATUS, -} from '../../../../services/application-submission/application-submission.dto'; -import { PdfGenerationService } from '../../../../services/pdf-generation/pdf-generation.service'; -import { DOCUMENT_SOURCE, DOCUMENT_TYPE } from '../../../../shared/dto/document.dto'; + PublicApplicationSubmissionDto, + PublicApplicationSubmissionReviewDto, + PublicDocumentDto, +} from '../../../../services/public/public.dto'; +import { PublicService } from '../../../../services/public/public.service'; +import { DOCUMENT_TYPE } from '../../../../shared/dto/document.dto'; @Component({ - selector: 'app-lfng-review', + selector: 'app-public-lfng-review', templateUrl: './lfng-review.component.html', styleUrls: ['./lfng-review.component.scss'], }) -export class LfngReviewComponent implements OnInit, OnDestroy { - private $destroy = new Subject(); +export class PublicLfngReviewComponent implements OnInit { + @Input() applicationSubmission!: PublicApplicationSubmissionDto; + @Input() applicationDocuments!: PublicDocumentDto[]; + @Input() applicationReview: PublicApplicationSubmissionReviewDto | undefined; - @Input() $application = new BehaviorSubject(undefined); - @Input() $applicationDocuments = new BehaviorSubject([]); - - @Output() onCancel = new EventEmitter(); - - application: ApplicationSubmissionDetailedDto | undefined; - applicationReview: ApplicationSubmissionReviewDto | undefined; SUBMISSION_STATUS = SUBMISSION_STATUS; - staffReport: ApplicationDocumentDto[] = []; - resolutionDocument: ApplicationDocumentDto[] = []; - governmentOtherAttachments: ApplicationDocumentDto[] = []; - hasCompletedStepsBeforeResolution = false; - hasCompletedStepsBeforeDocuments = false; - submittedToAlcStatus = false; + resolutionDocument: PublicDocumentDto[] = []; - constructor( - private applicationReviewService: ApplicationSubmissionReviewService, - private pdfGenerationService: PdfGenerationService, - private applicationDocumentService: ApplicationDocumentService, - private router: Router - ) {} + constructor(private publicService: PublicService) {} ngOnInit(): void { - this.applicationReviewService.$applicationReview.pipe(takeUntil(this.$destroy)).subscribe((appReview) => { - if (appReview) { - this.applicationReview = appReview; - - this.hasCompletedStepsBeforeResolution = - appReview.isFirstNationGovernment || - (!appReview.isFirstNationGovernment && - appReview.isOCPDesignation !== null && - appReview.isSubjectToZoning !== null && - (appReview.isOCPDesignation === true || appReview.isSubjectToZoning === true)); - - this.hasCompletedStepsBeforeDocuments = - appReview.isFirstNationGovernment || - (appReview.isAuthorized !== null && - appReview.isOCPDesignation !== null && - appReview.isSubjectToZoning !== null) || - (appReview.isAuthorized === null && - appReview.isOCPDesignation === false && - appReview.isSubjectToZoning === false); - } - }); - - this.$application.pipe(takeUntil(this.$destroy)).subscribe((application) => { - this.application = application; - this.submittedToAlcStatus = !!this.application?.submissionStatuses.find( - (s) => s.statusTypeCode === SUBMISSION_STATUS.SUBMITTED_TO_ALC && !!s.effectiveDate - ); - this.loadReview(); - }); - - this.$applicationDocuments.subscribe((documents) => { - this.staffReport = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.STAFF_REPORT); - this.resolutionDocument = documents.filter( - (document) => document.type?.code === DOCUMENT_TYPE.RESOLUTION_DOCUMENT - ); - this.governmentOtherAttachments = documents.filter( - (document) => document.type?.code === DOCUMENT_TYPE.OTHER && document.source === DOCUMENT_SOURCE.LFNG - ); - }); - } - - async onDownloadReviewPdf(fileNumber: string | undefined) { - if (fileNumber) { - await this.pdfGenerationService.generateReview(fileNumber); - } - } - - async loadReview() { - if ( - this.application && - this.application.typeCode !== 'TURP' && - (this.submittedToAlcStatus || - (this.application.status.code === SUBMISSION_STATUS.IN_REVIEW_BY_LG && this.application.canReview)) - ) { - await this.applicationReviewService.getByFileId(this.application.fileNumber); - } else { - this.applicationReview = undefined; - } + this.resolutionDocument = this.applicationDocuments.filter( + (document) => document.type?.code === DOCUMENT_TYPE.RESOLUTION_DOCUMENT + ); } async openFile(uuid: string) { - const res = await this.applicationDocumentService.openFile(uuid); + const res = await this.publicService.getApplicationFileUrl(this.applicationSubmission.fileNumber, uuid); if (res) { window.open(res.url, '_blank'); } } - - async onReview(fileId: string) { - if (this.application?.status.code === SUBMISSION_STATUS.SUBMITTED_TO_LG) { - const review = await this.applicationReviewService.startReview(fileId); - if (!review) { - return; - } - } - await this.router.navigateByUrl(`application/${fileId}/review`); - } - - onCancelClicked(fileNumber: string) { - this.onCancel.emit(fileNumber); - } - - ngOnDestroy(): void { - this.$destroy.next(); - this.$destroy.complete(); - } } diff --git a/portal-frontend/src/app/features/public/application/public-application.component.html b/portal-frontend/src/app/features/public/application/public-application.component.html index 8bf92b73ce..addc35e61c 100644 --- a/portal-frontend/src/app/features/public/application/public-application.component.html +++ b/portal-frontend/src/app/features/public/application/public-application.component.html @@ -28,8 +28,9 @@

Application ID: {{ submission.fileNumber }}

-
-
//TODO
+
+ + +
-
//TODO
+
+ +
diff --git a/portal-frontend/src/app/features/public/application/public-application.component.ts b/portal-frontend/src/app/features/public/application/public-application.component.ts index f3700a1941..84cba66c20 100644 --- a/portal-frontend/src/app/features/public/application/public-application.component.ts +++ b/portal-frontend/src/app/features/public/application/public-application.component.ts @@ -1,10 +1,14 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Subject, takeUntil } from 'rxjs'; -import { ApplicationDocumentDto } from '../../../services/application-document/application-document.dto'; -import { ApplicationParcelDto } from '../../../services/application-parcel/application-parcel.dto'; +import { ApplicationPortalDecisionDto } from '../../../services/application-decision/application-decision.dto'; import { SUBMISSION_STATUS } from '../../../services/application-submission/application-submission.dto'; -import { PublicApplicationSubmissionDto } from '../../../services/public/public.dto'; +import { + PublicApplicationParcelDto, + PublicApplicationSubmissionDto, + PublicApplicationSubmissionReviewDto, + PublicDocumentDto, +} from '../../../services/public/public.dto'; import { PublicService } from '../../../services/public/public.service'; @Component({ @@ -18,8 +22,10 @@ export class PublicApplicationComponent implements OnInit, OnDestroy { SUBMISSION_STATUS = SUBMISSION_STATUS; submission: PublicApplicationSubmissionDto | undefined; - documents: ApplicationDocumentDto[] = []; - parcels: ApplicationParcelDto[] = []; + review: PublicApplicationSubmissionReviewDto | undefined; + documents: PublicDocumentDto[] = []; + parcels: PublicApplicationParcelDto[] = []; + decisions: ApplicationPortalDecisionDto[] = []; constructor(private publicService: PublicService, private route: ActivatedRoute) {} @@ -35,11 +41,13 @@ export class PublicApplicationComponent implements OnInit, OnDestroy { private async loadApplication(fileId: string) { const res = await this.publicService.getApplication(fileId); if (res) { - const { submission, documents, parcels } = res; + const { submission, documents, parcels, review, decisions } = res; this.submission = submission; this.documents = documents; this.parcels = parcels; + this.review = review; + this.decisions = decisions; } } diff --git a/portal-frontend/src/app/features/public/application/submission/excl-details/excl-details.component.ts b/portal-frontend/src/app/features/public/application/submission/excl-details/excl-details.component.ts index cc7b23fc89..43a3f4c95e 100644 --- a/portal-frontend/src/app/features/public/application/submission/excl-details/excl-details.component.ts +++ b/portal-frontend/src/app/features/public/application/submission/excl-details/excl-details.component.ts @@ -1,8 +1,6 @@ import { Component, Input } from '@angular/core'; import { Router } from '@angular/router'; -import { ApplicationDocumentDto } from '../../../../../services/application-document/application-document.dto'; -import { ApplicationDocumentService } from '../../../../../services/application-document/application-document.service'; -import { PublicApplicationSubmissionDto } from '../../../../../services/public/public.dto'; +import { PublicApplicationSubmissionDto, PublicDocumentDto } from '../../../../../services/public/public.dto'; import { PublicService } from '../../../../../services/public/public.service'; import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; @@ -14,15 +12,15 @@ import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; export class ExclDetailsComponent { @Input() applicationSubmission!: PublicApplicationSubmissionDto; - @Input() set applicationDocuments(documents: ApplicationDocumentDto[]) { + @Input() set applicationDocuments(documents: PublicDocumentDto[]) { this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP); this.reportOfPublicHearing = documents.filter( (document) => document.type?.code === DOCUMENT_TYPE.REPORT_OF_PUBLIC_HEARING ); } - proposalMap: ApplicationDocumentDto[] = []; - reportOfPublicHearing: ApplicationDocumentDto[] = []; + proposalMap: PublicDocumentDto[] = []; + reportOfPublicHearing: PublicDocumentDto[] = []; constructor(private router: Router, private publicService: PublicService) {} diff --git a/portal-frontend/src/app/features/public/application/submission/incl-details/incl-details.component.ts b/portal-frontend/src/app/features/public/application/submission/incl-details/incl-details.component.ts index 53e325f10f..e08695999c 100644 --- a/portal-frontend/src/app/features/public/application/submission/incl-details/incl-details.component.ts +++ b/portal-frontend/src/app/features/public/application/submission/incl-details/incl-details.component.ts @@ -1,8 +1,6 @@ import { Component, Input } from '@angular/core'; import { Router } from '@angular/router'; -import { ApplicationDocumentDto } from '../../../../../services/application-document/application-document.dto'; -import { ApplicationDocumentService } from '../../../../../services/application-document/application-document.service'; -import { PublicApplicationSubmissionDto } from '../../../../../services/public/public.dto'; +import { PublicApplicationSubmissionDto, PublicDocumentDto } from '../../../../../services/public/public.dto'; import { PublicService } from '../../../../../services/public/public.service'; import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; @@ -12,12 +10,12 @@ import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; styleUrls: ['./incl-details.component.scss'], }) export class InclDetailsComponent { - proposalMap: ApplicationDocumentDto[] = []; - reportOfPublicHearing: ApplicationDocumentDto[] = []; + proposalMap: PublicDocumentDto[] = []; + reportOfPublicHearing: PublicDocumentDto[] = []; @Input() applicationSubmission!: PublicApplicationSubmissionDto; - @Input() set applicationDocuments(documents: ApplicationDocumentDto[]) { + @Input() set applicationDocuments(documents: PublicDocumentDto[]) { this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP); this.reportOfPublicHearing = documents.filter( (document) => document.type?.code === DOCUMENT_TYPE.REPORT_OF_PUBLIC_HEARING diff --git a/portal-frontend/src/app/features/public/application/submission/naru-details/naru-details.component.ts b/portal-frontend/src/app/features/public/application/submission/naru-details/naru-details.component.ts index e593aff636..f4f702d73c 100644 --- a/portal-frontend/src/app/features/public/application/submission/naru-details/naru-details.component.ts +++ b/portal-frontend/src/app/features/public/application/submission/naru-details/naru-details.component.ts @@ -1,8 +1,6 @@ import { Component, Input } from '@angular/core'; import { Router } from '@angular/router'; -import { ApplicationDocumentDto } from '../../../../../services/application-document/application-document.dto'; -import { ApplicationDocumentService } from '../../../../../services/application-document/application-document.service'; -import { PublicApplicationSubmissionDto } from '../../../../../services/public/public.dto'; +import { PublicApplicationSubmissionDto, PublicDocumentDto } from '../../../../../services/public/public.dto'; import { PublicService } from '../../../../../services/public/public.service'; import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; @@ -12,10 +10,10 @@ import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; styleUrls: ['./naru-details.component.scss'], }) export class NaruDetailsComponent { - proposalMap: ApplicationDocumentDto[] = []; + proposalMap: PublicDocumentDto[] = []; @Input() applicationSubmission!: PublicApplicationSubmissionDto; - @Input() set applicationDocuments(documents: ApplicationDocumentDto[]) { + @Input() set applicationDocuments(documents: PublicDocumentDto[]) { this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP); } diff --git a/portal-frontend/src/app/features/public/application/submission/nfu-details/nfu-details.component.ts b/portal-frontend/src/app/features/public/application/submission/nfu-details/nfu-details.component.ts index d0642d7090..27ff3c3d23 100644 --- a/portal-frontend/src/app/features/public/application/submission/nfu-details/nfu-details.component.ts +++ b/portal-frontend/src/app/features/public/application/submission/nfu-details/nfu-details.component.ts @@ -1,8 +1,6 @@ import { Component, Input } from '@angular/core'; import { Router } from '@angular/router'; -import { ApplicationDocumentDto } from '../../../../../services/application-document/application-document.dto'; -import { ApplicationDocumentService } from '../../../../../services/application-document/application-document.service'; -import { PublicApplicationSubmissionDto } from '../../../../../services/public/public.dto'; +import { PublicApplicationSubmissionDto, PublicDocumentDto } from '../../../../../services/public/public.dto'; import { PublicService } from '../../../../../services/public/public.service'; import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; @@ -14,11 +12,11 @@ import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; export class NfuDetailsComponent { @Input() applicationSubmission!: PublicApplicationSubmissionDto; - @Input() set applicationDocuments(documents: ApplicationDocumentDto[]) { + @Input() set applicationDocuments(documents: PublicDocumentDto[]) { this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP); } - proposalMap: ApplicationDocumentDto[] = []; + proposalMap: PublicDocumentDto[] = []; constructor(private router: Router, private publicService: PublicService) {} diff --git a/portal-frontend/src/app/features/public/application/submission/parcel/parcel.component.scss b/portal-frontend/src/app/features/public/application/submission/parcel/parcel.component.scss index a706f903ba..81d88321d1 100644 --- a/portal-frontend/src/app/features/public/application/submission/parcel/parcel.component.scss +++ b/portal-frontend/src/app/features/public/application/submission/parcel/parcel.component.scss @@ -18,20 +18,6 @@ .full-width { grid-column: 1/3; } - - .edit-button { - grid-column: 1/3; - } - - @media screen and (min-width: $tabletBreakpoint) { - .full-width { - grid-column: 1/5; - } - - .edit-button { - grid-column: 1/5; - } - } } .crown-land { diff --git a/portal-frontend/src/app/features/public/application/submission/parcel/parcel.component.ts b/portal-frontend/src/app/features/public/application/submission/parcel/parcel.component.ts index 0a4a1d2da5..9e17cad331 100644 --- a/portal-frontend/src/app/features/public/application/submission/parcel/parcel.component.ts +++ b/portal-frontend/src/app/features/public/application/submission/parcel/parcel.component.ts @@ -1,10 +1,7 @@ import { Component, Input } from '@angular/core'; import { Subject } from 'rxjs'; -import { - ApplicationParcelDto, - PARCEL_OWNERSHIP_TYPE, -} from '../../../../../services/application-parcel/application-parcel.dto'; -import { PublicApplicationSubmissionDto } from '../../../../../services/public/public.dto'; +import { PARCEL_OWNERSHIP_TYPE } from '../../../../../services/application-parcel/application-parcel.dto'; +import { PublicApplicationParcelDto, PublicApplicationSubmissionDto } from '../../../../../services/public/public.dto'; @Component({ selector: 'app-parcel', @@ -15,7 +12,7 @@ export class ParcelComponent { $destroy = new Subject(); @Input() applicationSubmission!: PublicApplicationSubmissionDto; - @Input() parcels: ApplicationParcelDto[] = []; + @Input() parcels: PublicApplicationParcelDto[] = []; PARCEL_OWNERSHIP_TYPES = PARCEL_OWNERSHIP_TYPE; pageTitle: string = 'Identify Parcel(s) Under Application'; diff --git a/portal-frontend/src/app/features/public/application/submission/pfrs-details/pfrs-details.component.ts b/portal-frontend/src/app/features/public/application/submission/pfrs-details/pfrs-details.component.ts index da1bd6a17b..f529357962 100644 --- a/portal-frontend/src/app/features/public/application/submission/pfrs-details/pfrs-details.component.ts +++ b/portal-frontend/src/app/features/public/application/submission/pfrs-details/pfrs-details.component.ts @@ -1,11 +1,8 @@ import { Component, Input } from '@angular/core'; import { Router } from '@angular/router'; -import { ApplicationDocumentDto } from '../../../../../services/application-document/application-document.dto'; -import { ApplicationDocumentService } from '../../../../../services/application-document/application-document.service'; -import { PublicApplicationSubmissionDto } from '../../../../../services/public/public.dto'; +import { PublicApplicationSubmissionDto, PublicDocumentDto } from '../../../../../services/public/public.dto'; import { PublicService } from '../../../../../services/public/public.service'; import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; -import { PublicApplicationComponent } from '../../public-application.component'; @Component({ selector: 'app-pfrs-details[applicationSubmission]', @@ -15,13 +12,13 @@ import { PublicApplicationComponent } from '../../public-application.component'; export class PfrsDetailsComponent { @Input() applicationSubmission!: PublicApplicationSubmissionDto; - @Input() set applicationDocuments(documents: ApplicationDocumentDto[]) { + @Input() set applicationDocuments(documents: PublicDocumentDto[]) { this.crossSections = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.CROSS_SECTIONS); this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP); } - crossSections: ApplicationDocumentDto[] = []; - proposalMap: ApplicationDocumentDto[] = []; + crossSections: PublicDocumentDto[] = []; + proposalMap: PublicDocumentDto[] = []; constructor(private router: Router, private publicService: PublicService) {} diff --git a/portal-frontend/src/app/features/public/application/submission/pofo-details/pofo-details.component.ts b/portal-frontend/src/app/features/public/application/submission/pofo-details/pofo-details.component.ts index 11c3f8cef4..9b48d576c5 100644 --- a/portal-frontend/src/app/features/public/application/submission/pofo-details/pofo-details.component.ts +++ b/portal-frontend/src/app/features/public/application/submission/pofo-details/pofo-details.component.ts @@ -1,8 +1,6 @@ import { Component, Input } from '@angular/core'; import { Router } from '@angular/router'; -import { ApplicationDocumentDto } from '../../../../../services/application-document/application-document.dto'; -import { ApplicationDocumentService } from '../../../../../services/application-document/application-document.service'; -import { PublicApplicationSubmissionDto } from '../../../../../services/public/public.dto'; +import { PublicApplicationSubmissionDto, PublicDocumentDto } from '../../../../../services/public/public.dto'; import { PublicService } from '../../../../../services/public/public.service'; import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; @@ -14,13 +12,13 @@ import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; export class PofoDetailsComponent { @Input() applicationSubmission!: PublicApplicationSubmissionDto; - @Input() set applicationDocuments(documents: ApplicationDocumentDto[]) { + @Input() set applicationDocuments(documents: PublicDocumentDto[]) { this.crossSections = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.CROSS_SECTIONS); this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP); } - crossSections: ApplicationDocumentDto[] = []; - proposalMap: ApplicationDocumentDto[] = []; + crossSections: PublicDocumentDto[] = []; + proposalMap: PublicDocumentDto[] = []; constructor(private router: Router, private publicService: PublicService) {} diff --git a/portal-frontend/src/app/features/public/application/submission/roso-details/roso-details.component.ts b/portal-frontend/src/app/features/public/application/submission/roso-details/roso-details.component.ts index 9ab2fc15d9..44bb4f91d5 100644 --- a/portal-frontend/src/app/features/public/application/submission/roso-details/roso-details.component.ts +++ b/portal-frontend/src/app/features/public/application/submission/roso-details/roso-details.component.ts @@ -1,8 +1,6 @@ import { Component, Input } from '@angular/core'; import { Router } from '@angular/router'; -import { ApplicationDocumentDto } from '../../../../../services/application-document/application-document.dto'; -import { ApplicationDocumentService } from '../../../../../services/application-document/application-document.service'; -import { PublicApplicationSubmissionDto } from '../../../../../services/public/public.dto'; +import { PublicApplicationSubmissionDto, PublicDocumentDto } from '../../../../../services/public/public.dto'; import { PublicService } from '../../../../../services/public/public.service'; import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; @@ -14,13 +12,13 @@ import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; export class RosoDetailsComponent { @Input() applicationSubmission!: PublicApplicationSubmissionDto; - @Input() set applicationDocuments(documents: ApplicationDocumentDto[]) { + @Input() set applicationDocuments(documents: PublicDocumentDto[]) { this.crossSections = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.CROSS_SECTIONS); this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP); } - crossSections: ApplicationDocumentDto[] = []; - proposalMap: ApplicationDocumentDto[] = []; + crossSections: PublicDocumentDto[] = []; + proposalMap: PublicDocumentDto[] = []; constructor(private router: Router, private publicService: PublicService) {} diff --git a/portal-frontend/src/app/features/public/application/submission/subd-details/subd-details.component.ts b/portal-frontend/src/app/features/public/application/submission/subd-details/subd-details.component.ts index a2f5720ac4..e9bf08d879 100644 --- a/portal-frontend/src/app/features/public/application/submission/subd-details/subd-details.component.ts +++ b/portal-frontend/src/app/features/public/application/submission/subd-details/subd-details.component.ts @@ -1,8 +1,6 @@ import { Component, Input } from '@angular/core'; import { Router } from '@angular/router'; -import { ApplicationDocumentDto } from '../../../../../services/application-document/application-document.dto'; -import { ApplicationDocumentService } from '../../../../../services/application-document/application-document.service'; -import { PublicApplicationSubmissionDto } from '../../../../../services/public/public.dto'; +import { PublicApplicationSubmissionDto, PublicDocumentDto } from '../../../../../services/public/public.dto'; import { PublicService } from '../../../../../services/public/public.service'; import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; @@ -14,11 +12,11 @@ import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; export class SubdDetailsComponent { @Input() applicationSubmission!: PublicApplicationSubmissionDto; - @Input() set applicationDocuments(documents: ApplicationDocumentDto[]) { + @Input() set applicationDocuments(documents: PublicDocumentDto[]) { this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP); } - proposalMap: ApplicationDocumentDto[] = []; + proposalMap: PublicDocumentDto[] = []; constructor(private router: Router, private publicService: PublicService) {} diff --git a/portal-frontend/src/app/features/public/application/submission/submission-details.component.ts b/portal-frontend/src/app/features/public/application/submission/submission-details.component.ts index c98f76888a..5849b23130 100644 --- a/portal-frontend/src/app/features/public/application/submission/submission-details.component.ts +++ b/portal-frontend/src/app/features/public/application/submission/submission-details.component.ts @@ -1,11 +1,15 @@ import { Component, Input, OnDestroy, OnInit } from '@angular/core'; import { Subject } from 'rxjs'; -import { ApplicationDocumentDto } from '../../../../services/application-document/application-document.dto'; import { ApplicationDocumentService } from '../../../../services/application-document/application-document.service'; -import { ApplicationParcelDto, PARCEL_TYPE } from '../../../../services/application-parcel/application-parcel.dto'; +import { PARCEL_TYPE } from '../../../../services/application-parcel/application-parcel.dto'; import { LocalGovernmentDto } from '../../../../services/code/code.dto'; import { CodeService } from '../../../../services/code/code.service'; -import { PublicApplicationSubmissionDto, PublicOwnerDto } from '../../../../services/public/public.dto'; +import { + PublicApplicationParcelDto, + PublicApplicationSubmissionDto, + PublicDocumentDto, + PublicOwnerDto, +} from '../../../../services/public/public.dto'; import { OWNER_TYPE } from '../../../../shared/dto/owner.dto'; @Component({ @@ -17,8 +21,8 @@ export class SubmissionDetailsComponent implements OnInit, OnDestroy { $destroy = new Subject(); @Input() applicationSubmission!: PublicApplicationSubmissionDto; - @Input() applicationDocuments: ApplicationDocumentDto[] = []; - @Input() applicationParcels: ApplicationParcelDto[] = []; + @Input() applicationDocuments: PublicDocumentDto[] = []; + @Input() applicationParcels: PublicApplicationParcelDto[] = []; parcelType = PARCEL_TYPE; primaryContact: PublicOwnerDto | undefined; diff --git a/portal-frontend/src/app/features/public/application/submission/tur-details/tur-details.component.ts b/portal-frontend/src/app/features/public/application/submission/tur-details/tur-details.component.ts index a448a06fae..11ff6e4162 100644 --- a/portal-frontend/src/app/features/public/application/submission/tur-details/tur-details.component.ts +++ b/portal-frontend/src/app/features/public/application/submission/tur-details/tur-details.component.ts @@ -1,7 +1,6 @@ import { Component, Input } from '@angular/core'; import { Router } from '@angular/router'; -import { ApplicationDocumentDto } from '../../../../../services/application-document/application-document.dto'; -import { PublicApplicationSubmissionDto } from '../../../../../services/public/public.dto'; +import { PublicApplicationSubmissionDto, PublicDocumentDto } from '../../../../../services/public/public.dto'; import { PublicService } from '../../../../../services/public/public.service'; import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; @@ -12,11 +11,11 @@ import { DOCUMENT_TYPE } from '../../../../../shared/dto/document.dto'; }) export class TurDetailsComponent { @Input() applicationSubmission!: PublicApplicationSubmissionDto; - @Input() set applicationDocuments(documents: ApplicationDocumentDto[]) { + @Input() set applicationDocuments(documents: PublicDocumentDto[]) { this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP); } - proposalMap: ApplicationDocumentDto[] = []; + proposalMap: PublicDocumentDto[] = []; constructor(private router: Router, private publicService: PublicService) {} diff --git a/portal-frontend/src/app/features/public/public.module.ts b/portal-frontend/src/app/features/public/public.module.ts index 57b0fa785e..d4df75e0df 100644 --- a/portal-frontend/src/app/features/public/public.module.ts +++ b/portal-frontend/src/app/features/public/public.module.ts @@ -6,6 +6,10 @@ import { MatSortModule } from '@angular/material/sort'; import { MatTreeModule } from '@angular/material/tree'; import { RouterModule, Routes } from '@angular/router'; import { SharedModule } from '../../shared/shared.module'; +import { PublicAlcReviewComponent } from './application/alc-review/alc-review.component'; +import { PublicDecisionsComponent } from './application/alc-review/decisions/decisions.component'; +import { PublicSubmissionDocumentsComponent } from './application/alc-review/submission-documents/submission-documents.component'; +import { PublicLfngReviewComponent } from './application/lfng-review/lfng-review.component'; import { PublicApplicationComponent } from './application/public-application.component'; import { SubmissionDetailsModule } from './application/submission/submission-details.module'; import { ApplicationSearchTableComponent } from './search/application-search-table/application-search-table.component'; @@ -35,6 +39,10 @@ const routes: Routes = [ FileTypeFilterDropDownComponent, SearchListComponent, PublicApplicationComponent, + PublicLfngReviewComponent, + PublicAlcReviewComponent, + PublicSubmissionDocumentsComponent, + PublicDecisionsComponent, ], imports: [ CommonModule, diff --git a/portal-frontend/src/app/services/public/public.dto.ts b/portal-frontend/src/app/services/public/public.dto.ts index 5c49d34add..ba6f3031d3 100644 --- a/portal-frontend/src/app/services/public/public.dto.ts +++ b/portal-frontend/src/app/services/public/public.dto.ts @@ -1,6 +1,7 @@ +import { BaseCodeDto } from '../../shared/dto/base.dto'; +import { DocumentTypeDto } from '../../shared/dto/document.dto'; import { OwnerTypeDto } from '../../shared/dto/owner.dto'; -import { ApplicationDocumentDto } from '../application-document/application-document.dto'; -import { ApplicationParcelDto } from '../application-parcel/application-parcel.dto'; +import { ApplicationPortalDecisionDto } from '../application-decision/application-decision.dto'; import { ApplicationStatusDto, NaruSubtypeDto, @@ -9,8 +10,10 @@ import { export interface GetPublicApplicationResponseDto { submission: PublicApplicationSubmissionDto; - parcels: ApplicationParcelDto[]; - documents: ApplicationDocumentDto[]; + parcels: PublicApplicationParcelDto[]; + documents: PublicDocumentDto[]; + review?: PublicApplicationSubmissionReviewDto; + decisions: ApplicationPortalDecisionDto[]; } export interface PublicOwnerDto { @@ -131,3 +134,50 @@ export interface PublicApplicationSubmissionDto { exclShareGovernmentBorders: boolean | null; inclGovernmentOwnsAllParcels?: boolean | null; } + +export interface PublicApplicationSubmissionReviewDto { + applicationFileNumber: string; + localGovernmentFileNumber: string | null; + firstName: string | null; + lastName: string | null; + position: string | null; + department: string | null; + isOCPDesignation: boolean | null; + OCPBylawName: string | null; + OCPDesignation: string | null; + OCPConsistent: boolean | null; + isSubjectToZoning: boolean | null; + zoningBylawName: string | null; + zoningDesignation: string | null; + zoningMinimumLotSize: string | null; + isZoningConsistent: boolean | null; + isAuthorized: boolean | null; +} + +export interface PublicApplicationParcelDto { + uuid: string; + pid?: string | null; + pin?: string | null; + legalDescription?: string | null; + civicAddress?: string | null; + mapAreaHectares?: number | null; + purchasedDate?: number | null; + isFarm?: boolean | null; + ownershipTypeCode?: string | null; + crownLandOwnerType?: string | null; + ownershipType?: BaseCodeDto; + parcelType: string; + alrArea: number | null; + owners: PublicOwnerDto[]; +} + +export interface PublicDocumentDto { + description?: string; + uuid: string; + type?: DocumentTypeDto; + documentUuid: string; + fileName: string; + fileSize?: number; + mimeType: string; + uploadedAt: number; +} diff --git a/services/apps/alcs/src/common/automapper/public.automapper.profile.ts b/services/apps/alcs/src/common/automapper/public.automapper.profile.ts index c463e68068..d1b49b784b 100644 --- a/services/apps/alcs/src/common/automapper/public.automapper.profile.ts +++ b/services/apps/alcs/src/common/automapper/public.automapper.profile.ts @@ -1,12 +1,25 @@ import { createMap, forMember, mapFrom, Mapper } from '@automapper/core'; import { AutomapperProfile, InjectMapper } from '@automapper/nestjs'; import { Injectable } from '@nestjs/common'; +import { ApplicationDocumentDto } from '../../alcs/application/application-document/application-document.dto'; +import { ApplicationDocument } from '../../alcs/application/application-document/application-document.entity'; +import { ApplicationSubmissionReview } from '../../portal/application-submission-review/application-submission-review.entity'; +import { ApplicationOwnerDto } from '../../portal/application-submission/application-owner/application-owner.dto'; import { ApplicationOwner } from '../../portal/application-submission/application-owner/application-owner.entity'; +import { ApplicationParcelDto } from '../../portal/application-submission/application-parcel/application-parcel.dto'; +import { ApplicationParcel } from '../../portal/application-submission/application-parcel/application-parcel.entity'; import { ApplicationSubmission } from '../../portal/application-submission/application-submission.entity'; import { + PublicApplicationParcelDto, PublicApplicationSubmissionDto, + PublicApplicationSubmissionReviewDto, + PublicDocumentDto, PublicOwnerDto, } from '../../portal/public/public.dto'; +import { + ParcelOwnershipType, + ParcelOwnershipTypeDto, +} from '../entities/parcel-ownership-type/parcel-ownership-type.entity'; @Injectable() export class PublicAutomapperProfile extends AutomapperProfile { @@ -33,7 +46,90 @@ export class PublicAutomapperProfile extends AutomapperProfile { }), ), ); - createMap(mapper, ApplicationOwner, PublicOwnerDto); + + createMap( + mapper, + ApplicationOwner, + PublicOwnerDto, + forMember( + (pd) => pd.displayName, + mapFrom((p) => `${p.firstName} ${p.lastName}`), + ), + ); + + createMap( + mapper, + ApplicationParcel, + PublicApplicationParcelDto, + forMember( + (pd) => pd.ownershipTypeCode, + mapFrom((p) => p.ownershipTypeCode), + ), + forMember( + (pd) => pd.purchasedDate, + mapFrom((p) => p.purchasedDate?.getTime()), + ), + forMember( + (p) => p.owners, + mapFrom((pd) => { + if (pd.owners) { + return this.mapper.mapArray( + pd.owners, + ApplicationOwner, + PublicOwnerDto, + ); + } else { + return []; + } + }), + ), + forMember( + (p) => p.ownershipType, + mapFrom((pd) => { + if (pd.ownershipType) { + return this.mapper.map( + pd.ownershipType, + ParcelOwnershipType, + ParcelOwnershipTypeDto, + ); + } else { + return undefined; + } + }), + ), + ); + + createMap( + mapper, + ApplicationSubmissionReview, + PublicApplicationSubmissionReviewDto, + ); + + createMap( + mapper, + ApplicationDocument, + PublicDocumentDto, + forMember( + (a) => a.mimeType, + mapFrom((ad) => ad.document.mimeType), + ), + forMember( + (a) => a.fileName, + mapFrom((ad) => ad.document.fileName), + ), + forMember( + (a) => a.fileSize, + mapFrom((ad) => ad.document.fileSize), + ), + forMember( + (a) => a.uploadedAt, + mapFrom((ad) => ad.document.uploadedAt.getTime()), + ), + forMember( + (a) => a.documentUuid, + mapFrom((ad) => ad.document.uuid), + ), + ); }; } } diff --git a/services/apps/alcs/src/portal/application-submission-review/application-submission-review.service.ts b/services/apps/alcs/src/portal/application-submission-review/application-submission-review.service.ts index 93c25f7da2..512fa2d345 100644 --- a/services/apps/alcs/src/portal/application-submission-review/application-submission-review.service.ts +++ b/services/apps/alcs/src/portal/application-submission-review/application-submission-review.service.ts @@ -256,6 +256,14 @@ export class ApplicationSubmissionReviewService { }; } + getForPublicReview(fileNumber: string) { + return this.applicationSubmissionReviewRepository.findOne({ + where: { + applicationFileNumber: fileNumber, + }, + }); + } + async delete(applicationReview: ApplicationSubmissionReview) { await this.applicationSubmissionReviewRepository.remove(applicationReview); } diff --git a/services/apps/alcs/src/portal/application-submission/application-parcel/application-parcel.dto.ts b/services/apps/alcs/src/portal/application-submission/application-parcel/application-parcel.dto.ts index b00a1195fb..f52e51f788 100644 --- a/services/apps/alcs/src/portal/application-submission/application-parcel/application-parcel.dto.ts +++ b/services/apps/alcs/src/portal/application-submission/application-parcel/application-parcel.dto.ts @@ -7,7 +7,6 @@ import { IsOptional, IsString, } from 'class-validator'; -import { Column } from 'typeorm'; import { ApplicationDocumentDto } from '../../../alcs/application/application-document/application-document.dto'; import { BaseCodeDto } from '../../../common/dtos/base.dto'; import { ApplicationOwnerDetailedDto } from '../application-owner/application-owner.dto'; diff --git a/services/apps/alcs/src/portal/public/public.controller.spec.ts b/services/apps/alcs/src/portal/public/public.controller.spec.ts index 734f96eae1..81dfde3181 100644 --- a/services/apps/alcs/src/portal/public/public.controller.spec.ts +++ b/services/apps/alcs/src/portal/public/public.controller.spec.ts @@ -5,6 +5,7 @@ import { createMock, DeepMocked } from '@golevelup/nestjs-testing'; import { Test, TestingModule } from '@nestjs/testing'; import { ClsService } from 'nestjs-cls'; import { mockKeyCloakProviders } from '../../../test/mocks/mockTypes'; +import { ApplicationDecisionV2Service } from '../../alcs/application-decision/application-decision-v2/application-decision/application-decision-v2.service'; import { ApplicationDocument, VISIBILITY_FLAG, @@ -14,6 +15,8 @@ import { ApplicationSubmissionToSubmissionStatus } from '../../alcs/application/ import { Application } from '../../alcs/application/application.entity'; import { ApplicationService } from '../../alcs/application/application.service'; import { PublicAutomapperProfile } from '../../common/automapper/public.automapper.profile'; +import { ApplicationSubmissionReview } from '../application-submission-review/application-submission-review.entity'; +import { ApplicationSubmissionReviewService } from '../application-submission-review/application-submission-review.service'; import { ApplicationParcelService } from '../application-submission/application-parcel/application-parcel.service'; import { ApplicationSubmission } from '../application-submission/application-submission.entity'; import { ApplicationSubmissionService } from '../application-submission/application-submission.service'; @@ -25,12 +28,16 @@ describe('PublicSearchController', () => { let mockAppSubService: DeepMocked; let mockAppParcelService: DeepMocked; let mockAppDocService: DeepMocked; + let mockAppReviewService: DeepMocked; + let mockAppDecService: DeepMocked; beforeEach(async () => { mockAppService = createMock(); mockAppSubService = createMock(); mockAppParcelService = createMock(); mockAppDocService = createMock(); + mockAppReviewService = createMock(); + mockAppDecService = createMock(); const module: TestingModule = await Test.createTestingModule({ imports: [ @@ -56,6 +63,14 @@ describe('PublicSearchController', () => { provide: ApplicationDocumentService, useValue: mockAppDocService, }, + { + provide: ApplicationSubmissionReviewService, + useValue: mockAppReviewService, + }, + { + provide: ApplicationDecisionV2Service, + useValue: mockAppDecService, + }, { provide: ClsService, useValue: {}, @@ -87,6 +102,10 @@ describe('PublicSearchController', () => { ); mockAppParcelService.fetchByApplicationFileId.mockResolvedValue([]); mockAppDocService.list.mockResolvedValue([]); + mockAppReviewService.getForPublicReview.mockResolvedValue( + new ApplicationSubmissionReview(), + ); + mockAppDecService.getByAppFileNumber.mockResolvedValue([]); const fileId = 'file-id'; await controller.getApplication(fileId); @@ -100,6 +119,8 @@ describe('PublicSearchController', () => { expect(mockAppDocService.list).toHaveBeenCalledWith(fileId, [ VISIBILITY_FLAG.PUBLIC, ]); + expect(mockAppReviewService.getForPublicReview).toHaveBeenCalledTimes(1); + expect(mockAppDecService.getByAppFileNumber).toHaveBeenCalledTimes(1); }); it('should call through to document service for getting files', async () => { diff --git a/services/apps/alcs/src/portal/public/public.controller.ts b/services/apps/alcs/src/portal/public/public.controller.ts index 264d0393b5..87b74408ec 100644 --- a/services/apps/alcs/src/portal/public/public.controller.ts +++ b/services/apps/alcs/src/portal/public/public.controller.ts @@ -3,6 +3,8 @@ import { Mapper } from '@automapper/core'; import { InjectMapper } from '@automapper/nestjs'; import { Controller, Get, Param } from '@nestjs/common'; import { Public } from 'nest-keycloak-connect'; +import { ApplicationDecisionV2Service } from '../../alcs/application-decision/application-decision-v2/application-decision/application-decision-v2.service'; +import { ApplicationDecision } from '../../alcs/application-decision/application-decision.entity'; import { ApplicationDocumentDto } from '../../alcs/application/application-document/application-document.dto'; import { ApplicationDocument, @@ -10,12 +12,21 @@ import { } from '../../alcs/application/application-document/application-document.entity'; import { ApplicationDocumentService } from '../../alcs/application/application-document/application-document.service'; import { ApplicationService } from '../../alcs/application/application.service'; +import { ApplicationPortalDecisionDto } from '../application-decision/application-decision.dto'; +import { ApplicationSubmissionReviewDto } from '../application-submission-review/application-submission-review.dto'; +import { ApplicationSubmissionReview } from '../application-submission-review/application-submission-review.entity'; +import { ApplicationSubmissionReviewService } from '../application-submission-review/application-submission-review.service'; import { ApplicationParcelDto } from '../application-submission/application-parcel/application-parcel.dto'; import { ApplicationParcel } from '../application-submission/application-parcel/application-parcel.entity'; import { ApplicationParcelService } from '../application-submission/application-parcel/application-parcel.service'; import { ApplicationSubmission } from '../application-submission/application-submission.entity'; import { ApplicationSubmissionService } from '../application-submission/application-submission.service'; -import { PublicApplicationSubmissionDto } from './public.dto'; +import { + PublicApplicationParcelDto, + PublicApplicationSubmissionDto, + PublicApplicationSubmissionReviewDto, + PublicDocumentDto, +} from './public.dto'; @Public() @Controller('/public') @@ -26,27 +37,29 @@ export class PublicController { private applicationSubmissionService: ApplicationSubmissionService, private applicationParcelService: ApplicationParcelService, private applicationDocumentService: ApplicationDocumentService, + private applicationSubmissionReviewService: ApplicationSubmissionReviewService, + private applicationDecisionService: ApplicationDecisionV2Service, ) {} @Get('/application/:fileId') - async getApplication(@Param('fileId') fileId: string) { - const application = await this.applicationService.get(fileId); + async getApplication(@Param('fileId') fileNumber: string) { + const application = await this.applicationService.get(fileNumber); if (!application?.dateReceivedAllItems) { throw new ServiceNotFoundException( - `Failed to find application with File ID ${fileId}`, + `Failed to find application with File ID ${fileNumber}`, ); } const submission = - await this.applicationSubmissionService.getOrFailByFileNumber(fileId); + await this.applicationSubmissionService.getOrFailByFileNumber(fileNumber); const parcels = - await this.applicationParcelService.fetchByApplicationFileId(fileId); + await this.applicationParcelService.fetchByApplicationFileId(fileNumber); const mappedParcels = this.mapper.mapArray( parcels, ApplicationParcel, - ApplicationParcelDto, + PublicApplicationParcelDto, ); const mappedSubmission = this.mapper.map( @@ -55,20 +68,45 @@ export class PublicController { PublicApplicationSubmissionDto, ); - const documents = await this.applicationDocumentService.list(fileId, [ + const documents = await this.applicationDocumentService.list(fileNumber, [ VISIBILITY_FLAG.PUBLIC, ]); const mappedDocuments = this.mapper.mapArray( documents, ApplicationDocument, - ApplicationDocumentDto, + PublicDocumentDto, + ); + + const review = + await this.applicationSubmissionReviewService.getForPublicReview( + fileNumber, + ); + + let mappedReview; + if (review) { + mappedReview = this.mapper.map( + review, + ApplicationSubmissionReview, + PublicApplicationSubmissionReviewDto, + ); + } + + const decisions = await this.applicationDecisionService.getByAppFileNumber( + fileNumber, + ); + const mappedDecisions = this.mapper.mapArray( + decisions, + ApplicationDecision, + ApplicationPortalDecisionDto, ); return { submission: mappedSubmission, parcels: mappedParcels, documents: mappedDocuments, + review: mappedReview, + decisions: mappedDecisions, }; } diff --git a/services/apps/alcs/src/portal/public/public.dto.ts b/services/apps/alcs/src/portal/public/public.dto.ts index e502cf8720..69968c4dae 100644 --- a/services/apps/alcs/src/portal/public/public.dto.ts +++ b/services/apps/alcs/src/portal/public/public.dto.ts @@ -1,6 +1,8 @@ import { AutoMap } from '@automapper/classes'; import { ApplicationStatusDto } from '../../alcs/application/application-submission-status/submission-status.dto'; import { OwnerTypeDto } from '../../common/owner-type/owner-type.entity'; +import { DocumentTypeDto } from '../../document/document.dto'; +import { ApplicationParcelOwnershipTypeDto } from '../application-submission/application-parcel/application-parcel.dto'; import { NaruSubtypeDto } from '../application-submission/application-submission.dto'; import { ProposedLot } from '../application-submission/application-submission.entity'; @@ -315,3 +317,113 @@ export class PublicApplicationSubmissionDto { @AutoMap(() => Boolean) inclGovernmentOwnsAllParcels?: boolean | null; } + +export class PublicApplicationSubmissionReviewDto { + @AutoMap() + applicationFileNumber: string; + + @AutoMap(() => String) + localGovernmentFileNumber: string | null; + + @AutoMap(() => String) + firstName: string | null; + + @AutoMap(() => String) + lastName: string | null; + + @AutoMap(() => String) + position: string | null; + + @AutoMap(() => String) + department: string | null; + + @AutoMap(() => Boolean) + isOCPDesignation: boolean | null; + + @AutoMap(() => String) + OCPBylawName: string | null; + + @AutoMap(() => String) + OCPDesignation: string | null; + + @AutoMap(() => Boolean) + OCPConsistent: boolean | null; + + @AutoMap(() => Boolean) + isSubjectToZoning: boolean | null; + + @AutoMap(() => String) + zoningBylawName: string | null; + + @AutoMap(() => String) + zoningDesignation: string | null; + + @AutoMap(() => String) + zoningMinimumLotSize: string | null; + + @AutoMap(() => Boolean) + isZoningConsistent: boolean | null; + + @AutoMap(() => Boolean) + isAuthorized: boolean | null; +} + +export class PublicApplicationParcelDto { + @AutoMap() + uuid: string; + + @AutoMap(() => String) + pid?: string | null; + + @AutoMap(() => String) + pin?: string | null; + + @AutoMap(() => String) + legalDescription?: string | null; + + @AutoMap(() => String) + civicAddress?: string | null; + + @AutoMap(() => Number) + mapAreaHectares?: number | null; + + @AutoMap(() => Number) + purchasedDate?: number | null; + + @AutoMap(() => Boolean) + isFarm?: boolean | null; + + @AutoMap(() => String) + ownershipTypeCode?: string | null; + + @AutoMap(() => String) + crownLandOwnerType?: string | null; + + ownershipType?: ApplicationParcelOwnershipTypeDto; + + @AutoMap(() => String) + parcelType: string; + + @AutoMap(() => Number) + alrArea: number | null; + + owners: PublicOwnerDto[]; +} + +export class PublicDocumentDto { + @AutoMap(() => String) + description?: string; + + @AutoMap() + uuid: string; + + @AutoMap(() => DocumentTypeDto) + type?: DocumentTypeDto; + + //Document Fields + documentUuid: string; + fileName: string; + fileSize?: number; + mimeType: string; + uploadedAt: number; +} diff --git a/services/apps/alcs/src/portal/public/public.module.ts b/services/apps/alcs/src/portal/public/public.module.ts index c0e86ea8d4..9bf1e39878 100644 --- a/services/apps/alcs/src/portal/public/public.module.ts +++ b/services/apps/alcs/src/portal/public/public.module.ts @@ -1,10 +1,11 @@ import { Module } from '@nestjs/common'; import { RouterModule } from '@nestjs/core'; +import { ApplicationDecisionV2Module } from '../../alcs/application-decision/application-decision-v2/application-decision-v2.module'; import { ApplicationSubmissionStatusModule } from '../../alcs/application/application-submission-status/application-submission-status.module'; import { ApplicationModule } from '../../alcs/application/application.module'; import { NotificationSubmissionStatusModule } from '../../alcs/notification/notification-submission-status/notification-submission-status.module'; -import { ApplicationSubmissionProfile } from '../../common/automapper/application-submission.automapper.profile'; import { PublicAutomapperProfile } from '../../common/automapper/public.automapper.profile'; +import { ApplicationSubmissionReviewModule } from '../application-submission-review/application-submission-review.module'; import { ApplicationSubmissionModule } from '../application-submission/application-submission.module'; import { PublicController } from './public.controller'; import { PublicSearchModule } from './search/public-search.module'; @@ -17,6 +18,8 @@ import { PublicStatusController } from './status/public-status.controller'; NotificationSubmissionStatusModule, ApplicationModule, ApplicationSubmissionModule, + ApplicationSubmissionReviewModule, + ApplicationDecisionV2Module, RouterModule.register([{ path: 'public', module: PublicSearchModule }]), ], controllers: [PublicStatusController, PublicController],