From 1645dddf3632a01807a924a758c538052229c379 Mon Sep 17 00:00:00 2001 From: Brandon Thomas-Davies <87308252+BrandonT95@users.noreply.github.com> Date: Thu, 28 Mar 2024 10:02:45 +0000 Subject: [PATCH 01/20] feat(cb2-10241): update adr notes to use custom component (#1446) --- .../view-list-item.component.html | 29 ------------------- ...examiner-notes-history-view.component.html | 10 +++---- .../forms/templates/general/adr.template.ts | 2 +- 3 files changed, 6 insertions(+), 35 deletions(-) diff --git a/src/app/forms/components/view-list-item/view-list-item.component.html b/src/app/forms/components/view-list-item/view-list-item.component.html index 254413c294..8ded37f9b4 100644 --- a/src/app/forms/components/view-list-item/view-list-item.component.html +++ b/src/app/forms/components/view-list-item/view-list-item.component.html @@ -20,35 +20,6 @@ - - - - - - - - - - - - - - - - - - -
DateCreated ByNotes
- {{ result.createdAtDate | date : 'dd/MM/yyyy' | defaultNullOrEmpty }} - {{ result.lastUpdatedBy }}{{ result.note }}
-
-
-
No additional examiner notes history available
-
-
- -
- diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html index 6e640b7c6e..87203f4425 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html @@ -1,21 +1,21 @@
-

ADR Examiner Notes History

+

Additional Examiner Notes History

- - + + diff --git a/src/app/forms/templates/general/adr.template.ts b/src/app/forms/templates/general/adr.template.ts index 4cc047312e..b1a86e2191 100644 --- a/src/app/forms/templates/general/adr.template.ts +++ b/src/app/forms/templates/general/adr.template.ts @@ -775,7 +775,7 @@ export const AdrTemplate: FormNode = { label: 'Additional examiner notes history', value: null, type: FormNodeTypes.CONTROL, - viewType: FormNodeViewTypes.ADR_EXAMINER_NOTES, // TODO: replace with custom + viewType: FormNodeViewTypes.CUSTOM, viewComponent: AdrExaminerNotesHistoryViewComponent, editType: FormNodeEditTypes.CUSTOM, editComponent: AdrExaminerNotesHistoryEditComponent, From e7e4fd5308ecf553a0f70498e1bf71e7a469632c Mon Sep 17 00:00:00 2001 From: Thomas Crawley Date: Tue, 2 Apr 2024 09:08:46 +0100 Subject: [PATCH 02/20] feat/CB2-11250 - Edit button on additional examiner notes takes you to blank page (#1447) * feat(cb2-10241): update adr notes to use custom component * feat(cb2-11250): format table * feat(cb2-11250): set up router link * feat(cb2-11250): blank page link working * feat(cb2-11250): revert unnecessary changes * feat(cb2-11250): amend routing function * feat(cb2-11250): fix linting and add unit test * feat(cb2-11250): fix linting and add unit test * feat(cb2-11250): update link design * feat(cb2-11250): fix button link styling --------- Co-authored-by: Brandon Thomas-Davies <87308252+BrandonT95@users.noreply.github.com> --- ...it-additional-examiner-note.component.html | 1 + ...it-additional-examiner-note.component.scss | 0 ...additional-examiner-note.component.spec.ts | 38 ++++++++++++ ...edit-additional-examiner-note.component.ts | 10 ++++ .../tech-record/tech-record-routing.module.ts | 59 ++++++++++++++++--- .../tech-record/tech-record.module.ts | 4 ++ ...examiner-notes-history-edit.component.html | 12 ++-- ...examiner-notes-history.component-edit.scss | 8 ++- ...miner-notes-history.component-edit.spec.ts | 18 +++++- ...r-examiner-notes-history.component-edit.ts | 21 ++++++- src/app/models/routes.enum.ts | 2 + 11 files changed, 158 insertions(+), 15 deletions(-) create mode 100644 src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.html create mode 100644 src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.scss create mode 100644 src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.spec.ts create mode 100644 src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.ts diff --git a/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.html b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.html new file mode 100644 index 0000000000..d2e41facc2 --- /dev/null +++ b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.html @@ -0,0 +1 @@ +
This is a blank page right now.
diff --git a/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.scss b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.spec.ts b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.spec.ts new file mode 100644 index 0000000000..f829df2360 --- /dev/null +++ b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.spec.ts @@ -0,0 +1,38 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { + AdrExaminerNotesHistoryEditComponent +} from '@forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit'; +import { DynamicFormsModule } from '@forms/dynamic-forms.module'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { RouterTestingModule } from '@angular/router/testing'; +import { TechnicalRecordService } from '@services/technical-record/technical-record.service'; +import { provideMockStore } from '@ngrx/store/testing'; +import { initialAppState } from '@store/index'; +import { ActivatedRoute, Router } from '@angular/router'; +import { of } from 'rxjs'; +import { TechRecordEditAdditionalExaminerNoteComponent } from './tech-record-edit-additional-examiner-note.component'; + + +const mockTechRecordService = { + techRecord$: jest.fn(), +}; +describe('TechRecordEditAdditionalExaminerNoteComponent', () => { + let fixture: ComponentFixture; + let component: TechRecordEditAdditionalExaminerNoteComponent; + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [TechRecordEditAdditionalExaminerNoteComponent], + imports: [DynamicFormsModule, FormsModule, ReactiveFormsModule, RouterTestingModule], + providers: [ + { provide: TechnicalRecordService, useValue: mockTechRecordService }, + provideMockStore({ initialState: initialAppState }), + { provide: ActivatedRoute, useValue: { params: of([{ id: 1 }]) } }, + ], + }).compileComponents(); + fixture = TestBed.createComponent(AdrExaminerNotesHistoryEditComponent); + component = fixture.componentInstance; + }); + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.ts b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.ts new file mode 100644 index 0000000000..b8139fa97c --- /dev/null +++ b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'tech-record-edit-additional-examiner-note', + templateUrl: './tech-record-edit-additional-examiner-note.component.html', + styleUrls: ['./tech-record-edit-additional-examiner-note.component.scss'], +}) +export class TechRecordEditAdditionalExaminerNoteComponent { + +} diff --git a/src/app/features/tech-record/tech-record-routing.module.ts b/src/app/features/tech-record/tech-record-routing.module.ts index 757d0dc75b..717d3f920b 100644 --- a/src/app/features/tech-record/tech-record-routing.module.ts +++ b/src/app/features/tech-record/tech-record-routing.module.ts @@ -10,20 +10,39 @@ import { techRecordDataResolver } from 'src/app/resolvers/tech-record-data/tech- import { techRecordValidateResolver } from 'src/app/resolvers/tech-record-validate/tech-record-validate.resolver'; import { techRecordViewResolver } from 'src/app/resolvers/tech-record-view/tech-record-view.resolver'; import { TechRecordRoutes } from '@models/routes.enum'; -import { AdrGenerateCertificateComponent } from './components/adr-generate-certificate/adr-generate-certificate.component'; -import { TechRecordAmendReasonComponent } from './components/tech-record-amend-reason/tech-record-amend-reason.component'; +import { + AdrGenerateCertificateComponent, +} from './components/adr-generate-certificate/adr-generate-certificate.component'; +import { + TechRecordAmendReasonComponent, +} from './components/tech-record-amend-reason/tech-record-amend-reason.component'; import { AmendVinComponent } from './components/tech-record-amend-vin/tech-record-amend-vin.component'; -import { AmendVrmReasonComponent } from './components/tech-record-amend-vrm-reason/tech-record-amend-vrm-reason.component'; +import { + AmendVrmReasonComponent, +} from './components/tech-record-amend-vrm-reason/tech-record-amend-vrm-reason.component'; import { AmendVrmComponent } from './components/tech-record-amend-vrm/tech-record-amend-vrm.component'; -import { TechRecordChangeStatusComponent } from './components/tech-record-change-status/tech-record-change-status.component'; +import { + TechRecordChangeStatusComponent, +} from './components/tech-record-change-status/tech-record-change-status.component'; import { ChangeVehicleTypeComponent } from './components/tech-record-change-type/tech-record-change-type.component'; -import { TechRecordChangeVisibilityComponent } from './components/tech-record-change-visibility/tech-record-change-visibility.component'; -import { GenerateLetterComponent } from './components/tech-record-generate-letter/tech-record-generate-letter.component'; +import { + TechRecordChangeVisibilityComponent, +} from './components/tech-record-change-visibility/tech-record-change-visibility.component'; +import { + GenerateLetterComponent, +} from './components/tech-record-generate-letter/tech-record-generate-letter.component'; import { GeneratePlateComponent } from './components/tech-record-generate-plate/tech-record-generate-plate.component'; -import { TechRecordSearchTyresComponent } from './components/tech-record-search-tyres/tech-record-search-tyres.component'; -import { TechRecordSummaryChangesComponent } from './components/tech-record-summary-changes/tech-record-summary-changes.component'; +import { + TechRecordSearchTyresComponent, +} from './components/tech-record-search-tyres/tech-record-search-tyres.component'; +import { + TechRecordSummaryChangesComponent, +} from './components/tech-record-summary-changes/tech-record-summary-changes.component'; import { TechRecordUnarchiveComponent } from './components/tech-record-unarchive/tech-record-unarchive-component'; import { TechRecordComponent } from './tech-record.component'; +import { + TechRecordEditAdditionalExaminerNoteComponent, +} from './components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component'; const routes: Routes = [ { @@ -154,6 +173,18 @@ const routes: Routes = [ data: { roles: Roles.TechRecordAmend }, canActivate: [MsalGuard, RoleGuard], }, + { + path: TechRecordRoutes.CORRECT_ERROR_EDIT_ADDITIONAL_EXAMINER_NOTE, + component: TechRecordEditAdditionalExaminerNoteComponent, + data: { + title: 'edit-additional-examiner-note', + roles: Roles.TechRecordAmend, + isEditing: true, + reason: ReasonForEditing.CORRECTING_AN_ERROR, + }, + canActivate: [MsalGuard, RoleGuard], + resolve: { techRecord: techRecordViewResolver }, + }, { path: TechRecordRoutes.NOTIFIABLE_ALTERATION_NEEDED_CHANGE_SUMMARY, component: TechRecordSummaryChangesComponent, @@ -172,6 +203,18 @@ const routes: Routes = [ canActivate: [MsalGuard, RoleGuard], resolve: { techRecord: techRecordViewResolver }, }, + { + path: TechRecordRoutes.NOTIFIABLE_ALTERNATION_NEEDED_EDIT_ADDITIONAL_EXAMINER_NOTE, + component: TechRecordEditAdditionalExaminerNoteComponent, + data: { + title: 'edit-additional-examiner-note', + roles: Roles.TechRecordAmend, + isEditing: true, + reason: ReasonForEditing.NOTIFIABLE_ALTERATION_NEEDED, + }, + canActivate: [MsalGuard, RoleGuard], + resolve: { techRecord: techRecordViewResolver }, + }, { path: TechRecordRoutes.TEST_RECORDS, data: { title: 'Test record', roles: Roles.TestResultView }, diff --git a/src/app/features/tech-record/tech-record.module.ts b/src/app/features/tech-record/tech-record.module.ts index 7ad498a655..34c34563bf 100644 --- a/src/app/features/tech-record/tech-record.module.ts +++ b/src/app/features/tech-record/tech-record.module.ts @@ -25,6 +25,9 @@ import { TechRecordComponent } from './tech-record.component'; import { AmendVrmReasonComponent } from './components/tech-record-amend-vrm-reason/tech-record-amend-vrm-reason.component'; import { TechRecordSummaryChangesComponent } from './components/tech-record-summary-changes/tech-record-summary-changes.component'; import { AdrGenerateCertificateComponent } from './components/adr-generate-certificate/adr-generate-certificate.component'; +import { + TechRecordEditAdditionalExaminerNoteComponent, +} from './components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component'; @NgModule({ declarations: [ @@ -43,6 +46,7 @@ import { AdrGenerateCertificateComponent } from './components/adr-generate-certi TechRecordHistoryComponent, TechRecordSearchTyresComponent, TechRecordTitleComponent, + TechRecordEditAdditionalExaminerNoteComponent, TechRouterOutletComponent, TestRecordSummaryComponent, VehicleTechnicalRecordComponent, diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html index aa75a8a9dd..1a3319f3a9 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html @@ -8,18 +8,22 @@
DateCreated By NotesCreated ByDate
- {{ result.createdAtDate | date : 'dd/MM/yyyy' | defaultNullOrEmpty }} + {{ result.note }} {{ result.lastUpdatedBy }} - {{ result.note }} + {{ result.createdAtDate | date : 'dd/MM/yyyy' | defaultNullOrEmpty }}
- - + + + + diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.scss b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.scss index dc97c176aa..2df9a0b23d 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.scss +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.scss @@ -15,4 +15,10 @@ display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 5; -} \ No newline at end of file +} + +.button { + cursor: pointer; + text-decoration: underline; + color: blue; +} diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.spec.ts b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.spec.ts index 8f3255936e..b66f521c34 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.spec.ts +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.spec.ts @@ -8,6 +8,11 @@ import { DynamicFormsModule } from '@forms/dynamic-forms.module'; import { mockVehicleTechnicalRecord } from '@mocks/mock-vehicle-technical-record.mock'; import { VehicleTypes } from '@models/vehicle-tech-record.model'; import { TechnicalRecordService } from '@services/technical-record/technical-record.service'; +import { provideMockStore } from '@ngrx/store/testing'; +import { initialAppState } from '@store/index'; +import { ActivatedRoute, Router } from '@angular/router'; +import { of } from 'rxjs'; +import { RouterTestingModule } from '@angular/router/testing'; const mockTechRecordService = { techRecord$: jest.fn(), @@ -15,16 +20,20 @@ const mockTechRecordService = { describe('AdrExaminerNotesHistoryEditComponent', () => { let component: AdrExaminerNotesHistoryEditComponent; let fixture: ComponentFixture; + let router: Router; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [AdrExaminerNotesHistoryEditComponent], - imports: [DynamicFormsModule, FormsModule, ReactiveFormsModule], + imports: [DynamicFormsModule, FormsModule, ReactiveFormsModule, RouterTestingModule], providers: [ { provide: TechnicalRecordService, useValue: mockTechRecordService }, + provideMockStore({ initialState: initialAppState }), + { provide: ActivatedRoute, useValue: { params: of([{ id: 1 }]) } }, ], }).compileComponents(); fixture = TestBed.createComponent(AdrExaminerNotesHistoryEditComponent); component = fixture.componentInstance; + router = TestBed.inject(Router); }); describe('ngOnDestroy', () => { it('should call destroy$.next and destroy$.complete', () => { @@ -56,4 +65,11 @@ describe('AdrExaminerNotesHistoryEditComponent', () => { expect(notes).toEqual([testNote]); }); }); + describe('getEditAdditionalExaminerNotePage', () => { + it('should navigate you to the EditAdditionalExaminerNotePage', () => { + const routerSpy = jest.spyOn(router, 'navigate'); + component.getEditAdditionalExaminerNotePage(1); + expect(routerSpy).toHaveBeenCalled(); + }); + }); }); diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.ts b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.ts index 608210e6da..cf732128cf 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.ts +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.ts @@ -1,4 +1,4 @@ -import { KeyValue } from '@angular/common'; +import { KeyValue, ViewportScroller } from '@angular/common'; import { AfterContentInit, Component, inject, OnDestroy, OnInit, @@ -9,6 +9,11 @@ import { BaseControlComponent } from '@forms/components/base-control/base-contro import { CustomControl, CustomFormControl } from '@forms/services/dynamic-form.types'; import { TechnicalRecordService } from '@services/technical-record/technical-record.service'; import { ReplaySubject, takeUntil } from 'rxjs'; +import { updateScrollPosition } from '@store/technical-records'; +import { TechnicalRecordServiceState } from '@store/technical-records/reducers/technical-record-service.reducer'; +import { Store } from '@ngrx/store'; +import { ActivatedRoute, Router } from '@angular/router'; +import { ReasonForEditing } from '@models/vehicle-tech-record.model'; @Component({ selector: 'app-adr-examiner-notes-history', @@ -22,6 +27,11 @@ export class AdrExaminerNotesHistoryEditComponent extends BaseControlComponent i formArray = new FormArray([]); currentTechRecord?: TechRecordType<'hgv' | 'lgv' | 'trl'> = undefined; technicalRecordService = inject(TechnicalRecordService); + store = inject(Store); + viewportScroller = inject(ViewportScroller); + router = inject(Router); + route = inject(ActivatedRoute); + editingReason?: ReasonForEditing; ngOnInit() { this.formArray.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((changes) => { @@ -30,6 +40,7 @@ export class AdrExaminerNotesHistoryEditComponent extends BaseControlComponent i this.technicalRecordService.techRecord$.pipe(takeUntil(this.destroy$)).subscribe((currentTechRecord) => { this.currentTechRecord = currentTechRecord as TechRecordType<'hgv' | 'lgv' | 'trl'>; }); + this.editingReason = this.route.snapshot.data['reason']; } override ngAfterContentInit() { @@ -48,6 +59,14 @@ export class AdrExaminerNotesHistoryEditComponent extends BaseControlComponent i return returnValue; } + getEditAdditionalExaminerNotePage(examinerNoteIndex: number) { + const route = `../${this.editingReason}/edit-additional-examiner-note/${examinerNoteIndex}`; + + this.store.dispatch(updateScrollPosition({ position: this.viewportScroller.getScrollPosition() })); + + void this.router.navigate([route], { relativeTo: this.route, state: this.currentTechRecord }); + } + ngOnDestroy() { this.destroy$.next(true); this.destroy$.complete(); diff --git a/src/app/models/routes.enum.ts b/src/app/models/routes.enum.ts index f478b7c7d4..1df9e718a1 100644 --- a/src/app/models/routes.enum.ts +++ b/src/app/models/routes.enum.ts @@ -30,8 +30,10 @@ export enum TechRecordRoutes { CHANGE_VTA_VISIBILITY = 'change-vta-visibility', CORRECT_ERROR_TYRE_SEARCH = 'correcting-an-error/tyre-search/:axleNumber', CORRECT_ERROR_CHANGE_SUMMARY = 'correcting-an-error/change-summary', + CORRECT_ERROR_EDIT_ADDITIONAL_EXAMINER_NOTE = 'correcting-an-error/edit-additional-examiner-note/:examinerNoteIndex', NOTIFIABLE_ALTERATION_NEEDED_CHANGE_SUMMARY = 'notifiable-alteration-needed/change-summary', NOTIFIABLE_ALTERATION_NEEDED_TYRE_SEARCH = 'notifiable-alteration-needed/tyre-search/:axleNumber', + NOTIFIABLE_ALTERNATION_NEEDED_EDIT_ADDITIONAL_EXAMINER_NOTE = 'notifiable-alteration-needed/edit-additional-examiner-note/:examinerNoteIndex', TEST_RECORDS = 'test-records/test-result/:testResultId/:testNumber', CREATE_TEST = 'test-records/create-test', ADR_CERTIFICATE = 'adr-certificate', From 40463f6addd1a6f978d457496aa72066c982a29c Mon Sep 17 00:00:00 2001 From: Brandon Thomas-Davies <87308252+BrandonT95@users.noreply.github.com> Date: Wed, 3 Apr 2024 08:39:26 +0100 Subject: [PATCH 03/20] feat(CB2-9916): Add warning to cherished transfer (#1451) * feat(cb2-9916): added cherised transfer warning message for psv and hgv * feat(cb2-9916): fix linting --- .../tech-record-amend-vrm.component.html | 6 ++++ .../tech-record-amend-vrm.component.spec.ts | 35 +++++++++++++++++-- .../tech-record-amend-vrm.component.ts | 7 ++++ ...additional-examiner-note.component.spec.ts | 5 ++- src/app/forms/dynamic-forms.module.ts | 1 + 5 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/app/features/tech-record/components/tech-record-amend-vrm/tech-record-amend-vrm.component.html b/src/app/features/tech-record/components/tech-record-amend-vrm/tech-record-amend-vrm.component.html index 2c6299caad..3d5c835d55 100644 --- a/src/app/features/tech-record/components/tech-record-amend-vrm/tech-record-amend-vrm.component.html +++ b/src/app/features/tech-record/components/tech-record-amend-vrm/tech-record-amend-vrm.component.html @@ -1,4 +1,10 @@
+

{{ makeAndModel }}

diff --git a/src/app/features/tech-record/components/tech-record-amend-vrm/tech-record-amend-vrm.component.spec.ts b/src/app/features/tech-record/components/tech-record-amend-vrm/tech-record-amend-vrm.component.spec.ts index 584608d6d5..962cf5989f 100644 --- a/src/app/features/tech-record/components/tech-record-amend-vrm/tech-record-amend-vrm.component.spec.ts +++ b/src/app/features/tech-record/components/tech-record-amend-vrm/tech-record-amend-vrm.component.spec.ts @@ -1,6 +1,4 @@ -import { - ComponentFixture, fakeAsync, TestBed, -} from '@angular/core/testing'; +import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { ActivatedRoute, ActivatedRouteSnapshot, Router } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; @@ -31,6 +29,7 @@ const mockTechRecordService = { validateVrmDoesNotExist: jest.fn(), validateVrmForCherishedTransfer: jest.fn(), checkVrmNotActive: jest.fn(), + getVehicleTypeWithSmallTrl: jest.fn(), }; const mockDynamicFormService = { @@ -170,4 +169,34 @@ describe('TechRecordChangeVrmComponent', () => { ); }); }); + + describe('showWarning', () => { + it('should return true if the vehicle type is a psv', () => { + component.techRecord = { techRecord_vehicleType: 'psv' } as VehiclesOtherThan<'trl'>; + mockTechRecordService.getVehicleTypeWithSmallTrl.mockReturnValue('psv'); + + expect(component.showWarning).toBe(true); + }); + + it('should return true if the vehicle type is a hgv', () => { + component.techRecord = { techRecord_vehicleType: 'hgv' } as VehiclesOtherThan<'trl'>; + mockTechRecordService.getVehicleTypeWithSmallTrl.mockReturnValue('hgv'); + + expect(component.showWarning).toBe(true); + }); + + it('should return false if the vehicle type is not a psv or hgv', () => { + component.techRecord = { techRecord_vehicleType: 'lgv' } as VehiclesOtherThan<'trl'>; + mockTechRecordService.getVehicleTypeWithSmallTrl.mockReturnValue('lgv'); + + expect(component.showWarning).toBe(false); + }); + + it('should default to false if the vehicle type is not present', () => { + component.techRecord = undefined; + mockTechRecordService.getVehicleTypeWithSmallTrl.mockReturnValue(undefined); + + expect(component.showWarning).toBe(false); + }); + }); }); diff --git a/src/app/features/tech-record/components/tech-record-amend-vrm/tech-record-amend-vrm.component.ts b/src/app/features/tech-record/components/tech-record-amend-vrm/tech-record-amend-vrm.component.ts index a3a23fdfde..90cf3ceed4 100644 --- a/src/app/features/tech-record/components/tech-record-amend-vrm/tech-record-amend-vrm.component.ts +++ b/src/app/features/tech-record/components/tech-record-amend-vrm/tech-record-amend-vrm.component.ts @@ -169,4 +169,11 @@ export class AmendVrmComponent implements OnDestroy, OnInit { } return true; } + + get showWarning(): boolean { + if (this.vehicleType) { + return this.vehicleType === 'psv' || this.vehicleType === 'hgv'; + } + return false; + } } diff --git a/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.spec.ts b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.spec.ts index f829df2360..65bf1af725 100644 --- a/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.spec.ts +++ b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.spec.ts @@ -1,6 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { - AdrExaminerNotesHistoryEditComponent + AdrExaminerNotesHistoryEditComponent, } from '@forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit'; import { DynamicFormsModule } from '@forms/dynamic-forms.module'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; @@ -8,11 +8,10 @@ import { RouterTestingModule } from '@angular/router/testing'; import { TechnicalRecordService } from '@services/technical-record/technical-record.service'; import { provideMockStore } from '@ngrx/store/testing'; import { initialAppState } from '@store/index'; -import { ActivatedRoute, Router } from '@angular/router'; +import { ActivatedRoute } from '@angular/router'; import { of } from 'rxjs'; import { TechRecordEditAdditionalExaminerNoteComponent } from './tech-record-edit-additional-examiner-note.component'; - const mockTechRecordService = { techRecord$: jest.fn(), }; diff --git a/src/app/forms/dynamic-forms.module.ts b/src/app/forms/dynamic-forms.module.ts index 306df05dec..9e319d5046 100644 --- a/src/app/forms/dynamic-forms.module.ts +++ b/src/app/forms/dynamic-forms.module.ts @@ -192,6 +192,7 @@ import { SuffixDirective } from './directives/suffix.directive'; ModifiedWeightsComponent, AdrComponent, AdrCertificateHistoryComponent, + FieldWarningMessageComponent, ], }) export class DynamicFormsModule { } From 6ffb3c3225c2ce82de76c8890096a2ca53957dd2 Mon Sep 17 00:00:00 2001 From: Brandon Thomas-Davies <87308252+BrandonT95@users.noreply.github.com> Date: Wed, 3 Apr 2024 09:35:48 +0100 Subject: [PATCH 04/20] feat(cb2-10032): add pagination to adr examiner notes (#1450) * feat(cb2-10032): add pagination to adr examiner notes * feat(cb2-10032): add pagination to notes amend view --- ...examiner-notes-history-edit.component.html | 9 ++- ...miner-notes-history.component-edit.spec.ts | 35 ++++++++++ ...r-examiner-notes-history.component-edit.ts | 27 ++++--- ...examiner-notes-history-view.component.html | 67 ++++++++++-------- ...miner-notes-history-view.component.spec.ts | 70 +++++++++++++++++++ ...r-examiner-notes-history-view.component.ts | 40 ++++++++++- 6 files changed, 207 insertions(+), 41 deletions(-) diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html index 1a3319f3a9..d92ac9a219 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html @@ -13,7 +13,7 @@
- +
DateCreated By NotesCreated ByDate
- {{ examinerNote.createdAtDate | date : 'dd/MM/yyyy' | defaultNullOrEmpty }} + {{ examinerNote.note }} {{ examinerNote.lastUpdatedBy }} - {{ examinerNote.note }} + {{ examinerNote.createdAtDate | date: 'dd/MM/yyyy' | defaultNullOrEmpty }} + + Edit
Date
{{ examinerNote.note }} @@ -29,6 +29,13 @@
+
diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.spec.ts b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.spec.ts index b66f521c34..3f01703139 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.spec.ts +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.spec.ts @@ -21,6 +21,9 @@ describe('AdrExaminerNotesHistoryEditComponent', () => { let component: AdrExaminerNotesHistoryEditComponent; let fixture: ComponentFixture; let router: Router; + + const MOCK_HGV = mockVehicleTechnicalRecord(VehicleTypes.HGV) as TechRecordType<'hgv'>; + beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [AdrExaminerNotesHistoryEditComponent], @@ -72,4 +75,36 @@ describe('AdrExaminerNotesHistoryEditComponent', () => { expect(routerSpy).toHaveBeenCalled(); }); }); + + describe('handlePaginationChange', () => { + it('should set the start and end pages', () => { + component.handlePaginationChange({ start: 0, end: 3 }); + + expect(component.pageStart).toBe(0); + expect(component.pageEnd).toBe(3); + }); + }); + + describe('currentAdrNotesPage', () => { + it('should return a sliced array of adr notes depending on the page the user is on', () => { + component.currentTechRecord = { ...MOCK_HGV }; + component.pageStart = 1; + component.pageEnd = 2; + component.currentTechRecord.techRecord_adrDetails_additionalExaminerNotes = [ + { createdAtDate: 'test1', lastUpdatedBy: 'test1', note: 'test note 1' }, + { createdAtDate: 'test2', lastUpdatedBy: 'test2', note: 'test note 2' }, + ]; + expect(component.currentAdrNotesPage).toEqual([ + { createdAtDate: 'test2', lastUpdatedBy: 'test2', note: 'test note 2' }, + ]); + }); + + it('should return an empty array if the adr examiner notes is undefined', () => { + component.currentTechRecord = { ...MOCK_HGV }; + component.pageStart = 2; + component.pageEnd = 3; + component.currentTechRecord.techRecord_adrDetails_additionalExaminerNotes = undefined; + expect(component.currentAdrNotesPage).toEqual([]); + }); + }); }); diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.ts b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.ts index cf732128cf..08e212cf4e 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.ts +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.ts @@ -14,6 +14,7 @@ import { TechnicalRecordServiceState } from '@store/technical-records/reducers/t import { Store } from '@ngrx/store'; import { ActivatedRoute, Router } from '@angular/router'; import { ReasonForEditing } from '@models/vehicle-tech-record.model'; +import { AdditionalExaminerNotes } from '@dvsa/cvs-type-definitions/types/v3/tech-record/get/hgv/complete'; @Component({ selector: 'app-adr-examiner-notes-history', @@ -21,9 +22,7 @@ import { ReasonForEditing } from '@models/vehicle-tech-record.model'; styleUrls: ['adr-examiner-notes-history.component-edit.scss'], }) export class AdrExaminerNotesHistoryEditComponent extends BaseControlComponent implements OnInit, OnDestroy, AfterContentInit { - destroy$ = new ReplaySubject(1); - formArray = new FormArray([]); currentTechRecord?: TechRecordType<'hgv' | 'lgv' | 'trl'> = undefined; technicalRecordService = inject(TechnicalRecordService); @@ -32,8 +31,10 @@ export class AdrExaminerNotesHistoryEditComponent extends BaseControlComponent i router = inject(Router); route = inject(ActivatedRoute); editingReason?: ReasonForEditing; + pageStart?: number; + pageEnd?: number; - ngOnInit() { + ngOnInit(): void { this.formArray.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((changes) => { this.control?.patchValue(changes, { emitModelToViewChange: true }); }); @@ -43,7 +44,7 @@ export class AdrExaminerNotesHistoryEditComponent extends BaseControlComponent i this.editingReason = this.route.snapshot.data['reason']; } - override ngAfterContentInit() { + override ngAfterContentInit(): void { const injectedControl = this.injector.get(NgControl, null); if (injectedControl) { const ngControl = injectedControl.control as unknown as KeyValue; @@ -54,9 +55,18 @@ export class AdrExaminerNotesHistoryEditComponent extends BaseControlComponent i } } - getAdditionalExaminerNotes() { - const returnValue = this.currentTechRecord ? this.currentTechRecord.techRecord_adrDetails_additionalExaminerNotes ?? [] : []; - return returnValue; + handlePaginationChange({ start, end }: { start: number; end: number }): void { + this.pageStart = start; + this.pageEnd = end; + this.cdr.detectChanges(); + } + + getAdditionalExaminerNotes(): AdditionalExaminerNotes[] { + return this.currentTechRecord?.techRecord_adrDetails_additionalExaminerNotes ?? []; + } + + get currentAdrNotesPage(): AdditionalExaminerNotes[] { + return this.currentTechRecord?.techRecord_adrDetails_additionalExaminerNotes?.slice(this.pageStart, this.pageEnd) ?? []; } getEditAdditionalExaminerNotePage(examinerNoteIndex: number) { @@ -67,9 +77,8 @@ export class AdrExaminerNotesHistoryEditComponent extends BaseControlComponent i void this.router.navigate([route], { relativeTo: this.route, state: this.currentTechRecord }); } - ngOnDestroy() { + ngOnDestroy(): void { this.destroy$.next(true); this.destroy$.complete(); } - } diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html index 87203f4425..ad1b14b431 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html @@ -1,32 +1,41 @@ -
-

Additional Examiner Notes History

- - - - - - - - - - - - + +
+

Additional Examiner Notes History

+
NotesCreated ByDate
- {{ result.note }} - {{ result.lastUpdatedBy }} - {{ result.createdAtDate | date : 'dd/MM/yyyy' | defaultNullOrEmpty }} -
+ + + + + - - -
NotesCreated ByDate
- -
-
-
No additional examiner notes history available
-
-
-
-
+ + + + {{ result.note }} + + {{ result.lastUpdatedBy }} + + {{ result.createdAtDate | date : 'dd/MM/yyyy' | defaultNullOrEmpty }} + + + + + + + +
+
+
No additional examiner notes history available
+
+
+
+
+
diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.spec.ts b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.spec.ts index 19bfc7d3d1..62814c8b35 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.spec.ts +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.spec.ts @@ -3,12 +3,22 @@ import { NG_VALUE_ACCESSOR, NgControl } from '@angular/forms'; import { CustomFormControl, FormNodeTypes } from '@forms/services/dynamic-form.types'; import { provideMockStore } from '@ngrx/store/testing'; import { State, initialAppState } from '@store/index'; +import { TechnicalRecordService } from '@services/technical-record/technical-record.service'; +import { mockVehicleTechnicalRecord } from '@mocks/mock-vehicle-technical-record.mock'; +import { VehicleTypes } from '@models/vehicle-tech-record.model'; +import { TechRecordType } from '@dvsa/cvs-type-definitions/types/v3/tech-record/tech-record-vehicle-type'; +import { of } from 'rxjs'; import { AdrExaminerNotesHistoryViewComponent } from './adr-examiner-notes-history-view.component'; describe('AdrExaminerNotesHistoryViewComponent', () => { let component: AdrExaminerNotesHistoryViewComponent; let fixture: ComponentFixture; + const MOCK_HGV = mockVehicleTechnicalRecord(VehicleTypes.HGV) as TechRecordType<'hgv'>; + const mockTechRecordService = { + techRecord$: of({ ...MOCK_HGV }), + }; + const control = new CustomFormControl({ name: 'techRecord_adrDetails_additionalExaminerNotes', type: FormNodeTypes.CONTROL, @@ -19,6 +29,7 @@ describe('AdrExaminerNotesHistoryViewComponent', () => { declarations: [AdrExaminerNotesHistoryViewComponent], providers: [ provideMockStore({ initialState: initialAppState }), + { provide: TechnicalRecordService, useValue: mockTechRecordService }, { provide: NG_VALUE_ACCESSOR, useExisting: AdrExaminerNotesHistoryViewComponent, multi: true }, { provide: NgControl, @@ -38,4 +49,63 @@ describe('AdrExaminerNotesHistoryViewComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + describe('ngOnInit', () => { + it('should set the currentTechRecord when ngOnInit is fired', () => { + component.currentTechRecord = undefined; + + component.ngOnInit(); + expect(component.currentTechRecord).toEqual(MOCK_HGV); + }); + }); + + describe('adrNotes', () => { + it('should return an array of the technical records adr examiner notes', () => { + component.currentTechRecord = { ...MOCK_HGV }; + component.currentTechRecord.techRecord_adrDetails_additionalExaminerNotes = [ + { createdAtDate: 'test', lastUpdatedBy: 'test', note: 'test note' }, + ]; + expect(component.adrNotes).toEqual([{ createdAtDate: 'test', lastUpdatedBy: 'test', note: 'test note' }]); + }); + + it('should return an empty array if the adr examiner notes is undefined', () => { + component.currentTechRecord = { ...MOCK_HGV }; + component.currentTechRecord.techRecord_adrDetails_additionalExaminerNotes = undefined; + expect(component.adrNotes).toEqual([]); + }); + }); + + describe('currentAdrNotesPage', () => { + it('should return a sliced array of adr notes depending on the page the user is on', () => { + component.currentTechRecord = { ...MOCK_HGV }; + component.pageStart = 2; + component.pageEnd = 3; + component.currentTechRecord.techRecord_adrDetails_additionalExaminerNotes = [ + { createdAtDate: 'test1', lastUpdatedBy: 'test1', note: 'test note 1' }, + { createdAtDate: 'test2', lastUpdatedBy: 'test2', note: 'test note 2' }, + { createdAtDate: 'test3', lastUpdatedBy: 'test3', note: 'test note 3' }, + { createdAtDate: 'test4', lastUpdatedBy: 'test4', note: 'test note 4' }, + ]; + expect(component.currentAdrNotesPage).toEqual([ + { createdAtDate: 'test3', lastUpdatedBy: 'test3', note: 'test note 3' }, + ]); + }); + + it('should return an empty array if the adr examiner notes is undefined', () => { + component.currentTechRecord = { ...MOCK_HGV }; + component.pageStart = 1; + component.pageEnd = 2; + component.currentTechRecord.techRecord_adrDetails_additionalExaminerNotes = undefined; + expect(component.currentAdrNotesPage).toEqual([]); + }); + }); + + describe('handlePaginationChange', () => { + it('should set the start and end pages', () => { + component.handlePaginationChange({ start: 0, end: 3 }); + + expect(component.pageStart).toBe(0); + expect(component.pageEnd).toBe(3); + }); + }); }); diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.ts b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.ts index 78fc2c0098..b493287287 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.ts +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.ts @@ -1,6 +1,12 @@ -import { Component } from '@angular/core'; +import { + Component, inject, OnDestroy, OnInit, +} from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { BaseControlComponent } from '@forms/components/base-control/base-control.component'; +import { AdditionalExaminerNotes } from '@dvsa/cvs-type-definitions/types/v3/tech-record/get/hgv/complete'; +import { TechRecordType } from '@dvsa/cvs-type-definitions/types/v3/tech-record/tech-record-vehicle-type'; +import { TechnicalRecordService } from '@services/technical-record/technical-record.service'; +import { Subject, takeUntil } from 'rxjs'; @Component({ selector: 'app-adr-examiner-notes-history-view', @@ -14,5 +20,35 @@ import { BaseControlComponent } from '@forms/components/base-control/base-contro }, ], }) -export class AdrExaminerNotesHistoryViewComponent extends BaseControlComponent { +export class AdrExaminerNotesHistoryViewComponent extends BaseControlComponent implements OnInit, OnDestroy { + technicalRecordService = inject(TechnicalRecordService); + currentTechRecord?: TechRecordType<'hgv' | 'lgv' | 'trl'> | undefined; + pageStart?: number; + pageEnd?: number; + private destroy$: Subject = new Subject(); + + ngOnInit(): void { + this.technicalRecordService.techRecord$.pipe(takeUntil(this.destroy$)).subscribe((currentTechRecord) => { + this.currentTechRecord = currentTechRecord as TechRecordType<'hgv' | 'lgv' | 'trl'>; + }); + } + + handlePaginationChange({ start, end }: { start: number; end: number }): void { + this.pageStart = start; + this.pageEnd = end; + this.cdr.detectChanges(); + } + + get adrNotes(): AdditionalExaminerNotes[] { + return this.currentTechRecord?.techRecord_adrDetails_additionalExaminerNotes ?? []; + } + + get currentAdrNotesPage(): AdditionalExaminerNotes[] { + return this.currentTechRecord?.techRecord_adrDetails_additionalExaminerNotes?.slice(this.pageStart, this.pageEnd) ?? []; + } + + ngOnDestroy(): void { + this.destroy$.next(); + this.destroy$.complete(); + } } From 5b4e5c11d73e44e6427bd5fb317a134e592a1248 Mon Sep 17 00:00:00 2001 From: Brandon Thomas-Davies <87308252+BrandonT95@users.noreply.github.com> Date: Fri, 5 Apr 2024 09:54:08 +0100 Subject: [PATCH 05/20] feat(cb2-11103): createdAtDate for adr examiner notes now save as full iso date string (#1452) * feat(cb2-11103): ability to submit and show date and time for adr notes creation * feat(cb2-11103): fix unit test * feat(cb2-11103): fix other unit test --- package-lock.json | 8 ++++---- package.json | 2 +- .../adr-examiner-notes-history-edit.component.html | 2 +- .../adr-examiner-notes-history.component-edit.spec.ts | 2 +- .../adr-examiner-notes-history-view.component.html | 2 +- .../reducers/technical-record-service.reducer.spec.ts | 2 +- .../reducers/technical-record-service.reducer.ts | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9363b1afc2..d68358f863 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "@angular/router": "^17.2.1", "@azure/msal-angular": "^3.0.13", "@azure/msal-browser": "^3.10.0", - "@dvsa/cvs-type-definitions": "^6.1.0", + "@dvsa/cvs-type-definitions": "^6.2.0", "@ngrx/effects": "^17.1.0", "@ngrx/entity": "^17.1.0", "@ngrx/router-store": "^17.1.0", @@ -3723,9 +3723,9 @@ } }, "node_modules/@dvsa/cvs-type-definitions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@dvsa/cvs-type-definitions/-/cvs-type-definitions-6.1.0.tgz", - "integrity": "sha512-NPS0mvEfRAiwCuLNHdq5Ip+dmx9KJQKX0RkHV6g0lmsDFwPasL+91R716Mgo44O/shBkeT9XsIQq3ZSoA3iOFA==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@dvsa/cvs-type-definitions/-/cvs-type-definitions-6.2.0.tgz", + "integrity": "sha512-r1oPXfn0WeP9zitBJVU+w0r4Eco4t02Wl54UdxeEdJ6B0u0BNC7mIQ1Wr1RqQmMw4kCFSIYop6RinEVpbp/WtA==", "dependencies": { "ajv": "^8.12.0", "json-schema-deref-sync": "^0.14.0", diff --git a/package.json b/package.json index f125fc4f3c..e82a2f37c5 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@angular/router": "^17.2.1", "@azure/msal-angular": "^3.0.13", "@azure/msal-browser": "^3.10.0", - "@dvsa/cvs-type-definitions": "^6.1.0", + "@dvsa/cvs-type-definitions": "^6.2.0", "@ngrx/effects": "^17.1.0", "@ngrx/entity": "^17.1.0", "@ngrx/router-store": "^17.1.0", diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html index d92ac9a219..c9c4a9141a 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html @@ -20,7 +20,7 @@ {{ examinerNote.lastUpdatedBy }} - {{ examinerNote.createdAtDate | date: 'dd/MM/yyyy' | defaultNullOrEmpty }} + {{ examinerNote.createdAtDate | date: 'dd/MM/yyyy HH:mm' | defaultNullOrEmpty }} Edit diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.spec.ts b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.spec.ts index 3f01703139..76ff27c32c 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.spec.ts +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit.spec.ts @@ -60,7 +60,7 @@ describe('AdrExaminerNotesHistoryEditComponent', () => { component.currentTechRecord = mockVehicleTechnicalRecord(VehicleTypes.HGV) as TechRecordType<'hgv'>; const testNote = { note: 'testNote', - createdAtDate: new Date().toISOString().split('T')[0], + createdAtDate: new Date().toISOString(), lastUpdatedBy: 'Someone Somewhere', }; component.currentTechRecord.techRecord_adrDetails_additionalExaminerNotes = [testNote]; diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html index ad1b14b431..fd9a5720ab 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html @@ -16,7 +16,7 @@

Additional Examiner Notes History

{{ result.lastUpdatedBy }} - {{ result.createdAtDate | date : 'dd/MM/yyyy' | defaultNullOrEmpty }} + {{ result.createdAtDate | date : 'dd/MM/yyyy HH:mm' | defaultNullOrEmpty }}
diff --git a/src/app/store/technical-records/reducers/technical-record-service.reducer.spec.ts b/src/app/store/technical-records/reducers/technical-record-service.reducer.spec.ts index 71076d2966..de24eb835d 100644 --- a/src/app/store/technical-records/reducers/technical-record-service.reducer.spec.ts +++ b/src/app/store/technical-records/reducers/technical-record-service.reducer.spec.ts @@ -562,7 +562,7 @@ describe('Vehicle Technical Record Reducer', () => { it('should', () => { const testNote = { note: 'testNote', - createdAtDate: new Date().toISOString().split('T')[0], + createdAtDate: new Date().toISOString(), lastUpdatedBy: 'someone', }; const state: TechnicalRecordServiceState = { diff --git a/src/app/store/technical-records/reducers/technical-record-service.reducer.ts b/src/app/store/technical-records/reducers/technical-record-service.reducer.ts index 4639b484da..2977368d0b 100644 --- a/src/app/store/technical-records/reducers/technical-record-service.reducer.ts +++ b/src/app/store/technical-records/reducers/technical-record-service.reducer.ts @@ -536,7 +536,7 @@ function handleADRExaminerNoteChanges(state: TechnicalRecordServiceState, userna const additionalExaminerNotes = { note: additionalNoteTechRecord.techRecord_adrDetails_additionalExaminerNotes_note, lastUpdatedBy: username, - createdAtDate: new Date().toISOString().split('T')[0], + createdAtDate: new Date().toISOString(), }; if (additionalNoteTechRecord.techRecord_adrDetails_additionalExaminerNotes === null || additionalNoteTechRecord.techRecord_adrDetails_additionalExaminerNotes === undefined) { From 3269b255c0411bd20747d97f320ca3b721c6ba26 Mon Sep 17 00:00:00 2001 From: Thomas Crawley Date: Fri, 5 Apr 2024 15:12:19 +0100 Subject: [PATCH 06/20] feat/CB2-10033 - Additional Examiner Note (#1448) * feat(cb2-10241): update adr notes to use custom component * feat(cb2-11250): format table * feat(cb2-11250): set up router link * feat(cb2-11250): blank page link working * feat(cb2-11250): revert unnecessary changes * feat(cb2-11250): amend routing function * feat(cb2-11250): fix linting and add unit test * feat(cb2-11250): fix linting and add unit test * feat(cb2-11250): update link design * feat(cb2-11250): fix button link styling * feat(cb2-10033): basic setup and grabbed selected note from record * feat(cb2-10033): stash for mobbing * feat(cb2-10033): hook form up to display note which is to be edited * feat(cb2-10033): set up model binding to component * feat(cb2-10033): use correct directive and basic form validation * feat(cb2-10033): amend routing title for notifiable alteration * feat(cb2-10033): remove validation as requirements confirmed not needed * feat(cb2-10033): implement state management solution * feat(cb2-10033): fix display for summary screen * feat(cb2-10033): refactor state and data handling approach * feat(cb2-10033): reducer tests * feat(cb2-10033): basic unit testing draft * feat(cb2-10033): unit testing * feat(cb2-10033): linting fix * feat(cb2-10033): fix review screen * feat(cb2-10033): git stash for mobbing * feat(cb2-10033): add logic to hide collapse function and fix missing acs * feat(cb2-10033): move title from component to templates * feat(cb2-10033): acordion issues solved --------- Co-authored-by: Brandon Thomas-Davies <87308252+BrandonT95@users.noreply.github.com> Co-authored-by: Tom Evans Co-authored-by: Thomas Evans <36958694+tomevs88@users.noreply.github.com> --- ...it-additional-examiner-note.component.html | 32 +++++- ...it-additional-examiner-note.component.scss | 8 ++ ...additional-examiner-note.component.spec.ts | 70 ++++++++++-- ...edit-additional-examiner-note.component.ts | 102 +++++++++++++++++- .../tech-record/tech-record-routing.module.ts | 14 ++- ...examiner-notes-history-edit.component.html | 2 +- ...examiner-notes-history-view.component.html | 10 +- ...miner-notes-history-view.component.spec.ts | 4 + ...r-examiner-notes-history-view.component.ts | 10 +- .../templates/general/adr-summary.template.ts | 9 +- .../forms/templates/general/adr.template.ts | 7 ++ .../collapsible-text.component.html | 28 +++++ .../collapsible-text.component.scss | 0 .../collapsible-text.component.spec.ts | 37 +++++++ .../collapsible-text.component.ts | 44 ++++++++ src/app/shared/shared.module.ts | 3 + .../technical-record-service.actions.ts | 7 +- .../technical-record-service.reducer.spec.ts | 27 ++++- .../technical-record-service.reducer.ts | 18 +++- 19 files changed, 410 insertions(+), 22 deletions(-) create mode 100644 src/app/shared/components/collapsible-text/collapsible-text.component.html create mode 100644 src/app/shared/components/collapsible-text/collapsible-text.component.scss create mode 100644 src/app/shared/components/collapsible-text/collapsible-text.component.spec.ts create mode 100644 src/app/shared/components/collapsible-text/collapsible-text.component.ts diff --git a/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.html b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.html index d2e41facc2..5efaac35ec 100644 --- a/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.html +++ b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.html @@ -1 +1,31 @@ -
This is a blank page right now.
+
+
+
+
+

Edit Additional Examiner Note

+
+ Date + {{ examinerNoteObj.createdAtDate | date: 'dd/MM/yyyy' | defaultNullOrEmpty }} + Created by + {{ examinerNoteObj.lastUpdatedBy }} +
+
+
+ + +
+
+
+
+
+ + Save + Cancel + +
diff --git a/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.scss b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.scss index e69de29bb2..bd6134d76f 100644 --- a/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.scss +++ b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.scss @@ -0,0 +1,8 @@ +.parent-div { + display: flex; + flex-direction: row; +} +.table-value { + margin-left: 1%; + margin-right: 1%; +} diff --git a/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.spec.ts b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.spec.ts index 65bf1af725..6568ebf897 100644 --- a/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.spec.ts +++ b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.spec.ts @@ -1,15 +1,13 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { - AdrExaminerNotesHistoryEditComponent, -} from '@forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history.component-edit'; import { DynamicFormsModule } from '@forms/dynamic-forms.module'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; import { TechnicalRecordService } from '@services/technical-record/technical-record.service'; -import { provideMockStore } from '@ngrx/store/testing'; +import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { initialAppState } from '@store/index'; -import { ActivatedRoute } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { of } from 'rxjs'; +import { GlobalErrorService } from '@core/components/global-error/global-error.service'; import { TechRecordEditAdditionalExaminerNoteComponent } from './tech-record-edit-additional-examiner-note.component'; const mockTechRecordService = { @@ -18,6 +16,11 @@ const mockTechRecordService = { describe('TechRecordEditAdditionalExaminerNoteComponent', () => { let fixture: ComponentFixture; let component: TechRecordEditAdditionalExaminerNoteComponent; + let router: Router; + let errorService: GlobalErrorService; + let route: ActivatedRoute; + let store: MockStore; + beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [TechRecordEditAdditionalExaminerNoteComponent], @@ -28,10 +31,65 @@ describe('TechRecordEditAdditionalExaminerNoteComponent', () => { { provide: ActivatedRoute, useValue: { params: of([{ id: 1 }]) } }, ], }).compileComponents(); - fixture = TestBed.createComponent(AdrExaminerNotesHistoryEditComponent); + fixture = TestBed.createComponent(TechRecordEditAdditionalExaminerNoteComponent); component = fixture.componentInstance; + router = TestBed.inject(Router); + errorService = TestBed.inject(GlobalErrorService); + route = TestBed.inject(ActivatedRoute); + store = TestBed.inject(MockStore); }); it('should create', () => { expect(component).toBeTruthy(); }); + describe('ngOnInit', () => { + it('should call all initialisation functions', () => { + const examinerNoteSpy = jest.spyOn(component, 'getExaminerNote').mockReturnValue(); + const techRecordSpy = jest.spyOn(component, 'getTechRecord').mockReturnValue(); + const formSpy = jest.spyOn(component, 'setupForm').mockReturnValue(); + component.ngOnInit(); + expect(examinerNoteSpy).toHaveBeenCalled(); + expect(formSpy).toHaveBeenCalled(); + expect(techRecordSpy).toHaveBeenCalled(); + }); + }); + describe('navigateBack', () => { + it('should clear all errors', () => { + jest.spyOn(router, 'navigate').mockImplementation(); + + const clearErrorsSpy = jest.spyOn(errorService, 'clearErrors'); + + component.navigateBack(); + + expect(clearErrorsSpy).toHaveBeenCalledTimes(1); + }); + + it('should navigate back to the previous page', () => { + const navigateSpy = jest.spyOn(router, 'navigate').mockImplementation(() => Promise.resolve(true)); + + component.navigateBack(); + + expect(navigateSpy).toHaveBeenCalledWith(['../../'], { relativeTo: route }); + }); + }); + describe('handleSubmit', () => { + it('should not dispatch an action if the notes are the same', () => { + const storeSpy = jest.spyOn(store, 'dispatch'); + const navigateBackSpy = jest.spyOn(component, 'navigateBack').mockReturnValue(); + component.originalExaminerNote = 'foobar'; + component.editedExaminerNote = 'foobar'; + component.handleSubmit(); + expect(storeSpy).not.toHaveBeenCalled(); + expect(navigateBackSpy).toHaveBeenCalled(); + }); + + it('should dispatch an action if the notes are not the same', () => { + const storeSpy = jest.spyOn(store, 'dispatch'); + const navigateBackSpy = jest.spyOn(component, 'navigateBack').mockReturnValue(); + component.originalExaminerNote = 'foo'; + component.editedExaminerNote = 'bar'; + component.handleSubmit(); + expect(storeSpy).toHaveBeenCalled(); + expect(navigateBackSpy).toHaveBeenCalled(); + }); + }); }); diff --git a/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.ts b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.ts index b8139fa97c..11e117cea6 100644 --- a/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.ts +++ b/src/app/features/tech-record/components/tech-record-edit-additional-examiner-note/tech-record-edit-additional-examiner-note.component.ts @@ -1,10 +1,108 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { TechnicalRecordService } from '@services/technical-record/technical-record.service'; +import { TechRecordType } from '@dvsa/cvs-type-definitions/types/v3/tech-record/tech-record-vehicle-type'; +import { ReplaySubject, take, takeUntil } from 'rxjs'; +import { GlobalErrorService } from '@core/components/global-error/global-error.service'; +import { + CustomFormControl, + FormNodeEditTypes, + FormNodeTypes, + FormNodeWidth, +} from '@forms/services/dynamic-form.types'; +import { FormGroup, Validators } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { State } from '@store/index'; +import { updateExistingADRAdditionalExaminerNote } from '@store/technical-records'; +import { AdditionalExaminerNotes } from '@dvsa/cvs-type-definitions/types/v3/tech-record/get/hgv/complete'; @Component({ selector: 'tech-record-edit-additional-examiner-note', templateUrl: './tech-record-edit-additional-examiner-note.component.html', styleUrls: ['./tech-record-edit-additional-examiner-note.component.scss'], }) -export class TechRecordEditAdditionalExaminerNoteComponent { +export class TechRecordEditAdditionalExaminerNoteComponent implements OnInit { + currentTechRecord!: TechRecordType<'hgv' | 'trl' | 'lgv'>; + examinerNoteIndex!: number; + editedExaminerNote: string = ''; + originalExaminerNote: string = ''; + examinerNoteObj!: AdditionalExaminerNotes; + destroy$ = new ReplaySubject(1); + form!: FormGroup; + formControl!: CustomFormControl; + + constructor( + private router: Router, + private route: ActivatedRoute, + private technicalRecordService: TechnicalRecordService, + private globalErrorService: GlobalErrorService, + private store: Store, + ) { } + + ngOnInit() { + this.getTechRecord(); + this.getExaminerNote(); + this.setupForm(); + } + + getTechRecord() { + this.technicalRecordService.techRecord$.pipe(takeUntil(this.destroy$)).subscribe((currentTechRecord) => { + this.currentTechRecord = currentTechRecord as TechRecordType<'hgv' | 'lgv' | 'trl'>; + }); + } + + getExaminerNote() { + this.route.params.pipe(take(1)).subscribe((params) => { + this.examinerNoteIndex = params['examinerNoteIndex']; + }); + const additionalExaminerNotes = this.currentTechRecord?.techRecord_adrDetails_additionalExaminerNotes; + if (additionalExaminerNotes) { + const examinerNote = additionalExaminerNotes[this.examinerNoteIndex].note; + if (examinerNote) { + this.examinerNoteObj = additionalExaminerNotes[this.examinerNoteIndex]; + this.originalExaminerNote = examinerNote; + this.editedExaminerNote = examinerNote; + } + } + } + + setupForm() { + this.formControl = new CustomFormControl({ + name: 'additionalExaminerNote', type: FormNodeTypes.CONTROL, + }, '', [Validators.required]); + this.form = new FormGroup({ + additionalExaminerNote: this.formControl, + }); + this.formControl.patchValue(this.editedExaminerNote); + } + + navigateBack() { + this.globalErrorService.clearErrors(); + void this.router.navigate(['../../'], { relativeTo: this.route }); + } + + handleSubmit(): void { + if (this.originalExaminerNote !== this.editedExaminerNote) { + this.store.dispatch( + updateExistingADRAdditionalExaminerNote({ + examinerNoteIndex: this.examinerNoteIndex, + additionalExaminerNote: this.editedExaminerNote, + }), + ); + } + this.navigateBack(); + } + + ngOnChanges(examinerNote: string) { + this.editedExaminerNote = examinerNote; + } + + get editTypes(): typeof FormNodeEditTypes { + return FormNodeEditTypes; + } + + get width(): typeof FormNodeWidth { + return FormNodeWidth; + } } diff --git a/src/app/features/tech-record/tech-record-routing.module.ts b/src/app/features/tech-record/tech-record-routing.module.ts index 717d3f920b..e56d706ea7 100644 --- a/src/app/features/tech-record/tech-record-routing.module.ts +++ b/src/app/features/tech-record/tech-record-routing.module.ts @@ -170,14 +170,17 @@ const routes: Routes = [ { path: TechRecordRoutes.CORRECT_ERROR_CHANGE_SUMMARY, component: TechRecordSummaryChangesComponent, - data: { roles: Roles.TechRecordAmend }, + data: { + roles: Roles.TechRecordAmend, + isEditing: true, + }, canActivate: [MsalGuard, RoleGuard], }, { path: TechRecordRoutes.CORRECT_ERROR_EDIT_ADDITIONAL_EXAMINER_NOTE, component: TechRecordEditAdditionalExaminerNoteComponent, data: { - title: 'edit-additional-examiner-note', + title: 'Edit Additional Examiner Note', roles: Roles.TechRecordAmend, isEditing: true, reason: ReasonForEditing.CORRECTING_AN_ERROR, @@ -188,7 +191,10 @@ const routes: Routes = [ { path: TechRecordRoutes.NOTIFIABLE_ALTERATION_NEEDED_CHANGE_SUMMARY, component: TechRecordSummaryChangesComponent, - data: { roles: Roles.TechRecordAmend }, + data: { + roles: Roles.TechRecordAmend, + isEditing: true, + }, canActivate: [MsalGuard, RoleGuard], }, { @@ -207,7 +213,7 @@ const routes: Routes = [ path: TechRecordRoutes.NOTIFIABLE_ALTERNATION_NEEDED_EDIT_ADDITIONAL_EXAMINER_NOTE, component: TechRecordEditAdditionalExaminerNoteComponent, data: { - title: 'edit-additional-examiner-note', + title: 'Edit Additional Examiner Note', roles: Roles.TechRecordAmend, isEditing: true, reason: ReasonForEditing.NOTIFIABLE_ALTERATION_NEEDED, diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html index c9c4a9141a..b84be43f86 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html @@ -16,7 +16,7 @@ - {{ examinerNote.note }} + {{ examinerNote.lastUpdatedBy }} diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html index fd9a5720ab..a8a219e9d9 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html @@ -1,7 +1,6 @@
-

Additional Examiner Notes History

@@ -12,11 +11,16 @@

Additional Examiner Notes History

diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.spec.ts b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.spec.ts index 62814c8b35..3d10b42996 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.spec.ts +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.spec.ts @@ -9,6 +9,8 @@ import { VehicleTypes } from '@models/vehicle-tech-record.model'; import { TechRecordType } from '@dvsa/cvs-type-definitions/types/v3/tech-record/tech-record-vehicle-type'; import { of } from 'rxjs'; import { AdrExaminerNotesHistoryViewComponent } from './adr-examiner-notes-history-view.component'; +import { RouterService } from '@services/router/router.service'; + describe('AdrExaminerNotesHistoryViewComponent', () => { let component: AdrExaminerNotesHistoryViewComponent; @@ -18,6 +20,7 @@ describe('AdrExaminerNotesHistoryViewComponent', () => { const mockTechRecordService = { techRecord$: of({ ...MOCK_HGV }), }; + const mockRouterService = {}; const control = new CustomFormControl({ name: 'techRecord_adrDetails_additionalExaminerNotes', @@ -30,6 +33,7 @@ describe('AdrExaminerNotesHistoryViewComponent', () => { providers: [ provideMockStore({ initialState: initialAppState }), { provide: TechnicalRecordService, useValue: mockTechRecordService }, + { provide: RouterService, useValue: mockRouterService }, { provide: NG_VALUE_ACCESSOR, useExisting: AdrExaminerNotesHistoryViewComponent, multi: true }, { provide: NgControl, diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.ts b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.ts index b493287287..4e12d6f635 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.ts +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.ts @@ -6,7 +6,10 @@ import { BaseControlComponent } from '@forms/components/base-control/base-contro import { AdditionalExaminerNotes } from '@dvsa/cvs-type-definitions/types/v3/tech-record/get/hgv/complete'; import { TechRecordType } from '@dvsa/cvs-type-definitions/types/v3/tech-record/tech-record-vehicle-type'; import { TechnicalRecordService } from '@services/technical-record/technical-record.service'; -import { Subject, takeUntil } from 'rxjs'; +import { + map, Observable, Subject, takeUntil, +} from 'rxjs'; +import { RouterService } from '@services/router/router.service'; @Component({ selector: 'app-adr-examiner-notes-history-view', @@ -22,6 +25,7 @@ import { Subject, takeUntil } from 'rxjs'; }) export class AdrExaminerNotesHistoryViewComponent extends BaseControlComponent implements OnInit, OnDestroy { technicalRecordService = inject(TechnicalRecordService); + routerService = inject(RouterService); currentTechRecord?: TechRecordType<'hgv' | 'lgv' | 'trl'> | undefined; pageStart?: number; pageEnd?: number; @@ -33,6 +37,10 @@ export class AdrExaminerNotesHistoryViewComponent extends BaseControlComponent i }); } + get isEditing$(): Observable { + return this.routerService.getRouteDataProperty$('isEditing').pipe(map((isEditing) => !!isEditing)); + } + handlePaginationChange({ start, end }: { start: number; end: number }): void { this.pageStart = start; this.pageEnd = end; diff --git a/src/app/forms/templates/general/adr-summary.template.ts b/src/app/forms/templates/general/adr-summary.template.ts index d54e01d5d1..f4c8450ec2 100644 --- a/src/app/forms/templates/general/adr-summary.template.ts +++ b/src/app/forms/templates/general/adr-summary.template.ts @@ -757,6 +757,13 @@ export const AdrSummaryTemplate: FormNode = { groups: ['declarations_details', 'dangerous_goods'], hide: true, }, + { + name: 'ExaminerNotesSectionTitle', + label: 'Additional Examiner Notes History', + type: FormNodeTypes.TITLE, + groups: ['adr_details', 'dangerous_goods'], + hide: true, + }, { name: 'techRecord_adrDetails_additionalExaminerNotes_note', label: 'Additional Examiner Notes', @@ -774,7 +781,7 @@ export const AdrSummaryTemplate: FormNode = { label: 'Additional examiner notes history', value: null, type: FormNodeTypes.CONTROL, - viewType: FormNodeViewTypes.HIDDEN, + viewType: FormNodeViewTypes.CUSTOM, viewComponent: AdrExaminerNotesHistoryViewComponent, editType: FormNodeEditTypes.CUSTOM, editComponent: AdrExaminerNotesHistoryEditComponent, diff --git a/src/app/forms/templates/general/adr.template.ts b/src/app/forms/templates/general/adr.template.ts index b1a86e2191..e87c807921 100644 --- a/src/app/forms/templates/general/adr.template.ts +++ b/src/app/forms/templates/general/adr.template.ts @@ -756,6 +756,13 @@ export const AdrTemplate: FormNode = { groups: ['declarations_details', 'dangerous_goods'], hide: true, }, + { + name: 'ExaminerNotesSectionTitle', + label: 'Additional Examiner Notes History', + type: FormNodeTypes.TITLE, + groups: ['adr_details', 'dangerous_goods'], + hide: true, + }, { name: 'techRecord_adrDetails_additionalExaminerNotes_note', label: 'Additional Examiner Notes', diff --git a/src/app/shared/components/collapsible-text/collapsible-text.component.html b/src/app/shared/components/collapsible-text/collapsible-text.component.html new file mode 100644 index 0000000000..a8f098860b --- /dev/null +++ b/src/app/shared/components/collapsible-text/collapsible-text.component.html @@ -0,0 +1,28 @@ + +
+ {{ getCollapsedString() }} +
+ + +
+ +
+ {{ text }} +
+ + +
diff --git a/src/app/shared/components/collapsible-text/collapsible-text.component.scss b/src/app/shared/components/collapsible-text/collapsible-text.component.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/app/shared/components/collapsible-text/collapsible-text.component.spec.ts b/src/app/shared/components/collapsible-text/collapsible-text.component.spec.ts new file mode 100644 index 0000000000..a7fd6d6e46 --- /dev/null +++ b/src/app/shared/components/collapsible-text/collapsible-text.component.spec.ts @@ -0,0 +1,37 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { CollapsibleTextComponent } from './collapsible-text.component'; + +describe('CollapsibleTextComponent', () => { + let component: CollapsibleTextComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [CollapsibleTextComponent], + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(CollapsibleTextComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should open when open method is called', () => { + component.isCollapsed = true; + component.open(); + expect(component.isCollapsed).toBe(false); + }); + + it('should close when close method is called', () => { + component.isCollapsed = false; + component.close(); + expect(component.isCollapsed).toBe(true); + }); +}); diff --git a/src/app/shared/components/collapsible-text/collapsible-text.component.ts b/src/app/shared/components/collapsible-text/collapsible-text.component.ts new file mode 100644 index 0000000000..37cd9a941e --- /dev/null +++ b/src/app/shared/components/collapsible-text/collapsible-text.component.ts @@ -0,0 +1,44 @@ +import { + ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, +} from '@angular/core'; +import { NG_VALUE_ACCESSOR } from '@angular/forms'; + +@Component({ + selector: 'collapsible-text', + templateUrl: './collapsible-text.component.html', + styleUrls: ['./collapsible-text.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: CollapsibleTextComponent, + multi: true, + }, + ], +}) +export class CollapsibleTextComponent { + + @Input() text: string = ''; + @Input() maxChars: number = 0; + @Input() isCollapsed = true; + + constructor(private cdr: ChangeDetectorRef) { + } + + getCollapsedString() { + if (this.text.length <= this.maxChars) { + return this.text; + } + return this.text.slice(0, this.maxChars); + } + + open() { + this.isCollapsed = false; + this.cdr.markForCheck(); + } + + close() { + this.isCollapsed = true; + this.cdr.markForCheck(); + } +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index 94f3bf1dd5..c812d56293 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -4,6 +4,7 @@ import { RouterModule } from '@angular/router'; import { DocumentRetrievalService } from '@api/document-retrieval'; import { RoleRequiredDirective } from '@directives/app-role-required.directive'; import { FeatureToggleDirective } from '@directives/feature-toggle.directive'; +import { CollapsibleTextComponent } from '@shared/components/collapsible-text/collapsible-text.component'; import { AccordionControlComponent } from './components/accordion-control/accordion-control.component'; import { AccordionComponent } from './components/accordion/accordion.component'; import { BannerComponent } from './components/banner/banner.component'; @@ -54,6 +55,7 @@ import { TyreAxleLoadPipe } from './pipes/tyre-axle-load/tyre-axle-load.pipe'; TyreAxleLoadPipe, GetControlLabelPipe, FormatVehicleTypePipe, + CollapsibleTextComponent, ], imports: [CommonModule, RouterModule], exports: [ @@ -80,6 +82,7 @@ import { TyreAxleLoadPipe } from './pipes/tyre-axle-load/tyre-axle-load.pipe'; TyreAxleLoadPipe, GetControlLabelPipe, FormatVehicleTypePipe, + CollapsibleTextComponent, ], providers: [DocumentRetrievalService], diff --git a/src/app/store/technical-records/actions/technical-record-service.actions.ts b/src/app/store/technical-records/actions/technical-record-service.actions.ts index 21ce912342..3e70e03b7b 100644 --- a/src/app/store/technical-records/actions/technical-record-service.actions.ts +++ b/src/app/store/technical-records/actions/technical-record-service.actions.ts @@ -98,7 +98,12 @@ export const clearScrollPosition = createAction(`${prefix} clearScrollPosition`) export const clearADRDetailsBeforeUpdate = createAction(`${prefix} clearADRDetailsBeforeUpdate`); -export const updateADRAdditionalExaminerNotes = createAction(`${prefix} handleADRExaminerNoteChanges`, props<{ username: string }>()); +export const updateADRAdditionalExaminerNotes = createAction(`${prefix} updateADRAdditionalExaminerNotes`, props<{ username: string }>()); + +export const updateExistingADRAdditionalExaminerNote = createAction( + `${prefix} updateExistingADRAdditionalExaminerNote`, + props<{ additionalExaminerNote: string, examinerNoteIndex: number }>(), +); export const generateADRCertificate = createAction(`${prefix} generateADRCertificate`, props<{ systemNumber: string, createdTimestamp: string, certificateType: string diff --git a/src/app/store/technical-records/reducers/technical-record-service.reducer.spec.ts b/src/app/store/technical-records/reducers/technical-record-service.reducer.spec.ts index de24eb835d..1991ea32fb 100644 --- a/src/app/store/technical-records/reducers/technical-record-service.reducer.spec.ts +++ b/src/app/store/technical-records/reducers/technical-record-service.reducer.spec.ts @@ -33,7 +33,7 @@ import { updateBody, updateBrakeForces, updateEditingTechRecord, - updateEditingTechRecordCancel, + updateEditingTechRecordCancel, updateExistingADRAdditionalExaminerNote, updateScrollPosition, updateTechRecord, updateTechRecordFailure, @@ -586,4 +586,29 @@ describe('Vehicle Technical Record Reducer', () => { .toContainEqual(testNote); }); }); + describe('handleUpdateExistingADRExaminerNote', () => { + it('should', () => { + const state: TechnicalRecordServiceState = { + ...initialState, + editingTechRecord: { + systemNumber: 'foo', + createdTimestamp: 'bar', + vin: 'testVin', + techRecord_adrDetails_additionalExaminerNotes: [ + { + note: 'foo', + createdAtDate: 'bar', + lastUpdatedBy: 'foo', + }, + ], + } as unknown as TechRecordType<'put'>, + loading: true, + }; + const newNote = 'foobar'; + const action = updateExistingADRAdditionalExaminerNote({ additionalExaminerNote: newNote, examinerNoteIndex: 0 }); + const newState = vehicleTechRecordReducer(state, action); + const editingTechRecord = newState.editingTechRecord as unknown as (NonVerbTechRecordType<'hgv' | 'lgv' | 'trl'>); + expect(editingTechRecord.techRecord_adrDetails_additionalExaminerNotes![0].note).toEqual(newNote); + }); + }); }); diff --git a/src/app/store/technical-records/reducers/technical-record-service.reducer.ts b/src/app/store/technical-records/reducers/technical-record-service.reducer.ts index 2977368d0b..908c1241c3 100644 --- a/src/app/store/technical-records/reducers/technical-record-service.reducer.ts +++ b/src/app/store/technical-records/reducers/technical-record-service.reducer.ts @@ -61,7 +61,7 @@ import { updateBody, updateBrakeForces, updateEditingTechRecord, - updateEditingTechRecordCancel, + updateEditingTechRecordCancel, updateExistingADRAdditionalExaminerNote, updateScrollPosition, updateTechRecord, updateTechRecordFailure, @@ -153,6 +153,8 @@ export const vehicleTechRecordReducer = createReducer( on(updateADRAdditionalExaminerNotes, (state, action) => handleADRExaminerNoteChanges(state, action.username)), + on(updateExistingADRAdditionalExaminerNote, (state, action) => handleUpdateExistingADRExaminerNote(state, action)), + on(addAxle, (state) => handleAddAxle(state)), on(removeAxle, (state, action) => handleRemoveAxle(state, action)), @@ -547,3 +549,17 @@ function handleADRExaminerNoteChanges(state: TechnicalRecordServiceState, userna } return { ...state, editingTechRecord: additionalNoteTechRecord as unknown as (TechRecordType<'put'>) }; } + +function handleUpdateExistingADRExaminerNote( + state: TechnicalRecordServiceState, + action: { additionalExaminerNote: string, examinerNoteIndex: number }, +) { + const { editingTechRecord } = state; + const editedTechRecord = editingTechRecord as unknown as + (NonVerbTechRecordType<'hgv' | 'lgv' | 'trl'>); + if (editedTechRecord) { + const examinerNotes = editedTechRecord.techRecord_adrDetails_additionalExaminerNotes; + examinerNotes![action.examinerNoteIndex].note = action.additionalExaminerNote; + } + return { ...state, editingTechRecord: editingTechRecord as unknown as (TechRecordType<'put'>) }; +} From 6ec627a25d63b5baec4d88fbfbf424666953947b Mon Sep 17 00:00:00 2001 From: Thomas Evans <36958694+tomevs88@users.noreply.github.com> Date: Tue, 9 Apr 2024 09:22:26 +0100 Subject: [PATCH 07/20] feat(cb2-10033): upped char count to 151 (#1453) Co-authored-by: Tom Evans --- .../adr-examiner-notes-history-edit.component.html | 2 +- .../adr-examiner-notes-history-view.component.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html index b84be43f86..95ea9ff828 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html @@ -16,7 +16,7 @@
From e689ac868ef698a54c79b7ab4c7c45ea34984d42 Mon Sep 17 00:00:00 2001 From: pbardy2000 <146740183+pbardy2000@users.noreply.github.com> Date: Thu, 11 Apr 2024 09:29:35 +0100 Subject: [PATCH 13/20] feat(cb2-10286): add hint text to 3 month extension (#1462) --- src/app/forms/templates/general/adr.template.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/app/forms/templates/general/adr.template.ts b/src/app/forms/templates/general/adr.template.ts index e87c807921..3ca4a4f918 100644 --- a/src/app/forms/templates/general/adr.template.ts +++ b/src/app/forms/templates/general/adr.template.ts @@ -587,6 +587,7 @@ export const AdrTemplate: FormNode = { { name: 'techRecord_adrDetails_memosApply', label: 'Memo 7/9 (3 month extension) applied', + hint: 'Only applicable for vehicles used on national journeys', type: FormNodeTypes.CONTROL, editType: FormNodeEditTypes.CHECKBOXGROUP, groups: ['tank_details', 'dangerous_goods'], From aff9b856ccb7e34ae8806269cf4c18fcdd92b74c Mon Sep 17 00:00:00 2001 From: Thomas Evans <36958694+tomevs88@users.noreply.github.com> Date: Thu, 11 Apr 2024 09:56:09 +0100 Subject: [PATCH 14/20] feat(cb2-10973): feature flags changed to show IVA flow in all envs (#1465) Co-authored-by: Tom Evans --- src/assets/featureToggle.int.json | 3 +-- src/assets/featureToggle.preprod.json | 3 +-- src/assets/featureToggle.prod.json | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/assets/featureToggle.int.json b/src/assets/featureToggle.int.json index 8c5f462fcb..14c9ac4699 100644 --- a/src/assets/featureToggle.int.json +++ b/src/assets/featureToggle.int.json @@ -2,6 +2,5 @@ "testToggle": false, "adrToggle": true, "adrCertToggle": true, - "requiredStandards": false + "requiredStandards": true } - \ No newline at end of file diff --git a/src/assets/featureToggle.preprod.json b/src/assets/featureToggle.preprod.json index 8c5f462fcb..14c9ac4699 100644 --- a/src/assets/featureToggle.preprod.json +++ b/src/assets/featureToggle.preprod.json @@ -2,6 +2,5 @@ "testToggle": false, "adrToggle": true, "adrCertToggle": true, - "requiredStandards": false + "requiredStandards": true } - \ No newline at end of file diff --git a/src/assets/featureToggle.prod.json b/src/assets/featureToggle.prod.json index 9fd2e25cdb..df58ab6e4b 100644 --- a/src/assets/featureToggle.prod.json +++ b/src/assets/featureToggle.prod.json @@ -2,5 +2,5 @@ "testToggle": false, "adrToggle": true, "adrCertToggle": true, - "requiredStandards": false + "requiredStandards": true } From 0fd205ad71ebe99e22bd5f2de729d883cc385bce Mon Sep 17 00:00:00 2001 From: pbardy2000 <146740183+pbardy2000@users.noreply.github.com> Date: Thu, 11 Apr 2024 10:48:04 +0100 Subject: [PATCH 15/20] feat(cb2-10125): make adr guidance notes a checkbox group (#1466) --- .../adr-guidance-notes.component.html | 48 ------- .../adr-guidance-notes.component.scss | 0 .../adr-guidance-notes.component.spec.ts | 126 ------------------ .../adr-guidance-notes.component.ts | 58 -------- src/app/forms/dynamic-forms.module.ts | 2 - .../templates/general/adr-summary.template.ts | 14 +- .../forms/templates/general/adr.template.ts | 10 +- 7 files changed, 5 insertions(+), 253 deletions(-) delete mode 100644 src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.html delete mode 100644 src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.scss delete mode 100644 src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.spec.ts delete mode 100644 src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.ts diff --git a/src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.html b/src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.html deleted file mode 100644 index 07d172802b..0000000000 --- a/src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - -
- {{ result.note }} + + + + + {{ result.note }} + {{ result.lastUpdatedBy }} - {{ result.createdAtDate | date : 'dd/MM/yyyy HH:mm' | defaultNullOrEmpty }} + {{ result.createdAtDate | date: 'dd/MM/yyyy' | defaultNullOrEmpty }}
- + {{ examinerNote.lastUpdatedBy }} diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html index a8a219e9d9..9ddb92933d 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html @@ -12,7 +12,7 @@
- + {{ result.note }} From 88de19d92cf8b9fab4022fc75ea0c204940b530a Mon Sep 17 00:00:00 2001 From: Tom Evans Date: Tue, 9 Apr 2024 14:18:00 +0100 Subject: [PATCH 08/20] feat(cb2-10033): upped char count to 150 --- .../adr-examiner-notes-history-edit.component.html | 2 +- .../adr-examiner-notes-history-view.component.html | 2 +- .../collapsible-text/collapsible-text.component.html | 2 +- .../collapsible-text/collapsible-text.component.ts | 7 +++++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html index 95ea9ff828..b84be43f86 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-edit/adr-examiner-notes-history-edit.component.html @@ -16,7 +16,7 @@
- + {{ examinerNote.lastUpdatedBy }} diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html index 9ddb92933d..a8a219e9d9 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.html @@ -12,7 +12,7 @@
- + {{ result.note }} diff --git a/src/app/shared/components/collapsible-text/collapsible-text.component.html b/src/app/shared/components/collapsible-text/collapsible-text.component.html index a8f098860b..a5a97d2d66 100644 --- a/src/app/shared/components/collapsible-text/collapsible-text.component.html +++ b/src/app/shared/components/collapsible-text/collapsible-text.component.html @@ -3,7 +3,7 @@ {{ getCollapsedString() }} - -
+
{{ text }}
-
{{ result.lastUpdatedBy }} - {{ result.createdAtDate | date: 'dd/MM/yyyy' | defaultNullOrEmpty }} + {{ result.createdAtDate | date: 'dd/MM/yyyy HH:mm' | defaultNullOrEmpty }}
- - - - - - - - -
- - - Remove -
- -

- Add guidance notes -

- diff --git a/src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.scss b/src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.scss deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.spec.ts b/src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.spec.ts deleted file mode 100644 index 9e2a91411f..0000000000 --- a/src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.spec.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { - FormControl, - FormGroup, - FormsModule, NG_VALUE_ACCESSOR, NgControl, ReactiveFormsModule, -} from '@angular/forms'; -import { FORM_INJECTION_TOKEN } from '@forms/components/dynamic-form-field/dynamic-form-field.component'; -import { FieldErrorMessageComponent } from '@forms/components/field-error-message/field-error-message.component'; -import { SelectComponent } from '@forms/components/select/select.component'; -import { DynamicFormsModule } from '@forms/dynamic-forms.module'; -import { CustomFormControl, FormNodeTypes } from '@forms/services/dynamic-form.types'; -import { AdrGuidanceNotesComponent } from './adr-guidance-notes.component'; - -describe('AdrGuidanceNotesComponent', () => { - let component: AdrGuidanceNotesComponent; - let fixture: ComponentFixture; - - const control = new CustomFormControl({ - name: 'techRecord_adrDetails_additionalNotes_guidanceNotes', - label: 'Guidance Notes', - type: FormNodeTypes.CONTROL, - }); - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [AdrGuidanceNotesComponent, SelectComponent, FieldErrorMessageComponent], - imports: [DynamicFormsModule, FormsModule, ReactiveFormsModule], - providers: [ - { provide: NG_VALUE_ACCESSOR, useExisting: AdrGuidanceNotesComponent, multi: true }, - { - provide: NgControl, - useValue: { - control: { key: control.meta.name, value: control }, - }, - }, - { - provide: FORM_INJECTION_TOKEN, - useValue: new FormGroup({ - techRecord_adrDetails_additionalNotes_guidanceNotes: new FormControl(null), - }), - }, - ], - }) - .compileComponents(); - - fixture = TestBed.createComponent(AdrGuidanceNotesComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - beforeEach(() => { - component.formArray.patchValue([]); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('ngOnInit', () => { - it('should set a subscription to listen to form array changes, and patch the control value', () => { - const ngOnInitSpy = jest.spyOn(component, 'ngOnInit'); - component.ngOnInit(); - expect(ngOnInitSpy).toHaveBeenCalled(); - }); - }); - - describe('ngAfterContentInit', () => { - - it('should set the form control name', () => { - component.ngAfterContentInit(); - expect(component.name).toBeTruthy(); - }); - - it('should inject the form to which the control belongs', () => { - component.ngAfterContentInit(); - expect(component.control).toBeTruthy(); - }); - - it('should inject the control created by the dynamic form service, which is derrived from the template', () => { - component.ngAfterContentInit(); - expect(component.control).toBeTruthy(); - }); - - it('should make this control the first index of the form array', () => { - const formArraySpy = jest.spyOn(component.formArray, 'push'); - component.ngAfterContentInit(); - expect(formArraySpy).toHaveBeenCalledTimes(1); - expect(component.formArray.controls.at(0)).toBeDefined(); - }); - }); - - describe('addGuidanceNote', () => { - it('should add a copy of the first guidance control note to the form array (but with a reset value)', () => { - const methodSpy = jest.spyOn(component, 'addGuidanceNote'); - const formArraySpy = jest.spyOn(component.formArray, 'push'); - component.addGuidanceNote(); - expect(methodSpy).toHaveBeenCalled(); - expect(formArraySpy).toHaveBeenCalled(); - expect(component.formArray.controls.at(1)).toBeDefined(); - expect(component.formArray.controls.at(1)?.value).toBeFalsy(); - }); - }); - - describe('removeGuidanceNote', () => { - it('should remove the guidance note control from the form array at the index specified', () => { - const methodSpy = jest.spyOn(component, 'removeGuidanceNote'); - const formArraySpy = jest.spyOn(component.formArray, 'removeAt'); - - component.addGuidanceNote(); - component.addGuidanceNote(); - component.addGuidanceNote(); - component.addGuidanceNote(); - - component.removeGuidanceNote(3); - component.removeGuidanceNote(2); - - expect(methodSpy).toHaveBeenCalledTimes(2); - expect(formArraySpy).toHaveBeenCalledTimes(2); - expect(component.formArray.controls.at(4)).toBeUndefined(); - expect(component.formArray.controls.at(3)).toBeUndefined(); - expect(component.formArray.controls.at(2)).toBeDefined(); - expect(component.formArray.controls).toHaveLength(3); - }); - }); -}); diff --git a/src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.ts b/src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.ts deleted file mode 100644 index 07641692cb..0000000000 --- a/src/app/forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { - AfterContentInit, - Component, OnDestroy, OnInit, -} from '@angular/core'; -import { - FormArray, - NG_VALUE_ACCESSOR, -} from '@angular/forms'; -import { CustomFormControl } from '@forms/services/dynamic-form.types'; -import { ReplaySubject, takeUntil } from 'rxjs'; -import { CustomFormControlComponent } from '../custom-form-control/custom-form-control.component'; - -@Component({ - selector: 'app-adr-guidance-notes', - templateUrl: './adr-guidance-notes.component.html', - styleUrls: ['./adr-guidance-notes.component.scss'], - providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: AdrGuidanceNotesComponent, multi: true }], -}) -export class AdrGuidanceNotesComponent extends CustomFormControlComponent implements OnInit, AfterContentInit, OnDestroy { - destroy$ = new ReplaySubject(1); - formArray = new FormArray([]); - - ngOnInit() { - this.formArray.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((changes) => { - this.control?.patchValue(changes, { emitModelToViewChange: true }); - }); - } - - ngOnDestroy(): void { - this.destroy$.next(true); - this.destroy$.complete(); - } - - override ngAfterContentInit() { - super.ngAfterContentInit(); - const { form, control } = this; - - if (!form) return; - if (!control) return; - - const value = form.get(this.name)?.value; - const values = Array.isArray(value) && value.length ? value : [null]; - values.forEach((guidanceNoteType: string) => { - this.formArray.push(new CustomFormControl(control.meta, guidanceNoteType)); - }); - } - - addGuidanceNote() { - const first = this.formArray.at(0); - this.formArray.push(new CustomFormControl(first.meta)); - } - - removeGuidanceNote(index: number) { - if (this.formArray.length < 2) return; - this.formArray.removeAt(index); - } - -} diff --git a/src/app/forms/dynamic-forms.module.ts b/src/app/forms/dynamic-forms.module.ts index 9e319d5046..821f4ff45f 100644 --- a/src/app/forms/dynamic-forms.module.ts +++ b/src/app/forms/dynamic-forms.module.ts @@ -38,7 +38,6 @@ import { ViewCombinationComponent } from './components/view-combination/view-com import { ViewListItemComponent } from './components/view-list-item/view-list-item.component'; import { AbandonDialogComponent } from './custom-sections/abandon-dialog/abandon-dialog.component'; import { AdrExaminerNotesHistoryViewComponent } from './custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component'; -import { AdrGuidanceNotesComponent } from './custom-sections/adr-guidance-notes/adr-guidance-notes.component'; import { AdrTankDetailsInitialInspectionViewComponent, } from './custom-sections/adr-tank-details-initial-inspection-view/adr-tank-details-initial-inspection-view.component'; @@ -131,7 +130,6 @@ import { SuffixDirective } from './directives/suffix.directive'; ModifiedWeightsComponent, FieldWarningMessageComponent, AdrComponent, - AdrGuidanceNotesComponent, AdrTankDetailsSubsequentInspectionsEditComponent, AdrTankStatementUnNumberEditComponent, CustomFormControlComponent, diff --git a/src/app/forms/templates/general/adr-summary.template.ts b/src/app/forms/templates/general/adr-summary.template.ts index f4c8450ec2..8dc59f683e 100644 --- a/src/app/forms/templates/general/adr-summary.template.ts +++ b/src/app/forms/templates/general/adr-summary.template.ts @@ -14,11 +14,10 @@ import { import { AdrExaminerNotesHistoryViewComponent, } from '@forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component'; -import { AdrGuidanceNotesComponent } from '@forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component'; -import { AdrTankDetailsM145ViewComponent } from '@forms/custom-sections/adr-tank-details-m145-view/adr-tank-details-m145-view.component'; import { AdrTankDetailsInitialInspectionViewComponent, } from '@forms/custom-sections/adr-tank-details-initial-inspection-view/adr-tank-details-initial-inspection-view.component'; +import { AdrTankDetailsM145ViewComponent } from '@forms/custom-sections/adr-tank-details-m145-view/adr-tank-details-m145-view.component'; import { AdrTankDetailsSubsequentInspectionsEditComponent, } from '@forms/custom-sections/adr-tank-details-subsequent-inspections-edit/adr-tank-details-subsequent-inspections-edit.component'; @@ -236,20 +235,13 @@ export const AdrSummaryTemplate: FormNode = { name: 'techRecord_adrDetails_additionalNotes_number', label: 'Guidance notes', type: FormNodeTypes.CONTROL, - editType: FormNodeEditTypes.CUSTOM, - editComponent: AdrGuidanceNotesComponent, + editType: FormNodeEditTypes.CHECKBOXGROUP, groups: ['adr_details', 'dangerous_goods'], hide: true, width: FormNodeWidth.XS, value: [], - customErrorMessage: 'Guidance notes is required with Able to carry dangerous goods', options: getOptionsFromEnum(ADRAdditionalNotesNumber), - validators: [ - { - name: ValidatorNames.IsArray, - args: { requiredIndices: [0], whenEquals: { sibling: 'techRecord_adrDetails_dangerousGoods', value: [true] } }, - }, - ], + validators: [], }, { name: 'techRecord_adrDetails_adrTypeApprovalNo', diff --git a/src/app/forms/templates/general/adr.template.ts b/src/app/forms/templates/general/adr.template.ts index 3ca4a4f918..902af33774 100644 --- a/src/app/forms/templates/general/adr.template.ts +++ b/src/app/forms/templates/general/adr.template.ts @@ -18,7 +18,6 @@ import { import { AdrExaminerNotesHistoryViewComponent, } from '@forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component'; -import { AdrGuidanceNotesComponent } from '@forms/custom-sections/adr-guidance-notes/adr-guidance-notes.component'; import { AdrTankDetailsInitialInspectionViewComponent, } from '@forms/custom-sections/adr-tank-details-initial-inspection-view/adr-tank-details-initial-inspection-view.component'; @@ -242,19 +241,14 @@ export const AdrTemplate: FormNode = { name: 'techRecord_adrDetails_additionalNotes_number', label: 'Guidance notes', type: FormNodeTypes.CONTROL, - editType: FormNodeEditTypes.CUSTOM, - editComponent: AdrGuidanceNotesComponent, + editType: FormNodeEditTypes.CHECKBOXGROUP, groups: ['adr_details', 'dangerous_goods'], hide: true, width: FormNodeWidth.XS, value: [], - customErrorMessage: 'Guidance notes is required with Able to carry dangerous goods', options: getOptionsFromEnum(ADRAdditionalNotesNumber), validators: [ - { - name: ValidatorNames.IsArray, - args: { requiredIndices: [0], whenEquals: { sibling: 'techRecord_adrDetails_dangerousGoods', value: [true] } }, - }, + { name: ValidatorNames.RequiredIfEquals, args: { sibling: 'techRecord_adrDetails_dangerousGoods', value: [true] } }, ], }, { From 57326c22b99dcb201d0298b4832af915108a1b74 Mon Sep 17 00:00:00 2001 From: pbardy2000 <146740183+pbardy2000@users.noreply.github.com> Date: Fri, 12 Apr 2024 11:20:13 +0100 Subject: [PATCH 16/20] feat(cb2-11546): make 'make' required for HGVs and TRLs which carry dangerous goods (#1461) * fix(cb2-11546): make vehicle make required when carrying dangerous goods * feat(cb2-11546): only make applicable for HGVs and LGVs --- src/app/forms/models/async-validators.enum.ts | 1 + .../forms/services/dynamic-form.service.ts | 1 + .../general/hgv-trl-body.template.ts | 2 + src/app/forms/utils/error-message-map.ts | 1 + .../custom-async-validators.spec.ts | 124 +++++++++++++++++- .../validators/custom-async-validators.ts | 20 ++- 6 files changed, 146 insertions(+), 3 deletions(-) diff --git a/src/app/forms/models/async-validators.enum.ts b/src/app/forms/models/async-validators.enum.ts index 14985ee9ca..4232bbe6ff 100644 --- a/src/app/forms/models/async-validators.enum.ts +++ b/src/app/forms/models/async-validators.enum.ts @@ -9,4 +9,5 @@ export enum AsyncValidatorNames { RequiredIfNotResult = 'requiredIfNotResult', HideIfEqualsWithCondition = 'hideIfEqualsWithCondition', PassResultDependantOnCustomDefects = 'passResultDependantOnCustomDefects', + RequiredWhenCarryingDangerousGoods = 'requiredWhenCarryingDangerousGoods', } diff --git a/src/app/forms/services/dynamic-form.service.ts b/src/app/forms/services/dynamic-form.service.ts index 0cb554a6e7..719ca039cc 100644 --- a/src/app/forms/services/dynamic-form.service.ts +++ b/src/app/forms/services/dynamic-form.service.ts @@ -107,6 +107,7 @@ export class DynamicFormService { [AsyncValidatorNames.ResultDependantOnRequiredStandards]: () => CustomAsyncValidators.resultDependantOnRequiredStandards(this.store), [AsyncValidatorNames.UpdateTesterDetails]: () => CustomAsyncValidators.updateTesterDetails(this.store), [AsyncValidatorNames.UpdateTestStationDetails]: () => CustomAsyncValidators.updateTestStationDetails(this.store), + [AsyncValidatorNames.RequiredWhenCarryingDangerousGoods]: () => CustomAsyncValidators.requiredWhenCarryingDangerousGoods(this.store), }; // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/src/app/forms/templates/general/hgv-trl-body.template.ts b/src/app/forms/templates/general/hgv-trl-body.template.ts index eda37032a8..e097b75124 100644 --- a/src/app/forms/templates/general/hgv-trl-body.template.ts +++ b/src/app/forms/templates/general/hgv-trl-body.template.ts @@ -1,3 +1,4 @@ +import { AsyncValidatorNames } from '@forms/models/async-validators.enum'; import { ValidatorNames } from '@forms/models/validators.enum'; import { TagType } from '@shared/components/tag/tag.component'; import { @@ -27,6 +28,7 @@ export const HgvAndTrlBodyTemplate: FormNode = { type: FormNodeTypes.CONTROL, editType: FormNodeEditTypes.TEXT, validators: [{ name: ValidatorNames.MaxLength, args: 50 }], + asyncValidators: [{ name: AsyncValidatorNames.RequiredWhenCarryingDangerousGoods }], customTags: [{ colour: TagType.PURPLE, label: TagTypeLabels.PLATES }], }, { diff --git a/src/app/forms/utils/error-message-map.ts b/src/app/forms/utils/error-message-map.ts index 9a47414b52..8318a8007f 100644 --- a/src/app/forms/utils/error-message-map.ts +++ b/src/app/forms/utils/error-message-map.ts @@ -50,4 +50,5 @@ export const ErrorMessageMap: Record = { [AsyncValidatorNames.RequiredIfNotFail]: (err: boolean, label?: string) => `${label || DEFAULT_LABEL} is required`, [AsyncValidatorNames.RequiredIfNotResult]: (err: boolean, label?: string) => `${label || DEFAULT_LABEL} is required`, [AsyncValidatorNames.RequiredIfNotResultAndSiblingEquals]: (err: boolean, label?: string) => `${label || DEFAULT_LABEL} is required`, + [AsyncValidatorNames.RequiredWhenCarryingDangerousGoods]: (err: { message: string }) => err.message, }; diff --git a/src/app/forms/validators/custom-async-validators.spec.ts b/src/app/forms/validators/custom-async-validators.spec.ts index 11f29ebf81..6c4e919959 100644 --- a/src/app/forms/validators/custom-async-validators.spec.ts +++ b/src/app/forms/validators/custom-async-validators.spec.ts @@ -1,5 +1,6 @@ import { TestBed } from '@angular/core/testing'; -import { FormGroup, ValidationErrors } from '@angular/forms'; +import { AbstractControl, FormGroup, ValidationErrors } from '@angular/forms'; +import { TechRecordType } from '@dvsa/cvs-type-definitions/types/v3/tech-record/tech-record-verb-vehicle-type'; import { operatorEnum } from '@forms/models/condition.model'; import { CustomFormControl, FormNodeTypes } from '@forms/services/dynamic-form.types'; import { createMockCustomDefect } from '@mocks/custom-defect.mock'; @@ -8,9 +9,10 @@ import { TestResultModel } from '@models/test-results/test-result.model'; import { resultOfTestEnum } from '@models/test-types/test-type.model'; import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { State, initialAppState } from '@store/.'; +import { editingTechRecord } from '@store/technical-records'; import { testResultInEdit } from '@store/test-records'; import { initialTestStationsState } from '@store/test-stations'; -import { Observable, firstValueFrom } from 'rxjs'; +import { Observable, firstValueFrom, lastValueFrom } from 'rxjs'; import { CustomAsyncValidators } from './custom-async-validators'; describe('resultDependantOnCustomDefects', () => { @@ -696,3 +698,121 @@ describe('hide if equals with condition', () => { expect((form.controls['bar'] as CustomFormControl).meta.hide).toBe(false); }); }); + +describe('requiredWhenCarryingDangerousGoods', () => { + let form: FormGroup; + let store: MockStore; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [provideMockStore({ initialState: initialAppState })], + }); + + store = TestBed.inject(MockStore); + + form = new FormGroup({ + techRecord_make: new CustomFormControl({ + name: 'techRecord_make', + type: FormNodeTypes.CONTROL, + children: [], + }, null), + techRecord_adrDetails_dangerousGoods: new CustomFormControl({ + name: 'techRecord_adrDetails_dangerousGoods', + type: FormNodeTypes.CONTROL, + children: [], + }, null), + }); + }); + it('should return null if the vehicle is not of type HGV or TRL', async () => { + // Not applicable tech record vehicle type + const carTechRecord: TechRecordType<'car', 'put'> = { + techRecord_vehicleType: 'car', + vin: 'car', + techRecord_reasonForCreation: 'test', + techRecord_statusCode: 'provisional', + }; + + store.overrideSelector(editingTechRecord, carTechRecord); + + const result = CustomAsyncValidators.requiredWhenCarryingDangerousGoods(store)(form.get('techRecord_make') as AbstractControl); + await expect(lastValueFrom(result)).resolves.toBeNull(); + }); + + it('should return null if the control is populated', async () => { + // Applicable vehicle tech record type + const hgvTechRecord: TechRecordType<'hgv', 'put'> = { + techRecord_vehicleType: 'hgv', + partialVin: '', + techRecord_bodyType_description: '', + techRecord_noOfAxles: 2, + techRecord_reasonForCreation: 'test', + techRecord_statusCode: 'provisional', + techRecord_vehicleClass_description: 'heavy goods vehicle', + primaryVrm: '', + vin: '', + + // Vehicle does carry dangerous goods + techRecord_adrDetails_dangerousGoods: true, + }; + + // ...but the control is populated + form.get('techRecord_make')?.patchValue('make'); + + store.overrideSelector(editingTechRecord, hgvTechRecord); + + const result = CustomAsyncValidators.requiredWhenCarryingDangerousGoods(store)(form.get('techRecord_make') as AbstractControl); + await expect(lastValueFrom(result)).resolves.toBeNull(); + }); + + it('should return null if the vehicle is an ADR vehicle, but does not carry dangerous goods', async () => { + // Applicable vehicle tech record type + const hgvTechRecord: TechRecordType<'hgv', 'put'> = { + techRecord_vehicleType: 'hgv', + partialVin: '', + techRecord_bodyType_description: '', + techRecord_noOfAxles: 2, + techRecord_reasonForCreation: 'test', + techRecord_statusCode: 'provisional', + techRecord_vehicleClass_description: 'heavy goods vehicle', + primaryVrm: '', + vin: '', + + // Vehicle doesn't carry dangerous goods + techRecord_adrDetails_dangerousGoods: false, + }; + + // ...and the control isn't populated + form.get('techRecord_make')?.patchValue(null); + + store.overrideSelector(editingTechRecord, hgvTechRecord); + + const result = CustomAsyncValidators.requiredWhenCarryingDangerousGoods(store)(form.get('techRecord_make') as AbstractControl); + await expect(lastValueFrom(result)).resolves.toBeNull(); + }); + + it('should return the required validation error when the vehicle is an ADR vehicle, and carries dangerous goods is selected', async () => { + // Applicable vehicle tech record type + const hgvTechRecord: TechRecordType<'hgv', 'put'> = { + techRecord_vehicleType: 'hgv', + partialVin: '', + techRecord_bodyType_description: '', + techRecord_noOfAxles: 2, + techRecord_reasonForCreation: 'test', + techRecord_statusCode: 'provisional', + techRecord_vehicleClass_description: 'heavy goods vehicle', + primaryVrm: '', + vin: '', + + // Vehicle does carry dangerous goods + techRecord_adrDetails_dangerousGoods: true, + }; + + // ...and the control isn't populated + form.get('techRecord_make')?.patchValue(null); + + store.overrideSelector(editingTechRecord, hgvTechRecord); + + const result = CustomAsyncValidators.requiredWhenCarryingDangerousGoods(store)(form.get('techRecord_make') as AbstractControl); + await expect(lastValueFrom(result)).resolves.toStrictEqual({ required: true }); + }); +}); diff --git a/src/app/forms/validators/custom-async-validators.ts b/src/app/forms/validators/custom-async-validators.ts index 1a0b1ad744..395ed33793 100644 --- a/src/app/forms/validators/custom-async-validators.ts +++ b/src/app/forms/validators/custom-async-validators.ts @@ -1,4 +1,6 @@ -import { AbstractControl, AsyncValidatorFn, ValidationErrors } from '@angular/forms'; +import { + AbstractControl, AsyncValidatorFn, ValidationErrors, Validators, +} from '@angular/forms'; import { Condition, operatorEnum } from '@forms/models/condition.model'; // eslint-disable-next-line import/no-cycle import { CustomFormControl } from '@forms/services/dynamic-form.types'; @@ -9,6 +11,7 @@ import { resultOfTestEnum } from '@models/test-types/test-type.model'; import { Store, select } from '@ngrx/store'; import { State } from '@store/.'; import { selectUserByResourceKey } from '@store/reference-data'; +import { editingTechRecord } from '@store/technical-records'; import { testResultInEdit } from '@store/test-records'; import { getTestStationFromProperty } from '@store/test-stations'; import { @@ -224,6 +227,21 @@ export class CustomAsyncValidators { ); } + static requiredWhenCarryingDangerousGoods = (store: Store) => { + return (control: AbstractControl): Observable => { + return store.select(editingTechRecord).pipe(take(1), map((form) => { + if ( + form + && (form.techRecord_vehicleType === 'hgv' || form.techRecord_vehicleType === 'trl') + && (form.techRecord_adrDetails_dangerousGoods)) { + return Validators.required(control); + } + + return null; + })); + }; + }; + private static checkConditions(testResult: TestResultModel, conditions: Condition | Condition[]) { if (!Array.isArray(conditions)) { return CustomAsyncValidators.checkCondition(testResult, conditions); From 49993bd0ca1e9d7e8997c32fcf7d899034333f1d Mon Sep 17 00:00:00 2001 From: pbardy2000 <146740183+pbardy2000@users.noreply.github.com> Date: Mon, 15 Apr 2024 09:04:13 +0100 Subject: [PATCH 17/20] feat(cb2-10286): add new certificate required field (#1463) * feat(cb2-10286): add new certificate required field * feat(cb2-9747): default checkbox to false so it will correctly display no text in read mode --- ...w-certificate-required-view.component.html | 12 ++++++ ...w-certificate-required-view.component.scss | 11 ++++++ ...ertificate-required-view.component.spec.ts | 39 +++++++++++++++++++ ...new-certificate-required-view.component.ts | 17 ++++++++ src/app/forms/dynamic-forms.module.ts | 4 ++ .../templates/general/adr-summary.template.ts | 21 ++++++++++ .../forms/templates/general/adr.template.ts | 21 ++++++++++ .../technical-record-service.reducer.ts | 1 + 8 files changed, 126 insertions(+) create mode 100644 src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.html create mode 100644 src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.scss create mode 100644 src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.spec.ts create mode 100644 src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.ts diff --git a/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.html b/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.html new file mode 100644 index 0000000000..45022e3b8c --- /dev/null +++ b/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.html @@ -0,0 +1,12 @@ + + + + + + + + +
+ New Certificate required: + {{ control.value | defaultNullOrEmpty }}
+
diff --git a/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.scss b/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.scss new file mode 100644 index 0000000000..20740fe733 --- /dev/null +++ b/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.scss @@ -0,0 +1,11 @@ +.m-0 { + margin: 0; +} + +.break-words { + word-break: break-word; +} + +.border-b-0 { + border-bottom-width: 0; +} \ No newline at end of file diff --git a/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.spec.ts b/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.spec.ts new file mode 100644 index 0000000000..63e0703123 --- /dev/null +++ b/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.spec.ts @@ -0,0 +1,39 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NG_VALUE_ACCESSOR, NgControl } from '@angular/forms'; +import { CustomFormControl, FormNodeTypes } from '@forms/services/dynamic-form.types'; +import { provideMockStore } from '@ngrx/store/testing'; +import { State, initialAppState } from '@store/index'; +import { AdrTankDetailsM145ViewComponent } from '../adr-tank-details-m145-view/adr-tank-details-m145-view.component'; +import { AdrNewCertificateRequiredViewComponent } from './adr-new-certificate-required-view.component'; + +describe('AdrNewCertificateRequiredViewComponent', () => { + let component: AdrNewCertificateRequiredViewComponent; + let fixture: ComponentFixture; + + const control = new CustomFormControl({ + name: 'techRecord_adrDetails_m145Statement', + type: FormNodeTypes.CONTROL, + value: [], + }); + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AdrNewCertificateRequiredViewComponent], + providers: [ + provideMockStore({ initialState: initialAppState }), + { provide: NG_VALUE_ACCESSOR, useExisting: AdrTankDetailsM145ViewComponent, multi: true }, + { provide: NgControl, useValue: { control } }, + ], + }) + .compileComponents(); + + fixture = TestBed.createComponent(AdrNewCertificateRequiredViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.ts b/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.ts new file mode 100644 index 0000000000..132dcd90de --- /dev/null +++ b/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.ts @@ -0,0 +1,17 @@ +import { Component } from '@angular/core'; +import { NG_VALUE_ACCESSOR } from '@angular/forms'; +import { BaseControlComponent } from '@forms/components/base-control/base-control.component'; + +@Component({ + selector: 'app-adr-new-certificate-required-view', + templateUrl: './adr-new-certificate-required-view.component.html', + styleUrl: './adr-new-certificate-required-view.component.scss', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: AdrNewCertificateRequiredViewComponent, + multi: true, + }, + ], +}) +export class AdrNewCertificateRequiredViewComponent extends BaseControlComponent {} diff --git a/src/app/forms/dynamic-forms.module.ts b/src/app/forms/dynamic-forms.module.ts index 821f4ff45f..a9aea0b22a 100644 --- a/src/app/forms/dynamic-forms.module.ts +++ b/src/app/forms/dynamic-forms.module.ts @@ -38,6 +38,9 @@ import { ViewCombinationComponent } from './components/view-combination/view-com import { ViewListItemComponent } from './components/view-list-item/view-list-item.component'; import { AbandonDialogComponent } from './custom-sections/abandon-dialog/abandon-dialog.component'; import { AdrExaminerNotesHistoryViewComponent } from './custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component'; +import { + AdrNewCertificateRequiredViewComponent, +} from './custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component'; import { AdrTankDetailsInitialInspectionViewComponent, } from './custom-sections/adr-tank-details-initial-inspection-view/adr-tank-details-initial-inspection-view.component'; @@ -141,6 +144,7 @@ import { SuffixDirective } from './directives/suffix.directive'; AdrCertificateHistoryComponent, AdrTankDetailsM145ViewComponent, ContingencyAdrGenerateCertComponent, + AdrNewCertificateRequiredViewComponent, ], imports: [CommonModule, FormsModule, ReactiveFormsModule, SharedModule, RouterModule], exports: [ diff --git a/src/app/forms/templates/general/adr-summary.template.ts b/src/app/forms/templates/general/adr-summary.template.ts index 8dc59f683e..b95eca03e1 100644 --- a/src/app/forms/templates/general/adr-summary.template.ts +++ b/src/app/forms/templates/general/adr-summary.template.ts @@ -14,6 +14,9 @@ import { import { AdrExaminerNotesHistoryViewComponent, } from '@forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component'; +import { + AdrNewCertificateRequiredViewComponent, +} from '@forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component'; import { AdrTankDetailsInitialInspectionViewComponent, } from '@forms/custom-sections/adr-tank-details-initial-inspection-view/adr-tank-details-initial-inspection-view.component'; @@ -749,6 +752,24 @@ export const AdrSummaryTemplate: FormNode = { groups: ['declarations_details', 'dangerous_goods'], hide: true, }, + { + name: 'NewCertificateRequested', + label: 'New Certificate required', + type: FormNodeTypes.TITLE, + groups: ['dangerous_goods'], + hide: true, + }, + { + name: 'techRecord_adrDetails_newCertificateRequested', + label: 'Yes', + type: FormNodeTypes.CONTROL, + editType: FormNodeEditTypes.CHECKBOX, + viewType: FormNodeViewTypes.CUSTOM, + viewComponent: AdrNewCertificateRequiredViewComponent, + value: false, + groups: ['dangerous_goods'], + hide: true, + }, { name: 'ExaminerNotesSectionTitle', label: 'Additional Examiner Notes History', diff --git a/src/app/forms/templates/general/adr.template.ts b/src/app/forms/templates/general/adr.template.ts index 902af33774..dfe6e4fcb1 100644 --- a/src/app/forms/templates/general/adr.template.ts +++ b/src/app/forms/templates/general/adr.template.ts @@ -18,6 +18,9 @@ import { import { AdrExaminerNotesHistoryViewComponent, } from '@forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component'; +import { + AdrNewCertificateRequiredViewComponent, +} from '@forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component'; import { AdrTankDetailsInitialInspectionViewComponent, } from '@forms/custom-sections/adr-tank-details-initial-inspection-view/adr-tank-details-initial-inspection-view.component'; @@ -751,6 +754,24 @@ export const AdrTemplate: FormNode = { groups: ['declarations_details', 'dangerous_goods'], hide: true, }, + { + name: 'NewCertificateRequested', + label: 'New Certificate required', + type: FormNodeTypes.TITLE, + groups: ['dangerous_goods'], + hide: true, + }, + { + name: 'techRecord_adrDetails_newCertificateRequested', + label: 'Yes', + type: FormNodeTypes.CONTROL, + viewType: FormNodeViewTypes.CUSTOM, + viewComponent: AdrNewCertificateRequiredViewComponent, + editType: FormNodeEditTypes.CHECKBOX, + value: false, + groups: ['dangerous_goods'], + hide: true, + }, { name: 'ExaminerNotesSectionTitle', label: 'Additional Examiner Notes History', diff --git a/src/app/store/technical-records/reducers/technical-record-service.reducer.ts b/src/app/store/technical-records/reducers/technical-record-service.reducer.ts index 908c1241c3..fa0c2f1a53 100644 --- a/src/app/store/technical-records/reducers/technical-record-service.reducer.ts +++ b/src/app/store/technical-records/reducers/technical-record-service.reducer.ts @@ -450,6 +450,7 @@ function handleClearADRDetails(state: TechnicalRecordServiceState) { techRecord_adrDetails_additionalNotes_number: null, techRecord_adrDetails_adrTypeApprovalNo: null, techRecord_adrDetails_adrCertificateNotes: null, + techRecord_adrDetails_newCertificateRequested: null, ...nulledTankDetails, }, }; From e5d2de9433624a148e342d61c54e1be646bcc514 Mon Sep 17 00:00:00 2001 From: Thomas Crawley Date: Mon, 15 Apr 2024 09:11:30 +0100 Subject: [PATCH 18/20] feat/CB2-10740 - Mark if a vehicle is used for international journeys on VTM (#1467) * feat(cb2-10740): hook up template and values correctly to type definition * feat(cb2-10740): lint fix --------- Co-authored-by: pbardy2000 <146740183+pbardy2000@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- ...xaminer-notes-history-view.component.spec.ts | 3 +-- .../templates/general/adr-summary.template.ts | 12 ++++++++++++ src/app/forms/templates/general/adr.template.ts | 17 ++++++++++++++++- .../technical-record-service.reducer.ts | 1 + 6 files changed, 35 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index d68358f863..1be11df960 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "@angular/router": "^17.2.1", "@azure/msal-angular": "^3.0.13", "@azure/msal-browser": "^3.10.0", - "@dvsa/cvs-type-definitions": "^6.2.0", + "@dvsa/cvs-type-definitions": "^6.3.0", "@ngrx/effects": "^17.1.0", "@ngrx/entity": "^17.1.0", "@ngrx/router-store": "^17.1.0", @@ -3723,9 +3723,9 @@ } }, "node_modules/@dvsa/cvs-type-definitions": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@dvsa/cvs-type-definitions/-/cvs-type-definitions-6.2.0.tgz", - "integrity": "sha512-r1oPXfn0WeP9zitBJVU+w0r4Eco4t02Wl54UdxeEdJ6B0u0BNC7mIQ1Wr1RqQmMw4kCFSIYop6RinEVpbp/WtA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@dvsa/cvs-type-definitions/-/cvs-type-definitions-6.3.0.tgz", + "integrity": "sha512-wWeGVDdfacUnO+aM1a/42k72XJjPwWIT/9Fc94hJATdUeF8b4rd7DefDXHEzlP+7uZr7CwtVn0/bLStJ7n35Tw==", "dependencies": { "ajv": "^8.12.0", "json-schema-deref-sync": "^0.14.0", diff --git a/package.json b/package.json index e82a2f37c5..01bfaf4df4 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@angular/router": "^17.2.1", "@azure/msal-angular": "^3.0.13", "@azure/msal-browser": "^3.10.0", - "@dvsa/cvs-type-definitions": "^6.2.0", + "@dvsa/cvs-type-definitions": "^6.3.0", "@ngrx/effects": "^17.1.0", "@ngrx/entity": "^17.1.0", "@ngrx/router-store": "^17.1.0", diff --git a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.spec.ts b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.spec.ts index 3d10b42996..cac1bda6d0 100644 --- a/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.spec.ts +++ b/src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.spec.ts @@ -8,9 +8,8 @@ import { mockVehicleTechnicalRecord } from '@mocks/mock-vehicle-technical-record import { VehicleTypes } from '@models/vehicle-tech-record.model'; import { TechRecordType } from '@dvsa/cvs-type-definitions/types/v3/tech-record/tech-record-vehicle-type'; import { of } from 'rxjs'; -import { AdrExaminerNotesHistoryViewComponent } from './adr-examiner-notes-history-view.component'; import { RouterService } from '@services/router/router.service'; - +import { AdrExaminerNotesHistoryViewComponent } from './adr-examiner-notes-history-view.component'; describe('AdrExaminerNotesHistoryViewComponent', () => { let component: AdrExaminerNotesHistoryViewComponent; diff --git a/src/app/forms/templates/general/adr-summary.template.ts b/src/app/forms/templates/general/adr-summary.template.ts index b95eca03e1..3ef290f770 100644 --- a/src/app/forms/templates/general/adr-summary.template.ts +++ b/src/app/forms/templates/general/adr-summary.template.ts @@ -173,6 +173,18 @@ export const AdrSummaryTemplate: FormNode = { }, ], }, + { + name: 'techRecord_adrDetails_vehicleDetails_usedOnInternationalJourneys', + label: 'Vehicle used on international journeys', + type: FormNodeTypes.CONTROL, + options: [ + { value: 'yes', label: 'Yes' }, + { value: 'no', label: 'No' }, + { value: 'n/a', label: 'Not applicable' }, + ], + hide: true, + groups: ['adr_details', 'dangerous_goods'], + }, { name: 'techRecord_adrDetails_vehicleDetails_approvalDate', label: 'Date processed', diff --git a/src/app/forms/templates/general/adr.template.ts b/src/app/forms/templates/general/adr.template.ts index dfe6e4fcb1..2ea993c830 100644 --- a/src/app/forms/templates/general/adr.template.ts +++ b/src/app/forms/templates/general/adr.template.ts @@ -24,7 +24,9 @@ import { import { AdrTankDetailsInitialInspectionViewComponent, } from '@forms/custom-sections/adr-tank-details-initial-inspection-view/adr-tank-details-initial-inspection-view.component'; -import { AdrTankDetailsM145ViewComponent } from '@forms/custom-sections/adr-tank-details-m145-view/adr-tank-details-m145-view.component'; +import { + AdrTankDetailsM145ViewComponent, +} from '@forms/custom-sections/adr-tank-details-m145-view/adr-tank-details-m145-view.component'; import { AdrTankDetailsSubsequentInspectionsEditComponent, } from '@forms/custom-sections/adr-tank-details-subsequent-inspections-edit/adr-tank-details-subsequent-inspections-edit.component'; @@ -178,6 +180,19 @@ export const AdrTemplate: FormNode = { }, ], }, + { + name: 'techRecord_adrDetails_vehicleDetails_usedOnInternationalJourneys', + label: 'Vehicle used on international journeys', + type: FormNodeTypes.CONTROL, + editType: FormNodeEditTypes.RADIO, + options: [ + { value: 'yes', label: 'Yes' }, + { value: 'no', label: 'No' }, + { value: 'n/a', label: 'Not applicable' }, + ], + hide: true, + groups: ['adr_details', 'dangerous_goods'], + }, { name: 'techRecord_adrDetails_vehicleDetails_approvalDate', label: 'Date processed', diff --git a/src/app/store/technical-records/reducers/technical-record-service.reducer.ts b/src/app/store/technical-records/reducers/technical-record-service.reducer.ts index fa0c2f1a53..320ce60951 100644 --- a/src/app/store/technical-records/reducers/technical-record-service.reducer.ts +++ b/src/app/store/technical-records/reducers/technical-record-service.reducer.ts @@ -427,6 +427,7 @@ function handleClearADRDetails(state: TechnicalRecordServiceState) { editingTechRecord: { ...editingTechRecord, techRecord_adrDetails_vehicleDetails_type: null, + techRecord_adrDetails_vehicleDetails_usedOnInternationalJourneys: null, techRecord_adrDetails_vehicleDetails_approvalDate: null, techRecord_adrDetails_permittedDangerousGoods: null, ...nulledCompatibilityGroupJ, From d9c602aae1776ade1587eb9edd72802c1a7dd63c Mon Sep 17 00:00:00 2001 From: Brandon Thomas-Davies <87308252+BrandonT95@users.noreply.github.com> Date: Mon, 15 Apr 2024 13:41:14 +0100 Subject: [PATCH 19/20] fix(cb2-9747): fix failing unit test (#1468) --- .../adr-new-certificate-required-view.component.spec.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.spec.ts b/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.spec.ts index 63e0703123..88ca0a36d5 100644 --- a/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.spec.ts +++ b/src/app/forms/custom-sections/adr-new-certificate-required-view/adr-new-certificate-required-view.component.spec.ts @@ -6,6 +6,7 @@ import { provideMockStore } from '@ngrx/store/testing'; import { State, initialAppState } from '@store/index'; import { AdrTankDetailsM145ViewComponent } from '../adr-tank-details-m145-view/adr-tank-details-m145-view.component'; import { AdrNewCertificateRequiredViewComponent } from './adr-new-certificate-required-view.component'; +import { SharedModule } from '@shared/shared.module'; describe('AdrNewCertificateRequiredViewComponent', () => { let component: AdrNewCertificateRequiredViewComponent; @@ -19,7 +20,8 @@ describe('AdrNewCertificateRequiredViewComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [AdrNewCertificateRequiredViewComponent], + declarations: [AdrNewCertificateRequiredViewComponent], + imports: [SharedModule], providers: [ provideMockStore({ initialState: initialAppState }), { provide: NG_VALUE_ACCESSOR, useExisting: AdrTankDetailsM145ViewComponent, multi: true }, From 3e639e7d687b2e245c9348dce0e720615cd5a2e4 Mon Sep 17 00:00:00 2001 From: Brandon Thomas-Davies <87308252+BrandonT95@users.noreply.github.com> Date: Tue, 16 Apr 2024 11:47:05 +0100 Subject: [PATCH 20/20] fix(cb2-9747): create mocked date to fix failing unit test (#1469) --- .../reducers/technical-record-service.reducer.spec.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/app/store/technical-records/reducers/technical-record-service.reducer.spec.ts b/src/app/store/technical-records/reducers/technical-record-service.reducer.spec.ts index 1991ea32fb..9bb48cd36b 100644 --- a/src/app/store/technical-records/reducers/technical-record-service.reducer.spec.ts +++ b/src/app/store/technical-records/reducers/technical-record-service.reducer.spec.ts @@ -559,7 +559,16 @@ describe('Vehicle Technical Record Reducer', () => { }); describe('handleADRExaminerNoteChanges', () => { - it('should', () => { + beforeEach(() => { + const mockedDate = new Date(2024, 5, 20); + jest.useFakeTimers(); + jest.setSystemTime(mockedDate); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + it('should handle any changes made to the adr examiner notes', () => { const testNote = { note: 'testNote', createdAtDate: new Date().toISOString(),