Skip to content

Commit

Permalink
Add Other Structures to NOI Step 6 and Subtypes
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Haselhan committed Sep 19, 2023
1 parent 4a039f0 commit bd83d1d
Show file tree
Hide file tree
Showing 17 changed files with 231 additions and 248 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@
</div>
</ng-container>

<ng-container *ngIf="isSoilOtherStructureUseReasonVisible">
<div class="subheading2 grid-1">Describe the intended use of the 'Other' structure</div>
<div class="grid-double">
{{ _noiSubmission.soilStructureOtherUseReason }}
<app-no-data *ngIf="!_noiSubmission.soilStructureOtherUseReason"></app-no-data>
</div>
</ng-container>

<div class="subheading2 grid-1">Detailed Building Plan(s)</div>
<div class="grid-double multiple-documents">
<a *ngFor="let file of buildingPlans" (click)="openFile(file)">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,20 @@ export class AdditionalInformationComponent {
@Input() set noiSubmission(noiSubmission: NoticeOfIntentSubmissionDetailedDto | undefined) {
if (noiSubmission) {
this._noiSubmission = noiSubmission;
this.setVisibilityAndValidatorsForResidentialFields();
this.setVisibilityAndValidatorsForAccessoryFields();
this.setVisibilityAndValidatorsForFarmFields();

this.isSoilStructureResidentialUseReasonVisible = !!this._noiSubmission?.soilProposedStructures.some(
(structure) => structure.type && RESIDENTIAL_STRUCTURE_TYPES.includes(structure.type)
);

this.isSoilStructureResidentialAccessoryUseReasonVisible = !!this._noiSubmission?.soilProposedStructures.some(
(structure) => structure.type === STRUCTURE_TYPES.ACCESSORY_STRUCTURE
);

this.isSoilOtherStructureUseReasonVisible = !!this._noiSubmission?.soilProposedStructures.some(
(structure) => structure.type === STRUCTURE_TYPES.OTHER
);

this.setVisibilityForFarmFields();
this.setFirstQuestion(noiSubmission);
}
}
Expand All @@ -38,34 +49,11 @@ export class AdditionalInformationComponent {
isSoilStructureResidentialUseReasonVisible = false;
isSoilAgriParcelActivityVisible = false;
isSoilStructureResidentialAccessoryUseReasonVisible = false;
isSoilOtherStructureUseReasonVisible = false;

constructor(private router: Router, private noticeOfIntentDocumentService: NoiDocumentService) {}

private setVisibilityAndValidatorsForResidentialFields() {
if (
this._noiSubmission?.soilProposedStructures.some(
(structure) => structure.type && RESIDENTIAL_STRUCTURE_TYPES.includes(structure.type)
)
) {
this.isSoilStructureResidentialUseReasonVisible = true;
} else {
this.isSoilStructureResidentialUseReasonVisible = false;
}
}

private setVisibilityAndValidatorsForAccessoryFields() {
if (
this._noiSubmission?.soilProposedStructures.some(
(structure) => structure.type === STRUCTURE_TYPES.ACCESSORY_STRUCTURE
)
) {
this.isSoilStructureResidentialAccessoryUseReasonVisible = true;
} else {
this.isSoilStructureResidentialAccessoryUseReasonVisible = false;
}
}

private setVisibilityAndValidatorsForFarmFields() {
private setVisibilityForFarmFields() {
if (
this._noiSubmission?.soilProposedStructures.some((structure) => structure.type === STRUCTURE_TYPES.FARM_STRUCTURE)
) {
Expand All @@ -76,6 +64,7 @@ export class AdditionalInformationComponent {
this.isSoilStructureFarmUseReasonVisible = false;
}
}

async openFile(file: NoticeOfIntentDocumentDto) {
await this.noticeOfIntentDocumentService.download(file.uuid, file.fileName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ export class PreparationComponent implements OnInit {
return true;
}

const isOther =
submission.soilProposedStructures?.some((struct) => struct.type === STRUCTURE_TYPES.OTHER) &&
subtype.code === 'OTHR';
if (isOther) {
return true;
}

if (submission.soilIsAreaWideFilling && subtype.code === 'ARWF') {
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ export interface NoticeOfIntentSubmissionDetailedDto extends NoticeOfIntentSubmi
soilStructureResidentialUseReason?: string | null;
soilAgriParcelActivity?: string | null;
soilStructureResidentialAccessoryUseReason?: string | null;
soilStructureOtherUseReason?: string | null;
soilProposedStructures: ProposedStructure[];
}

Expand Down Expand Up @@ -273,6 +274,7 @@ export enum STRUCTURE_TYPES {
PRINCIPAL_RESIDENCE = 'Residential - Principal Residence',
ADDITIONAL_RESIDENCE = 'Residential - Additional Residence',
ACCESSORY_STRUCTURE = 'Residential - Accessory Structure',
OTHER = 'Other Structure',
}

export interface NoticeOfIntentOwnerDto {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class NoticeOfIntentService {
return await firstValueFrom(this.http.post<NoticeOfIntentDto>(`${this.url}/${fileNumber}`, updateDto));
} catch (e) {
console.error(e);
this.toastService.showErrorToast('Failed to create Notice of Intent');
this.toastService.showErrorToast('Failed to update Notice of Intent');
return undefined;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ <h2>Additional Proposal Information</h2>
<ng-container *ngIf="confirmRemovalOfSoil">
<div class="form-row">
<div class="full-row">
<form [formGroup]="lotsForm">
<form [formGroup]="structuresForm">
<label>Provide the total floor area (m<sup>2</sup>) of the proposed structure(s) </label>
<table mat-table [dataSource]="structuresSource">
<ng-container matColumnDef="index">
Expand All @@ -91,13 +91,13 @@ <h2>Additional Proposal Information</h2>
</mat-form-field>
<div
*ngIf="
lotsForm.controls[i + '-type']!.invalid &&
(lotsForm.controls[i + '-type']!.dirty || lotsForm.controls[i + '-type']!.touched)
structuresForm.controls[i + '-type']!.invalid &&
(structuresForm.controls[i + '-type']!.dirty || structuresForm.controls[i + '-type']!.touched)
"
class="field-error"
>
<mat-icon>warning</mat-icon>
<div *ngIf="lotsForm.controls[i + '-type']!.errors?.['required']">This field is required</div>
<div *ngIf="structuresForm.controls[i + '-type']!.errors?.['required']">This field is required</div>
</div>
</td>
</ng-container>
Expand All @@ -120,13 +120,13 @@ <h2>Additional Proposal Information</h2>
</mat-form-field>
<div
*ngIf="
lotsForm.controls[i + '-area']!.invalid &&
(lotsForm.controls[i + '-area']!.dirty || lotsForm.controls[i + '-area']!.touched)
structuresForm.controls[i + '-area']!.invalid &&
(structuresForm.controls[i + '-area']!.dirty || structuresForm.controls[i + '-area']!.touched)
"
class="field-error"
>
<mat-icon>warning</mat-icon>
<div *ngIf="lotsForm.controls[i + '-area']!.errors?.['required']">This field is required</div>
<div *ngIf="structuresForm.controls[i + '-area']!.errors?.['required']">This field is required</div>
</div>
</td>
</ng-container>
Expand Down Expand Up @@ -275,6 +275,31 @@ <h2>Additional Proposal Information</h2>
<div class="subtext">Characters left: {{ 4000 - structureResidentialAccessoryUseReasonText.textLength }}</div>
</div>

<div class="full-row" *ngIf="isSoilOtherUseReasonVisible">
<label for="soilStructureOtherUseReason"> Describe the intended use of the 'Other' structure </label>
<mat-form-field appearance="outline">
<textarea
formControlName="soilStructureOtherUseReason"
#soilStructureOtherUseReasonText
maxlength="4000"
id="soilStructureOtherUseReason"
matInput
placeholder="Type comment"
></textarea>
</mat-form-field>
<div
*ngIf="
soilStructureOtherUseReason.invalid &&
(soilStructureOtherUseReason.dirty || soilStructureOtherUseReason.touched)
"
class="field-error"
>
<mat-icon>warning</mat-icon>
<div *ngIf="soilStructureOtherUseReason.errors?.['required']">This field is required</div>
</div>
<div class="subtext">Characters left: {{ 4000 - soilStructureOtherUseReasonText.textLength }}</div>
</div>

<div class="full-row">
<label class="subheading2" for="detailed-building-plans">Detailed Building Plan(s)</label>
<div class="subtext">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export enum STRUCTURE_TYPES {
PRINCIPAL_RESIDENCE = 'Residential - Principal Residence',
ADDITIONAL_RESIDENCE = 'Residential - Additional Residence',
ACCESSORY_STRUCTURE = 'Residential - Accessory Structure',
OTHER_STRUCTURE = 'Other Structure',
}

type FormProposedStructure = { type: STRUCTURE_TYPES | null; area: string | null };
Expand All @@ -48,6 +49,7 @@ export class AdditionalInformationComponent extends FilesStepComponent implement
STRUCTURE_TYPES.PRINCIPAL_RESIDENCE,
STRUCTURE_TYPES.ADDITIONAL_RESIDENCE,
STRUCTURE_TYPES.ACCESSORY_STRUCTURE,
STRUCTURE_TYPES.OTHER_STRUCTURE,
];

private submissionUuid = '';
Expand All @@ -63,22 +65,25 @@ export class AdditionalInformationComponent extends FilesStepComponent implement
isSoilStructureResidentialUseReasonVisible = false;
isSoilAgriParcelActivityVisible = false;
isSoilStructureResidentialAccessoryUseReasonVisible = false;
isSoilOtherUseReasonVisible = false;

isRemovingSoilForNewStructure = new FormControl<string | null>(null, [Validators.required]);
soilStructureFarmUseReason = new FormControl<string | null>(null);
soilStructureResidentialUseReason = new FormControl<string | null>(null);
soilAgriParcelActivity = new FormControl<string | null>(null);
soilStructureResidentialAccessoryUseReason = new FormControl<string | null>(null);
soilStructureOtherUseReason = new FormControl<string | null>(null);

form = new FormGroup({
isRemovingSoilForNewStructure: this.isRemovingSoilForNewStructure,
soilStructureFarmUseReason: this.soilStructureFarmUseReason,
soilStructureResidentialUseReason: this.soilStructureResidentialUseReason,
soilAgriParcelActivity: this.soilAgriParcelActivity,
soilStructureResidentialAccessoryUseReason: this.soilStructureResidentialAccessoryUseReason,
soilStructureOtherUseReason: this.soilStructureOtherUseReason,
});

lotsForm = new FormGroup({} as any);
structuresForm = new FormGroup({} as any);

firstQuestion: string = 'FIX THIS';

Expand Down Expand Up @@ -118,6 +123,7 @@ export class AdditionalInformationComponent extends FilesStepComponent implement
soilStructureResidentialUseReason: noiSubmission.soilStructureResidentialUseReason,
soilAgriParcelActivity: noiSubmission.soilAgriParcelActivity,
soilStructureResidentialAccessoryUseReason: noiSubmission.soilStructureResidentialAccessoryUseReason,
soilStructureOtherUseReason: noiSubmission.soilStructureOtherUseReason,
});

this.proposedStructures = noiSubmission.soilProposedStructures.map((structure) => ({
Expand All @@ -130,13 +136,13 @@ export class AdditionalInformationComponent extends FilesStepComponent implement
newForm.addControl(`${index}-type`, new FormControl(lot.type, [Validators.required]));
newForm.addControl(`${index}-area`, new FormControl(lot.area, [Validators.required]));
}
this.lotsForm = newForm;
this.structuresForm = newForm;

this.structuresSource = new MatTableDataSource(this.proposedStructures);
this.prepareStructureSpecificTextInputs();

if (this.showErrors) {
this.lotsForm.markAllAsTouched();
this.structuresForm.markAllAsTouched();
this.form.markAllAsTouched();
}
}
Expand All @@ -151,6 +157,7 @@ export class AdditionalInformationComponent extends FilesStepComponent implement
this.setVisibilityAndValidatorsForFarmFields();
this.setVisibilityAndValidatorsForAccessoryFields();
this.setVisibilityAndValidatorsForResidentialFields();
this.setVisibilityAndValidatorsForOtherFields();
}

private setVisibilityAndValidatorsForResidentialFields() {
Expand All @@ -168,6 +175,20 @@ export class AdditionalInformationComponent extends FilesStepComponent implement
}
}

private setVisibilityAndValidatorsForOtherFields() {
const hasOtherStructure = this.proposedStructures.some(
(structure) => structure.type && structure.type === STRUCTURE_TYPES.OTHER_STRUCTURE
);
if (hasOtherStructure) {
this.isSoilOtherUseReasonVisible = true;
this.setRequired(this.soilStructureOtherUseReason);
} else {
this.isSoilOtherUseReasonVisible = false;
this.soilStructureOtherUseReason.removeValidators([Validators.required]);
this.soilStructureOtherUseReason.reset();
}
}

private setVisibilityAndValidatorsForAccessoryFields() {
if (this.proposedStructures.some((structure) => structure.type === STRUCTURE_TYPES.ACCESSORY_STRUCTURE)) {
this.isSoilStructureResidentialAccessoryUseReasonVisible = true;
Expand Down Expand Up @@ -200,17 +221,18 @@ export class AdditionalInformationComponent extends FilesStepComponent implement
}

protected async save(): Promise<void> {
if (this.fileId && (this.form.dirty || this.lotsForm.dirty)) {
const isRemovingSoilForNewStructure = this.isRemovingSoilForNewStructure.getRawValue();
const soilStructureFarmUseReason = this.soilStructureFarmUseReason.getRawValue();
const soilStructureResidentialUseReason = this.soilStructureResidentialUseReason.getRawValue();
const soilAgriParcelActivity = this.soilAgriParcelActivity.getRawValue();
const soilStructureResidentialAccessoryUseReason = this.soilStructureResidentialAccessoryUseReason.getRawValue();
if (this.fileId && (this.form.dirty || this.structuresForm.dirty)) {
const isRemovingSoilForNewStructure = this.isRemovingSoilForNewStructure.value;
const soilStructureFarmUseReason = this.soilStructureFarmUseReason.value;
const soilStructureResidentialUseReason = this.soilStructureResidentialUseReason.value;
const soilAgriParcelActivity = this.soilAgriParcelActivity.value;
const soilStructureResidentialAccessoryUseReason = this.soilStructureResidentialAccessoryUseReason.value;
const soilStructureOtherUseReason = this.soilStructureOtherUseReason.value;

const updatedStructures: ProposedStructure[] = [];
for (const [index, lot] of this.proposedStructures.entries()) {
const lotType = this.lotsForm.controls[`${index}-type`].value;
const lotArea = this.lotsForm.controls[`${index}-area`].value;
const lotType = this.structuresForm.controls[`${index}-type`].value;
const lotArea = this.structuresForm.controls[`${index}-area`].value;
updatedStructures.push({
type: lotType,
area: lotArea ? parseFloat(lotArea) : null,
Expand All @@ -223,6 +245,7 @@ export class AdditionalInformationComponent extends FilesStepComponent implement
soilIsRemovingSoilForNewStructure: parseStringToBoolean(isRemovingSoilForNewStructure),
soilAgriParcelActivity,
soilStructureResidentialAccessoryUseReason,
soilStructureOtherUseReason,
soilProposedStructures: updatedStructures,
};

Expand Down Expand Up @@ -286,9 +309,9 @@ export class AdditionalInformationComponent extends FilesStepComponent implement
private deleteStructure(index: number) {
const deletedStructure: FormProposedStructure = this.proposedStructures.splice(index, 1)[0];
this.structuresSource = new MatTableDataSource(this.proposedStructures);
this.lotsForm.removeControl(`${index}-type`);
this.lotsForm.removeControl(`${index}-area`);
this.lotsForm.markAsDirty();
this.structuresForm.removeControl(`${index}-type`);
this.structuresForm.removeControl(`${index}-area`);
this.structuresForm.markAsDirty();

if (deletedStructure.type === STRUCTURE_TYPES.FARM_STRUCTURE) {
this.setVisibilityAndValidatorsForFarmFields();
Expand All @@ -301,16 +324,20 @@ export class AdditionalInformationComponent extends FilesStepComponent implement
if (deletedStructure.type && RESIDENTIAL_STRUCTURE_TYPES.includes(deletedStructure.type)) {
this.setVisibilityAndValidatorsForResidentialFields();
}

if (deletedStructure.type === STRUCTURE_TYPES.OTHER_STRUCTURE) {
this.setVisibilityAndValidatorsForOtherFields();
}
}

onStructureAdd() {
this.proposedStructures.push({ type: null, area: '' });
this.structuresSource = new MatTableDataSource(this.proposedStructures);

const index = this.proposedStructures.length - 1;
this.lotsForm.addControl(`${index}-type`, new FormControl(null, [Validators.required]));
this.lotsForm.addControl(`${index}-area`, new FormControl(null, [Validators.required]));
this.lotsForm.markAsDirty();
this.structuresForm.addControl(`${index}-type`, new FormControl(null, [Validators.required]));
this.structuresForm.addControl(`${index}-area`, new FormControl(null, [Validators.required]));
this.structuresForm.markAsDirty();
}

private setRequired(formControl: FormControl<any>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,19 @@
</div>
</ng-container>

<ng-container *ngIf="isSoilOtherStructureVisible">
<div class="subheading2 grid-1">
Describe the intended use of the 'Other' structure
<app-updated-banner
*ngIf="updatedFields.includes('soilStructureResidentialAccessoryUseReason')"
></app-updated-banner>
</div>
<div class="grid-double">
{{ _noiSubmission.soilStructureOtherUseReason }}
<app-no-data [showRequired]="showErrors" *ngIf="!_noiSubmission.soilStructureOtherUseReason"></app-no-data>
</div>
</ng-container>

<div class="subheading2 grid-1">Detailed Building Plan(s)</div>
<div class="grid-double multiple-documents">
<a *ngFor="let file of buildingPlans" (click)="openFile(file.uuid)">
Expand Down
Loading

0 comments on commit bd83d1d

Please sign in to comment.