Skip to content

Commit

Permalink
feat(cb2-14451): more edit mode progress
Browse files Browse the repository at this point in the history
  • Loading branch information
BrandonT95 committed Nov 28, 2024
1 parent 4ed3df2 commit 821483f
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ <h1>
</app-date-controls>

<!-- Month of manufacture (TRL Only) -->
<div *ngIf="shouldDisplayFormControl('techRecord_manufactureMonth')" class="govuk-form-group-select">
<label>
Month of manufacture
</label>
<app-control-errors elementId="techRecord_manufactureMonth" [control]="$any(form.get('techRecord_manufactureMonth'))" />
<select govukSelect formControlName="techRecord_manufactureMonth">
<option [value]="option.value" *ngFor="let option of months">{{ option.label }}</option>
</select>
</div>

<!-- Year of manufacture -->
<div *ngIf="shouldDisplayFormControl('techRecord_manufactureYear')" class="govuk-form-group-input">
Expand Down Expand Up @@ -77,8 +86,8 @@ <h1>
<input id="techRecord_noOfAxles" [width]="FormNodeWidth.XXS" govukInput formControlName="techRecord_noOfAxles" />
</div>

<!-- Vehicle Subclass (LGV/CAR only) -->
<ng-container *ngIf="techRecord().techRecord_vehicleType === VehicleTypes.LGV || techRecord().techRecord_vehicleType === VehicleTypes.CAR">
<!-- Vehicle Subclass (LGV/CAR/Small TRL only) -->
<ng-container *ngIf="shouldShowSubclass">
<govuk-checkbox-group
*ngIf="shouldDisplayFormControl('techRecord_vehicleSubclass')"
label="Vehicle subclass"
Expand Down Expand Up @@ -243,8 +252,8 @@ <h1>
</fieldset>
</div>

<!-- Vehicle class (HGV/Motorcycle) -->
<ng-container *ngIf="techRecord().techRecord_vehicleType === VehicleTypes.HGV || techRecord().techRecord_vehicleType === VehicleTypes.MOTORCYCLE">
<!-- Vehicle class (HGV/Motorcycle/Small TRL/TRL Only) -->
<ng-container *ngIf="shouldShowClass">
<ng-container *ngIf="shouldDisplayFormControl('techRecord_vehicleClass_description')" [ngTemplateOutlet]="vehicleClass"></ng-container>
</ng-container>

Expand Down Expand Up @@ -307,7 +316,7 @@ <h1>
</div>

<!-- Number of wheels (Motorcycle only) -->
<ng-container *ngIf="techRecord().techRecord_vehicleType === VehicleTypes.MOTORCYCLE">
<ng-container *ngIf="getVehicleType() === VehicleTypes.MOTORCYCLE">
<div *ngIf="shouldDisplayFormControl('techRecord_numberOfWheelsDriven')" class="govuk-form-group-input">
<h1>
<label tag for="techRecord_numberOfWheelsDriven"> Number of wheels <div>
Expand All @@ -328,7 +337,7 @@ <h1>
</div>

<!-- PSV Only Fields -->
<div class="govuk-form-group-split-controls" *ngIf="techRecord()?.techRecord_vehicleType === VehicleTypes.PSV">
<div class="govuk-form-group-split-controls" *ngIf="getVehicleType() === VehicleTypes.PSV">
<h1>
<label>Seats:</label>
</h1>
Expand Down Expand Up @@ -512,7 +521,7 @@ <h1>
<app-tag [type]="TagType.RED">{{ TagTypeLabels.REQUIRED }}</app-tag>
</div>
</label>
<div *ngIf="techRecord()?.techRecord_vehicleType === VehicleTypes.PSV" class="govuk-hint">
<div *ngIf="getVehicleType() === VehicleTypes.PSV" class="govuk-hint">
The Vehicle Class is calculated automatically based on the number of seats and standing capacity.
Only change the Class if you need to
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { FuelPropulsionSystem } from '@dvsa/cvs-type-definitions/types/v3/tech-r
import { TechRecordType } from '@dvsa/cvs-type-definitions/types/v3/tech-record/tech-record-vehicle-type';
import { getOptionsFromEnum } from '@forms/utils/enum-map';
import { CommonValidatorsService } from '@forms/validators/common-validators.service';
import { MultiOptions } from '@models/options.model';
import { EmissionStandard } from '@models/test-types/emissions.enum';
import {
HgvPsvVehicleConfiguration,
Expand All @@ -26,6 +27,7 @@ import { VehicleSize } from '@models/vehicle-size.enum';
import { FuelTypes, V3TechRecordModel, VehicleSubclass, VehicleTypes } from '@models/vehicle-tech-record.model';
import { Store } from '@ngrx/store';
import { FormNodeWidth, TagTypeLabels } from '@services/dynamic-forms/dynamic-form.types';
import { TechnicalRecordService } from '@services/technical-record/technical-record.service';
import { ReplaySubject } from 'rxjs';

type VehicleSectionForm = Partial<Record<keyof TechRecordType<'hgv' | 'car' | 'psv' | 'lgv' | 'trl'>, FormControl>>;
Expand All @@ -44,6 +46,7 @@ export class VehicleSectionEditComponent implements OnInit, OnDestroy {
store = inject(Store);
controlContainer = inject(ControlContainer);
commonValidators = inject(CommonValidatorsService);
technicalRecordService = inject(TechnicalRecordService);
techRecord = input.required<V3TechRecordModel>();

destroy$ = new ReplaySubject<boolean>(1);
Expand All @@ -56,8 +59,6 @@ export class VehicleSectionEditComponent implements OnInit, OnDestroy {
this.commonValidators.min(1000, 'Year of manufacture must be greater than or equal to 1000'),
this.commonValidators.pastYear('Year of manufacture must be the current or a past year'),
]),
techRecord_noOfAxles: this.fb.control<number | null>({ value: null, disabled: true }),
techRecord_regnDate: this.fb.control<string | null>(null),
techRecord_statusCode: this.fb.control<string | null>(null),
techRecord_vehicleConfiguration: this.fb.control<VehicleConfiguration | null>(null, [this.updateFunctionCode]),
techRecord_vehicleType: this.fb.control<VehicleTypes | null>({ value: null, disabled: true }),
Expand Down Expand Up @@ -108,11 +109,6 @@ export class VehicleSectionEditComponent implements OnInit, OnDestroy {
this.destroy$.complete();
}

// Potential to have a getter for each vehicle type as some vehicle types
// have different fields to others, this would allow for a more dynamic form
// could have an overall getter that sets the form with controls that belong
// to all vehicle types and then a getter for each vehicle type that adds the
// specific controls that only belong to that vehicle type?
get hgvFields(): Partial<Record<keyof TechRecordType<'hgv'>, FormControl>> {
return {
techRecord_alterationMarker: this.fb.control<boolean | null>(null),
Expand All @@ -131,6 +127,8 @@ export class VehicleSectionEditComponent implements OnInit, OnDestroy {
techRecord_vehicleClass_description: this.fb.control<string | null>(null, [
this.commonValidators.required('Vehicle class is required'),
]),
techRecord_regnDate: this.fb.control<string | null>(null),
techRecord_noOfAxles: this.fb.control<number | null>({ value: null, disabled: true }),
};
}

Expand Down Expand Up @@ -167,6 +165,8 @@ export class VehicleSectionEditComponent implements OnInit, OnDestroy {
techRecord_seatbeltInstallationApprovalDate: this.fb.control<string | null>(null, [
this.commonValidators.pastDate('Seatbelt installation approval date / type approved must be in the past'),
]),
techRecord_regnDate: this.fb.control<string | null>(null),
techRecord_noOfAxles: this.fb.control<number | null>({ value: null, disabled: true }),
};
}

Expand All @@ -185,12 +185,42 @@ export class VehicleSectionEditComponent implements OnInit, OnDestroy {
this.commonValidators.max(99999, 'Max load on coupling (optional) must be less than or equal to 99999'),
]),
techRecord_frameDescription: this.fb.control<string | null>(null),
techRecord_regnDate: this.fb.control<string | null>(null),
techRecord_noOfAxles: this.fb.control<number | null>({ value: null, disabled: true }),
techRecord_manufactureMonth: this.fb.control<string | null>(null, [
this.commonValidators.max(9999, 'Year of manufacture must be less than or equal to 9999'),
this.commonValidators.min(1000, 'Year of manufacture must be greater than or equal to 1000'),
this.commonValidators.xYearsAfterCurrent(
1,
`Year of manufacture must be equal to or before ${new Date().getFullYear() + 1}`
),
]),
};
}

get smallTrlFields(): Partial<Record<any, FormControl>> {
return {
techRecord_vehicleSubclass: this.fb.control<string[] | null>(null),
techRecord_manufactureMonth: this.fb.control<string | null>(null, [
this.commonValidators.max(9999, 'Year of manufacture must be less than or equal to 9999'),
this.commonValidators.min(1000, 'Year of manufacture must be greater than or equal to 1000'),
this.commonValidators.xYearsAfterCurrent(
1,
`Year of manufacture must be equal to or before ${new Date().getFullYear() + 1}`
),
]),
techRecord_vehicleClass_description: this.fb.control<string | null>(null, [
this.commonValidators.required('Vehicle class is required'),
]),
techRecord_noOfAxles: this.fb.control<number | null>(null),
};
}

get lgvAndCarFields(): Partial<Record<keyof TechRecordType<'lgv' | 'car'>, FormControl>> {
return {
techRecord_vehicleSubclass: this.fb.control<string[] | null>(null),
techRecord_regnDate: this.fb.control<string | null>(null),
techRecord_noOfAxles: this.fb.control<number | null>({ value: null, disabled: true }),
};
}

Expand All @@ -201,14 +231,11 @@ export class VehicleSectionEditComponent implements OnInit, OnDestroy {
techRecord_vehicleClass_description: this.fb.control<string | null>(null, [
this.commonValidators.required('Vehicle class is required'),
]),
techRecord_regnDate: this.fb.control<string | null>(null),
techRecord_noOfAxles: this.fb.control<number | null>({ value: null, disabled: true }),
};
}

isInvalid(formControlName: string) {
const control = this.form.get(formControlName);
return control?.invalid && control?.touched;
}

updateFunctionCode(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
if (control?.parent) {
Expand Down Expand Up @@ -303,6 +330,23 @@ export class VehicleSectionEditComponent implements OnInit, OnDestroy {
}
}

get months(): MultiOptions {
return [
{ value: 'January', label: 'January' },
{ value: 'February', label: 'Febraury' },
{ value: 'March', label: 'March' },
{ value: 'April', label: 'April' },
{ value: 'May', label: 'May' },
{ value: 'June', label: 'June' },
{ value: 'July', label: 'July' },
{ value: 'August', label: 'August' },
{ value: 'September', label: 'September' },
{ value: 'October', label: 'October' },
{ value: 'November', label: 'November' },
{ value: 'December', label: 'December' },
];
}

get subClassOptions() {
return getOptionsFromEnum(VehicleSubclass);
}
Expand All @@ -312,14 +356,15 @@ export class VehicleSectionEditComponent implements OnInit, OnDestroy {
}

get controlsBasedOffVehicleType() {
switch (this.techRecord()?.techRecord_vehicleType.toLowerCase()) {
switch (this.technicalRecordService.getVehicleTypeWithSmallTrl(this.techRecord())) {
case VehicleTypes.HGV:
return this.hgvFields;
case VehicleTypes.PSV:
return this.psvFields;
case VehicleTypes.TRL:
case VehicleTypes.SMALL_TRL:
return this.trlFields;
case VehicleTypes.SMALL_TRL:
return this.smallTrlFields;
case VehicleTypes.LGV:
case VehicleTypes.CAR:
return this.lgvAndCarFields;
Expand All @@ -337,20 +382,28 @@ export class VehicleSectionEditComponent implements OnInit, OnDestroy {
}
}

toggle(formControlName: string, value: string) {
const control = this.form.get(formControlName);
if (!control) return;
shouldDisplayFormControl(formControlName: string) {
return !!this.form.get(formControlName);
}

if (!control.value) {
return control.setValue([value]);
}
getVehicleType() {
return this.technicalRecordService.getVehicleTypeWithSmallTrl(this.techRecord());
}

const arr = [...control.value];
arr.includes(value) ? arr.splice(arr.indexOf(value), 1) : arr.push(value);
control.setValue(arr);
get shouldShowSubclass(): boolean {
return (
this.getVehicleType() === VehicleTypes.SMALL_TRL ||
this.getVehicleType() === VehicleTypes.LGV ||
this.getVehicleType() === VehicleTypes.CAR
);
}

shouldDisplayFormControl(formControlName: string) {
return !!this.form.get(formControlName);
get shouldShowClass(): boolean {
return (
this.getVehicleType() === VehicleTypes.TRL ||
this.getVehicleType() === VehicleTypes.SMALL_TRL ||
this.getVehicleType() === VehicleTypes.HGV ||
this.getVehicleType() === VehicleTypes.MOTORCYCLE
);
}
}
15 changes: 14 additions & 1 deletion src/app/forms/validators/common-validators.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Injectable } from '@angular/core';
import { ValidatorFn } from '@angular/forms';
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
import { CustomFormControl } from '@services/dynamic-forms/dynamic-form.types';
import validateDate from 'validate-govuk-date';

@Injectable({ providedIn: 'root' })
Expand Down Expand Up @@ -148,4 +149,16 @@ export class CommonValidatorsService {
return null;
};
}

xYearsAfterCurrent(xYears: number, message: string): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const currentYear = new Date().getFullYear();
const inputYear = control.value;
const maxYear = currentYear + xYears;
if (control instanceof CustomFormControl && inputYear && (inputYear > maxYear || inputYear < 0)) {
return { xYearsAfterCurrent: message };
}
return null;
};
}
}

0 comments on commit 821483f

Please sign in to comment.