From 1644ec17dd16992fd3feab885095857a233ccfd1 Mon Sep 17 00:00:00 2001
From: NogaNHS <127490765+NogaNHS@users.noreply.github.com>
Date: Tue, 20 Jan 2026 14:36:22 +0000
Subject: [PATCH 1/2] Add download report feature to Admin and Home pages
---
app/src/pages/adminPage/AdminPage.test.tsx | 22 ++++++++
app/src/pages/adminPage/AdminPage.tsx | 26 +++++++--
app/src/pages/homePage/HomePage.test.tsx | 32 +++++++++++-
app/src/pages/homePage/HomePage.tsx | 61 ++++++++++++----------
4 files changed, 107 insertions(+), 34 deletions(-)
diff --git a/app/src/pages/adminPage/AdminPage.test.tsx b/app/src/pages/adminPage/AdminPage.test.tsx
index 5d43d2b95..d0654e26d 100644
--- a/app/src/pages/adminPage/AdminPage.test.tsx
+++ b/app/src/pages/adminPage/AdminPage.test.tsx
@@ -44,6 +44,28 @@ describe('AdminPage', (): void => {
),
).toBeInTheDocument();
});
+
+ it('renders the Download a report card', (): void => {
+ render();
+ const reportLink = screen.getByTestId('download-report-btn');
+ expect(reportLink).toBeInTheDocument();
+ expect(reportLink).toHaveTextContent('Download a report');
+ });
+
+ it('renders the Download a report card with correct href', (): void => {
+ render();
+ const reportLink = screen.getByTestId('download-report-btn');
+ expect(reportLink).toHaveAttribute('href', '/create-report?reportType=0');
+ });
+
+ it('renders the Download a report card description', (): void => {
+ render();
+ expect(
+ screen.getByText(
+ 'This report shows the list of Lloyd George records stored for your organisation.',
+ ),
+ ).toBeInTheDocument();
+ });
});
describe('Accessibility', (): void => {
diff --git a/app/src/pages/adminPage/AdminPage.tsx b/app/src/pages/adminPage/AdminPage.tsx
index 88def26be..63f6cea11 100644
--- a/app/src/pages/adminPage/AdminPage.tsx
+++ b/app/src/pages/adminPage/AdminPage.tsx
@@ -2,7 +2,8 @@ import { Card } from 'nhsuk-react-components';
import { JSX } from 'react';
import useTitle from '../../helpers/hooks/useTitle';
import { ReactComponent as RightCircleIcon } from '../../styles/right-chevron-circle.svg';
-import { routeChildren } from '../../types/generic/routes';
+import { routeChildren, routes } from '../../types/generic/routes';
+import { REPORT_TYPE } from '../../types/generic/reports';
import { useNavigate } from 'react-router-dom';
export const AdminPage = (): JSX.Element => {
@@ -19,9 +20,9 @@ export const AdminPage = (): JSX.Element => {
{
- navigate(routeChildren.ADMIN_REVIEW)
+ navigate(routeChildren.ADMIN_REVIEW);
}}
>
Review documents
@@ -35,6 +36,25 @@ export const AdminPage = (): JSX.Element => {
+
+
+
+
+
+ Download a report
+
+
+
+ This report shows the list of Lloyd George records stored for your
+ organisation.
+
+
+
+
+
>
);
diff --git a/app/src/pages/homePage/HomePage.test.tsx b/app/src/pages/homePage/HomePage.test.tsx
index c173a1cb8..edd9f6a84 100644
--- a/app/src/pages/homePage/HomePage.test.tsx
+++ b/app/src/pages/homePage/HomePage.test.tsx
@@ -31,9 +31,11 @@ describe('HomePage', () => {
});
describe('Rendering', () => {
- it('should render home page with patient search and download report', async () => {
+ it('should render home page with patient search and download report when uploadDocumentIteration3Enabled is false', async () => {
+ mockUseConfig.mockReturnValue(
+ buildConfig(undefined, { uploadDocumentIteration3Enabled: false }),
+ );
render();
-
const searchPatientButton = screen.getByTestId(
'search-patient-btn',
) as HTMLAnchorElement;
@@ -67,6 +69,32 @@ describe('HomePage', () => {
expect(screen.queryByTestId('admin-console-btn')).not.toBeInTheDocument();
});
+
+ it('should render home page with patient search and admin console when uploadDocumentIteration3Enabled is true', async () => {
+ mockUseConfig.mockReturnValue(
+ buildConfig(undefined, { uploadDocumentIteration3Enabled: true }),
+ );
+ render();
+ const searchPatientButton = screen.getByTestId(
+ 'search-patient-btn',
+ ) as HTMLAnchorElement;
+ const adminConsoleButton = screen.getByTestId('admin-console-btn') as HTMLAnchorElement;
+ expect(searchPatientButton).toBeInTheDocument();
+ expect(adminConsoleButton).toBeInTheDocument();
+ expect(adminConsoleButton).toHaveTextContent('Admin console');
+ expect(adminConsoleButton).toHaveAttribute('href', '#');
+ expect(screen.queryByTestId('download-report-btn')).not.toBeInTheDocument();
+ });
+
+ it('does not render admin console button when feature flag is disabled', () => {
+ mockUseConfig.mockReturnValue(
+ buildConfig(undefined, { uploadDocumentIteration3Enabled: false }),
+ );
+
+ render();
+
+ expect(screen.queryByTestId('admin-console-btn')).not.toBeInTheDocument();
+ });
});
describe('Navigation', () => {
diff --git a/app/src/pages/homePage/HomePage.tsx b/app/src/pages/homePage/HomePage.tsx
index e6402576a..d24a8cb0c 100644
--- a/app/src/pages/homePage/HomePage.tsx
+++ b/app/src/pages/homePage/HomePage.tsx
@@ -27,9 +27,9 @@ const HomePage = (): React.JSX.Element => {
{
- navigate(routes.SEARCH_PATIENT)
+ navigate(routes.SEARCH_PATIENT);
}}
>
View or upload a patient record
@@ -45,9 +45,9 @@ const HomePage = (): React.JSX.Element => {
{
- navigate(routes.SEARCH_PATIENT)
+ navigate(routes.SEARCH_PATIENT);
}}
>
Search for a patient
@@ -63,16 +63,16 @@ const HomePage = (): React.JSX.Element => {
- {config.featureFlags.uploadDocumentIteration3Enabled && (
+ {config.featureFlags.uploadDocumentIteration3Enabled ? (
{
- navigate(routes.ADMIN_ROUTE)
+ navigate(routes.ADMIN_ROUTE);
}}
>
Admin console
@@ -85,29 +85,32 @@ const HomePage = (): React.JSX.Element => {
+ ) : (
+
+
+
+
+ {
+ navigate(
+ `${routes.REPORT_DOWNLOAD}?reportType=${REPORT_TYPE.ODS_PATIENT_SUMMARY}`,
+ );
+ }}
+ >
+ Download a report
+
+
+
+ This report shows the list of Lloyd George records stored for
+ your organisation.
+
+
+
+
+
)}
-
-
-
-
- {
- navigate(`${routes.REPORT_DOWNLOAD}?reportType=${REPORT_TYPE.ODS_PATIENT_SUMMARY}`)
- }}
- >
- Download a report
-
-
-
- This report shows the list of Lloyd George records stored for your
- organisation.
-
-
-
-
-
>
);
From 65a6d03218c15fb60909766c64f3f2425639e7de Mon Sep 17 00:00:00 2001
From: steph-torres-nhs <173282814+steph-torres-nhs@users.noreply.github.com>
Date: Mon, 26 Jan 2026 09:14:11 +0000
Subject: [PATCH 2/2] [PRMP-991] conditional rendering of back link, download
report stage
---
.../DownloadReportSelectStage.test.tsx | 29 +++++++++++++++++++
.../DownloadReportSelectStage.tsx | 7 +++--
2 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/app/src/components/blocks/_downloadReport/downloadReportSelectStage/DownloadReportSelectStage.test.tsx b/app/src/components/blocks/_downloadReport/downloadReportSelectStage/DownloadReportSelectStage.test.tsx
index 82ba12dd3..3f7de871d 100644
--- a/app/src/components/blocks/_downloadReport/downloadReportSelectStage/DownloadReportSelectStage.test.tsx
+++ b/app/src/components/blocks/_downloadReport/downloadReportSelectStage/DownloadReportSelectStage.test.tsx
@@ -10,6 +10,8 @@ import downloadReport from '../../../../helpers/requests/downloadReport';
import { beforeEach, describe, expect, it, vi, MockedFunction, Mock } from 'vitest';
const mockDownloadReport = downloadReport as MockedFunction;
+const mockUseConfig = vi.fn();
+
const mockedUseNavigate = vi.fn();
vi.mock('react-router-dom', async () => {
@@ -27,9 +29,16 @@ vi.mock('../../../../helpers/utils/isLocal', () => ({
isMock: (): boolean => false,
}));
+vi.mock('../../../../helpers/hooks/useConfig', () => ({
+ default: (): unknown => mockUseConfig(),
+}));
+
describe('DownloadReportSelectStage', () => {
beforeEach(() => {
import.meta.env.VITE_ENVIRONMENT = 'vitest';
+ mockUseConfig.mockReturnValue({
+ featureFlags: {},
+ });
});
describe('Rendering', () => {
@@ -107,4 +116,24 @@ describe('DownloadReportSelectStage', () => {
expect(mockedUseNavigate).toHaveBeenCalledWith(routes.HOME);
});
});
+
+ it ('should navigate to admin hub, upload version 3 enabled', async () => {
+ mockUseConfig.mockReturnValue({
+ featureFlags: { uploadDocumentIteration3Enabled: true },
+ });
+
+ const report = getReportByType(REPORT_TYPE.ODS_PATIENT_SUMMARY);
+ render();
+
+ let backLink: Element;
+ backLink = screen.getByTestId('return-to-home-button');
+
+ expect(backLink).toHaveTextContent('Go back');
+
+ await userEvent.click(backLink);
+
+ await waitFor(() => {
+ expect(mockedUseNavigate).toHaveBeenCalledWith(routes.ADMIN_ROUTE);
+ })
+ });
});
diff --git a/app/src/components/blocks/_downloadReport/downloadReportSelectStage/DownloadReportSelectStage.tsx b/app/src/components/blocks/_downloadReport/downloadReportSelectStage/DownloadReportSelectStage.tsx
index 71ce19f83..cf83dd887 100644
--- a/app/src/components/blocks/_downloadReport/downloadReportSelectStage/DownloadReportSelectStage.tsx
+++ b/app/src/components/blocks/_downloadReport/downloadReportSelectStage/DownloadReportSelectStage.tsx
@@ -5,6 +5,7 @@ import { BackLink, Button } from 'nhsuk-react-components';
import downloadReport from '../../../../helpers/requests/downloadReport';
import useBaseAPIUrl from '../../../../helpers/hooks/useBaseAPIUrl';
import useBaseAPIHeaders from '../../../../helpers/hooks/useBaseAPIHeaders';
+import useConfig from '../../../../helpers/hooks/useConfig';
import { AxiosError } from 'axios';
import { isMock } from '../../../../helpers/utils/isLocal';
import { JSX, ReactNode, useRef } from 'react';
@@ -19,6 +20,7 @@ type Props = {
const DownloadReportSelectStage = (props: Props): JSX.Element => {
const baseUrl = useBaseAPIUrl();
const baseHeaders = useBaseAPIHeaders();
+ const config = useConfig();
const navigate = useNavigate();
const [downloading, setDownloading] = React.useState(false);
const [downloadError, setDownloadError] = React.useState(null);
@@ -28,6 +30,7 @@ const DownloadReportSelectStage = (props: Props): JSX.Element => {
navigate(`${routeChildren.REPORT_DOWNLOAD_COMPLETE}?reportType=${props.report.reportType}`);
};
+ const uploadV3Enabled: boolean = !!config.featureFlags.uploadDocumentIteration3Enabled;
const noDataContent = (): JSX.Element => {
return (
<>
@@ -131,11 +134,11 @@ const DownloadReportSelectStage = (props: Props): JSX.Element => {
asElement="a"
href='#'
onClick={(): void => {
- navigate(routes.HOME)
+ uploadV3Enabled ? navigate(routes.ADMIN_ROUTE) : navigate(routes.HOME);
}}
className="mb-5"
>
- Go to home
+ {uploadV3Enabled ? 'Go back' : 'Go to home'}
{downloadError && (