-
-
-
-
-
-
warning
-
This field is required
+
+
+
+
+
+
+ At least one structure is required
+
-
- Example: Project phasing, providing landscape screening, fencing, buffering, erosion and sediment control,
- temporary or permanent drainage, etc.
-
- Characters left: {{ 4000 - reduceNegativeImpactsText.textLength }}
-
+
+
+
+ Selected proposed structure type(s) will determine the proposal questions below
+
+
+
+
+
0">
+
+
+
+ Please refer to
+
Farm Structures in the ALR
+ on the ALC website for more detail.
+
+
+
+
+
+
warning
+
This field is required
+
+
Characters left: {{ 4000 - soilStructureFarmUseReasonText.textLength }}
+
+
+
+
+
Include the area, yields, crop types, and farm equipment size and attachments
+
+
+
+
+
warning
+
This field is required
+
+
Characters left: {{ 4000 - soilAgriParcelActivityText.textLength }}
+
+
+
+
0 ||
+ structureTypeCounts[structureTypes.ADDITIONAL_RESIDENCE] > 0 ||
+ structureTypeCounts[structureTypes.ACCESSORY_STRUCTURE] > 0
+ "
+ >
+
+
+
+ Please refer to
+
Housing in the ALR
+ on the ALC website for more detail.
+
+
+
+
+
+
warning
+
This field is required
+
+
Characters left: {{ 4000 - soilStructureResidentialUseReasonText.textLength }}
+
+
+
+
0">
+
+
+
+ Please refer to
+
Housing in the ALR
+ on the ALC website for more detail.
+
+
+
+
+
+
warning
+
This field is required
+
+
Characters left: {{ 4000 - structureResidentialAccessoryUseReasonText.textLength }}
+
+
+
+
0">
+
+
+
+
+
+
+
warning
+
This field is required
+
+
Characters left: {{ 4000 - soilStructureOtherUseReasonText.textLength }}
+
+
+
+
+
+
+
+
+
+
+
warning
+
This field is required
+
+
+ Example: Project phasing, providing landscape screening, fencing, buffering, erosion and sediment control,
+ temporary or permanent drainage, etc.
+
+
Characters left: {{ 4000 - reduceNegativeImpactsText.textLength }}
+
+
Proposal Map / Site Plan
@@ -210,57 +564,61 @@
Proposal
[showVirusError]="showProposalMapVirus"
>
-
-
Cross Sections
-
Include North-South and East-West cross sections
-
- Please refer to
- Removal of Soil
- on the ALC website for more information
-
-
-
-
-
Reclamation Plan
-
- The Reclamation Plan should be completed by a qualified Professional Agrologist and contain the area's
- agricultural capability assessment.
+
+
+
+
Cross Sections
+
Include North-South and East-West cross sections
+
+ Please refer to
+ Removal of Soil
+ on the ALC website for more information
+
+
-
- Please refer to
- Removal of Soil
- on the ALC website for more information
-
-
-
+
+
+
Reclamation Plan
+
+ The Reclamation Plan should be completed by a qualified Professional Agrologist and contain the area's
+ agricultural capability assessment.
+
+
+ Please refer to
+ Removal of Soil
+ on the ALC website for more information
+
+
+
+
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.ts b/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.ts
index b7eb501e6..36ccbd817 100644
--- a/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.ts
+++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-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 { Router } from '@angular/router';
@@ -15,6 +15,17 @@ import { parseStringToBoolean } from '../../../../../shared/utils/string-helper'
import { EditApplicationSteps } from '../../edit-submission.component';
import { FilesStepComponent } from '../../files-step.partial';
import { SoilTableData } from '../../../../../shared/soil-table/soil-table.component';
+import {
+ FormProposedStructure,
+ STRUCTURE_TYPE_OPTIONS,
+ STRUCTURE_TYPES,
+} from '../../../../notice-of-intents/edit-submission/additional-information/additional-information.component';
+import { MatTableDataSource } from '@angular/material/table';
+import { ConfirmationDialogService } from '../../../../../shared/confirmation-dialog/confirmation-dialog.service';
+import { MOBILE_BREAKPOINT } from '../../../../../shared/utils/breakpoints';
+import { AddStructureDialogComponent } from '../../../../../features/notice-of-intents/edit-submission/additional-information/add-structure-dialog/add-structure-dialog.component';
+import { ProposedStructure } from '../../../../../services/notice-of-intent-submission/notice-of-intent-submission.dto';
+import { v4 } from 'uuid';
@Component({
selector: 'app-roso-proposal',
@@ -24,8 +35,19 @@ import { SoilTableData } from '../../../../../shared/soil-table/soil-table.compo
export class RosoProposalComponent extends FilesStepComponent implements OnInit, OnDestroy {
currentStep = EditApplicationSteps.Proposal;
+ @HostListener('window:resize', ['$event'])
+ onWindowResize() {
+ this.isMobile = window.innerWidth <= MOBILE_BREAKPOINT;
+ }
+
DOCUMENT = DOCUMENT_TYPE;
+ structureTypes = STRUCTURE_TYPES;
+ structureTypeOptions = STRUCTURE_TYPE_OPTIONS;
+ structureTypeCounts: Record = Object.fromEntries(
+ Object.entries(STRUCTURE_TYPES).map(([_, type]) => [type, 0]),
+ ) as { [key in STRUCTURE_TYPES]: number };
+
proposalMap: ApplicationDocumentDto[] = [];
crossSections: ApplicationDocumentDto[] = [];
reclamationPlan: ApplicationDocumentDto[] = [];
@@ -34,6 +56,7 @@ export class RosoProposalComponent extends FilesStepComponent implements OnInit,
showCrossSectionVirus = false;
showReclamationPlanVirus = false;
+ isNewStructure = new FormControl(null, [Validators.required]);
isFollowUp = new FormControl(null, [Validators.required]);
followUpIds = new FormControl({ value: null, disabled: true }, [Validators.required]);
purpose = new FormControl(null, [Validators.required]);
@@ -42,16 +65,34 @@ export class RosoProposalComponent extends FilesStepComponent implements OnInit,
projectDuration = new FormControl(null, [Validators.required]);
areComponentsDirty = false;
+ soilStructureFarmUseReason = new FormControl(null);
+ soilStructureResidentialUseReason = new FormControl(null);
+ soilAgriParcelActivity = new FormControl(null);
+ soilStructureResidentialAccessoryUseReason = new FormControl(null);
+ soilStructureOtherUseReason = new FormControl(null);
+
form = new FormGroup({
+ isNewStructure: this.isNewStructure,
isFollowUp: this.isFollowUp,
followUpIds: this.followUpIds,
purpose: this.purpose,
soilTypeRemoved: this.soilTypeRemoved,
reduceNegativeImpacts: this.reduceNegativeImpacts,
projectDuration: this.projectDuration,
+ soilStructureFarmUseReason: this.soilStructureFarmUseReason,
+ soilStructureResidentialUseReason: this.soilStructureResidentialUseReason,
+ soilAgriParcelActivity: this.soilAgriParcelActivity,
+ soilStructureResidentialAccessoryUseReason: this.soilStructureResidentialAccessoryUseReason,
+ soilStructureOtherUseReason: this.soilStructureOtherUseReason,
});
+ structuresForm = new FormGroup({} as any);
+ proposedStructures: FormProposedStructure[] = [];
+ structuresSource = new MatTableDataSource(this.proposedStructures);
+ displayedColumns = ['index', 'type', 'area', 'action'];
+
private submissionUuid = '';
+ isMobile = false;
removalTableData: SoilTableData = {};
alreadyRemovedTableData: SoilTableData = {};
@@ -60,12 +101,15 @@ export class RosoProposalComponent extends FilesStepComponent implements OnInit,
private applicationService: ApplicationSubmissionService,
applicationDocumentService: ApplicationDocumentService,
dialog: MatDialog,
- toastService: ToastService
+ toastService: ToastService,
+ private confirmationDialogService: ConfirmationDialogService,
) {
super(applicationDocumentService, dialog, toastService);
}
ngOnInit(): void {
+ this.isMobile = window.innerWidth <= MOBILE_BREAKPOINT;
+
this.$applicationSubmission.pipe(takeUntil(this.$destroy)).subscribe((applicationSubmission) => {
if (applicationSubmission) {
this.fileId = applicationSubmission.fileNumber;
@@ -90,13 +134,27 @@ export class RosoProposalComponent extends FilesStepComponent implements OnInit,
}
this.form.patchValue({
+ isNewStructure: applicationSubmission.soilIsNewStructure,
isFollowUp: formatBooleanToString(applicationSubmission.soilIsFollowUp),
followUpIds: applicationSubmission.soilFollowUpIDs,
purpose: applicationSubmission.purpose,
soilTypeRemoved: applicationSubmission.soilTypeRemoved,
reduceNegativeImpacts: applicationSubmission.soilReduceNegativeImpacts,
projectDuration: applicationSubmission.soilProjectDuration,
+ soilStructureFarmUseReason: applicationSubmission.soilStructureFarmUseReason,
+ soilStructureResidentialUseReason: applicationSubmission.soilStructureResidentialUseReason,
+ soilAgriParcelActivity: applicationSubmission.soilAgriParcelActivity,
+ soilStructureResidentialAccessoryUseReason: applicationSubmission.soilStructureResidentialAccessoryUseReason,
+ soilStructureOtherUseReason: applicationSubmission.soilStructureOtherUseReason,
});
+
+ this.proposedStructures = [];
+ this.structuresForm = new FormGroup({});
+ for (const structure of applicationSubmission.soilProposedStructures) {
+ this.addControl(structure.type, structure.area);
+ }
+ this.structuresSource = new MatTableDataSource(this.proposedStructures);
+
if (this.showErrors) {
this.form.markAllAsTouched();
}
@@ -131,16 +189,27 @@ export class RosoProposalComponent extends FilesStepComponent implements OnInit,
protected async save() {
if (this.fileId && (this.form.dirty || this.areComponentsDirty)) {
+ const isNewStructure = this.isNewStructure.getRawValue();
const isNOIFollowUp = this.isFollowUp.getRawValue();
const soilFollowUpIDs = this.followUpIds.getRawValue();
const purpose = this.purpose.getRawValue();
const soilTypeRemoved = this.soilTypeRemoved.getRawValue();
const soilReduceNegativeImpacts = this.reduceNegativeImpacts.getRawValue();
+ const updatedStructures: ProposedStructure[] = this.proposedStructures.map((lot) => {
+ const lotType = this.structuresForm.controls[`${lot.id}-type`].value;
+ const lotArea = this.structuresForm.controls[`${lot.id}-area`].value;
+ return {
+ type: lotType,
+ area: lotArea ? parseFloat(lotArea) : null,
+ };
+ });
+
const updateDto: ApplicationSubmissionUpdateDto = {
purpose,
soilTypeRemoved,
soilReduceNegativeImpacts,
+ soilIsNewStructure: isNewStructure,
soilIsFollowUp: parseStringToBoolean(isNOIFollowUp),
soilFollowUpIDs,
soilToRemoveVolume: this.removalTableData?.volume ?? null,
@@ -152,6 +221,9 @@ export class RosoProposalComponent extends FilesStepComponent implements OnInit,
soilAlreadyRemovedMaximumDepth: this.alreadyRemovedTableData?.maximumDepth ?? null,
soilAlreadyRemovedAverageDepth: this.alreadyRemovedTableData?.averageDepth ?? null,
soilProjectDuration: this.projectDuration.value,
+ soilStructureFarmUseReason: this.soilStructureFarmUseReason.value,
+ soilStructureResidentialUseReason: this.soilStructureResidentialUseReason.value,
+ soilProposedStructures: updatedStructures,
};
const updatedApp = await this.applicationService.updatePending(this.submissionUuid, updateDto);
@@ -159,6 +231,59 @@ export class RosoProposalComponent extends FilesStepComponent implements OnInit,
}
}
+ onChangeIsNewStructure(answeredYes: boolean | null) {
+ const hasValuesThatWillBeCleared: boolean = !!(
+ (answeredYes &&
+ (this.crossSections.length > 0 || this.reclamationPlan.length > 0 || this.reduceNegativeImpacts.value)) ||
+ (!answeredYes &&
+ (this.proposedStructures.length > 0 ||
+ this.soilStructureFarmUseReason.value ||
+ this.soilStructureResidentialUseReason.value ||
+ this.soilAgriParcelActivity.value ||
+ this.soilStructureResidentialAccessoryUseReason.value ||
+ this.soilStructureOtherUseReason.value))
+ );
+
+ if (hasValuesThatWillBeCleared) {
+ this.confirmationDialogService
+ .openDialog({
+ title: 'Are you removing soil in order to build a structure?',
+ body: 'Warning: Changing your answer will remove all the saved progress on this step. Do you want to continue?',
+ confirmAction: 'Confirm',
+ cancelAction: 'Cancel',
+ })
+ .subscribe((isConfirmed) => {
+ if (isConfirmed) {
+ if (answeredYes) {
+ // Clear docs
+ this.crossSections = [];
+ this.reclamationPlan = [];
+
+ // Clear questions
+ this.reduceNegativeImpacts.reset();
+ } else {
+ // Clear structures
+ this.structuresForm = new FormGroup({});
+ this.proposedStructures = [];
+ this.structuresSource = new MatTableDataSource(this.proposedStructures);
+ for (const type of Object.keys(this.structureTypeCounts) as Array) {
+ this.structureTypeCounts[type] = 0;
+ }
+
+ // Clear conditional questions
+ this.soilStructureFarmUseReason.reset();
+ this.soilStructureResidentialUseReason.reset();
+ this.soilAgriParcelActivity.reset();
+ this.soilStructureResidentialAccessoryUseReason.reset();
+ this.soilStructureOtherUseReason.reset();
+ }
+ } else {
+ this.isNewStructure.setValue(!answeredYes);
+ }
+ });
+ }
+ }
+
onChangeIsFollowUp(selectedValue: string) {
if (selectedValue === 'true') {
this.followUpIds.enable();
@@ -168,6 +293,189 @@ export class RosoProposalComponent extends FilesStepComponent implements OnInit,
}
}
+ onStructureAdd() {
+ if (this.isMobile) {
+ const dialog = this.dialog.open(AddStructureDialogComponent, {
+ width: '70%',
+ data: {
+ structureData: {
+ options: this.structureTypeOptions,
+ },
+ },
+ });
+ dialog
+ .beforeClosed()
+ .subscribe(async (result: { isEditing: boolean; structureId: string; dto: ProposedStructure }) => {
+ if (!result) return;
+ this.addControl(result.dto.type, result.dto.area);
+ this.structuresSource = new MatTableDataSource(this.proposedStructures);
+
+ this.structureTypeCounts[result.dto.type!]++;
+ });
+ } else {
+ this.addControl();
+ this.structuresSource = new MatTableDataSource(this.proposedStructures);
+ }
+ }
+
+ addControl(type: STRUCTURE_TYPES | null = null, area: number | null = null) {
+ const areaStr = area ? area.toString(10) : null;
+ const newStructure = { type, area: areaStr, id: v4() };
+ this.proposedStructures.push(newStructure);
+ this.structuresForm.addControl(
+ `${newStructure.id}-type`,
+ new FormControl(type, [Validators.required]),
+ );
+ this.structuresForm.addControl(
+ `${newStructure.id}-area`,
+ new FormControl(areaStr, [Validators.required]),
+ );
+
+ if (type) {
+ this.structureTypeCounts[type]++;
+ }
+ }
+
+ isWarning(index: number, item: ProposedStructure): boolean {
+ return item.type === STRUCTURE_TYPES.PRINCIPAL_RESIDENCE || item.type === STRUCTURE_TYPES.ADDITIONAL_RESIDENCE;
+ }
+
+ onStructureRemove(id: string) {
+ this.confirmationDialogService
+ .openDialog({
+ title:
+ 'Warning: Deleting the structure type can remove some content already saved to this page. Do you want to continue?',
+ body: 'Changing the structure type will remove inputs relevant to the current structure. Do you want to continue?',
+ confirmAction: 'Confirm',
+ cancelAction: 'Cancel',
+ })
+ .subscribe(async (result) => {
+ if (result) {
+ this.deleteStructure(id);
+ }
+ });
+ }
+
+ private deleteStructure(id: string) {
+ const structureToDelete = this.proposedStructures.find((structure) => structure.id === id);
+
+ if (!structureToDelete) {
+ console.error('Failed to find deleted structure');
+ return;
+ }
+
+ this.proposedStructures = this.proposedStructures.filter((structure) => structure.id !== structureToDelete.id);
+ this.structuresSource = new MatTableDataSource(this.proposedStructures);
+ this.structuresForm.removeControl(`${id}-type`);
+ this.structuresForm.removeControl(`${id}-area`);
+ this.structuresForm.markAsDirty();
+
+ if (structureToDelete.type !== null && this.structureTypeCounts[structureToDelete.type] > 0) {
+ this.structureTypeCounts[structureToDelete.type]--;
+ }
+ }
+
+ onStructureEdit(id: string) {
+ const structureToEdit = this.proposedStructures.find((structure) => structure.id === id);
+ const dialog = this.dialog.open(AddStructureDialogComponent, {
+ width: '70%',
+ data: {
+ isEdit: true,
+ structureId: structureToEdit?.id,
+ structureData: {
+ area: structureToEdit?.area,
+ type: structureToEdit?.type,
+ options: this.structureTypeOptions,
+ },
+ },
+ });
+ dialog
+ .afterClosed()
+ .subscribe(async (result: { isEditing: boolean; structureId: string; dto: ProposedStructure }) => {
+ if (!result) return;
+ const structureToEdit = this.proposedStructures.find((structure) => structure.id === id);
+
+ if (structureToEdit) {
+ if (structureToEdit.type !== result.dto.type) {
+ this.setStructureTypeInput(structureToEdit, result.dto.type!);
+ }
+
+ structureToEdit.area = result.dto.area ? result.dto.area.toString(10) : null;
+ structureToEdit.type = result.dto.type;
+ const areaControl = this.structuresForm.controls[`${structureToEdit?.id}-area`];
+ const typeControl = this.structuresForm.controls[`${structureToEdit?.id}-type`];
+ areaControl.setValue(structureToEdit.area?.toString());
+ typeControl.setValue(structureToEdit.type);
+ this.structuresForm.markAsDirty();
+ }
+ });
+ }
+
+ onChangeStructureType(id: string, newType: STRUCTURE_TYPES) {
+ const structure = this.proposedStructures.find((structure) => structure.id === id);
+
+ if (!structure) {
+ console.error('Failed to find structure');
+ return;
+ }
+
+ if (this.hasInput(structure.type)) {
+ this.confirmationDialogService
+ .openDialog({
+ title: 'Change Structure Type',
+ body: 'Changing the structure type will remove inputs relevant to the current structure. Do you want to continue?',
+ confirmAction: 'Confirm',
+ cancelAction: 'Cancel',
+ })
+ .subscribe((isConfirmed) => {
+ if (isConfirmed) {
+ this.setStructureTypeInput(structure, newType);
+ } else {
+ this.structuresForm.get(structure.id + '-type')?.setValue(structure.type);
+ }
+ });
+ } else {
+ return this.setStructureTypeInput(structure, newType);
+ }
+ }
+
+ private hasInput(type: STRUCTURE_TYPES | null) {
+ switch (type) {
+ case STRUCTURE_TYPES.FARM_STRUCTURE:
+ return !!(this.soilAgriParcelActivity.value || this.soilStructureFarmUseReason.value);
+
+ case STRUCTURE_TYPES.ACCESSORY_STRUCTURE:
+ return !!(
+ this.soilStructureResidentialUseReason.value || this.soilStructureResidentialAccessoryUseReason.value
+ );
+
+ case STRUCTURE_TYPES.OTHER_STRUCTURE:
+ return !!this.soilStructureOtherUseReason.value;
+
+ case STRUCTURE_TYPES.PRINCIPAL_RESIDENCE:
+ case STRUCTURE_TYPES.ADDITIONAL_RESIDENCE:
+ return !!this.soilStructureResidentialUseReason.value;
+
+ case null:
+ return false;
+
+ default:
+ return true;
+ }
+ }
+
+ private setStructureTypeInput(structure: FormProposedStructure, newType: STRUCTURE_TYPES) {
+ if (structure.type !== null && this.structureTypeCounts[structure.type] > 0) {
+ this.structureTypeCounts[structure.type]--;
+ }
+
+ this.structureTypeCounts[newType]++;
+
+ structure.type = newType;
+
+ this.form.markAsDirty();
+ }
+
markDirty() {
this.areComponentsDirty = true;
}
From a2dfd3e9495bc91e082219852e3057c729c17e75 Mon Sep 17 00:00:00 2001
From: Tristan Slater <1631008+trslater@users.noreply.github.com>
Date: Thu, 24 Oct 2024 10:38:43 -0700
Subject: [PATCH 20/45] Add building plans
---
.../pfrs-proposal.component.html | 21 +++++++++++++++++++
.../pfrs-proposal/pfrs-proposal.component.ts | 12 ++++++++++-
.../pofo-proposal.component.html | 19 +++++++++++++++++
.../pofo-proposal/pofo-proposal.component.ts | 12 ++++++++++-
.../roso-proposal.component.html | 19 +++++++++++++++++
.../roso-proposal/roso-proposal.component.ts | 12 ++++++++++-
6 files changed, 92 insertions(+), 3 deletions(-)
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.html b/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.html
index e009e4c59..6d3192b52 100644
--- a/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.html
+++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.html
@@ -737,7 +737,28 @@ Proposal
[showVirusError]="showReclamationPlanVirus"
>
+
+
+
+
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
+
+
+
+
+
+
Is your proposal for aggregate extraction or placer mining?
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.ts b/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.ts
index 6bfdbb39b..47fb37b1d 100644
--- a/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.ts
+++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.ts
@@ -50,12 +50,14 @@ export class PfrsProposalComponent extends FilesStepComponent implements OnInit,
proposalMap: ApplicationDocumentDto[] = [];
crossSections: ApplicationDocumentDto[] = [];
reclamationPlan: ApplicationDocumentDto[] = [];
+ buildingPlans: ApplicationDocumentDto[] = [];
noticeOfWork: ApplicationDocumentDto[] = [];
areComponentsDirty = false;
showProposalMapVirus = false;
showCrossSectionVirus = false;
showReclamationPlanVirus = false;
+ showBuildingPlanVirus = false;
showNoticeOfWorkVirus = false;
isNewStructure = new FormControl(null, [Validators.required]);
@@ -207,6 +209,7 @@ export class PfrsProposalComponent extends FilesStepComponent implements OnInit,
this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP);
this.crossSections = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.CROSS_SECTIONS);
this.reclamationPlan = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.RECLAMATION_PLAN);
+ this.buildingPlans = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.BUILDING_PLAN);
this.noticeOfWork = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.NOTICE_OF_WORK);
});
}
@@ -230,6 +233,11 @@ export class PfrsProposalComponent extends FilesStepComponent implements OnInit,
this.showReclamationPlanVirus = !res;
}
+ async attachBuildingPlan(file: FileHandle) {
+ const res = await this.attachFile(file, DOCUMENT_TYPE.BUILDING_PLAN);
+ this.showBuildingPlanVirus = !res;
+ }
+
async attachNoticeOfWork(file: FileHandle) {
const res = await this.attachFile(file, DOCUMENT_TYPE.NOTICE_OF_WORK);
this.showNoticeOfWorkVirus = !res;
@@ -313,7 +321,8 @@ export class PfrsProposalComponent extends FilesStepComponent implements OnInit,
this.soilStructureResidentialUseReason.value ||
this.soilAgriParcelActivity.value ||
this.soilStructureResidentialAccessoryUseReason.value ||
- this.soilStructureOtherUseReason.value))
+ this.soilStructureOtherUseReason.value ||
+ this.buildingPlans.length > 0))
);
if (hasValuesThatWillBeCleared) {
@@ -330,6 +339,7 @@ export class PfrsProposalComponent extends FilesStepComponent implements OnInit,
// Clear docs
this.crossSections = [];
this.reclamationPlan = [];
+ this.buildingPlans = [];
this.noticeOfWork = [];
// Clear questions
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.html b/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.html
index 69afe447f..0d89bff88 100644
--- a/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.html
+++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.html
@@ -651,6 +651,25 @@ 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
+
+
+
+
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.ts b/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.ts
index c4249b147..9f7b22349 100644
--- a/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.ts
+++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.ts
@@ -51,10 +51,12 @@ export class PofoProposalComponent extends FilesStepComponent implements OnInit,
proposalMap: ApplicationDocumentDto[] = [];
crossSections: ApplicationDocumentDto[] = [];
reclamationPlan: ApplicationDocumentDto[] = [];
+ buildingPlans: ApplicationDocumentDto[] = [];
showProposalMapVirus = false;
showCrossSectionVirus = false;
showReclamationPlanVirus = false;
+ showBuildingPlanVirus = false;
isNewStructure = new FormControl(null, [Validators.required]);
isFollowUp = new FormControl(null, [Validators.required]);
@@ -168,6 +170,7 @@ export class PofoProposalComponent extends FilesStepComponent implements OnInit,
this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP);
this.crossSections = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.CROSS_SECTIONS);
this.reclamationPlan = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.RECLAMATION_PLAN);
+ this.buildingPlans = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.BUILDING_PLAN);
});
}
@@ -190,6 +193,11 @@ export class PofoProposalComponent extends FilesStepComponent implements OnInit,
this.showReclamationPlanVirus = !res;
}
+ async attachBuildingPlan(file: FileHandle) {
+ const res = await this.attachFile(file, DOCUMENT_TYPE.BUILDING_PLAN);
+ this.showBuildingPlanVirus = !res;
+ }
+
protected async save() {
if (this.fileId && (this.form.dirty || this.areComponentsDirty)) {
const isNewStructure = this.isNewStructure.getRawValue();
@@ -249,7 +257,8 @@ export class PofoProposalComponent extends FilesStepComponent implements OnInit,
this.soilStructureResidentialUseReason.value ||
this.soilAgriParcelActivity.value ||
this.soilStructureResidentialAccessoryUseReason.value ||
- this.soilStructureOtherUseReason.value))
+ this.soilStructureOtherUseReason.value ||
+ this.buildingPlans.length > 0))
);
if (hasValuesThatWillBeCleared) {
@@ -266,6 +275,7 @@ export class PofoProposalComponent extends FilesStepComponent implements OnInit,
// Clear docs
this.crossSections = [];
this.reclamationPlan = [];
+ this.buildingPlans = [];
// Clear questions
this.reduceNegativeImpacts.reset();
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.html b/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.html
index da4574dbd..92c359c4a 100644
--- a/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.html
+++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.html
@@ -619,6 +619,25 @@ 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
+
+
+
+
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.ts b/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.ts
index 36ccbd817..0d5500bc9 100644
--- a/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.ts
+++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.ts
@@ -51,10 +51,12 @@ export class RosoProposalComponent extends FilesStepComponent implements OnInit,
proposalMap: ApplicationDocumentDto[] = [];
crossSections: ApplicationDocumentDto[] = [];
reclamationPlan: ApplicationDocumentDto[] = [];
+ buildingPlans: ApplicationDocumentDto[] = [];
showProposalMapVirus = false;
showCrossSectionVirus = false;
showReclamationPlanVirus = false;
+ showBuildingPlanVirus = false;
isNewStructure = new FormControl(null, [Validators.required]);
isFollowUp = new FormControl(null, [Validators.required]);
@@ -165,6 +167,7 @@ export class RosoProposalComponent extends FilesStepComponent implements OnInit,
this.proposalMap = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.PROPOSAL_MAP);
this.crossSections = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.CROSS_SECTIONS);
this.reclamationPlan = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.RECLAMATION_PLAN);
+ this.buildingPlans = documents.filter((document) => document.type?.code === DOCUMENT_TYPE.BUILDING_PLAN);
});
}
@@ -187,6 +190,11 @@ export class RosoProposalComponent extends FilesStepComponent implements OnInit,
this.showReclamationPlanVirus = !res;
}
+ async attachBuildingPlan(file: FileHandle) {
+ const res = await this.attachFile(file, DOCUMENT_TYPE.BUILDING_PLAN);
+ this.showBuildingPlanVirus = !res;
+ }
+
protected async save() {
if (this.fileId && (this.form.dirty || this.areComponentsDirty)) {
const isNewStructure = this.isNewStructure.getRawValue();
@@ -241,7 +249,8 @@ export class RosoProposalComponent extends FilesStepComponent implements OnInit,
this.soilStructureResidentialUseReason.value ||
this.soilAgriParcelActivity.value ||
this.soilStructureResidentialAccessoryUseReason.value ||
- this.soilStructureOtherUseReason.value))
+ this.soilStructureOtherUseReason.value ||
+ this.buildingPlans.length > 0))
);
if (hasValuesThatWillBeCleared) {
@@ -258,6 +267,7 @@ export class RosoProposalComponent extends FilesStepComponent implements OnInit,
// Clear docs
this.crossSections = [];
this.reclamationPlan = [];
+ this.buildingPlans = [];
// Clear questions
this.reduceNegativeImpacts.reset();
From 3b1763c8e76e4647062a5cf7fc496b409cedae87 Mon Sep 17 00:00:00 2001
From: Tristan Slater <1631008+trslater@users.noreply.github.com>
Date: Thu, 24 Oct 2024 10:40:43 -0700
Subject: [PATCH 21/45] Fix clearing file uploads
---
.../pfrs-proposal/pfrs-proposal.component.ts | 16 ++++++++++++----
.../pofo-proposal/pofo-proposal.component.ts | 12 +++++++++---
.../roso-proposal/roso-proposal.component.ts | 12 +++++++++---
3 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.ts b/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.ts
index 47fb37b1d..342efcf4e 100644
--- a/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.ts
+++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.ts
@@ -337,10 +337,18 @@ export class PfrsProposalComponent extends FilesStepComponent implements OnInit,
if (isConfirmed) {
if (answeredYes) {
// Clear docs
- this.crossSections = [];
- this.reclamationPlan = [];
- this.buildingPlans = [];
- this.noticeOfWork = [];
+ for (const crossSection of this.crossSections) {
+ this.onDeleteFile(crossSection);
+ }
+ for (const reclamationPlan_ of this.reclamationPlan) {
+ this.onDeleteFile(reclamationPlan_);
+ }
+ for (const buildingPlan of this.buildingPlans) {
+ this.onDeleteFile(buildingPlan);
+ }
+ for (const noticeOfWork_ of this.noticeOfWork) {
+ this.onDeleteFile(noticeOfWork_);
+ }
// Clear questions
this.reduceNegativeImpacts.reset();
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.ts b/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.ts
index 9f7b22349..59cb5a6e1 100644
--- a/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.ts
+++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.ts
@@ -273,9 +273,15 @@ export class PofoProposalComponent extends FilesStepComponent implements OnInit,
if (isConfirmed) {
if (answeredYes) {
// Clear docs
- this.crossSections = [];
- this.reclamationPlan = [];
- this.buildingPlans = [];
+ for (const crossSection of this.crossSections) {
+ this.onDeleteFile(crossSection);
+ }
+ for (const reclamationPlan_ of this.reclamationPlan) {
+ this.onDeleteFile(reclamationPlan_);
+ }
+ for (const buildingPlan of this.buildingPlans) {
+ this.onDeleteFile(buildingPlan);
+ }
// Clear questions
this.reduceNegativeImpacts.reset();
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.ts b/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.ts
index 0d5500bc9..e82699a6c 100644
--- a/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.ts
+++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.ts
@@ -265,9 +265,15 @@ export class RosoProposalComponent extends FilesStepComponent implements OnInit,
if (isConfirmed) {
if (answeredYes) {
// Clear docs
- this.crossSections = [];
- this.reclamationPlan = [];
- this.buildingPlans = [];
+ for (const crossSection of this.crossSections) {
+ this.onDeleteFile(crossSection);
+ }
+ for (const reclamationPlan_ of this.reclamationPlan) {
+ this.onDeleteFile(reclamationPlan_);
+ }
+ for (const buildingPlan of this.buildingPlans) {
+ this.onDeleteFile(buildingPlan);
+ }
// Clear questions
this.reduceNegativeImpacts.reset();
From 9bdfad6b84c13fae860a6b4ba51b45ed822dabc2 Mon Sep 17 00:00:00 2001
From: Tristan Slater <1631008+trslater@users.noreply.github.com>
Date: Thu, 24 Oct 2024 10:49:08 -0700
Subject: [PATCH 22/45] Update POFO/ROSO styles
---
.../pofo-proposal.component.scss | 24 ++++++++++++++++++
.../roso-proposal.component.scss | 25 +++++++++++++++++++
2 files changed, 49 insertions(+)
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.scss b/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.scss
index a4d0e0cc5..7d96b08e8 100644
--- a/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.scss
+++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/pofo-proposal/pofo-proposal.component.scss
@@ -7,3 +7,27 @@ section {
.steps-list {
margin: rem(16) 0;
}
+
+.mat-mdc-form-field {
+ width: 100%;
+}
+
+.info-banner {
+ background-color: rgba(colors.$secondary-color-light, 0.5);
+ padding: rem(4);
+ margin-bottom: 0 !important;
+}
+
+.residential-warning {
+ width: 74%;
+ background-color: rgba(colors.$secondary-color-light, 0.5);
+ margin-bottom: rem(20);
+ margin-left: 6.5%;
+}
+
+.residential-warning-text {
+ font-weight: 400;
+ font-size: rem(12);
+ margin: rem(10) 0 rem(20) rem(5);
+ line-height: rem(24);
+}
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.scss b/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.scss
index a4d0e0cc5..f6303c573 100644
--- a/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.scss
+++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/roso-proposal/roso-proposal.component.scss
@@ -1,4 +1,5 @@
@use '../../../../../../styles/functions' as *;
+@use '../../../../../../styles/colors';
section {
margin-top: rem(36);
@@ -7,3 +8,27 @@ section {
.steps-list {
margin: rem(16) 0;
}
+
+.mat-mdc-form-field {
+ width: 100%;
+}
+
+.info-banner {
+ background-color: rgba(colors.$secondary-color-light, 0.5);
+ padding: rem(4);
+ margin-bottom: 0 !important;
+}
+
+.residential-warning {
+ width: 74%;
+ background-color: rgba(colors.$secondary-color-light, 0.5);
+ margin-bottom: rem(20);
+ margin-left: 6.5%;
+}
+
+.residential-warning-text {
+ font-weight: 400;
+ font-size: rem(12);
+ margin: rem(10) 0 rem(20) rem(5);
+ line-height: rem(24);
+}
From 26365c02e08714ea8709ecafef67e0d5dc28d2d3 Mon Sep 17 00:00:00 2001
From: Tristan Slater <1631008+trslater@users.noreply.github.com>
Date: Thu, 24 Oct 2024 10:49:23 -0700
Subject: [PATCH 23/45] Fix structure add button layout
---
.../pfrs-proposal.component.html | 28 ++++++++++---------
.../pofo-proposal.component.html | 28 ++++++++++---------
.../pofo-proposal.component.scss | 1 +
.../roso-proposal.component.html | 28 ++++++++++---------
4 files changed, 46 insertions(+), 39 deletions(-)
diff --git a/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.html b/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.html
index 6d3192b52..5d46097a3 100644
--- a/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.html
+++ b/portal-frontend/src/app/features/applications/edit-submission/proposal/pfrs-proposal/pfrs-proposal.component.html
@@ -419,19 +419,21 @@ Proposal