diff --git a/app/cypress/e2e/0-ndr-core-tests/homepage.cy.js b/app/cypress/e2e/0-ndr-core-tests/homepage.cy.js index ba635d03e..6695a970d 100644 --- a/app/cypress/e2e/0-ndr-core-tests/homepage.cy.js +++ b/app/cypress/e2e/0-ndr-core-tests/homepage.cy.js @@ -58,13 +58,13 @@ describe('Home Page', () => { 'have.text', 'Access and store digital patient documents', ); - cy.get('.nhsuk-header__navigation').should('not.exist'); + cy.get('.nhsuk-navigation-container').should('not.exist'); cy.get('.nhsuk-header__navigation-list').should('not.exist'); cy.login(Roles.GP_CLINICAL, true); cy.url().should('eq', baseUrl + patientSearchUrl); - cy.get('.nhsuk-header__navigation').should('exist'); + cy.get('.nhsuk-navigation-container').should('exist'); cy.get('.nhsuk-header__navigation-list').should('exist'); }, ); @@ -111,7 +111,7 @@ describe('Home Page', () => { 'You’re outside of Birmingham and Solihull (BSOL)', ); - cy.get('.nhsuk-header__navigation').should('exist'); + cy.get('.nhsuk-navigation-container').should('exist'); cy.get('.nhsuk-header__navigation-list').should('exist'); }, ); @@ -129,7 +129,7 @@ describe('Home Page', () => { 'You’re outside of Birmingham and Solihull (BSOL)', ); - cy.get('.nhsuk-header__navigation').should('exist'); + cy.get('.nhsuk-navigation-container').should('exist'); cy.get('.nhsuk-header__navigation-list').should('exist'); }, ); @@ -157,7 +157,7 @@ describe('Home Page', () => { cy.login(Roles.GP_CLINICAL); - cy.get('.nhsuk-header__navigation').should('exist'); + cy.get('.nhsuk-navigation-container').should('exist'); cy.get('.nhsuk-header__navigation-list').should('exist'); cy.intercept('GET', '/Auth/Logout', { diff --git a/app/package-lock.json b/app/package-lock.json index 8c4d99764..9de7c275c 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -19,8 +19,8 @@ "fake-progress": "^1.0.4", "history": "^5.3.0", "moment": "^2.30.1", - "nhsuk-frontend": "^7.0.0", - "nhsuk-react-components": "^2.2.2", + "nhsuk-frontend": "^9.1.0", + "nhsuk-react-components": "^5.0.0", "pdfobject": "^2.2.12", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -22575,19 +22575,22 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "node_modules/nhsuk-frontend": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/nhsuk-frontend/-/nhsuk-frontend-7.1.0.tgz", - "integrity": "sha512-V3GDwwAWgBOZHKlh8kdpq8hiOh/mbD95MQrgI1qych2yRFeMXdOg1439VkOmmdKBJT5zuy9BA//33aU5NzYfjw==" + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/nhsuk-frontend/-/nhsuk-frontend-9.1.0.tgz", + "integrity": "sha512-z2hcZDUDz12hjBTWLasq5lfX+sv2jwZFkUdip8qL9fBQ6qykyQFQ8PjWuBBgQN03IU0wMkV3BBLbwBjFiSxREQ==", + "engines": { + "node": ">=20.0.0" + } }, "node_modules/nhsuk-react-components": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/nhsuk-react-components/-/nhsuk-react-components-2.2.2.tgz", - "integrity": "sha512-jShzbw7Wi6Vb+KxFuBF9fWPHw9ZUxxUVaAWGsFsRrdc6+yBiA+q5x/DwxnGytq7+UFpN5on+kd8Q1jnrOkBn3A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nhsuk-react-components/-/nhsuk-react-components-5.0.0.tgz", + "integrity": "sha512-9QbYNEgLXdFaaEbrGs3IR9Gfn3M0a/6VH8a8fjPLWofl9FaP9HArpXh+eKz6D5YzUP6SmA0+0M8b84stJyBqdQ==", "dependencies": { "classnames": "^2.2.6" }, "peerDependencies": { - "nhsuk-frontend": ">=4.0.0", + "nhsuk-frontend": ">=9.0.0 <10.0.0", "react": ">=16.8.0", "react-dom": ">=16.8.0" } diff --git a/app/package.json b/app/package.json index 6797421de..1e2006753 100644 --- a/app/package.json +++ b/app/package.json @@ -32,8 +32,8 @@ "fake-progress": "^1.0.4", "history": "^5.3.0", "moment": "^2.30.1", - "nhsuk-frontend": "^7.0.0", - "nhsuk-react-components": "^2.2.2", + "nhsuk-frontend": "^9.1.0", + "nhsuk-react-components": "^5.0.0", "pdfobject": "^2.2.12", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/app/src/components/blocks/_arf/documentInputForm/DocumentInputForm.tsx b/app/src/components/blocks/_arf/documentInputForm/DocumentInputForm.tsx index db145e703..25225bd1d 100644 --- a/app/src/components/blocks/_arf/documentInputForm/DocumentInputForm.tsx +++ b/app/src/components/blocks/_arf/documentInputForm/DocumentInputForm.tsx @@ -1,4 +1,4 @@ -import { Input, Table, WarningCallout } from 'nhsuk-react-components'; +import { TextInput, Table, WarningCallout } from 'nhsuk-react-components'; import React from 'react'; import { DOCUMENT_TYPE, @@ -37,7 +37,7 @@ const DocumentInputForm = ({ }); return ( <> -
- ) => { + const handleChangeCheckboxes = (e: React.FormEvent) => { const target = e.target as HTMLInputElement; const toggledDocumentId = target.value; if (target.checked) { @@ -122,19 +122,18 @@ const AvailableFilesTable = ({ > {allowSelectDocument && ( - - - - {result.fileName} - - - + handleChangeCheckboxes(e)} + > + + {result.fileName} + + )} { }); }); - it('navigates to specified location when the "toLocation" property is defined' , async () => { - + it('navigates to specified location when the "toLocation" property is defined', async () => { render(); - userEvent.click( screen.getByText('Go back')); + userEvent.click(screen.getByText('Go back')); await waitFor(() => { expect(mockUseNavigate).toHaveBeenCalledWith('/specified-location'); }); - }); it('displays default back link text when "backLinkText" is not provided', async () => { - render(); - expect(screen.getByText('Go back')).toBeInTheDocument(); - + expect(screen.getByText('Go back')).toBeInTheDocument(); }); it('displays custom back link text when "backLinkText" is defined', async () => { - render(); expect(screen.getByText('navigate to ...')).toBeInTheDocument(); - }); - }); diff --git a/app/src/components/layout/header/Header.test.tsx b/app/src/components/layout/header/Header.test.tsx index 0ef5318b6..927868b69 100644 --- a/app/src/components/layout/header/Header.test.tsx +++ b/app/src/components/layout/header/Header.test.tsx @@ -46,7 +46,7 @@ describe('Header', () => { mockedUseRole.mockReturnValue(REPOSITORY_ROLE.GP_ADMIN); renderHeaderWithRouter(); - userEvent.click(screen.getByRole('img', { name: 'NHS Logo' })); + userEvent.click(screen.getByText('NHS Logo')); await waitFor(() => { expect(mockedUseNavigate).toHaveBeenCalledWith(routes.HOME); @@ -57,7 +57,7 @@ describe('Header', () => { mockedUseRole.mockReturnValue(null); renderHeaderWithRouter(); - userEvent.click(screen.getByRole('img', { name: 'NHS Logo' })); + userEvent.click(screen.getByText('NHS Logo')); await waitFor(() => { expect(mockedUseNavigate).toHaveBeenCalledWith(routes.START); diff --git a/app/src/components/layout/navLinks/NavLinks.tsx b/app/src/components/layout/navLinks/NavLinks.tsx index 4433aeae6..10c069e0e 100644 --- a/app/src/components/layout/navLinks/NavLinks.tsx +++ b/app/src/components/layout/navLinks/NavLinks.tsx @@ -1,4 +1,3 @@ -import React, { useEffect, useState } from 'react'; import type { MouseEvent as ReactEvent } from 'react'; import { Header } from 'nhsuk-react-components'; import { useNavigate } from 'react-router-dom'; @@ -8,69 +7,31 @@ import { useSessionContext } from '../../../providers/sessionProvider/SessionPro const NavLinks = () => { const navigate = useNavigate(); const [session] = useSessionContext(); - const [width, setWidth] = useState(window.innerWidth); const nav = (e: ReactEvent, link: string) => { e.preventDefault(); navigate(link); }; - useEffect(() => { - const handleResizeWindow = () => setWidth(window.innerWidth); - window.addEventListener('resize', handleResizeWindow); - return () => { - window.removeEventListener('resize', handleResizeWindow); - }; - }, []); - const appLinks = [ + { href: routes.START, label: 'Home', id: 'home-btn' }, { href: routes.SEARCH_PATIENT, label: 'Search for a patient', id: 'search-btn' }, { href: routes.LOGOUT, label: 'Sign out', id: 'logout-btn' }, ]; return session.isLoggedIn ? ( - - nav(e, routes.START)} - > - Home - - {width <= 990 ? ( - <> - {appLinks.map((l) => ( - nav(e, l.href)} - > - {l.label} - - ))} - - ) : ( -
- {appLinks.map((l) => ( - nav(e, l.href)} - > - {l.label} - - ))} -
- )} + + {appLinks.map((l) => ( + nav(e, l.href)} + > + {l.label} + + ))} ) : null; }; diff --git a/app/src/pages/feedbackPage/FeedbackPage.tsx b/app/src/pages/feedbackPage/FeedbackPage.tsx index aebd74b72..2d8f85ed5 100644 --- a/app/src/pages/feedbackPage/FeedbackPage.tsx +++ b/app/src/pages/feedbackPage/FeedbackPage.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { SubmitHandler, useForm, UseFormRegisterReturn } from 'react-hook-form'; import isEmail from 'validator/lib/isEmail'; -import { Button, Fieldset, Input, Radios, Textarea } from 'nhsuk-react-components'; +import { Button, Fieldset, TextInput, Radios, Textarea } from 'nhsuk-react-components'; import { useNavigate } from 'react-router-dom'; import { AxiosError } from 'axios'; import { @@ -133,7 +133,7 @@ function FeedbackPage() { us in developing this service.

- - { beforeEach(() => { @@ -50,14 +51,11 @@ describe('PatientResultPage', () => { render(); - expect( - screen.getByRole('heading', { name: PAGE_HEADER_TEXT }), - ).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: PAGE_HEADER_TEXT })).toBeInTheDocument(); expect(screen.getByText(familyName)).toBeInTheDocument(); expect( screen.getByRole('button', { name: CONFIRM_BUTTON_TEXT }), ).toBeInTheDocument(); - }, ); @@ -72,14 +70,8 @@ describe('PatientResultPage', () => { render(); - expect( - screen.getByRole('heading', { name: PAGE_HEADER_TEXT }), - ).toBeInTheDocument(); - expect( - screen.getByText( - PAGE_TEXT , - ), - ).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: PAGE_HEADER_TEXT })).toBeInTheDocument(); + expect(screen.getByText(PAGE_TEXT)).toBeInTheDocument(); }, ); @@ -93,20 +85,14 @@ describe('PatientResultPage', () => { render(); - expect( - screen.getByRole('heading', { name: PAGE_HEADER_TEXT }), - ).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: PAGE_HEADER_TEXT })).toBeInTheDocument(); expect(screen.queryByText('Select patient status')).not.toBeInTheDocument(); expect(screen.queryByRole('radio', { name: 'Active patient' })).not.toBeInTheDocument(); expect( screen.queryByRole('radio', { name: 'Inactive patient' }), ).not.toBeInTheDocument(); - expect( - screen.queryByText( - PAGE_TEXT, - ), - ).not.toBeInTheDocument(); + expect(screen.queryByText(PAGE_TEXT)).not.toBeInTheDocument(); }); it.each([REPOSITORY_ROLE.GP_ADMIN, REPOSITORY_ROLE.GP_CLINICAL])( @@ -141,9 +127,7 @@ describe('PatientResultPage', () => { render(); - expect( - screen.getByRole('heading', { name: PAGE_HEADER_TEXT }), - ).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: PAGE_HEADER_TEXT })).toBeInTheDocument(); expect( screen.getByText('The NHS number for this patient has changed.'), ).toBeInTheDocument(); @@ -160,9 +144,7 @@ describe('PatientResultPage', () => { render(); - expect( - screen.getByRole('heading', { name: PAGE_HEADER_TEXT }), - ).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: PAGE_HEADER_TEXT })).toBeInTheDocument(); expect( screen.getByText( 'Certain details about this patient cannot be displayed without the necessary access.', @@ -183,9 +165,7 @@ describe('PatientResultPage', () => { render(); - expect( - screen.getByRole('heading', { name: PAGE_HEADER_TEXT }), - ).toBeInTheDocument(); + expect(screen.getByRole('heading', { name: PAGE_HEADER_TEXT })).toBeInTheDocument(); const results = await runAxeTest(document.body); expect(results).toHaveNoViolations(); @@ -252,9 +232,7 @@ describe('PatientResultPage', () => { render(); act(() => { - userEvent.click( - screen.getByRole('button', { name: CONFIRM_BUTTON_TEXT }), - ); + userEvent.click(screen.getByRole('button', { name: CONFIRM_BUTTON_TEXT })); }); await waitFor(() => { diff --git a/app/src/pages/patientSearchPage/PatientSearchPage.test.tsx b/app/src/pages/patientSearchPage/PatientSearchPage.test.tsx index ab0cc84ba..5ddc6c91f 100644 --- a/app/src/pages/patientSearchPage/PatientSearchPage.test.tsx +++ b/app/src/pages/patientSearchPage/PatientSearchPage.test.tsx @@ -350,16 +350,13 @@ describe('PatientSearchPage', () => { ); it('a defined width class is applied to the NHS number input field', async () => { - const definedWidthClass = 'nhsuk-input--width-10'; renderPatientSearchPage(); const input = screen.getByTestId('nhs-number-input'); expect(input).toHaveClass(definedWidthClass); - }); - }); }); diff --git a/app/src/pages/patientSearchPage/PatientSearchPage.tsx b/app/src/pages/patientSearchPage/PatientSearchPage.tsx index 696f7a60a..c11f5d74b 100644 --- a/app/src/pages/patientSearchPage/PatientSearchPage.tsx +++ b/app/src/pages/patientSearchPage/PatientSearchPage.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { routes } from '../../types/generic/routes'; import { FieldValues, useForm } from 'react-hook-form'; import ErrorBox from '../../components/layout/errorBox/ErrorBox'; -import { Button, Input } from 'nhsuk-react-components'; +import { Button, Fieldset, TextInput } from 'nhsuk-react-components'; import SpinnerButton from '../../components/generic/spinnerButton/SpinnerButton'; import { InputRef } from '../../types/generic/inputRef'; import { useNavigate } from 'react-router-dom'; @@ -107,30 +107,31 @@ function PatientSearchPage() { )} )} -

{pageTitle}

- - +

{pageTitle}

+
+ +
{submissionState === SEARCH_STATES.SEARCHING ? (