-
+
+
diff --git a/frontend/src/app/features/wdf/wdf-data-change/wdf-staff-summary/wdf-staff-summary.component.spec.ts b/frontend/src/app/features/wdf/wdf-data-change/wdf-staff-summary/wdf-staff-summary.component.spec.ts
index fe3a06a0d7..37aa44d592 100644
--- a/frontend/src/app/features/wdf/wdf-data-change/wdf-staff-summary/wdf-staff-summary.component.spec.ts
+++ b/frontend/src/app/features/wdf/wdf-data-change/wdf-staff-summary/wdf-staff-summary.component.spec.ts
@@ -1,45 +1,84 @@
import { HttpClient } from '@angular/common/http';
import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { getTestBed } from '@angular/core/testing';
import { BrowserModule } from '@angular/platform-browser';
-import { Router } from '@angular/router';
+import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { Establishment } from '@core/model/establishment.model';
import { Worker } from '@core/model/worker.model';
import { EstablishmentService } from '@core/services/establishment.service';
import { PermissionsService } from '@core/services/permissions/permissions.service';
-import { ReportService } from '@core/services/report.service';
import { UserService } from '@core/services/user.service';
+import { WorkerService } from '@core/services/worker.service';
import { establishmentBuilder, MockEstablishmentService } from '@core/test-utils/MockEstablishmentService';
import { MockPermissionsService } from '@core/test-utils/MockPermissionsService';
-import { MockReportService } from '@core/test-utils/MockReportService';
import { workerBuilder } from '@core/test-utils/MockWorkerService';
+import { PaginationComponent } from '@shared/components/pagination/pagination.component';
+import { SearchInputComponent } from '@shared/components/search-input/search-input.component';
+import { TablePaginationWrapperComponent } from '@shared/components/table-pagination-wrapper/table-pagination-wrapper.component';
import { SharedModule } from '@shared/shared.module';
-import { render } from '@testing-library/angular';
+import { fireEvent, render } from '@testing-library/angular';
+import userEvent from '@testing-library/user-event';
+import { of } from 'rxjs';
+import sinon from 'sinon';
import { WdfModule } from '../wdf.module';
import { WdfStaffSummaryComponent } from './wdf-staff-summary.component';
describe('WdfStaffSummaryComponent', () => {
- const setup = async () => {
- const { fixture, getByText, getAllByText, getByTestId, queryByText } = await render(WdfStaffSummaryComponent, {
- imports: [RouterTestingModule, HttpClientTestingModule, BrowserModule, SharedModule, WdfModule],
+ const setup = async (overrides: any = {}) => {
+ const establishment = establishmentBuilder() as Establishment;
+ const workers = [workerBuilder(), workerBuilder(), workerBuilder()] as Worker[];
+
+ const setupTools = await render(WdfStaffSummaryComponent, {
+ imports: [RouterTestingModule, HttpClientTestingModule, BrowserModule, SharedModule, WdfModule, RouterModule],
+ declarations: [PaginationComponent, TablePaginationWrapperComponent, SearchInputComponent],
providers: [
- { provide: ReportService, useClass: MockReportService },
{
provide: PermissionsService,
useFactory: MockPermissionsService.factory(['canViewWorker']),
deps: [HttpClient, Router, UserService],
},
+ WorkerService,
+ {
+ provide: ActivatedRoute,
+ useValue: {
+ snapshot: {
+ queryParamMap: {
+ get: sinon.fake(),
+ },
+ params: overrides?.params ?? {
+ establishmentuid: establishment.uid,
+ },
+ },
+ },
+ },
{ provide: EstablishmentService, useClass: MockEstablishmentService },
],
componentProperties: {
- workplace: establishmentBuilder() as Establishment,
- workers: [workerBuilder(), workerBuilder(), workerBuilder()] as Worker[],
+ workplace: establishment,
+ workers: workers,
+ workerCount: workers.length,
+ ...overrides?.componentProperties,
},
});
- const component = fixture.componentInstance;
+ const component = setupTools.fixture.componentInstance;
+
+ const injector = getTestBed();
+ const router = injector.inject(Router) as Router;
+ const routerSpy = spyOn(router, 'navigate').and.returnValue(null);
+ const workerService = injector.inject(WorkerService) as WorkerService;
+
+ const getAllWorkersSpy = spyOn(workerService, 'getAllWorkers').and.returnValue(
+ of({ workers: [...workers, ...workers, ...workers, ...workers, ...workers, ...workers], workerCount: 18 }),
+ );
- return { component, fixture, getByText, getAllByText, getByTestId, queryByText };
+ return {
+ ...setupTools,
+ component,
+ routerSpy,
+ getAllWorkersSpy,
+ };
};
it('should render a WdfStaffSummaryComponent', async () => {
@@ -47,86 +86,232 @@ describe('WdfStaffSummaryComponent', () => {
expect(component).toBeTruthy();
});
- it('should display green ticks on 3 staff records when the user has qualified for WDF and all staff records are eligible', async () => {
- const { component, fixture, getAllByText } = await setup();
- const greenTickVisuallyHiddenMessage = 'Green tick';
- const meetingMessage = 'Meeting';
+ it('should display the table headers', async () => {
+ const { getByText } = await setup();
- component.overallWdfEligibility = true;
- component.workers[0].wdfEligible = true;
- component.workers[1].wdfEligible = true;
- component.workers[2].wdfEligible = true;
- fixture.detectChanges();
-
- expect(getAllByText(greenTickVisuallyHiddenMessage, { exact: false }).length).toBe(3);
- expect(getAllByText(meetingMessage, { exact: true }).length).toBe(3);
+ expect(getByText('Name or ID number')).toBeTruthy();
+ expect(getByText('Job role')).toBeTruthy();
+ expect(getByText('Last update')).toBeTruthy();
+ expect(getByText('Funding requirements')).toBeTruthy();
});
- it('should display an orange flag on staff record when the user has qualified for WDF but 1 staff record is no longer eligible', async () => {
- const { component, fixture, getByText } = await setup();
- const orangeFlagVisuallyHiddenMessage = 'Orange warning flag';
- const notMeetingMessage = 'Not meeting';
+ describe('Calling getAllWorkers when sorting', () => {
+ const sortByOptions = [
+ ['0_asc', 'staffNameAsc', 'Staff name (A to Z)'],
+ ['0_dsc', 'staffNameDesc', 'Staff name (Z to A)'],
+ ['1_asc', 'jobRoleAsc', 'Job role (A to Z)'],
+ ['1_dsc', 'jobRoleDesc', 'Job role (Z to A)'],
+ ['2_meeting', 'wdfMeeting', 'Funding requirements (meeting)'],
+ ['2_not_meeting', 'wdfNotMeeting', 'Funding requirements (not meeting)'],
+ ];
+
+ for (const option of sortByOptions) {
+ it(`should call getAllWorkers with sortBy set to ${option[1]} when sorting by ${option[2]}`, async () => {
+ const { component, getAllWorkersSpy, getByLabelText, getByText } = await setup();
+
+ const select = getByLabelText('Sort by', { exact: false });
- component.overallWdfEligibility = true;
- component.workers[0].wdfEligible = false;
- component.workers[1].wdfEligible = true;
- component.workers[2].wdfEligible = true;
- fixture.detectChanges();
+ const optionElement = getByText(option[2]) as HTMLOptionElement;
+ fireEvent.change(select, { target: { value: optionElement.value } });
- expect(getByText(orangeFlagVisuallyHiddenMessage, { exact: false })).toBeTruthy();
- expect(getByText(notMeetingMessage, { exact: true })).toBeTruthy();
+ const establishmentUid = component.workplace.uid;
+ const paginationEmission = { pageIndex: 0, itemsPerPage: 15, sortBy: option[1] };
+
+ expect(getAllWorkersSpy.calls.mostRecent().args[0]).toEqual(establishmentUid);
+ expect(getAllWorkersSpy.calls.mostRecent().args[1]).toEqual(paginationEmission);
+ });
+ }
});
- it('should display one orange flag and two green flags when the user has qualified for WDF but 1 staff record is no longer eligible and two still are', async () => {
- const { component, fixture, getByText, getAllByText } = await setup();
- const orangeFlagVisuallyHiddenMessage = 'Orange warning flag';
- const notMeetingMessage = 'Not meeting';
- const greenTickVisuallyHiddenMessage = 'Green tick';
- const meetingMessage = 'Meeting';
+ describe('Calling getAllWorkers when using search', () => {
+ it('it does not render the search bar when pagination threshold is not met', async () => {
+ const { queryByLabelText } = await setup();
- component.overallWdfEligibility = true;
- component.workers[0].wdfEligible = false;
- component.workers[1].wdfEligible = true;
- component.workers[2].wdfEligible = true;
- fixture.detectChanges();
+ const searchInput = queryByLabelText('Search staff training records');
+ expect(searchInput).toBeNull();
+ });
- expect(getByText(orangeFlagVisuallyHiddenMessage, { exact: false })).toBeTruthy();
- expect(getByText(notMeetingMessage, { exact: true })).toBeTruthy();
- expect(getAllByText(greenTickVisuallyHiddenMessage, { exact: false }).length).toBe(2);
- expect(getAllByText(meetingMessage, { exact: true }).length).toBe(2);
+ it('should display the label for the search input', async () => {
+ const overrides = {
+ componentProperties: {
+ workerCount: 16,
+ },
+ };
+
+ const { fixture, getByText, getByLabelText, getAllWorkersSpy } = await setup(overrides);
+
+ await fixture.whenStable();
+
+ expect(getByText('Search by name or ID number')).toBeTruthy();
+ const searchInput = getByLabelText('Search by name or ID number for staff records');
+ expect(searchInput).toBeTruthy();
+
+ userEvent.type(searchInput, 'search term here{enter}');
+
+ const expectedEmit = { pageIndex: 0, itemsPerPage: 15, sortBy: 'staffNameAsc', searchTerm: 'search term here' };
+ expect(getAllWorkersSpy.calls.mostRecent().args[1]).toEqual(expectedEmit);
+ });
+
+ it('should reset the pageIndex before calling getAllWorkers when handling search', async () => {
+ const overrides = {
+ componentProperties: {
+ workerCount: 16,
+ },
+ };
+
+ const { getAllWorkersSpy, getByLabelText } = await setup(overrides);
+
+ userEvent.type(getByLabelText('Search by name or ID number for staff records'), 'search term here{enter}');
+ expect(getAllWorkersSpy.calls.mostRecent().args[1].pageIndex).toEqual(0);
+ });
});
- it('should display a red cross on staff record when the user has not qualified for WDF overall and 1 staff record is not eligible', async () => {
- const { component, fixture, getByText } = await setup();
- const redCrossVisuallyHiddenMessage = 'Red cross';
- const notMeetingMessage = 'Not meeting';
+ describe('No staff records message', () => {
+ it('should display the message when there are no staff records', async () => {
+ const overrides = {
+ componentProperties: {
+ workers: [],
+ workerCount: 0,
+ },
+ };
+
+ const { getByTestId } = await setup(overrides);
- component.overallWdfEligibility = false;
- component.workers[0].wdfEligible = false;
- component.workers[1].wdfEligible = true;
- component.workers[2].wdfEligible = true;
- fixture.detectChanges();
+ const noRecordsTestId = getByTestId('noRecords');
+
+ const message =
+ 'You need to add some staff records before you can check whether your data meets funding requirements.';
+ expect(noRecordsTestId).toBeTruthy();
+ expect(noRecordsTestId.textContent).toContain(message);
+ });
- expect(getByText(redCrossVisuallyHiddenMessage, { exact: false })).toBeTruthy();
- expect(getByText(notMeetingMessage, { exact: true })).toBeTruthy();
+ it('should navigate to staff records tab when is not parent user viewing sub workplace (no uid in params)', async () => {
+ const overrides = {
+ componentProperties: {
+ workers: [],
+ workerCount: 0,
+ },
+ params: {},
+ };
+
+ const { getByText, routerSpy } = await setup(overrides);
+
+ const staffRecordsLink = getByText('add some staff records');
+ userEvent.click(staffRecordsLink);
+
+ expect(routerSpy).toHaveBeenCalledWith(['dashboard'], { fragment: 'staff-records' });
+ });
+
+ it('should navigate to subsidiary staff records tab when parent user viewing sub workplace (uid in params)', async () => {
+ const workplace = establishmentBuilder();
+ workplace.uid = 'a123koj3213233';
+
+ const overrides = {
+ componentProperties: {
+ workers: [],
+ workerCount: 0,
+ workplace,
+ },
+ params: { establishmentuid: workplace.uid },
+ };
+
+ const { getByText, routerSpy } = await setup(overrides);
+
+ const staffRecordsLink = getByText('add some staff records');
+ userEvent.click(staffRecordsLink);
+
+ expect(routerSpy).toHaveBeenCalledWith(['/subsidiary', workplace.uid, 'staff-records']);
+ });
});
- it('should display two red crosses and one green tick when the user has not qualified for WDF but 1 staff record is eligible and two are not', async () => {
- const { component, fixture, getByText, getAllByText } = await setup();
- const redCrossVisuallyHiddenMessage = 'Red cross';
- const notMeetingMessage = 'Not meeting';
+ describe('Eligibility icons for staff', () => {
+ const redFlagVisuallyHiddenMessage = 'Red flag';
const greenTickVisuallyHiddenMessage = 'Green tick';
+ const orangeFlagVisuallyHiddenMessage = 'Orange warning flag';
+ const newStaffRecordMessage = 'New staff record';
+ const notMeetingMessage = 'Not meeting';
const meetingMessage = 'Meeting';
- component.overallWdfEligibility = false;
- component.workers[0].wdfEligible = false;
- component.workers[1].wdfEligible = true;
- component.workers[2].wdfEligible = false;
- fixture.detectChanges();
+ it('should display green ticks on 3 staff records when the user has qualified for WDF and all staff records are eligible', async () => {
+ const workers = [workerBuilder(), workerBuilder(), workerBuilder()] as Worker[];
+ workers[0].wdfEligible = true;
+ workers[1].wdfEligible = true;
+ workers[2].wdfEligible = true;
+ const overrides = {
+ componentProperties: {
+ workers,
+ overallWdfEligibility: true,
+ },
+ };
+
+ const { getAllByText } = await setup(overrides);
- expect(getAllByText(redCrossVisuallyHiddenMessage, { exact: false }).length).toBe(2);
- expect(getAllByText(notMeetingMessage, { exact: true }).length).toBe(2);
- expect(getByText(greenTickVisuallyHiddenMessage, { exact: false })).toBeTruthy();
- expect(getByText(meetingMessage, { exact: true })).toBeTruthy();
+ expect(getAllByText(greenTickVisuallyHiddenMessage, { exact: false }).length).toBe(3);
+ expect(getAllByText(meetingMessage, { exact: true }).length).toBe(3);
+ });
+
+ it("should display an orange flag and 'New staff record' on staff record when the user has qualified for WDF but 1 staff record is not eligible (new)", async () => {
+ const workers = [workerBuilder(), workerBuilder(), workerBuilder()] as Worker[];
+ workers[0].wdfEligible = false;
+ workers[1].wdfEligible = true;
+ workers[2].wdfEligible = true;
+ const overrides = {
+ componentProperties: { workers, overallWdfEligibility: true },
+ };
+
+ const { getByText } = await setup(overrides);
+
+ expect(getByText(orangeFlagVisuallyHiddenMessage, { exact: false })).toBeTruthy();
+ expect(getByText(newStaffRecordMessage, { exact: true })).toBeTruthy();
+ });
+
+ it('should display one orange flag and two green flags when the user has qualified for WDF but 1 staff record is not eligible and two still are', async () => {
+ const workers = [workerBuilder(), workerBuilder(), workerBuilder()] as Worker[];
+ workers[0].wdfEligible = false;
+ workers[1].wdfEligible = true;
+ workers[2].wdfEligible = true;
+ const overrides = {
+ componentProperties: { workers, overallWdfEligibility: true },
+ };
+
+ const { getByText, getAllByText } = await setup(overrides);
+
+ expect(getByText(orangeFlagVisuallyHiddenMessage, { exact: false })).toBeTruthy();
+ expect(getByText(newStaffRecordMessage, { exact: true })).toBeTruthy();
+ expect(getAllByText(greenTickVisuallyHiddenMessage, { exact: false }).length).toBe(2);
+ expect(getAllByText(meetingMessage, { exact: true }).length).toBe(2);
+ });
+
+ it('should display a red flag on staff record when the user has not qualified for WDF overall and 1 staff record is not eligible', async () => {
+ const workers = [workerBuilder(), workerBuilder(), workerBuilder()] as Worker[];
+ workers[0].wdfEligible = false;
+ workers[1].wdfEligible = true;
+ workers[2].wdfEligible = true;
+ const overrides = {
+ componentProperties: { workers, overallWdfEligibility: false },
+ };
+
+ const { getByText } = await setup(overrides);
+
+ expect(getByText(redFlagVisuallyHiddenMessage, { exact: false })).toBeTruthy();
+ expect(getByText(notMeetingMessage, { exact: true })).toBeTruthy();
+ });
+
+ it('should display two red flags and one green tick when the user has not qualified for WDF but 1 staff record is eligible and two are not', async () => {
+ const workers = [workerBuilder(), workerBuilder(), workerBuilder()] as Worker[];
+ workers[0].wdfEligible = false;
+ workers[1].wdfEligible = true;
+ workers[2].wdfEligible = false;
+ const overrides = {
+ componentProperties: { workers, overallWdfEligibility: false },
+ };
+
+ const { getByText, getAllByText } = await setup(overrides);
+
+ expect(getAllByText(redFlagVisuallyHiddenMessage, { exact: false }).length).toBe(2);
+ expect(getAllByText(notMeetingMessage, { exact: true }).length).toBe(2);
+ expect(getByText(greenTickVisuallyHiddenMessage, { exact: false })).toBeTruthy();
+ expect(getByText(meetingMessage, { exact: true })).toBeTruthy();
+ });
});
});
diff --git a/frontend/src/app/features/wdf/wdf-data-change/wdf-staff-summary/wdf-staff-summary.component.ts b/frontend/src/app/features/wdf/wdf-data-change/wdf-staff-summary/wdf-staff-summary.component.ts
index 7472492636..31159634c3 100644
--- a/frontend/src/app/features/wdf/wdf-data-change/wdf-staff-summary/wdf-staff-summary.component.ts
+++ b/frontend/src/app/features/wdf/wdf-data-change/wdf-staff-summary/wdf-staff-summary.component.ts
@@ -1,47 +1,34 @@
-import { Component, Input, OnChanges, OnInit } from '@angular/core';
-import { ActivatedRoute } from '@angular/router';
-import { Establishment, WdfSortStaffOptions } from '@core/model/establishment.model';
-import { Worker } from '@core/model/worker.model';
+import { Component, Input } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
import { EstablishmentService } from '@core/services/establishment.service';
import { PermissionsService } from '@core/services/permissions/permissions.service';
-import { ReportService } from '@core/services/report.service';
import { TabsService } from '@core/services/tabs.service';
-import dayjs from 'dayjs';
-import orderBy from 'lodash/orderBy';
-import { Subscription } from 'rxjs';
+import { WorkerService } from '@core/services/worker.service';
+import { StaffSummaryDirective } from '@shared/directives/staff-summary/staff-summary.directive';
+import { orderBy } from 'lodash';
@Component({
selector: 'app-wdf-staff-summary',
templateUrl: './wdf-staff-summary.component.html',
})
-export class WdfStaffSummaryComponent implements OnInit, OnChanges {
- @Input() workplace: Establishment;
- @Input() workers: Array
;
- @Input() canEditWorker: boolean;
- @Input() standAloneAccount: boolean;
+export class WdfStaffSummaryComponent extends StaffSummaryDirective {
+ @Input() overallWdfEligibility: boolean;
+
+ public wdfView = true;
public workplaceUid: string;
- public primaryWorkplaceUid: string;
- public canViewWorker: boolean;
- public sortStaffOptions;
- public sortBy: string;
- public overallWdfEligibility: boolean;
- private subscriptions: Subscription = new Subscription();
constructor(
- private permissionsService: PermissionsService,
- private reportService: ReportService,
- private route: ActivatedRoute,
- private establishmentService: EstablishmentService,
- private tabsService: TabsService,
- ) {}
-
- public lastUpdated(timestamp: string): string {
- const lastUpdated = dayjs(timestamp);
- const isToday: boolean = dayjs().isSame(lastUpdated, 'day');
- return isToday ? 'Today' : lastUpdated.format('D MMMM YYYY');
+ protected permissionsService: PermissionsService,
+ protected workerService: WorkerService,
+ protected router: Router,
+ protected route: ActivatedRoute,
+ protected establishmentService: EstablishmentService,
+ protected tabsService: TabsService,
+ ) {
+ super(permissionsService, workerService, router, route, establishmentService, tabsService);
}
- public getWorkerRecordPath(worker: Worker) {
+ public getWorkerRecordPath(worker) {
if (this.route.snapshot.params.establishmentuid) {
this.workplaceUid = this.route.snapshot.params.establishmentuid;
return ['/wdf', 'workplaces', this.workplaceUid, 'staff-record', worker.uid];
@@ -51,10 +38,7 @@ export class WdfStaffSummaryComponent implements OnInit, OnChanges {
}
}
- ngOnInit() {
- this.sortStaffOptions = WdfSortStaffOptions;
- this.getOverallWdfEligibility();
- this.restoreSortBy();
+ protected init() {
this.saveWorkerList();
}
@@ -64,7 +48,7 @@ export class WdfStaffSummaryComponent implements OnInit, OnChanges {
return worker;
});
this.workers = orderBy(this.workers, [(worker) => worker.nameOrId.toLowerCase()], ['asc']);
- this.restoreSortBy();
+
this.saveWorkerList();
}
@@ -73,57 +57,12 @@ export class WdfStaffSummaryComponent implements OnInit, OnChanges {
localStorage.setItem('ListOfWorkers', JSON.stringify(listOfWorkerUids));
}
- public restoreSortBy() {
- this.sortBy = localStorage.getItem('SortBy');
- if (this.sortBy) {
- this.sortByColumn(this.sortBy);
- }
- }
-
- public sortByColumn(selectedColumn: any) {
- localStorage.setItem('SortBy', selectedColumn);
- switch (selectedColumn) {
- case '0_asc': {
- this.workers = orderBy(this.workers, [(worker) => worker.nameOrId.toLowerCase()], ['asc']);
- break;
- }
- case '0_dsc': {
- this.workers = orderBy(this.workers, [(worker) => worker.nameOrId.toLowerCase()], ['desc']);
- break;
- }
- case '1_asc': {
- this.workers = orderBy(this.workers, [(worker) => worker.jobRole.toLowerCase()], ['asc']);
- break;
- }
- case '1_dsc': {
- this.workers = orderBy(this.workers, [(worker) => worker.jobRole.toLowerCase()], ['desc']);
- break;
- }
- case '2_meeting': {
- this.workers = orderBy(this.workers, [(worker) => worker.wdfEligible], ['desc']);
- break;
- }
- case '2_not_meeting': {
- this.workers = orderBy(this.workers, [(worker) => worker.wdfEligible], ['asc']);
- break;
- }
- default: {
- this.workers = orderBy(this.workers, [(worker) => worker.nameOrId.toLowerCase()], ['asc']);
- break;
- }
- }
- this.saveWorkerList();
- }
-
- private getOverallWdfEligibility() {
- this.subscriptions.add(
- this.reportService.getWDFReport(this.workplace.uid).subscribe((report) => {
- this.overallWdfEligibility = report.wdf.overall;
- }),
- );
- }
public navigateToStaffRecords(event: Event): void {
event.preventDefault();
- this.tabsService.selectedTab = 'staff-records';
+ if (this.route.snapshot.params.establishmentuid) {
+ this.router.navigate(['/subsidiary', this.workplace.uid, 'staff-records']);
+ } else {
+ this.router.navigate(['dashboard'], { fragment: 'staff-records' });
+ }
}
}
diff --git a/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary-table/wdf-workplaces-summary-table.component.html b/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary-table/wdf-workplaces-summary-table.component.html
deleted file mode 100644
index ac42f39370..0000000000
--- a/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary-table/wdf-workplaces-summary-table.component.html
+++ /dev/null
@@ -1,48 +0,0 @@
-
- Sort by
-
-
- {{ sortWorkplaceOption.value }}
-
-
-
-
-
diff --git a/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary-table/wdf-workplaces-summary-table.component.spec.ts b/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary-table/wdf-workplaces-summary-table.component.spec.ts
deleted file mode 100644
index 6349692129..0000000000
--- a/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary-table/wdf-workplaces-summary-table.component.spec.ts
+++ /dev/null
@@ -1,199 +0,0 @@
-import { HttpClientTestingModule } from '@angular/common/http/testing';
-import { BrowserModule } from '@angular/platform-browser';
-import { RouterTestingModule } from '@angular/router/testing';
-import { DataPermissions, WorkplaceDataOwner } from '@core/model/my-workplaces.model';
-import { SharedModule } from '@shared/shared.module';
-import { render } from '@testing-library/angular';
-
-import { WdfModule } from '../wdf.module';
-import { WdfWorkplacesSummaryTableComponent } from './wdf-workplaces-summary-table.component';
-
-describe('WdfWorkplacesSummaryTableComponent', () => {
- const workplaces = [
- {
- name: 'Workplace name',
- wdf: {
- overall: true,
- staff: true,
- workplace: true,
- },
- },
- {
- name: 'Workplace name 2',
- wdf: {
- overall: true,
- staff: true,
- workplace: true,
- },
- },
- ];
-
- const setup = async () => {
- const { fixture, getByText, getAllByText, getByTestId, queryByText } = await render(
- WdfWorkplacesSummaryTableComponent,
- {
- imports: [RouterTestingModule, HttpClientTestingModule, BrowserModule, SharedModule, WdfModule],
- providers: [],
- componentProperties: {
- workplaces: workplaces,
- },
- },
- );
- const component = fixture.componentInstance;
-
- return { component, fixture, getByText, getAllByText, getByTestId, queryByText };
- };
-
- it('should render a WdfWorkplacesSummaryTableComponent', async () => {
- const { component } = await setup();
- expect(component).toBeTruthy();
- });
-
- it('should display two green ticks for each workplace when the workplace has qualified for WDF and the workplace and staff records are eligible', async () => {
- const { component, fixture, getAllByText } = await setup();
- const greenTickVisuallyHiddenMessage = 'Green tick';
- const meetingMessage = 'Meeting';
-
- component.workplaces[0].wdf.overall = true;
- component.workplaces[0].wdf.workplace = true;
- component.workplaces[0].wdf.staff = true;
-
- component.workplaces[1].wdf.overall = true;
- component.workplaces[1].wdf.workplace = true;
- component.workplaces[1].wdf.staff = true;
- fixture.detectChanges();
-
- expect(getAllByText(greenTickVisuallyHiddenMessage, { exact: false }).length).toBe(4);
- expect(getAllByText(meetingMessage, { exact: true }).length).toBe(4);
- });
- it('should not display a link for workplaces without rights', async () => {
- const { component, fixture, getAllByText } = await setup();
- component.workplaces[0].isParent = false;
- component.workplaces[0].dataOwner = WorkplaceDataOwner.Workplace;
- component.workplaces[0].dataPermissions = DataPermissions.None;
- component.workplaces[0].name = 'Test Workplace';
-
- fixture.detectChanges();
- expect(getAllByText('Test Workplace', { exact: false })[0].outerHTML).toContain('');
- });
- it('should display a link for workplaces with rights to at least workplace', async () => {
- const { component, fixture, getAllByText } = await setup();
-
- component.workplaces[0].dataOwner = WorkplaceDataOwner.Workplace;
- component.workplaces[0].dataPermissions = DataPermissions.Workplace;
- component.workplaces[0].name = 'Test Workplace';
-
- fixture.detectChanges();
- expect(getAllByText('Test Workplace', { exact: false })[0].outerHTML).toContain('');
- });
- it('should display a link for workplaces if parent', async () => {
- const { component, fixture, getAllByText } = await setup();
-
- component.workplaces[0].dataOwner = WorkplaceDataOwner.Workplace;
- component.workplaces[0].dataPermissions = DataPermissions.None;
- component.workplaces[0].isParent = true;
- component.workplaces[0].name = 'Test Workplace';
-
- fixture.detectChanges();
- expect(getAllByText('Test Workplace', { exact: false })[0].outerHTML).toContain('');
- });
- it('canViewWorkplace should return true if parent', async () => {
- const { component } = await setup();
-
- const workplace = component.workplaces[0];
- workplace.isParent = true;
-
- const canViewWorkplace = component.canViewWorkplace(workplace);
- expect(canViewWorkplace).toBeTruthy(true);
- });
-
- describe('sortByColumn', async () => {
- it('should put workplaces not meeting WDF at top of table when sorting by WDF requirements (not meeting)', async () => {
- const { component, fixture } = await setup();
-
- component.workplaces[0].wdf.overall = true;
- component.workplaces[0].wdf.workplace = true;
- component.workplaces[0].wdf.staff = true;
-
- component.workplaces[1].wdf.overall = false;
- component.workplaces[1].wdf.workplace = false;
- component.workplaces[1].wdf.staff = false;
-
- fixture.componentInstance.sortByColumn('1_not_meeting');
- const workplaces = component.workplaces;
- fixture.detectChanges();
-
- expect(workplaces[0].wdf.overall).toEqual(false);
- expect(workplaces[1].wdf.overall).toEqual(true);
- });
-
- it('should put workplaces not meeting WDF for either workplace or staff record at top of table when sorting by WDF requirements (not meeting)', async () => {
- const { component, fixture } = await setup();
-
- component.workplaces[0].wdf.overall = true;
- component.workplaces[0].wdf.workplace = false;
- component.workplaces[0].wdf.staff = true;
-
- component.workplaces[1].wdf.overall = true;
- component.workplaces[1].wdf.workplace = false;
- component.workplaces[1].wdf.staff = false;
-
- fixture.componentInstance.sortByColumn('1_not_meeting');
- const workplaces = component.workplaces;
- fixture.detectChanges();
-
- expect(workplaces[0].wdf.workplace).toEqual(false);
- expect(workplaces[0].wdf.staff).toEqual(false);
- expect(workplaces[1].wdf.workplace).toEqual(false);
- expect(workplaces[1].wdf.staff).toEqual(true);
- });
-
- it('should put workplaces not meeting WDF (red crosses) before those meeting with changes (orange flags) when sorting by WDF requirements (not meeting)', async () => {
- const { component, fixture } = await setup();
-
- component.workplaces[0].wdf.overall = false;
- component.workplaces[0].wdf.workplace = true;
- component.workplaces[0].wdf.staff = false;
-
- component.workplaces[1].wdf.overall = true;
- component.workplaces[1].wdf.workplace = false;
- component.workplaces[1].wdf.staff = true;
-
- fixture.componentInstance.sortByColumn('1_not_meeting');
- const workplaces = component.workplaces;
- fixture.detectChanges();
-
- expect(workplaces[0].wdf.overall).toEqual(false);
- expect(workplaces[0].wdf.workplace).toEqual(true);
- expect(workplaces[0].wdf.staff).toEqual(false);
-
- expect(workplaces[1].wdf.overall).toEqual(true);
- expect(workplaces[1].wdf.workplace).toEqual(false);
- expect(workplaces[1].wdf.staff).toEqual(true);
- });
-
- it('should put workplaces meeting WDF with changes (orange flags) before those not meeting (red crosses) when sorting by WDF requirements (meeting)', async () => {
- const { component, fixture } = await setup();
-
- component.workplaces[0].wdf.overall = false;
- component.workplaces[0].wdf.workplace = false;
- component.workplaces[0].wdf.staff = false;
-
- component.workplaces[1].wdf.overall = true;
- component.workplaces[1].wdf.workplace = false;
- component.workplaces[1].wdf.staff = true;
-
- fixture.componentInstance.sortByColumn('2_meeting');
- const workplaces = component.workplaces;
- fixture.detectChanges();
-
- expect(workplaces[0].wdf.overall).toEqual(true);
- expect(workplaces[0].wdf.workplace).toEqual(false);
- expect(workplaces[0].wdf.staff).toEqual(true);
-
- expect(workplaces[1].wdf.overall).toEqual(false);
- expect(workplaces[1].wdf.workplace).toEqual(false);
- expect(workplaces[1].wdf.staff).toEqual(false);
- });
- });
-});
diff --git a/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary-table/wdf-workplaces-summary-table.component.ts b/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary-table/wdf-workplaces-summary-table.component.ts
deleted file mode 100644
index 3f0b6e1214..0000000000
--- a/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary-table/wdf-workplaces-summary-table.component.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import { Component, Input, OnInit } from '@angular/core';
-import { WdfParentSortWorkplacesOptions } from '@core/model/establishment.model';
-import { DataPermissions, WorkplaceDataOwner } from '@core/model/my-workplaces.model';
-import { PermissionsService } from '@core/services/permissions/permissions.service';
-import orderBy from 'lodash/orderBy';
-
-@Component({
- selector: 'app-wdf-workplaces-summary-table',
- templateUrl: './wdf-workplaces-summary-table.component.html',
-})
-export class WdfWorkplacesSummaryTableComponent implements OnInit {
- @Input() public workplaces = [];
- public sortWorkplacesOptions;
- public sortBy: string;
- constructor(private permissionsService: PermissionsService) {}
-
- ngOnInit(): void {
- this.sortWorkplacesOptions = WdfParentSortWorkplacesOptions;
- }
-
- ngOnChanges() {
- this.sortByColumn('1_not_meeting');
- }
-
- public sortByColumn(selectedColumn: any) {
- switch (selectedColumn) {
- case '1_not_meeting': {
- this.workplaces = this.orderWorkplaces('asc');
- break;
- }
- case '2_meeting': {
- this.workplaces = this.orderWorkplaces('desc');
- break;
- }
- case '3_asc': {
- this.workplaces = orderBy(this.workplaces, [(workplace) => workplace.name.toLowerCase()], ['asc']);
- break;
- }
- case '4_dsc': {
- this.workplaces = orderBy(this.workplaces, [(workplace) => workplace.name.toLowerCase()], ['desc']);
- break;
- }
- default: {
- this.workplaces = this.workplaces = this.orderWorkplaces('asc');
- break;
- }
- }
- }
-
- public canViewWorkplace(workplace) {
- if (workplace.isParent === true) {
- return true;
- }
- return !(
- workplace.dataOwner === WorkplaceDataOwner.Workplace && workplace.dataPermissions === DataPermissions.None
- );
- }
-
- private orderWorkplaces(order: boolean | 'asc' | 'desc'): Array {
- return orderBy(
- this.workplaces,
- [
- (workplace) => workplace.wdf.overall,
- (workplace) => workplace.wdf.workplace,
- (workplace) => workplace.wdf.staff,
- ],
- [order, order, order],
- );
- }
-}
diff --git a/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary/wdf-workplaces-summary.component.html b/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary/wdf-workplaces-summary.component.html
index 975433193a..cb90f19209 100644
--- a/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary/wdf-workplaces-summary.component.html
+++ b/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary/wdf-workplaces-summary.component.html
@@ -1,27 +1,63 @@
-
-
- Workforce Development Fund (WDF)
- Workplaces
-
+
-
+
+
+ Sort by
+
+
+ {{ sortWorkplaceOption.value }}
+
+
+
-
-
-
+
diff --git a/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary/wdf-workplaces-summary.component.spec.ts b/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary/wdf-workplaces-summary.component.spec.ts
index ba624b7a9f..502452ccca 100644
--- a/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary/wdf-workplaces-summary.component.spec.ts
+++ b/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary/wdf-workplaces-summary.component.spec.ts
@@ -4,6 +4,7 @@ import { TestBed } from '@angular/core/testing';
import { BrowserModule } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
+import { DataPermissions, WorkplaceDataOwner } from '@core/model/my-workplaces.model';
import { BreadcrumbService } from '@core/services/breadcrumb.service';
import { EstablishmentService } from '@core/services/establishment.service';
import { PermissionsService } from '@core/services/permissions/permissions.service';
@@ -22,8 +23,39 @@ import { WdfModule } from '../wdf.module';
import { WdfWorkplacesSummaryComponent } from './wdf-workplaces-summary.component';
describe('WdfWorkplacesSummaryComponent', () => {
- const setup = async (viewPermission?) => {
- const { fixture, getByText, getAllByText, getByTestId, queryByText } = await render(WdfWorkplacesSummaryComponent, {
+ const mockWorkplaces = (): any[] => [
+ {
+ name: 'Workplace name',
+ wdf: {
+ overall: true,
+ staff: true,
+ workplace: true,
+ },
+ },
+ {
+ name: 'Workplace name 2',
+ wdf: {
+ overall: true,
+ staff: true,
+ workplace: true,
+ },
+ },
+ ];
+
+ const overallEligible = {
+ overall: true,
+ staff: true,
+ workplace: true,
+ };
+
+ const allIneligible = {
+ overall: false,
+ staff: false,
+ workplace: false,
+ };
+
+ const setup = async (overrides: any = {}) => {
+ const setupTools = await render(WdfWorkplacesSummaryComponent, {
imports: [RouterTestingModule, HttpClientTestingModule, BrowserModule, SharedModule, WdfModule],
providers: [
{ provide: BreadcrumbService, useClass: MockBreadcrumbService },
@@ -32,16 +64,20 @@ describe('WdfWorkplacesSummaryComponent', () => {
{ provide: UserService, useClass: MockUserService },
{
provide: PermissionsService,
- useFactory: viewPermission
+ useFactory: overrides.viewPermission
? MockPermissionsService.factory(['canViewEstablishment'])
: MockPermissionsService.factory(['canEditEstablishment']),
deps: [HttpClient, Router, UserService],
},
],
+ componentProperties: {
+ workplaces: mockWorkplaces(),
+ ...overrides,
+ },
});
- const component = fixture.componentInstance;
+ const component = setupTools.fixture.componentInstance;
- return { component, fixture, getByText, getAllByText, getByTestId, queryByText };
+ return { ...setupTools, component };
};
it('should render a WdfWorkplacesSummaryComponent', async () => {
@@ -49,82 +85,242 @@ describe('WdfWorkplacesSummaryComponent', () => {
expect(component).toBeTruthy();
});
- it('should show the download a WDF report when the user has edit permissions', async () => {
+ it('should show the download your funding report link when user has edit permissions', async () => {
const { getByText } = await setup();
- expect(getByText('Download your WDF report (Excel)', { exact: false })).toBeTruthy();
+ expect(getByText('Download your funding report (Excel)', { exact: false })).toBeTruthy();
});
- it('should not show the download a WDF report when the user has view permissions', async () => {
- const { queryByText } = await setup(true);
- expect(queryByText('Download your WDF report (Excel)', { exact: false })).toBeFalsy();
+ it('should not show the download your funding report link when user only has view permissions', async () => {
+ const { queryByText } = await setup({ viewPermission: true });
+ expect(queryByText('Download your funding report (Excel)', { exact: false })).toBeFalsy();
});
- it('should download a WDF report when the download link is clicked', async () => {
+ it('should download the funding report when the download link is clicked', async () => {
const { fixture, getByText } = await setup();
const reportService = TestBed.inject(ReportService);
const getReport = spyOn(reportService, 'getParentWDFReport').and.callFake(() => of(null));
const saveAs = spyOn(fixture.componentInstance, 'saveFile').and.callFake(() => {}); // eslint-disable-line @typescript-eslint/no-empty-function
- fireEvent.click(getByText('Download your WDF report (Excel)', { exact: false }));
+ fireEvent.click(getByText('Download your funding report (Excel)', { exact: false }));
expect(getReport).toHaveBeenCalled();
expect(saveAs).toHaveBeenCalled();
});
- describe('WdfParentStatusMessageComponent', async () => {
- it('should display the correct message and timeframe if meeting WDF requirements', async () => {
- const { component, fixture, getByText } = await setup();
- const year = new Date().getFullYear();
- const timeFrameSentence = `All your workplaces' data meets the WDF ${year} to ${year + 1} requirements`;
+ describe('Table', () => {
+ describe('eligibility messages', () => {
+ const greenTickVisuallyHiddenMessage = 'Green tick';
+ const meetingMessage = 'Meeting';
+ const redFlagVisuallyHiddenMessage = 'Red flag';
+ const notMeetingMessage = 'Not meeting';
+ const orangeFlagVisuallyHiddenMessage = 'Orange warning flag';
+
+ it('should display two green ticks for each workplace when the workplace has qualified for funding and the workplace and staff records are eligible', async () => {
+ const workplaces = mockWorkplaces();
+ workplaces[0].wdf = overallEligible;
+ workplaces[1].wdf = overallEligible;
+
+ const { getAllByText } = await setup({ workplaces });
+
+ expect(getAllByText(greenTickVisuallyHiddenMessage, { exact: false }).length).toBe(4);
+ expect(getAllByText(meetingMessage, { exact: true }).length).toBe(4);
+ });
+
+ it('should display two red flags for workplace when the workplace has not qualified for funding and the workplace and staff records are ineligible', async () => {
+ const workplaces = [
+ {
+ name: 'Workplace name',
+ wdf: allIneligible,
+ },
+ ];
+
+ const { getAllByText } = await setup({ workplaces });
+
+ expect(getAllByText(redFlagVisuallyHiddenMessage, { exact: false }).length).toBe(2);
+ expect(getAllByText(notMeetingMessage, { exact: true }).length).toBe(2);
+ });
- component.parentOverallEligibilityStatus = true;
- component.parentCurrentEligibilityStatus = true;
- fixture.detectChanges();
+ it('should display one red flag and one green for workplace when the workplace has not qualified for funding, workplace is eligible but staff records are ineligible', async () => {
+ const workplaces = [
+ {
+ name: 'Workplace name',
+ wdf: {
+ overall: false,
+ staff: false,
+ workplace: true,
+ },
+ },
+ ];
- expect(getByText(timeFrameSentence, { exact: false })).toBeTruthy();
+ const { getByText } = await setup({ workplaces });
+
+ expect(getByText(redFlagVisuallyHiddenMessage, { exact: false })).toBeTruthy();
+ expect(getByText(notMeetingMessage, { exact: true })).toBeTruthy();
+ expect(getByText(greenTickVisuallyHiddenMessage, { exact: false })).toBeTruthy();
+ expect(getByText(meetingMessage, { exact: true })).toBeTruthy();
+ });
+
+ it('should display one red flag and one green for workplace when the workplace has not qualified for funding, staff records are eligible but workplace is ineligible', async () => {
+ const workplaces = [
+ {
+ name: 'Workplace name',
+ wdf: {
+ overall: false,
+ staff: true,
+ workplace: false,
+ },
+ },
+ ];
+
+ const { getByText } = await setup({ workplaces });
+
+ expect(getByText(redFlagVisuallyHiddenMessage, { exact: false })).toBeTruthy();
+ expect(getByText(notMeetingMessage, { exact: true })).toBeTruthy();
+ expect(getByText(greenTickVisuallyHiddenMessage, { exact: false })).toBeTruthy();
+ expect(getByText(meetingMessage, { exact: true })).toBeTruthy();
+ });
+
+ it("should display orange flag and 'Check your workplace data' message when the workplace has qualified for funding but workplace is ineligible", async () => {
+ const workplaces = [
+ {
+ name: 'Workplace name',
+ wdf: {
+ overall: true,
+ staff: true,
+ workplace: false,
+ },
+ },
+ ];
+
+ const { getByText } = await setup({ workplaces });
+
+ expect(getByText(orangeFlagVisuallyHiddenMessage, { exact: false })).toBeTruthy();
+ expect(getByText('Check your workplace data', { exact: true })).toBeTruthy();
+ });
+
+ it("should display orange flag and 'New staff records' message when the workplace has qualified for funding but staff records are ineligible", async () => {
+ const workplaces = [
+ {
+ name: 'Workplace name',
+ wdf: {
+ overall: true,
+ staff: false,
+ workplace: true,
+ },
+ },
+ ];
+
+ const { getByText } = await setup({ workplaces });
+
+ expect(getByText(orangeFlagVisuallyHiddenMessage, { exact: false })).toBeTruthy();
+ expect(getByText('New staff records', { exact: true })).toBeTruthy();
+ });
});
- it('should display the correct message if workplaces have met WDF requirements this year but not meeting currently', async () => {
- const { component, fixture, getByText } = await setup();
- const year = new Date().getFullYear();
- const timeFrameSentence = `Your workplaces met the WDF ${year} to ${
- year + 1
- } requirements, but updating those currently shown as 'not meeting' will save you time next year.`;
+ it('should not display a link for workplaces without rights', async () => {
+ const workplaces = mockWorkplaces();
+ workplaces[0].isParent = false;
+ workplaces[0].dataOwner = WorkplaceDataOwner.Workplace;
+ workplaces[0].dataPermissions = DataPermissions.None;
+ workplaces[0].name = 'Test Workplace';
- component.parentOverallEligibilityStatus = true;
- component.parentCurrentEligibilityStatus = false;
- fixture.detectChanges();
+ const { getAllByText } = await setup({ workplaces });
- expect(getByText(timeFrameSentence, { exact: false })).toBeTruthy();
+ expect(getAllByText('Test Workplace', { exact: false })[0].outerHTML).toContain('
');
});
- it('should display the correct message if workplaces have not met WDF requirements this year', async () => {
- const { component, fixture, getByText } = await setup();
- const year = new Date().getFullYear();
- const timeFrameSentence = `Some of your workplaces' data does not meet the WDF ${year} to ${
- year + 1
- } requirements`;
+ it('should display a link for workplaces with rights to at least workplace', async () => {
+ const workplaces = mockWorkplaces();
+ workplaces[0].dataPermissions = DataPermissions.Workplace;
+ workplaces[0].name = 'Test Workplace';
+ workplaces[0].dataOwner = WorkplaceDataOwner.Workplace;
- component.parentOverallEligibilityStatus = false;
- component.parentCurrentEligibilityStatus = false;
- fixture.detectChanges();
+ const { getAllByText } = await setup({ workplaces });
- expect(getByText(timeFrameSentence, { exact: false })).toBeTruthy();
+ expect(getAllByText('Test Workplace', { exact: false })[0].outerHTML).toContain('');
});
- });
- describe('workplace rendering', async () => {
- it('Should not display a sub workplace with a ustatus of PENDING or IN PROGRESS', async () => {
- const { fixture } = await setup();
- const wdfWorkplaceTableRows = fixture.nativeElement.querySelectorAll('tr');
- const rowOne = wdfWorkplaceTableRows[1];
-
- //One array location as headings, another as the primary workplace and the final as the only valid sub account
- expect(wdfWorkplaceTableRows.length).toEqual(3);
- expect(rowOne.cells['0'].innerHTML).toContain('First Subsid Workplace');
- expect(rowOne.cells['1'].innerHTML).toContain('Not meeting');
- expect(rowOne.cells['2'].innerHTML).toContain('Not meeting');
+ describe('sortByColumn', async () => {
+ it('should put workplaces not meeting WDF at top of table when sorting by WDF requirements (not meeting)', async () => {
+ const workplaces = mockWorkplaces();
+ workplaces[0].wdf = overallEligible;
+ workplaces[1].wdf = allIneligible;
+
+ const { component, fixture } = await setup({ workplaces });
+
+ fixture.componentInstance.sortByColumn('1_not_meeting');
+
+ const sortedWorkplaces = component.workplaces;
+
+ expect(sortedWorkplaces[0].wdf.overall).toEqual(false);
+ expect(sortedWorkplaces[1].wdf.overall).toEqual(true);
+ });
+
+ it('should put workplaces not meeting for either workplace or staff record at top of table when sorting by funding requirements (not meeting)', async () => {
+ const workplaces = mockWorkplaces();
+ workplaces[0].wdf.overall = false;
+ workplaces[0].wdf.workplace = false;
+ workplaces[0].wdf.staff = true;
+
+ workplaces[1].wdf = allIneligible;
+
+ const { component, fixture } = await setup({ workplaces });
+
+ fixture.componentInstance.sortByColumn('1_not_meeting');
+ const sortedWorkplaces = component.workplaces;
+
+ expect(sortedWorkplaces[0].wdf.workplace).toEqual(false);
+ expect(sortedWorkplaces[0].wdf.staff).toEqual(false);
+ expect(sortedWorkplaces[1].wdf.workplace).toEqual(false);
+ expect(sortedWorkplaces[1].wdf.staff).toEqual(true);
+ });
+
+ it('should put workplaces not meeting (red flag) before those meeting with changes (orange flags) when sorting by funding requirements (not meeting)', async () => {
+ const workplaces = mockWorkplaces();
+ workplaces[0].wdf.overall = false;
+ workplaces[0].wdf.workplace = true;
+ workplaces[0].wdf.staff = false;
+
+ workplaces[1].wdf.overall = true;
+ workplaces[1].wdf.workplace = true;
+ workplaces[1].wdf.staff = false;
+
+ const { component, fixture } = await setup({ workplaces });
+
+ fixture.componentInstance.sortByColumn('1_not_meeting');
+ const sortedWorkplaces = component.workplaces;
+
+ expect(sortedWorkplaces[0].wdf.overall).toEqual(false);
+ expect(sortedWorkplaces[0].wdf.workplace).toEqual(true);
+ expect(sortedWorkplaces[0].wdf.staff).toEqual(false);
+
+ expect(sortedWorkplaces[1].wdf.overall).toEqual(true);
+ expect(sortedWorkplaces[1].wdf.workplace).toEqual(true);
+ expect(sortedWorkplaces[1].wdf.staff).toEqual(false);
+ });
+
+ it('should put workplaces meeting WDF with changes (orange flags) before those not meeting (red crosses) when sorting by WDF requirements (meeting)', async () => {
+ const workplaces = mockWorkplaces();
+ workplaces[0].wdf = allIneligible;
+
+ workplaces[1].wdf.overall = true;
+ workplaces[1].wdf.workplace = false;
+ workplaces[1].wdf.staff = true;
+
+ const { component, fixture } = await setup({ workplaces });
+
+ fixture.componentInstance.sortByColumn('2_meeting');
+ const sortedWorkplaces = component.workplaces;
+
+ expect(sortedWorkplaces[0].wdf.overall).toEqual(true);
+ expect(sortedWorkplaces[0].wdf.workplace).toEqual(false);
+ expect(sortedWorkplaces[0].wdf.staff).toEqual(true);
+
+ expect(sortedWorkplaces[1].wdf.overall).toEqual(false);
+ expect(sortedWorkplaces[1].wdf.workplace).toEqual(false);
+ expect(sortedWorkplaces[1].wdf.staff).toEqual(false);
+ });
});
});
});
diff --git a/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary/wdf-workplaces-summary.component.ts b/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary/wdf-workplaces-summary.component.ts
index fa1fa0d727..42df012e77 100644
--- a/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary/wdf-workplaces-summary.component.ts
+++ b/frontend/src/app/features/wdf/wdf-data-change/wdf-workplaces-summary/wdf-workplaces-summary.component.ts
@@ -1,15 +1,10 @@
import { HttpResponse } from '@angular/common/http';
-import { Component, OnInit } from '@angular/core';
-import { JourneyType } from '@core/breadcrumb/breadcrumb.model';
-import { GetWorkplacesResponse } from '@core/model/my-workplaces.model';
-import { WDFReport } from '@core/model/reports.model';
-import { URLStructure } from '@core/model/url.model';
-import { BreadcrumbService } from '@core/services/breadcrumb.service';
+import { Component, Input, OnDestroy, OnInit } from '@angular/core';
+import { FundingParentSortWorkplacesOptions } from '@core/model/establishment.model';
+import { DataPermissions, WorkplaceDataOwner } from '@core/model/my-workplaces.model';
import { EstablishmentService } from '@core/services/establishment.service';
import { PermissionsService } from '@core/services/permissions/permissions.service';
import { ReportService } from '@core/services/report.service';
-import { UserService } from '@core/services/user.service';
-import dayjs from 'dayjs';
import saveAs from 'file-saver';
import orderBy from 'lodash/orderBy';
import { Subscription } from 'rxjs';
@@ -18,74 +13,22 @@ import { Subscription } from 'rxjs';
selector: 'app-wdf-workplaces-summary',
templateUrl: './wdf-workplaces-summary.component.html',
})
-export class WdfWorkplacesSummaryComponent implements OnInit {
- public workplaces = [];
+export class WdfWorkplacesSummaryComponent implements OnInit, OnDestroy {
+ @Input() workplaces = [];
public workplaceUid: string;
- public wdfStartDate: string;
- public wdfEndDate: string;
- public returnUrl: URLStructure;
- public report: WDFReport;
- public parentOverallEligibilityStatus: boolean;
- public parentCurrentEligibilityStatus: boolean;
- public parentOverallEligibilityDate: string;
- public now: Date = new Date();
private subscriptions: Subscription = new Subscription();
public canDownloadReport: boolean;
+ public sortWorkplacesOptions = FundingParentSortWorkplacesOptions;
constructor(
private establishmentService: EstablishmentService,
private reportService: ReportService,
- private breadcrumbService: BreadcrumbService,
- private userService: UserService,
private permissionsService: PermissionsService,
) {}
ngOnInit(): void {
- this.breadcrumbService.show(JourneyType.WDF_PARENT);
- this.returnUrl = { url: ['/wdf', 'workplaces'] };
-
this.workplaceUid = this.establishmentService.primaryWorkplace.uid;
this.canDownloadReport = this.permissionsService.can(this.workplaceUid, 'canEditEstablishment');
- this.getParentAndSubs();
- this.getWdfReport();
- }
-
- private getParentAndSubs(): void {
- this.subscriptions.add(
- this.userService.getEstablishments(true).subscribe((workplaces: GetWorkplacesResponse) => {
- if (workplaces.subsidaries) {
- this.workplaces = workplaces.subsidaries.establishments.filter(
- (item) => item.ustatus !== 'PENDING' && item.ustatus !== 'IN PROGRESS',
- );
- }
- this.workplaces.push(workplaces.primary);
- this.workplaces = orderBy(this.workplaces, ['wdf.overall', 'updated'], ['asc', 'desc']);
- this.getParentWdfEligibility();
- }),
- );
- }
-
- private getParentWdfEligibility(): void {
- this.parentOverallEligibilityStatus = !this.workplaces.some((workplace) => {
- return workplace.wdf.overall === false;
- });
- this.parentCurrentEligibilityStatus = !this.workplaces.some((workplace) => {
- return workplace.wdf.workplace === false || workplace.wdf.staff === false;
- });
- }
-
- private getWdfReport() {
- this.subscriptions.add(
- this.reportService.getWDFReport(this.workplaceUid).subscribe((report) => {
- this.report = report;
- this.setDates(report);
- }),
- );
- }
-
- private setDates(report: WDFReport): void {
- this.wdfStartDate = dayjs(report.effectiveFrom).format('D MMMM YYYY');
- this.wdfEndDate = dayjs(report.effectiveFrom).add(1, 'years').format('D MMMM YYYY');
}
public downloadWdfParentReport(event: Event) {
@@ -106,4 +49,58 @@ export class WdfWorkplacesSummaryComponent implements OnInit {
const blob = new Blob([response.body], { type: 'text/plain;charset=utf-8' });
saveAs(blob, filename);
}
+
+ ngOnChanges() {
+ this.sortByColumn('1_not_meeting');
+ }
+
+ public sortByColumn(selectedColumn: any) {
+ switch (selectedColumn) {
+ case '1_not_meeting': {
+ this.workplaces = this.orderWorkplaces('asc');
+ break;
+ }
+ case '2_meeting': {
+ this.workplaces = this.orderWorkplaces('desc');
+ break;
+ }
+ case '3_asc': {
+ this.workplaces = orderBy(this.workplaces, [(workplace) => workplace.name.toLowerCase()], ['asc']);
+ break;
+ }
+ case '4_dsc': {
+ this.workplaces = orderBy(this.workplaces, [(workplace) => workplace.name.toLowerCase()], ['desc']);
+ break;
+ }
+ default: {
+ this.workplaces = this.workplaces = this.orderWorkplaces('asc');
+ break;
+ }
+ }
+ }
+
+ public canViewWorkplace(workplace) {
+ if (workplace.isParent === true) {
+ return true;
+ }
+ return !(
+ workplace.dataOwner === WorkplaceDataOwner.Workplace && workplace.dataPermissions === DataPermissions.None
+ );
+ }
+
+ private orderWorkplaces(order: boolean | 'asc' | 'desc'): Array {
+ return orderBy(
+ this.workplaces,
+ [
+ (workplace) => workplace.wdf.overall,
+ (workplace) => workplace.wdf.workplace,
+ (workplace) => workplace.wdf.staff,
+ ],
+ [order, order, order],
+ );
+ }
+
+ ngOnDestroy(): void {
+ this.subscriptions.unsubscribe();
+ }
}
diff --git a/frontend/src/app/features/wdf/wdf-data-change/wdf.module.ts b/frontend/src/app/features/wdf/wdf-data-change/wdf.module.ts
index 5481ce9af2..6b7eff84b5 100644
--- a/frontend/src/app/features/wdf/wdf-data-change/wdf.module.ts
+++ b/frontend/src/app/features/wdf/wdf-data-change/wdf.module.ts
@@ -2,23 +2,23 @@ import { OverlayModule } from '@angular/cdk/overlay';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
+import { JobsResolver } from '@core/resolvers/jobs.resolver';
import { WorkerResolver } from '@core/resolvers/worker.resolver';
import { WorkplaceResolver } from '@core/resolvers/workplace.resolver';
import { SharedModule } from '@shared/shared.module';
+import { FundingRequirementsComponent } from './funding-requirements/funding-requirements.component';
+import { LearnMoreAboutFundingComponent } from './learn-more-about-funding/learn-more-about-funding.component';
import { WdfDataStatusMessageComponent } from './wdf-data-status-message/wdf-data-status-message.component';
import { WdfDataComponent } from './wdf-data/wdf-data.component';
import { WdfOverviewComponent } from './wdf-overview/wdf-overview.component';
import { WdfParentStatusMessageComponent } from './wdf-parent-status-message/wdf-parent-status-message.component';
-import { WdfRequirementsStateComponent } from './wdf-requirements-state/wdf-requirements-state.component';
import { WdfRoutingModule } from './wdf-routing.module';
import { WdfStaffRecordStatusMessageComponent } from './wdf-staff-record-status-message/wdf-staff-record-status-message.component';
import { WdfPaginationComponent } from './wdf-staff-record/wdf-pagination/wdf-pagination.component';
import { WdfStaffRecordComponent } from './wdf-staff-record/wdf-staff-record.component';
import { WdfStaffSummaryComponent } from './wdf-staff-summary/wdf-staff-summary.component';
-import { WdfWorkplacesSummaryTableComponent } from './wdf-workplaces-summary-table/wdf-workplaces-summary-table.component';
import { WdfWorkplacesSummaryComponent } from './wdf-workplaces-summary/wdf-workplaces-summary.component';
-import { JobsResolver } from '@core/resolvers/jobs.resolver';
@NgModule({
imports: [CommonModule, ReactiveFormsModule, SharedModule, OverlayModule, WdfRoutingModule],
@@ -26,14 +26,14 @@ import { JobsResolver } from '@core/resolvers/jobs.resolver';
WdfDataComponent,
WdfStaffSummaryComponent,
WdfStaffRecordComponent,
- WdfRequirementsStateComponent,
WdfDataStatusMessageComponent,
WdfStaffRecordStatusMessageComponent,
WdfPaginationComponent,
WdfWorkplacesSummaryComponent,
- WdfWorkplacesSummaryTableComponent,
WdfParentStatusMessageComponent,
WdfOverviewComponent,
+ FundingRequirementsComponent,
+ LearnMoreAboutFundingComponent,
],
providers: [WorkerResolver, WorkplaceResolver, JobsResolver],
})
diff --git a/frontend/src/app/shared/components/funding-requirements-state/funding-requirements-state.component.html b/frontend/src/app/shared/components/funding-requirements-state/funding-requirements-state.component.html
new file mode 100644
index 0000000000..1334fbb958
--- /dev/null
+++ b/frontend/src/app/shared/components/funding-requirements-state/funding-requirements-state.component.html
@@ -0,0 +1,16 @@
+
+
+
+ Green tick Meeting
+
+
+
+ Orange warning flag
+ {{ orangeFlagMessage }}
+ Not meeting
+
+
+
+ Red flag Not meeting
+
+
diff --git a/frontend/src/app/shared/components/funding-requirements-state/funding-requirements-state.component.spec.ts b/frontend/src/app/shared/components/funding-requirements-state/funding-requirements-state.component.spec.ts
new file mode 100644
index 0000000000..96c788cab0
--- /dev/null
+++ b/frontend/src/app/shared/components/funding-requirements-state/funding-requirements-state.component.spec.ts
@@ -0,0 +1,91 @@
+import { SharedModule } from '@shared/shared.module';
+import { render, within } from '@testing-library/angular';
+
+import { WdfModule } from '../../../features/wdf/wdf-data-change/wdf.module';
+import { FundingRequirementsStateComponent } from './funding-requirements-state.component';
+
+describe('FundingRequirementsStateComponent', () => {
+ const setup = async (overrides: any = {}) => {
+ const { fixture, getByText, getAllByText, getByTestId, queryByText, queryByTestId } = await render(
+ FundingRequirementsStateComponent,
+ {
+ imports: [SharedModule, WdfModule],
+ providers: [],
+ componentProperties: {
+ ...overrides,
+ },
+ declarations: [],
+ },
+ );
+ const component = fixture.componentInstance;
+
+ return {
+ component,
+ fixture,
+ getByText,
+ getAllByText,
+ getByTestId,
+ queryByText,
+ queryByTestId,
+ };
+ };
+
+ it('should render a FundingRequirementsStateComponent', async () => {
+ const { component } = await setup();
+
+ expect(component).toBeTruthy();
+ });
+
+ it('should show the green tick if eligible', async () => {
+ const overrides = {
+ currentWdfEligibility: true,
+ };
+ const { getByTestId } = await setup(overrides);
+
+ const requirementsStateText = getByTestId('requirements-state');
+
+ expect(getByTestId('green-tick')).toBeTruthy();
+ expect(within(requirementsStateText).getByText('Meeting')).toBeTruthy();
+ });
+
+ describe('orange warning flag', () => {
+ it('should show the input message if orangeFlagMessage is passed in', async () => {
+ const inputMessage = 'New staff record';
+ const overrides = {
+ currentWdfEligibility: false,
+ overallWdfEligibility: true,
+ orangeFlagMessage: inputMessage,
+ };
+ const { getByTestId } = await setup(overrides);
+ const requirementsStateText = getByTestId('requirements-state');
+
+ expect(getByTestId('orange-flag')).toBeTruthy();
+ expect(within(requirementsStateText).getByText(inputMessage)).toBeTruthy();
+ });
+
+ it('should show the default not meeting message if no orange flag message passed in', async () => {
+ const overrides = {
+ currentWdfEligibility: false,
+ overallWdfEligibility: true,
+ };
+ const { getByTestId } = await setup(overrides);
+ const requirementsStateText = getByTestId('requirements-state');
+
+ expect(getByTestId('orange-flag')).toBeTruthy();
+ expect(within(requirementsStateText).getByText('Not meeting')).toBeTruthy();
+ });
+ });
+
+ it('should show the red cross', async () => {
+ const overrides = {
+ currentWdfEligibility: false,
+ overallWdfEligibility: false,
+ };
+ const { getByTestId } = await setup(overrides);
+
+ const requirementsStateText = getByTestId('requirements-state');
+
+ expect(getByTestId('red-flag')).toBeTruthy();
+ expect(within(requirementsStateText).getByText('Not meeting')).toBeTruthy();
+ });
+});
diff --git a/frontend/src/app/shared/components/funding-requirements-state/funding-requirements-state.component.ts b/frontend/src/app/shared/components/funding-requirements-state/funding-requirements-state.component.ts
new file mode 100644
index 0000000000..bb32e1566d
--- /dev/null
+++ b/frontend/src/app/shared/components/funding-requirements-state/funding-requirements-state.component.ts
@@ -0,0 +1,11 @@
+import { Component, Input } from '@angular/core';
+
+@Component({
+ selector: 'app-funding-requirements-state',
+ templateUrl: './funding-requirements-state.component.html',
+})
+export class FundingRequirementsStateComponent {
+ @Input() overallWdfEligibility: boolean;
+ @Input() currentWdfEligibility: boolean;
+ @Input() orangeFlagMessage: string;
+}
diff --git a/frontend/src/app/shared/components/new-wdf-workplace-summary/wdf-workplace-summary.component.html b/frontend/src/app/shared/components/new-wdf-workplace-summary/wdf-workplace-summary.component.html
index 81aa029a2f..e81d20f6fe 100644
--- a/frontend/src/app/shared/components/new-wdf-workplace-summary/wdf-workplace-summary.component.html
+++ b/frontend/src/app/shared/components/new-wdf-workplace-summary/wdf-workplace-summary.component.html
@@ -1,171 +1,124 @@
-
-
-
-
- Name
- Address
-
-
-
- {{ workplace.name }}
-
-
-
{{ workplace.address1 }}
-
{{ workplace.address2 }}
-
{{ workplace.address3 }}
-
{{ workplace.town }}
-
{{ workplace.county }}
-
{{ workplace.postcode }}
-
-
-
-
-
-
-
-
CQC location ID
-
- {{ workplace.locationId }}
-
-
- Change
-
-
-
-
- Number of staff
-
-
-
- {{ workplace.numberOfStaff | numericAnswer }}
-
-
-
-
-
-
-
-
-
-
-
-
- Number of staff warning
-
-
- workerCount">You've more staff than staff records
- You've more staff records than staff
- The number of staff is missing
-
-
- View staff records
-
+
+ Your workplace details
+
+
+
+
+ Name
+
+
+ {{ workplace.name }}
+
+
+
+
+
+
+
+ Address
+
+
+
+
{{ workplace.address1 }}
+
{{ workplace.address2 }}
+
{{ workplace.address3 }}
+
{{ workplace.town }}
+
{{ workplace.county }}
+
{{ workplace.postcode }}
-
-
-
-
Employer type
-
-
-
- -
-
-
- {{ workplace.employerType?.other ? workplace.employerType.other : workplace.employerType.value }}
-
-
-
-
-
-
-
-
+
+
+
+
CQC location ID
+
+ {{ workplace.locationId }}
+
+
+ Change
+
+
+
+
+
Number of staff
+
+ {{ workplace.numberOfStaff | numericAnswer }}
+
+
+
+
+
+
+
+
+
+
+
Employer type
+
+
+ -
+
+
+ {{ workplace.employerType?.other ? workplace.employerType.other : workplace.employerType.value }}
+
+
+
+
+
+
+
@@ -181,39 +134,23 @@
Main service
-
- {{ cqcStatusRequested ? requestedServiceName : workplace.mainService?.name }}
-
- - {{ cqcStatusRequested ? requestedServiceOtherName : workplace.mainService?.other }}
-
-
-
-
+ - {{ cqcStatusRequested ? requestedServiceOtherName : workplace.mainService?.other }}
+
-
+
+
+
+
+
Other services
@@ -276,43 +219,25 @@
-
+
Service capacity
-
- -
-
-
- {{ capacity.message }}
-
-
-
-
-
+ -
+
+
+ {{ capacity.message }}
+
+
+
+
+
-
+
Service users
-
- -
-
-
-
- {{ users.service }}
- - {{ users.other }}
-
-
-
-
-
+ -
+
+
+
+ {{ users.service }}
+ - {{ users.other }}
+
+
+
+
+
@@ -377,46 +311,28 @@ Vacanci
-
+
Current staff vacancies
-
- -
-
-
-
- {{ vacancy.total }} {{ vacancy.title }}
-
-
- {{ workplace.vacancies }}
-
-
-
-
+ -
+
+
+
+ {{ vacancy.total }} {{ vacancy.title }}
+
+
+ {{ workplace.vacancies }}
+
Vacanci
>
+
+
+
-
+
New starters
-
- -
-
-
-
- {{ starter.total }} {{ starter.title }}
-
-
-
- {{ workplace.starters }}
-
-
-
-
-
+ -
+
+
+
+ {{ starter.total }} {{ starter.title }}
+
+
+
+ {{ workplace.starters }}
+
+
Vacanci
>
+
+
+
-
+
Leavers
-
- -
-
-
-
- {{ leaver.total }} {{ leaver.title }}
-
-
-
- {{ workplace.leavers }}
-
-
-
-
-
+ -
+
+
+
+ {{ leaver.total }} {{ leaver.title }}
+
+
+
+ {{ workplace.leavers }}
+
+
Vacanci
>
+
+
+
@@ -537,37 +456,31 @@ Recruit
Advertising spend
-
+ -
+
+
- -
-
-
-
-
- {{ workplace.moneySpentOnAdvertisingInTheLastFourWeeks }}
-
-
- £{{ this.formatMonetaryValue(workplace.moneySpentOnAdvertisingInTheLastFourWeeks) }}
-
+
+ {{ workplace.moneySpentOnAdvertisingInTheLastFourWeeks }}
+
+
+ £{{ this.formatMonetaryValue(workplace.moneySpentOnAdvertisingInTheLastFourWeeks) }}
-
+
Recruit
People interviewed
-
-
- -
-
-
- {{ workplace.peopleInterviewedInTheLastFourWeeks }}
-
-
+ -
+
+
+ {{ workplace.peopleInterviewedInTheLastFourWeeks }}
+
Recruit
Repeat training
-
-
- -
-
-
- {{ workplace.doNewStartersRepeatMandatoryTrainingFromPreviousEmployment }}
-
-
+ -
+
+
+ {{ workplace.doNewStartersRepeatMandatoryTrainingFromPreviousEmployment }}
+
Recruit
Accept Care Certificate
-
-
- -
-
-
- {{ workplace.wouldYouAcceptCareCertificatesFromPreviousEmployment }}
-
-
+ -
+
+
+ {{ workplace.wouldYouAcceptCareCertificatesFromPreviousEmployment }}
+
Staff b
Cash loyalty bonus
-
+ -
+
+
- -
-
-
-
-
- {{ workplace.careWorkersCashLoyaltyForFirstTwoYears }}
-
-
- £{{ this.formatMonetaryValue(workplace.careWorkersCashLoyaltyForFirstTwoYears) }}
-
+
+ {{ workplace.careWorkersCashLoyaltyForFirstTwoYears }}
+
+
+ £{{ this.formatMonetaryValue(workplace.careWorkersCashLoyaltyForFirstTwoYears) }}
-
+
Staff b
Offer more than Statutory Sick Pay
-
- -
-
- {{ workplace.sickPay }}
-
-
+ -
+
+ {{ workplace.sickPay }}
+
Staff b
Higher pension contributions
-
- -
-
- {{ workplace.pensionContribution }}
-
-
+ -
+
+ {{ workplace.pensionContribution }}
+
Staff b
Number of days leave
-
-
- -
-
-
- {{ workplace.careWorkersLeaveDaysPerYear }}
-
-
+
+ -
+
+
+ {{ workplace.careWorkersLeaveDaysPerYear }}
+
{
- const setup = async (shareWith = null) => {
+ const setup = async (overrides: any = {}) => {
+ const workplace = establishmentWithWdfBuilder() as Establishment;
+
const { fixture, getByText, getByTestId, queryByTestId, rerender } = await render(WDFWorkplaceSummaryComponent, {
imports: [SharedModule, RouterModule, RouterTestingModule, HttpClientTestingModule, WdfModule],
declarations: [],
@@ -50,8 +51,10 @@ describe('WDFWorkplaceSummaryComponent', () => {
],
componentProperties: {
wdfView: true,
- workplace: shareWith ? establishmentWithShareWith(shareWith) : (establishmentWithWdfBuilder() as Establishment),
+ workplace,
removeServiceSectionMargin: false,
+ workerCount: workplace.numberOfStaff,
+ ...overrides,
},
});
const component = fixture.componentInstance;
@@ -65,6 +68,12 @@ describe('WDFWorkplaceSummaryComponent', () => {
expect(component).toBeTruthy();
});
+ it('should render a heading', async () => {
+ const { component, getByText } = await setup();
+
+ expect(getByText('Your workplace details')).toBeTruthy();
+ });
+
it('should render all the sections', async () => {
const { component, fixture, getByTestId } = await setup();
@@ -72,6 +81,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
fixture.detectChanges();
expect(getByTestId('workplace-section')).toBeTruthy();
+ expect(getByTestId('address-section')).toBeTruthy();
expect(getByTestId('cqcLocationId')).toBeTruthy();
expect(getByTestId('numberOfStaff')).toBeTruthy();
expect(getByTestId('employerType')).toBeTruthy();
@@ -82,23 +92,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
expect(getByTestId('staff-benefits-section')).toBeTruthy();
});
- it('should render the certain sections when on the check-answers page', async () => {
- const { component, fixture, getByTestId, queryByTestId } = await setup();
-
- component.checkAnswersPage = true;
- fixture.detectChanges();
-
- expect(queryByTestId('workplace-section')).toBeFalsy();
- expect(queryByTestId('cqcLocationId')).toBeFalsy();
- expect(queryByTestId('numberOfStaff')).toBeFalsy();
- expect(queryByTestId('employerType')).toBeFalsy();
- expect(getByTestId('services-section')).toBeTruthy();
- expect(getByTestId('vacancies-and-turnover-section')).toBeTruthy();
- expect(getByTestId('recruitment-section')).toBeTruthy();
- expect(getByTestId('permissions-section')).toBeTruthy();
- expect(getByTestId('staff-benefits-section')).toBeTruthy();
- });
-
it('should render the services section with top margin when removeServiceSectionMargin is false, and without margin when true', async () => {
const { rerender, getByText } = await setup();
@@ -142,7 +135,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.name = 'Care Home';
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const workplaceRow = within(document.body).queryByTestId('workplace-section');
@@ -158,7 +151,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.isRegulated = true;
- component.canEditEstablishment = true;
+
component.workplace.locationId = '1-23452354';
fixture.detectChanges();
@@ -172,10 +165,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
});
it('should render not the locationID if the workplace is not regulated', async () => {
- const { component, fixture, queryByTestId } = await setup();
-
- component.canEditEstablishment = true;
- fixture.detectChanges();
+ const { queryByTestId } = await setup();
expect(queryByTestId('cqcLocationId')).toBeFalsy();
});
@@ -185,9 +175,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
it('should render the number of staff and a Change link with a bottom border', async () => {
const { component, fixture } = await setup();
- component.canEditEstablishment = true;
component.workplace.numberOfStaff = 4;
-
fixture.detectChanges();
const numberOfStaffRow = within(document.body).queryByTestId('numberOfStaff');
@@ -200,109 +188,47 @@ describe('WDFWorkplaceSummaryComponent', () => {
expect(within(numberOfStaffRow).queryByText('4')).toBeTruthy();
});
- it('should render the number of staff row without bottom border when there is a staff mismatch and it has been longer than 8 weeks since first login', async () => {
- const { component, fixture } = await setup();
+ it('should render the number of staff row without bottom border when staff mismatch message is shown', async () => {
+ const workplace = establishmentWithWdfBuilder() as Establishment;
+ workplace.numberOfStaff = 9;
- component.canEditEstablishment = true;
- component.canViewListOfWorkers = true;
- component.workerCount = 2;
- component.workplace.numberOfStaff = 4;
- component.wdfView = false;
- component.workplace.eightWeeksFromFirstLogin = dayjs(new Date()).subtract(1, 'day').toString();
- fixture.detectChanges();
+ const { queryByTestId } = await setup({ workplace, workerCount: 10 });
- const numberOfStaffRow = within(document.body).queryByTestId('numberOfStaff');
- const property = within(numberOfStaffRow).queryByText('Number of staff');
+ const numberOfStaffRow = queryByTestId('numberOfStaff');
- expect(property.getAttribute('class')).toContain('asc-no-border');
+ expect(numberOfStaffRow.getAttribute('class')).toContain('govuk-summary-list__row--no-bottom-border');
});
});
describe('Number of staff warning', () => {
it('should show banner if you have more staff records', async () => {
- const { component, fixture } = await setup();
+ const workplace = establishmentWithWdfBuilder() as Establishment;
+ workplace.numberOfStaff = 9;
- component.workerCount = 10;
- component.workplace.numberOfStaff = 9;
- component.wdfView = false;
- component.canViewListOfWorkers = true;
- component.workplace.eightWeeksFromFirstLogin = dayjs(new Date()).subtract(1, 'day').toString();
-
- fixture.detectChanges();
+ const { queryByTestId } = await setup({ workplace, workerCount: 10 });
- const moreRecords = within(document.body).queryByTestId('morerecords');
- expect(moreRecords.innerHTML).toContain(`You've more staff records than staff`);
- expect(moreRecords.innerHTML).toContain('View staff records');
+ const staffMismatchMessage = queryByTestId('staffMismatchMessage');
+ expect(staffMismatchMessage).toBeTruthy();
});
it('should show banner if you have more total staff', async () => {
- const { component, fixture } = await setup();
+ const workplace = establishmentWithWdfBuilder() as Establishment;
+ workplace.numberOfStaff = 9;
- component.workerCount = 8;
- component.workplace.numberOfStaff = 9;
- component.wdfView = false;
- component.canViewListOfWorkers = true;
- component.workplace.eightWeeksFromFirstLogin = dayjs(new Date()).subtract(1, 'day').toString();
- fixture.detectChanges();
+ const { queryByTestId } = await setup({ workplace, workerCount: 8 });
- const moreRecords = within(document.body).queryByTestId('morerecords');
- expect(moreRecords.innerHTML).toContain(`You've more staff than staff records`);
+ const staffMismatchMessage = queryByTestId('staffMismatchMessage');
+ expect(staffMismatchMessage).toBeTruthy();
});
it('should show banner if you have more staff records and 0 staff', async () => {
- const { component, fixture } = await setup();
-
- component.workerCount = 10;
- component.workplace.numberOfStaff = 0;
- component.wdfView = false;
- component.canViewListOfWorkers = true;
- component.workplace.eightWeeksFromFirstLogin = dayjs(new Date()).subtract(1, 'day').toString();
- fixture.detectChanges();
-
- const moreRecords = within(document.body).queryByTestId('morerecords');
- expect(moreRecords.innerHTML).toContain(`You've more staff records than staff`);
- });
-
- it('should not show banner if first login date is within eight weeks of now', async () => {
- const { component, fixture } = await setup();
+ const workplace = establishmentWithWdfBuilder() as Establishment;
+ workplace.numberOfStaff = 0;
- component.workerCount = 10;
- component.workplace.numberOfStaff = 0;
- component.wdfView = false;
- component.canViewListOfWorkers = true;
- component.workplace.eightWeeksFromFirstLogin = dayjs(new Date()).add(1, 'day').toString();
- fixture.detectChanges();
-
- const moreRecords = within(document.body).queryByTestId('morerecords');
- expect(moreRecords).toBe(null);
- });
-
- it(`should not show banner if you don't have permission to list workers`, async () => {
- const { component, fixture } = await setup();
-
- component.workerCount = 10;
- component.workplace.numberOfStaff = 9;
- component.wdfView = false;
- component.canViewListOfWorkers = false;
- component.workplace.eightWeeksFromFirstLogin = dayjs(new Date()).subtract(1, 'day').toString();
- fixture.detectChanges();
-
- const moreRecords = within(document.body).queryByTestId('morerecords');
- expect(moreRecords).toBe(null);
- });
+ const { queryByTestId } = await setup({ workplace, workerCount: 10 });
- it('should not show banner if it is the WDF View', async () => {
- const { component, fixture } = await setup();
-
- component.workerCount = 10;
- component.workplace.numberOfStaff = 9;
- component.wdfView = true;
- component.canViewListOfWorkers = true;
- component.workplace.eightWeeksFromFirstLogin = dayjs(new Date()).subtract(1, 'day').toString();
- fixture.detectChanges();
-
- const moreRecords = within(document.body).queryByTestId('morerecords');
- expect(moreRecords).toBe(null);
+ const staffMismatchMessage = queryByTestId('staffMismatchMessage');
+ expect(staffMismatchMessage).toBeTruthy();
});
});
@@ -310,7 +236,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
it('should render the employer type and a Change link when employer type is the other field in object', async () => {
const { component, fixture } = await setup();
- component.canEditEstablishment = true;
component.workplace.employerType = { other: 'Adult care', value: 'Other' };
fixture.detectChanges();
@@ -326,7 +251,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
it('should render the employer type and a Change link when employer type is the other field in object', async () => {
const { component, fixture } = await setup();
- component.canEditEstablishment = true;
component.workplace.employerType = { other: null, value: 'Voluntary / Charity' };
fixture.detectChanges();
@@ -342,24 +266,12 @@ describe('WDFWorkplaceSummaryComponent', () => {
});
describe('services section', () => {
- it('should show not show the main service row if on the check answers page', async () => {
- const { component, fixture, getByTestId, queryByTestId } = await setup();
-
- component.checkAnswersPage = true;
- fixture.detectChanges();
-
- expect(queryByTestId('mainService')).toBeFalsy();
- expect(getByTestId('otherServices')).toBeTruthy();
- expect(getByTestId('serviceCapacity')).toBeTruthy();
- expect(getByTestId('serviceUsers')).toBeTruthy();
- });
-
describe('Main service', () => {
it('should show Pending on main service when non-CQC to CQC main service change has been requested', async () => {
const { component, fixture } = await setup();
component.cqcStatusRequested = true;
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const mainServiceChangeOrPending = within(document.body).queryByTestId('main-service-change-or-pending');
@@ -370,7 +282,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.cqcStatusRequested = false;
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const mainServiceChangeOrPending = within(document.body).queryByTestId('main-service-change-or-pending');
@@ -403,9 +315,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
it('should show the Change link when there is a main service', async () => {
const { component, fixture } = await setup();
- component.canEditEstablishment = true;
- fixture.detectChanges();
-
const mainServiceRow = within(document.body).queryByTestId('mainService');
const link = within(mainServiceRow).queryByText('Change');
@@ -417,7 +326,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.mainService = null;
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const mainServiceRow = within(document.body).queryByTestId('mainService');
@@ -431,7 +340,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.cqcStatusRequested = true;
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const mainServiceRow = within(document.body).queryByTestId('mainService');
@@ -446,7 +355,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.otherServices = { value: null };
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const otherServicesRow = within(document.body).queryByTestId('otherServices');
@@ -461,7 +370,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.otherServices = { value: 'No' };
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const otherServicesRow = within(document.body).queryByTestId('otherServices');
@@ -480,7 +389,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
services: [{ category: 'category1', services: [{ id: 1, name: 'Carers' }] }],
};
- component.canEditEstablishment = true;
fixture.detectChanges();
const otherServicesRow = within(document.body).queryByTestId('otherServices');
@@ -508,7 +416,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
],
};
- component.canEditEstablishment = true;
fixture.detectChanges();
const otherServicesRow = within(document.body).queryByTestId('otherServices');
@@ -527,7 +434,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.capacities = [];
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const serviceCapacityRow = within(document.body).queryByTestId('serviceCapacity');
@@ -566,7 +473,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
{ message: '1 bed available', service: ' (some kind of service)' },
{ message: '4 people receiving care', service: ' (some kind of service)' },
];
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const serviceCapacityRow = within(document.body).queryByTestId('serviceCapacity');
@@ -584,7 +491,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.serviceUsers = [];
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const serviceUsersRow = within(document.body).queryByTestId('serviceUsers');
@@ -606,7 +513,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
},
];
- component.canEditEstablishment = true;
fixture.detectChanges();
const serviceUsersRow = within(document.body).queryByTestId('serviceUsers');
@@ -633,7 +539,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
},
];
- component.canEditEstablishment = true;
fixture.detectChanges();
const serviceUsersRow = within(document.body).queryByTestId('serviceUsers');
@@ -653,7 +558,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.vacancies = null;
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const vacanciesRow = within(document.body).queryByTestId('vacancies');
@@ -668,7 +573,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.vacancies = `Don't know`;
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const vacanciesRow = within(document.body).queryByTestId('vacancies');
@@ -683,7 +588,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.vacancies = `None`;
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const vacanciesRow = within(document.body).queryByTestId('vacancies');
@@ -698,7 +603,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.vacancies = [{ jobId: 1, title: 'Administrative', total: 3 }];
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const vacanciesRow = within(document.body).queryByTestId('vacancies');
@@ -716,7 +621,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
{ jobId: 1, title: 'Administrative', total: 3 },
{ jobId: 2, title: 'Nursing', total: 2 },
];
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const vacanciesRow = within(document.body).queryByTestId('vacancies');
@@ -725,49 +630,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
expect(within(vacanciesRow).queryByText(`3 Administrative`)).toBeTruthy();
expect(within(vacanciesRow).queryByText('2 Nursing')).toBeTruthy();
});
-
- it('should show WdfFieldConfirmation component when is eligible but needs to be confirmed for Current Staff Vacancies', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.workplace.wdf.vacancies.isEligible = Eligibility.YES;
- component.workplace.wdf.vacancies.updatedSinceEffectiveDate = false;
- component.workplace.vacancies = [
- {
- jobId: 1,
- title: 'Activities worker or co-ordinator',
- total: 1,
- },
- ];
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Current Staff Vacancies', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.workplace.wdf.vacancies.isEligible = Eligibility.YES;
- component.workplace.wdf.vacancies.updatedSinceEffectiveDate = false;
- component.workplace.vacancies = [
- {
- jobId: 1,
- title: 'Activities worker or co-ordinator',
- total: 1,
- },
- ];
-
- fixture.detectChanges();
-
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
-
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
});
describe('New starters', () => {
@@ -775,7 +637,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.starters = null;
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const startersRow = within(document.body).queryByTestId('starters');
@@ -790,7 +652,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.starters = `Don't know`;
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const startersRow = within(document.body).queryByTestId('starters');
@@ -805,7 +667,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.starters = `None`;
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const startersRow = within(document.body).queryByTestId('starters');
@@ -820,7 +682,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.starters = [{ jobId: 1, title: 'Administrative', total: 3 }];
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const startersRow = within(document.body).queryByTestId('starters');
@@ -838,7 +700,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
{ jobId: 1, title: 'Administrative', total: 3 },
{ jobId: 2, title: 'Nursing', total: 2 },
];
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const startersRow = within(document.body).queryByTestId('starters');
@@ -847,49 +709,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
expect(within(startersRow).queryByText(`3 Administrative`)).toBeTruthy();
expect(within(startersRow).queryByText('2 Nursing')).toBeTruthy();
});
-
- it('should show WdfFieldConfirmation component when is eligible but needs to be confirmed for New Starters', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.workplace.wdf.starters.isEligible = Eligibility.YES;
- component.workplace.wdf.starters.updatedSinceEffectiveDate = false;
- component.workplace.starters = [
- {
- jobId: 1,
- title: 'Activities worker or co-ordinator',
- total: 1,
- },
- ];
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for New Starters', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.workplace.wdf.starters.isEligible = Eligibility.YES;
- component.workplace.wdf.starters.updatedSinceEffectiveDate = false;
- component.workplace.starters = [
- {
- jobId: 1,
- title: 'Activities worker or co-ordinator',
- total: 1,
- },
- ];
-
- fixture.detectChanges();
-
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
-
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
});
describe('Staff leavers', () => {
@@ -897,7 +716,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.leavers = null;
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const leaversRow = within(document.body).queryByTestId('leavers');
@@ -912,7 +731,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.leavers = `Don't know`;
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const leaversRow = within(document.body).queryByTestId('leavers');
@@ -927,7 +746,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.leavers = `None`;
- component.canEditEstablishment = true;
+
fixture.detectChanges();
const leaversRow = within(document.body).queryByTestId('leavers');
@@ -942,7 +761,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.leavers = [{ jobId: 1, title: 'Administrative', total: 3 }];
- component.canEditEstablishment = true;
fixture.detectChanges();
const leaversRow = within(document.body).queryByTestId('leavers');
@@ -960,7 +778,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
{ jobId: 1, title: 'Administrative', total: 3 },
{ jobId: 2, title: 'Nursing', total: 2 },
];
- component.canEditEstablishment = true;
fixture.detectChanges();
const leaversRow = within(document.body).queryByTestId('leavers');
@@ -969,49 +786,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
expect(within(leaversRow).queryByText(`3 Administrative`)).toBeTruthy();
expect(within(leaversRow).queryByText('2 Nursing')).toBeTruthy();
});
-
- it('should show WdfFieldConfirmation component when is eligible but needs to be confirmed for Staff Leavers', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.workplace.wdf.leavers.isEligible = Eligibility.YES;
- component.workplace.wdf.leavers.updatedSinceEffectiveDate = false;
- component.workplace.vacancies = [
- {
- jobId: 1,
- title: 'Activities worker or co-ordinator',
- total: 1,
- },
- ];
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Staff Leavers', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.workplace.wdf.leavers.isEligible = Eligibility.YES;
- component.workplace.wdf.leavers.updatedSinceEffectiveDate = false;
- component.workplace.vacancies = [
- {
- jobId: 1,
- title: 'Activities worker or co-ordinator',
- total: 1,
- },
- ];
-
- fixture.detectChanges();
-
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
-
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
});
});
@@ -1021,7 +795,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.moneySpentOnAdvertisingInTheLastFourWeeks = null;
- component.canEditEstablishment = true;
fixture.detectChanges();
const advertisingSpendRow = within(document.body).queryByTestId('advertising-spend');
@@ -1035,7 +808,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
it('should show Change button on Advertising spend row when moneySpentOnAdvertisingInTheLastFourWeeksType has a value (answered)', async () => {
const { component, fixture } = await setup();
- component.canEditEstablishment = true;
fixture.detectChanges();
const advertisingSpendRow = within(document.body).queryByTestId('advertising-spend');
@@ -1056,7 +828,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.peopleInterviewedInTheLastFourWeeks = null;
- component.canEditEstablishment = true;
fixture.detectChanges();
const peopleInterviewedRow = within(document.body).queryByTestId('people-interviewed');
@@ -1070,9 +841,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
it('should show Change button on People Interviewed row when peopleInterviewedInTheLastFourWeeks has a value (answered)', async () => {
const { component, fixture } = await setup();
- component.canEditEstablishment = true;
- fixture.detectChanges();
-
const peopleInterviewedRow = within(document.body).queryByTestId('people-interviewed');
const link = within(peopleInterviewedRow).queryByText('Change');
@@ -1089,7 +857,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.doNewStartersRepeatMandatoryTrainingFromPreviousEmployment = null;
- component.canEditEstablishment = true;
fixture.detectChanges();
const repeatTrainingRow = within(document.body).queryByTestId('repeat-training');
@@ -1105,9 +872,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
it('should show Change button on Repeat Training row when doNewStartersRepeatMandatoryTrainingFromPreviousEmployment has a value (answered)', async () => {
const { component, fixture } = await setup();
- component.canEditEstablishment = true;
- fixture.detectChanges();
-
const repeatTrainingRow = within(document.body).queryByTestId('repeat-training');
const link = within(repeatTrainingRow).queryByText('Change');
@@ -1129,7 +893,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.wouldYouAcceptCareCertificatesFromPreviousEmployment = null;
- component.canEditEstablishment = true;
fixture.detectChanges();
const acceptCareCertificateRow = within(document.body).queryByTestId('accept-care-certificate');
@@ -1146,9 +909,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
it('should show Change button on accept care certificate row when wouldYouAcceptCareCertificatesFromPreviousEmployment has a value (answered)', async () => {
const { component, fixture } = await setup();
- component.canEditEstablishment = true;
- fixture.detectChanges();
-
const acceptCareCertificateRow = within(document.body).queryByTestId('accept-care-certificate');
const link = within(acceptCareCertificateRow).queryByText('Change');
@@ -1171,7 +931,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.careWorkersCashLoyaltyForFirstTwoYears = null;
- component.canEditEstablishment = true;
fixture.detectChanges();
const careWorkersCashLoyaltyRow = within(document.body).queryByTestId('cash-loyalty-bonus-spend');
@@ -1185,9 +944,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
it('should show Change button on Cash loyalty bonus row when careWorkersCashLoyaltyForFirstTwoYears has a value (answered)', async () => {
const { component, fixture } = await setup();
- component.canEditEstablishment = true;
- fixture.detectChanges();
-
const careWorkersCashLoyaltyRow = within(document.body).queryByTestId('cash-loyalty-bonus-spend');
const link = within(careWorkersCashLoyaltyRow).queryByText('Change');
@@ -1206,7 +962,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.sickPay = null;
- component.canEditEstablishment = true;
fixture.detectChanges();
const statutorySickPayRow = within(document.body).queryByTestId('offer-more-than-statutory-sick-pay');
@@ -1220,9 +975,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
it('should show Change button on statutory sick pay row when sickPay has a value (answered)', async () => {
const { component, fixture } = await setup();
- component.canEditEstablishment = true;
- fixture.detectChanges();
-
const statutorySickPayRow = within(document.body).queryByTestId('offer-more-than-statutory-sick-pay');
const link = within(statutorySickPayRow).queryByText('Change');
@@ -1237,7 +989,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.pensionContribution = null;
- component.canEditEstablishment = true;
fixture.detectChanges();
const pensionContributionRow = within(document.body).queryByTestId('higher-pension-contributions');
@@ -1252,7 +1003,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.pensionContribution = 'Yes';
- component.canEditEstablishment = true;
fixture.detectChanges();
const pensionContributionRow = within(document.body).queryByTestId('higher-pension-contributions');
@@ -1269,7 +1019,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
const { component, fixture } = await setup();
component.workplace.careWorkersLeaveDaysPerYear = null;
- component.canEditEstablishment = true;
fixture.detectChanges();
const careWorkersLeaveDaysPerYearRow = within(document.body).queryByTestId('number-of-days-leave');
@@ -1283,7 +1032,6 @@ describe('WDFWorkplaceSummaryComponent', () => {
it('should show Change button on number of days leave row when careWorkersLeaveDaysPerYear has a value (answered)', async () => {
const { component, fixture } = await setup();
- component.canEditEstablishment = true;
fixture.detectChanges();
const careWorkersLeaveDaysPerYearRow = within(document.body).queryByTestId('number-of-days-leave');
@@ -1301,10 +1049,7 @@ describe('WDFWorkplaceSummaryComponent', () => {
describe('Permissions section', () => {
describe('Data sharing', () => {
it('should show dash and have Add information button on Data sharing when cqc and localAuthorities set to null (not answered)', async () => {
- const { component, fixture } = await setup();
-
- component.canEditEstablishment = true;
- fixture.detectChanges();
+ const { component } = await setup();
const dataSharing = within(document.body).queryByTestId('data-sharing');
const link = within(dataSharing).queryByText('Add');
@@ -1315,10 +1060,8 @@ describe('WDFWorkplaceSummaryComponent', () => {
});
it('should show Local authorities and have Change button on Data sharing when localAuthorities set to true', async () => {
- const { component, fixture } = await setup({ cqc: null, localAuthorities: true });
-
- component.canEditEstablishment = true;
- fixture.detectChanges();
+ const workplace = establishmentWithShareWith({ cqc: null, localAuthorities: true });
+ const { component } = await setup({ workplace });
const dataSharing = within(document.body).queryByTestId('data-sharing');
const link = within(dataSharing).queryByText('Change');
@@ -1329,10 +1072,8 @@ describe('WDFWorkplaceSummaryComponent', () => {
});
it('should show CQC and have Change button on Data sharing when cqc set to true', async () => {
- const { component, fixture } = await setup({ cqc: true, localAuthorities: false });
-
- component.canEditEstablishment = true;
- fixture.detectChanges();
+ const workplace = establishmentWithShareWith({ cqc: true, localAuthorities: false });
+ await setup({ workplace });
const dataSharing = within(document.body).queryByTestId('data-sharing');
@@ -1341,10 +1082,8 @@ describe('WDFWorkplaceSummaryComponent', () => {
});
it('should show Not sharing and have Change button on Data sharing when cqc and localAuthorities are set to false', async () => {
- const { component, fixture } = await setup({ cqc: false, localAuthorities: false });
-
- component.canEditEstablishment = true;
- fixture.detectChanges();
+ const workplace = establishmentWithShareWith({ cqc: false, localAuthorities: false });
+ const { component, fixture } = await setup({ workplace });
const dataSharing = within(document.body).queryByTestId('data-sharing');
@@ -1353,10 +1092,8 @@ describe('WDFWorkplaceSummaryComponent', () => {
});
it('should show Not sharing and have Change button on Data sharing when cqc is set to false and localAuthorities is null (not answered)', async () => {
- const { component, fixture } = await setup({ cqc: false, localAuthorities: null });
-
- component.canEditEstablishment = true;
- fixture.detectChanges();
+ const workplace = establishmentWithShareWith({ cqc: false, localAuthorities: null });
+ const { component, fixture } = await setup({ workplace });
const dataSharing = within(document.body).queryByTestId('data-sharing');
@@ -1365,10 +1102,8 @@ describe('WDFWorkplaceSummaryComponent', () => {
});
it('should show Not sharing and have Change button on Data sharing when localAuthorities is set to false and cqc is null (not answered)', async () => {
- const { component, fixture } = await setup({ cqc: null, localAuthorities: false });
-
- component.canEditEstablishment = true;
- fixture.detectChanges();
+ const workplace = establishmentWithShareWith({ cqc: null, localAuthorities: false });
+ await setup({ workplace });
const dataSharing = within(document.body).queryByTestId('data-sharing');
@@ -1377,10 +1112,8 @@ describe('WDFWorkplaceSummaryComponent', () => {
});
it('should not show Not sharing when one of cqc and localAuthorities is false and one is true', async () => {
- const { component, fixture } = await setup({ cqc: true, localAuthorities: false });
-
- component.canEditEstablishment = true;
- fixture.detectChanges();
+ const workplace = establishmentWithShareWith({ cqc: true, localAuthorities: false });
+ await setup({ workplace });
const dataSharing = within(document.body).queryByTestId('data-sharing');
@@ -1389,4 +1122,171 @@ describe('WDFWorkplaceSummaryComponent', () => {
});
});
});
+
+ describe('WdfFieldConfirmation', () => {
+ [
+ {
+ fieldName: 'vacancies',
+ value: [
+ {
+ jobId: 1,
+ title: 'Activities worker or co-ordinator',
+ total: 1,
+ },
+ ],
+ },
+ {
+ fieldName: 'starters',
+ value: [
+ {
+ jobId: 1,
+ title: 'Activities worker or co-ordinator',
+ total: 1,
+ },
+ ],
+ },
+ {
+ fieldName: 'leavers',
+ value: [
+ {
+ jobId: 1,
+ title: 'Activities worker or co-ordinator',
+ total: 1,
+ },
+ ],
+ },
+ {
+ fieldName: 'mainService',
+ value: { name: 'Care Giving' },
+ },
+ {
+ fieldName: 'capacities',
+ value: [{ message: '4 beds' }],
+ },
+ {
+ fieldName: 'serviceUsers',
+ value: [{ service: 'Care Giving' }],
+ },
+ {
+ fieldName: 'numberOfStaff',
+ value: 3,
+ },
+ ].forEach((field) => {
+ const establishmentWithWdfFieldEligibleButNotUpdatedSinceEffective = (fieldName, value) => {
+ const workplace = establishmentWithWdfBuilder() as Establishment;
+ workplace.wdf[field.fieldName].isEligible = Eligibility.YES;
+ workplace.wdf[field.fieldName].updatedSinceEffectiveDate = false;
+ workplace[field.fieldName] = field.value;
+
+ return workplace;
+ };
+
+ it(`should show WdfFieldConfirmation when is eligible but needs to be confirmed for ${field.fieldName}`, async () => {
+ const workplace = establishmentWithWdfFieldEligibleButNotUpdatedSinceEffective(field.fieldName, field.value);
+
+ const { getByText } = await setup({ workplace });
+
+ expect(getByText('Is this still correct?')).toBeTruthy();
+ expect(getByText('Yes, it is')).toBeTruthy();
+ expect(getByText('No, change it')).toBeTruthy();
+ });
+
+ it(`should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for ${field.fieldName}`, async () => {
+ const workplace = establishmentWithWdfFieldEligibleButNotUpdatedSinceEffective(field.fieldName, field.value);
+
+ const { fixture, getByText } = await setup({ workplace });
+
+ const yesItIsButton = getByText('Yes, it is', { exact: false });
+ yesItIsButton.click();
+
+ fixture.detectChanges();
+
+ expect(getByText('Meeting requirements')).toBeTruthy();
+ });
+ });
+ });
+
+ describe('Add information messages', () => {
+ [
+ {
+ name: 'employerType',
+ validResponse: { value: 'Care Home' },
+ },
+ {
+ name: 'capacities',
+ validResponse: [{ message: '10 beds used (care home)' }],
+ specificMessage: 'Add the capacity of your main service',
+ },
+ {
+ name: 'serviceUsers',
+ validResponse: [{ group: 'Adults', id: 10, service: 'Adults with dementia' }],
+ },
+ {
+ name: 'vacancies',
+ validResponse: [{ jobId: 13, title: 'First-line manager', total: 1 }],
+ },
+ {
+ name: 'starters',
+ validResponse: [{ jobId: 13, title: 'First-line manager', total: 1 }],
+ },
+ {
+ name: 'leavers',
+ validResponse: [
+ {
+ jobId: 1,
+ title: 'Activities worker or co-ordinator',
+ total: 1,
+ },
+ ],
+ },
+ {
+ name: 'numberOfStaff',
+ validResponse: 3,
+ },
+ {
+ name: 'mainService',
+ validResponse: { name: 'Care Giving' },
+ },
+ ].forEach((field) => {
+ const expectedWarningMessage = field.specificMessage ?? 'Add this information';
+
+ it(`should show '${expectedWarningMessage}' message and red flag when workplace is not eligible and needs to add ${field.name}`, async () => {
+ const workplace = establishmentWithWdfBuilder() as Establishment;
+ workplace[field.name] = null;
+ workplace.wdf[field.name].isEligible = Eligibility.NO;
+
+ const { getByTestId } = await setup({ workplace });
+
+ const wdfWarningSection = getByTestId(field.name + 'WdfWarning');
+
+ expect(within(wdfWarningSection).getByText(expectedWarningMessage)).toBeTruthy();
+ expect(within(wdfWarningSection).getByAltText('Red flag icon')).toBeTruthy();
+ });
+
+ it(`should not show '${expectedWarningMessage}' message when workplace is not eligible but has added ${field.name}`, async () => {
+ const workplace = establishmentWithWdfBuilder() as Establishment;
+ workplace[field.name] = field.validResponse;
+ workplace.wdf[field.name].isEligible = Eligibility.YES;
+
+ const { queryByTestId } = await setup({ workplace });
+
+ const wdfWarningSection = queryByTestId(field.name + 'WdfWarning');
+
+ expect(wdfWarningSection).toBeFalsy();
+ });
+
+ it(`should show '${expectedWarningMessage}' and orange flag when workplace does not have ${field.name} added but workplace has met WDF eligibility`, async () => {
+ const workplace = establishmentWithWdfBuilder() as Establishment;
+ workplace[field.name] = null;
+ workplace.wdf[field.name].isEligible = Eligibility.NO;
+
+ const { getByTestId } = await setup({ workplace, overallWdfEligibility: true });
+
+ const wdfWarningSection = getByTestId(field.name + 'WdfWarning');
+
+ expect(within(wdfWarningSection).queryByText(expectedWarningMessage)).toBeTruthy();
+ expect(within(wdfWarningSection).getByAltText('Orange flag icon')).toBeTruthy();
+ });
+ });
+ });
});
diff --git a/frontend/src/app/shared/components/new-wdf-workplace-summary/wdf-workplace-summary.component.ts b/frontend/src/app/shared/components/new-wdf-workplace-summary/wdf-workplace-summary.component.ts
index 793d5300e5..dddcce267f 100644
--- a/frontend/src/app/shared/components/new-wdf-workplace-summary/wdf-workplace-summary.component.ts
+++ b/frontend/src/app/shared/components/new-wdf-workplace-summary/wdf-workplace-summary.component.ts
@@ -2,6 +2,7 @@ import { I18nPluralPipe } from '@angular/common';
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core';
import { Service } from '@core/model/services.model';
import { URLStructure } from '@core/model/url.model';
+import { Eligibility } from '@core/model/wdf.model';
import { CqcStatusChangeService } from '@core/services/cqc-status-change.service';
import { EstablishmentService } from '@core/services/establishment.service';
import { PermissionsService } from '@core/services/permissions/permissions.service';
@@ -17,7 +18,6 @@ import { Subscription } from 'rxjs';
})
export class WDFWorkplaceSummaryComponent implements OnInit, OnDestroy, OnChanges {
private _workplace: any;
- public resp: any;
protected subscriptions: Subscription = new Subscription();
public hasCapacity: boolean;
private capacities: any;
@@ -30,13 +30,23 @@ export class WDFWorkplaceSummaryComponent implements OnInit, OnDestroy, OnChange
public canViewListOfWorkers = false;
public confirmedFields: Array = [];
public showTotalStaffWarning: boolean;
- public checkAnswersPage: boolean;
public now: Date = new Date();
public typeOfEmployer: string;
+ public showWdfConfirmations: any = {
+ starters: null,
+ leavers: null,
+ vacancies: null,
+ mainService: null,
+ capacities: null,
+ serviceUsers: null,
+ numberOfStaff: null,
+ };
+ public Eligibility = Eligibility;
+ public wdfView = true;
+
@Output() allFieldsConfirmed: EventEmitter = new EventEmitter();
@Input() removeServiceSectionMargin = false;
- @Input() wdfView = false;
@Input() overallWdfEligibility: boolean;
@Input() workerCount: number;
@Input()
@@ -64,13 +74,8 @@ export class WDFWorkplaceSummaryComponent implements OnInit, OnDestroy, OnChange
}
}
}
- }
- get totalStaffWarningNonWDF(): boolean {
- return (
- (this.workplace.numberOfStaff != null || this.workplace.totalWorkers !== null) &&
- this.workplace.numberOfStaff !== this.workerCount
- );
+ this.setShowWdfConfirmations();
}
constructor(
@@ -109,10 +114,9 @@ export class WDFWorkplaceSummaryComponent implements OnInit, OnDestroy, OnChange
ngOnInit(): void {
this.canEditEstablishment = this.permissionsService.can(this.workplace.uid, 'canEditEstablishment');
this.canViewListOfWorkers = this.permissionsService.can(this.workplace.uid, 'canViewListOfWorkers');
- this.checkAnswersPage = this.return?.url.includes('check-answers');
this.setTotalStaffWarning();
- if (this.canEditEstablishment && this.wdfView) {
+ if (this.canEditEstablishment) {
this.updateEmployerTypeIfNotUpdatedSinceEffectiveDate();
}
@@ -157,6 +161,8 @@ export class WDFWorkplaceSummaryComponent implements OnInit, OnDestroy, OnChange
}
}),
);
+
+ this.setShowWdfConfirmations();
}
public sortedCapacityService(capacityService: any) {
@@ -165,9 +171,6 @@ export class WDFWorkplaceSummaryComponent implements OnInit, OnDestroy, OnChange
});
}
- ngOnDestroy(): void {
- this.subscriptions.unsubscribe();
- }
public setTotalStaffWarning(): void {
if (this.workplace.workerCount === null && this.workerCount === null) {
this.showTotalStaffWarning = false;
@@ -202,21 +205,10 @@ export class WDFWorkplaceSummaryComponent implements OnInit, OnDestroy, OnChange
this.establishmentService.setReturnTo(this.return);
}
- public selectStaffTab(event: Event): void {
- event.preventDefault();
- this.workerService.tabChanged.next(true);
- }
-
public isNumber(value: unknown): boolean {
return typeof value === 'number';
}
- public staffMismatchWarning(): boolean {
- return (
- this.canViewListOfWorkers && this.isNumber(this.workerCount) && !this.wdfView && this.totalStaffWarningNonWDF
- );
- }
-
public getRoutePath(name: string): Array {
return ['/workplace', this.workplace.uid, name];
}
@@ -253,10 +245,29 @@ export class WDFWorkplaceSummaryComponent implements OnInit, OnDestroy, OnChange
'serviceUsers',
'starters',
'vacancies',
+ 'capacities',
];
return requiredFields.every(
(field) => this.workplace.wdf[field].updatedSinceEffectiveDate || this.confirmedFields.includes(field),
);
}
+
+ protected setShowWdfConfirmations(): void {
+ Object.keys(this.showWdfConfirmations).forEach((field) => {
+ this.showWdfConfirmations[field] = this.shouldShowWdfConfirmation(field);
+ });
+ }
+
+ public shouldShowWdfConfirmation(field: string): boolean {
+ return (
+ this.canEditEstablishment &&
+ this.workplace.wdf?.[field]?.isEligible === 'Yes' &&
+ !this.workplace.wdf?.[field]?.updatedSinceEffectiveDate
+ );
+ }
+
+ ngOnDestroy(): void {
+ this.subscriptions.unsubscribe();
+ }
}
diff --git a/frontend/src/app/shared/components/select-view-panel/select-view-panel.component.html b/frontend/src/app/shared/components/select-view-panel/select-view-panel.component.html
new file mode 100644
index 0000000000..15d9131b9e
--- /dev/null
+++ b/frontend/src/app/shared/components/select-view-panel/select-view-panel.component.html
@@ -0,0 +1,19 @@
+
diff --git a/frontend/src/app/shared/components/select-view-panel/select-view-panel.component.scss b/frontend/src/app/shared/components/select-view-panel/select-view-panel.component.scss
new file mode 100644
index 0000000000..e991096639
--- /dev/null
+++ b/frontend/src/app/shared/components/select-view-panel/select-view-panel.component.scss
@@ -0,0 +1,34 @@
+@import 'govuk-frontend/govuk/base';
+
+.asc-tabs {
+ &__list {
+ list-style: none;
+ display: flex;
+ padding: 0;
+ margin: 0;
+ }
+
+ &__list-item {
+ padding: 10px 35px;
+ margin-right: 0px;
+ background-color: govuk-colour('white');
+
+ &--active {
+ border-bottom: 8px solid govuk-colour('blue');
+ }
+
+ &:not:first-of-type {
+ margin-left: 35px;
+ }
+ }
+
+ &__link {
+ font-size: 19px;
+ color: govuk-colour('blue') !important;
+
+ &--active {
+ text-decoration: none;
+ color: black !important;
+ }
+ }
+}
diff --git a/frontend/src/app/shared/components/select-view-panel/select-view-panel.component.spec.ts b/frontend/src/app/shared/components/select-view-panel/select-view-panel.component.spec.ts
new file mode 100644
index 0000000000..f2f614b4c8
--- /dev/null
+++ b/frontend/src/app/shared/components/select-view-panel/select-view-panel.component.spec.ts
@@ -0,0 +1,147 @@
+import { fireEvent, render, within } from '@testing-library/angular';
+import { spy } from 'sinon';
+
+import { SelectViewPanelComponent } from './select-view-panel.component';
+
+describe('SelectViewPanelComponent', () => {
+ async function setup(overrides: any = {}) {
+ const setupTools = await render(SelectViewPanelComponent, {
+ imports: [],
+ declarations: [],
+ providers: [],
+ componentProperties: {
+ handleTabChange: {
+ emit: spy(),
+ } as any,
+ tabs: [
+ { name: 'Tab0', fragment: 'tab0' },
+ { name: 'Tab1', fragment: 'tab1' },
+ ],
+ ...overrides,
+ },
+ });
+
+ const component = setupTools.fixture.componentInstance;
+ const handleTabChangeSpy = spyOn(component.handleTabChange, 'emit').and.callThrough();
+
+ return {
+ component,
+ handleTabChangeSpy,
+ ...setupTools,
+ };
+ }
+
+ it('should render the component', async () => {
+ const { component } = await setup();
+ expect(component).toBeTruthy();
+ });
+
+ describe('Two tabs', () => {
+ async function setupTwoTabs(overrides = {}) {
+ const tabs = [
+ { name: 'Tab0', fragment: 'tab0' },
+ { name: 'Tab1', fragment: 'tab1' },
+ ];
+
+ const setupTools = await setup({ tabs, ...overrides });
+
+ const firstTab = setupTools.getByTestId('tab0');
+ const secondTab = setupTools.getByTestId('tab1');
+ const firstTabLink = within(firstTab).getByText(tabs[0].name);
+ const secondTabLink = within(secondTab).getByText(tabs[1].name);
+
+ return { ...setupTools, firstTab, secondTab, firstTabLink, secondTabLink, tabs };
+ }
+
+ it('should set the first tab as active on load if no activeTabIndex passed in', async () => {
+ const { firstTab, firstTabLink, secondTab, secondTabLink } = await setupTwoTabs();
+
+ expect(firstTab.getAttribute('class')).toContain('asc-tabs__list-item--active');
+ expect(firstTabLink.getAttribute('class')).toContain('asc-tabs__link--active');
+ expect(secondTab.getAttribute('class')).not.toContain('asc-tabs__list-item--active');
+ expect(secondTabLink.getAttribute('class')).not.toContain('asc-tabs__link--active');
+ });
+
+ it('should set the second tab as active on load if activeTabIndex passed in as 1', async () => {
+ const { firstTab, firstTabLink, secondTab, secondTabLink } = await setupTwoTabs({ activeTabIndex: 1 });
+
+ expect(secondTab.getAttribute('class')).toContain('asc-tabs__list-item--active');
+ expect(secondTabLink.getAttribute('class')).toContain('asc-tabs__link--active');
+ expect(firstTab.getAttribute('class')).not.toContain('asc-tabs__list-item--active');
+ expect(firstTabLink.getAttribute('class')).not.toContain('asc-tabs__link--active');
+ });
+
+ it('should set the second tab as active after clicking second tab', async () => {
+ const { fixture, firstTab, firstTabLink, secondTab, secondTabLink } = await setupTwoTabs();
+
+ fireEvent.click(secondTabLink);
+ fixture.detectChanges();
+
+ expect(secondTab.getAttribute('class')).toContain('asc-tabs__list-item--active');
+ expect(secondTabLink.getAttribute('class')).toContain('asc-tabs__link--active');
+ expect(firstTab.getAttribute('class')).not.toContain('asc-tabs__list-item--active');
+ expect(firstTabLink.getAttribute('class')).not.toContain('asc-tabs__link--active');
+ });
+
+ it('should emit handleTabChange with second index (1) when second tab is clicked', async () => {
+ const { handleTabChangeSpy, secondTabLink } = await setupTwoTabs();
+
+ fireEvent.click(secondTabLink);
+
+ expect(handleTabChangeSpy).toHaveBeenCalledWith(1);
+ });
+
+ it('should emit handleTabChange with first index (0) when the first tab link is clicked', async () => {
+ const { component, fixture, handleTabChangeSpy, firstTabLink } = await setupTwoTabs();
+
+ component.activeTabIndex = 1;
+ fixture.detectChanges();
+
+ fireEvent.click(firstTabLink);
+
+ expect(handleTabChangeSpy).toHaveBeenCalledWith(0);
+ });
+ });
+
+ describe('More than two tabs', () => {
+ async function setupThreeTabs(overrides = {}) {
+ const tabs = [
+ { name: 'Tab0', fragment: 'tab0' },
+ { name: 'Tab1', fragment: 'tab1' },
+ { name: 'Tab2', fragment: 'tab2' },
+ ];
+
+ const setupTools = await setup({ tabs, ...overrides });
+
+ const thirdTab = setupTools.getByTestId('tab2');
+ const thirdTabLink = within(thirdTab).getByText(tabs[2].name);
+
+ return { ...setupTools, thirdTab, thirdTabLink, tabs };
+ }
+
+ it('should set the third tab as active on load if activeTabIndex passed in as 2', async () => {
+ const { thirdTab, thirdTabLink } = await setupThreeTabs({ activeTabIndex: 2 });
+
+ expect(thirdTab.getAttribute('class')).toContain('asc-tabs__list-item--active');
+ expect(thirdTabLink.getAttribute('class')).toContain('asc-tabs__link--active');
+ });
+
+ it('should set the third tab as active after clicking third tab', async () => {
+ const { fixture, thirdTab, thirdTabLink } = await setupThreeTabs({ activeTabIndex: 0 });
+
+ fireEvent.click(thirdTabLink);
+ fixture.detectChanges();
+
+ expect(thirdTab.getAttribute('class')).toContain('asc-tabs__list-item--active');
+ expect(thirdTabLink.getAttribute('class')).toContain('asc-tabs__link--active');
+ });
+
+ it('should emit handleTabChange with third index (2) when third tab is clicked', async () => {
+ const { thirdTabLink, handleTabChangeSpy } = await setupThreeTabs({ activeTabIndex: 0 });
+
+ fireEvent.click(thirdTabLink);
+
+ expect(handleTabChangeSpy).toHaveBeenCalledWith(2);
+ });
+ });
+});
diff --git a/frontend/src/app/shared/components/select-view-panel/select-view-panel.component.ts b/frontend/src/app/shared/components/select-view-panel/select-view-panel.component.ts
new file mode 100644
index 0000000000..a506b25790
--- /dev/null
+++ b/frontend/src/app/shared/components/select-view-panel/select-view-panel.component.ts
@@ -0,0 +1,18 @@
+import { Component, EventEmitter, Input, Output } from '@angular/core';
+
+@Component({
+ selector: 'app-select-view-panel',
+ templateUrl: './select-view-panel.component.html',
+ styleUrls: ['./select-view-panel.component.scss'],
+})
+export class SelectViewPanelComponent {
+ @Input() tabs: { name: string; fragment: string }[];
+ @Input() activeTabIndex: number = 0;
+ @Output() handleTabChange: EventEmitter = new EventEmitter();
+
+ public handleViewChange(event: Event, index: number): void {
+ event.preventDefault();
+ this.activeTabIndex = index;
+ this.handleTabChange.emit(index);
+ }
+}
diff --git a/frontend/src/app/shared/components/staff-record-summary/basic-record/basic-record.component.html b/frontend/src/app/shared/components/staff-record-summary/basic-record/basic-record.component.html
index 484d507c6b..11242051d0 100644
--- a/frontend/src/app/shared/components/staff-record-summary/basic-record/basic-record.component.html
+++ b/frontend/src/app/shared/components/staff-record-summary/basic-record/basic-record.component.html
@@ -1,11 +1,11 @@
{{ basicTitle }}
-
Name or ID number
-
+ Name or ID number
+
{{ worker.nameOrId }}
@@ -21,62 +21,42 @@ {{ basicTitle }}
Contract type
-
-
- Pool, Bank
-
- {{ worker.contract }}
-
-
-
+
+ Pool, Bank
+
+ {{ worker.contract }}
+
+
-
-
-
Main job role
-
-
-
- {{ worker.mainJob.other }}
-
-
- {{ worker.mainJob.title }}
-
-
-
+
+
+
Main job role
+
+
+ {{ worker.mainJob.other }}
+
+
+ {{ worker.mainJob.title }}
+
{{ basicTitle }}
>
+
diff --git a/frontend/src/app/shared/components/staff-record-summary/basic-record/basic-record.component.ts b/frontend/src/app/shared/components/staff-record-summary/basic-record/basic-record.component.ts
index 784811ada8..08a5f9de27 100644
--- a/frontend/src/app/shared/components/staff-record-summary/basic-record/basic-record.component.ts
+++ b/frontend/src/app/shared/components/staff-record-summary/basic-record/basic-record.component.ts
@@ -13,9 +13,25 @@ export class BasicRecordComponent extends StaffRecordSummaryComponent {
@Input() public canEditWorker: boolean;
@Input() public mandatoryDetailsPage = false;
+ public showWdfConfirmations: any = {
+ contract: null,
+ mainJob: null,
+ };
+
public getMandatoryDetailsRoute(path: string): Array {
if (path) {
return ['/workplace', this.workplaceUid, 'staff-record', this.worker.uid, 'mandatory-details', path];
}
}
+
+ protected setShowWdfConfirmations(): void {
+ this.showWdfConfirmations = {
+ contract: this.showWdfConfirmation('contract'),
+ mainJob: this.showWdfConfirmation('mainJob'),
+ };
+ }
+
+ ngOnChanges(): void {
+ this.setShowWdfConfirmations();
+ }
}
diff --git a/frontend/src/app/shared/components/staff-record-summary/employment/employment.component.html b/frontend/src/app/shared/components/staff-record-summary/employment/employment.component.html
index a540c58f4e..2b8ab58ae9 100644
--- a/frontend/src/app/shared/components/staff-record-summary/employment/employment.component.html
+++ b/frontend/src/app/shared/components/staff-record-summary/employment/employment.component.html
@@ -1,8 +1,8 @@
Employment details
-
+
-
On a Health and Care Worker visa
-
+ On a Health and Care Worker visa
+
{{ worker.healthAndCareVisa | closedEndedAnswer }}
@@ -19,10 +19,8 @@ Employment details
*ngIf="displayEmployedFromOutsideOrInsideUk"
data-testid="employed-inside-or-outside-section"
>
-
- Employed from outside or inside the UK
-
-
+ Employed from outside or inside the UK
+
{{ displayEmployedFromOutsideOrInsideUkValue | closedEndedAnswer }}
@@ -34,38 +32,21 @@ Employment details
>
-
-
Date started in main job role
-
-
- {{ worker.mainJobStartDate ? mainStartDate : '-' }}
-
-
+
+
Date started in main job role
+
+ {{ worker.mainJobStartDate ? mainStartDate : '-' }}
Employment details
>
+
+
Approved Mental Health Professional
-
+
{{ worker.approvedMentalHealthWorker | closedEndedAnswer }}
@@ -91,7 +85,7 @@ Employment details
Nursing and Midwifery Council category
-
+
{{ (worker.registeredNurse | nursingCategoriesText) || '-' }}
@@ -106,7 +100,7 @@ Employment details
Nursing specialisms used in current role
-
+
-
Not using any of their specialisms
Not known
@@ -128,20 +122,19 @@ Employment details
-
+
Recruited from
-
-
- {{
- worker.recruitedFrom?.from?.from !== null
- ? worker.recruitedFrom?.from?.from
- : (worker.recruitedFrom?.value | openEndedAnswer)
- }}
-
+
+ {{
+ worker.recruitedFrom?.from?.from !== null
+ ? worker.recruitedFrom?.from?.from
+ : (worker.recruitedFrom?.value | openEndedAnswer)
+ }}
Employment details
>
+
Year started in adult social care
-
+
{{
worker.socialCareStartDate?.year
? worker.socialCareStartDate?.year
@@ -172,74 +170,58 @@ Employment details
-
-
Days sickness in last 12 months
-
-
+
+
+
Days sickness in last 12 months
+
{{ worker.daysSick | workerDays | openEndedAnswer }}
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
Zero hours contract
-
-
- {{ worker.zeroHoursContract || '-' | closedEndedAnswer }}
-
-
+
+ {{ worker.zeroHoursContract || '-' | closedEndedAnswer }}
Employment details
>
+
+
-
-
Average weekly working hours
-
-
+
+
+
Average weekly working hours
+
{{
isNumber(worker.weeklyHoursAverage?.hours)
? worker.weeklyHoursAverage?.hours
: (worker.weeklyHoursAverage?.value | openEndedAnswer)
}}
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
Contracted weekly hours
-
-
+
+
+
Contracted weekly hours
+
{{
isNumber(worker.weeklyHoursContracted?.hours)
? worker.weeklyHoursContracted?.hours
: (worker.weeklyHoursContracted?.value | openEndedAnswer)
}}
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
Hourly pay or annual salary
-
-
- {{ worker.annualHourlyPay | workerPay | closedEndedAnswer }}
-
-
+
+ {{ worker.annualHourlyPay | workerPay | closedEndedAnswer }}
Employment details
>
+
+
diff --git a/frontend/src/app/shared/components/staff-record-summary/employment/employment.component.ts b/frontend/src/app/shared/components/staff-record-summary/employment/employment.component.ts
index 74a014c82a..68d0358cd7 100644
--- a/frontend/src/app/shared/components/staff-record-summary/employment/employment.component.ts
+++ b/frontend/src/app/shared/components/staff-record-summary/employment/employment.component.ts
@@ -3,6 +3,7 @@ import { Component, Input } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Contracts } from '@core/model/contracts.enum';
import { EthnicityService } from '@core/services/ethnicity.service';
+import { InternationalRecruitmentService } from '@core/services/international-recruitment.service';
import { PermissionsService } from '@core/services/permissions/permissions.service';
import { WdfConfirmFieldsService } from '@core/services/wdf/wdf-confirm-fields.service';
import { WorkerService } from '@core/services/worker.service';
@@ -10,7 +11,6 @@ import dayjs from 'dayjs';
import isNumber from 'lodash/isNumber';
import { StaffRecordSummaryComponent } from '../staff-record-summary.component';
-import { InternationalRecruitmentService } from '@core/services/international-recruitment.service';
@Component({
selector: 'app-employment',
@@ -84,4 +84,23 @@ export class EmploymentComponent extends StaffRecordSummaryComponent {
this.worker.employedFromOutsideUk,
);
}
+
+ public showWdfConfirmations: any = {
+ mainJobStartDate: null,
+ daysSick: null,
+ zeroHoursContract: null,
+ weeklyHoursAverage: null,
+ weeklyHoursContracted: null,
+ annualHourlyPay: null,
+ };
+
+ protected setShowWdfConfirmations(): void {
+ Object.keys(this.showWdfConfirmations).forEach((field) => {
+ this.showWdfConfirmations[field] = this.showWdfConfirmation(field);
+ });
+ }
+
+ ngOnChanges(): void {
+ this.setShowWdfConfirmations();
+ }
}
diff --git a/frontend/src/app/shared/components/staff-record-summary/personal-details/personal-details.component.html b/frontend/src/app/shared/components/staff-record-summary/personal-details/personal-details.component.html
index 2228d4c5ee..926ae5ad4c 100644
--- a/frontend/src/app/shared/components/staff-record-summary/personal-details/personal-details.component.html
+++ b/frontend/src/app/shared/components/staff-record-summary/personal-details/personal-details.component.html
@@ -1,25 +1,24 @@
Personal details
-
-
-
Date of birth
-
-
+
+
+
Date of birth
+
+
+ -
+ {{ dobHidden ? '*********' : dob }}
+
+
-
-
-
-
+
Personal details
>
+
National Insurance number
- -
+ -
-
+
{{ ninoHidden ? '*********' : worker.nationalInsuranceNumber }}
@@ -63,7 +67,7 @@ Personal details
Home postcode
-
+
{{ worker.postcode || '-' }}
@@ -76,17 +80,16 @@ Personal details
-
+
Gender identity
-
-
- {{ worker.gender || '-' | closedEndedAnswer }}
-
+
+ {{ worker.gender || '-' | closedEndedAnswer }}
Personal details
>
+
Disabled
-
+
{{ showDisability || '-' | closedEndedAnswer }}
@@ -115,7 +123,7 @@ Personal details
Ethnic group
-
+
{{ ethnicGroupData || '-' }}
@@ -130,7 +138,7 @@ Personal details
Ethnic background
-
+
{{ ethnicityData || '-' }}
@@ -143,20 +151,19 @@ Personal details
-
+
Nationality
-
-
- {{
- worker.nationality?.other?.nationality !== null
- ? worker.nationality?.other?.nationality
- : (worker.nationality?.value | closedEndedAnswer)
- }}
-
+
+ {{
+ worker.nationality?.other?.nationality !== null
+ ? worker.nationality?.other?.nationality
+ : (worker.nationality?.value | closedEndedAnswer)
+ }}
Personal details
>
+
British citizenship
-
+
{{ worker.britishCitizenship | closedEndedAnswer }}
@@ -185,7 +197,7 @@ Personal details
Country of birth
-
+
{{
worker.countryOfBirth?.other?.country !== null
? worker.countryOfBirth?.other?.country
@@ -204,7 +216,7 @@ Personal details
Year arrived in the UK
-
+
{{ worker.yearArrived?.year ? worker.yearArrived?.year : (worker.yearArrived?.value | openEndedAnswer) }}
diff --git a/frontend/src/app/shared/components/staff-record-summary/qualifications-and-training/qualifications-and-training.component.html b/frontend/src/app/shared/components/staff-record-summary/qualifications-and-training/qualifications-and-training.component.html
index cb4c0834ba..182c7a637c 100644
--- a/frontend/src/app/shared/components/staff-record-summary/qualifications-and-training/qualifications-and-training.component.html
+++ b/frontend/src/app/shared/components/staff-record-summary/qualifications-and-training/qualifications-and-training.component.html
@@ -1,40 +1,20 @@
Training and qualifications
-
-
-
Care Certificate
+
+
+
Care Certificate
-
-
- {{ worker.careCertificate || '-' }}
-
-
+
+ {{ worker.careCertificate || '-' }}
Training and qualifications
>
+
+
-
Level 2 Adult Social Care Certificate
+
Level 2 Adult Social Care Certificate
-
+
{{ worker.level2CareCertificate?.value || '-' }}
@@ -61,7 +54,7 @@ Training and qualifications
Apprenticeship training
-
+
{{ worker.apprenticeshipTraining || '-' | closedEndedAnswer }}
@@ -74,40 +67,21 @@ Training and qualifications
-
+
Has a social care qualification
-
-
- {{ worker.qualificationInSocialCare || '-' | closedEndedAnswer }}
-
-
+
+ {{ worker.qualificationInSocialCare || '-' | closedEndedAnswer }}
Training and qualifications
>
+
+
-
-
Highest level of social care qualification
-
-
+
+
+
Highest level of social care qualification
+
{{ worker.socialCareQualification?.title | closedEndedAnswer }}
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
Other qualifications
-
-
- {{ worker.otherQualification || '-' | closedEndedAnswer }}
-
-
+
+ {{ worker.otherQualification || '-' | closedEndedAnswer }}
Training and qualifications
>
+
+
-
-
Highest level of other qualifications
-
-
+
+
+
Highest level of other qualifications
+
{{ worker.highestQualification?.title || '-' }}
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/frontend/src/app/shared/components/staff-record-summary/qualifications-and-training/qualifications-and-training.component.ts b/frontend/src/app/shared/components/staff-record-summary/qualifications-and-training/qualifications-and-training.component.ts
index 18b37886fa..99a4076b37 100644
--- a/frontend/src/app/shared/components/staff-record-summary/qualifications-and-training/qualifications-and-training.component.ts
+++ b/frontend/src/app/shared/components/staff-record-summary/qualifications-and-training/qualifications-and-training.component.ts
@@ -18,4 +18,38 @@ export class QualificationsAndTrainingComponent extends StaffRecordSummaryCompon
get displayOtherQualifications() {
return this.worker.otherQualification === 'Yes';
}
+
+ public showWdfConfirmations: any = {
+ careCertificate: null,
+ qualificationInSocialCare: null,
+ socialCareQualification: null,
+ otherQualification: null,
+ highestQualification: null,
+ };
+
+ protected setShowWdfConfirmations(): void {
+ this.showWdfConfirmations = {
+ careCertificate: this.showWdfConfirmationForCareCertificate(),
+ qualificationInSocialCare: this.showWdfConfirmationForQualInSocialCare(),
+ socialCareQualification: this.showWdfConfirmation('socialCareQualification'),
+ otherQualification: this.showWdfConfirmationForOtherQualification(),
+ highestQualification: this.showWdfConfirmation('highestQualification'),
+ };
+ }
+
+ ngOnChanges(): void {
+ this.setShowWdfConfirmations();
+ }
+
+ public showWdfConfirmationForCareCertificate(): boolean {
+ return this.showWdfConfirmation('careCertificate') && this.worker.careCertificate !== 'Yes, completed';
+ }
+
+ public showWdfConfirmationForQualInSocialCare(): boolean {
+ return this.showWdfConfirmation('qualificationInSocialCare') && this.worker.qualificationInSocialCare !== 'Yes';
+ }
+
+ public showWdfConfirmationForOtherQualification(): boolean {
+ return this.showWdfConfirmation('otherQualification') && this.worker.otherQualification !== 'Yes';
+ }
}
diff --git a/frontend/src/app/shared/components/staff-record-summary/staff-record-summary.component.html b/frontend/src/app/shared/components/staff-record-summary/staff-record-summary.component.html
index b51650d13b..dfc85e9f89 100644
--- a/frontend/src/app/shared/components/staff-record-summary/staff-record-summary.component.html
+++ b/frontend/src/app/shared/components/staff-record-summary/staff-record-summary.component.html
@@ -1,5 +1,5 @@
{
- const setup = async () => {
- const { fixture, getByText, queryByText, getAllByText } = await render(StaffRecordSummaryComponent, {
- imports: [SharedModule, RouterTestingModule, HttpClientTestingModule, BrowserModule, WdfModule],
- providers: [
- InternationalRecruitmentService,
- {
- provide: PermissionsService,
- useFactory: MockPermissionsService.factory(['canEditWorker']),
- deps: [HttpClient, Router, UserService],
- },
- {
- provide: WorkerService,
- useClass: MockWorkerService,
+ const setup = async (overrides: any = {}) => {
+ const { fixture, getByText, queryByText, getAllByText, getByAltText, getByTestId, queryByTestId } = await render(
+ StaffRecordSummaryComponent,
+ {
+ imports: [SharedModule, RouterTestingModule, HttpClientTestingModule, BrowserModule, WdfModule],
+ providers: [
+ InternationalRecruitmentService,
+ {
+ provide: PermissionsService,
+ useFactory: MockPermissionsService.factory(overrides.permissions ?? ['canEditWorker']),
+ deps: [HttpClient, Router, UserService],
+ },
+ {
+ provide: WorkerService,
+ useClass: MockWorkerService,
+ },
+ WdfConfirmFieldsService,
+ ],
+ componentProperties: {
+ wdfView: overrides.wdfView ?? true,
+ workplace: establishmentBuilder() as Establishment,
+ worker: overrides.worker ?? (workerWithWdf() as Worker),
+ overallWdfEligibility: overrides.overallWdfEligibility ?? false,
},
- WdfConfirmFieldsService,
- ],
- componentProperties: {
- wdfView: true,
- workplace: establishmentBuilder() as Establishment,
- worker: workerWithWdf() as Worker,
},
- });
+ );
const component = fixture.componentInstance;
const injector = getTestBed();
const workerService = injector.inject(WorkerService) as WorkerService;
+ spyOn(workerService, 'updateWorker').and.returnValue(of({ uid: '123' } as WorkerEditResponse));
+
const wdfConfirmFieldsService = injector.inject(WdfConfirmFieldsService) as WdfConfirmFieldsService;
- return { component, fixture, getByText, queryByText, workerService, wdfConfirmFieldsService, getAllByText };
+ return {
+ component,
+ fixture,
+ getByText,
+ queryByText,
+ workerService,
+ wdfConfirmFieldsService,
+ getAllByText,
+ getByAltText,
+ getByTestId,
+ queryByTestId,
+ };
};
const eligibleObject = {
isEligible: Eligibility.YES,
@@ -71,6 +88,24 @@ describe('StaffRecordSummaryComponent', () => {
updatedSinceEffectiveDate: false,
};
+ const buildWorker = (workerOverrides) => {
+ const worker = workerWithWdf() as Worker;
+
+ if (workerOverrides.overrides) {
+ workerOverrides.overrides.forEach((override) => {
+ worker[override.name] = override.response;
+ });
+ }
+
+ if (workerOverrides.wdf) {
+ workerOverrides.wdf.forEach((field) => {
+ worker.wdf[field.name] = field.response;
+ });
+ }
+
+ return worker;
+ };
+
it('should render a StaffRecordSummaryComponent', async () => {
const { component } = await setup();
@@ -80,7 +115,6 @@ describe('StaffRecordSummaryComponent', () => {
describe('updateFieldsWhichDontRequireConfirmation()', () => {
it('should update worker if there are auto fields which have not been updated and are eligible', async () => {
const { component, fixture, workerService } = await setup();
- spyOn(workerService, 'updateWorker').and.returnValue(of({ uid: '123' } as WorkerEditResponse));
component.worker.wdf.dateOfBirth = eligibleButNotUpdatedObject;
@@ -92,7 +126,6 @@ describe('StaffRecordSummaryComponent', () => {
it('should NOT auto update the worker when confirm field is called after all fields are updated and eligible', async () => {
const { component, fixture, workerService } = await setup();
- spyOn(workerService, 'updateWorker').and.returnValue(of({ uid: '123' } as WorkerEditResponse));
component.worker.wdf.dateOfBirth = eligibleObject;
fixture.detectChanges();
@@ -107,7 +140,6 @@ describe('StaffRecordSummaryComponent', () => {
it('should update the worker for careCertificate if its Yes, completed and not updated', async () => {
const { component, fixture, workerService } = await setup();
- spyOn(workerService, 'updateWorker').and.returnValue(of({ uid: '123' } as WorkerEditResponse));
component.worker.wdf.careCertificate = eligibleButNotUpdatedObject;
component.worker.careCertificate = 'Yes, completed';
@@ -122,7 +154,6 @@ describe('StaffRecordSummaryComponent', () => {
it('should NOT update the worker for careCertificate if it is No and not updated', async () => {
const { component, fixture, workerService } = await setup();
- spyOn(workerService, 'updateWorker').and.returnValue(of({ uid: '123' } as WorkerEditResponse));
component.worker.wdf.careCertificate = eligibleButNotUpdatedObject;
component.worker.careCertificate = 'No';
@@ -138,7 +169,6 @@ describe('StaffRecordSummaryComponent', () => {
it('should update the worker for qualificationInSocialCare if it is Yes and not updated', async () => {
const { component, fixture, workerService } = await setup();
- spyOn(workerService, 'updateWorker').and.returnValue(of({ uid: '123' } as WorkerEditResponse));
component.worker.wdf.qualificationInSocialCare = eligibleButNotUpdatedObject;
component.worker.qualificationInSocialCare = 'Yes';
@@ -154,7 +184,6 @@ describe('StaffRecordSummaryComponent', () => {
it('should NOT update the worker for qualificationInSocialCare if it is NO and not updated', async () => {
const { component, fixture, workerService } = await setup();
- spyOn(workerService, 'updateWorker').and.returnValue(of({ uid: '123' } as WorkerEditResponse));
component.worker.wdf.qualificationInSocialCare = eligibleButNotUpdatedObject;
component.worker.qualificationInSocialCare = 'NO';
@@ -212,667 +241,339 @@ describe('StaffRecordSummaryComponent', () => {
});
});
- it('should show WdfFieldConfirmation component when is eligible but needs to be confirmed for Date Started', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.mainJobStartDate.isEligible = Eligibility.YES;
- component.worker.wdf.mainJobStartDate.updatedSinceEffectiveDate = false;
- component.worker.mainJobStartDate = '2020-01-12';
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should not show WdfFieldConfirmation component when fields do not need to be confirmed', async () => {
- const { queryByText } = await setup();
-
- expect(queryByText('Is this still correct?', { exact: false })).toBeFalsy();
- expect(queryByText('Yes, it is')).toBeFalsy();
- expect(queryByText('No, change it')).toBeFalsy();
- });
-
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Date Started', async () => {
- const { component, fixture, getByText } = await setup();
-
- const workerService = TestBed.inject(WorkerService);
- spyOn(workerService, 'updateWorker').and.returnValue(of(null));
-
- component.worker.wdf.mainJobStartDate.isEligible = Eligibility.YES;
- component.worker.wdf.mainJobStartDate.updatedSinceEffectiveDate = false;
- component.worker.mainJobStartDate = '2020-01-12';
-
- fixture.detectChanges();
-
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
-
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
-
- it('should show WdfFieldConfirmation component when is eligible but needs to be confirmed for Sickness in last 12 Months', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.daysSick.isEligible = Eligibility.YES;
- component.worker.wdf.daysSick.updatedSinceEffectiveDate = false;
- component.worker.contract = Contracts.Permanent;
- const myWorkerDay: WorkerDays = {
- days: 4,
- value: null,
- };
- component.worker.daysSick = myWorkerDay;
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Sickness in the last 12 months', async () => {
- const { component, fixture, getByText } = await setup();
-
- const workerService = TestBed.inject(WorkerService);
- spyOn(workerService, 'updateWorker').and.returnValue(of(null));
-
- component.worker.wdf.daysSick.isEligible = Eligibility.YES;
- component.worker.wdf.daysSick.updatedSinceEffectiveDate = false;
- component.worker.contract = Contracts.Permanent;
- const myWorkerDay: WorkerDays = {
- days: 4,
- value: null,
+ describe('WdfFieldConfirmation', () => {
+ const buildWorkerWithFieldNotUpdatedSinceEffectiveDate = (fields) => {
+ return buildWorker({
+ overrides: fields,
+ wdf: [
+ {
+ name: fields[0].name,
+ response: {
+ isEligible: Eligibility.YES,
+ updatedSinceEffectiveDate: false,
+ },
+ },
+ ],
+ });
};
- component.worker.daysSick = myWorkerDay;
-
- fixture.detectChanges();
-
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
-
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
-
- it('should show WdfFieldConfirmation component when is eligible but needs to be confirmed for Zero hours contracts', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.zeroHoursContract.isEligible = Eligibility.YES;
- component.worker.wdf.zeroHoursContract.updatedSinceEffectiveDate = false;
- component.worker.zeroHoursContract = 'Yes';
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Zero hour contracts', async () => {
- const { component, fixture, getByText } = await setup();
-
- const workerService = TestBed.inject(WorkerService);
- spyOn(workerService, 'updateWorker').and.returnValue(of(null));
-
- component.worker.wdf.zeroHoursContract.isEligible = Eligibility.YES;
- component.worker.wdf.zeroHoursContract.updatedSinceEffectiveDate = false;
- component.worker.zeroHoursContract = 'Yes';
-
- fixture.detectChanges();
-
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
-
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
-
- it('should show WdfFieldConfirmation component when is eligible but needs to be confirmed for Contracted weekly hours', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.weeklyHoursContracted.isEligible = Eligibility.YES;
- component.worker.wdf.weeklyHoursContracted.updatedSinceEffectiveDate = false;
- component.worker.weeklyHoursContracted = { value: 'Yes', hours: 30 };
- component.worker.contract = Contracts.Permanent;
- component.worker.zeroHoursContract = 'No';
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Contracted weekly hours', async () => {
- const { component, fixture, getByText } = await setup();
-
- const workerService = TestBed.inject(WorkerService);
- spyOn(workerService, 'updateWorker').and.returnValue(of(null));
-
- component.worker.wdf.weeklyHoursContracted.isEligible = Eligibility.YES;
- component.worker.wdf.weeklyHoursContracted.updatedSinceEffectiveDate = false;
- component.worker.weeklyHoursContracted = { value: 'Yes', hours: 30 };
- component.worker.contract = Contracts.Permanent;
- component.worker.zeroHoursContract = 'No';
-
- fixture.detectChanges();
-
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
-
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
-
- it('should show WdfFieldConfirmation component when is eligible but needs to be confirmed for Average weekly working hours', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.weeklyHoursAverage.isEligible = Eligibility.YES;
- component.worker.wdf.weeklyHoursAverage.updatedSinceEffectiveDate = false;
- component.worker.zeroHoursContract = 'Yes';
- component.worker.weeklyHoursAverage = { value: 'Yes', hours: 30 };
- component.worker.contract = Contracts.Agency;
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Average weekly working hours', async () => {
- const { component, fixture, getByText } = await setup();
-
- const workerService = TestBed.inject(WorkerService);
- spyOn(workerService, 'updateWorker').and.returnValue(of(null));
-
- component.worker.wdf.weeklyHoursAverage.isEligible = Eligibility.YES;
- component.worker.wdf.weeklyHoursAverage.updatedSinceEffectiveDate = false;
- component.worker.zeroHoursContract = 'Yes';
- component.worker.weeklyHoursAverage = { value: 'Yes', hours: 30 };
- component.worker.contract = Contracts.Agency;
-
- fixture.detectChanges();
-
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
-
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
-
- it('should show WdfFieldConfirmation component when is eligible but needs to be confirmed for Salary', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.annualHourlyPay.isEligible = Eligibility.YES;
- component.worker.wdf.annualHourlyPay.updatedSinceEffectiveDate = false;
- component.worker.annualHourlyPay = { value: 'Annually', rate: 24000 };
- component.worker.contract = Contracts.Permanent;
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Salary', async () => {
- const { component, fixture, getByText } = await setup();
-
- const workerService = TestBed.inject(WorkerService);
- spyOn(workerService, 'updateWorker').and.returnValue(of(null));
-
- component.worker.wdf.annualHourlyPay.isEligible = Eligibility.YES;
- component.worker.wdf.annualHourlyPay.updatedSinceEffectiveDate = false;
- component.worker.annualHourlyPay = { value: 'Annually', rate: 24000 };
- component.worker.contract = Contracts.Permanent;
-
- fixture.detectChanges();
-
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
-
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
-
- it('should show WdfFieldConfirmation component when is eligible but needs to be confirmed for Main Job Role', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.mainJob.isEligible = Eligibility.YES;
- component.worker.wdf.mainJob.updatedSinceEffectiveDate = false;
- component.worker.mainJob = { jobId: 10, title: 'Care Worker' };
- component.worker.contract = Contracts.Permanent;
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Main Job Role', async () => {
- const { component, fixture, getByText } = await setup();
-
- const workerService = TestBed.inject(WorkerService);
- spyOn(workerService, 'updateWorker').and.returnValue(of(null));
-
- component.worker.wdf.mainJob.isEligible = Eligibility.YES;
- component.worker.wdf.mainJob.updatedSinceEffectiveDate = false;
- component.worker.mainJob = { jobId: 10, title: 'Care Worker' };
- component.worker.contract = Contracts.Permanent;
-
- fixture.detectChanges();
-
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
-
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
-
- it('should show WdfFieldConfirmation component when is eligible but needs to be confirmed for Contract', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.contract.isEligible = Eligibility.YES;
- component.worker.wdf.contract.updatedSinceEffectiveDate = false;
- component.worker.contract = Contracts.Permanent;
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Contract', async () => {
- const { component, fixture, getByText } = await setup();
-
- const workerService = TestBed.inject(WorkerService);
- spyOn(workerService, 'updateWorker').and.returnValue(of(null));
-
- component.worker.wdf.contract.isEligible = Eligibility.YES;
- component.worker.wdf.contract.updatedSinceEffectiveDate = false;
- component.worker.contract = Contracts.Permanent;
-
- fixture.detectChanges();
-
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
-
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
-
- it('should show WdfFieldConfirmation component when is eligible but needs to be confirmed for Highest level of social care qualification', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.socialCareQualification.isEligible = Eligibility.YES;
- component.worker.wdf.socialCareQualification.updatedSinceEffectiveDate = false;
- component.worker.qualificationInSocialCare = 'Yes';
- component.worker.socialCareQualification = { qualificationId: 4, title: 'Level 3' };
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Highest level of social care qualification', async () => {
- const { component, fixture, getByText } = await setup();
-
- const workerService = TestBed.inject(WorkerService);
- spyOn(workerService, 'updateWorker').and.returnValue(of(null));
-
- component.worker.wdf.socialCareQualification.isEligible = Eligibility.YES;
- component.worker.wdf.socialCareQualification.updatedSinceEffectiveDate = false;
- component.worker.qualificationInSocialCare = 'Yes';
- component.worker.socialCareQualification = { qualificationId: 4, title: 'Level 3' };
-
- fixture.detectChanges();
-
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
-
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
-
- it('should show WdfFieldConfirmation component when is eligible, set to no but needs to be confirmed for Any social care qualification', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.qualificationInSocialCare.isEligible = Eligibility.YES;
- component.worker.wdf.qualificationInSocialCare.updatedSinceEffectiveDate = false;
- component.worker.qualificationInSocialCare = 'No';
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it("should show WdfFieldConfirmation component when is eligible, set to Don't know but needs to be confirmed for Any social care qualification", async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.qualificationInSocialCare.isEligible = Eligibility.YES;
- component.worker.wdf.qualificationInSocialCare.updatedSinceEffectiveDate = false;
- component.worker.qualificationInSocialCare = "Don't know";
- fixture.detectChanges();
+ it('should not show WdfFieldConfirmation component when fields do not need to be confirmed', async () => {
+ const { queryByText } = await setup();
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should not show WdfFieldConfirmation component when is eligible and needs to be confirmed but is set to Yes for Any social care qualification', async () => {
- const { component, fixture, queryByText } = await setup();
-
- component.worker.wdf.qualificationInSocialCare.isEligible = Eligibility.YES;
- component.worker.wdf.qualificationInSocialCare.updatedSinceEffectiveDate = false;
- component.worker.qualificationInSocialCare = 'Yes';
-
- fixture.detectChanges();
-
- expect(queryByText('Is this still correct?')).toBeFalsy();
- expect(queryByText('Yes, it is')).toBeFalsy();
- expect(queryByText('No, change it')).toBeFalsy();
- });
-
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Any social care qualification', async () => {
- const { component, fixture, getByText } = await setup();
-
- const workerService = TestBed.inject(WorkerService);
- spyOn(workerService, 'updateWorker').and.returnValue(of(null));
-
- component.worker.wdf.qualificationInSocialCare.isEligible = Eligibility.YES;
- component.worker.wdf.qualificationInSocialCare.updatedSinceEffectiveDate = false;
- component.worker.qualificationInSocialCare = "Don't know";
-
- fixture.detectChanges();
-
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
-
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
-
- describe('Field confirmation for Started or completed Care Certificate', () => {
- it('should show WdfFieldConfirmation component when is eligible(set to No) but needs to be confirmed for Started or completed Care Certificate', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.careCertificate.isEligible = Eligibility.YES;
- component.worker.wdf.careCertificate.updatedSinceEffectiveDate = false;
- component.worker.careCertificate = 'No';
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should show WdfFieldConfirmation component when is eligible(set to Yes, in progress or partially completed) but needs to be confirmed for Started or completed Care Certificate', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.careCertificate.isEligible = Eligibility.YES;
- component.worker.wdf.careCertificate.updatedSinceEffectiveDate = false;
- component.worker.careCertificate = 'Yes, in progress or partially completed';
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should not show WdfFieldConfirmation component when is eligible and needs to be confirmed but is set to Yes for Any social care qualification', async () => {
- const { component, fixture, queryByText } = await setup();
-
- component.worker.wdf.careCertificate.isEligible = Eligibility.YES;
- component.worker.wdf.careCertificate.updatedSinceEffectiveDate = false;
- component.worker.careCertificate = 'Yes, completed';
-
- fixture.detectChanges();
-
- expect(queryByText('Is this still correct?')).toBeFalsy();
- expect(queryByText('Yes, it is')).toBeFalsy();
- expect(queryByText('No, change it')).toBeFalsy();
- });
-
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Started or completed Care Certificate', async () => {
- const { component, fixture, getByText } = await setup();
-
- const workerService = TestBed.inject(WorkerService);
- spyOn(workerService, 'updateWorker').and.returnValue(of(null));
-
- component.worker.wdf.careCertificate.isEligible = Eligibility.YES;
- component.worker.wdf.careCertificate.updatedSinceEffectiveDate = false;
- component.worker.careCertificate = 'No';
-
- fixture.detectChanges();
-
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
-
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
- });
-
- describe('Field confirmation for Non-social care qualification', () => {
- it('should show WdfFieldConfirmation component when is eligible(set to No) but needs to be confirmed for Non-social care qualification', async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.otherQualification.isEligible = Eligibility.YES;
- component.worker.wdf.otherQualification.updatedSinceEffectiveDate = false;
- component.worker.otherQualification = 'No';
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it("should show WdfFieldConfirmation component when is eligible(set to Don't know) but needs to be confirmed for Non-social care qualification", async () => {
- const { component, fixture, getByText } = await setup();
-
- component.worker.wdf.otherQualification.isEligible = Eligibility.YES;
- component.worker.wdf.otherQualification.updatedSinceEffectiveDate = false;
- component.worker.otherQualification = "Don't know";
-
- fixture.detectChanges();
-
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
- });
-
- it('should not show WdfFieldConfirmation component when is eligible and needs to be confirmed but is set to Yes for Non-social care qualification', async () => {
- const { component, fixture, queryByText } = await setup();
-
- component.worker.wdf.otherQualification.isEligible = Eligibility.YES;
- component.worker.wdf.otherQualification.updatedSinceEffectiveDate = false;
- component.worker.otherQualification = 'Yes';
-
- fixture.detectChanges();
-
- expect(queryByText('Is this still correct?')).toBeFalsy();
+ expect(queryByText('Is this still correct?', { exact: false })).toBeFalsy();
expect(queryByText('Yes, it is')).toBeFalsy();
expect(queryByText('No, change it')).toBeFalsy();
});
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Non-social care qualification', async () => {
- const { component, fixture, getByText } = await setup();
-
- const workerService = TestBed.inject(WorkerService);
- spyOn(workerService, 'updateWorker').and.returnValue(of(null));
-
- component.worker.wdf.otherQualification.isEligible = Eligibility.YES;
- component.worker.wdf.otherQualification.updatedSinceEffectiveDate = false;
- component.worker.otherQualification = 'No';
+ [
+ {
+ name: 'Main job role',
+ fields: [
+ { name: 'mainJob', response: { jobId: 10, title: 'Care Worker' } },
+ { name: 'contract', response: Contracts.Permanent },
+ ],
+ },
+ {
+ name: 'Contract type',
+ fields: [{ name: 'contract', response: Contracts.Permanent }],
+ },
+ {
+ name: 'Date started in main job role',
+ fields: [{ name: 'mainJobStartDate', response: '2020-01-12' }],
+ },
+ {
+ name: 'Days sickness in last 12 months',
+ fields: [
+ {
+ name: 'daysSick',
+ response: {
+ days: 4,
+ value: null,
+ } as WorkerDays,
+ },
+ { name: 'contract', response: Contracts.Permanent },
+ ],
+ },
+ {
+ name: 'Zero hours contract',
+ fields: [
+ {
+ name: 'zeroHoursContract',
+ response: 'Yes',
+ },
+ ],
+ },
+ {
+ name: 'Highest level of social care qualification',
+ fields: [
+ {
+ name: 'socialCareQualification',
+ response: { qualificationId: 4, title: 'Level 3' },
+ },
+ {
+ name: 'qualificationInSocialCare',
+ response: 'Yes',
+ },
+ ],
+ },
+ {
+ name: 'Has a social care qualification when answer No',
+ fields: [
+ {
+ name: 'qualificationInSocialCare',
+ response: 'No',
+ },
+ ],
+ },
+ {
+ name: "Has a social care qualification when answer Don't know",
+ fields: [
+ {
+ name: 'qualificationInSocialCare',
+ response: "Don't know",
+ },
+ ],
+ },
+ {
+ name: "Started or completed Care Certificate when answered 'No'",
+ fields: [
+ {
+ name: 'careCertificate',
+ response: 'No',
+ },
+ ],
+ },
+ {
+ name: "Started or completed Care Certificate when answered 'Yes, in progress or partially completed'",
+ fields: [
+ {
+ name: 'careCertificate',
+ response: 'Yes, in progress or partially completed',
+ },
+ ],
+ },
+ {
+ name: 'Highest level of non-social care qualification',
+ fields: [
+ {
+ name: 'highestQualification',
+ response: { qualificationId: 5, title: 'Level 4' },
+ },
+ {
+ name: 'otherQualification',
+ response: 'Yes',
+ },
+ ],
+ },
+ {
+ name: 'Salary',
+ fields: [
+ {
+ name: 'annualHourlyPay',
+ response: { value: 'Annually', rate: 24000 },
+ },
+ {
+ name: 'contract',
+ response: Contracts.Permanent,
+ },
+ ],
+ },
+ {
+ name: 'Average weekly working hours',
+ fields: [
+ {
+ name: 'weeklyHoursAverage',
+ response: { value: 'Yes', hours: 30 },
+ },
+ {
+ name: 'contract',
+ response: Contracts.Agency,
+ },
+ {
+ name: 'zeroHoursContract',
+ response: 'Yes',
+ },
+ ],
+ },
+ {
+ name: 'Contracted weekly hours',
+ fields: [
+ {
+ name: 'weeklyHoursContracted',
+ response: { value: 'Yes', hours: 30 },
+ },
+ {
+ name: 'contract',
+ response: Contracts.Permanent,
+ },
+ {
+ name: 'zeroHoursContract',
+ response: 'No',
+ },
+ ],
+ },
+ {
+ name: "Non-social care qualification when answered 'No'",
+ fields: [
+ {
+ name: 'otherQualification',
+ response: 'No',
+ },
+ ],
+ },
+ {
+ name: "Non-social care qualification when answered 'Don't know'",
+ fields: [
+ {
+ name: 'otherQualification',
+ response: "Don't know",
+ },
+ ],
+ },
+ ].forEach((scenario) => {
+ describe(scenario.name, () => {
+ const worker = buildWorkerWithFieldNotUpdatedSinceEffectiveDate(scenario.fields);
- fixture.detectChanges();
+ it('should display when is eligible but needs to be confirmed', async () => {
+ const { queryByText } = await setup({ worker });
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
+ expect(queryByText('Is this still correct?')).toBeTruthy();
+ expect(queryByText('Yes, it is')).toBeTruthy();
+ expect(queryByText('No, change it')).toBeTruthy();
+ });
- fixture.detectChanges();
+ it("should show meeting requirements message when 'Yes it is' is clicked", async () => {
+ const { fixture, queryByText } = await setup({ worker });
- expect(getByText('Meeting requirements')).toBeTruthy();
- });
- });
+ const yesItIsButton = queryByText('Yes, it is', { exact: false });
+ yesItIsButton.click();
- describe('Field confirmation for Highest level of non-social care qualification', () => {
- it('should show WdfFieldConfirmation component when is eligible but needs to be confirmed for Highest level of non-social care qualification', async () => {
- const { component, fixture, getByText } = await setup();
+ fixture.detectChanges();
- component.worker.otherQualification = 'Yes';
- component.worker.highestQualification = { qualificationId: 5, title: 'Level 4' };
- component.worker.wdf.highestQualification.isEligible = Eligibility.YES;
- component.worker.wdf.highestQualification.updatedSinceEffectiveDate = false;
+ expect(queryByText('Meeting requirements')).toBeTruthy();
+ });
- fixture.detectChanges();
+ it('should not display when user does not have edit permissions', async () => {
+ const { queryByText } = await setup({ worker, permissions: [] });
- expect(getByText('Is this still correct?')).toBeTruthy();
- expect(getByText('Yes, it is')).toBeTruthy();
- expect(getByText('No, change it')).toBeTruthy();
+ expect(queryByText('Is this still correct?', { exact: false })).toBeFalsy();
+ expect(queryByText('Yes, it is')).toBeFalsy();
+ expect(queryByText('No, change it')).toBeFalsy();
+ });
+ });
});
- it('should show meeting requirements message in WdfFieldConfirmation when Yes it is is clicked for Highest level of non-social care qualification', async () => {
- const { component, fixture, getByText } = await setup();
-
- const workerService = TestBed.inject(WorkerService);
- spyOn(workerService, 'updateWorker').and.returnValue(of(null));
+ describe('Responses where confirmation is not required', () => {
+ it("should not show when 'Has a social care qualification' is set to Yes", async () => {
+ const { queryByText } = await setup({
+ worker: buildWorkerWithFieldNotUpdatedSinceEffectiveDate([
+ { name: 'qualificationInSocialCare', response: 'Yes' },
+ ]),
+ });
+
+ expect(queryByText('Is this still correct?')).toBeFalsy();
+ expect(queryByText('Yes, it is')).toBeFalsy();
+ expect(queryByText('No, change it')).toBeFalsy();
+ });
- component.worker.otherQualification = 'Yes';
- component.worker.highestQualification = { qualificationId: 5, title: 'Level 4' };
- component.worker.wdf.highestQualification.isEligible = Eligibility.YES;
- component.worker.wdf.highestQualification.updatedSinceEffectiveDate = false;
+ it("should not show when Care Certificate answered with 'Yes, completed'", async () => {
+ const { queryByText } = await setup({
+ worker: buildWorkerWithFieldNotUpdatedSinceEffectiveDate([
+ { name: 'careCertificate', response: 'Yes, completed' },
+ ]),
+ });
- fixture.detectChanges();
+ expect(queryByText('Is this still correct?')).toBeFalsy();
+ expect(queryByText('Yes, it is')).toBeFalsy();
+ expect(queryByText('No, change it')).toBeFalsy();
+ });
- const yesItIsButton = getByText('Yes, it is', { exact: false });
- yesItIsButton.click();
+ it('should not show when Non-social care qualification is set to Yes', async () => {
+ const { queryByText } = await setup({
+ worker: buildWorkerWithFieldNotUpdatedSinceEffectiveDate([{ name: 'otherQualification', response: 'Yes' }]),
+ });
- fixture.detectChanges();
-
- expect(getByText('Meeting requirements')).toBeTruthy();
+ expect(queryByText('Is this still correct?')).toBeFalsy();
+ expect(queryByText('Yes, it is')).toBeFalsy();
+ expect(queryByText('No, change it')).toBeFalsy();
+ });
});
});
- describe('Permission check for workers who do not have permission to edit fields', () => {
- it('when a user does not have edit permissions then they should not see the Wdf Field Confirmation component for basic record fields', async () => {
- const { component, fixture, queryByText } = await setup();
-
- component.worker.wdf.mainJob.isEligible = Eligibility.YES;
- component.worker.wdf.mainJob.updatedSinceEffectiveDate = false;
- component.worker.mainJob = { jobId: 10, title: 'Care Worker' };
-
- component.worker.contract = Contracts.Permanent;
- component.worker.wdf.contract.isEligible = Eligibility.YES;
- component.worker.wdf.contract.updatedSinceEffectiveDate = false;
-
- component.canEditWorker = false;
-
- fixture.detectChanges();
-
- expect(queryByText('Is this still correct?', { exact: false })).toBeFalsy();
- expect(queryByText('Yes, it is')).toBeFalsy();
- expect(queryByText('No, change it')).toBeFalsy();
- });
-
- it('when a user does not have edit permissions then they should not see the Wdf Field Confirmation component for employment fields', async () => {
- const { component, fixture, queryByText } = await setup();
-
- component.worker.contract = Contracts.Permanent;
- component.worker.wdf.daysSick.isEligible = Eligibility.YES;
- component.worker.wdf.daysSick.updatedSinceEffectiveDate = false;
- const myWorkerDay: WorkerDays = {
- days: 4,
- value: null,
- };
- component.worker.daysSick = myWorkerDay;
-
- component.worker.wdf.weeklyHoursContracted.isEligible = Eligibility.YES;
- component.worker.wdf.weeklyHoursContracted.updatedSinceEffectiveDate = false;
- component.worker.weeklyHoursContracted = { value: 'Yes', hours: 30 };
-
- component.worker.wdf.annualHourlyPay.isEligible = Eligibility.YES;
- component.worker.wdf.annualHourlyPay.updatedSinceEffectiveDate = false;
- component.worker.annualHourlyPay = { value: 'Annually', rate: 24000 };
-
- component.canEditWorker = false;
+ describe('Add information messages for WDF', () => {
+ [
+ { name: 'dateOfBirth', validResponse: '01/01/1999' },
+ { name: 'gender', validResponse: 'Male' },
+ { name: 'nationality', validResponse: { value: 'British' } },
+ { name: 'mainJobStartDate', validResponse: '01/01/2021' },
+ { name: 'recruitedFrom', validResponse: 'Agency' },
+ { name: 'daysSick', validResponse: 3, overrides: [{ name: 'contract', response: Contracts.Permanent }] },
+ { name: 'zeroHoursContract', validResponse: 'Yes' },
+ { name: 'weeklyHoursAverage', validResponse: 35, overrides: [{ name: 'zeroHoursContract', response: 'Yes' }] },
+ { name: 'annualHourlyPay', validResponse: { value: 'Annually' } },
+ { name: 'careCertificate', validResponse: { value: 'Yes, completed' } },
+ { name: 'qualificationInSocialCare', validResponse: 'Yes' },
+ {
+ name: 'socialCareQualification',
+ validResponse: 'Level 4',
+ overrides: [{ name: 'qualificationInSocialCare', response: 'Yes' }],
+ },
+ { name: 'otherQualification', validResponse: 'Yes' },
+ {
+ name: 'highestQualification',
+ validResponse: 'Level 4',
+ overrides: [{ name: 'otherQualification', response: 'Yes' }],
+ },
+ ].forEach((field) => {
+ it(`should show 'Add this information' message when worker is not eligible and needs to add ${field.name}`, async () => {
+ const worker = buildWorker(field);
+ worker[field.name] = null;
+ worker.wdf[field.name].isEligible = Eligibility.NO;
- fixture.detectChanges();
+ const { getByTestId } = await setup({ worker });
- expect(queryByText('Is this still correct?', { exact: false })).toBeFalsy();
- expect(queryByText('Yes, it is')).toBeFalsy();
- expect(queryByText('No, change it')).toBeFalsy();
- });
+ const wdfWarningSection = getByTestId(field.name + 'WdfWarning');
- it('when a user does not have edit permissions then they should not see the Wdf Field Confirmation component for employment fields with zero hours', async () => {
- const { component, fixture, queryByText } = await setup();
+ expect(within(wdfWarningSection).getByText('Add this information')).toBeTruthy();
+ expect(within(wdfWarningSection).getByAltText('Red flag icon')).toBeTruthy();
+ });
- component.worker.wdf.weeklyHoursAverage.isEligible = Eligibility.YES;
- component.worker.wdf.weeklyHoursAverage.updatedSinceEffectiveDate = false;
- component.worker.zeroHoursContract = 'Yes';
- component.worker.weeklyHoursAverage = { value: 'Yes', hours: 30 };
- component.worker.contract = Contracts.Agency;
+ it(`should not show 'Add this information' message when worker is not eligible but has added ${field.name}`, async () => {
+ const worker = buildWorker(field);
+ worker[field.name] = field.validResponse;
+ worker.wdf[field.name].isEligible = Eligibility.YES;
- component.canEditWorker = false;
+ const { queryByTestId } = await setup({ worker });
- fixture.detectChanges();
+ const wdfWarningSection = queryByTestId(field.name + 'WdfWarning');
- expect(queryByText('Is this still correct?', { exact: false })).toBeFalsy();
- expect(queryByText('Yes, it is')).toBeFalsy();
- expect(queryByText('No, change it')).toBeFalsy();
- });
+ expect(wdfWarningSection).toBeFalsy();
+ });
- it('when a user does not have edit permissions then they should not see the Wdf Field Confirmation component for qualification fields', async () => {
- const { component, fixture, queryByText } = await setup();
+ it(`should not show 'Add this information' message when worker does not have ${field.name} added but not in WDF view`, async () => {
+ const worker = buildWorker(field);
+ worker[field.name] = null;
+ worker.wdf[field.name].isEligible = Eligibility.NO;
- component.worker.wdf.socialCareQualification.isEligible = Eligibility.YES;
- component.worker.wdf.socialCareQualification.updatedSinceEffectiveDate = false;
- component.worker.qualificationInSocialCare = 'Yes';
- component.worker.socialCareQualification = { qualificationId: 4, title: 'Level 3' };
+ const { queryByTestId } = await setup({ worker, wdfView: false });
- component.worker.wdf.careCertificate.isEligible = Eligibility.YES;
- component.worker.wdf.careCertificate.updatedSinceEffectiveDate = false;
- component.worker.careCertificate = 'No';
+ const wdfWarningSection = queryByTestId(field.name + 'WdfWarning');
- component.worker.wdf.otherQualification.isEligible = Eligibility.YES;
- component.worker.wdf.otherQualification.updatedSinceEffectiveDate = false;
- component.worker.otherQualification = 'Yes';
+ expect(wdfWarningSection).toBeFalsy();
+ });
- component.worker.highestQualification = { qualificationId: 5, title: 'Level 4' };
- component.worker.wdf.highestQualification.isEligible = Eligibility.YES;
- component.worker.wdf.highestQualification.updatedSinceEffectiveDate = false;
+ it(`should show 'Add this information' and orange flag when worker does not have ${field.name} added but workplace has met WDF eligibility`, async () => {
+ const worker = buildWorker(field);
+ worker[field.name] = null;
+ worker.wdf[field.name].isEligible = Eligibility.NO;
- component.canEditWorker = false;
+ const { getByTestId } = await setup({ worker, overallWdfEligibility: true });
- fixture.detectChanges();
+ const wdfWarningSection = getByTestId(field.name + 'WdfWarning');
- expect(queryByText('Is this still correct?', { exact: false })).toBeFalsy();
- expect(queryByText('Yes, it is')).toBeFalsy();
- expect(queryByText('No, change it')).toBeFalsy();
+ expect(within(wdfWarningSection).queryByText('Add this information')).toBeTruthy();
+ expect(within(wdfWarningSection).getByAltText('Orange flag icon')).toBeTruthy();
+ });
});
});
diff --git a/frontend/src/app/shared/components/staff-record-summary/staff-record-summary.component.ts b/frontend/src/app/shared/components/staff-record-summary/staff-record-summary.component.ts
index 7c5469e98c..a1ba795efd 100644
--- a/frontend/src/app/shared/components/staff-record-summary/staff-record-summary.component.ts
+++ b/frontend/src/app/shared/components/staff-record-summary/staff-record-summary.component.ts
@@ -2,6 +2,7 @@ import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angu
import { ActivatedRoute } from '@angular/router';
import { Establishment } from '@core/model/establishment.model';
import { Ethnicity } from '@core/model/ethnicity.model';
+import { Eligibility } from '@core/model/wdf.model';
import { Worker } from '@core/model/worker.model';
import { EthnicityService } from '@core/services/ethnicity.service';
import { InternationalRecruitmentService } from '@core/services/international-recruitment.service';
@@ -38,6 +39,7 @@ export class StaffRecordSummaryComponent implements OnInit, OnDestroy {
public ethnicGroupData: string;
public ethnicityData: string;
private ethnicityObject: Ethnicity;
+ public Eligibility = Eligibility;
constructor(
private permissionsService: PermissionsService,
@@ -214,4 +216,13 @@ export class StaffRecordSummaryComponent implements OnInit, OnDestroy {
await this.workerService.updateWorker(this.workplace.uid, this.worker.uid, props).toPromise();
this.allFieldsConfirmed.emit();
}
+
+ public showWdfConfirmation(field: string): boolean {
+ return (
+ this.canEditWorker &&
+ this.wdfView &&
+ this.worker.wdf?.[field].isEligible === 'Yes' &&
+ !this.worker.wdf?.[field].updatedSinceEffectiveDate
+ );
+ }
}
diff --git a/frontend/src/app/shared/components/staff-record-summary/wdf-warning-message/wdf-warning-message.component.html b/frontend/src/app/shared/components/staff-record-summary/wdf-warning-message/wdf-warning-message.component.html
new file mode 100644
index 0000000000..e670a144a6
--- /dev/null
+++ b/frontend/src/app/shared/components/staff-record-summary/wdf-warning-message/wdf-warning-message.component.html
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+ {{ warningMessage ?? 'Add this information' }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/app/shared/components/staff-record-summary/wdf-warning-message/wdf-warning-message.component.scss b/frontend/src/app/shared/components/staff-record-summary/wdf-warning-message/wdf-warning-message.component.scss
new file mode 100644
index 0000000000..560171ce12
--- /dev/null
+++ b/frontend/src/app/shared/components/staff-record-summary/wdf-warning-message/wdf-warning-message.component.scss
@@ -0,0 +1,16 @@
+@import 'govuk-frontend/govuk/base';
+
+:host {
+ display: contents;
+}
+
+.govuk-summary-list__message {
+ margin-bottom: 20px;
+ background-color: govuk-colour('light-grey');
+}
+
+.message-content {
+ white-space: nowrap;
+ overflow: visible;
+ padding: 7px 0px;
+}
diff --git a/frontend/src/app/shared/components/staff-record-summary/wdf-warning-message/wdf-warning-message.component.spec.ts b/frontend/src/app/shared/components/staff-record-summary/wdf-warning-message/wdf-warning-message.component.spec.ts
new file mode 100644
index 0000000000..5e4ee5e4bf
--- /dev/null
+++ b/frontend/src/app/shared/components/staff-record-summary/wdf-warning-message/wdf-warning-message.component.spec.ts
@@ -0,0 +1,77 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { BrowserModule } from '@angular/platform-browser';
+import { RouterTestingModule } from '@angular/router/testing';
+import { WdfModule } from '@features/wdf/wdf-data-change/wdf.module';
+import { SharedModule } from '@shared/shared.module';
+import { render } from '@testing-library/angular';
+
+import { WdfWarningMessageComponent } from './wdf-warning-message.component';
+
+describe('WdfWarningMessageComponent', () => {
+ const setup = async (overrides: any = {}) => {
+ const { fixture, getByText, queryByAltText, queryByText } = await render(WdfWarningMessageComponent, {
+ imports: [SharedModule, RouterTestingModule, HttpClientTestingModule, BrowserModule, WdfModule],
+ componentProperties: {
+ overallWdfEligibility: false,
+ warningMessage: null,
+ ...overrides,
+ },
+ });
+
+ const component = fixture.componentInstance;
+
+ return {
+ component,
+ fixture,
+ queryByAltText,
+ queryByText,
+ getByText,
+ };
+ };
+
+ it("should display 'Add this information' message and red flag when not eligible overall", async () => {
+ const { getByText, queryByAltText } = await setup({ overallWdfEligibility: false });
+
+ expect(getByText('Add this information')).toBeTruthy();
+ expect(queryByAltText('Red flag icon')).toBeTruthy();
+
+ expect(queryByAltText('Orange flag icon')).toBeFalsy();
+ });
+
+ it("should display 'Add this information' message and orange flag when eligible overall", async () => {
+ const { getByText, queryByAltText } = await setup({ overallWdfEligibility: true });
+
+ expect(queryByAltText('Red flag icon')).toBeFalsy();
+
+ expect(getByText('Add this information')).toBeTruthy();
+ expect(queryByAltText('Orange flag icon')).toBeTruthy();
+ });
+
+ it('should display message passed in and red flag when not eligible overall and specific warning message provided', async () => {
+ const specificMessage = 'Add the capacity of your main service';
+
+ const { getByText, queryByAltText } = await setup({
+ overallWdfEligibility: false,
+ warningMessage: specificMessage,
+ });
+
+ expect(getByText(specificMessage)).toBeTruthy();
+ expect(queryByAltText('Red flag icon')).toBeTruthy();
+
+ expect(queryByAltText('Orange flag icon')).toBeFalsy();
+ });
+
+ it('should display message passed in and orange flag when eligible overall and specific warning message provided', async () => {
+ const specificMessage = 'Add the capacity of your main service';
+
+ const { getByText, queryByAltText } = await setup({
+ overallWdfEligibility: true,
+ warningMessage: specificMessage,
+ });
+
+ expect(queryByAltText('Red flag icon')).toBeFalsy();
+
+ expect(getByText(specificMessage)).toBeTruthy();
+ expect(queryByAltText('Orange flag icon')).toBeTruthy();
+ });
+});
diff --git a/frontend/src/app/shared/components/staff-record-summary/wdf-warning-message/wdf-warning-message.component.ts b/frontend/src/app/shared/components/staff-record-summary/wdf-warning-message/wdf-warning-message.component.ts
new file mode 100644
index 0000000000..ad03833bb9
--- /dev/null
+++ b/frontend/src/app/shared/components/staff-record-summary/wdf-warning-message/wdf-warning-message.component.ts
@@ -0,0 +1,11 @@
+import { Component, Input } from '@angular/core';
+
+@Component({
+ selector: 'app-wdf-warning-message',
+ templateUrl: './wdf-warning-message.component.html',
+ styleUrls: ['./wdf-warning-message.component.scss'],
+})
+export class WdfWarningMessageComponent {
+ @Input() overallWdfEligibility: boolean;
+ @Input() warningMessage: string;
+}
diff --git a/frontend/src/app/shared/components/staff-summary/staff-summary.component.html b/frontend/src/app/shared/components/staff-summary/staff-summary.component.html
index ad08b309f6..1e397de17a 100644
--- a/frontend/src/app/shared/components/staff-summary/staff-summary.component.html
+++ b/frontend/src/app/shared/components/staff-summary/staff-summary.component.html
@@ -7,13 +7,14 @@
[sortOptions]="sortStaffOptions"
accessibleLabel="for staff records"
(fetchData)="getPageOfWorkers($event)"
+ [label]="searchLabel"
>
-
+
@@ -34,7 +35,7 @@
{{ worker.mainJob.jobRoleName }}
- last updated
+ last update
{{ lastUpdated(worker.updated) }}
diff --git a/frontend/src/app/shared/components/staff-summary/staff-summary.component.spec.ts b/frontend/src/app/shared/components/staff-summary/staff-summary.component.spec.ts
index 8cce112b86..86993d4ca1 100644
--- a/frontend/src/app/shared/components/staff-summary/staff-summary.component.spec.ts
+++ b/frontend/src/app/shared/components/staff-summary/staff-summary.component.spec.ts
@@ -148,7 +148,7 @@ describe('StaffSummaryComponent', () => {
component.fixture.componentInstance.totalWorkerCount = 16;
component.fixture.detectChanges();
- const searchInput = component.getByLabelText('Search for staff records');
+ const searchInput = component.getByLabelText('Search by name or ID number for staff records');
expect(searchInput).toBeTruthy();
userEvent.type(searchInput, 'search term here{enter}');
@@ -162,7 +162,10 @@ describe('StaffSummaryComponent', () => {
component.fixture.componentInstance.totalWorkerCount = 16;
component.fixture.detectChanges();
- userEvent.type(component.getByLabelText('Search for staff records'), 'search term here{enter}');
+ userEvent.type(
+ component.getByLabelText('Search by name or ID number for staff records'),
+ 'search term here{enter}',
+ );
expect(getAllWorkersSpy.calls.mostRecent().args[1].pageIndex).toEqual(0);
});
@@ -190,7 +193,9 @@ describe('StaffSummaryComponent', () => {
component.fixture.componentInstance.totalWorkerCount = 16;
component.fixture.detectChanges();
- expect((component.getByLabelText('Search for staff records') as HTMLInputElement).value).toBe('mysupersearch');
+ expect(
+ (component.getByLabelText('Search by name or ID number for staff records') as HTMLInputElement).value,
+ ).toBe('mysupersearch');
});
});
diff --git a/frontend/src/app/shared/components/staff-summary/staff-summary.component.ts b/frontend/src/app/shared/components/staff-summary/staff-summary.component.ts
index 3dfe92d70b..250f4196b2 100644
--- a/frontend/src/app/shared/components/staff-summary/staff-summary.component.ts
+++ b/frontend/src/app/shared/components/staff-summary/staff-summary.component.ts
@@ -1,94 +1,33 @@
-import { Component, Input, OnInit } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
-import { Establishment, SortStaffOptions, WdfSortStaffOptions } from '@core/model/establishment.model';
import { Worker } from '@core/model/worker.model';
+import { EstablishmentService } from '@core/services/establishment.service';
import { PermissionsService } from '@core/services/permissions/permissions.service';
+import { TabsService } from '@core/services/tabs.service';
import { WorkerService } from '@core/services/worker.service';
-import dayjs from 'dayjs';
-import { take } from 'rxjs/operators';
+import { StaffSummaryDirective } from '@shared/directives/staff-summary/staff-summary.directive';
@Component({
selector: 'app-staff-summary',
templateUrl: './staff-summary.component.html',
})
-export class StaffSummaryComponent implements OnInit {
- @Input() workplace: Establishment;
- @Input() workers: Array;
- @Input() workerCount: number;
- @Input() wdfView = false;
-
- public totalWorkerCount: number;
- public canViewWorker: boolean;
- public canEditWorker: boolean;
- public sortStaffOptions;
- public workersOrderBy: Array;
- public paginatedWorkers: Array;
- public sortByValue = 'staffNameAsc';
- public searchTerm = '';
- public sortByParamMap = {
- '0_asc': 'staffNameAsc',
- '0_dsc': 'staffNameDesc',
- '1_asc': 'jobRoleAsc',
- '1_dsc': 'jobRoleDesc',
- '2_meeting': 'wdfMeeting',
- '2_not_meeting': 'wdfNotMeeting',
- };
-
+export class StaffSummaryComponent extends StaffSummaryDirective implements OnInit {
constructor(
- private permissionsService: PermissionsService,
- private workerService: WorkerService,
- private router: Router,
- private route: ActivatedRoute,
- ) {}
-
- public lastUpdated(timestamp: string): string {
- const lastUpdated: dayjs.Dayjs = dayjs(timestamp);
- const isToday: boolean = dayjs().isSame(lastUpdated, 'day');
- return isToday ? 'Today' : lastUpdated.format('D MMMM YYYY');
+ protected permissionsService: PermissionsService,
+ protected workerService: WorkerService,
+ protected router: Router,
+ protected route: ActivatedRoute,
+ protected establishmentService: EstablishmentService,
+ protected tabsService: TabsService,
+ ) {
+ super(permissionsService, workerService, router, route, establishmentService, tabsService);
}
+ protected init(): void {}
+
public getWorkerRecordPath(event: Event, worker: Worker) {
event.preventDefault();
const path = ['/workplace', this.workplace.uid, 'staff-record', worker.uid, 'staff-record-summary'];
this.router.navigate(this.wdfView ? [...path, 'wdf-summary'] : path);
}
-
- ngOnInit(): void {
- this.totalWorkerCount = this.workerCount;
- this.paginatedWorkers = this.workers;
- this.canViewWorker = this.permissionsService.can(this.workplace.uid, 'canViewWorker');
- this.canEditWorker = this.permissionsService.can(this.workplace.uid, 'canEditWorker');
- this.sortStaffOptions = this.wdfView ? WdfSortStaffOptions : SortStaffOptions;
- this.setSearchIfPrevious();
- }
-
- private setSearchIfPrevious(): void {
- const search = this.route.snapshot.queryParamMap.get('search');
- const tab = this.route.snapshot.queryParamMap.get('tab');
-
- if (search && tab === 'staff') {
- this.searchTerm = search;
- }
- }
-
- public getPageOfWorkers(properties: {
- index: number;
- itemsPerPage: number;
- searchTerm: string;
- sortByValue: string;
- }): void {
- const { index, itemsPerPage, searchTerm, sortByValue } = properties;
- this.workerService
- .getAllWorkers(this.workplace.uid, {
- pageIndex: index,
- itemsPerPage: itemsPerPage,
- sortBy: sortByValue,
- ...(searchTerm ? { searchTerm } : {}),
- })
- .pipe(take(1))
- .subscribe(({ workers, workerCount }) => {
- this.paginatedWorkers = workers;
- this.workerCount = workerCount;
- });
- }
}
diff --git a/frontend/src/app/shared/components/wdf-field-confirmation/wdf-field-confirmation.component.html b/frontend/src/app/shared/components/wdf-field-confirmation/wdf-field-confirmation.component.html
index cf02fa935a..e458ca8838 100644
--- a/frontend/src/app/shared/components/wdf-field-confirmation/wdf-field-confirmation.component.html
+++ b/frontend/src/app/shared/components/wdf-field-confirmation/wdf-field-confirmation.component.html
@@ -1,18 +1,59 @@
-
+
+
+
+
+
+
+
+ Is this still correct?
+
+ Yes, it is
+
+ No, change it
+
+
+
+ Meeting requirements
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/app/shared/components/wdf-field-confirmation/wdf-field-confirmation.component.scss b/frontend/src/app/shared/components/wdf-field-confirmation/wdf-field-confirmation.component.scss
new file mode 100644
index 0000000000..40aa2c182e
--- /dev/null
+++ b/frontend/src/app/shared/components/wdf-field-confirmation/wdf-field-confirmation.component.scss
@@ -0,0 +1,16 @@
+@import 'govuk-frontend/govuk/base';
+
+:host {
+ display: contents;
+}
+
+.govuk-summary-list__message {
+ padding-bottom: 0px;
+ padding-top: 15px;
+ background-color: govuk-colour('light-grey');
+}
+
+.confirmation-content {
+ width: calc(100% + 4rem);
+ margin-top: 0px;
+}
diff --git a/frontend/src/app/shared/components/wdf-field-confirmation/wdf-field-confirmation.component.ts b/frontend/src/app/shared/components/wdf-field-confirmation/wdf-field-confirmation.component.ts
index 7860f7a1a3..5c4e0c39b4 100644
--- a/frontend/src/app/shared/components/wdf-field-confirmation/wdf-field-confirmation.component.ts
+++ b/frontend/src/app/shared/components/wdf-field-confirmation/wdf-field-confirmation.component.ts
@@ -3,6 +3,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'app-wdf-field-confirmation',
templateUrl: './wdf-field-confirmation.component.html',
+ styleUrls: ['./wdf-field-confirmation.component.scss'],
})
export class WdfFieldConfirmationComponent {
public confirmButtonClicked = false;
@@ -11,6 +12,7 @@ export class WdfFieldConfirmationComponent {
@Output() fieldConfirmation: EventEmitter = new EventEmitter();
@Output() setReturnClicked: EventEmitter = new EventEmitter();
@Input() changeLink: any[];
+ @Input() staffRecordView: boolean = false;
@Input() set workerUid(uid: string) {
this._workerUid = uid;
diff --git a/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.html b/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.html
index 9a6d883714..9a8d18e052 100644
--- a/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.html
+++ b/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.html
@@ -1,8 +1,19 @@
-
- {{ staffMismatchMessage }}
-
-
- Either change the total or
- view staff records to
- {{ addOrDeleteRecordsMessage }}.
-
+
+
+
+
+ {{ staffMismatchMessage }}
+
+
+ Either change the total or
+ view staff records to
+ {{ addOrDeleteRecordsMessage }}.
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.scss b/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.scss
new file mode 100644
index 0000000000..560171ce12
--- /dev/null
+++ b/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.scss
@@ -0,0 +1,16 @@
+@import 'govuk-frontend/govuk/base';
+
+:host {
+ display: contents;
+}
+
+.govuk-summary-list__message {
+ margin-bottom: 20px;
+ background-color: govuk-colour('light-grey');
+}
+
+.message-content {
+ white-space: nowrap;
+ overflow: visible;
+ padding: 7px 0px;
+}
diff --git a/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.spec.ts b/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.spec.ts
index 855c301dd6..ab541e0d4d 100644
--- a/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.spec.ts
+++ b/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.spec.ts
@@ -11,30 +11,30 @@ import { render } from '@testing-library/angular';
import { WdfStaffMismatchMessageComponent } from './wdf-staff-mismatch-message.component';
describe('WdfStaffMismatchMessageComponent', () => {
- const setup = async (uid = '') => {
- const { fixture, getByText, getAllByText, getByTestId, queryByText } = await render(
- WdfStaffMismatchMessageComponent,
- {
- imports: [RouterTestingModule, HttpClientTestingModule, BrowserModule, SharedModule],
- providers: [
- { provide: EstablishmentService, useClass: MockEstablishmentService },
- {
- provide: ActivatedRoute,
- useValue: {
- snapshot: {
- params: {
- establishmentuid: uid,
- },
+ const setup = async (overrides: any = {}) => {
+ const setupTools = await render(WdfStaffMismatchMessageComponent, {
+ imports: [RouterTestingModule, HttpClientTestingModule, BrowserModule, SharedModule],
+ providers: [
+ { provide: EstablishmentService, useClass: MockEstablishmentService },
+ {
+ provide: ActivatedRoute,
+ useValue: {
+ snapshot: {
+ params: {
+ establishmentuid: overrides.uidInParams ?? null,
},
},
},
- ],
- componentProperties: { workplace: establishmentBuilder() as Establishment, workerCount: 1 },
+ },
+ ],
+ componentProperties: {
+ workplace: overrides.workplace ?? (establishmentBuilder() as Establishment),
+ workerCount: 1,
},
- );
+ });
- const component = fixture.componentInstance;
- return { component, fixture, getByText, getAllByText, getByTestId, queryByText };
+ const component = setupTools.fixture.componentInstance;
+ return { ...setupTools, component };
};
it('should create', async () => {
@@ -106,7 +106,7 @@ describe('WdfStaffMismatchMessageComponent', () => {
expect(component.icon).toEqual(orangeFlagIcon);
});
- it('should show a red cross if the user is not meeting WDF overall', async () => {
+ it('should show a red flag if the user is not meeting WDF overall', async () => {
const { component, fixture } = await setup();
component.workerCount = 10;
component.workplace.numberOfStaff = 9;
@@ -114,33 +114,26 @@ describe('WdfStaffMismatchMessageComponent', () => {
component.setIcon();
fixture.detectChanges();
- const crossIcon = 'cross-icon';
- expect(component.icon).toEqual(crossIcon);
+ const redFlagIcon = 'red-flag-wdf-table';
+ expect(component.icon).toEqual(redFlagIcon);
});
describe('setStaffRecordsUrl', async () => {
it("should set URL to subs's staff records if user is a parent viewing their subsidiary", async () => {
- const { component, fixture } = await setup('123');
- const expectedUrl = { url: ['/workplace', '456'], fragment: 'staff-records' };
+ const workplace = establishmentBuilder();
+ workplace.uid = 'abc12323123';
- component.primaryWorkplaceUid = '123';
- component.workplace.uid = '456';
- fixture.componentInstance.setStaffRecordsUrl();
- fixture.detectChanges();
+ const { getByText } = await setup({ uidInParams: workplace.uid, workplace });
- expect(component.staffRecordsUrl).toEqual(expectedUrl);
+ const viewStaffRecordsLink = getByText('view staff records');
+ expect((viewStaffRecordsLink as HTMLAnchorElement).href).toContain(`/subsidiary/${workplace.uid}/staff-records`);
});
- it('should set URL to staff records tab on dashboard if the user is the primary user', async () => {
- const { component, fixture } = await setup();
- const expectedUrl = { url: ['/dashboard'], fragment: 'staff-records' };
-
- component.primaryWorkplaceUid = '123';
- component.workplace.uid = '123';
- fixture.componentInstance.setStaffRecordsUrl();
- fixture.detectChanges();
+ it('should set URL to staff records tab on dashboard if the user is viewing primary workplace', async () => {
+ const { getByText } = await setup();
- expect(component.staffRecordsUrl).toEqual(expectedUrl);
+ const viewStaffRecordsLink = getByText('view staff records');
+ expect((viewStaffRecordsLink as HTMLAnchorElement).href).toContain(`dashboard#staff-records`);
});
});
});
diff --git a/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.ts b/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.ts
index 70714ec165..702c442c1f 100644
--- a/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.ts
+++ b/frontend/src/app/shared/components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component.ts
@@ -7,6 +7,7 @@ import { EstablishmentService } from '@core/services/establishment.service';
@Component({
selector: 'app-wdf-staff-mismatch-message',
templateUrl: './wdf-staff-mismatch-message.component.html',
+ styleUrls: ['./wdf-staff-mismatch-message.component.scss'],
})
export class WdfStaffMismatchMessageComponent implements OnInit, OnChanges {
@Input() public workplace: Establishment;
@@ -55,7 +56,7 @@ export class WdfStaffMismatchMessageComponent implements OnInit, OnChanges {
return;
}
if (this.overallWdfEligibility == false) {
- this.icon = 'cross-icon';
+ this.icon = 'red-flag-wdf-table';
return;
}
}
@@ -77,7 +78,7 @@ export class WdfStaffMismatchMessageComponent implements OnInit, OnChanges {
public setStaffRecordsUrl(): void {
if (this.route.snapshot.params.establishmentuid && this.primaryWorkplaceUid !== this.workplace.uid) {
- this.staffRecordsUrl = { url: ['/workplace', this.workplace.uid], fragment: 'staff-records' };
+ this.staffRecordsUrl = { url: ['/subsidiary', this.workplace.uid, 'staff-records'] };
} else {
this.staffRecordsUrl = { url: ['/dashboard'], fragment: 'staff-records' };
}
diff --git a/frontend/src/app/shared/components/wdf-summary-panel/wdf-summary-panel.component.html b/frontend/src/app/shared/components/wdf-summary-panel/wdf-summary-panel.component.html
new file mode 100644
index 0000000000..b75508c0eb
--- /dev/null
+++ b/frontend/src/app/shared/components/wdf-summary-panel/wdf-summary-panel.component.html
@@ -0,0 +1,56 @@
+
diff --git a/frontend/src/app/shared/components/wdf-summary-panel/wdf-summary-panel.component.scss b/frontend/src/app/shared/components/wdf-summary-panel/wdf-summary-panel.component.scss
new file mode 100644
index 0000000000..4d0f50570b
--- /dev/null
+++ b/frontend/src/app/shared/components/wdf-summary-panel/wdf-summary-panel.component.scss
@@ -0,0 +1,10 @@
+.summary-section {
+ &__title {
+ width: 29%;
+ padding: 0 15px;
+ }
+
+ &__summary-text {
+ width: 71%;
+ }
+}
diff --git a/frontend/src/app/shared/components/wdf-summary-panel/wdf-summary-panel.component.spec.ts b/frontend/src/app/shared/components/wdf-summary-panel/wdf-summary-panel.component.spec.ts
new file mode 100644
index 0000000000..cdd0388db5
--- /dev/null
+++ b/frontend/src/app/shared/components/wdf-summary-panel/wdf-summary-panel.component.spec.ts
@@ -0,0 +1,390 @@
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { getTestBed } from '@angular/core/testing';
+import { BrowserModule } from '@angular/platform-browser';
+import { Router } from '@angular/router';
+import { RouterTestingModule } from '@angular/router/testing';
+import { SharedModule } from '@shared/shared.module';
+import { fireEvent, render, within } from '@testing-library/angular';
+
+import { WdfSummaryPanel } from './wdf-summary-panel.component';
+
+describe('WdfSummaryPanel', () => {
+ const currentYear = new Date().getFullYear();
+
+ const messages = {
+ fundingMet: `Your data has met the funding requirements for ${currentYear} to ${currentYear + 1}`,
+ fundingNotMet: `Your data does not meet the funding requirements for ${currentYear} to ${currentYear + 1}`,
+ fundingMetBySomeSubs: `Some data does not meet the funding requirements for ${currentYear} to ${currentYear + 1}`,
+ };
+
+ const setup = async (overrides: any = {}) => {
+ const setupTools = await render(WdfSummaryPanel, {
+ imports: [RouterTestingModule, HttpClientTestingModule, BrowserModule, SharedModule],
+ providers: [],
+ componentProperties: {
+ wdfStartDate: `1 April ${currentYear}`,
+ wdfEndDate: `31 March ${currentYear + 1}`,
+ ...overrides,
+ },
+ });
+ const component = setupTools.fixture.componentInstance;
+
+ const injector = getTestBed();
+ const router = injector.inject(Router) as Router;
+ const routerSpy = spyOn(router, 'navigate').and.returnValue(Promise.resolve(true));
+
+ return { ...setupTools, component, routerSpy };
+ };
+
+ it('should create', async () => {
+ const { component } = await setup();
+
+ expect(component).toBeTruthy();
+ });
+
+ describe('meeting funding requirements', () => {
+ it('should display the correct message with timeframe for meeting WDF requirements for the workplace', async () => {
+ const overrides = {
+ workplaceWdfEligibilityStatus: true,
+ overallWdfEligibility: false,
+ };
+
+ const { getByTestId } = await setup(overrides);
+
+ const workplaceRow = getByTestId('workplace-row');
+
+ expect(workplaceRow).toBeTruthy();
+ expect(within(workplaceRow).queryByText(messages.fundingNotMet)).toBeFalsy();
+ expect(within(workplaceRow).getByText(messages.fundingMet)).toBeTruthy();
+ expect(within(workplaceRow).getByTestId('green-tick')).toBeTruthy();
+ });
+
+ it('should display the correct message with timeframe for meeting WDF requirements for the workplace if overall has met but workplace hasn\t', async () => {
+ const overrides = {
+ workplaceWdfEligibilityStatus: false,
+ overallWdfEligibility: true,
+ };
+
+ const { getByTestId } = await setup(overrides);
+
+ const workplaceRow = getByTestId('workplace-row');
+
+ expect(workplaceRow).toBeTruthy();
+ expect(within(workplaceRow).queryByText(messages.fundingNotMet)).toBeFalsy();
+ expect(within(workplaceRow).getByText(messages.fundingMet)).toBeTruthy();
+ expect(within(workplaceRow).getByTestId('green-tick')).toBeTruthy();
+ });
+
+ it('should display the correct message with timeframe for meeting WDF requirements for staff', async () => {
+ const overrides = {
+ staffWdfEligibilityStatus: true,
+ overallWdfEligibility: false,
+ };
+
+ const { getByTestId } = await setup(overrides);
+
+ const staffRow = getByTestId('staff-row');
+
+ expect(staffRow).toBeTruthy();
+ expect(within(staffRow).queryByText(messages.fundingNotMet)).toBeFalsy();
+ expect(within(staffRow).getByText(messages.fundingMet)).toBeTruthy();
+ expect(within(staffRow).getByTestId('green-tick')).toBeTruthy();
+ });
+
+ it("should display the correct message with timeframe for meeting WDF requirements for staff if overall has met but staff hasn't", async () => {
+ const overrides = {
+ staffWdfEligibilityStatus: false,
+ overallWdfEligibility: true,
+ };
+
+ const { getByTestId } = await setup(overrides);
+
+ const staffRow = getByTestId('staff-row');
+
+ expect(staffRow).toBeTruthy();
+ expect(within(staffRow).queryByText(messages.fundingNotMet)).toBeFalsy();
+ expect(within(staffRow).getByText(messages.fundingMet)).toBeTruthy();
+ expect(within(staffRow).getByTestId('green-tick')).toBeTruthy();
+ });
+
+ it('should display the correct message with timeframe for meeting WDF requirements for all other workplaces', async () => {
+ const overrides = {
+ subsidiariesOverallWdfEligibility: true,
+ isParent: true,
+ };
+
+ const { getByTestId } = await setup(overrides);
+
+ const workplacesRow = getByTestId('workplaces-row');
+
+ expect(workplacesRow).toBeTruthy();
+ expect(within(workplacesRow).queryByText(messages.fundingNotMet)).toBeFalsy();
+ expect(within(workplacesRow).getByText(messages.fundingMet)).toBeTruthy();
+ expect(within(workplacesRow).getByTestId('green-tick')).toBeTruthy();
+ });
+
+ describe('funding message links', () => {
+ it('should show both messages as links when no active fragment', async () => {
+ const overrides = {
+ workplaceWdfEligibilityStatus: true,
+ staffWdfEligibilityStatus: true,
+ };
+
+ const { getByTestId } = await setup(overrides);
+
+ const workplaceRow = getByTestId('workplace-row');
+ const staffRow = getByTestId('staff-row');
+
+ const workplaceFundingMessage = within(workplaceRow).getByRole('link');
+ const staffFundingMessage = within(staffRow).getByRole('link');
+
+ expect(workplaceFundingMessage).toBeTruthy();
+ expect(staffFundingMessage).toBeTruthy();
+ });
+
+ it('should show workplace without a link and staff with a link when workplace is the active fragment', async () => {
+ const overrides = {
+ workplaceWdfEligibilityStatus: true,
+ staffWdfEligibilityStatus: true,
+ activatedFragment: 'workplace',
+ };
+
+ const { getByTestId } = await setup(overrides);
+
+ const workplaceRow = getByTestId('workplace-row');
+ const staffRow = getByTestId('staff-row');
+
+ const workplaceFundingMessage = within(workplaceRow).queryByRole('link');
+ const staffFundingMessage = within(staffRow).getByRole('link');
+
+ expect(workplaceFundingMessage).toBeFalsy();
+ expect(staffFundingMessage).toBeTruthy();
+ });
+
+ it('should show workplace with a link and staff without a link when staff is the active fragment', async () => {
+ const overrides = {
+ workplaceWdfEligibilityStatus: true,
+ staffWdfEligibilityStatus: true,
+ activatedFragment: 'staff',
+ };
+
+ const { getByTestId } = await setup(overrides);
+
+ const workplaceRow = getByTestId('workplace-row');
+ const staffRow = getByTestId('staff-row');
+
+ const workplaceFundingMessage = within(workplaceRow).getByRole('link');
+ const staffFundingMessage = within(staffRow).queryByRole('link');
+
+ expect(workplaceFundingMessage).toBeTruthy();
+ expect(staffFundingMessage).toBeFalsy();
+ });
+ });
+
+ describe('parent', () => {
+ it('should show all messages as clickable links when no active fragment', async () => {
+ const overrides = {
+ workplaceWdfEligibilityStatus: true,
+ staffWdfEligibilityStatus: true,
+ subsidiariesOverallWdfEligibility: true,
+ isParent: true,
+ };
+
+ const { getByTestId } = await setup(overrides);
+
+ const workplaceRow = getByTestId('workplace-row');
+ const staffRow = getByTestId('staff-row');
+ const allWorkplacesRow = getByTestId('workplaces-row');
+
+ const workplaceFundingMessage = within(workplaceRow).getByRole('link');
+ const staffFundingMessage = within(staffRow).getByRole('link');
+ const allWorkplacesFundingMessage = within(allWorkplacesRow).getByRole('link');
+
+ expect(workplaceFundingMessage).toBeTruthy();
+ expect(staffFundingMessage).toBeTruthy();
+ expect(allWorkplacesFundingMessage).toBeTruthy();
+ });
+
+ it('should show your other workplaces without a link when fragment is active', async () => {
+ const overrides = {
+ workplaceWdfEligibilityStatus: true,
+ staffWdfEligibilityStatus: true,
+ subsidiariesOverallWdfEligibility: true,
+ isParent: true,
+ activatedFragment: 'workplaces',
+ };
+
+ const { getByTestId } = await setup(overrides);
+
+ const workplaceRow = getByTestId('workplace-row');
+ const staffRow = getByTestId('staff-row');
+ const allWorkplacesRow = getByTestId('workplaces-row');
+
+ const workplaceFundingMessage = within(workplaceRow).getByRole('link');
+ const staffFundingMessage = within(staffRow).getByRole('link');
+ const allWorkplacesFundingMessage = within(allWorkplacesRow).queryByRole('link');
+
+ expect(workplaceFundingMessage).toBeTruthy();
+ expect(staffFundingMessage).toBeTruthy();
+ expect(allWorkplacesFundingMessage).toBeFalsy();
+ });
+ });
+ });
+
+ describe('not meeting funding requirements', () => {
+ it('should display the not meeting WDF requirements message for the workplace', async () => {
+ const overrides = {
+ workplaceWdfEligibilityStatus: false,
+ staffWdfEligibilityStatus: false,
+ overallWdfEligibility: false,
+ };
+
+ const { getByTestId } = await setup(overrides);
+
+ const workplaceRow = getByTestId('workplace-row');
+
+ expect(workplaceRow).toBeTruthy();
+ expect(within(workplaceRow).queryByText(messages.fundingMet)).toBeFalsy();
+ expect(within(workplaceRow).getByText(messages.fundingNotMet)).toBeTruthy();
+ expect(within(workplaceRow).getByTestId('red-flag')).toBeTruthy();
+ });
+
+ it('should display the not meeting WDF requirements message for staff', async () => {
+ const overrides = {
+ workplaceWdfEligibilityStatus: false,
+ staffWdfEligibilityStatus: false,
+ overallWdfEligibility: false,
+ };
+
+ const { getByTestId } = await setup(overrides);
+
+ const staffRow = getByTestId('staff-row');
+
+ expect(staffRow).toBeTruthy();
+ expect(within(staffRow).queryByText(messages.fundingMet)).toBeFalsy();
+ expect(within(staffRow).getByText(messages.fundingNotMet)).toBeTruthy();
+ expect(within(staffRow).getByTestId('red-flag')).toBeTruthy();
+ });
+
+ it('should display the not meeting WDF requirements message for all other workplaces', async () => {
+ const overrides = {
+ workplaceWdfEligibilityStatus: false,
+ staffWdfEligibilityStatus: false,
+ subsidiariesOverallWdfEligibility: false,
+ isParent: true,
+ overallWdfEligibility: false,
+ };
+
+ const { getByTestId } = await setup(overrides);
+
+ const workplacesRow = getByTestId('workplaces-row');
+
+ expect(workplacesRow).toBeTruthy();
+ expect(within(workplacesRow).queryByText(messages.fundingMet)).toBeFalsy();
+ expect(within(workplacesRow).getByText(messages.fundingNotMet)).toBeTruthy();
+ expect(within(workplacesRow).getByTestId('red-flag')).toBeTruthy();
+ });
+
+ it('should display some data not meeting requirements message when ineligible but some sub workplaces are meeting', async () => {
+ const overrides = {
+ workplaceWdfEligibilityStatus: false,
+ staffWdfEligibilityStatus: false,
+ subsidiariesOverallWdfEligibility: false,
+ someSubsidiariesMeetingRequirements: true,
+ isParent: true,
+ overallWdfEligibility: false,
+ };
+
+ const { getByTestId } = await setup(overrides);
+
+ const workplacesRow = getByTestId('workplaces-row');
+
+ expect(within(workplacesRow).getByText(messages.fundingMetBySomeSubs)).toBeTruthy();
+ expect(within(workplacesRow).getByTestId('red-flag')).toBeTruthy();
+
+ expect(within(workplacesRow).queryByText(messages.fundingMet)).toBeFalsy();
+ expect(within(workplacesRow).queryByText(messages.fundingNotMet)).toBeFalsy();
+ });
+ });
+
+ describe('Navigation', () => {
+ [
+ {
+ scenario: 'with wdf/data in url when not on data page',
+ expectedLink: ['/wdf/data'],
+ onDataPage: false,
+ },
+ {
+ scenario: 'with no url when already on the data page',
+ expectedLink: [],
+ onDataPage: true,
+ },
+ ].forEach(({ scenario, onDataPage, expectedLink }) => {
+ [{ isEligible: true }, { isEligible: false }].forEach(({ isEligible }) => {
+ const linkId = isEligible ? 'met-funding-message' : 'not-met-funding-message';
+
+ it(`should navigate to workplace when ${linkId} clicked ${scenario}`, async () => {
+ const overrides = {
+ workplaceWdfEligibilityStatus: isEligible,
+ overallWdfEligibility: isEligible,
+ onDataPage,
+ };
+
+ const { fixture, getByTestId, routerSpy } = await setup(overrides);
+
+ const workplaceRow = getByTestId('workplace-row');
+
+ const notMetFundingMessage = within(workplaceRow).getByTestId(linkId);
+
+ expect(notMetFundingMessage).toBeTruthy();
+
+ fireEvent.click(notMetFundingMessage);
+ fixture.detectChanges();
+
+ expect(routerSpy).toHaveBeenCalledWith(expectedLink, { fragment: 'workplace' });
+ });
+
+ it(`should navigate to staff when ${linkId} clicked ${scenario}`, async () => {
+ const overrides = {
+ staffWdfEligibilityStatus: isEligible,
+ overallWdfEligibility: isEligible,
+ onDataPage,
+ };
+
+ const { fixture, getByTestId, routerSpy } = await setup(overrides);
+
+ const staffRow = getByTestId('staff-row');
+
+ const notMetFundingMessage = within(staffRow).getByTestId(linkId);
+
+ expect(notMetFundingMessage).toBeTruthy();
+
+ fireEvent.click(notMetFundingMessage);
+
+ expect(routerSpy).toHaveBeenCalledWith(expectedLink, { fragment: 'staff' });
+ });
+
+ it(`should navigate to your other workplaces when clicked ${scenario}`, async () => {
+ const overrides = {
+ subsidiariesOverallWdfEligibility: isEligible,
+ isParent: true,
+ onDataPage,
+ };
+
+ const { fixture, getByTestId, routerSpy } = await setup(overrides);
+
+ const workplacesRow = getByTestId('workplaces-row');
+
+ const notMetFundingMessage = within(workplacesRow).getByTestId(linkId);
+
+ expect(notMetFundingMessage).toBeTruthy();
+
+ fireEvent.click(notMetFundingMessage);
+ fixture.detectChanges();
+
+ expect(routerSpy).toHaveBeenCalledWith(expectedLink, { fragment: 'workplaces' });
+ });
+ });
+ });
+ });
+});
diff --git a/frontend/src/app/shared/components/wdf-summary-panel/wdf-summary-panel.component.ts b/frontend/src/app/shared/components/wdf-summary-panel/wdf-summary-panel.component.ts
new file mode 100644
index 0000000000..9cb5dbabfe
--- /dev/null
+++ b/frontend/src/app/shared/components/wdf-summary-panel/wdf-summary-panel.component.ts
@@ -0,0 +1,106 @@
+import { DatePipe } from '@angular/common';
+import { Component, Input, OnChanges, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+
+@Component({
+ selector: 'app-wdf-summary-panel',
+ templateUrl: './wdf-summary-panel.component.html',
+ styleUrls: ['../summary-section/summary-section.component.scss', './wdf-summary-panel.component.scss'],
+ providers: [DatePipe],
+})
+export class WdfSummaryPanel implements OnInit, OnChanges {
+ @Input() workplaceWdfEligibilityStatus: boolean;
+ @Input() staffWdfEligibilityStatus: boolean;
+ @Input() wdfStartDate: string;
+ @Input() wdfEndDate: string;
+ @Input() isParent: boolean;
+ @Input() subsidiariesOverallWdfEligibility: boolean;
+ @Input() overallWdfEligibility: boolean;
+ @Input() activatedFragment: string;
+ @Input() onDataPage: boolean = true;
+ @Input() someSubsidiariesMeetingRequirements: boolean;
+
+ public sections: any = [];
+ public meetingMessage: string;
+ public notMeetingMessage: string;
+ public someSubsMeetingMessage: string;
+
+ constructor(private router: Router, private datePipe: DatePipe) {}
+
+ ngOnInit(): void {
+ this.setMessages();
+ this.getSections();
+ this.showLink(this.activatedFragment);
+ }
+
+ ngOnChanges(): void {
+ this.getSections();
+ this.showLink(this.activatedFragment);
+ }
+
+ private setMessages(): void {
+ const formattedStartDate = this.datePipe.transform(this.wdfStartDate, 'yyyy');
+ const formattedEndDate = this.datePipe.transform(this.wdfEndDate, 'yyyy');
+
+ this.meetingMessage = `Your data has met the funding requirements for ${formattedStartDate} to ${formattedEndDate}`;
+ this.notMeetingMessage = `Your data does not meet the funding requirements for ${formattedStartDate} to ${formattedEndDate}`;
+ this.someSubsMeetingMessage = `Some data does not meet the funding requirements for ${formattedStartDate} to ${formattedEndDate}`;
+ }
+
+ public getSections(): void {
+ this.sections = [
+ {
+ title: 'Workplace',
+ eligibility:
+ this.workplaceWdfEligibilityStatus || (!this.workplaceWdfEligibilityStatus && this.overallWdfEligibility),
+ fragment: 'workplace',
+ showLink: true,
+ meetingMessage: this.meetingMessage,
+ notMeetingMessage: this.notMeetingMessage,
+ },
+ {
+ title: 'Staff records',
+ eligibility: this.staffWdfEligibilityStatus || (!this.staffWdfEligibilityStatus && this.overallWdfEligibility),
+ fragment: 'staff',
+ showLink: true,
+ meetingMessage: this.meetingMessage,
+ notMeetingMessage: this.notMeetingMessage,
+ },
+ ];
+
+ if (this.isParent) {
+ this.sections.push({
+ title: 'Your other workplaces',
+ eligibility: this.subsidiariesOverallWdfEligibility,
+ fragment: 'workplaces',
+ showLink: true,
+ meetingMessage: this.meetingMessage,
+ notMeetingMessage: this.getOtherWorkplacesNotMeetingMessage(),
+ });
+ }
+ }
+
+ public onClick(event: Event, fragment: string): void {
+ event.preventDefault();
+
+ const urlToNavigateTo = this.onDataPage ? [] : ['/wdf/data'];
+ this.router.navigate(urlToNavigateTo, { fragment: fragment });
+ }
+
+ private getOtherWorkplacesNotMeetingMessage(): string {
+ if (!this.subsidiariesOverallWdfEligibility && this.someSubsidiariesMeetingRequirements) {
+ return this.someSubsMeetingMessage;
+ }
+ return this.notMeetingMessage;
+ }
+
+ public showLink(fragment: string): void {
+ for (var i = 0; i < this.sections.length; i++) {
+ if (fragment === this.sections[i].fragment) {
+ this.sections[i].showLink = false;
+ } else {
+ this.sections[i].showLink = true;
+ }
+ }
+ }
+}
diff --git a/frontend/src/app/shared/directives/staff-summary/staff-summary.directive.ts b/frontend/src/app/shared/directives/staff-summary/staff-summary.directive.ts
new file mode 100644
index 0000000000..44d3a2ea92
--- /dev/null
+++ b/frontend/src/app/shared/directives/staff-summary/staff-summary.directive.ts
@@ -0,0 +1,96 @@
+import { Directive, Input, OnInit } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { Establishment, SortStaffOptions, WdfSortStaffOptions } from '@core/model/establishment.model';
+import { Worker } from '@core/model/worker.model';
+import { EstablishmentService } from '@core/services/establishment.service';
+import { PermissionsService } from '@core/services/permissions/permissions.service';
+import { TabsService } from '@core/services/tabs.service';
+import { WorkerService } from '@core/services/worker.service';
+import dayjs from 'dayjs';
+import { Subscription } from 'rxjs';
+import { take } from 'rxjs/operators';
+
+@Directive({})
+export class StaffSummaryDirective implements OnInit {
+ @Input() workplace: Establishment;
+ @Input() workers: Array;
+ @Input() workerCount: number;
+
+ public wdfView = false;
+ public subscriptions: Subscription = new Subscription();
+ public totalWorkerCount: number;
+ public canViewWorker: boolean;
+ public canEditWorker: boolean;
+ public sortStaffOptions;
+ public workersOrderBy: Array;
+ public paginatedWorkers: Array;
+ public sortByValue = 'staffNameAsc';
+ public searchTerm = '';
+ public sortByParamMap = {
+ '0_asc': 'staffNameAsc',
+ '0_dsc': 'staffNameDesc',
+ '1_asc': 'jobRoleAsc',
+ '1_dsc': 'jobRoleDesc',
+ '2_meeting': 'wdfMeeting',
+ '2_not_meeting': 'wdfNotMeeting',
+ };
+ public searchLabel = 'Search by name or ID number';
+
+ constructor(
+ protected permissionsService: PermissionsService,
+ protected workerService: WorkerService,
+ protected router: Router,
+ protected route: ActivatedRoute,
+ protected establishmentService: EstablishmentService,
+ protected tabsService: TabsService,
+ ) {}
+
+ ngOnInit(): void {
+ this.totalWorkerCount = this.workerCount;
+ this.paginatedWorkers = this.workers;
+ this.canViewWorker = this.permissionsService.can(this.workplace.uid, 'canViewWorker');
+ this.canEditWorker = this.permissionsService.can(this.workplace.uid, 'canEditWorker');
+ this.sortStaffOptions = this.wdfView ? WdfSortStaffOptions : SortStaffOptions;
+ this.setSearchIfPrevious();
+ this.init();
+ }
+
+ protected init(): void {}
+
+ public lastUpdated(timestamp: string): string {
+ const lastUpdated: dayjs.Dayjs = dayjs(timestamp);
+ const isToday: boolean = dayjs().isSame(lastUpdated, 'day');
+
+ return isToday ? 'Today' : lastUpdated.format('D MMM YYYY');
+ }
+
+ protected setSearchIfPrevious(): void {
+ const search = this.route.snapshot.queryParamMap?.get('search');
+ const tab = this.route.snapshot.queryParamMap?.get('tab');
+
+ if (search && tab === 'staff') {
+ this.searchTerm = search;
+ }
+ }
+
+ protected getPageOfWorkers(properties: {
+ index: number;
+ itemsPerPage: number;
+ searchTerm: string;
+ sortByValue: string;
+ }): void {
+ const { index, itemsPerPage, searchTerm, sortByValue } = properties;
+ this.workerService
+ .getAllWorkers(this.workplace.uid, {
+ pageIndex: index,
+ itemsPerPage: itemsPerPage,
+ sortBy: sortByValue,
+ ...(searchTerm ? { searchTerm } : {}),
+ })
+ .pipe(take(1))
+ .subscribe(({ workers, workerCount }) => {
+ this.paginatedWorkers = workers;
+ this.workerCount = workerCount;
+ });
+ }
+}
diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts
index cf32a1c4ab..a2cd21bc32 100644
--- a/frontend/src/app/shared/shared.module.ts
+++ b/frontend/src/app/shared/shared.module.ts
@@ -10,15 +10,9 @@ import { PageResolver } from '@core/resolvers/page.resolver';
import { DialogService } from '@core/services/dialog.service';
import { ArticleListComponent } from '@features/articles/article-list/article-list.component';
import { NewArticleListComponent } from '@features/articles/new-article-list/new-article-list.component';
-import {
- NewTrainingLinkPanelComponent,
-} from '@features/new-dashboard/training-tab/training-link-panel/training-link-panel.component';
-import {
- MissingMandatoryTrainingComponent,
-} from '@features/training-and-qualifications/new-training-qualifications-record/missing-mandatory-training/missing-mandatory-training.component';
-import {
- DeleteWorkplaceDialogComponent,
-} from '@features/workplace/delete-workplace-dialog/delete-workplace-dialog.component';
+import { NewTrainingLinkPanelComponent } from '@features/new-dashboard/training-tab/training-link-panel/training-link-panel.component';
+import { MissingMandatoryTrainingComponent } from '@features/training-and-qualifications/new-training-qualifications-record/missing-mandatory-training/missing-mandatory-training.component';
+import { DeleteWorkplaceDialogComponent } from '@features/workplace/delete-workplace-dialog/delete-workplace-dialog.component';
import { AlertComponent } from '@shared/components/alert/alert.component';
import { CheckCQCDetailsComponent } from '@shared/components/check-cqc-details/check-cqc-details.component';
import { NewDashboardHeaderComponent } from '@shared/components/new-dashboard-header/dashboard-header.component';
@@ -27,12 +21,8 @@ import { WorkplaceTabComponent } from '@shared/components/workplace-tab/workplac
import { BulkUploadFileTypePipePipe } from '@shared/pipes/bulk-upload-file-type.pipe';
import { SanitizeVideoUrlPipe } from '@shared/pipes/sanitize-video-url.pipe';
-import {
- GroupedRadioButtonAccordionComponent,
-} from './components/accordions/radio-button-accordion/grouped-radio-button-accordion/grouped-radio-button-accordion.component';
-import {
- RadioButtonAccordionComponent,
-} from './components/accordions/radio-button-accordion/radio-button-accordion.component';
+import { GroupedRadioButtonAccordionComponent } from './components/accordions/radio-button-accordion/grouped-radio-button-accordion/grouped-radio-button-accordion.component';
+import { RadioButtonAccordionComponent } from './components/accordions/radio-button-accordion/radio-button-accordion.component';
import { AddNoteComponent } from './components/add-note/add-note.component';
import { AutoSuggestComponent } from './components/auto-suggest/auto-suggest.component';
import { BackLinkComponent } from './components/back-link/back-link.component';
@@ -46,67 +36,48 @@ import { CharacterCountComponent } from './components/character-count/character-
import { AboutTheDataLinkComponent } from './components/data-area-tab/about-the-data-link/about-the-data-link.component';
import { DatePickerComponent } from './components/date-picker/date-picker.component';
import { DetailsComponent } from './components/details/details.component';
-import {
- ValidationErrorMessageComponent,
-} from './components/drag-and-drop/validation-error-message/validation-error-message.component';
+import { ValidationErrorMessageComponent } from './components/drag-and-drop/validation-error-message/validation-error-message.component';
import { EligibilityIconComponent } from './components/eligibility-icon/eligibility-icon.component';
import { ErrorSummaryComponent } from './components/error-summary/error-summary.component';
+import { FundingRequirementsStateComponent } from './components/funding-requirements-state/funding-requirements-state.component';
import { InsetTextComponent } from './components/inset-text/inset-text.component';
-import {
- LinkToParentCancelDialogComponent,
-} from './components/link-to-parent-cancel/link-to-parent-cancel-dialog.component';
-import {
- LinkToParentRemoveDialogComponent,
-} from './components/link-to-parent-remove/link-to-parent-remove-dialog.component';
+import { LinkToParentCancelDialogComponent } from './components/link-to-parent-cancel/link-to-parent-cancel-dialog.component';
+import { LinkToParentRemoveDialogComponent } from './components/link-to-parent-remove/link-to-parent-remove-dialog.component';
import { LinkToParentDialogComponent } from './components/link-to-parent/link-to-parent-dialog.component';
import { LinkWithArrowComponent } from './components/link-with-arrow/link-with-arrow.component';
import { MessagesComponent } from './components/messages/messages.component';
import { MoveWorkplaceDialogComponent } from './components/move-workplace/move-workplace-dialog.component';
-import {
- NavigateToWorkplaceDropdownComponent,
-} from './components/navigate-to-workplace-dropdown/navigate-to-workplace-dropdown.component';
+import { NavigateToWorkplaceDropdownComponent } from './components/navigate-to-workplace-dropdown/navigate-to-workplace-dropdown.component';
import { NewBackLinkComponent } from './components/new-back-link/new-back-link.component';
import { NewTabsComponent } from './components/new-tabs/new-tabs.component';
import { WDFTabComponent } from './components/new-wdf-tabs/new-wdf-tab.component';
import { WDFWorkplaceSummaryComponent } from './components/new-wdf-workplace-summary/wdf-workplace-summary.component';
import { NewWorkplaceSummaryComponent } from './components/new-workplace-summary/workplace-summary.component';
import { OtherLinksComponent } from './components/other-links/other-links.component';
-import {
- OwnershipChangeMessageDialogComponent,
-} from './components/ownership-change-message/ownership-change-message-dialog.component';
+import { OwnershipChangeMessageDialogComponent } from './components/ownership-change-message/ownership-change-message-dialog.component';
import { PageComponent } from './components/page/page.component';
import { PaginationComponent } from './components/pagination/pagination.component';
import { PanelComponent } from './components/panel/panel.component';
import { PhaseBannerComponent } from './components/phase-banner/phase-banner.component';
import { ProgressBarComponent } from './components/progress-bar/progress-bar.component';
import { ProgressComponent } from './components/progress/progress.component';
-import {
- RegistrationSubmitButtonsComponent,
-} from './components/registration-submit-buttons/registration-submit-buttons.component';
+import { RegistrationSubmitButtonsComponent } from './components/registration-submit-buttons/registration-submit-buttons.component';
import { RejectRequestDialogComponent } from './components/reject-request-dialog/reject-request-dialog.component';
-import {
- RemoveParentConfirmationComponent,
-} from './components/remove-parent-confirmation/remove-parent-confirmation.component';
+import { RemoveParentConfirmationComponent } from './components/remove-parent-confirmation/remove-parent-confirmation.component';
import { ReviewCheckboxComponent } from './components/review-checkbox/review-checkbox.component';
import { SearchInputComponent } from './components/search-input/search-input.component';
-import {
- SelectUploadCertificateComponent,
-} from './components/select-upload-certificate/select-upload-certificate.component';
+import { SelectUploadCertificateComponent } from './components/select-upload-certificate/select-upload-certificate.component';
import { SelectUploadFileComponent } from './components/select-upload-file/select-upload-file.component';
-import {
- SelectWorkplaceDropdownFormComponent,
-} from './components/select-workplace-dropdown-form/select-workplace-dropdown-form.component';
-import {
- SelectWorkplaceRadioButtonFormComponent,
-} from './components/select-workplace-radio-button-form/select-workplace-radio-button-form.component';
+import { SelectViewPanelComponent } from './components/select-view-panel/select-view-panel.component';
+import { SelectWorkplaceDropdownFormComponent } from './components/select-workplace-dropdown-form/select-workplace-dropdown-form.component';
+import { SelectWorkplaceRadioButtonFormComponent } from './components/select-workplace-radio-button-form/select-workplace-radio-button-form.component';
import { SetDataPermissionDialogComponent } from './components/set-data-permission/set-data-permission-dialog.component';
import { BasicRecordComponent } from './components/staff-record-summary/basic-record/basic-record.component';
import { EmploymentComponent } from './components/staff-record-summary/employment/employment.component';
import { PersonalDetailsComponent } from './components/staff-record-summary/personal-details/personal-details.component';
-import {
- QualificationsAndTrainingComponent,
-} from './components/staff-record-summary/qualifications-and-training/qualifications-and-training.component';
+import { QualificationsAndTrainingComponent } from './components/staff-record-summary/qualifications-and-training/qualifications-and-training.component';
import { StaffRecordSummaryComponent } from './components/staff-record-summary/staff-record-summary.component';
+import { WdfWarningMessageComponent } from './components/staff-record-summary/wdf-warning-message/wdf-warning-message.component';
import { StaffRecordsTabComponent } from './components/staff-records-tab/staff-records-tab.component';
import { StaffSummaryComponent } from './components/staff-summary/staff-summary.component';
import { StatusComponent } from './components/status/status.component';
@@ -120,35 +91,22 @@ import { TabComponent } from './components/tabs/tab.component';
import { TabsComponent } from './components/tabs/tabs.component';
import { TotalStaffPanelComponent } from './components/total-staff-panel/total-staff-panel.component';
import { TotalStaffComponent } from './components/total-staff/total-staff.component';
-import {
- TrainingAndQualificationsCategoriesComponent,
-} from './components/training-and-qualifications-categories/training-and-qualifications-categories.component';
-import {
- ViewTrainingComponent,
-} from './components/training-and-qualifications-categories/view-trainings/view-trainings.component';
-import {
- TrainingAndQualificationsSummaryComponent,
-} from './components/training-and-qualifications-summary/training-and-qualifications-summary.component';
-import {
- TrainingAndQualificationsTabComponent,
-} from './components/training-and-qualifications-tab/training-and-qualifications-tab.component';
+import { TrainingAndQualificationsCategoriesComponent } from './components/training-and-qualifications-categories/training-and-qualifications-categories.component';
+import { ViewTrainingComponent } from './components/training-and-qualifications-categories/view-trainings/view-trainings.component';
+import { TrainingAndQualificationsSummaryComponent } from './components/training-and-qualifications-summary/training-and-qualifications-summary.component';
+import { TrainingAndQualificationsTabComponent } from './components/training-and-qualifications-tab/training-and-qualifications-tab.component';
import { TrainingInfoPanelComponent } from './components/training-info-panel/training-info-panel.component';
import { TrainingLinkPanelComponent } from './components/training-link-panel/training-link-panel.component';
-import {
- TrainingSelectViewPanelComponent,
-} from './components/training-select-view-panel/training-select-view-panel.component';
+import { TrainingSelectViewPanelComponent } from './components/training-select-view-panel/training-select-view-panel.component';
import { UserAccountsSummaryComponent } from './components/user-accounts-summary/user-accounts-summary.component';
import { UserFormComponent } from './components/user-form/user-form.component';
import { UserTableComponent } from './components/users-table/user.table.component';
import { WdfConfirmationPanelComponent } from './components/wdf-confirmation-panel/wdf-confirmation-panel.component';
import { WdfFieldConfirmationComponent } from './components/wdf-field-confirmation/wdf-field-confirmation.component';
-import {
- WdfStaffMismatchMessageComponent,
-} from './components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component';
+import { WdfStaffMismatchMessageComponent } from './components/wdf-staff-mismatch-message/wdf-staff-mismatch-message.component';
+import { WdfSummaryPanel } from './components/wdf-summary-panel/wdf-summary-panel.component';
import { WdfTabComponent } from './components/wdf-tab/wdf-tab.component';
-import {
- WorkplaceContinueCancelButtonComponent,
-} from './components/workplace-continue-cancel-button.component/workplace-continue-cancel-button.component';
+import { WorkplaceContinueCancelButtonComponent } from './components/workplace-continue-cancel-button.component/workplace-continue-cancel-button.component';
import { WorkplaceSubmitButtonComponent } from './components/workplace-submit-button/workplace-submit-button.component';
import { WorkplaceSummaryComponent } from './components/workplace-summary/workplace-summary.component';
import { FileValueAccessorDirective } from './form-controls/file-control-value-accessor';
@@ -295,6 +253,10 @@ import { WorkplacePermissionsBearerPipe } from './pipes/workplace-permissions-be
CertificationsTableComponent,
SelectUploadFileComponent,
SelectUploadCertificateComponent,
+ WdfWarningMessageComponent,
+ WdfSummaryPanel,
+ FundingRequirementsStateComponent,
+ SelectViewPanelComponent,
],
exports: [
AbsoluteNumberPipe,
@@ -416,6 +378,10 @@ import { WorkplacePermissionsBearerPipe } from './pipes/workplace-permissions-be
CertificationsTableComponent,
SelectUploadFileComponent,
SelectUploadCertificateComponent,
+ WdfWarningMessageComponent,
+ WdfSummaryPanel,
+ FundingRequirementsStateComponent,
+ SelectViewPanelComponent,
],
providers: [DialogService, TotalStaffComponent, ArticleListResolver, PageResolver],
})
diff --git a/frontend/src/assets/images/benchmarks.svg b/frontend/src/assets/images/benchmarks.svg
index f258ee62ac..00cdacd4d6 100644
--- a/frontend/src/assets/images/benchmarks.svg
+++ b/frontend/src/assets/images/benchmarks.svg
@@ -1,95 +1,285 @@
-
-
- Benchmarks
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/assets/images/large-green-tick.svg b/frontend/src/assets/images/large-green-tick.svg
new file mode 100644
index 0000000000..d55138d6b8
--- /dev/null
+++ b/frontend/src/assets/images/large-green-tick.svg
@@ -0,0 +1,14 @@
+
+
+ Group
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/assets/images/large-orange-flag.svg b/frontend/src/assets/images/large-orange-flag.svg
new file mode 100644
index 0000000000..bbb40c67e2
--- /dev/null
+++ b/frontend/src/assets/images/large-orange-flag.svg
@@ -0,0 +1,19 @@
+
+
+ Group
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/assets/images/large-red-flag.svg b/frontend/src/assets/images/large-red-flag.svg
new file mode 100644
index 0000000000..26ac552be5
--- /dev/null
+++ b/frontend/src/assets/images/large-red-flag.svg
@@ -0,0 +1,19 @@
+
+
+ Group
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/assets/images/red-flag-wdf-table.svg b/frontend/src/assets/images/red-flag-wdf-table.svg
new file mode 100644
index 0000000000..b7738553ab
--- /dev/null
+++ b/frontend/src/assets/images/red-flag-wdf-table.svg
@@ -0,0 +1,23 @@
+
+
+ Cross icon
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/assets/images/wdf.svg b/frontend/src/assets/images/wdf.svg
index 58443815a3..58fa3b6046 100644
--- a/frontend/src/assets/images/wdf.svg
+++ b/frontend/src/assets/images/wdf.svg
@@ -4,288 +4,210 @@
viewBox="0 0 380 212" style="enable-background:new 0 0 380 212;" xml:space="preserve">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
diff --git a/frontend/src/assets/scss/components/_summary-list.scss b/frontend/src/assets/scss/components/_summary-list.scss
index e8ab5b2ca1..ab8d93454e 100644
--- a/frontend/src/assets/scss/components/_summary-list.scss
+++ b/frontend/src/assets/scss/components/_summary-list.scss
@@ -93,8 +93,17 @@
}
.asc-summary-list--wide-value {
+ .govuk-summary-list__key {
+ width: 35%;
+ }
+
.govuk-summary-list__value {
- width: 70%;
+ width: 55%;
+ padding-left: 15px;
+ }
+
+ .govuk-summary-list__actions {
+ width: 10%;
}
}
@@ -151,13 +160,19 @@
}
}
}
+
.govuk-summary-list--wide-key {
.govuk-summary-list__key {
- width: 40%;
+ width: 45%;
}
.govuk-summary-list__value {
- width: 60%;
+ width: 45%;
+ padding-left: 15px;
+ }
+
+ .govuk-summary-list__actions {
+ width: 10%;
}
}