Skip to content

Commit 3829756

Browse files
[PRMP-731] Fix screenspace issue with pdf-viewer at high zoom (#844)
Co-authored-by: Kamen Bachvarov <[email protected]>
1 parent 583318d commit 3829756

File tree

5 files changed

+135
-13
lines changed

5 files changed

+135
-13
lines changed

app/cypress/e2e/0-ndr-core-tests/gp_user_workflows/view_lloyd_george_workflow.cy.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,21 @@ describe('GP Workflow: View Lloyd George record', () => {
5151
cy.getByTestId('patient-summary-date-of-birth').should('have.text', `1 January 1970`);
5252
};
5353

54+
const assertPatientInfoSmall = () => {
55+
cy.getByTestId('patient-summary-full-name').should(
56+
'have.text',
57+
`${searchPatientPayload.familyName}, ${searchPatientPayload.givenName}`,
58+
);
59+
cy.getByTestId('patient-summary-small-nhs-number').should(
60+
'have.text',
61+
`NHS number: 900 000 0009`,
62+
);
63+
cy.getByTestId('patient-summary-small-date-of-birth').should(
64+
'have.text',
65+
`Date of birth: 1 January 1970`,
66+
);
67+
};
68+
5469
const beforeEachConfiguration = (role) => {
5570
cy.login(role);
5671
cy.navigateToPatientSearchPage();
@@ -112,7 +127,7 @@ describe('GP Workflow: View Lloyd George record', () => {
112127
}
113128

114129
// Assert
115-
assertPatientInfo();
130+
assertPatientInfoSmall();
116131
cy.getByTestId('pdf-card').should('not.exist');
117132
cy.getByTestId('pdf-viewer').should('be.visible');
118133

app/src/components/blocks/_lloydGeorge/lloydGeorgeViewRecordStage/LloydGeorgeViewRecordStage.test.tsx

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Imports
2-
import { render, screen, waitFor } from '@testing-library/react';
2+
import { render, screen, waitFor, act } from '@testing-library/react';
33
import userEvent from '@testing-library/user-event';
44
import { createMemoryHistory } from 'history';
55
import * as ReactRouter from 'react-router-dom';
@@ -65,6 +65,20 @@ const TestApp = (props: Omit<Props, 'setStage' | 'stage'>) => {
6565
);
6666
};
6767

68+
const simulateFullscreenChange = (isFullscreen: boolean) => {
69+
act(() => {
70+
// Update the fullscreenElement property to simulate browser state
71+
Object.defineProperty(document, 'fullscreenElement', {
72+
writable: true,
73+
configurable: true,
74+
value: isFullscreen ? document.documentElement : null,
75+
});
76+
77+
// Dispatch the fullscreenchange event
78+
document.dispatchEvent(new Event('fullscreenchange'));
79+
});
80+
};
81+
6882
const renderComponent = (propsOverride?: Partial<Props>) => {
6983
const props: Omit<Props, 'setStage' | 'stage'> = {
7084
downloadStage: DOWNLOAD_STAGE.SUCCEEDED,
@@ -89,10 +103,23 @@ describe('<LloydGeorgeViewRecordStage />', () => {
89103
import.meta.env.VITE_ENVIRONMENT = 'vitest';
90104
mockedUsePatient.mockReturnValue(mockPatientDetails);
91105
mockUseConfig.mockReturnValue(buildConfig());
92-
});
93-
94-
afterEach(() => {
95-
vi.clearAllMocks();
106+
107+
// Mock fullscreen API
108+
Object.defineProperty(document, 'fullscreenEnabled', {
109+
writable: true,
110+
configurable: true,
111+
value: true,
112+
});
113+
114+
Object.defineProperty(document, 'fullscreenElement', {
115+
writable: true,
116+
configurable: true,
117+
value: null,
118+
});
119+
120+
// Mock fullscreen methods
121+
(document as any).exitFullscreen = vi.fn();
122+
(document.documentElement as any).requestFullscreen = vi.fn();
96123
});
97124

98125
describe('Rendering', () => {
@@ -135,11 +162,14 @@ describe('<LloydGeorgeViewRecordStage />', () => {
135162

136163
await screen.findByTitle(EMBEDDED_PDF_VIEWER_TITLE);
137164
await userEvent.click(screen.getByText('View in full screen'));
165+
166+
// Simulate the browser entering fullscreen
167+
simulateFullscreenChange(true);
138168

139169
await screen.findByText('Exit full screen');
140170

141171
expect(screen.getByText(patientName)).toBeInTheDocument();
142-
expect(screen.getByText(dob)).toBeInTheDocument();
172+
expect(screen.getByText(new RegExp(dob))).toBeInTheDocument();
143173
expect(screen.getByText(/NHS number/)).toBeInTheDocument();
144174
});
145175

@@ -154,7 +184,12 @@ describe('<LloydGeorgeViewRecordStage />', () => {
154184
renderComponent();
155185

156186
await userEvent.click(await screen.findByText('View in full screen'));
187+
// Simulate entering fullscreen
188+
simulateFullscreenChange(true);
189+
157190
await userEvent.click(await screen.findByText('Exit full screen'));
191+
// Simulate exiting fullscreen
192+
simulateFullscreenChange(false);
158193

159194
expect(screen.getByText('View in full screen')).toBeInTheDocument();
160195
});
@@ -223,6 +258,9 @@ describe('<LloydGeorgeViewRecordStage />', () => {
223258
await userEvent.click(
224259
await screen.findByRole('button', { name: 'View in full screen' }),
225260
);
261+
262+
// Simulate entering fullscreen
263+
simulateFullscreenChange(true);
226264

227265
await screen.findByText('Exit full screen');
228266

app/src/components/blocks/_lloydGeorge/lloydGeorgeViewRecordStage/LloydGeorgeViewRecordStage.tsx

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ function LloydGeorgeViewRecordStage({
5555
} else if (document.fullscreenElement !== null) {
5656
document.exitFullscreen?.();
5757
}
58-
59-
setUserSession({ ...session, isFullscreen });
58+
// Note: Let the fullscreen event handlers manage the session state to avoid race conditions
6059
};
6160

6261
let recordLinksToShow = getUserRecordActionLinks({ role, hasRecordInStorage }).map((link) => {
@@ -88,6 +87,26 @@ function LloydGeorgeViewRecordStage({
8887
}
8988
}, [refreshRecord, resetDocState]);
9089

90+
// Handle fullscreen changes from browser events
91+
useEffect(() => {
92+
const handleFullscreenChange = () => {
93+
const isCurrentlyFullscreen = document.fullscreenElement !== null;
94+
// Only update if the state has actually changed to avoid unnecessary re-renders
95+
if (session.isFullscreen !== isCurrentlyFullscreen) {
96+
setUserSession({
97+
...session,
98+
isFullscreen: isCurrentlyFullscreen
99+
});
100+
}
101+
};
102+
103+
document.addEventListener('fullscreenchange', handleFullscreenChange);
104+
105+
return () => {
106+
document.removeEventListener('fullscreenchange', handleFullscreenChange);
107+
};
108+
}, [session, setUserSession]);
109+
91110
const menuClass = showMenu ? '--menu' : '--upload';
92111

93112
return (
@@ -137,7 +156,7 @@ function LloydGeorgeViewRecordStage({
137156
</>
138157
)}
139158

140-
<PatientSummary showDeceasedTag>
159+
<PatientSummary showDeceasedTag oneLine={session.isFullscreen}>
141160
<PatientSummary.Child item={PatientInfo.FULL_NAME} />
142161
<PatientSummary.Child item={PatientInfo.NHS_NUMBER} />
143162
<PatientSummary.Child item={PatientInfo.BIRTH_DATE} />
@@ -151,7 +170,7 @@ function LloydGeorgeViewRecordStage({
151170
/>
152171
)}
153172

154-
{hasRecordInStorage && config.featureFlags.uploadLloydGeorgeWorkflowEnabled && (
173+
{!session.isFullscreen && hasRecordInStorage && config.featureFlags.uploadLloydGeorgeWorkflowEnabled && (
155174
<>
156175
<h2>Uploading files</h2>
157176
<p>

app/src/components/generic/patientSummary/PatientSummary.tsx

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { JSX, ReactNode, createContext, useContext } from 'react';
1+
import { JSX, ReactNode, createContext, useContext, useMemo } from 'react';
22
import usePatient from '../../../helpers/hooks/usePatient';
3-
import { getFormattedDateFromString } from '../../../helpers/utils/formatDate';
3+
import { getFormattedDate, getFormattedDateFromString } from '../../../helpers/utils/formatDate';
44
import { SummaryList, Tag } from 'nhsuk-react-components';
55
import type { PatientDetails } from '../../../types/generic/patientDetails';
66
import { formatNhsNumber } from '../../../helpers/utils/formatNhsNumber';
@@ -15,6 +15,7 @@ import { getFormattedPatientFullName } from '../../../helpers/utils/formatPatien
1515
type PatientSummaryProps = {
1616
showDeceasedTag?: boolean;
1717
children?: ReactNode;
18+
oneLine?: boolean;
1819
};
1920

2021
// Context for sharing patient data and configuration
@@ -124,8 +125,56 @@ const Details: React.FC<{ item: PatientInfo }> = ({ item }) => {
124125
const PatientSummary = ({
125126
showDeceasedTag = false,
126127
children,
128+
oneLine,
127129
}: PatientSummaryProps): JSX.Element => {
128130
const patientDetails = usePatient();
131+
const patientDetailsContextValue = useMemo(() => ({ patientDetails }), [patientDetails]);
132+
133+
if (oneLine) {
134+
const nameLengthLimit = 30;
135+
const givenName = patientDetails?.givenName.join(' ') || '';
136+
const familyName = patientDetails?.familyName || '';
137+
const longname = givenName.length + familyName.length > nameLengthLimit;
138+
139+
return (
140+
<PatientSummaryContext.Provider value={patientDetailsContextValue}>
141+
<>
142+
{showDeceasedTag && patientDetails?.deceased && (
143+
<Tag color="blue" className="mb-6" data-testid="deceased-patient-tag">
144+
Deceased patient
145+
</Tag>
146+
)}
147+
<div
148+
id="patient-info"
149+
data-testid="patient-info"
150+
className="lloydgeorge_record-stage_patient-info"
151+
>
152+
<p>
153+
<span
154+
data-testid="patient-summary-full-name"
155+
className="nhsuk-u-padding-right-9 nhsuk-u-font-weight-bold"
156+
>
157+
{getFormattedPatientFullName(patientDetails)}
158+
</span>
159+
160+
{longname && <br />}
161+
162+
<span
163+
data-testid="patient-summary-small-nhs-number"
164+
className="nhsuk-u-padding-right-9"
165+
>
166+
NHS number: {formatNhsNumber(patientDetails!.nhsNumber)}
167+
</span>
168+
<span data-testid="patient-summary-small-date-of-birth">
169+
Date of birth:{' '}
170+
{getFormattedDate(new Date(patientDetails!.birthDate))}
171+
</span>
172+
</p>
173+
</div>
174+
</>
175+
</PatientSummaryContext.Provider>
176+
);
177+
}
129178

130179
// If children are provided, use compound component pattern
131180
if (children) {

app/src/styles/App.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,7 @@ $hunit: '%';
826826

827827
#pdf-viewer {
828828
height: 75vh;
829+
min-height: fit-content;
829830

830831
&.upload-preview {
831832
height: 90vh;

0 commit comments

Comments
 (0)