diff --git a/alcs-frontend/src/app/features/application/applicant-info/application-details/application-details.component.spec.ts b/alcs-frontend/src/app/features/application/applicant-info/application-details/application-details.component.spec.ts index fe141f2d2f..763c225ebd 100644 --- a/alcs-frontend/src/app/features/application/applicant-info/application-details/application-details.component.spec.ts +++ b/alcs-frontend/src/app/features/application/applicant-info/application-details/application-details.component.spec.ts @@ -56,6 +56,15 @@ describe('ApplicationDetailsComponent', () => { status: {} as ApplicationStatus, type: '', uuid: '', + naruWillBeOverFiveHundredM2: null, + naruWillRetainResidence: null, + naruWillHaveAdditionalResidence: null, + naruWillHaveTemporaryForeignWorkerHousing: null, + tfwhCount: null, + tfwhDesign: null, + tfwhFarmSize: null, + naruClustered: null, + naruSetback: null, naruExistingStructures: null, naruFillOrigin: null, naruFillType: null, diff --git a/alcs-frontend/src/app/features/application/applicant-info/application-details/naru-details/naru-details.component.html b/alcs-frontend/src/app/features/application/applicant-info/application-details/naru-details/naru-details.component.html index e32a308c52..639ca8f3b4 100644 --- a/alcs-frontend/src/app/features/application/applicant-info/application-details/naru-details/naru-details.component.html +++ b/alcs-frontend/src/app/features/application/applicant-info/application-details/naru-details/naru-details.component.html @@ -1,140 +1,174 @@
-
Selected Subtype:
+
+ Is your proposal for a principal residence with a total floor area greater than 500 m2? +
+
+ {{ _applicationSubmission.naruWillBeOverFiveHundredM2 ? 'Yes' : 'No' }} +
+ +
Is your proposal to retain an existing residence while building a new residence?
+
+ {{ _applicationSubmission.naruWillRetainResidence ? 'Yes' : 'No' }} +
+ +
Is your proposal for an additional residence?
+
+ {{ _applicationSubmission.naruWillHaveAdditionalResidence ? 'Yes' : 'No' }} +
+ +
Is your proposal for temporary foreign worker housing?
- {{ _applicationSubmission.naruSubtype?.label }} + {{ _applicationSubmission.naruWillHaveTemporaryForeignWorkerHousing ? 'Yes' : 'No' }}
+ +
+ Do you need to import any fill to construct or conduct the proposed non-adhering residential use? +
+
+ {{ _applicationSubmission.naruWillImportFill ? 'Yes' : 'No' }} +
+
What is the purpose of the proposal?
{{ _applicationSubmission.purpose }}
- -
- What is the total floor area (m2) of the proposed additional residence? -
-
- {{ _applicationSubmission.naruFloorArea }} m2 -
-
- Describe the necessity for an additional residence for farm use and how it will support agriculture in the short - or long term. -
-
- {{ _applicationSubmission.naruResidenceNecessity }} -
-
Describe the rationale for the proposed location of the additional residence.
-
- {{ _applicationSubmission.naruLocationRationale }} -
-
- Provide the total area (m2) and a description of infrastructure necessary to support the additional - residence. -
-
- {{ _applicationSubmission.naruInfrastructure }} -
-
- -
- What is the total floor area (m2) of the proposed principal residence? -
-
- {{ _applicationSubmission.naruFloorArea }} m2 -
+ +
- Describe how the proposal for a principal residence more than 500 m2 will support agriculture in the - short or long term. + Is your proposal necessary for farm use? If so, please explain + what the temporary foreign workers will be doing on the farm.
{{ _applicationSubmission.naruResidenceNecessity }}
-
Describe the rationale for the proposed location of the principal residence.
-
- {{ _applicationSubmission.naruLocationRationale }} -
-
- Provide the total area (m2) and a description of infrastructure necessary to support the principal - residence. -
-
- {{ _applicationSubmission.naruInfrastructure }} -
- -
What is the total floor area (m2) of the proposed accommodation?
+ +
How many temporary foreign workers will be housed by the proposal?
- {{ _applicationSubmission.naruFloorArea }} m2 -
-
How many "sleeping units" in total are proposed?
-
- {{ _applicationSubmission.naruSleepingUnits }} + {{ _applicationSubmission.tfwhCount }}
+
- Describe how the proposal for tourism accommodation will support agriculture in the short or long term. -
-
- {{ _applicationSubmission.naruResidenceNecessity }} + Will the temporary foreign worker housing be designed to move from one place to another?
-
Describe the rationale for the proposed location of the tourism accommodation.
- {{ _applicationSubmission.naruLocationRationale }} + {{ _applicationSubmission.tfwhDesign ? 'Yes' : 'No' }}
+
- Provide the total area (m2) and a description of infrastructure necessary to support the tourism - accommodation. -
-
- {{ _applicationSubmission.naruInfrastructure }} + What is the size (in hectares) of the farm operation that the temporary foreign workers will be supporting?
-
Describe any agri-tourism that is currently taking place on the property.
- {{ _applicationSubmission.naruAgriTourism }} + {{ _applicationSubmission.tfwhFarmSize }}
- Describe the total floor area (m2), type, number, and occupancy of all residential structures currently - located on the property. + Will the proposed residence(s) be clustered with existing residential structures? Please explain.
- {{ _applicationSubmission.naruExistingStructures }} + {{ _applicationSubmission.naruClustered }}
-
Proposal Map / Site Plan
+
+ Will the proposed residence(s) be located within a 60 m setback from the front lot line? Please explain. +
-
- - {{ file.fileName }} - -
+ {{ _applicationSubmission.naruSetback }}
- Do you need to import any fill to construct or conduct the proposed non-adhering residential use? + Where on the parcel will the proposal be situated and is there an agricultural rationale for the proposed location?
- {{ _applicationSubmission.naruWillImportFill ? 'Yes' : 'No' }} + {{ _applicationSubmission.naruLocationRationale }}
- -
Describe the type and amount of fill proposed to be placed.
-
- {{ _applicationSubmission.naruFillType }} + +
+ Describe any infrastructure required to support the proposed residence(s) and the approximate area (m2) + required for that infrastructure +
+
+ {{ _applicationSubmission.naruInfrastructure }} +
+ + +
+
Existing Residence
+
Total Floor Area
+
Description
+ +
+ +
+
+ +
+ {{ i + 1 }} +
+
+ {{ existingResidence.floorArea }} m2 +
+
{{ existingResidence.description }}
+
+
+ + +
+
Proposed Residence
+
Total Floor Area
+
Description
+ +
+ {{ i + 1 }} +
+
+ {{ proposedResidence.floorArea }} m2 +
+
{{ proposedResidence.description }}
+
+
+
-
Briefly describe the origin and quality of fill.
+
Proposal Map / Site Plan
+ + + +
Detailed Building Plan(s)
- {{ _applicationSubmission.naruFillOrigin }} +
+
-
Placement of Fill Project Duration
+ +
Describe the type and amount of fill proposed to be placed.
- {{ _applicationSubmission.naruProjectDuration }} + {{ _applicationSubmission.naruFillType }}
Fill to be Placed
-
Volume
-
{{ _applicationSubmission.naruToPlaceVolume }} m3
Area
{{ _applicationSubmission.naruToPlaceArea }} m2
Maximum Depth
diff --git a/alcs-frontend/src/app/features/application/applicant-info/application-details/naru-details/naru-details.component.scss b/alcs-frontend/src/app/features/application/applicant-info/application-details/naru-details/naru-details.component.scss index f53378423d..3b3fd509ff 100644 --- a/alcs-frontend/src/app/features/application/applicant-info/application-details/naru-details/naru-details.component.scss +++ b/alcs-frontend/src/app/features/application/applicant-info/application-details/naru-details/naru-details.component.scss @@ -4,3 +4,28 @@ grid-column-gap: 36px; grid-row-gap: 12px; } + +.existing-residences { + display: grid; + grid-template-columns: 1fr 1fr 1fr; + word-wrap: break-word; + white-space: pre-line; + grid-column-gap: 36px; + grid-row-gap: 12px; + + .full-width { + grid-column: 1/3; + } + + .grid-1 { + grid-column: 1/2; + } + + .grid-2 { + grid-column: 2/3; + } + + .grid-3 { + grid-column: 3/5; + } +} diff --git a/alcs-frontend/src/app/features/application/applicant-info/application-details/naru-details/naru-details.component.ts b/alcs-frontend/src/app/features/application/applicant-info/application-details/naru-details/naru-details.component.ts index 94a33a8f5a..d0a187d2a4 100644 --- a/alcs-frontend/src/app/features/application/applicant-info/application-details/naru-details/naru-details.component.ts +++ b/alcs-frontend/src/app/features/application/applicant-info/application-details/naru-details/naru-details.component.ts @@ -21,10 +21,12 @@ export class NaruDetailsComponent { @Input() set files(documents: ApplicationDocumentDto[] | undefined) { if (documents) { this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP); + this.buildingPlans = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.BUILDING_PLAN); } } proposalMap: ApplicationDocumentDto[] = []; + buildingPlans: ApplicationDocumentDto[] = []; constructor(private applicationDocumentService: ApplicationDocumentService) {} diff --git a/alcs-frontend/src/app/features/application/applicant-info/application-details/nfu-details/nfu-details.component.html b/alcs-frontend/src/app/features/application/applicant-info/application-details/nfu-details/nfu-details.component.html index 570dbce906..791e0654e0 100644 --- a/alcs-frontend/src/app/features/application/applicant-info/application-details/nfu-details/nfu-details.component.html +++ b/alcs-frontend/src/app/features/application/applicant-info/application-details/nfu-details/nfu-details.component.html @@ -42,20 +42,9 @@

Soil and Fill Components

{{ applicationSubmission.nfuFillTypeDescription }}
-
Briefly describe the origin and quality of fill.
-
- {{ applicationSubmission.nfuFillOriginDescription }} -
- -
Placement of Fill Project Duration
-
- {{ applicationSubmission.nfuProjectDuration }} -
Fill to be Placed
-
Volume
-
{{ applicationSubmission.nfuFillVolume }} m3
Area
{{ applicationSubmission.nfuTotalFillArea }} m2
Maximum Depth
diff --git a/alcs-frontend/src/app/features/application/application.module.ts b/alcs-frontend/src/app/features/application/application.module.ts index 3aa11fc91d..e347318a34 100644 --- a/alcs-frontend/src/app/features/application/application.module.ts +++ b/alcs-frontend/src/app/features/application/application.module.ts @@ -87,6 +87,6 @@ const routes: Routes = [ BoundaryAmendmentComponent, EditBoundaryAmendmentDialogComponent, ], - imports: [SharedModule, RouterModule.forChild(routes), ApplicationDetailsModule, DecisionModule], + imports: [SharedModule.forRoot(), RouterModule.forChild(routes), ApplicationDetailsModule, DecisionModule], }) export class ApplicationModule {} diff --git a/alcs-frontend/src/app/features/application/decision/decision-v2/decision-component/naru/naru.component.html b/alcs-frontend/src/app/features/application/decision/decision-v2/decision-component/naru/naru.component.html index dafcee70ff..d4460ed483 100644 --- a/alcs-frontend/src/app/features/application/decision/decision-v2/decision-component/naru/naru.component.html +++ b/alcs-frontend/src/app/features/application/decision/decision-v2/decision-component/naru/naru.component.html @@ -1,9 +1,4 @@ -
-
Residential Use Type
- {{ component.naruSubtype?.label }} - -
Expiry Date
diff --git a/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/decision-component.component.ts b/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/decision-component.component.ts index 42fa785246..f498be18f8 100644 --- a/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/decision-component.component.ts +++ b/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/decision-component.component.ts @@ -49,7 +49,7 @@ export class DecisionComponentComponent implements OnInit { // pofo, pfrs fillTypeToPlace = new FormControl(null, [Validators.required]); - volumeToPlace = new FormControl(null, [Validators.required, Validators.min(MIN_SOIL_FIELDS)]); + volumeToPlace = new FormControl(null, [Validators.min(MIN_SOIL_FIELDS)]); areaToPlace = new FormControl(null, [Validators.required, Validators.min(MIN_SOIL_FIELDS)]); maximumDepthToPlace = new FormControl(null, [Validators.required, Validators.min(MIN_SOIL_FIELDS)]); averageDepthToPlace = new FormControl(null, [Validators.required, Validators.min(MIN_SOIL_FIELDS)]); @@ -59,13 +59,12 @@ export class DecisionComponentComponent implements OnInit { // roso, pfrs soilTypeRemoved = new FormControl(null, [Validators.required]); - volumeToRemove = new FormControl(null, [Validators.required, Validators.min(MIN_SOIL_FIELDS)]); + volumeToRemove = new FormControl(null, [Validators.min(MIN_SOIL_FIELDS)]); areaToRemove = new FormControl(null, [Validators.required, Validators.min(MIN_SOIL_FIELDS)]); maximumDepthToRemove = new FormControl(null, [Validators.required, Validators.min(MIN_SOIL_FIELDS)]); averageDepthToRemove = new FormControl(null, [Validators.required, Validators.min(MIN_SOIL_FIELDS)]); // naru - naruSubtypeCode = new FormControl(null, [Validators.required]); naruEndDate = new FormControl(null); //subd @@ -266,13 +265,11 @@ export class DecisionComponentComponent implements OnInit { } private patchNaruFields() { - this.form.addControl('naruSubtypeCode', this.naruSubtypeCode); this.form.addControl('naruEndDate', this.naruEndDate); this.form.addControl('expiryDate', this.expiryDate); this.naruEndDate.setValue(this.data.endDate ? new Date(this.data.endDate) : null); this.expiryDate.setValue(this.data.expiryDate ? new Date(this.data.expiryDate) : null); - this.naruSubtypeCode.setValue(this.data.naruSubtypeCode ?? null); } private patchSubdFields() { @@ -350,16 +347,18 @@ export class DecisionComponentComponent implements OnInit { return { endDate: this.naruEndDate.value ? formatDateForApi(this.naruEndDate.value) : null, expiryDate: this.expiryDate.value ? formatDateForApi(this.expiryDate.value) : null, - naruSubtypeCode: this.naruSubtypeCode.value ?? null, }; } private getSubdDataChange(): SubdDecisionComponentDto { - const update = this.subdApprovedLots.value?.map((e) => ({ - ...e, - size: e.size ? e.size : null, - alrArea: e.alrArea ? e.alrArea : null - }) as ProposedDecisionLotDto); + const update = this.subdApprovedLots.value?.map( + (e) => + ({ + ...e, + size: e.size ? e.size : null, + alrArea: e.alrArea ? e.alrArea : null, + }) as ProposedDecisionLotDto, + ); return { lots: update ?? undefined, expiryDate: this.expiryDate.value ? formatDateForApi(this.expiryDate.value) : null, diff --git a/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/naru-input/naru-input.component.html b/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/naru-input/naru-input.component.html index f9d5b365b0..a623f2a4f2 100644 --- a/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/naru-input/naru-input.component.html +++ b/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/naru-input/naru-input.component.html @@ -13,19 +13,6 @@ /> -
- -
- Expiry Date Fill to be placed
- +
diff --git a/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/pofo-input/pofo-input.component.html b/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/pofo-input/pofo-input.component.html index 4b33f8722c..da4c83412c 100644 --- a/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/pofo-input/pofo-input.component.html +++ b/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/pofo-input/pofo-input.component.html @@ -47,7 +47,7 @@ thousandSeparator="," separatorLimit="9999999999" formControlName="volumeToPlace" - placeholder="Volume*" + placeholder="Volume" /> m3 diff --git a/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/roso-input/roso-input.component.html b/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/roso-input/roso-input.component.html index de69effab1..ab0d9dc9d5 100644 --- a/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/roso-input/roso-input.component.html +++ b/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-component/roso-input/roso-input.component.html @@ -46,7 +46,7 @@ thousandSeparator="," separatorLimit="9999999999" formControlName="volumeToRemove" - placeholder="Volume*" + placeholder="Volume" /> m3 diff --git a/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-components.component.ts b/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-components.component.ts index 906e2910f0..8012fd4a18 100644 --- a/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-components.component.ts +++ b/alcs-frontend/src/app/features/application/decision/decision-v2/decision-input/decision-components/decision-components.component.ts @@ -261,7 +261,6 @@ export class DecisionComponentsComponent implements OnInit, OnDestroy, AfterView private patchNaruFields(component: ApplicationDecisionComponentDto) { component.endDate = this.application.proposalEndDate; component.expiryDate = this.application.proposalExpiryDate; - component.naruSubtypeCode = this.application.submittedApplication?.naruSubtype?.code; } private patchInclExclFields(component: ApplicationDecisionComponentDto) { diff --git a/alcs-frontend/src/app/features/application/lfng-info/return-application-dialog/return-application-dialog.component.scss b/alcs-frontend/src/app/features/application/lfng-info/return-application-dialog/return-application-dialog.component.scss index 261b090287..fdaeb72f2f 100644 --- a/alcs-frontend/src/app/features/application/lfng-info/return-application-dialog/return-application-dialog.component.scss +++ b/alcs-frontend/src/app/features/application/lfng-info/return-application-dialog/return-application-dialog.component.scss @@ -35,6 +35,7 @@ } .comment-input { + font-size: 16px; resize: none; margin-top: 4px; border: 1px solid rgba(0, 0, 0, 0.42); diff --git a/alcs-frontend/src/app/features/application/proposal/naru/naru.component.html b/alcs-frontend/src/app/features/application/proposal/naru/naru.component.html index aeb7253ea3..9dc7ecc966 100644 --- a/alcs-frontend/src/app/features/application/proposal/naru/naru.component.html +++ b/alcs-frontend/src/app/features/application/proposal/naru/naru.component.html @@ -5,8 +5,3 @@ (save)="updateApplicationValue('proposalEndDate', $event)" >
- -
-
Residential Use Type
- {{ naruSubtype }} -
diff --git a/alcs-frontend/src/app/features/application/proposal/naru/naru.component.ts b/alcs-frontend/src/app/features/application/proposal/naru/naru.component.ts index bfe290e186..162e323018 100644 --- a/alcs-frontend/src/app/features/application/proposal/naru/naru.component.ts +++ b/alcs-frontend/src/app/features/application/proposal/naru/naru.component.ts @@ -1,7 +1,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { Subject, takeUntil } from 'rxjs'; import { ApplicationDetailService } from '../../../../services/application/application-detail.service'; -import { ApplicationSubmissionService } from '../../../../services/application/application-submission/application-submission.service'; import { ApplicationDto, UpdateApplicationDto } from '../../../../services/application/application.dto'; import { ApplicationDecisionV2Service } from '../../../../services/application/decision/application-decision-v2/application-decision-v2.service'; import { ToastService } from '../../../../services/toast/toast.service'; @@ -19,21 +18,16 @@ interface InlineSelect { export class NaruProposalComponent implements OnDestroy, OnInit { $destroy = new Subject(); application: ApplicationDto | undefined; - naruSubtype: string = ''; constructor( private applicationDetailService: ApplicationDetailService, private toastService: ToastService, - private applicationSubmissionService: ApplicationSubmissionService, ) {} ngOnInit(): void { this.applicationDetailService.$application.pipe(takeUntil(this.$destroy)).subscribe((application) => { if (application) { this.application = application; - this.applicationSubmissionService - .fetchSubmission(application.fileNumber) - .then((e) => (this.naruSubtype = e.naruSubtype?.label ?? '')); } }); } diff --git a/alcs-frontend/src/app/features/application/proposal/proposal.component.html b/alcs-frontend/src/app/features/application/proposal/proposal.component.html index 4c11008118..4d04777a98 100644 --- a/alcs-frontend/src/app/features/application/proposal/proposal.component.html +++ b/alcs-frontend/src/app/features/application/proposal/proposal.component.html @@ -8,7 +8,7 @@
Proposal Components - {{ application.type.label }}
(ha) (m2)
- +
Agricultural Capability
@@ -55,7 +55,7 @@
Parcels
-
Staff Comments and Observations
+
Staff Comments and Observations
- (existingDecision && existingDecision.modifies?.uuid === modification.uuid) || - (modification.reviewOutcome.code === 'PRC' && !modification.resultingDecision), + modification.reviewOutcome.code === 'PRC' && + ((existingDecision && existingDecision.modifies?.uuid === modification.uuid) || + !modification.resultingDecision), ); this.postDecisions = proceededModifications.map((modification, index) => ({ label: `Modification Request #${modifications.length - index} - ${modification.modifiesDecisions diff --git a/alcs-frontend/src/app/features/notice-of-intent/proposal/proposal.component.html b/alcs-frontend/src/app/features/notice-of-intent/proposal/proposal.component.html index 2c75181097..04c06fd85b 100644 --- a/alcs-frontend/src/app/features/notice-of-intent/proposal/proposal.component.html +++ b/alcs-frontend/src/app/features/notice-of-intent/proposal/proposal.component.html @@ -4,7 +4,7 @@
Proposal Components - {{ noticeOfIntent.type.label }}
Proposal ALR Area Impacted (ha)
- +
Agricultural Capability
@@ -46,7 +46,7 @@
Parcels
-
Staff Comments and Observations
+
Staff Comments and Observations
- Fill to be Placed Soil to be Removed + Fill to be Placed Volume - {{ submission.soilToPlaceVolume }} m3 {{ submission.soilToRemoveVolume }} m3 + {{ submission.soilToPlaceVolume }} m3 Area - {{ submission.soilToPlaceArea }} m2 {{ submission.soilToRemoveArea }} m2 + {{ submission.soilToPlaceArea }} m2 Maximum Depth - {{ submission.soilToPlaceMaximumDepth }} m {{ submission.soilToRemoveMaximumDepth }} m + {{ submission.soilToPlaceMaximumDepth }} m Average Depth - {{ submission.soilToPlaceAverageDepth }} m {{ submission.soilToRemoveAverageDepth }} m + {{ submission.soilToPlaceAverageDepth }} m diff --git a/alcs-frontend/src/app/features/notification/intake/intake.component.ts b/alcs-frontend/src/app/features/notification/intake/intake.component.ts index 1cdd070cbc..125fb08a75 100644 --- a/alcs-frontend/src/app/features/notification/intake/intake.component.ts +++ b/alcs-frontend/src/app/features/notification/intake/intake.component.ts @@ -92,6 +92,7 @@ export class IntakeComponent implements OnInit, OnDestroy { if (update) { this.toastService.showSuccessToast('Notification updated'); this.contactEmail = email; + this.resendResponse(); } } } diff --git a/alcs-frontend/src/app/services/application/application-submission/application-submission.service.spec.ts b/alcs-frontend/src/app/services/application/application-submission/application-submission.service.spec.ts index 5f94cfdd01..e26b0d4ad1 100644 --- a/alcs-frontend/src/app/services/application/application-submission/application-submission.service.spec.ts +++ b/alcs-frontend/src/app/services/application/application-submission/application-submission.service.spec.ts @@ -32,6 +32,15 @@ describe('ApplicationSubmissionService', () => { status: {} as ApplicationStatus, type: '', uuid: '', + naruWillBeOverFiveHundredM2: null, + naruWillRetainResidence: null, + naruWillHaveAdditionalResidence: null, + naruWillHaveTemporaryForeignWorkerHousing: null, + tfwhCount: null, + tfwhDesign: null, + tfwhFarmSize: null, + naruClustered: null, + naruSetback: null, naruExistingStructures: null, naruFillOrigin: null, naruFillType: null, diff --git a/alcs-frontend/src/app/services/application/application.dto.ts b/alcs-frontend/src/app/services/application/application.dto.ts index d25a47b51c..9fe3f94b7e 100644 --- a/alcs-frontend/src/app/services/application/application.dto.ts +++ b/alcs-frontend/src/app/services/application/application.dto.ts @@ -48,6 +48,16 @@ export interface ProposedLot { componentUuid: string; } +export interface ExistingResidence { + floorArea: number; + description: string; +} + +export interface ProposedResidence { + floorArea: number; + description: string; +} + export interface ApplicationReviewDto { localGovernmentFileNumber: string; firstName: string; @@ -189,13 +199,22 @@ export interface ApplicationSubmissionDto { soilHasSubmittedNotice: boolean | null; //NARU Fields + naruWillBeOverFiveHundredM2: boolean | null; + naruWillRetainResidence: boolean | null; + naruWillHaveAdditionalResidence: boolean | null; + naruWillHaveTemporaryForeignWorkerHousing: boolean | null; + naruWillImportFill: boolean | null; + tfwhCount: string | null; + tfwhDesign: boolean | null; + tfwhFarmSize: string | null; + naruClustered: string | null; + naruSetback: string | null; naruSubtype: BaseCodeDto | null; naruFloorArea: number | null; naruResidenceNecessity: string | null; naruLocationRationale: string | null; naruInfrastructure: string | null; naruExistingStructures: string | null; - naruWillImportFill: boolean | null; naruFillType: string | null; naruFillOrigin: string | null; naruProjectDuration: string | null; @@ -205,6 +224,8 @@ export interface ApplicationSubmissionDto { naruToPlaceAverageDepth: number | null; naruSleepingUnits: number | null; naruAgriTourism: string | null; + naruExistingResidences?: ExistingResidence[]; + naruProposedResidences?: ProposedResidence[]; //Inclusion / Exclusion Fields prescribedBody: string | null; diff --git a/portal-frontend/src/app/features/applications/application-details/naru-details/naru-details.component.html b/portal-frontend/src/app/features/applications/application-details/naru-details/naru-details.component.html index 54da0f349d..0ec5fa11cf 100644 --- a/portal-frontend/src/app/features/applications/application-details/naru-details/naru-details.component.html +++ b/portal-frontend/src/app/features/applications/application-details/naru-details/naru-details.component.html @@ -1,228 +1,271 @@
-
Selected Subtype:
+
+ Is your proposal for a principal residence with a total floor area greater than 500 m2? +
- - {{ _applicationSubmission.naruSubtype.label }} - - + {{ + _applicationSubmission.naruWillBeOverFiveHundredM2 ? 'Yes' : 'No' + }} +
- -
What is the purpose of the proposal?
-
- {{ _applicationSubmission.purpose }} - -
- - -
- What is the total floor area (m2) of the proposed additional residence? -
-
- {{ _applicationSubmission.naruFloorArea }} - m2 - -
- -
- Describe the necessity for an additional residence for farm use and how it will support agriculture in the short - or long term. -
-
- {{ _applicationSubmission.naruResidenceNecessity }} - -
- -
- Describe the rationale for the proposed location of the additional residence. -
-
- {{ _applicationSubmission.naruLocationRationale }} - -
- -
- Provide the total area (m2) and a description of infrastructure necessary to support the additional - residence. -
-
- {{ _applicationSubmission.naruInfrastructure }} - -
-
- - -
- What is the total floor area (m2) of the proposed principal residence? -
-
- {{ _applicationSubmission.naruFloorArea }} - m2 - -
- -
- Describe how the proposal for a principal residence more than 500 m2 will support agriculture in the - short or long term. -
-
- {{ _applicationSubmission.naruResidenceNecessity }} - -
- -
Describe the rationale for the proposed location of the principal residence.
-
- {{ _applicationSubmission.naruLocationRationale }} - -
- -
- Provide the total area (m2) and a description of infrastructure necessary to support the additional - residence. -
-
- {{ _applicationSubmission.naruInfrastructure }} - -
-
- - -
What is the total floor area (m2) of the proposed accommodation?
-
- {{ _applicationSubmission.naruFloorArea }} - m2 - -
- -
How many "sleeping units" in total are proposed?
-
- {{ _applicationSubmission.naruSleepingUnits }} - -
+
Is your proposal to retain an existing residence while building a new residence?
+
+ {{ + _applicationSubmission.naruWillRetainResidence ? 'Yes' : 'No' + }} + +
-
- Describe how the proposal for tourism accommodation will support agriculture in the short or long term. -
-
- {{ _applicationSubmission.naruResidenceNecessity }} - -
+
Is your proposal for an additional residence?
+
+ {{ + _applicationSubmission.naruWillHaveAdditionalResidence ? 'Yes' : 'No' + }} + +
-
- Describe the rationale for the proposed location of the tourism accommodation. -
-
- {{ _applicationSubmission.naruLocationRationale }} - -
+
Is your proposal for temporary foreign worker housing?
+
+ {{ + _applicationSubmission.naruWillHaveTemporaryForeignWorkerHousing ? 'Yes' : 'No' + }} + +
-
- Provide the total area (m2) and a description of infrastructure necessary to support the tourism - accommodation. -
-
- {{ _applicationSubmission.naruInfrastructure }} - -
+
+ Do you need to import any fill to construct or conduct the proposed non-adhering residential use? +
+
+ {{ + _applicationSubmission.naruWillImportFill ? 'Yes' : 'No' + }} + +
-
Describe any agri-tourism that is currently taking place on the property.
-
- {{ _applicationSubmission.naruAgriTourism }} - -
-
+
What is the purpose of the proposal?
+
+ {{ _applicationSubmission.purpose }} + +
+
- Describe the total floor area (m2), type, number, and occupancy of all residential structures currently - located on the property. + Is your proposal necessary for farm use? If so, please explain + what the temporary foreign workers will be doing on the farm. +
+
+ {{ _applicationSubmission.naruResidenceNecessity }} +
+
+ + +
How many temporary foreign workers will be housed by the proposal?
- {{ _applicationSubmission.naruExistingStructures }} - + {{ _applicationSubmission.tfwhCount }} +
-
Proposal Map / Site Plan
+
+ Will the temporary foreign worker housing be designed to move from one place to another? +
- - {{ map.fileName }} - - + + {{ _applicationSubmission.tfwhDesign ? 'Yes' : 'No' }} + +
- Do you need to import any fill to construct or conduct the proposed non-adhering residential use? + What is the size (in hectares) of the farm operation that the temporary foreign workers will be supporting?
- {{ - _applicationSubmission.naruWillImportFill ? 'Yes' : 'No' - }} - + {{ _applicationSubmission.tfwhFarmSize }} +
+
- -
Describe the type and amount of fill proposed to be placed.
-
- {{ _applicationSubmission.naruFillType }} - -
+
+ Will the proposed residence(s) be clustered with existing residential structures? Please explain. +
+
+ {{ _applicationSubmission.naruClustered }} + +
-
Briefly describe the origin and quality of fill.
-
- {{ _applicationSubmission.naruFillOrigin }} - -
+
+ Will the proposed residence(s) be located within a 60 m setback from the front lot line? Please explain. +
+
+ {{ _applicationSubmission.naruSetback }} + +
-
Placement of Fill Project Duration
-
-
{{ _applicationSubmission.naruProjectDuration }}
- -
+
+ Where on the parcel will the proposal be situated and is there an agricultural rationale for the proposed location? +
+
+ {{ _applicationSubmission.naruLocationRationale }} + +
-
-
-
Fill to be Placed
+
+ Describe any infrastructure required to support the proposed residence(s) and the approximate area (m2) + required for that infrastructure +
+
+ {{ _applicationSubmission.naruInfrastructure }} + +
-
Volume
+ +
+
Existing Residence
+
Total Floor Area
+
Description
+
- {{ _applicationSubmission.naruToPlaceVolume }} - m3 - +
- -
Area
+
+
- {{ _applicationSubmission.naruToPlaceArea }} - m2 - + {{ i + 1 }}
- -
Maximum Depth
- {{ _applicationSubmission.naruToPlaceMaximumDepth }} - m - + {{ existingResidence.floorArea }} m2
- -
Average Depth
+
{{ existingResidence.description }}
+
+
+ +
Total Floor Area of Existing Residence(s) - If Applicable
+
- {{ _applicationSubmission.naruToPlaceAverageDepth }} - m - +
+
+ + +
+
+ +
+
Proposed Residence
+
Total Floor Area
+
Description
+ +
+
+ +
+ {{ i + 1 }} +
+
+ {{ proposedResidence.floorArea }} m2 +
+
{{ proposedResidence.description }}
+
+
+ +
Total Floor Area of Proposed Residence(s)
+ +
+ +
+
+ + +
+ +
Proposal Map / Site Plan
+ + +
Detailed Building Plan(s)
+ + + +
Describe the type and amount of fill proposed to be placed.
+
+ {{ _applicationSubmission.naruFillType }} + +
+ +
+
+
Fill to be Placed
+ +
Area
+
+ {{ _applicationSubmission.naruToPlaceArea }} + m2 + +
+ +
Maximum Depth
+
+ {{ _applicationSubmission.naruToPlaceMaximumDepth }} + m + +
+ +
Average Depth
+
+ {{ _applicationSubmission.naruToPlaceAverageDepth }} + m + +
+
diff --git a/portal-frontend/src/app/features/applications/application-details/naru-details/naru-details.component.scss b/portal-frontend/src/app/features/applications/application-details/naru-details/naru-details.component.scss index 63cfeaa16b..80594f9f2d 100644 --- a/portal-frontend/src/app/features/applications/application-details/naru-details/naru-details.component.scss +++ b/portal-frontend/src/app/features/applications/application-details/naru-details/naru-details.component.scss @@ -16,3 +16,19 @@ grid-column-gap: rem(16); } } + +.existing-residences { + display: grid; + grid-template-columns: max-content max-content max-content max-content max-content; + overflow-x: auto; + grid-column-gap: rem(36); + grid-row-gap: rem(12); + + @media screen and (min-width: $tabletBreakpoint) { + grid-template-columns: 1fr 1fr 1fr; + } + + .full-width { + grid-column: 1/3; + } +} diff --git a/portal-frontend/src/app/features/applications/application-details/naru-details/naru-details.component.ts b/portal-frontend/src/app/features/applications/application-details/naru-details/naru-details.component.ts index 6c68512e71..9873fa4829 100644 --- a/portal-frontend/src/app/features/applications/application-details/naru-details/naru-details.component.ts +++ b/portal-frontend/src/app/features/applications/application-details/naru-details/naru-details.component.ts @@ -1,10 +1,11 @@ -import { Component, Input } from '@angular/core'; +import { Component, HostListener, 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 { ApplicationSubmissionDetailedDto } from '../../../../services/application-submission/application-submission.dto'; import { DOCUMENT_TYPE } from '../../../../shared/dto/document.dto'; import { openFileInline } from '../../../../shared/utils/file'; +import { MOBILE_BREAKPOINT } from '../../../../shared/utils/breakpoints'; @Component({ selector: 'app-naru-details[applicationSubmission]', @@ -16,6 +17,8 @@ export class NaruDetailsComponent { @Input() showEdit = true; @Input() draftMode = false; + isMobile = window.innerWidth <= MOBILE_BREAKPOINT; + _applicationSubmission: ApplicationSubmissionDetailedDto | undefined; @Input() set applicationSubmission(applicationSubmission: ApplicationSubmissionDetailedDto | undefined) { @@ -26,16 +29,21 @@ export class NaruDetailsComponent { @Input() set applicationDocuments(documents: ApplicationDocumentDto[]) { this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP); + this.buildingPlans = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.BUILDING_PLAN); } proposalMap: ApplicationDocumentDto[] = []; + buildingPlans: ApplicationDocumentDto[] = []; - constructor(private router: Router, private applicationDocumentService: ApplicationDocumentService) {} + constructor( + private router: Router, + private applicationDocumentService: ApplicationDocumentService, + ) {} async onEditSection(step: number) { if (this.draftMode) { await this.router.navigateByUrl( - `/alcs/application/${this._applicationSubmission?.fileNumber}/edit/${step}?errors=t` + `/alcs/application/${this._applicationSubmission?.fileNumber}/edit/${step}?errors=t`, ); } else { await this.router.navigateByUrl(`application/${this._applicationSubmission?.fileNumber}/edit/${step}?errors=t`); @@ -48,4 +56,9 @@ export class NaruDetailsComponent { openFileInline(res.url, file.fileName); } } + + @HostListener('window:resize', ['$event']) + onWindowResize() { + this.isMobile = window.innerWidth <= MOBILE_BREAKPOINT; + } } diff --git a/portal-frontend/src/app/features/applications/application-details/nfu-details/nfu-details.component.html b/portal-frontend/src/app/features/applications/application-details/nfu-details/nfu-details.component.html index a87c462967..820031167d 100644 --- a/portal-frontend/src/app/features/applications/application-details/nfu-details/nfu-details.component.html +++ b/portal-frontend/src/app/features/applications/application-details/nfu-details/nfu-details.component.html @@ -48,29 +48,11 @@

Soil and Fill Components

{{ applicationSubmission.nfuFillTypeDescription }}
-
Briefly describe the origin and quality of fill.
-
- {{ applicationSubmission.nfuFillOriginDescription }} - -
- -
Placement of Fill Project Duration
-
-
{{ applicationSubmission.nfuProjectDuration }}
- -
Fill to be Placed
-
Volume
-
- {{ applicationSubmission.nfuFillVolume }} - m3 - -
-
Area
{{ applicationSubmission.nfuTotalFillArea }} diff --git a/portal-frontend/src/app/features/applications/edit-submission/edit-submission-base.module.ts b/portal-frontend/src/app/features/applications/edit-submission/edit-submission-base.module.ts index 39a6bfbc93..a6f40c8bf5 100644 --- a/portal-frontend/src/app/features/applications/edit-submission/edit-submission-base.module.ts +++ b/portal-frontend/src/app/features/applications/edit-submission/edit-submission-base.module.ts @@ -24,7 +24,6 @@ import { CoveProposalComponent } from './proposal/cove-proposal/cove-proposal.co import { CovenantTransfereeDialogComponent } from './proposal/cove-proposal/transferee-dialog/transferee-dialog.component'; import { ExclProposalComponent } from './proposal/excl-proposal/excl-proposal.component'; import { InclProposalComponent } from './proposal/incl-proposal/incl-proposal.component'; -import { ChangeSubtypeConfirmationDialogComponent } from './proposal/naru-proposal/change-subtype-confirmation-dialog/change-subtype-confirmation-dialog.component'; import { NaruProposalComponent } from './proposal/naru-proposal/naru-proposal.component'; import { NfuProposalComponent } from './proposal/nfu-proposal/nfu-proposal.component'; import { PfrsProposalComponent } from './proposal/pfrs-proposal/pfrs-proposal.component'; @@ -39,6 +38,7 @@ import { SuccessComponent } from './success/success.component'; import { PrimaryContactConfirmationDialogComponent } from './primary-contact/primary-contact-confirmation-dialog/primary-contact-confirmation-dialog.component'; import { OtherAttachmentsUploadDialogComponent } from './other-attachments/other-attachments-upload-dialog/other-attachments-upload-dialog.component'; import { MatCard, MatCardHeader, MatCardModule } from '@angular/material/card'; +import { ResidenceDialogComponent } from './proposal/naru-proposal/residence-dialog/residence-dialog.component'; @NgModule({ declarations: [ @@ -64,7 +64,7 @@ import { MatCard, MatCardHeader, MatCardModule } from '@angular/material/card'; PofoProposalComponent, PfrsProposalComponent, NaruProposalComponent, - ChangeSubtypeConfirmationDialogComponent, + ResidenceDialogComponent, ExclProposalComponent, InclProposalComponent, CoveProposalComponent, @@ -112,6 +112,7 @@ import { MatCard, MatCardHeader, MatCardModule } from '@angular/material/card'; CoveProposalComponent, CovenantTransfereeDialogComponent, SuccessComponent, + ResidenceDialogComponent, ], }) export class EditSubmissionBaseModule {} diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/change-subtype-confirmation-dialog/change-subtype-confirmation-dialog.component.html b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/change-subtype-confirmation-dialog/change-subtype-confirmation-dialog.component.html deleted file mode 100644 index 8daaf7501b..0000000000 --- a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/change-subtype-confirmation-dialog/change-subtype-confirmation-dialog.component.html +++ /dev/null @@ -1,17 +0,0 @@ -
-

Change Non-Adhering Residential Use Application Sub-Type

-
- -
-
- - Changing application sub-type will remove content already saved to this page.
- Do you want to continue? -
- -
- - -
-
-
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/change-subtype-confirmation-dialog/change-subtype-confirmation-dialog.component.scss b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/change-subtype-confirmation-dialog/change-subtype-confirmation-dialog.component.scss deleted file mode 100644 index c4e03e5c59..0000000000 --- a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/change-subtype-confirmation-dialog/change-subtype-confirmation-dialog.component.scss +++ /dev/null @@ -1,24 +0,0 @@ -@use '../../../../../../../styles/functions' as *; - -.margin-bottom-1 { - margin-bottom: rem(16); -} - -.step-controls { - display: flex; - justify-content: space-between; -} - -.confirm-content { - margin: rem(24) 0; -} - -@media screen and (min-width: $desktopBreakpoint) { - .step-controls { - justify-content: flex-end; - - button { - margin-left: rem(25) !important; - } - } -} diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/change-subtype-confirmation-dialog/change-subtype-confirmation-dialog.component.spec.ts b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/change-subtype-confirmation-dialog/change-subtype-confirmation-dialog.component.spec.ts deleted file mode 100644 index bb2be65361..0000000000 --- a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/change-subtype-confirmation-dialog/change-subtype-confirmation-dialog.component.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { MatDialog, MatDialogRef } from '@angular/material/dialog'; -import { ChangeSubtypeConfirmationDialogComponent } from './change-subtype-confirmation-dialog.component'; - -describe('ChangeSubtypeConfirmationDialogComponent', () => { - let component: ChangeSubtypeConfirmationDialogComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ChangeSubtypeConfirmationDialogComponent], - providers: [ - { - provide: MatDialog, - useValue: {}, - }, - { - provide: MatDialogRef, - useValue: {}, - }, - ], - schemas: [NO_ERRORS_SCHEMA], - }).compileComponents(); - - fixture = TestBed.createComponent(ChangeSubtypeConfirmationDialogComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/change-subtype-confirmation-dialog/change-subtype-confirmation-dialog.component.ts b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/change-subtype-confirmation-dialog/change-subtype-confirmation-dialog.component.ts deleted file mode 100644 index 7483d10a9e..0000000000 --- a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/change-subtype-confirmation-dialog/change-subtype-confirmation-dialog.component.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Component } from '@angular/core'; -import { MatDialogRef } from '@angular/material/dialog'; - -@Component({ - selector: 'app-change-subtype-confirmation-dialog', - templateUrl: './change-subtype-confirmation-dialog.component.html', - styleUrls: ['./change-subtype-confirmation-dialog.component.scss'], -}) -export class ChangeSubtypeConfirmationDialogComponent { - stepIdx = 0; - - constructor(private dialogRef: MatDialogRef) {} - - async onCancel() { - this.dialogRef.close(false); - } - - async onConfirm() { - this.dialogRef.close(true); - } -} diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/naru-proposal.component.html b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/naru-proposal.component.html index 7ecb48b175..fa94eb7893 100644 --- a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/naru-proposal.component.html +++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/naru-proposal.component.html @@ -27,29 +27,181 @@

Proposal

-
Select a Sub-Type for your Non-Adhering Residential Use application
- + Is your proposal for a principal residence with a total floor area greater than 500 m2? + +
Total floor area includes the basement and any attached garage
+ + Yes + No + +
- {{ - subtype.label - }} - -
warning -
This field is required
+
This field is required
-
-
- Please select a sub-type above to view proposal questions + +
+ + Is your proposal to retain an existing residence while building a new residence? + + + Yes + No + +
+ warning +
This field is required
+
-
+
+ Is your proposal for an additional residence? + + Yes + No + +
+ warning +
This field is required
+
+
+ +
+ + Is your proposal for temporary foreign worker housing? + +
For registration in a federal temporary worker program
+ + Yes + No + +
+ warning +
This field is required
+
+
+ +
+ + Do you need to import any fill to construct or conduct the proposed non-adhering residential use? + +
Fill is any material brought onto the property, including gravel for construction.
+ + Yes + No + +
+ warning +
This field is required
+
+
+ +
Include why you are applying for non-adhering residential use, what the proposal will achieve, and any benefits @@ -65,506 +217,456 @@

Proposal

Characters left: {{ 4000 - purposeText.textLength }}
- -
- + +
+ Include a description of the scale, intensity, and labour capacity of the farm operation +
+ + + +
+ warning +
This field is required
+
Characters left: {{ 4000 - residenceNecessityText.textLength }}
+
-
- -
- Include a description of the scale, intensity, and labour capacity of the farm operation -
- - - -
- warning -
This field is required
-
-
Characters left: {{ 4000 - residenceNecessityText.textLength }}
+
+ + + + +
+ warning +
This field is required
+
Characters left: {{ 4000 - tfwhCountText.textLength }}
+
-
- + + Will the temporary foreign worker housing be designed to move from one place to another? + +
Examples: modular trailers, manufactured homes
+ + Yes -
- Include a description of the scale, intensity, and labour capacity of the farm operation -
- - - -
No - warning -
This field is required
-
-
Characters left: {{ 4000 - locationRationaleText.textLength }}
+
+
+ warning +
This field is required
+
-
- -
- Describe any infrastructure required to accommodate the additional residence and the approximate area required - for that infrastructure -
- - - -
- warning -
This field is required
-
-
Characters left: {{ 4000 - infrastructureText.textLength }}
+
+ +
+ The farm may include multiple parcels (leased, rented or owned) that are not adjacent but are managed as a + single operation.
- - - -
- - - - m2 - -
- warning -
This field is required
-
+ + + +
+ warning +
This field is required
+
Characters left: {{ 4000 - tfwhFarmSizeText.textLength }}
+
-
- - - - -
- warning -
This field is required
-
-
Characters left: {{ 4000 - residenceNecessityText.textLength }}
-
+
+ + + Siting of the residence(s) + -
- - - - -
- warning -
This field is required
-
-
Characters left: {{ 4000 - locationRationaleText.textLength }}
-
+
+

+ Siting of the residence in the ALR should maintain a viable agricultural remainder and should not + unnecessarily infringe upon the productive farming area of the property. Siting considers both clustering + and setback from the lot line. +

-
- -
- Describe any infrastructure required to accommodate the additional residence and the approximate area required - for that infrastructure -
- - - -
- warning -
This field is required
-
-
Characters left: {{ 4000 - infrastructureText.textLength }}
-
- +

+ For more information see + Policy L-26: Non-Adhering Residential Applications for Housing in the ALR. +

- -
- - - - m2 - -
- warning -
This field is required
-
-
+
+
+
Unclustered
+ +
-
- -
- A "sleeping unit" means: -
    -
  1. A bedroom or other area used for sleeping located in a residence, cabin or other
  2. - structure -
  3. A vehicle, trailer, tent or other structure, located on a campsite, field or other area
  4. -
-
- - - -
- warning -
This field is required
+
+
Clustered
+ +
+ +
+
Setback
+ +
+
+ +
+ +
+ + + + +
+ warning +
This field is required
+
Characters left: {{ 4000 - clusteredText.textLength }}
+
-
- - - - -
- warning -
This field is required
-
-
Characters left: {{ 4000 - residenceNecessityText.textLength }}
+
+ + + + +
+ warning +
This field is required
+
Characters left: {{ 4000 - setbackText.textLength }}
+
-
- - - - -
- warning -
This field is required
-
-
Characters left: {{ 4000 - locationRationaleText.textLength }}
+
+ + + + +
+ warning +
This field is required
+
Characters left: {{ 4000 - locationRationaleText.textLength }}
+
-
- -
- Describe any infrastructure required to accommodate the tourism accommodation and the approximate area - required for that infrastructure. -
- - - -
- warning -
This field is required
-
-
Characters left: {{ 4000 - infrastructureText.textLength }}
+
+ +
For example: driveway, septic field, sewage lagoon, yard
+ + + +
+ warning +
This field is required
+
Characters left: {{ 4000 - infrastructureText.textLength }}
+
-
- -
Agri-tourism activities are defined in the Agricultural Land Reserve Use Regulation.
- - Please refer to the - - Non-Adhering Residential Use + Total Floor Area of Existing Residence(s) - If Applicable +
+ + + + + + + + + + + + + + + + + + + - page on the ALC website for more information - - - - -
- warning -
This field is required
-
-
Characters left: {{ 4000 - agriTourismText.textLength }}
- - - -
- -
- Residential structure is defined as a structure, whether used permanently or temporarily as a residence, - agri-tourism accommodation, or tourist accommodation. +
+ + + + + +
Existing Residence{{ i + 1 }}Total Floor Area + {{ element.floorArea }} m2 + Description + {{ element.isExpanded ? element.description : getTruncatedDescription(element.description) }} + + {{ element.isExpanded ? 'Read Less' : 'Read More' }} + + Action + + +
Use the button below to add any existing residence(s)
+
+ +
+ Use the button below to add any existing residence(s)
- - - -
- warning -
This field is required
-
-
Characters left: {{ 4000 - existingStructuresText.textLength }}
+ +
+
+
+
-
- Proposal Map / Site Plan -
A visual representation of your proposal.
- -
+
+ Total Floor Area of Proposed Residence(s) +
+ + + + + -
- - Do you need to import any fill to construct or conduct the proposed non-adhering residential use? - -
Fill is any material brought onto the property, including gravel for construction.
- - Yes - No +
+ + + + + + + + + + + - -
- warning -
This field is required
-
- - - - -
-

Soil & Fill Components

-
-
- -
The Commission must approve any proposed fill. List all proposed types of fill.
- - - -
- warning -
This field is required
-
- Example: Aggregate, topsoil, structural fill, sand, gravel, etc -
Characters left: {{ 4000 - fillTypeToPlaceText.textLength }}
+
+ + + + + +
Proposed Residence{{ i + 1 }}Total Floor Area + {{ element.floorArea }} m2 + Description + {{ element.isExpanded ? element.description : getTruncatedDescription(element.description) }} + + {{ element.isExpanded ? 'Read Less' : 'Read More' }} + + Action + + +
Use the button below to add any proposed residence(s)
+
+ +
+ Use the button below to add any proposed residence(s)
+ + +
+ +
+ warning +
This field is required
+
-
-
- - - - -
- warning -
This field is required
-
-
Characters left: {{ 4000 - fillOriginToPlaceText.textLength }}
-
+
+ Proposal Map / Site Plan +
A visual representation of your proposal.
+ +
+ +
+ Detailed Building Plan(s) +
+ Building plans must be the most up to date, current version and should include (1) the total floor area of all + levels and intended use; and (2) interior and exterior views
+ +
+
-
-
- -
Length of time you anticipate it would take to complete the project
- - - -
+

Soil & Fill Components

+
+
+ +
+ The Commission must approve any proposed fill. List all proposed types of fill. + Prohibited fill - warning -
This field is required
-
- Example: 30 years; or 3 months; or 5 days -
Characters left: {{ 500 - (projectDuration.value || '').length }}
+ cannot be placed in the ALR.
+ + + +
+ warning +
This field is required
+
+ Example: Aggregate, topsoil, structural fill, sand, gravel, etc +
Characters left: {{ 4000 - fillTypeToPlaceText.textLength }}
+
- -
- + +
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/naru-proposal.component.scss b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/naru-proposal.component.scss index dafa0c82fd..e87fd2f97a 100644 --- a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/naru-proposal.component.scss +++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/naru-proposal.component.scss @@ -1,4 +1,5 @@ @use '../../../../../../styles/functions' as *; +@use '../../../../../../styles/colors'; section { margin-top: rem(36); @@ -18,3 +19,96 @@ section { :host::ng-deep .mat-mdc-radio-button label { font-weight: 400 !important; } + +.scrollable { + overflow-x: auto; +} + +.actions { + button:not(:last-child) { + margin-right: rem(8) !important; + } +} + +.no-data-text { + color: colors.$grey-dark; + text-align: center; + padding-top: 5px; +} + +.visible-count-container { + text-align: center; + margin: 12px 0; + font-size: 1.1rem; +} + +.no-data-container { + justify-content: center !important; +} + +td { + vertical-align: top; + padding-top: 10px; + padding-bottom: 10px; +} + +.description-column { + width: 40%; +} + +.description-data { + word-wrap: break-word; + white-space: normal; + overflow-wrap: break-word; + max-width: 40%; +} + +.siting-of-residences { + --mat-expansion-header-text-weight: bold; +} + +.siting-of-residences-content { + display: flex; + flex-direction: column; + gap: rem(24); +} + +.siting-of-residences-figures { + display: flex; + gap: rem(32); + flex-wrap: wrap; + justify-content: center; + min-width: 0; +} + +.siting-of-residences-figure { + margin: 0; +} + +.siting-of-residences-figure-caption { + text-align: center; + line-height: 1.5; + margin-bottom: rem(4); +} + +.siting-of-residences-figure-image { + display: block; +} + +.residence-btn { + padding-bottom: 10px; +} + +.error-field-outlined.ng-invalid { + border: 1px solid colors.$error-color !important; + + .mat-button-toggle { + border-color: colors.$error-color; + color: colors.$error-color !important; + } + + &.upload-button { + border: 2px solid colors.$error-color; + margin-bottom: 0 !important; + } +} diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/naru-proposal.component.ts b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/naru-proposal.component.ts index f874a8c5a8..a65b6f3634 100644 --- a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/naru-proposal.component.ts +++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/naru-proposal.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, HostListener, OnDestroy, OnInit } from '@angular/core'; import { FormControl, FormGroup, Validators } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { MatRadioChange } from '@angular/material/radio'; @@ -6,10 +6,7 @@ import { Router } from '@angular/router'; import { takeUntil } from 'rxjs'; import { ApplicationDocumentDto } from '../../../../../services/application-document/application-document.dto'; import { ApplicationDocumentService } from '../../../../../services/application-document/application-document.service'; -import { - ApplicationSubmissionUpdateDto, - NaruSubtypeDto, -} from '../../../../../services/application-submission/application-submission.dto'; +import { ApplicationSubmissionUpdateDto } from '../../../../../services/application-submission/application-submission.dto'; import { ApplicationSubmissionService } from '../../../../../services/application-submission/application-submission.service'; import { CodeService } from '../../../../../services/code/code.service'; import { ToastService } from '../../../../../services/toast/toast.service'; @@ -18,8 +15,15 @@ import { FileHandle } from '../../../../../shared/file-drag-drop/drag-drop.direc import { EditApplicationSteps } from '../../edit-submission.component'; import { FilesStepComponent } from '../../files-step.partial'; import { SoilTableData } from '../../../../../shared/soil-table/soil-table.component'; -import { ChangeSubtypeConfirmationDialogComponent } from './change-subtype-confirmation-dialog/change-subtype-confirmation-dialog.component'; import { ConfirmationDialogService } from '../../../../../shared/confirmation-dialog/confirmation-dialog.service'; +import { MatTableDataSource } from '@angular/material/table'; +import { ResidenceDialogComponent } from './residence-dialog/residence-dialog.component'; +import { MOBILE_BREAKPOINT } from '../../../../../shared/utils/breakpoints'; +import { isTruncated, truncate } from '../../../../../shared/utils/string-helper'; +import { EXISTING_RESIDENCE_DESCRIPTION_CHAR_LIMIT } from '../../../../../shared/constants'; + +export type FormExisingResidence = { id?: number; floorArea: number; description: string; isExpanded?: boolean }; +export type FormProposedResidence = { id?: number; floorArea: number; description: string; isExpanded?: boolean }; @Component({ selector: 'app-naru-proposal', @@ -30,62 +34,64 @@ export class NaruProposalComponent extends FilesStepComponent implements OnInit, currentStep = EditApplicationSteps.Proposal; showProposalMapVirus = false; + showBuildingPlanVirus = false; - previousSubtype: string | null = null; - subtype = new FormControl(null, [Validators.required]); + willBeOverFiveHundredM2 = new FormControl(null, [Validators.required]); + willRetainResidence = new FormControl(null, [Validators.required]); + willHaveAdditionalResidence = new FormControl(null, [Validators.required]); + willHaveTemporaryForeignWorkerHousing = new FormControl(null, [Validators.required]); + willImportFill = new FormControl(null, [Validators.required]); purpose = new FormControl(null, [Validators.required]); - floorArea = new FormControl(null, [Validators.required]); residenceNecessity = new FormControl(null, [Validators.required]); + tfwhCount = new FormControl(null, [Validators.required]); + tfwhDesign = new FormControl(null, [Validators.required]); + tfwhFarmSize = new FormControl(null, [Validators.required]); + clustered = new FormControl(null, [Validators.required]); + setback = new FormControl(null, [Validators.required]); locationRationale = new FormControl(null, [Validators.required]); infrastructure = new FormControl(null, [Validators.required]); - existingStructures = new FormControl(null, [Validators.required]); - sleepingUnits = new FormControl(null, [Validators.required]); - agriTourism = new FormControl(null, [Validators.required]); - willImportFill = new FormControl(null, [Validators.required]); fillType = new FormControl( { disabled: true, value: null, }, - [Validators.required] - ); - fillOrigin = new FormControl( - { - disabled: true, - value: null, - }, - [Validators.required] - ); - projectDuration = new FormControl( - { - disabled: true, - value: null, - }, - [Validators.required] + [Validators.required], ); + existingResidences: FormExisingResidence[] = []; + existingResidencesSource = new MatTableDataSource(this.existingResidences); + proposedResidences: FormExisingResidence[] = []; + proposedResidencesSource = new MatTableDataSource(this.proposedResidences); proposalMap: ApplicationDocumentDto[] = []; + buildingPlans: ApplicationDocumentDto[] = []; fillTableData: SoilTableData = {}; fillTableDisabled = true; + isMobile = window.innerWidth <= MOBILE_BREAKPOINT; + isExistingResidencesDirty = false; + isProposedResidencesDirty = false; + proposedResidencesRequired = true; form = new FormGroup({ - subtype: this.subtype, + willBeOverFiveHundredM2: this.willBeOverFiveHundredM2, + willRetainResidence: this.willRetainResidence, + willHaveAdditionalResidence: this.willHaveAdditionalResidence, + willHaveTemporaryForeignWorkerHousing: this.willHaveTemporaryForeignWorkerHousing, + willImportFill: this.willImportFill, purpose: this.purpose, - floorArea: this.floorArea, residenceNecessity: this.residenceNecessity, + tfwhCount: this.tfwhCount, + tfwhDesign: this.tfwhDesign, + tfwhFarmSize: this.tfwhFarmSize, + clustered: this.clustered, + setback: this.setback, locationRationale: this.locationRationale, infrastructure: this.infrastructure, - existingStructures: this.existingStructures, - willImportFill: this.willImportFill, fillType: this.fillType, - fillOrigin: this.fillOrigin, - projectDuration: this.projectDuration, - sleepingUnits: this.sleepingUnits, - agriTourism: this.agriTourism, }); private submissionUuid = ''; - naruSubtypes: NaruSubtypeDto[] = []; + existingResidencesDisplayedColumns: string[] = ['index', 'floorArea', 'description', 'action']; + proposedResidencesDisplayedColumns: string[] = ['index', 'floorArea', 'description', 'action']; constructor( private router: Router, @@ -94,36 +100,34 @@ export class NaruProposalComponent extends FilesStepComponent implements OnInit, applicationDocumentService: ApplicationDocumentService, dialog: MatDialog, private confirmationDialogService: ConfirmationDialogService, - toastService: ToastService + toastService: ToastService, ) { super(applicationDocumentService, dialog, toastService); } ngOnInit(): void { - this.loadNaruSubtypes(); this.$applicationSubmission.pipe(takeUntil(this.$destroy)).subscribe((applicationSubmission) => { if (applicationSubmission) { this.fileId = applicationSubmission.fileNumber; this.submissionUuid = applicationSubmission.uuid; this.form.patchValue({ - subtype: applicationSubmission.naruSubtype?.code, - existingStructures: applicationSubmission.naruExistingStructures, + willBeOverFiveHundredM2: applicationSubmission.naruWillBeOverFiveHundredM2, + willRetainResidence: applicationSubmission.naruWillRetainResidence, + willHaveAdditionalResidence: applicationSubmission.naruWillHaveAdditionalResidence, + willHaveTemporaryForeignWorkerHousing: applicationSubmission.naruWillHaveTemporaryForeignWorkerHousing, willImportFill: applicationSubmission.naruWillImportFill, + purpose: applicationSubmission.purpose, + residenceNecessity: applicationSubmission.naruResidenceNecessity, + tfwhCount: applicationSubmission.tfwhCount, + tfwhDesign: applicationSubmission.tfwhDesign, + tfwhFarmSize: applicationSubmission.tfwhFarmSize, + clustered: applicationSubmission.naruClustered, + setback: applicationSubmission.naruSetback, fillType: applicationSubmission.naruFillType, - fillOrigin: applicationSubmission.naruFillOrigin, - floorArea: applicationSubmission.naruFloorArea ? applicationSubmission.naruFloorArea.toString() : null, infrastructure: applicationSubmission.naruInfrastructure, locationRationale: applicationSubmission.naruLocationRationale, - projectDuration: applicationSubmission.naruProjectDuration, - purpose: applicationSubmission.purpose, - residenceNecessity: applicationSubmission.naruResidenceNecessity, - agriTourism: applicationSubmission.naruAgriTourism, - sleepingUnits: applicationSubmission.naruSleepingUnits - ? applicationSubmission.naruSleepingUnits.toString() - : null, }); - this.previousSubtype = applicationSubmission.naruSubtype?.code ?? null; if (applicationSubmission.naruWillImportFill !== null) { this.onChangeFill(applicationSubmission.naruWillImportFill); @@ -133,12 +137,31 @@ export class NaruProposalComponent extends FilesStepComponent implements OnInit, } this.fillTableData = { - volume: applicationSubmission.naruToPlaceVolume ?? undefined, area: applicationSubmission.naruToPlaceArea ?? undefined, maximumDepth: applicationSubmission.naruToPlaceMaximumDepth ?? undefined, averageDepth: applicationSubmission.naruToPlaceAverageDepth ?? undefined, }; + if (applicationSubmission.naruExistingResidences) { + this.existingResidences = applicationSubmission.naruExistingResidences?.map((item, index) => ({ + id: index + 1, + floorArea: item.floorArea, + description: item.description, + isExpanded: false, + })); + this.existingResidencesSource = new MatTableDataSource(this.existingResidences); + } + + if (applicationSubmission.naruProposedResidences) { + this.proposedResidences = applicationSubmission.naruProposedResidences?.map((item, index) => ({ + id: index + 1, + floorArea: item.floorArea, + description: item.description, + isExpanded: false, + })); + this.proposedResidencesSource = new MatTableDataSource(this.proposedResidences); + } + if (this.showErrors) { this.form.markAllAsTouched(); } @@ -147,6 +170,7 @@ export class NaruProposalComponent extends FilesStepComponent implements OnInit, this.$applicationDocuments.pipe(takeUntil(this.$destroy)).subscribe((documents) => { this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP); + this.buildingPlans = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.BUILDING_PLAN); }); } @@ -159,32 +183,92 @@ export class NaruProposalComponent extends FilesStepComponent implements OnInit, this.showProposalMapVirus = !res; } - onChangeSubtype($event: MatRadioChange) { - if (this.previousSubtype) { - this.dialog - .open(ChangeSubtypeConfirmationDialogComponent) - .beforeClosed() - .subscribe((didConfirm) => { - if (didConfirm) { - this.previousSubtype = $event.value; - } else { - this.subtype.setValue(this.previousSubtype); + async attachBuildingPlan(file: FileHandle) { + const res = await this.attachFile(file, DOCUMENT_TYPE.BUILDING_PLAN); + this.showBuildingPlanVirus = !res; + } + + onChangeOver500m2(answerIsYes: boolean) { + if ( + !answerIsYes && + this.residenceNecessity.value && + this.willHaveAdditionalResidence.value !== true && + this.willHaveTemporaryForeignWorkerHousing.value !== true + ) { + this.confirmationDialogService + .openDialog({ + title: 'Is your proposal for a principal residence with a total floor area greater than 500 m²?', + body: 'Warning: Changing your answer could remove some content already saved to this page. Do you want to continue?', + }) + .subscribe((confirmed) => { + this.willBeOverFiveHundredM2.setValue(!confirmed); + + if (confirmed) { + this.residenceNecessity.setValue(null); + } + }); + } + } + + onChangeAdditional(answerIsYes: boolean) { + if ( + !answerIsYes && + this.residenceNecessity.value && + this.willBeOverFiveHundredM2.value !== true && + this.willHaveTemporaryForeignWorkerHousing.value !== true + ) { + this.confirmationDialogService + .openDialog({ + title: 'Is your proposal for an additional residence?', + body: 'Warning: Changing your answer could remove some content already saved to this page. Do you want to continue?', + }) + .subscribe((confirmed) => { + this.willHaveAdditionalResidence.setValue(!confirmed); + + if (confirmed) { + this.residenceNecessity.setValue(null); + } + }); + } + } + + onChangeTemporaryHousing(answerIsYes: boolean) { + if ( + !answerIsYes && + (this.tfwhCount.value || + this.tfwhDesign.value !== null || + this.tfwhFarmSize.value || + (this.residenceNecessity.value && + this.willBeOverFiveHundredM2.value !== true && + this.willHaveAdditionalResidence.value !== true)) + ) { + this.confirmationDialogService + .openDialog({ + title: 'Is your proposal for temporary foreign worker housing?', + body: 'Warning: Changing your answer could remove some content already saved to this page. Do you want to continue?', + }) + .subscribe((confirmed) => { + this.willHaveTemporaryForeignWorkerHousing.setValue(!confirmed); + + if (confirmed) { + this.tfwhCount.setValue(null); + this.tfwhDesign.setValue(null); + this.tfwhFarmSize.setValue(null); + + if (this.willBeOverFiveHundredM2.value !== true && this.willHaveAdditionalResidence.value !== true) { + this.residenceNecessity.setValue(null); + } } }); - } else { - this.previousSubtype = $event.value; } } onChangeFill(willImportFill: boolean) { const hasValues = - this.projectDuration.value || - this.fillOrigin.value || this.fillType.value || this.fillTableData.area || this.fillTableData.averageDepth || - this.fillTableData.maximumDepth || - this.fillTableData.volume; + this.fillTableData.maximumDepth; if (!willImportFill && hasValues) { this.confirmationDialogService @@ -205,69 +289,174 @@ export class NaruProposalComponent extends FilesStepComponent implements OnInit, this.fillTableDisabled = !willImportFill; if (willImportFill) { - this.projectDuration.enable(); - this.fillOrigin.enable(); this.fillType.enable(); } else { - this.projectDuration.disable(); - this.fillOrigin.disable(); this.fillType.disable(); - this.projectDuration.setValue(null); - this.fillOrigin.setValue(null); this.fillType.setValue(null); } } protected async save() { - if (this.fileId && this.form.dirty) { + if (this.fileId && (this.form.dirty || this.isExistingResidencesDirty || this.isProposedResidencesDirty)) { const { - existingStructures, + willBeOverFiveHundredM2, + willRetainResidence, + willHaveAdditionalResidence, + willHaveTemporaryForeignWorkerHousing, willImportFill, + purpose, + residenceNecessity, + tfwhCount, + tfwhDesign, + tfwhFarmSize, + clustered, + setback, fillType, - fillOrigin, - floorArea, infrastructure, locationRationale, - projectDuration, - purpose, - residenceNecessity, - subtype, - sleepingUnits, - agriTourism, } = this.form.getRawValue(); const updateDto: ApplicationSubmissionUpdateDto = { - naruExistingStructures: existingStructures, + naruWillBeOverFiveHundredM2: willBeOverFiveHundredM2, + naruWillRetainResidence: willRetainResidence, + naruWillHaveAdditionalResidence: willHaveAdditionalResidence, + naruWillHaveTemporaryForeignWorkerHousing: willHaveTemporaryForeignWorkerHousing, naruWillImportFill: willImportFill, + purpose: purpose, + naruResidenceNecessity: residenceNecessity, + tfwhCount: tfwhCount, + tfwhDesign: tfwhDesign, + tfwhFarmSize: tfwhFarmSize, + naruClustered: clustered, + naruSetback: setback, naruFillType: fillType, - naruFillOrigin: fillOrigin, naruToPlaceAverageDepth: this.fillTableData.averageDepth ?? null, naruToPlaceMaximumDepth: this.fillTableData.maximumDepth ?? null, naruToPlaceArea: this.fillTableData.area ?? null, - naruToPlaceVolume: this.fillTableData.volume ?? null, - naruFloorArea: floorArea ? parseFloat(floorArea) : null, naruInfrastructure: infrastructure, naruLocationRationale: locationRationale, - naruProjectDuration: projectDuration, - purpose: purpose, - naruResidenceNecessity: residenceNecessity, - naruSubtypeCode: subtype, - naruSleepingUnits: sleepingUnits ? parseFloat(sleepingUnits) : null, - naruAgriTourism: agriTourism, + naruExistingResidences: this.existingResidences.map(({ id, ...rest }) => rest), + naruProposedResidences: this.proposedResidences.map(({ id, ...rest }) => rest), }; - const updatedApp = await this.applicationSubmissionService.updatePending(this.submissionUuid, updateDto); this.$applicationSubmission.next(updatedApp); } } - private async loadNaruSubtypes() { - const subtypes = await this.codeService.loadCodes(); - this.naruSubtypes = subtypes.naruSubtypes; - } - markDirty() { this.form.markAsDirty(); } + + onAddEditResidence( + isExistingResidence: boolean, + residence: FormExisingResidence | FormProposedResidence | undefined, + isEdit: boolean, + ) { + const dialog = this.dialog + .open(ResidenceDialogComponent, { + width: this.isMobile ? '90%' : '75%', + data: { + isEdit: isEdit, + residenceData: residence, + isExisting: isExistingResidence, + }, + }) + .afterClosed() + .subscribe(async (res) => { + if (!res.isCancel) { + if (isExistingResidence) { + this.isExistingResidencesDirty = true; + if (res.isEdit) { + const index = this.existingResidences.findIndex((e) => e.id === res.residence.id); + if (index > -1) { + this.existingResidences[index] = res.residence; + } + } else { + this.existingResidences.push({ ...res.residence, id: this.existingResidences.length + 1 }); + } + this.existingResidencesSource.data = this.existingResidences; + } else { + this.isProposedResidencesDirty = true; + if (res.isEdit) { + const index = this.proposedResidences.findIndex((e) => e.id === res.residence.id); + if (index > -1) { + this.proposedResidences[index] = res.residence; + } + } else { + this.proposedResidences.push({ ...res.residence, id: this.proposedResidences.length + 1 }); + this.proposedResidencesRequired = false; + } + this.proposedResidencesSource.data = this.proposedResidences; + } + } + }); + } + + onDeleteResidence(isExistingResidence: boolean, residence: FormExisingResidence | FormProposedResidence) { + if (isExistingResidence) { + this.confirmationDialogService + .openDialog({ title: 'Remove existing residence?', body: 'Do you want to continue?' }) + .subscribe((confirmed) => { + if (confirmed) { + const index = this.existingResidences.findIndex((e) => e.id === residence.id); + if (index > -1) { + this.existingResidences.splice(index, 1); + this.existingResidencesSource.data = this.existingResidences; + this.isExistingResidencesDirty = true; + this.existingResidences.forEach((item, index) => { + item.id = index + 1; + }); + } + } + }); + } else { + this.confirmationDialogService + .openDialog({ title: 'Remove proposed residence?', body: 'Do you want to continue?' }) + .subscribe((confirmed) => { + if (confirmed) { + const index = this.proposedResidences.findIndex((e) => e.id === residence.id); + if (index > -1) { + this.proposedResidences.splice(index, 1); + this.proposedResidencesSource.data = this.proposedResidences; + this.isProposedResidencesDirty = true; + this.proposedResidences.forEach((item, index) => { + item.id = index + 1; + }); + + if (this.proposedResidences.length === 0) { + this.proposedResidencesRequired = true; + } + } + } + }); + } + } + + getTruncatedDescription(description: string): string { + return truncate(description, EXISTING_RESIDENCE_DESCRIPTION_CHAR_LIMIT); + } + + isDescriptionTruncated(description: string): boolean { + return isTruncated(description, EXISTING_RESIDENCE_DESCRIPTION_CHAR_LIMIT); + } + + toggleReadMore(isExistingResidence: boolean, residence: FormExisingResidence | FormProposedResidence) { + if (isExistingResidence) { + const index = this.existingResidences.findIndex((e) => e.id === residence.id); + if (index > -1) { + this.existingResidences[index].isExpanded = !this.existingResidences[index].isExpanded; + } + } else { + const index = this.proposedResidences.findIndex((e) => e.id === residence.id); + if (index > -1) { + this.proposedResidences[index].isExpanded = !this.proposedResidences[index].isExpanded; + } + } + } + + @HostListener('window:resize', ['$event']) + onWindowResize() { + this.isMobile = window.innerWidth <= MOBILE_BREAKPOINT; + } } diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/residence-dialog/residence-dialog.component.html b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/residence-dialog/residence-dialog.component.html new file mode 100644 index 0000000000..af66171a21 --- /dev/null +++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/residence-dialog/residence-dialog.component.html @@ -0,0 +1,91 @@ +
+

+ Add Existing Residence + Add Proposed Residence +

+

+ Edit Existing Residence + Edit Proposed Residence +

+
+
+
+
+
+
+ +
+
Include the basement and any attached garage
+ + + m2 + +
+ warning +
This field is required
+
+ This field must be a non-zero number with no more than 2 decimal places. +
+
+
+ +
+
+ +
+
Include if it has an attached garage or basement
+ + + +
Characters left: {{ 4000 - description.value?.length! }}
+
+ warning +
This field is required
+
+
+
+
+
+ +
+ + + +
+
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/residence-dialog/residence-dialog.component.scss b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/residence-dialog/residence-dialog.component.scss new file mode 100644 index 0000000000..590346d8a1 --- /dev/null +++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/residence-dialog/residence-dialog.component.scss @@ -0,0 +1,132 @@ +@use '../../../../../../../styles/functions' as *; +@use '../../../../../../../styles/colors'; + +.actions { + display: flex; + padding: rem(16) rem(24); + flex-direction: column-reverse; + gap: rem(8); + + @media screen and (min-width: $tabletBreakpoint) { + flex-direction: unset; + gap: unset; + margin-top: unset; + } +} + +.btn-group { + width: 100%; + display: flex; + gap: rem(16); + + button { + flex: 1 1 auto; + } + + @media screen and (min-width: $tabletBreakpoint) { + width: unset; + + button { + flex: unset; + } + } +} + +:host::ng-deep { + .warning-banner { + padding: 0.5rem !important; + } +} + +.mat-button-toggle-checked.mat-button-toggle-appearance-standard { + background-color: colors.$primary-color-light; +} + +:host::ng-deep { + .field-error { + color: colors.$error-color; + font-size: rem(15); + font-weight: 700; + display: flex; + align-items: center; + margin-top: rem(4); + } +} + +.delete-btn { + order: -1; + margin-right: auto !important; + width: 100%; + + @media screen and (min-width: $tabletBreakpoint) { + width: unset; + } +} + +.warning-icon { + padding-right: 27px; +} + +.form-container { + display: flex; + flex-wrap: wrap; + flex-direction: column; + gap: 25px; + + .form-field-floor-area { + flex: 1 1 50%; + box-sizing: border-box; + display: grid; + flex-direction: column; + align-items: flex-start; + width: 40%; + } + + .form-field-description { + flex: 1 1 100%; + box-sizing: border-box; + display: grid; + flex-direction: column; + align-items: flex-start; + } + + @media screen and (max-width: $tabletBreakpoint) { + gap: 10px; + .form-field-floor-area { + width: 100%; + flex: 1 1 100%; + margin: 0 5px; + } + } +} + +.button-container { + display: flex; + flex-direction: row-reverse; + gap: 15px; + margin: 0 15px 10px 0; + button { + flex: 0 0 100px; + padding: 10px 10px; + } + + @media screen and (max-width: $tabletBreakpoint) { + button { + flex: 1 1 48%; + } + } +} + +.label { + display: flex; + flex-direction: column; + justify-content: center; + + @media screen and (min-width: $tabletBreakpoint) { + margin-bottom: 0; + } + + .subtext { + margin-bottom: rem(-8) !important; + } +} diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/residence-dialog/residence-dialog.component.ts b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/residence-dialog/residence-dialog.component.ts new file mode 100644 index 0000000000..808a01f74c --- /dev/null +++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/naru-proposal/residence-dialog/residence-dialog.component.ts @@ -0,0 +1,56 @@ +import { ChangeDetectionStrategy, Component, Inject, Input, OnInit } from '@angular/core'; +import { FormControl, FormGroup, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { FormExisingResidence, FormProposedResidence } from '../naru-proposal.component'; + +@Component({ + selector: 'app-residence-dialog', + templateUrl: './residence-dialog.component.html', + styleUrl: './residence-dialog.component.scss', +}) +export class ResidenceDialogComponent implements OnInit { + floorArea = new FormControl(null, [ + Validators.required, + Validators.pattern(/^(?!0(\.0{1,2})?$)\d+(\.\d{1,2})?$/), + ]); + description = new FormControl(null, [Validators.required]); + form = new FormGroup({ + floorArea: this.floorArea, + description: this.description, + }); + + isSaving: boolean = false; + residence: FormExisingResidence | FormProposedResidence = { floorArea: 0, description: '', isExpanded: false }; + + constructor( + private dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) + public data: { + isEdit?: boolean; + isExisting?: boolean; + residenceData?: FormExisingResidence | FormProposedResidence; + }, + ) {} + + ngOnInit(): void { + if (this.data.residenceData) { + this.floorArea.setValue(this.data.residenceData.floorArea!.toString()); + this.description.setValue(this.data.residenceData.description!); + this.residence = { ...this.data.residenceData }; + } + } + + onSaveAdd() { + if (this.form.valid) { + this.residence.description = this.description.value!; + this.residence.floorArea = Number(this.floorArea.value!); + this.dialogRef.close({ isCancel: false, isEdit: this.data.isEdit, residence: this.residence }); + } else { + this.form.markAllAsTouched(); + } + } + + onCancel() { + this.dialogRef.close({ isCancel: true }); + } +} diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/nfu-proposal/nfu-proposal.component.html b/portal-frontend/src/app/features/applications/edit-submission/proposal/nfu-proposal/nfu-proposal.component.html index e1df7a7324..f21a41495c 100644 --- a/portal-frontend/src/app/features/applications/edit-submission/proposal/nfu-proposal/nfu-proposal.component.html +++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/nfu-proposal/nfu-proposal.component.html @@ -156,7 +156,13 @@

Soil & Fill Components

-
The Commission must approve any proposed fill. List all proposed types of fill.
+
+ The Commission must approve any proposed fill. List all proposed types of fill. + Prohibited fill + cannot be placed in the ALR. +
- -
- warning -
This field is required
-
-
Characters left: {{ 4000 - fillOriginToPlaceText.textLength }}
-
-
- -
-
- -
Length of time you anticipate it would take to complete the project
- - - -
- warning -
This field is required
-
- Example: 30 years; or 3 months; or 5 days -
Characters left: {{ 500 - (projectDuration.value || '').length }}
-
-
- diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/nfu-proposal/nfu-proposal.component.ts b/portal-frontend/src/app/features/applications/edit-submission/proposal/nfu-proposal/nfu-proposal.component.ts index 7cbad0f733..09fd87a73c 100644 --- a/portal-frontend/src/app/features/applications/edit-submission/proposal/nfu-proposal/nfu-proposal.component.ts +++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/nfu-proposal/nfu-proposal.component.ts @@ -32,26 +32,12 @@ export class NfuProposalComponent extends FilesStepComponent implements OnInit, outsideLands = new FormControl(null, [Validators.required]); agricultureSupport = new FormControl(null, [Validators.required]); willImportFill = new FormControl(null, [Validators.required]); - projectDuration = new FormControl( - { - disabled: true, - value: null, - }, - [Validators.required] - ); fillTypeDescription = new FormControl( { disabled: true, value: null, }, - [Validators.required] - ); - fillOriginDescription = new FormControl( - { - disabled: true, - value: null, - }, - [Validators.required] + [Validators.required], ); form = new FormGroup({ @@ -60,9 +46,7 @@ export class NfuProposalComponent extends FilesStepComponent implements OnInit, outsideLands: this.outsideLands, agricultureSupport: this.agricultureSupport, willImportFill: this.willImportFill, - projectDuration: this.projectDuration, fillTypeDescription: this.fillTypeDescription, - fillOriginDescription: this.fillOriginDescription, }); private submissionUuid = ''; proposalMap: ApplicationDocumentDto[] = []; @@ -73,7 +57,7 @@ export class NfuProposalComponent extends FilesStepComponent implements OnInit, applicationDocumentService: ApplicationDocumentService, dialog: MatDialog, private confirmationDialogService: ConfirmationDialogService, - toastService: ToastService + toastService: ToastService, ) { super(applicationDocumentService, dialog, toastService); } @@ -89,13 +73,10 @@ export class NfuProposalComponent extends FilesStepComponent implements OnInit, purpose: applicationSubmission.purpose, outsideLands: applicationSubmission.nfuOutsideLands, agricultureSupport: applicationSubmission.nfuAgricultureSupport, - projectDuration: applicationSubmission.nfuProjectDuration, fillTypeDescription: applicationSubmission.nfuFillTypeDescription, - fillOriginDescription: applicationSubmission.nfuFillOriginDescription, }); this.fillTableData = { - volume: applicationSubmission.nfuFillVolume ?? undefined, area: applicationSubmission.nfuTotalFillArea ?? undefined, maximumDepth: applicationSubmission.nfuMaxFillDepth ?? undefined, averageDepth: applicationSubmission.nfuAverageFillDepth ?? undefined, @@ -133,9 +114,7 @@ export class NfuProposalComponent extends FilesStepComponent implements OnInit, const nfuOutsideLands = this.outsideLands.getRawValue(); const nfuAgricultureSupport = this.agricultureSupport.getRawValue(); const nfuWillImportFill = this.willImportFill.getRawValue(); - const nfuProjectDuration = this.projectDuration.getRawValue(); const nfuFillTypeDescription = this.fillTypeDescription.getRawValue(); - const nfuFillOriginDescription = this.fillOriginDescription.getRawValue(); const updateDto: ApplicationSubmissionUpdateDto = { nfuHectares: nfuHectares ? parseFloat(nfuHectares) : null, @@ -146,10 +125,7 @@ export class NfuProposalComponent extends FilesStepComponent implements OnInit, nfuTotalFillArea: this.fillTableData.area ?? null, nfuMaxFillDepth: this.fillTableData.maximumDepth ?? null, nfuAverageFillDepth: this.fillTableData.averageDepth ?? null, - nfuFillVolume: this.fillTableData.volume ?? null, - nfuProjectDuration, nfuFillTypeDescription, - nfuFillOriginDescription, }; const updatedApp = await this.applicationSubmissionService.updatePending(this.submissionUuid, updateDto); @@ -159,13 +135,10 @@ export class NfuProposalComponent extends FilesStepComponent implements OnInit, onChangeFill(willImportFill: boolean) { const hasValues = - this.projectDuration.value || - this.fillOriginDescription.value || this.fillTypeDescription.value || this.fillTableData.area || this.fillTableData.averageDepth || - this.fillTableData.maximumDepth || - this.fillTableData.volume; + this.fillTableData.maximumDepth; if (!willImportFill && hasValues) { this.confirmationDialogService @@ -186,16 +159,10 @@ export class NfuProposalComponent extends FilesStepComponent implements OnInit, this.fillTableDisabled = !willImportFill; if (willImportFill) { - this.projectDuration.enable(); - this.fillOriginDescription.enable(); this.fillTypeDescription.enable(); } else { - this.projectDuration.disable(); - this.fillOriginDescription.disable(); this.fillTypeDescription.disable(); - this.projectDuration.setValue(null); - this.fillOriginDescription.setValue(null); this.fillTypeDescription.setValue(null); } } diff --git a/portal-frontend/src/app/features/applications/review-submission/return-application-dialog/return-application-dialog.component.html b/portal-frontend/src/app/features/applications/review-submission/return-application-dialog/return-application-dialog.component.html index b3cf10b4e7..c6085c4478 100644 --- a/portal-frontend/src/app/features/applications/review-submission/return-application-dialog/return-application-dialog.component.html +++ b/portal-frontend/src/app/features/applications/review-submission/return-application-dialog/return-application-dialog.component.html @@ -60,16 +60,23 @@

Reason for Return

Characters left: {{ 4000 - comment.textLength }} +
+ warning +
This field is required
+
diff --git a/portal-frontend/src/app/features/applications/review-submission/return-application-dialog/return-application-dialog.component.scss b/portal-frontend/src/app/features/applications/review-submission/return-application-dialog/return-application-dialog.component.scss index 5c9b16b19e..066039b9ab 100644 --- a/portal-frontend/src/app/features/applications/review-submission/return-application-dialog/return-application-dialog.component.scss +++ b/portal-frontend/src/app/features/applications/review-submission/return-application-dialog/return-application-dialog.component.scss @@ -69,6 +69,7 @@ } .comment-input { + font-size: rem(16); resize: none; margin-top: rem(4); border: 1px solid rgba(0, 0, 0, 0.42); @@ -77,3 +78,9 @@ height: rem(120); width: 100%; } + +.field-error { + color: colors.$error-color; + display: flex; + align-items: center; +} diff --git a/portal-frontend/src/app/features/applications/review-submission/return-application-dialog/return-application-dialog.component.ts b/portal-frontend/src/app/features/applications/review-submission/return-application-dialog/return-application-dialog.component.ts index 31da37f008..d3aec937b9 100644 --- a/portal-frontend/src/app/features/applications/review-submission/return-application-dialog/return-application-dialog.component.ts +++ b/portal-frontend/src/app/features/applications/review-submission/return-application-dialog/return-application-dialog.component.ts @@ -25,6 +25,8 @@ export class ReturnApplicationDialogComponent implements OnInit { stepIdx = 0; applicantComment = ''; + showError: boolean = false; + constructor( private dialogRef: MatDialogRef, private applicationReviewService: ApplicationSubmissionReviewService, @@ -53,6 +55,11 @@ export class ReturnApplicationDialogComponent implements OnInit { } async next() { + if (this.stepIdx === 1 && this.applicantComment === '') { + this.showError = true; + return; + } + this.stepIdx += 1; } diff --git a/portal-frontend/src/app/features/create-submission-dialog/create-submission-dialog.component.scss b/portal-frontend/src/app/features/create-submission-dialog/create-submission-dialog.component.scss index 5eefdcbdd3..cafa0d2c29 100644 --- a/portal-frontend/src/app/features/create-submission-dialog/create-submission-dialog.component.scss +++ b/portal-frontend/src/app/features/create-submission-dialog/create-submission-dialog.component.scss @@ -64,7 +64,7 @@ ul { } .srw-list { - margin-left: rem(-24); + margin-left: rem(-16); margin-bottom: 0; li { diff --git a/portal-frontend/src/app/features/public/application/submission/naru-details/naru-details.component.html b/portal-frontend/src/app/features/public/application/submission/naru-details/naru-details.component.html index d19c9a205e..fc54d54ae4 100644 --- a/portal-frontend/src/app/features/public/application/submission/naru-details/naru-details.component.html +++ b/portal-frontend/src/app/features/public/application/submission/naru-details/naru-details.component.html @@ -1,10 +1,46 @@
-
Selected Subtype:
+
+ Is your proposal for a principal residence with a total floor area greater than 500 m2? +
+
+ {{ + applicationSubmission.naruWillBeOverFiveHundredM2 ? 'Yes' : 'No' + }} + +
+ +
Is your proposal to retain an existing residence while building a new residence?
+
+ {{ + applicationSubmission.naruWillRetainResidence ? 'Yes' : 'No' + }} + +
+ +
Is your proposal for an additional residence?
- - {{ applicationSubmission.naruSubtype.label }} - - + {{ + applicationSubmission.naruWillHaveAdditionalResidence ? 'Yes' : 'No' + }} + +
+ +
Is your proposal for temporary foreign worker housing?
+
+ {{ + applicationSubmission.naruWillHaveTemporaryForeignWorkerHousing ? 'Yes' : 'No' + }} + +
+ +
+ Do you need to import any fill to construct or conduct the proposed non-adhering residential use? +
+
+ {{ + applicationSubmission.naruWillImportFill ? 'Yes' : 'No' + }} +
What is the purpose of the proposal?
@@ -13,126 +49,122 @@
- +
- What is the total floor area (m2) of the proposed additional residence? -
-
- {{ applicationSubmission.naruFloorArea }} m2 - -
- -
- Describe the necessity for an additional residence for farm use and how it will support agriculture in the short - or long term. + Is your proposal necessary for farm use? If so, please explain + what the temporary foreign workers will be doing on the farm.
{{ applicationSubmission.naruResidenceNecessity }}
- -
Describe the rationale for the proposed location of the additional residence.
-
- {{ applicationSubmission.naruLocationRationale }} - -
- -
- Provide the total area (m2) and a description of infrastructure necessary to support the additional - residence. -
-
- {{ applicationSubmission.naruInfrastructure }} - -
- -
- What is the total floor area (m2) of the proposed principal residence? -
+ +
How many temporary foreign workers will be housed by the proposal?
- {{ applicationSubmission.naruFloorArea }} m2 - + {{ applicationSubmission.tfwhCount }} +
- Describe how the proposal for a principal residence more than 500 m2 will support agriculture in the - short or long term. + Will the temporary foreign worker housing be designed to move from one place to another?
- {{ applicationSubmission.naruResidenceNecessity }} - -
- -
Describe the rationale for the proposed location of the principal residence.
-
- {{ applicationSubmission.naruLocationRationale }} - + {{ applicationSubmission.tfwhDesign ? 'Yes' : 'No' }} +
- Provide the total area (m2) and a description of infrastructure necessary to support the additional - residence. + What is the size (in hectares) of the farm operation that the temporary foreign workers will be supporting?
- {{ applicationSubmission.naruInfrastructure }} - + {{ applicationSubmission.tfwhFarmSize }} +
- -
What is the total floor area (m2) of the proposed accommodation?
-
- {{ applicationSubmission.naruFloorArea }} m2 - -
+
+ Will the proposed residence(s) be clustered with existing residential structures? Please explain. +
+
+ {{ applicationSubmission.naruClustered }} + +
-
How many "sleeping units" in total are proposed?
-
- {{ applicationSubmission.naruSleepingUnits }} - -
+
+ Will the proposed residence(s) be located within a 60 m setback from the front lot line? Please explain. +
+
+ {{ applicationSubmission.naruSetback }} + +
-
- Describe how the proposal for tourism accommodation will support agriculture in the short or long term. -
-
- {{ applicationSubmission.naruResidenceNecessity }} - -
+
+ Where on the parcel will the proposal be situated and is there an agricultural rationale for the proposed location? +
+
+ {{ applicationSubmission.naruLocationRationale }} + +
-
Describe the rationale for the proposed location of the tourism accommodation.
-
- {{ applicationSubmission.naruLocationRationale }} - -
+
+ Describe any infrastructure required to support the proposed residence(s) and the approximate area (m2) + required for that infrastructure +
+
+ {{ applicationSubmission.naruInfrastructure }} + +
-
- Provide the total area (m2) and a description of infrastructure necessary to support the tourism - accommodation. -
-
- {{ applicationSubmission.naruInfrastructure }} - + +
+
Existing Residence
+
Total Floor Area
+
Description
+ +
+ +
+
+ +
+ {{ i + 1 }} +
+
+ {{ existingResidence.floorArea }} m2 +
+
{{ existingResidence.description }}
+
+
-
Describe any agri-tourism that is currently taking place on the property.
-
- {{ applicationSubmission.naruAgriTourism }} - + +
+
Proposed Residence
+
Total Floor Area
+
Description
+ +
+ {{ i + 1 }} +
+
+ {{ proposedResidence.floorArea }} m2 +
+
{{ proposedResidence.description }}
+
-
- Describe the total floor area (m2), type, number, and occupancy of all residential structures currently - located on the property. -
-
- {{ applicationSubmission.naruExistingStructures }} - -
-
Proposal Map / Site Plan
-
- Do you need to import any fill to construct or conduct the proposed non-adhering residential use? -
-
- {{ - applicationSubmission.naruWillImportFill ? 'Yes' : 'No' - }} - -
+ +
Detailed Building Plans
+
+
Describe the type and amount of fill proposed to be placed.
@@ -158,29 +190,9 @@
-
Briefly describe the origin and quality of fill.
-
- {{ applicationSubmission.naruFillOrigin }} - -
- -
Project Duration
-
-
- {{ applicationSubmission.naruProjectDuration }} -
- -
-
Fill to be Placed
-
Volume
-
- {{ applicationSubmission.naruToPlaceVolume }} - m3 - -
Area
{{ applicationSubmission.naruToPlaceArea }} @@ -199,38 +211,5 @@ m
- -
-
-
Fill to be Placed
- -
Volume
-
- {{ applicationSubmission.naruToPlaceVolume }} - m3 - -
- -
Area
-
- {{ applicationSubmission.naruToPlaceArea }} - m2 - -
- -
Maximum Depth
-
- {{ applicationSubmission.naruToPlaceMaximumDepth }} - m - -
- -
Average Depth
-
- {{ applicationSubmission.naruToPlaceAverageDepth }} - m - -
-
diff --git a/portal-frontend/src/app/features/public/application/submission/naru-details/naru-details.component.scss b/portal-frontend/src/app/features/public/application/submission/naru-details/naru-details.component.scss index 9999107edd..1133f57b42 100644 --- a/portal-frontend/src/app/features/public/application/submission/naru-details/naru-details.component.scss +++ b/portal-frontend/src/app/features/public/application/submission/naru-details/naru-details.component.scss @@ -1,24 +1,39 @@ @use '../../../../../../styles/functions' as *; .soil-table { - display: grid; - overflow-x: auto; - grid-column-gap: rem(36); - grid-row-gap: rem(12); - grid-template-columns: max-content max-content; - - @media screen and (min-width: $tabletBreakpoint) { - grid-template-columns: 0.55fr 1fr; - } - - @media screen and (min-width: $midBreakpoint) { - grid-template-columns: 0.95fr 3fr; - grid-column-gap: rem(16); - } + display: grid; + overflow-x: auto; + grid-column-gap: rem(36); + grid-row-gap: rem(12); + grid-template-columns: max-content max-content; + + @media screen and (min-width: $tabletBreakpoint) { + grid-template-columns: 0.55fr 1fr; + } + + @media screen and (min-width: $midBreakpoint) { + grid-template-columns: 0.95fr 3fr; + grid-column-gap: rem(16); + } .spacer-row { grid-column: 1/4; height: rem(16); } } - \ No newline at end of file + +.existing-residences { + display: grid; + grid-template-columns: max-content max-content max-content max-content max-content; + overflow-x: auto; + grid-column-gap: rem(36); + grid-row-gap: rem(12); + + @media screen and (min-width: $tabletBreakpoint) { + grid-template-columns: 1fr 1fr 1fr; + } + + .full-width { + grid-column: 1/3; + } +} 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 426d98a570..29231ca6fb 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 @@ -13,13 +13,18 @@ import { openFileInline } from '../../../../../shared/utils/file'; }) export class NaruDetailsComponent { proposalMap: PublicDocumentDto[] = []; + buildingPlans: PublicDocumentDto[] = []; @Input() applicationSubmission!: PublicApplicationSubmissionDto; @Input() set applicationDocuments(documents: PublicDocumentDto[]) { this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP); + this.buildingPlans = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.BUILDING_PLAN); } - constructor(private router: Router, private publicService: PublicService) {} + constructor( + private router: Router, + private publicService: PublicService, + ) {} async openFile(file: PublicDocumentDto) { const res = await this.publicService.getApplicationOpenFileUrl(this.applicationSubmission.fileNumber, file.uuid); diff --git a/portal-frontend/src/app/features/public/application/submission/nfu-details/nfu-details.component.html b/portal-frontend/src/app/features/public/application/submission/nfu-details/nfu-details.component.html index 0192fa6e3c..611b48d46a 100644 --- a/portal-frontend/src/app/features/public/application/submission/nfu-details/nfu-details.component.html +++ b/portal-frontend/src/app/features/public/application/submission/nfu-details/nfu-details.component.html @@ -48,31 +48,11 @@

Soil and Fill Components

{{ applicationSubmission.nfuFillTypeDescription }}
-
Briefly describe the origin and quality of fill.
-
- {{ applicationSubmission.nfuFillOriginDescription }} - -
- -
Placement of Fill Project Duration
-
-
- {{ applicationSubmission.nfuProjectDuration }} -
- -
Fill to be Placed
-
Volume
-
- {{ applicationSubmission.nfuFillVolume }} - m3 - -
-
Area
{{ applicationSubmission.nfuTotalFillArea }} diff --git a/portal-frontend/src/app/features/public/application/submission/pfrs-details/pfrs-details.component.html b/portal-frontend/src/app/features/public/application/submission/pfrs-details/pfrs-details.component.html index 94e04b31d9..e502c8a3a6 100644 --- a/portal-frontend/src/app/features/public/application/submission/pfrs-details/pfrs-details.component.html +++ b/portal-frontend/src/app/features/public/application/submission/pfrs-details/pfrs-details.component.html @@ -180,7 +180,7 @@
Cross Sections
-
+
{{ file.fileName }} @@ -188,7 +188,7 @@
Reclamation Plan
-
+
{{ file.fileName }} diff --git a/portal-frontend/src/app/features/public/application/submission/pofo-details/pofo-details.component.html b/portal-frontend/src/app/features/public/application/submission/pofo-details/pofo-details.component.html index db43f0d4b6..0700f62109 100644 --- a/portal-frontend/src/app/features/public/application/submission/pofo-details/pofo-details.component.html +++ b/portal-frontend/src/app/features/public/application/submission/pofo-details/pofo-details.component.html @@ -122,7 +122,7 @@
Cross Sections
-
+
{{ file.fileName }} diff --git a/portal-frontend/src/app/features/public/application/submission/roso-details/roso-details.component.html b/portal-frontend/src/app/features/public/application/submission/roso-details/roso-details.component.html index a358a4490e..cd243734e5 100644 --- a/portal-frontend/src/app/features/public/application/submission/roso-details/roso-details.component.html +++ b/portal-frontend/src/app/features/public/application/submission/roso-details/roso-details.component.html @@ -114,7 +114,7 @@
Cross Sections
-
+
{{ file.fileName }} diff --git a/portal-frontend/src/app/features/public/application/submission/submission-details.component.scss b/portal-frontend/src/app/features/public/application/submission/submission-details.component.scss index 9796891103..2911f5311e 100644 --- a/portal-frontend/src/app/features/public/application/submission/submission-details.component.scss +++ b/portal-frontend/src/app/features/public/application/submission/submission-details.component.scss @@ -158,4 +158,10 @@ } } } + + .multiple-documents { + a { + display: block; + } + } } diff --git a/portal-frontend/src/app/features/public/notice-of-intent/submission/pfrs-details/pfrs-details.component.html b/portal-frontend/src/app/features/public/notice-of-intent/submission/pfrs-details/pfrs-details.component.html index 815fdaaef6..1fe39814b5 100644 --- a/portal-frontend/src/app/features/public/notice-of-intent/submission/pfrs-details/pfrs-details.component.html +++ b/portal-frontend/src/app/features/public/notice-of-intent/submission/pfrs-details/pfrs-details.component.html @@ -183,7 +183,7 @@
Cross Sections
-
+
{{ file.fileName }} diff --git a/portal-frontend/src/app/features/public/notice-of-intent/submission/pofo-details/pofo-details.component.html b/portal-frontend/src/app/features/public/notice-of-intent/submission/pofo-details/pofo-details.component.html index 5409a3b115..0436d6ea75 100644 --- a/portal-frontend/src/app/features/public/notice-of-intent/submission/pofo-details/pofo-details.component.html +++ b/portal-frontend/src/app/features/public/notice-of-intent/submission/pofo-details/pofo-details.component.html @@ -117,7 +117,7 @@
Cross Sections
-
+
{{ file.fileName }} diff --git a/portal-frontend/src/app/features/public/notice-of-intent/submission/roso-details/roso-details.component.html b/portal-frontend/src/app/features/public/notice-of-intent/submission/roso-details/roso-details.component.html index 7ff9ffeecd..0569712ccb 100644 --- a/portal-frontend/src/app/features/public/notice-of-intent/submission/roso-details/roso-details.component.html +++ b/portal-frontend/src/app/features/public/notice-of-intent/submission/roso-details/roso-details.component.html @@ -117,7 +117,7 @@
Cross Sections
-
+
{{ file.fileName }} diff --git a/portal-frontend/src/app/features/public/notice-of-intent/submission/submission-details.component.scss b/portal-frontend/src/app/features/public/notice-of-intent/submission/submission-details.component.scss index 8e568b8c10..f4b04222dd 100644 --- a/portal-frontend/src/app/features/public/notice-of-intent/submission/submission-details.component.scss +++ b/portal-frontend/src/app/features/public/notice-of-intent/submission/submission-details.component.scss @@ -152,4 +152,10 @@ } } } + + .multiple-documents { + a { + display: block; + } + } } diff --git a/portal-frontend/src/app/services/application-submission/application-submission.dto.ts b/portal-frontend/src/app/services/application-submission/application-submission.dto.ts index 63f1bc4f12..ad02ffb28c 100644 --- a/portal-frontend/src/app/services/application-submission/application-submission.dto.ts +++ b/portal-frontend/src/app/services/application-submission/application-submission.dto.ts @@ -37,6 +37,16 @@ export interface ProposedLot { size: number | null; } +export interface ExistingResidence { + floorArea: number; + description: string; +} + +export interface ProposedResidence { + floorArea: number; + description: string; +} + export interface ApplicationSubmissionDto { uuid: string; fileNumber: string; @@ -131,13 +141,22 @@ export interface ApplicationSubmissionDetailedDto extends ApplicationSubmissionD soilHasSubmittedNotice: boolean; //NARU Fields + naruWillBeOverFiveHundredM2: boolean | null; + naruWillRetainResidence: boolean | null; + naruWillHaveAdditionalResidence: boolean | null; + naruWillHaveTemporaryForeignWorkerHousing: boolean | null; + naruWillImportFill: boolean | null; + tfwhCount: string | null; + tfwhDesign: boolean | null; + tfwhFarmSize: string | null; + naruClustered: string | null; + naruSetback: string | null; naruSubtype: NaruSubtypeDto | null; naruFloorArea: number | null; naruResidenceNecessity: string | null; naruLocationRationale: string | null; naruInfrastructure: string | null; naruExistingStructures: string | null; - naruWillImportFill: boolean | null; naruFillType: string | null; naruFillOrigin: string | null; naruProjectDuration: string | null; @@ -147,6 +166,8 @@ export interface ApplicationSubmissionDetailedDto extends ApplicationSubmissionD naruToPlaceAverageDepth: number | null; naruSleepingUnits: number | null; naruAgriTourism: string | null; + naruExistingResidences?: ExistingResidence[]; + naruProposedResidences?: ProposedResidence[]; //Inclusion / Exclusion Fields prescribedBody: string | null; @@ -240,13 +261,22 @@ export interface ApplicationSubmissionUpdateDto { soilHasSubmittedNotice?: boolean | null; //NARU Fields + naruWillBeOverFiveHundredM2?: boolean | null; + naruWillRetainResidence?: boolean | null; + naruWillHaveAdditionalResidence?: boolean | null; + naruWillHaveTemporaryForeignWorkerHousing?: boolean | null; + naruWillImportFill?: boolean | null; + tfwhCount?: string | null; + tfwhDesign?: boolean | null; + tfwhFarmSize?: string | null; + naruClustered?: string | null; + naruSetback?: string | null; naruSubtypeCode?: string | null; naruFloorArea?: number | null; naruResidenceNecessity?: string | null; naruLocationRationale?: string | null; naruInfrastructure?: string | null; naruExistingStructures?: string | null; - naruWillImportFill?: boolean | null; naruFillType?: string | null; naruFillOrigin?: string | null; naruProjectDuration?: string | null; @@ -256,6 +286,8 @@ export interface ApplicationSubmissionUpdateDto { naruToPlaceAverageDepth?: number | null; naruSleepingUnits?: number | null; naruAgriTourism?: string | null; + naruExistingResidences?: ExistingResidence[]; + naruProposedResidences?: ProposedResidence[]; //Inclusion / Exclusion Fields prescribedBody?: string | null; diff --git a/portal-frontend/src/app/services/public/public-application.dto.ts b/portal-frontend/src/app/services/public/public-application.dto.ts index cd597b65d6..111381bac5 100644 --- a/portal-frontend/src/app/services/public/public-application.dto.ts +++ b/portal-frontend/src/app/services/public/public-application.dto.ts @@ -6,6 +6,16 @@ import { } from '../application-submission/application-submission.dto'; import { PublicDocumentDto, PublicOwnerDto, PublicParcelDto } from './public.dto'; +export interface ExistingResidence { + floorArea: number; + description: string; +} + +export interface ProposedResidence { + floorArea: number; + description: string; +} + export interface GetPublicApplicationResponseDto { submission: PublicApplicationSubmissionDto; parcels: PublicParcelDto[]; @@ -96,13 +106,22 @@ export interface PublicApplicationSubmissionDto { soilHasSubmittedNotice?: boolean; //NARU Fields + naruWillBeOverFiveHundredM2: boolean | null; + naruWillRetainResidence: boolean | null; + naruWillHaveAdditionalResidence: boolean | null; + naruWillHaveTemporaryForeignWorkerHousing: boolean | null; + naruWillImportFill: boolean | null; + tfwhCount: string | null; + tfwhDesign: boolean | null; + tfwhFarmSize: string | null; + naruClustered: string | null; + naruSetback: string | null; naruSubtype: NaruSubtypeDto | null; naruFloorArea: number | null; naruResidenceNecessity: string | null; naruLocationRationale: string | null; naruInfrastructure: string | null; naruExistingStructures: string | null; - naruWillImportFill: boolean | null; naruFillType: string | null; naruFillOrigin: string | null; naruProjectDuration: string | null; @@ -112,6 +131,8 @@ export interface PublicApplicationSubmissionDto { naruToPlaceAverageDepth: number | null; naruSleepingUnits: number | null; naruAgriTourism: string | null; + naruExistingResidences?: ExistingResidence[]; + naruProposedResidences?: ProposedResidence[]; //Inclusion / Exclusion Fields prescribedBody: string | null; diff --git a/portal-frontend/src/app/shared/constants.ts b/portal-frontend/src/app/shared/constants.ts index eb03bb10e0..5ca62501cd 100644 --- a/portal-frontend/src/app/shared/constants.ts +++ b/portal-frontend/src/app/shared/constants.ts @@ -1 +1,3 @@ export const VISIBLE_COUNT_INCREMENT = 5; +export const EXISTING_RESIDENCE_DESCRIPTION_CHAR_LIMIT = 120; +export const EXISTING_RESIDENCE_DESCRIPTION_CHAR_LIMIT_MOBILE = 100; diff --git a/portal-frontend/src/app/shared/mobile/naru-residence-mobile-card/naru-residence-mobile-card.component.html b/portal-frontend/src/app/shared/mobile/naru-residence-mobile-card/naru-residence-mobile-card.component.html new file mode 100644 index 0000000000..13da40de44 --- /dev/null +++ b/portal-frontend/src/app/shared/mobile/naru-residence-mobile-card/naru-residence-mobile-card.component.html @@ -0,0 +1,27 @@ + + + + #{{ residence.id }} Total Floor Area: {{ residence.floorArea }} + m2 + + + + + + + + + + + {{ residence.isExpanded ? residence.description : getTruncatedDescription(residence.description) }} + + {{ residence.isExpanded ? 'Read Less' : 'Read More' }} + + + diff --git a/portal-frontend/src/app/shared/mobile/naru-residence-mobile-card/naru-residence-mobile-card.component.scss b/portal-frontend/src/app/shared/mobile/naru-residence-mobile-card/naru-residence-mobile-card.component.scss new file mode 100644 index 0000000000..1f04e7b8ea --- /dev/null +++ b/portal-frontend/src/app/shared/mobile/naru-residence-mobile-card/naru-residence-mobile-card.component.scss @@ -0,0 +1,50 @@ +@use '../../../../styles/colors'; + +mat-card { + width: 100%; + box-shadow: none; + border: none; + border-bottom: 1px solid #565656; + border-radius: 0; + word-wrap: break-word; + white-space: normal; +} + +mat-card-header { + display: flex; + justify-content: space-between; + align-items: center; + font-weight: bold; + padding: 0 !important; +} + +mat-card-content { + display: flex; + flex-direction: column; + gap: 15px; + padding: 0 0 10px 0 !important; +} + +.span-action { + font-weight: normal; +} + +.last-card { + border-bottom: none !important; + margin-bottom: 20px; +} + +.review-step { + border-bottom: 1px solid #565656; + background-color: transparent; + + mat-card-header { + padding: 5px 0 10px 0 !important; + } +} + +a { + align-self: flex-end; + padding-right: 30px; + padding-bottom: 10px; +} diff --git a/portal-frontend/src/app/shared/mobile/naru-residence-mobile-card/naru-residence-mobile-card.component.ts b/portal-frontend/src/app/shared/mobile/naru-residence-mobile-card/naru-residence-mobile-card.component.ts new file mode 100644 index 0000000000..ee1d6e7351 --- /dev/null +++ b/portal-frontend/src/app/shared/mobile/naru-residence-mobile-card/naru-residence-mobile-card.component.ts @@ -0,0 +1,41 @@ +import { CommonModule } from '@angular/common'; +import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, type OnInit } from '@angular/core'; +import { + FormExisingResidence, + FormProposedResidence, +} from '../../../features/applications/edit-submission/proposal/naru-proposal/naru-proposal.component'; +import { isTruncated, truncate } from '../../utils/string-helper'; +import { EXISTING_RESIDENCE_DESCRIPTION_CHAR_LIMIT_MOBILE } from '../../constants'; + +@Component({ + selector: 'app-naru-residence-mobile-card', + templateUrl: './naru-residence-mobile-card.component.html', + styleUrl: './naru-residence-mobile-card.component.scss', +}) +export class NaruResidenceMobileCardComponent { + @Input() residence!: FormExisingResidence | FormProposedResidence; + @Input() isLast: boolean = false; + @Input() isReviewStep: boolean = false; + @Output() editClicked = new EventEmitter(); + @Output() removeClicked = new EventEmitter(); + + onEdit() { + this.editClicked.emit(this.residence); + } + + onRemove() { + this.removeClicked.emit(this.residence); + } + + getTruncatedDescription(description: string): string { + return truncate(description, EXISTING_RESIDENCE_DESCRIPTION_CHAR_LIMIT_MOBILE); + } + + isDescriptionTruncated(description: string): boolean { + return isTruncated(description, EXISTING_RESIDENCE_DESCRIPTION_CHAR_LIMIT_MOBILE); + } + + toggleReadMore(existingResidence: FormExisingResidence) { + this.residence.isExpanded = !this.residence.isExpanded; + } +} diff --git a/portal-frontend/src/app/shared/owner-dialogs/parcel-owners/parcel-owners.component.html b/portal-frontend/src/app/shared/owner-dialogs/parcel-owners/parcel-owners.component.html index eee249674a..91ef5969b9 100644 --- a/portal-frontend/src/app/shared/owner-dialogs/parcel-owners/parcel-owners.component.html +++ b/portal-frontend/src/app/shared/owner-dialogs/parcel-owners/parcel-owners.component.html @@ -28,7 +28,7 @@ Phone - {{ element.phoneNumber | mask : '(000) 000-0000' }} + {{ element.phoneNumber | mask: '(000) 000-0000' }} @@ -41,8 +41,8 @@
{{ - element.corporateSummary.fileName - }} + element.corporateSummary.fileName + }}
Not Applicable
@@ -78,14 +78,15 @@
- + (openFileClicked)="onOpenFile(owner.corporateSummary)" + >
See more owners diff --git a/portal-frontend/src/app/shared/owner-dialogs/parcel-owners/parcel-owners.component.ts b/portal-frontend/src/app/shared/owner-dialogs/parcel-owners/parcel-owners.component.ts index 1185a60f79..b17993c393 100644 --- a/portal-frontend/src/app/shared/owner-dialogs/parcel-owners/parcel-owners.component.ts +++ b/portal-frontend/src/app/shared/owner-dialogs/parcel-owners/parcel-owners.component.ts @@ -15,6 +15,7 @@ import { openFileInline } from '../../utils/file'; import { ApplicationDocumentDto } from '../../../services/application-document/application-document.dto'; import { NoticeOfIntentDocumentDto } from '../../../services/notice-of-intent-document/notice-of-intent-document.dto'; import { MOBILE_BREAKPOINT } from '../../utils/breakpoints'; +import { ConfirmationDialogService } from '../../../shared/confirmation-dialog/confirmation-dialog.service'; @Component({ selector: 'app-parcel-owners[owners][fileId][submissionUuid][ownerService]', @@ -70,7 +71,7 @@ export class ParcelOwnersComponent implements OnInit{ VISIBLE_COUNT = 5; visibleCount = this.VISIBLE_COUNT; - constructor(private dialog: MatDialog) {} + constructor(private dialog: MatDialog, private confirmationDialogService: ConfirmationDialogService) {} ngOnInit(): void { this.isMobile = window.innerWidth <= MOBILE_BREAKPOINT; @@ -114,7 +115,16 @@ export class ParcelOwnersComponent implements OnInit{ } async onRemove(uuid: string) { - this.onOwnerRemoved.emit(uuid); + this.confirmationDialogService + .openDialog({ + body: `Warning: Do you want to continue?`, + title: 'Remove Parcel Owner', + }) + .subscribe(async (answer) => { + if (answer) { + this.onOwnerRemoved.emit(uuid); + } + }); } async onOpenFile(file: ApplicationDocumentDto | NoticeOfIntentDocumentDto) { diff --git a/portal-frontend/src/app/shared/shared.module.ts b/portal-frontend/src/app/shared/shared.module.ts index 1228fea16d..a6c6f7e54e 100644 --- a/portal-frontend/src/app/shared/shared.module.ts +++ b/portal-frontend/src/app/shared/shared.module.ts @@ -53,6 +53,7 @@ import { OptionalAttachmentsMobileCardComponent } from './optional-attachments-m import { OtherAttachmentMobileCardComponent } from './other-attachment-mobile-card/other-attachment-mobile-card.component'; import { ParcelOwnerMobileCardComponent } from './mobile/parcel-owner-mobile-card/parcel-owner-mobile-card.component'; import { TransfereeMobileCardComponent } from './mobile/transferee-mobile-card/transferee-mobile-card.component'; +import { NaruResidenceMobileCardComponent } from './mobile/naru-residence-mobile-card/naru-residence-mobile-card.component'; @NgModule({ providers: [ @@ -113,6 +114,7 @@ import { TransfereeMobileCardComponent } from './mobile/transferee-mobile-card/t OtherAttachmentMobileCardComponent, ParcelOwnerMobileCardComponent, TransfereeMobileCardComponent, + NaruResidenceMobileCardComponent, ], exports: [ CommonModule, @@ -165,6 +167,7 @@ import { TransfereeMobileCardComponent } from './mobile/transferee-mobile-card/t OtherAttachmentMobileCardComponent, ParcelOwnerMobileCardComponent, TransfereeMobileCardComponent, + NaruResidenceMobileCardComponent, ], }) export class SharedModule { diff --git a/portal-frontend/src/app/shared/soil-table/soil-table.component.html b/portal-frontend/src/app/shared/soil-table/soil-table.component.html index 56ba63f4b4..f8bb602769 100644 --- a/portal-frontend/src/app/shared/soil-table/soil-table.component.html +++ b/portal-frontend/src/app/shared/soil-table/soil-table.component.html @@ -19,48 +19,50 @@ {{ tableHeader2 }}
-
- -
-
- - - m3 - -
- warning -
This field is required
+ +
+
-
-
- - - m3 - -
- warning -
This field is required
+
+ + + m3 + +
+ warning +
This field is required
+
-
+
+ + + m3 + +
+ warning +
This field is required
+
+
+
diff --git a/portal-frontend/src/app/shared/soil-table/soil-table.component.ts b/portal-frontend/src/app/shared/soil-table/soil-table.component.ts index cc6895e9dd..cfe91bef05 100644 --- a/portal-frontend/src/app/shared/soil-table/soil-table.component.ts +++ b/portal-frontend/src/app/shared/soil-table/soil-table.component.ts @@ -20,6 +20,7 @@ export class SoilTableComponent implements OnInit, OnChanges { @Input() data2?: SoilTableData; @Input() disabled = false; @Input() touchAll = false; + @Input() showVolumeField = true; @Output() dataChange = new EventEmitter(); @Output() data2Change = new EventEmitter(); @@ -27,12 +28,12 @@ export class SoilTableComponent implements OnInit, OnChanges { idSuffix?: string; idSuffix2?: string | undefined; - volume = new FormControl(null, [Validators.required]); + volume = new FormControl(null); area = new FormControl(null, [Validators.required]); maximumDepth = new FormControl(null, [Validators.required]); averageDepth = new FormControl(null, [Validators.required]); - volume2 = new FormControl(null, [Validators.required]); + volume2 = new FormControl(null); area2 = new FormControl(null, [Validators.required]); maximumDepth2 = new FormControl(null, [Validators.required]); averageDepth2 = new FormControl(null, [Validators.required]); @@ -49,6 +50,11 @@ export class SoilTableComponent implements OnInit, OnChanges { }); ngOnInit(): void { + if (this.showVolumeField) { + this.volume.setValidators([Validators.required]); + this.volume2.setValidators([Validators.required]); + } + if (this.data) { this.volume.setValue(this.data.volume?.toString(10) ?? null); this.area.setValue(this.data.area?.toString(10) ?? null); diff --git a/portal-frontend/src/app/shared/utils/string-helper.ts b/portal-frontend/src/app/shared/utils/string-helper.ts index d70405abe1..17d1814874 100644 --- a/portal-frontend/src/app/shared/utils/string-helper.ts +++ b/portal-frontend/src/app/shared/utils/string-helper.ts @@ -10,3 +10,11 @@ export const parseStringToBoolean = (val?: string | null) => { return undefined; } }; + +export function truncate(text: string, limit: number): string { + return text.length > limit ? text.substring(0, limit) + '...' : text; +} + +export function isTruncated(text: string, limit: number): boolean { + return text.length > limit; +} diff --git a/portal-frontend/src/assets/siting-figures/clustered.svg b/portal-frontend/src/assets/siting-figures/clustered.svg new file mode 100644 index 0000000000..648e54ffbd --- /dev/null +++ b/portal-frontend/src/assets/siting-figures/clustered.svg @@ -0,0 +1,4358 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/portal-frontend/src/assets/siting-figures/setback.svg b/portal-frontend/src/assets/siting-figures/setback.svg new file mode 100644 index 0000000000..c0e90cf3c8 --- /dev/null +++ b/portal-frontend/src/assets/siting-figures/setback.svg @@ -0,0 +1,13 @@ + + + + + + + \ No newline at end of file diff --git a/portal-frontend/src/assets/siting-figures/unclustered.svg b/portal-frontend/src/assets/siting-figures/unclustered.svg new file mode 100644 index 0000000000..13983d6386 --- /dev/null +++ b/portal-frontend/src/assets/siting-figures/unclustered.svg @@ -0,0 +1,2704 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/services/apps/alcs/src/alcs/application-decision/application-decision-v2/application-decision/component/application-decision-component.service.ts b/services/apps/alcs/src/alcs/application-decision/application-decision-v2/application-decision/component/application-decision-component.service.ts index bafe559735..a665505c42 100644 --- a/services/apps/alcs/src/alcs/application-decision/application-decision-v2/application-decision/component/application-decision-component.service.ts +++ b/services/apps/alcs/src/alcs/application-decision/application-decision-v2/application-decision/component/application-decision-component.service.ts @@ -46,29 +46,23 @@ export class ApplicationDecisionComponentService { updateDto.applicationDecisionComponentTypeCode; } - component.alrArea = filterUndefined( - updateDto.alrArea, - component.alrArea - ); - component.agCap = filterUndefined( - updateDto.agCap, - component.agCap - ); + component.alrArea = filterUndefined(updateDto.alrArea, component.alrArea); + component.agCap = filterUndefined(updateDto.agCap, component.agCap); component.agCapSource = filterUndefined( updateDto.agCapSource, - component.agCapSource + component.agCapSource, ); component.agCapMap = filterUndefined( updateDto.agCapMap, - component.agCapMap + component.agCapMap, ); component.agCapConsultant = filterUndefined( updateDto.agCapConsultant, - component.agCapConsultant + component.agCapConsultant, ); component.endDate2 = filterUndefined( formatIncomingDate(updateDto.endDate2), - component.endDate2 + component.endDate2, ); this.patchNfuFields(component, updateDto); @@ -85,7 +79,7 @@ export class ApplicationDecisionComponentService { component.inclExclApplicantType = updateDto.inclExclApplicantType; component.expiryDate = filterUndefined( formatIncomingDate(updateDto.expiryDate), - component.expiryDate + component.expiryDate, ); } @@ -159,16 +153,13 @@ export class ApplicationDecisionComponentService { ) { component.endDate = filterUndefined( formatIncomingDate(updateDto.endDate), - component.endDate + component.endDate, ); component.nfuSubType = filterUndefined( updateDto.nfuSubType, - component.nfuSubType - ); - component.nfuType = filterUndefined( - updateDto.nfuType, - component.nfuType + component.nfuSubType, ); + component.nfuType = filterUndefined(updateDto.nfuType, component.nfuType); } private patchTurpFields( @@ -177,7 +168,7 @@ export class ApplicationDecisionComponentService { ) { component.expiryDate = filterUndefined( formatIncomingDate(updateDto.expiryDate), - component.expiryDate + component.expiryDate, ); } @@ -187,27 +178,27 @@ export class ApplicationDecisionComponentService { ) { component.endDate = filterUndefined( formatIncomingDate(updateDto.endDate), - component.endDate + component.endDate, ); component.soilFillTypeToPlace = filterUndefined( updateDto.soilFillTypeToPlace, - component.soilFillTypeToPlace + component.soilFillTypeToPlace, ); component.soilToPlaceArea = filterUndefined( updateDto.soilToPlaceArea, - component.soilToPlaceArea + component.soilToPlaceArea, ); component.soilToPlaceVolume = filterUndefined( updateDto.soilToPlaceVolume, - component.soilToPlaceVolume + component.soilToPlaceVolume, ); component.soilToPlaceMaximumDepth = filterUndefined( updateDto.soilToPlaceMaximumDepth, - component.soilToPlaceMaximumDepth + component.soilToPlaceMaximumDepth, ); component.soilToPlaceAverageDepth = filterUndefined( updateDto.soilToPlaceAverageDepth, - component.soilToPlaceAverageDepth + component.soilToPlaceAverageDepth, ); } @@ -217,27 +208,27 @@ export class ApplicationDecisionComponentService { ) { component.endDate = filterUndefined( formatIncomingDate(updateDto.endDate), - component.endDate + component.endDate, ); component.soilTypeRemoved = filterUndefined( updateDto.soilTypeRemoved, - component.soilTypeRemoved + component.soilTypeRemoved, ); component.soilToRemoveVolume = filterUndefined( updateDto.soilToRemoveVolume, - component.soilToRemoveVolume + component.soilToRemoveVolume, ); component.soilToRemoveArea = filterUndefined( updateDto.soilToRemoveArea, - component.soilToRemoveArea + component.soilToRemoveArea, ); component.soilToRemoveMaximumDepth = filterUndefined( updateDto.soilToRemoveMaximumDepth, - component.soilToRemoveMaximumDepth + component.soilToRemoveMaximumDepth, ); component.soilToRemoveAverageDepth = filterUndefined( updateDto.soilToRemoveAverageDepth, - component.soilToRemoveAverageDepth + component.soilToRemoveAverageDepth, ); } @@ -247,11 +238,11 @@ export class ApplicationDecisionComponentService { ) { component.endDate = filterUndefined( formatIncomingDate(updateDto.endDate), - component.endDate + component.endDate, ); component.expiryDate = filterUndefined( formatIncomingDate(updateDto.expiryDate), - component.expiryDate + component.expiryDate, ); component.naruSubtypeCode = updateDto.naruSubtypeCode; } @@ -354,13 +345,6 @@ export class ApplicationDecisionComponentService { this.validatePofoDecisionComponentFields(component, errors); this.validateRosoDecisionComponentFields(component, errors); } - - if ( - component.applicationDecisionComponentTypeCode === - APPLICATION_DECISION_COMPONENT_TYPE.NARU - ) { - this.validateNaruDecisionComponentFields(component, errors); - } } if (errors.length > 0) { @@ -389,9 +373,6 @@ export class ApplicationDecisionComponentService { 'Type, origin and quality of fill approved to be placed is required', ); } - if (!component.soilToPlaceVolume) { - errors.push('Volume To Place is required'); - } if (!component.soilToPlaceArea) { errors.push('Area To Place is required'); } @@ -410,9 +391,6 @@ export class ApplicationDecisionComponentService { if (!component.soilTypeRemoved) { errors.push('Type of soil approved to be removed is required'); } - if (!component.soilToRemoveVolume) { - errors.push('Volume To Remove is required'); - } if (!component.soilToRemoveArea) { errors.push('Area To Remove is required'); } @@ -423,13 +401,4 @@ export class ApplicationDecisionComponentService { errors.push('Average Depth To Remove is required'); } } - - private validateNaruDecisionComponentFields( - component: CreateApplicationDecisionComponentDto, - errors: string[], - ) { - if (!component.naruSubtypeCode) { - errors.push('Residential Use Type is required'); - } - } } diff --git a/services/apps/alcs/src/alcs/application/application.service.ts b/services/apps/alcs/src/alcs/application/application.service.ts index 095e42a1cc..ac8aac6a1f 100644 --- a/services/apps/alcs/src/alcs/application/application.service.ts +++ b/services/apps/alcs/src/alcs/application/application.service.ts @@ -545,8 +545,9 @@ export class ApplicationService { SELECT * FROM alcs.calculate_active_days(ARRAY(SELECT fa."application_uuid" FROM filtered_applications fa)) ) - SELECT a.file_number, a.applicant, board.code, u.name, u.given_name, u.family_name, c.high_priority, calc.active_days FROM alcs.application a - INNER JOIN alcs.card c ON c."uuid" = a.card_uuid + SELECT a.file_number, a.applicant, board.code, u.name, u.given_name, u.family_name, c.high_priority, calc.active_days FROM alcs.application a + INNER JOIN alcs.application_reconsideration ar on ar.application_uuid = a.uuid + INNER JOIN alcs.card c ON c."uuid" = ar.card_uuid INNER JOIN calculated calc ON a."uuid" = calc.application_uuid INNER JOIN alcs.board board on c.board_uuid = board.uuid LEFT JOIN alcs.user u on u.uuid = c.assignee_uuid diff --git a/services/apps/alcs/src/portal/application-submission/application-submission-validator.service.spec.ts b/services/apps/alcs/src/portal/application-submission/application-submission-validator.service.spec.ts index dffa1ebb44..69e8d168cb 100644 --- a/services/apps/alcs/src/portal/application-submission/application-submission-validator.service.spec.ts +++ b/services/apps/alcs/src/portal/application-submission/application-submission-validator.service.spec.ts @@ -520,12 +520,9 @@ describe('ApplicationSubmissionValidatorService', () => { nfuAgricultureSupport: 'VALID', nfuWillImportFill: true, nfuFillTypeDescription: 'VALID', - nfuFillOriginDescription: 'VALID', nfuTotalFillArea: 0.0, nfuMaxFillDepth: 1.5125, nfuAverageFillDepth: 1261.21, - nfuFillVolume: 742.1, - nfuProjectDuration: '1 day', }); const res = await service.validateSubmission(application); @@ -567,13 +564,9 @@ describe('ApplicationSubmissionValidatorService', () => { nfuOutsideLands: 'VALID', nfuAgricultureSupport: 'VALID', nfuWillImportFill: true, - nfuFillTypeDescription: 'VALID', - nfuFillOriginDescription: null, nfuTotalFillArea: 0.0, nfuMaxFillDepth: 1.5125, nfuAverageFillDepth: 121, - nfuFillVolume: 742.1, - nfuProjectDuration: '1 day', typeCode: 'NFUP', }); diff --git a/services/apps/alcs/src/portal/application-submission/application-submission-validator.service.ts b/services/apps/alcs/src/portal/application-submission/application-submission-validator.service.ts index 8b91a901b2..8d43578847 100644 --- a/services/apps/alcs/src/portal/application-submission/application-submission-validator.service.ts +++ b/services/apps/alcs/src/portal/application-submission/application-submission-validator.service.ts @@ -425,12 +425,9 @@ export class ApplicationSubmissionValidatorService { if (applicationSubmission.nfuWillImportFill) { if ( !applicationSubmission.nfuFillTypeDescription || - !applicationSubmission.nfuFillOriginDescription || applicationSubmission.nfuTotalFillArea === null || applicationSubmission.nfuMaxFillDepth === null || - applicationSubmission.nfuAverageFillDepth === null || - applicationSubmission.nfuFillVolume === null || - !applicationSubmission.nfuProjectDuration + applicationSubmission.nfuAverageFillDepth === null ) { errors.push( new ServiceValidationException(`NFU Fill Section incomplete`), diff --git a/services/apps/alcs/src/portal/application-submission/application-submission.dto.ts b/services/apps/alcs/src/portal/application-submission/application-submission.dto.ts index dc5abea643..9023fb215f 100644 --- a/services/apps/alcs/src/portal/application-submission/application-submission.dto.ts +++ b/services/apps/alcs/src/portal/application-submission/application-submission.dto.ts @@ -15,7 +15,11 @@ import { } from '../../alcs/application/application-submission-status/submission-status.dto'; import { BaseCodeDto } from '../../common/dtos/base.dto'; import { ApplicationOwnerDto } from './application-owner/application-owner.dto'; -import { ProposedLot } from './application-submission.entity'; +import { + ExistingResidence, + ProposedLot, + ProposedResidence, +} from './application-submission.entity'; export const MAX_DESCRIPTION_FIELD_LENGTH = 4000; export const MAX_LANDUSE_FIELD_LENGTH = 500; @@ -238,6 +242,36 @@ export class ApplicationSubmissionDetailedDto extends ApplicationSubmissionDto { @AutoMap(() => Boolean) soilHasSubmittedNotice?: boolean; + @AutoMap(() => Boolean) + naruWillBeOverFiveHundredM2: boolean | null; + + @AutoMap(() => Boolean) + naruWillRetainResidence: boolean | null; + + @AutoMap(() => Boolean) + naruWillHaveAdditionalResidence: boolean | null; + + @AutoMap(() => Boolean) + naruWillHaveTemporaryForeignWorkerHousing: boolean | null; + + @AutoMap(() => Boolean) + naruWillImportFill: boolean | null; + + @AutoMap(() => String) + tfwhCount: string | null; + + @AutoMap(() => Boolean) + tfwhDesign: boolean | null; + + @AutoMap(() => String) + tfwhFarmSize: string | null; + + @AutoMap(() => String) + naruClustered: string | null; + + @AutoMap(() => String) + naruSetback: string | null; + //NARU Fields @AutoMap(() => [NaruSubtypeDto]) naruSubtype: NaruSubtypeDto | null; @@ -257,9 +291,6 @@ export class ApplicationSubmissionDetailedDto extends ApplicationSubmissionDto { @AutoMap(() => String) naruExistingStructures: string | null; - @AutoMap(() => Boolean) - naruWillImportFill: boolean | null; - @AutoMap(() => String) naruFillType: string | null; @@ -287,6 +318,12 @@ export class ApplicationSubmissionDetailedDto extends ApplicationSubmissionDto { @AutoMap(() => String) naruAgriTourism: string | null; + @AutoMap(() => ExistingResidence) + naruExistingResidences?: ExistingResidence[]; + + @AutoMap(() => ProposedResidence) + naruProposedResidences?: ProposedResidence[]; + @AutoMap(() => ApplicationSubmissionToSubmissionStatusDto) submissionStatuses: ApplicationSubmissionToSubmissionStatusDto[]; @@ -618,6 +655,46 @@ export class ApplicationSubmissionUpdateDto { soilHasSubmittedNotice?: boolean; //NARU Fields + @IsBoolean() + @IsOptional() + naruWillBeOverFiveHundredM2?: boolean | null; + + @IsBoolean() + @IsOptional() + naruWillRetainResidence?: boolean | null; + + @IsBoolean() + @IsOptional() + naruWillHaveAdditionalResidence?: boolean | null; + + @IsBoolean() + @IsOptional() + naruWillHaveTemporaryForeignWorkerHousing?: boolean | null; + + @IsBoolean() + @IsOptional() + naruWillImportFill?: boolean | null; + + @IsString() + @IsOptional() + tfwhCount?: string | null; + + @IsBoolean() + @IsOptional() + tfwhDesign?: boolean | null; + + @IsString() + @IsOptional() + tfwhFarmSize?: string | null; + + @IsString() + @IsOptional() + naruClustered?: string | null; + + @IsString() + @IsOptional() + naruSetback?: string | null; + @IsString() @IsOptional() naruSubtypeCode?: string | null; @@ -642,10 +719,6 @@ export class ApplicationSubmissionUpdateDto { @IsOptional() naruExistingStructures?: string | null; - @IsBoolean() - @IsOptional() - naruWillImportFill?: boolean | null; - @IsString() @IsOptional() naruFillType?: string | null; @@ -683,6 +756,14 @@ export class ApplicationSubmissionUpdateDto { @IsOptional() naruAgriTourism?: string | null; + @IsArray() + @IsOptional() + naruExistingResidences?: ExistingResidence[]; + + @IsArray() + @IsOptional() + naruProposedResidences?: ProposedResidence[]; + //Inclusion / Exclusion Fields @IsString() @IsOptional() diff --git a/services/apps/alcs/src/portal/application-submission/application-submission.entity.ts b/services/apps/alcs/src/portal/application-submission/application-submission.entity.ts index 59db1d3596..e887c6f4fe 100644 --- a/services/apps/alcs/src/portal/application-submission/application-submission.entity.ts +++ b/services/apps/alcs/src/portal/application-submission/application-submission.entity.ts @@ -25,6 +25,16 @@ export class ProposedLot { planNumbers: string | null; } +export class ExistingResidence { + floorArea: number; + description: string; +} + +export class ProposedResidence { + floorArea: number; + description: string; +} + @Entity({ comment: 'Portal intake form fields for applications', }) @@ -557,6 +567,42 @@ export class ApplicationSubmission extends Base { @Column({ type: 'boolean', nullable: true }) soilHasSubmittedNotice: boolean | null; + @AutoMap(() => Boolean) + @Column({ type: 'boolean', nullable: true }) + naruWillBeOverFiveHundredM2: boolean | null; + + @AutoMap(() => Boolean) + @Column({ type: 'boolean', nullable: true }) + naruWillRetainResidence: boolean | null; + + @AutoMap(() => Boolean) + @Column({ type: 'boolean', nullable: true }) + naruWillHaveAdditionalResidence: boolean | null; + + @AutoMap(() => Boolean) + @Column({ type: 'boolean', nullable: true }) + naruWillHaveTemporaryForeignWorkerHousing: boolean | null; + + @AutoMap(() => String) + @Column({ type: 'text', nullable: true }) + tfwhCount: string | null; + + @AutoMap(() => Boolean) + @Column({ type: 'boolean', nullable: true }) + tfwhDesign: boolean | null; + + @AutoMap(() => String) + @Column({ type: 'text', nullable: true }) + tfwhFarmSize: string | null; + + @AutoMap(() => String) + @Column({ type: 'text', nullable: true }) + naruClustered: string | null; + + @AutoMap(() => String) + @Column({ type: 'text', nullable: true }) + naruSetback: string | null; + //NARU @AutoMap(() => NaruSubtype) @ManyToOne(() => NaruSubtype) @@ -662,6 +708,24 @@ export class ApplicationSubmission extends Base { @Column({ type: 'text', nullable: true }) naruAgriTourism: string | null; + @AutoMap(() => [ExistingResidence]) + @Column({ + comment: 'JSONB column containing NARU existing residences', + type: 'jsonb', + array: false, + default: () => `'[]'`, + }) + naruExistingResidences: ExistingResidence[]; + + @AutoMap(() => [ProposedResidence]) + @Column({ + comment: 'JSONB column containing NARU proposed residences', + type: 'jsonb', + array: false, + default: () => `'[]'`, + }) + naruProposedResidences: ProposedResidence[]; + //Inclusion / Exclusion Fields @AutoMap(() => String) diff --git a/services/apps/alcs/src/portal/application-submission/application-submission.service.ts b/services/apps/alcs/src/portal/application-submission/application-submission.service.ts index e6baa3ba92..8b64f91950 100644 --- a/services/apps/alcs/src/portal/application-submission/application-submission.service.ts +++ b/services/apps/alcs/src/portal/application-submission/application-submission.service.ts @@ -743,22 +743,10 @@ export class ApplicationSubmissionService { updateDto.nfuAverageFillDepth, application.nfuAverageFillDepth, ); - application.nfuFillVolume = filterUndefined( - updateDto.nfuFillVolume, - application.nfuFillVolume, - ); - application.nfuProjectDuration = filterUndefined( - updateDto.nfuProjectDuration, - application.nfuProjectDuration, - ); application.nfuFillTypeDescription = filterUndefined( updateDto.nfuFillTypeDescription, application.nfuFillTypeDescription, ); - application.nfuFillOriginDescription = filterUndefined( - updateDto.nfuFillOriginDescription, - application.nfuFillOriginDescription, - ); return application; } @@ -950,6 +938,47 @@ export class ApplicationSubmissionService { applicationSubmission: ApplicationSubmission, updateDto: ApplicationSubmissionUpdateDto, ) { + applicationSubmission.naruWillBeOverFiveHundredM2 = filterUndefined( + updateDto.naruWillBeOverFiveHundredM2, + applicationSubmission.naruWillBeOverFiveHundredM2, + ); + applicationSubmission.naruWillRetainResidence = filterUndefined( + updateDto.naruWillRetainResidence, + applicationSubmission.naruWillRetainResidence, + ); + applicationSubmission.naruWillHaveAdditionalResidence = filterUndefined( + updateDto.naruWillHaveAdditionalResidence, + applicationSubmission.naruWillHaveAdditionalResidence, + ); + applicationSubmission.naruWillHaveTemporaryForeignWorkerHousing = + filterUndefined( + updateDto.naruWillHaveTemporaryForeignWorkerHousing, + applicationSubmission.naruWillHaveTemporaryForeignWorkerHousing, + ); + applicationSubmission.naruWillImportFill = filterUndefined( + updateDto.naruWillImportFill, + applicationSubmission.naruWillImportFill, + ); + applicationSubmission.tfwhCount = filterUndefined( + updateDto.tfwhCount, + applicationSubmission.tfwhCount, + ); + applicationSubmission.tfwhDesign = filterUndefined( + updateDto.tfwhDesign, + applicationSubmission.tfwhDesign, + ); + applicationSubmission.tfwhFarmSize = filterUndefined( + updateDto.tfwhFarmSize, + applicationSubmission.tfwhFarmSize, + ); + applicationSubmission.naruClustered = filterUndefined( + updateDto.naruClustered, + applicationSubmission.naruClustered, + ); + applicationSubmission.naruSetback = filterUndefined( + updateDto.naruSetback, + applicationSubmission.naruSetback, + ); applicationSubmission.naruSubtype = undefined; applicationSubmission.naruSubtypeCode = filterUndefined( updateDto.naruSubtypeCode, @@ -975,26 +1004,10 @@ export class ApplicationSubmissionService { updateDto.naruExistingStructures, applicationSubmission.naruExistingStructures, ); - applicationSubmission.naruWillImportFill = filterUndefined( - updateDto.naruWillImportFill, - applicationSubmission.naruWillImportFill, - ); applicationSubmission.naruFillType = filterUndefined( updateDto.naruFillType, applicationSubmission.naruFillType, ); - applicationSubmission.naruFillOrigin = filterUndefined( - updateDto.naruFillOrigin, - applicationSubmission.naruFillOrigin, - ); - applicationSubmission.naruProjectDuration = filterUndefined( - updateDto.naruProjectDuration, - applicationSubmission.naruProjectDuration, - ); - applicationSubmission.naruToPlaceVolume = filterUndefined( - updateDto.naruToPlaceVolume, - applicationSubmission.naruToPlaceVolume, - ); applicationSubmission.naruToPlaceArea = filterUndefined( updateDto.naruToPlaceArea, applicationSubmission.naruToPlaceArea, @@ -1015,6 +1028,15 @@ export class ApplicationSubmissionService { updateDto.naruAgriTourism, applicationSubmission.naruAgriTourism, ); + applicationSubmission.naruExistingResidences = filterUndefined( + updateDto.naruExistingResidences, + applicationSubmission.naruExistingResidences, + ); + + applicationSubmission.naruProposedResidences = filterUndefined( + updateDto.naruProposedResidences, + applicationSubmission.naruProposedResidences, + ); } private setInclusionExclusionFields( 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 87899e710d..933389891a 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 @@ -42,6 +42,7 @@ export class InboxNotificationService { if (cachedSearch) { const cachedNumbers = JSON.parse(cachedSearch) as string[]; fileNumbers = new Set(cachedNumbers); + didSearch = true; } else { const res = await this.searchForFileNumbers(searchDto); fileNumbers = res.finalResult; @@ -155,6 +156,7 @@ export class InboxNotificationService { } if (searchDto.fileTypes.includes('SRW')) { + didSearch = true; const promise = NOTIFICATION_SEARCH_FILTERS.addFileTypeResults( searchDto, this.notificationRepository, diff --git a/services/apps/alcs/src/portal/pdf-generation/generate-submission-document.service.ts b/services/apps/alcs/src/portal/pdf-generation/generate-submission-document.service.ts index 5a6510448e..682eef4416 100644 --- a/services/apps/alcs/src/portal/pdf-generation/generate-submission-document.service.ts +++ b/services/apps/alcs/src/portal/pdf-generation/generate-submission-document.service.ts @@ -180,7 +180,7 @@ export class GenerateSubmissionDocumentService { payload = this.populateNfuData(payload, submission); return { payload, templateName: 'nfu-submission-template.docx' }; case APPLICATION_SUBMISSION_TYPES.NARU: - payload = this.populateNaruData(payload, submission); + payload = this.populateNaruData(payload, submission, documents); return { payload, templateName: 'naru-submission-template.docx' }; case APPLICATION_SUBMISSION_TYPES.TURP: payload = this.populateTurData(payload, submission, documents); @@ -254,11 +254,11 @@ export class GenerateSubmissionDocumentService { const otherDocuments = documents.filter( (e) => (!e.typeCode || - [ - DOCUMENT_TYPE.PHOTOGRAPH, - DOCUMENT_TYPE.PROFESSIONAL_REPORT, - DOCUMENT_TYPE.OTHER, - ].includes((e.typeCode ?? 'undefined') as DOCUMENT_TYPE)) && + [ + DOCUMENT_TYPE.PHOTOGRAPH, + DOCUMENT_TYPE.PROFESSIONAL_REPORT, + DOCUMENT_TYPE.OTHER, + ].includes((e.typeCode ?? 'undefined') as DOCUMENT_TYPE)) && e.document.source === DOCUMENT_SOURCE.APPLICANT, ); @@ -369,23 +369,58 @@ export class GenerateSubmissionDocumentService { }; } - private populateNaruData(pdfData: any, submission: ApplicationSubmission) { + private populateNaruData( + pdfData: any, + submission: ApplicationSubmission, + documents: ApplicationDocument[], + ) { + const naruExistingResidences = submission.naruExistingResidences.map( + (item, index) => { + return { ...item, cnt: index + 1 }; + }, + ); + + const naruProposedResidences = submission.naruProposedResidences.map( + (item, index) => { + return { ...item, cnt: index + 1 }; + }, + ); + return { ...pdfData, - naruSubtypeLabel: submission.naruSubtype?.label, - naruSubtypeCode: submission.naruSubtypeCode, - naruFloorArea: submission.naruFloorArea, - naruResidenceNecessity: submission.naruResidenceNecessity, - naruLocationRationale: submission.naruLocationRationale, - naruInfrastructure: submission.naruInfrastructure, - naruExistingStructures: submission.naruExistingStructures, - naruSleepingUnits: submission.naruSleepingUnits, - naruAgriTourism: submission.naruAgriTourism, - showImportFill: submission.naruWillImportFill, + naruWillBeOverFiveHundredM2: formatBooleanToYesNoString( + submission.naruWillBeOverFiveHundredM2, + ), + naruWillRetainResidence: formatBooleanToYesNoString( + submission.naruWillRetainResidence, + ), + naruWillHaveAdditionalResidence: formatBooleanToYesNoString( + submission.naruWillHaveAdditionalResidence, + ), + naruWillHaveTemporaryForeignWorkerHousing: formatBooleanToYesNoString( + submission.naruWillHaveTemporaryForeignWorkerHousing, + ), naruWillImportFill: formatBooleanToYesNoString( submission.naruWillImportFill, ), + naruResidenceNecessity: submission.naruResidenceNecessity, + tfwhCount: submission.tfwhCount, + tfwhDesign: formatBooleanToYesNoString(submission.tfwhDesign), + tfwhFarmSize: submission.tfwhFarmSize, + naruClustered: submission.naruClustered, + naruSetback: submission.naruSetback, + naruLocationRationale: submission.naruLocationRationale, + naruInfrastructure: submission.naruInfrastructure, + naruExistingResidences: naruExistingResidences, + naruProposedResidences: naruProposedResidences, + buildingPlans: documents + .filter( + (document) => document.type?.code === DOCUMENT_TYPE.BUILDING_PLAN, + ) + .find((d) => d)?.document.fileName, + + showImportFill: submission.naruWillImportFill, // NFU Proposal => Soil and Fill naruFillType: submission.naruFillType, naruFillOrigin: submission.naruFillOrigin, diff --git a/services/apps/alcs/src/portal/public/application/public-application.dto.ts b/services/apps/alcs/src/portal/public/application/public-application.dto.ts index 1e0648d59c..d295a31809 100644 --- a/services/apps/alcs/src/portal/public/application/public-application.dto.ts +++ b/services/apps/alcs/src/portal/public/application/public-application.dto.ts @@ -1,7 +1,11 @@ import { AutoMap } from 'automapper-classes'; import { ApplicationStatusDto } from '../../../alcs/application/application-submission-status/submission-status.dto'; import { NaruSubtypeDto } from '../../application-submission/application-submission.dto'; -import { ProposedLot } from '../../application-submission/application-submission.entity'; +import { + ExistingResidence, + ProposedLot, + ProposedResidence, +} from '../../application-submission/application-submission.entity'; import { PublicOwnerDto } from '../public.dto'; export class PublicApplicationSubmissionDto { @@ -220,6 +224,36 @@ export class PublicApplicationSubmissionDto { soilHasSubmittedNotice?: boolean; //NARU Fields + @AutoMap(() => Boolean) + naruWillBeOverFiveHundredM2: boolean | null; + + @AutoMap(() => Boolean) + naruWillRetainResidence: boolean | null; + + @AutoMap(() => Boolean) + naruWillHaveAdditionalResidence: boolean | null; + + @AutoMap(() => Boolean) + naruWillHaveTemporaryForeignWorkerHousing: boolean | null; + + @AutoMap(() => Boolean) + naruWillImportFill: boolean | null; + + @AutoMap(() => String) + tfwhCount: string | null; + + @AutoMap(() => Boolean) + tfwhDesign: boolean | null; + + @AutoMap(() => String) + tfwhFarmSize: string | null; + + @AutoMap(() => String) + naruClustered: string | null; + + @AutoMap(() => String) + naruSetback: string | null; + @AutoMap(() => [NaruSubtypeDto]) naruSubtype: NaruSubtypeDto | null; @@ -238,9 +272,6 @@ export class PublicApplicationSubmissionDto { @AutoMap(() => String) naruExistingStructures: string | null; - @AutoMap(() => Boolean) - naruWillImportFill: boolean | null; - @AutoMap(() => String) naruFillType: string | null; @@ -268,6 +299,12 @@ export class PublicApplicationSubmissionDto { @AutoMap(() => String) naruAgriTourism: string | null; + @AutoMap(() => ExistingResidence) + naruExistingResidences?: ExistingResidence[]; + + @AutoMap(() => ProposedResidence) + naruProposedResidences: ProposedResidence[] | null; + //Inclusion / Exclusion Fields @AutoMap(() => String) prescribedBody: string | null; diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1726098613152-update_naru_subtypes.ts b/services/apps/alcs/src/providers/typeorm/migrations/1726098613152-update_naru_subtypes.ts new file mode 100644 index 0000000000..33291371fc --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1726098613152-update_naru_subtypes.ts @@ -0,0 +1,38 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class UpdateNaruSubtypes1726098613152 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + queryRunner.query(` + update alcs.application_type at + set html_description = 'Choose this option if you are proposing to conduct a non-adhering residential use within the Agricultural Land Reserve under + Section 20.1(2) of the Agricultural Land Commission Act. +

+ Non-adhering residential uses include: +
    +
  • An additional residence(s)
  • +
  • A residential structure larger than 500 m²
  • +
  • Retain an existing residence while building a new residence
  • +
  • Temporary foreign worker housing
  • +
+ ' + where at.code = 'NARU'; + `); + } + + public async down(queryRunner: QueryRunner): Promise { + queryRunner.query(` + update alcs.application_type at + set html_description = 'Choose this option if you are proposing to conduct a non-adhering residential use within the Agricultural Land Reserve under + Section 20.1(2) of the Agricultural Land Commission Act. +

+ Non-adhering residential uses include: +
    +
  • An additional residence for farm use;
  • +
  • A residential structure larger than 500 m²; or,
  • +
  • A non-adhering tourism accommodation.
  • +
+ ' + where at.code = 'NARU'; + `); + } +} diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1726156915372-fix_new_naru_text.ts b/services/apps/alcs/src/providers/typeorm/migrations/1726156915372-fix_new_naru_text.ts new file mode 100644 index 0000000000..ce0fea50af --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1726156915372-fix_new_naru_text.ts @@ -0,0 +1,39 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class FixNewNaruText1726156915372 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + queryRunner.query(` + update alcs.application_type at + set html_description = 'Choose this option if you are proposing to conduct a non-adhering residential use within the Agricultural Land Reserve under + Section 20.1(2) of the Agricultural Land Commission Act. +

+ Non-adhering residential uses include: +
    +
  • Additional residence(s)
  • +
  • Residence(s) with Total Floor Area greater than 500 m²
  • +
  • Retain an existing residence while building a new residence
  • +
  • Temporary foreign worker housing
  • +
+ ' + where at.code = 'NARU'; + `); + } + + public async down(queryRunner: QueryRunner): Promise { + queryRunner.query(` + update alcs.application_type at + set html_description = 'Choose this option if you are proposing to conduct a non-adhering residential use within the Agricultural Land Reserve under + Section 20.1(2) of the Agricultural Land Commission Act. +

+ Non-adhering residential uses include: +
    +
  • An additional residence(s)
  • +
  • A residential structure larger than 500 m²
  • +
  • Retain an existing residence while building a new residence
  • +
  • Temporary foreign worker housing
  • +
+ ' + where at.code = 'NARU'; + `); + } +} diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1726271415863-new_naru_fields.ts b/services/apps/alcs/src/providers/typeorm/migrations/1726271415863-new_naru_fields.ts new file mode 100644 index 0000000000..3b03fb9c4e --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1726271415863-new_naru_fields.ts @@ -0,0 +1,47 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class NewNaruFiels1726271415863 implements MigrationInterface { + name = 'NewNaruFiels1726271415863'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" ADD "naru_will_be_over_five_hundred_m2" boolean`, + ); + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" ADD "naru_will_retain_residence" boolean`, + ); + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" ADD "naru_will_have_additional_residence" boolean`, + ); + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" ADD "naru_will_have_temporary_foreign_worker_housing" boolean`, + ); + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" ADD "naru_clustered" text`, + ); + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" ADD "naru_setback" text`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" DROP COLUMN "naru_setback"`, + ); + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" DROP COLUMN "naru_clustered"`, + ); + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" DROP COLUMN "naru_will_have_temporary_foreign_worker_housing"`, + ); + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" DROP COLUMN "naru_will_have_additional_residence"`, + ); + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" DROP COLUMN "naru_will_retain_residence"`, + ); + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" DROP COLUMN "naru_will_be_over_five_hundred_m2"`, + ); + } +} diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1727199312985-add-naru-existing-residences.ts b/services/apps/alcs/src/providers/typeorm/migrations/1727199312985-add-naru-existing-residences.ts new file mode 100644 index 0000000000..10f5fddf7f --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1727199312985-add-naru-existing-residences.ts @@ -0,0 +1,16 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddNaruExistingResidences1727199312985 implements MigrationInterface { + name = 'AddNaruExistingResidences1727199312985' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "alcs"."application_submission" ADD "naru_existing_residences" jsonb NOT NULL DEFAULT '[]'`); + await queryRunner.query(`COMMENT ON COLUMN "alcs"."application_submission"."naru_existing_residences" IS 'JSONB column containing NARU existing residence'`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`COMMENT ON COLUMN "alcs"."application_submission"."naru_existing_residences" IS 'JSONB column containing NARU existing residence'`); + await queryRunner.query(`ALTER TABLE "alcs"."application_submission" DROP COLUMN "naru_existing_residences"`); + } + +} diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1727304004390-convert_naru_subtype_to_answers.ts b/services/apps/alcs/src/providers/typeorm/migrations/1727304004390-convert_naru_subtype_to_answers.ts new file mode 100644 index 0000000000..62f31cf767 --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1727304004390-convert_naru_subtype_to_answers.ts @@ -0,0 +1,22 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class ConvertNaruSubtypeToAnswers1727304004390 + implements MigrationInterface +{ + public async up(queryRunner: QueryRunner): Promise { + queryRunner.query(` + update alcs.application_submission as2 + set + naru_will_have_additional_residence = case + when as2.naru_subtype_code = 'ARFU' then true + end, + naru_will_be_over_five_hundred_m2 = case + when as2.naru_subtype_code = 'PRIN' then true + end + where as2.naru_subtype_code is not null + and as2.naru_subtype_code <> 'TOUR'; + `); + } + + public async down(queryRunner: QueryRunner): Promise {} +} diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1727382304979-add_naru_proposed_residences.ts b/services/apps/alcs/src/providers/typeorm/migrations/1727382304979-add_naru_proposed_residences.ts new file mode 100644 index 0000000000..7ed3e8f869 --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1727382304979-add_naru_proposed_residences.ts @@ -0,0 +1,18 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class AddNaruProposedResidences1727382304979 implements MigrationInterface { + name = 'AddNaruProposedResidences1727382304979' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "alcs"."application_submission" ADD "naru_proposed_residences" jsonb NOT NULL DEFAULT '[]'`); + await queryRunner.query(`COMMENT ON COLUMN "alcs"."application_submission"."naru_proposed_residences" IS 'JSONB column containing NARU proposed residences'`); + await queryRunner.query(`COMMENT ON COLUMN "alcs"."application_submission"."naru_existing_residences" IS 'JSONB column containing NARU existing residences'`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`COMMENT ON COLUMN "alcs"."application_submission"."naru_existing_residences" IS 'JSONB column containing NARU existing residence'`); + await queryRunner.query(`COMMENT ON COLUMN "alcs"."application_submission"."naru_proposed_residences" IS 'JSONB column containing NARU proposed residences'`); + await queryRunner.query(`ALTER TABLE "alcs"."application_submission" DROP COLUMN "naru_proposed_residences"`); + } + +} diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1727382390880-make_tfwh_columns.ts b/services/apps/alcs/src/providers/typeorm/migrations/1727382390880-make_tfwh_columns.ts new file mode 100644 index 0000000000..7dae3dee9a --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1727382390880-make_tfwh_columns.ts @@ -0,0 +1,29 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class MakeTfwhColumns1727382390880 implements MigrationInterface { + name = 'MakeTfwhColumns1727382390880'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" ADD "tfwh_count" text`, + ); + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" ADD "tfwh_design" boolean`, + ); + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" ADD "tfwh_farm_size" text`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" DROP COLUMN "tfwh_farm_size"`, + ); + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" DROP COLUMN "tfwh_design"`, + ); + await queryRunner.query( + `ALTER TABLE "alcs"."application_submission" DROP COLUMN "tfwh_count"`, + ); + } +} diff --git a/services/apps/alcs/src/providers/typeorm/migrations/1727461542081-change_app_type_html.ts b/services/apps/alcs/src/providers/typeorm/migrations/1727461542081-change_app_type_html.ts new file mode 100644 index 0000000000..8b98ce2b29 --- /dev/null +++ b/services/apps/alcs/src/providers/typeorm/migrations/1727461542081-change_app_type_html.ts @@ -0,0 +1,15 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class ChangeAppTypeHtml1727461542081 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `UPDATE "alcs"."application_type" SET + "html_description"=CONCAT(html_description, '

If you need help selecting an application type, please Contact Us.

') + WHERE "html_description" is not null`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + // N/A + } +} diff --git a/services/templates/pdf/submissions/naru-submission-template.docx b/services/templates/pdf/submissions/naru-submission-template.docx index 9c2e0866a6..14867314fe 100644 Binary files a/services/templates/pdf/submissions/naru-submission-template.docx and b/services/templates/pdf/submissions/naru-submission-template.docx differ diff --git a/services/templates/pdf/submissions/nfu-submission-template.docx b/services/templates/pdf/submissions/nfu-submission-template.docx index 429af6871b..43171f6a0d 100644 Binary files a/services/templates/pdf/submissions/nfu-submission-template.docx and b/services/templates/pdf/submissions/nfu-submission-template.docx differ