Skip to content

Commit

Permalink
feat/CB2-10033 - Additional Examiner Note (#1448)
Browse files Browse the repository at this point in the history
* 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 <thomas.evans@dvsa.gov.uk>
Co-authored-by: Thomas Evans <36958694+tomevs88@users.noreply.github.com>
  • Loading branch information
4 people authored Apr 5, 2024
1 parent 5b4e5c1 commit 3269b25
Show file tree
Hide file tree
Showing 19 changed files with 410 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1,31 @@
<div>This is a blank page right now.</div>
<div *ngIf="currentTechRecord">
<div class="govuk-grid-row">
<div class="govuk-grid-column-full">
<dl class="govuk-summary-list">
<h1 class="govuk-heading-l">Edit Additional Examiner Note</h1>
<div class="parent-div">
<td class="govuk-heading-s">Date</td>
<td class="table-value">{{ examinerNoteObj.createdAtDate | date: 'dd/MM/yyyy' | defaultNullOrEmpty }}</td>
<td class="govuk-heading-s">Created by</td>
<td class="table-value">{{ examinerNoteObj.lastUpdatedBy }}</td>
</div>
<div class="govuk-summary-list__row">
<form [formGroup]="form">
<app-text-area
#examinerNote
formControlName="additionalExaminerNote"
name="AdditionalExaminerNote"
[width]="width.L"
(ngModelChange)="ngOnChanges(examinerNote.value)"
>
</app-text-area>
</form>
</div>
</dl>
</div>
</div>
<app-button-group>
<app-button id="submit-examiner-note" (clicked)="handleSubmit()">Save</app-button>
<app-button id="cancel-amend-examiner-note" design="link" data-module="govuk-button" (clicked)="navigateBack()">Cancel</app-button>
</app-button-group>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.parent-div {
display: flex;
flex-direction: row;
}
.table-value {
margin-left: 1%;
margin-right: 1%;
}
Original file line number Diff line number Diff line change
@@ -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 = {
Expand All @@ -18,6 +16,11 @@ const mockTechRecordService = {
describe('TechRecordEditAdditionalExaminerNoteComponent', () => {
let fixture: ComponentFixture<TechRecordEditAdditionalExaminerNoteComponent>;
let component: TechRecordEditAdditionalExaminerNoteComponent;
let router: Router;
let errorService: GlobalErrorService;
let route: ActivatedRoute;
let store: MockStore;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [TechRecordEditAdditionalExaminerNoteComponent],
Expand All @@ -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();
});
});
});
Original file line number Diff line number Diff line change
@@ -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<boolean>(1);
form!: FormGroup;
formControl!: CustomFormControl;

constructor(
private router: Router,
private route: ActivatedRoute,
private technicalRecordService: TechnicalRecordService,
private globalErrorService: GlobalErrorService,
private store: Store<State>,
) { }

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;
}

}
14 changes: 10 additions & 4 deletions src/app/features/tech-record/tech-record-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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],
},
{
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<ng-container *ngFor="let examinerNote of currentAdrNotesPage; let i = index; let isLast = last">
<tr class="govuk-table__row" *ngIf="i < 3">
<td class="govuk-table__cell break-words" [class.border-b-0]="i === 2 || isLast">
{{ examinerNote.note }}
<collapsible-text [text]="examinerNote.note ?? ''" [maxChars]="150"></collapsible-text>
</td>
<td class="govuk-table__cell break-words" [class.border-b-0]="i === 2 || isLast">{{ examinerNote.lastUpdatedBy }}</td>
<td class="govuk-table__cell break-words" [class.border-b-0]="i === 2 || isLast">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<ng-container *ngIf="control">
<ng-container *ngIf="adrNotes">
<section class="govuk-!-margin-top-4">
<h3 class="govuk-heading-m">Additional Examiner Notes History</h3>
<table class="govuk-table" *ngIf="adrNotes && adrNotes.length > 0; else empty">
<tbody class="govuk-table__body">
<tr class="govuk-table__row">
Expand All @@ -12,11 +11,16 @@ <h3 class="govuk-heading-m">Additional Examiner Notes History</h3>
<ng-container *ngFor="let result of currentAdrNotesPage; let i = index; let isLast = last">
<tr class="govuk-table__row" *ngIf="i < 3">
<td class="govuk-table__cell break-words" [class.border-b-0]="i === 2 || isLast">
{{ result.note }}
<ng-container *ngIf="(isEditing$ | async) === false">
<collapsible-text [text]="result.note ?? ''" [maxChars]="150"></collapsible-text>
</ng-container>
<ng-container *ngIf="(isEditing$ | async) === true">
{{ result.note }}
</ng-container>
</td>
<td class="govuk-table__cell break-words" [class.border-b-0]="i === 2 || isLast">{{ result.lastUpdatedBy }}</td>
<td class="govuk-table__cell break-words" [class.border-b-0]="i === 2 || isLast">
{{ result.createdAtDate | date : 'dd/MM/yyyy HH:mm' | defaultNullOrEmpty }}
{{ result.createdAtDate | date: 'dd/MM/yyyy' | defaultNullOrEmpty }}
</td>
</tr>
</ng-container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Check failure on line 12 in src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.spec.ts

View workflow job for this annotation

GitHub Actions / lint (18.18.0)

`@services/router/router.service` import should occur before import of `./adr-examiner-notes-history-view.component`


Check failure on line 14 in src/app/forms/custom-sections/adr-examiner-notes-history-view/adr-examiner-notes-history-view.component.spec.ts

View workflow job for this annotation

GitHub Actions / lint (18.18.0)

More than 1 blank line not allowed
describe('AdrExaminerNotesHistoryViewComponent', () => {
let component: AdrExaminerNotesHistoryViewComponent;
Expand All @@ -18,6 +20,7 @@ describe('AdrExaminerNotesHistoryViewComponent', () => {
const mockTechRecordService = {
techRecord$: of({ ...MOCK_HGV }),
};
const mockRouterService = {};

const control = new CustomFormControl({
name: 'techRecord_adrDetails_additionalExaminerNotes',
Expand All @@ -30,6 +33,7 @@ describe('AdrExaminerNotesHistoryViewComponent', () => {
providers: [
provideMockStore<State>({ initialState: initialAppState }),
{ provide: TechnicalRecordService, useValue: mockTechRecordService },
{ provide: RouterService, useValue: mockRouterService },
{ provide: NG_VALUE_ACCESSOR, useExisting: AdrExaminerNotesHistoryViewComponent, multi: true },
{
provide: NgControl,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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;
Expand All @@ -33,6 +37,10 @@ export class AdrExaminerNotesHistoryViewComponent extends BaseControlComponent i
});
}

get isEditing$(): Observable<boolean> {
return this.routerService.getRouteDataProperty$('isEditing').pipe(map((isEditing) => !!isEditing));
}

handlePaginationChange({ start, end }: { start: number; end: number }): void {
this.pageStart = start;
this.pageEnd = end;
Expand Down
Loading

0 comments on commit 3269b25

Please sign in to comment.