@kenyaemr/esm-patient-registration-app 7.0.3-pre.89 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +16 -15
- package/dist/130.js +1 -1
- package/dist/130.js.map +1 -1
- package/dist/271.js +1 -1
- package/dist/319.js +1 -1
- package/dist/460.js +1 -1
- package/dist/564.js +1 -0
- package/dist/564.js.map +1 -0
- package/dist/623.js +1 -0
- package/dist/623.js.map +1 -0
- package/dist/644.js +1 -1
- package/dist/757.js +1 -1
- package/dist/788.js +1 -1
- package/dist/807.js +1 -1
- package/dist/831.js +2 -0
- package/dist/831.js.map +1 -0
- package/dist/833.js +1 -1
- package/dist/kenyaemr-esm-patient-registration-app.js +1 -1
- package/dist/kenyaemr-esm-patient-registration-app.js.buildmanifest.json +99 -99
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +2 -3
- package/src/add-patient-link.test.tsx +5 -9
- package/src/config-schema.ts +2 -0
- package/src/nav-link.test.tsx +3 -3
- package/src/patient-registration/field/address/address-field.component.tsx +2 -2
- package/src/patient-registration/field/address/address-hierarchy-levels.component.tsx +16 -18
- package/src/patient-registration/field/address/address-search.scss +5 -5
- package/src/patient-registration/field/address/tests/address-hierarchy.test.tsx +165 -95
- package/src/patient-registration/field/address/tests/address-search-component.test.tsx +18 -17
- package/src/patient-registration/field/dob/dob.component.tsx +3 -6
- package/src/patient-registration/field/dob/dob.test.tsx +69 -53
- package/src/patient-registration/field/field.scss +30 -25
- package/src/patient-registration/field/field.test.tsx +50 -52
- package/src/patient-registration/field/gender/gender-field.component.tsx +2 -2
- package/src/patient-registration/field/gender/gender-field.test.tsx +45 -27
- package/src/patient-registration/field/id/id-field.component.tsx +11 -12
- package/src/patient-registration/field/id/id-field.test.tsx +64 -49
- package/src/patient-registration/field/id/identifier-selection.scss +12 -8
- package/src/patient-registration/field/name/name-field.component.tsx +1 -1
- package/src/patient-registration/field/obs/obs-field.component.tsx +7 -12
- package/src/patient-registration/field/obs/obs-field.test.tsx +98 -62
- package/src/patient-registration/field/person-attributes/coded-person-attribute-field.test.tsx +9 -6
- package/src/patient-registration/field/person-attributes/person-attribute-field.test.tsx +49 -51
- package/src/patient-registration/field/person-attributes/text-person-attribute-field.test.tsx +2 -0
- package/src/patient-registration/input/basic-input/select/select-input.test.tsx +1 -1
- package/src/patient-registration/input/custom-input/autosuggest/autosuggest.scss +5 -5
- package/src/patient-registration/input/custom-input/autosuggest/autosuggest.test.tsx +75 -33
- package/src/patient-registration/input/custom-input/identifier/identifier-input.component.tsx +3 -1
- package/src/patient-registration/input/custom-input/identifier/identifier-input.test.tsx +9 -12
- package/src/patient-registration/input/dummy-data/dummy-data-input.test.tsx +2 -11
- package/src/patient-registration/input/input.scss +12 -12
- package/src/patient-registration/patient-registration-context.ts +6 -6
- package/src/patient-registration/patient-registration-utils.ts +4 -5
- package/src/patient-registration/patient-registration.component.tsx +4 -14
- package/src/patient-registration/patient-registration.resource.test.tsx +0 -4
- package/src/patient-registration/patient-registration.scss +11 -25
- package/src/patient-registration/patient-registration.test.tsx +75 -85
- package/src/patient-registration/patient-registration.types.ts +18 -18
- package/src/patient-registration/section/death-info/death-info-section.test.tsx +1 -10
- package/src/patient-registration/section/demographics/demographics-section.test.tsx +32 -29
- package/src/patient-registration/section/patient-relationships/relationships-section.test.tsx +16 -6
- package/src/patient-registration/section/patient-relationships/relationships.scss +4 -4
- package/src/patient-registration/section/section-wrapper.component.tsx +1 -1
- package/src/patient-registration/section/section.scss +16 -1
- package/src/patient-registration/ui-components/overlay/overlay.scss +8 -8
- package/src/patient-registration/validation/patient-registration-validation.test.tsx +35 -10
- package/src/patient-verification/patient-verification-utils.ts +0 -1
- package/src/widgets/cancel-patient-edit.test.tsx +0 -4
- package/src/widgets/delete-identifier-confirmation.scss +8 -8
- package/src/widgets/delete-identifier-confirmation.test.tsx +0 -4
- package/src/widgets/edit-patient-details-button.test.tsx +2 -8
- package/translations/am.json +4 -0
- package/translations/ar.json +4 -0
- package/translations/es.json +4 -0
- package/translations/fr.json +4 -0
- package/translations/he.json +4 -0
- package/translations/km.json +4 -0
- package/translations/zh.json +4 -0
- package/translations/zh_CN.json +4 -0
- package/dist/220.js +0 -2
- package/dist/220.js.map +0 -1
- package/dist/453.js +0 -1
- package/dist/453.js.map +0 -1
- package/dist/975.js +0 -1
- package/dist/975.js.map +0 -1
- package/src/root.test.tsx +0 -32
- /package/dist/{220.js.LICENSE.txt → 831.js.LICENSE.txt} +0 -0
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
@use '@carbon/layout';
|
|
2
2
|
@use '@carbon/type';
|
|
3
|
-
@
|
|
4
|
-
|
|
5
|
-
.title {
|
|
6
|
-
color: var(--omrs-color-brand-teal);
|
|
7
|
-
}
|
|
3
|
+
@use '@openmrs/esm-styleguide/src/vars' as *;
|
|
8
4
|
|
|
9
5
|
.submit {
|
|
10
|
-
width:
|
|
6
|
+
width: 15.625rem;
|
|
11
7
|
}
|
|
12
8
|
|
|
13
9
|
.submit:hover {
|
|
@@ -32,6 +28,12 @@
|
|
|
32
28
|
max-width: 50rem;
|
|
33
29
|
}
|
|
34
30
|
|
|
31
|
+
:global(.omrs-breakpoint-lt-desktop) {
|
|
32
|
+
.infoGrid {
|
|
33
|
+
max-width: unset;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
35
37
|
.label01 {
|
|
36
38
|
@include type.type-style('label-01');
|
|
37
39
|
margin-top: layout.$spacing-05;
|
|
@@ -39,12 +41,6 @@
|
|
|
39
41
|
color: $ui-04;
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
.productiveHeading02 {
|
|
43
|
-
@include type.type-style('heading-compact-02');
|
|
44
|
-
color: $ui-04;
|
|
45
|
-
cursor: pointer;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
44
|
.space05 {
|
|
49
45
|
margin: layout.$spacing-05 0;
|
|
50
46
|
}
|
|
@@ -57,8 +53,8 @@
|
|
|
57
53
|
.stickyColumn {
|
|
58
54
|
position: sticky;
|
|
59
55
|
margin-top: layout.$spacing-05;
|
|
60
|
-
//
|
|
61
|
-
top:
|
|
56
|
+
// layout.$spacing-09 for the nav height and layout.$spacing-05 for top margin
|
|
57
|
+
top: layout.$spacing-10;
|
|
62
58
|
}
|
|
63
59
|
|
|
64
60
|
.touchTarget a:active {
|
|
@@ -83,18 +79,8 @@
|
|
|
83
79
|
}
|
|
84
80
|
}
|
|
85
81
|
|
|
86
|
-
.main {
|
|
87
|
-
background-color: white;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
:global(.omrs-breakpoint-lt-desktop) {
|
|
91
|
-
.infoGrid {
|
|
92
|
-
max-width: unset;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
82
|
.spinner {
|
|
97
|
-
min-height:
|
|
83
|
+
min-height: layout.$spacing-05;
|
|
98
84
|
width: max-content;
|
|
99
85
|
|
|
100
86
|
:global(.cds--inline-loading__text) {
|
|
@@ -1,24 +1,31 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import dayjs from 'dayjs';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
2
4
|
import { BrowserRouter as Router, useParams } from 'react-router-dom';
|
|
3
5
|
import { render, screen, within } from '@testing-library/react';
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
+
import {
|
|
7
|
+
type FetchResponse,
|
|
8
|
+
getDefaultsFromConfigSchema,
|
|
9
|
+
OpenmrsDatePicker,
|
|
10
|
+
showSnackbar,
|
|
11
|
+
useConfig,
|
|
12
|
+
usePatient,
|
|
13
|
+
} from '@openmrs/esm-framework';
|
|
14
|
+
import { mockedAddressTemplate } from '__mocks__';
|
|
15
|
+
import { mockPatient } from 'tools';
|
|
16
|
+
import { saveEncounter, savePatient } from './patient-registration.resource';
|
|
17
|
+
import { type RegistrationConfig, esmPatientRegistrationSchema } from '../config-schema';
|
|
6
18
|
import type { AddressTemplate, Encounter } from './patient-registration.types';
|
|
7
|
-
import { type RegistrationConfig } from '../config-schema';
|
|
8
|
-
import { FormManager } from './form-manager';
|
|
9
19
|
import { ResourcesContext } from '../offline.resources';
|
|
20
|
+
import { FormManager } from './form-manager';
|
|
10
21
|
import { PatientRegistration } from './patient-registration.component';
|
|
11
|
-
import { saveEncounter, savePatient } from './patient-registration.resource';
|
|
12
|
-
import { mockedAddressTemplate } from '__mocks__';
|
|
13
|
-
import { mockPatient } from 'tools';
|
|
14
|
-
import dayjs from 'dayjs';
|
|
15
|
-
import { CalendarDate, parseDate } from '@internationalized/date';
|
|
16
22
|
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
23
|
+
const mockSaveEncounter = jest.mocked(saveEncounter);
|
|
24
|
+
const mockSavePatient = savePatient as jest.Mock;
|
|
25
|
+
const mockShowSnackbar = jest.mocked(showSnackbar);
|
|
26
|
+
const mockUseConfig = jest.mocked(useConfig<RegistrationConfig>);
|
|
27
|
+
const mockUsePatient = jest.mocked(usePatient);
|
|
28
|
+
const mockOpenmrsDatePicker = jest.mocked(OpenmrsDatePicker);
|
|
22
29
|
|
|
23
30
|
jest.mock('./field/field.resource', () => ({
|
|
24
31
|
useConcept: jest.fn().mockImplementation((uuid: string) => {
|
|
@@ -86,38 +93,26 @@ jest.mock('react-router-dom', () => ({
|
|
|
86
93
|
useParams: jest.fn().mockReturnValue({ patientUuid: undefined }),
|
|
87
94
|
}));
|
|
88
95
|
|
|
89
|
-
jest.mock('./patient-registration.resource', () => {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
saveEncounter: jest.fn(),
|
|
95
|
-
savePatient: jest.fn(),
|
|
96
|
-
};
|
|
97
|
-
});
|
|
96
|
+
jest.mock('./patient-registration.resource', () => ({
|
|
97
|
+
...jest.requireActual('./patient-registration.resource'),
|
|
98
|
+
saveEncounter: jest.fn(),
|
|
99
|
+
savePatient: jest.fn(),
|
|
100
|
+
}));
|
|
98
101
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
onChange={(evt) => {
|
|
114
|
-
onChange(dayjs(evt.target.value).toDate());
|
|
115
|
-
}}
|
|
116
|
-
/>
|
|
117
|
-
</>
|
|
118
|
-
);
|
|
119
|
-
}),
|
|
120
|
-
};
|
|
102
|
+
mockOpenmrsDatePicker.mockImplementation(({ id, labelText, value, onChange }) => {
|
|
103
|
+
return (
|
|
104
|
+
<>
|
|
105
|
+
<label htmlFor={id}>{labelText}</label>
|
|
106
|
+
<input
|
|
107
|
+
id={id}
|
|
108
|
+
// @ts-ignore
|
|
109
|
+
value={value ? dayjs(value).format('DD/MM/YYYY') : ''}
|
|
110
|
+
onChange={(evt) => {
|
|
111
|
+
onChange(dayjs(evt.target.value).toDate());
|
|
112
|
+
}}
|
|
113
|
+
/>
|
|
114
|
+
</>
|
|
115
|
+
);
|
|
121
116
|
});
|
|
122
117
|
|
|
123
118
|
const mockResourcesContextValue = {
|
|
@@ -140,6 +135,9 @@ let mockOpenmrsConfig: RegistrationConfig = {
|
|
|
140
135
|
],
|
|
141
136
|
fieldDefinitions: [],
|
|
142
137
|
fieldConfigurations: {
|
|
138
|
+
phone: {
|
|
139
|
+
personAttributeUuid: '14d4f066-15f5-102d-96e4-000c29c2a5d7',
|
|
140
|
+
},
|
|
143
141
|
dateOfBirth: {
|
|
144
142
|
allowEstimatedDateOfBirth: true,
|
|
145
143
|
useEstimatedDateOfBirth: {
|
|
@@ -170,9 +168,6 @@ let mockOpenmrsConfig: RegistrationConfig = {
|
|
|
170
168
|
},
|
|
171
169
|
},
|
|
172
170
|
},
|
|
173
|
-
concepts: {
|
|
174
|
-
patientPhotoUuid: '736e8771-e501-4615-bfa7-570c03f4bef5',
|
|
175
|
-
},
|
|
176
171
|
links: {
|
|
177
172
|
submitButton: '#',
|
|
178
173
|
},
|
|
@@ -236,7 +231,6 @@ const fillRequiredFields = async () => {
|
|
|
236
231
|
const familyNameInput = within(demographicsSection).getByLabelText(/family/i) as HTMLInputElement;
|
|
237
232
|
const dateOfBirthInput = within(demographicsSection).getByLabelText(/date of birth/i) as HTMLInputElement;
|
|
238
233
|
const genderInput = within(demographicsSection).getByLabelText(/Male/) as HTMLSelectElement;
|
|
239
|
-
screen.debug(dateOfBirthInput);
|
|
240
234
|
await user.type(givenNameInput, 'Paul');
|
|
241
235
|
await user.type(familyNameInput, 'Gaihre');
|
|
242
236
|
await user.clear(dateOfBirthInput);
|
|
@@ -254,11 +248,11 @@ function Wrapper({ children }) {
|
|
|
254
248
|
|
|
255
249
|
describe('Registering a new patient', () => {
|
|
256
250
|
beforeEach(() => {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
251
|
+
mockUseConfig.mockReturnValue({
|
|
252
|
+
...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
|
|
253
|
+
...mockOpenmrsConfig,
|
|
254
|
+
});
|
|
255
|
+
mockSavePatient.mockReturnValue({ data: { uuid: 'new-pt-uuid' }, ok: true });
|
|
262
256
|
});
|
|
263
257
|
|
|
264
258
|
it('renders without crashing', () => {
|
|
@@ -268,8 +262,8 @@ describe('Registering a new patient', () => {
|
|
|
268
262
|
it('has the expected sections', async () => {
|
|
269
263
|
render(<PatientRegistration isOffline={false} savePatientForm={jest.fn()} />, { wrapper: Wrapper });
|
|
270
264
|
|
|
271
|
-
expect(screen.
|
|
272
|
-
expect(screen.
|
|
265
|
+
expect(screen.getByRole('region', { name: /demographics section/i })).toBeInTheDocument();
|
|
266
|
+
expect(screen.getByRole('region', { name: /contact info section/i })).toBeInTheDocument();
|
|
273
267
|
});
|
|
274
268
|
|
|
275
269
|
// TODO O3-3482: Fix this test case when OpenmrsDatePicker gets fixed on core
|
|
@@ -282,7 +276,7 @@ describe('Registering a new patient', () => {
|
|
|
282
276
|
|
|
283
277
|
await fillRequiredFields();
|
|
284
278
|
await user.click(await screen.findByText(/Register Patient/i));
|
|
285
|
-
expect(
|
|
279
|
+
expect(mockSavePatient).toHaveBeenCalledWith(
|
|
286
280
|
expect.objectContaining({
|
|
287
281
|
identifiers: [], //TODO when the identifer story is finished: { identifier: '', identifierType: '05a29f94-c0ed-11e2-94be-8c13b969e334', location: '' },
|
|
288
282
|
person: {
|
|
@@ -304,23 +298,23 @@ describe('Registering a new patient', () => {
|
|
|
304
298
|
it('should not save the patient if validation fails', async () => {
|
|
305
299
|
const user = userEvent.setup();
|
|
306
300
|
|
|
307
|
-
const
|
|
308
|
-
render(<PatientRegistration isOffline={false} savePatientForm={
|
|
301
|
+
const mockSavePatientForm = jest.fn();
|
|
302
|
+
render(<PatientRegistration isOffline={false} savePatientForm={mockSavePatientForm} />, { wrapper: Wrapper });
|
|
309
303
|
|
|
310
304
|
const givenNameInput = (await screen.findByLabelText('First Name')) as HTMLInputElement;
|
|
311
305
|
|
|
312
306
|
await user.type(givenNameInput, '5');
|
|
313
307
|
await user.click(screen.getByText(/Register Patient/i));
|
|
314
308
|
|
|
315
|
-
expect(
|
|
309
|
+
expect(mockSavePatientForm).not.toHaveBeenCalled();
|
|
316
310
|
});
|
|
317
311
|
|
|
318
312
|
// TODO O3-3482: Fix this test case when OpenmrsDatePicker gets fixed on core
|
|
319
313
|
it.skip('renders and saves registration obs', async () => {
|
|
320
314
|
const user = userEvent.setup();
|
|
321
315
|
|
|
322
|
-
|
|
323
|
-
|
|
316
|
+
mockSaveEncounter.mockResolvedValue({} as unknown as FetchResponse);
|
|
317
|
+
mockUseConfig.mockReturnValue(configWithObs);
|
|
324
318
|
|
|
325
319
|
render(<PatientRegistration isOffline={false} savePatientForm={FormManager.savePatientFormOnline} />, {
|
|
326
320
|
wrapper: Wrapper,
|
|
@@ -337,9 +331,9 @@ describe('Registering a new patient', () => {
|
|
|
337
331
|
|
|
338
332
|
await user.click(screen.getByText(/Register Patient/i));
|
|
339
333
|
|
|
340
|
-
expect(
|
|
334
|
+
expect(mockSavePatient).toHaveBeenCalled();
|
|
341
335
|
|
|
342
|
-
expect(
|
|
336
|
+
expect(mockSaveEncounter).toHaveBeenCalledWith(
|
|
343
337
|
expect.objectContaining<Partial<Encounter>>({
|
|
344
338
|
encounterType: 'reg-enc-uuid',
|
|
345
339
|
patient: 'new-pt-uuid',
|
|
@@ -356,7 +350,7 @@ describe('Registering a new patient', () => {
|
|
|
356
350
|
it.skip('retries saving registration obs after a failed attempt', async () => {
|
|
357
351
|
const user = userEvent.setup();
|
|
358
352
|
|
|
359
|
-
|
|
353
|
+
mockUseConfig.mockReturnValue(configWithObs);
|
|
360
354
|
|
|
361
355
|
render(<PatientRegistration isOffline={false} savePatientForm={FormManager.savePatientFormOnline} />, {
|
|
362
356
|
wrapper: Wrapper,
|
|
@@ -367,52 +361,48 @@ describe('Registering a new patient', () => {
|
|
|
367
361
|
const weight = within(customSection).getByLabelText('Weight (kg) (optional)');
|
|
368
362
|
await user.type(weight, '-999');
|
|
369
363
|
|
|
370
|
-
|
|
364
|
+
mockSaveEncounter.mockRejectedValue({ status: 400, responseBody: { error: { message: 'an error message' } } });
|
|
371
365
|
|
|
372
366
|
const registerPatientButton = screen.getByText(/Register Patient/i);
|
|
373
367
|
|
|
374
368
|
await user.click(registerPatientButton);
|
|
375
369
|
|
|
376
|
-
expect(
|
|
377
|
-
expect(
|
|
370
|
+
expect(mockSavePatient).toHaveBeenCalledTimes(1);
|
|
371
|
+
expect(mockSaveEncounter).toHaveBeenCalledTimes(1);
|
|
378
372
|
|
|
379
|
-
expect(
|
|
380
|
-
|
|
373
|
+
expect(mockShowSnackbar).toHaveBeenCalledWith(expect.objectContaining({ subtitle: 'an error message' })),
|
|
374
|
+
mockSaveEncounter.mockResolvedValue({} as FetchResponse);
|
|
381
375
|
|
|
382
376
|
await user.click(registerPatientButton);
|
|
383
|
-
expect(
|
|
384
|
-
expect(
|
|
377
|
+
expect(mockSavePatient).toHaveBeenCalledTimes(2);
|
|
378
|
+
expect(mockSaveEncounter).toHaveBeenCalledTimes(2);
|
|
385
379
|
|
|
386
|
-
expect(
|
|
380
|
+
expect(mockShowSnackbar).toHaveBeenCalledWith(expect.objectContaining({ kind: 'success' }));
|
|
387
381
|
});
|
|
388
382
|
});
|
|
389
383
|
|
|
390
384
|
describe('Updating an existing patient record', () => {
|
|
391
385
|
beforeEach(() => {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
mockedSaveEncounter.mockClear();
|
|
395
|
-
mockedShowSnackbar.mockClear();
|
|
396
|
-
jest.clearAllMocks();
|
|
386
|
+
mockUseConfig.mockReturnValue(mockOpenmrsConfig);
|
|
387
|
+
mockSavePatient.mockReturnValue({ data: { uuid: 'new-pt-uuid' }, ok: true });
|
|
397
388
|
});
|
|
398
389
|
|
|
399
390
|
it('edits patient demographics', async () => {
|
|
400
391
|
const user = userEvent.setup();
|
|
392
|
+
mockSavePatient.mockResolvedValue({} as FetchResponse);
|
|
401
393
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
const mockedUseParams = useParams as jest.Mock;
|
|
394
|
+
const mockUseParams = useParams as jest.Mock;
|
|
405
395
|
|
|
406
|
-
|
|
396
|
+
mockUseParams.mockReturnValue({ patientUuid: mockPatient.id });
|
|
407
397
|
|
|
408
|
-
|
|
398
|
+
mockUsePatient.mockReturnValue({
|
|
409
399
|
isLoading: false,
|
|
410
400
|
patient: mockPatient,
|
|
411
401
|
patientUuid: mockPatient.id,
|
|
412
402
|
error: null,
|
|
413
403
|
});
|
|
414
404
|
|
|
415
|
-
render(<PatientRegistration isOffline={false} savePatientForm={
|
|
405
|
+
render(<PatientRegistration isOffline={false} savePatientForm={mockSavePatient} />, { wrapper: Wrapper });
|
|
416
406
|
|
|
417
407
|
const givenNameInput: HTMLInputElement = screen.getByLabelText(/First Name/);
|
|
418
408
|
const familyNameInput: HTMLInputElement = screen.getByLabelText(/Family Name/);
|
|
@@ -436,7 +426,7 @@ describe('Updating an existing patient record', () => {
|
|
|
436
426
|
await user.type(familyNameInput, 'Smith');
|
|
437
427
|
await user.click(screen.getByText(/Update patient/i));
|
|
438
428
|
|
|
439
|
-
expect(
|
|
429
|
+
expect(mockSavePatient).toHaveBeenCalledWith(
|
|
440
430
|
false,
|
|
441
431
|
{
|
|
442
432
|
'0': {
|
|
@@ -154,36 +154,36 @@ export interface RelationshipValue {
|
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
export interface FormValues {
|
|
157
|
-
|
|
158
|
-
givenName: string;
|
|
159
|
-
middleName: string;
|
|
160
|
-
familyName: string;
|
|
157
|
+
additionalFamilyName: string;
|
|
161
158
|
additionalGivenName: string;
|
|
162
159
|
additionalMiddleName: string;
|
|
163
|
-
additionalFamilyName: string;
|
|
164
160
|
addNameInLocalLanguage: boolean;
|
|
165
|
-
|
|
161
|
+
address: {
|
|
162
|
+
[addressField: string]: string;
|
|
163
|
+
};
|
|
164
|
+
attributes?: {
|
|
165
|
+
[attributeTypeUuid: string]: string;
|
|
166
|
+
};
|
|
166
167
|
birthdate: Date | string;
|
|
167
|
-
yearsEstimated: number;
|
|
168
|
-
monthsEstimated: number;
|
|
169
168
|
birthdateEstimated: boolean;
|
|
170
|
-
telephoneNumber: string;
|
|
171
|
-
isDead: boolean;
|
|
172
|
-
deathDate: string;
|
|
173
169
|
deathCause: string;
|
|
174
|
-
|
|
170
|
+
deathDate: string;
|
|
171
|
+
familyName: string;
|
|
172
|
+
gender: string;
|
|
173
|
+
givenName: string;
|
|
175
174
|
identifiers: {
|
|
176
175
|
[identifierFieldName: string]: PatientIdentifierValue;
|
|
177
176
|
};
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
177
|
+
isDead: boolean;
|
|
178
|
+
middleName: string;
|
|
179
|
+
monthsEstimated: number;
|
|
181
180
|
obs?: {
|
|
182
181
|
[conceptUuid: string]: string;
|
|
183
182
|
};
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
183
|
+
patientUuid: string;
|
|
184
|
+
relationships: Array<RelationshipValue>;
|
|
185
|
+
telephoneNumber: string;
|
|
186
|
+
yearsEstimated: number;
|
|
187
187
|
observation?: ObsResponse;
|
|
188
188
|
concepts?: Array<ConceptAnswers>;
|
|
189
189
|
token?: string;
|
|
@@ -6,15 +6,6 @@ import { DeathInfoSection } from './death-info-section.component';
|
|
|
6
6
|
import { type FormValues } from '../../patient-registration.types';
|
|
7
7
|
import { PatientRegistrationContext } from '../../patient-registration-context';
|
|
8
8
|
|
|
9
|
-
jest.mock('@openmrs/esm-framework', () => {
|
|
10
|
-
const originalModule = jest.requireActual('@openmrs/esm-framework');
|
|
11
|
-
|
|
12
|
-
return {
|
|
13
|
-
...originalModule,
|
|
14
|
-
validator: jest.fn(),
|
|
15
|
-
};
|
|
16
|
-
});
|
|
17
|
-
|
|
18
9
|
const initialContextValues = {
|
|
19
10
|
currentPhoto: 'data:image/png;base64,1234567890',
|
|
20
11
|
identifierTypes: [],
|
|
@@ -34,7 +25,7 @@ describe('Death info section', () => {
|
|
|
34
25
|
const renderDeathInfoSection = (isDead) => {
|
|
35
26
|
initialContextValues.values.isDead = isDead;
|
|
36
27
|
|
|
37
|
-
|
|
28
|
+
render(
|
|
38
29
|
<PatientRegistrationContext.Provider value={initialContextValues}>
|
|
39
30
|
<Formik initialValues={initialFormValues} onSubmit={jest.fn()}>
|
|
40
31
|
<Form>
|
|
@@ -1,37 +1,30 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import dayjs from 'dayjs';
|
|
3
4
|
import { Formik, Form } from 'formik';
|
|
4
5
|
import { initialFormValues } from '../../patient-registration.component';
|
|
6
|
+
import { getDefaultsFromConfigSchema, OpenmrsDatePicker, useConfig } from '@openmrs/esm-framework';
|
|
5
7
|
import { DemographicsSection } from './demographics-section.component';
|
|
6
8
|
import { PatientRegistrationContext } from '../../patient-registration-context';
|
|
7
|
-
import { type
|
|
8
|
-
import dayjs from 'dayjs';
|
|
9
|
+
import { type RegistrationConfig, esmPatientRegistrationSchema } from '../../../config-schema';
|
|
9
10
|
|
|
10
|
-
jest.
|
|
11
|
-
|
|
11
|
+
const mockOpenmrsDatePicker = jest.mocked(OpenmrsDatePicker);
|
|
12
|
+
const mockUseConfig = jest.mocked(useConfig<RegistrationConfig>);
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
onChange={(evt) => {
|
|
28
|
-
onChange(dayjs(evt.target.value).toDate());
|
|
29
|
-
}}
|
|
30
|
-
/>
|
|
31
|
-
</>
|
|
32
|
-
);
|
|
33
|
-
}),
|
|
34
|
-
};
|
|
14
|
+
mockOpenmrsDatePicker.mockImplementation(({ id, labelText, value, onChange }) => {
|
|
15
|
+
return (
|
|
16
|
+
<>
|
|
17
|
+
<label htmlFor={id}>{labelText}</label>
|
|
18
|
+
<input
|
|
19
|
+
id={id}
|
|
20
|
+
// @ts-ignore
|
|
21
|
+
value={value ? dayjs(value).format('DD/MM/YYYY') : ''}
|
|
22
|
+
onChange={(evt) => {
|
|
23
|
+
onChange(dayjs(evt.target.value).toDate());
|
|
24
|
+
}}
|
|
25
|
+
/>
|
|
26
|
+
</>
|
|
27
|
+
);
|
|
35
28
|
});
|
|
36
29
|
|
|
37
30
|
jest.mock('../../field/name/name-field.component', () => {
|
|
@@ -64,8 +57,18 @@ jest.mock('../../field/id/id-field.component', () => {
|
|
|
64
57
|
};
|
|
65
58
|
});
|
|
66
59
|
|
|
67
|
-
describe('
|
|
68
|
-
|
|
60
|
+
describe('Demographics section', () => {
|
|
61
|
+
beforeEach(() => {
|
|
62
|
+
mockUseConfig.mockReturnValue({
|
|
63
|
+
...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
|
|
64
|
+
fieldConfigurations: {
|
|
65
|
+
dateOfBirth: {
|
|
66
|
+
allowEstimatedDateOfBirth: true,
|
|
67
|
+
useEstimatedDateOfBirth: { enabled: true, dayOfMonth: 0, month: 0 },
|
|
68
|
+
},
|
|
69
|
+
} as RegistrationConfig['fieldConfigurations'],
|
|
70
|
+
});
|
|
71
|
+
});
|
|
69
72
|
|
|
70
73
|
const setupSection = async (birthdateEstimated?: boolean, addNameInLocalLanguage?: boolean) => {
|
|
71
74
|
render(
|
|
@@ -83,7 +86,7 @@ describe('demographics section', () => {
|
|
|
83
86
|
isOffline: true,
|
|
84
87
|
setCapturePhotoProps: (value) => {},
|
|
85
88
|
}}>
|
|
86
|
-
<DemographicsSection fields={['name', 'gender', 'dob']}
|
|
89
|
+
<DemographicsSection fields={['name', 'gender', 'dob']} />
|
|
87
90
|
</PatientRegistrationContext.Provider>
|
|
88
91
|
</Form>
|
|
89
92
|
</Formik>,
|
package/src/patient-registration/section/patient-relationships/relationships-section.test.tsx
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Form, Formik } from 'formik';
|
|
3
3
|
import { render, screen } from '@testing-library/react';
|
|
4
|
-
import { PatientRegistrationContext } from '../../patient-registration-context';
|
|
5
4
|
import { type Resources, ResourcesContext } from '../../../offline.resources';
|
|
5
|
+
import { type FormValues } from '../../patient-registration.types';
|
|
6
|
+
import { PatientRegistrationContext } from '../../patient-registration-context';
|
|
6
7
|
import { RelationshipsSection } from './relationships-section.component';
|
|
7
8
|
|
|
8
9
|
jest.mock('../../patient-registration.resource', () => ({
|
|
@@ -27,6 +28,19 @@ let mockResourcesContextValue = {
|
|
|
27
28
|
relationshipTypes: null,
|
|
28
29
|
} as Resources;
|
|
29
30
|
|
|
31
|
+
const initialContextValues = {
|
|
32
|
+
currentPhoto: 'data:image/png;base64,1234567890',
|
|
33
|
+
identifierTypes: [],
|
|
34
|
+
inEditMode: false,
|
|
35
|
+
initialFormValues: {} as FormValues,
|
|
36
|
+
isOffline: false,
|
|
37
|
+
setCapturePhotoProps: jest.fn(),
|
|
38
|
+
setFieldValue: jest.fn(),
|
|
39
|
+
setInitialFormValues: jest.fn(),
|
|
40
|
+
validationSchema: null,
|
|
41
|
+
values: {} as FormValues,
|
|
42
|
+
};
|
|
43
|
+
|
|
30
44
|
describe('RelationshipsSection', () => {
|
|
31
45
|
it('renders a loader when relationshipTypes are not available', () => {
|
|
32
46
|
render(
|
|
@@ -76,11 +90,7 @@ describe('RelationshipsSection', () => {
|
|
|
76
90
|
}}
|
|
77
91
|
onSubmit={null}>
|
|
78
92
|
<Form>
|
|
79
|
-
<PatientRegistrationContext.Provider
|
|
80
|
-
value={{
|
|
81
|
-
setFieldValue: jest.fn(),
|
|
82
|
-
setInitialFormValues: jest.fn(),
|
|
83
|
-
}}>
|
|
93
|
+
<PatientRegistrationContext.Provider value={initialContextValues}>
|
|
84
94
|
<RelationshipsSection />
|
|
85
95
|
</PatientRegistrationContext.Provider>
|
|
86
96
|
</Form>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
@use '@carbon/
|
|
2
|
-
@use '@carbon/
|
|
3
|
-
@
|
|
1
|
+
@use '@carbon/layout';
|
|
2
|
+
@use '@carbon/type';
|
|
3
|
+
@use '@openmrs/esm-styleguide/src/vars' as *;
|
|
4
4
|
|
|
5
5
|
.labelText {
|
|
6
6
|
@include type.type-style('label-01');
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
.searchBox {
|
|
14
|
-
margin-bottom:
|
|
14
|
+
margin-bottom: layout.$spacing-05;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
.relationshipHeader {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import styles from '../patient-registration.scss';
|
|
3
2
|
import { Tile } from '@carbon/react';
|
|
4
3
|
import { useTranslation } from 'react-i18next';
|
|
5
4
|
import { type SectionDefinition } from '../../config-schema';
|
|
6
5
|
import { Section } from './section.component';
|
|
6
|
+
import styles from './section.scss';
|
|
7
7
|
|
|
8
8
|
export interface SectionWrapperProps {
|
|
9
9
|
sectionDefinition: SectionDefinition;
|
|
@@ -1 +1,16 @@
|
|
|
1
|
-
@
|
|
1
|
+
@use '@carbon/layout';
|
|
2
|
+
@use '@carbon/type';
|
|
3
|
+
@use '@openmrs/esm-styleguide/src/vars' as *;
|
|
4
|
+
|
|
5
|
+
.label01 {
|
|
6
|
+
@include type.type-style('label-01');
|
|
7
|
+
margin-top: layout.$spacing-05;
|
|
8
|
+
margin-bottom: layout.$spacing-05;
|
|
9
|
+
color: $ui-04;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.productiveHeading02 {
|
|
13
|
+
@include type.type-style('heading-compact-02');
|
|
14
|
+
color: $ui-04;
|
|
15
|
+
cursor: pointer;
|
|
16
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
@use '@carbon/
|
|
2
|
-
@use '@carbon/
|
|
3
|
-
@
|
|
1
|
+
@use '@carbon/layout';
|
|
2
|
+
@use '@carbon/type';
|
|
3
|
+
@use '@openmrs/esm-styleguide/src/vars' as *;
|
|
4
4
|
|
|
5
5
|
.desktopOverlay {
|
|
6
6
|
position: fixed;
|
|
7
|
-
top:
|
|
7
|
+
top: layout.$spacing-09;
|
|
8
8
|
right: 0;
|
|
9
|
-
height: calc(100vh -
|
|
9
|
+
height: calc(100vh - layout.$spacing-09);
|
|
10
10
|
min-width: 27rem;
|
|
11
11
|
background-color: $ui-02;
|
|
12
12
|
border-left: 1px solid $text-03;
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
z-index: 9999;
|
|
26
26
|
background-color: $ui-02;
|
|
27
27
|
overflow: hidden;
|
|
28
|
-
padding-top:
|
|
28
|
+
padding-top: layout.$spacing-09;
|
|
29
29
|
display: grid;
|
|
30
30
|
grid-template-rows: 1fr auto;
|
|
31
31
|
}
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
|
|
50
50
|
.headerContent {
|
|
51
51
|
@include type.type-style('heading-compact-02');
|
|
52
|
-
padding: 0
|
|
52
|
+
padding: 0 layout.$spacing-05;
|
|
53
53
|
color: $ui-05;
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -58,6 +58,6 @@
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
.overlayContent {
|
|
61
|
-
padding:
|
|
61
|
+
padding: layout.$spacing-05;
|
|
62
62
|
overflow-y: auto;
|
|
63
63
|
}
|