@kenyaemr/esm-patient-registration-app 7.0.3-pre.88 → 7.0.3-pre.94
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 +15 -14
- 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 +1 -1
- 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/266.js +0 -2
- package/dist/266.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/{266.js.LICENSE.txt → 831.js.LICENSE.txt} +0 -0
|
@@ -3,42 +3,65 @@ import dayjs from 'dayjs';
|
|
|
3
3
|
import { Formik, Form } from 'formik';
|
|
4
4
|
import { render, screen } from '@testing-library/react';
|
|
5
5
|
import userEvent from '@testing-library/user-event';
|
|
6
|
-
import {
|
|
6
|
+
import { getDefaultsFromConfigSchema, OpenmrsDatePicker, useConfig } from '@openmrs/esm-framework';
|
|
7
|
+
import { type RegistrationConfig, esmPatientRegistrationSchema } from '../../../config-schema';
|
|
7
8
|
import { PatientRegistrationContext } from '../../patient-registration-context';
|
|
8
9
|
import { initialFormValues } from '../../patient-registration.component';
|
|
9
|
-
import {
|
|
10
|
+
import { DobField } from './dob.component';
|
|
10
11
|
|
|
11
|
-
jest.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const mockOpenmrsDatePicker = jest.mocked(OpenmrsDatePicker);
|
|
13
|
+
const mockUseConfig = jest.mocked(useConfig<RegistrationConfig>);
|
|
14
|
+
|
|
15
|
+
mockOpenmrsDatePicker.mockImplementation(({ id, labelText, value, onChange }) => {
|
|
16
|
+
return (
|
|
17
|
+
<>
|
|
18
|
+
<label htmlFor={id}>{labelText}</label>
|
|
19
|
+
<input
|
|
20
|
+
id={id}
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
value={value ? dayjs(value).format('DD/MM/YYYY') : ''}
|
|
23
|
+
onChange={(evt) => {
|
|
24
|
+
onChange(dayjs(evt.target.value).toDate());
|
|
25
|
+
}}
|
|
26
|
+
/>
|
|
27
|
+
</>
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
describe('Dob', () => {
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
mockUseConfig.mockReturnValue({
|
|
34
|
+
...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
|
|
16
35
|
fieldConfigurations: {
|
|
17
36
|
dateOfBirth: {
|
|
18
37
|
allowEstimatedDateOfBirth: true,
|
|
19
38
|
useEstimatedDateOfBirth: { enabled: true, dayOfMonth: 0, month: 0 },
|
|
20
39
|
},
|
|
21
|
-
},
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
OpenmrsDatePicker: jest.fn().mockImplementation(({ id, labelText, value, onChange }) => {
|
|
25
|
-
return (
|
|
26
|
-
<>
|
|
27
|
-
<label htmlFor={id}>{labelText}</label>
|
|
28
|
-
<input
|
|
29
|
-
id={id}
|
|
30
|
-
value={value ? dayjs(value).format('DD/MM/YYYY') : undefined}
|
|
31
|
-
onChange={(evt) => onChange(dayjs(evt.target.value).toDate())}
|
|
32
|
-
/>
|
|
33
|
-
</>
|
|
34
|
-
);
|
|
35
|
-
}),
|
|
36
|
-
};
|
|
37
|
-
});
|
|
40
|
+
} as RegistrationConfig['fieldConfigurations'],
|
|
41
|
+
});
|
|
42
|
+
});
|
|
38
43
|
|
|
39
|
-
describe('Dob', () => {
|
|
40
44
|
it('renders the fields in the birth section of the registration form', async () => {
|
|
41
|
-
|
|
45
|
+
render(
|
|
46
|
+
<Formik initialValues={{ birthdate: '' }} onSubmit={() => {}}>
|
|
47
|
+
<Form>
|
|
48
|
+
<PatientRegistrationContext.Provider
|
|
49
|
+
value={{
|
|
50
|
+
identifierTypes: [],
|
|
51
|
+
values: initialFormValues,
|
|
52
|
+
validationSchema: null,
|
|
53
|
+
inEditMode: false,
|
|
54
|
+
setFieldValue: () => {},
|
|
55
|
+
setCapturePhotoProps: (value) => {},
|
|
56
|
+
currentPhoto: '',
|
|
57
|
+
isOffline: false,
|
|
58
|
+
initialFormValues: initialFormValues,
|
|
59
|
+
}}>
|
|
60
|
+
<DobField />
|
|
61
|
+
</PatientRegistrationContext.Provider>
|
|
62
|
+
</Form>
|
|
63
|
+
</Formik>,
|
|
64
|
+
);
|
|
42
65
|
|
|
43
66
|
expect(screen.getByRole('heading', { name: /birth/i })).toBeInTheDocument();
|
|
44
67
|
expect(screen.getByText(/date of birth known?/i)).toBeInTheDocument();
|
|
@@ -54,38 +77,31 @@ describe('Dob', () => {
|
|
|
54
77
|
it.skip('typing in the date picker input sets the date of birth', async () => {
|
|
55
78
|
const user = userEvent.setup();
|
|
56
79
|
|
|
57
|
-
|
|
80
|
+
render(
|
|
81
|
+
<Formik initialValues={{ birthdate: '' }} onSubmit={() => {}}>
|
|
82
|
+
<Form>
|
|
83
|
+
<PatientRegistrationContext.Provider
|
|
84
|
+
value={{
|
|
85
|
+
identifierTypes: [],
|
|
86
|
+
values: initialFormValues,
|
|
87
|
+
validationSchema: null,
|
|
88
|
+
inEditMode: false,
|
|
89
|
+
setFieldValue: () => {},
|
|
90
|
+
setCapturePhotoProps: (value) => {},
|
|
91
|
+
currentPhoto: '',
|
|
92
|
+
isOffline: false,
|
|
93
|
+
initialFormValues: initialFormValues,
|
|
94
|
+
}}>
|
|
95
|
+
<DobField />
|
|
96
|
+
</PatientRegistrationContext.Provider>
|
|
97
|
+
</Form>
|
|
98
|
+
</Formik>,
|
|
99
|
+
);
|
|
58
100
|
|
|
59
101
|
const dateInput = screen.getByLabelText(/Date of birth/i);
|
|
60
102
|
expect(dateInput).toBeInTheDocument();
|
|
61
103
|
|
|
62
104
|
await user.type(dateInput, '10/10/2022');
|
|
63
|
-
|
|
64
105
|
expect(screen.getByPlaceholderText('dd/mm/YYYY')).toHaveValue('10/10/2022');
|
|
65
106
|
});
|
|
66
107
|
});
|
|
67
|
-
|
|
68
|
-
function renderDob() {
|
|
69
|
-
let formValues: FormValues = initialFormValues;
|
|
70
|
-
|
|
71
|
-
render(
|
|
72
|
-
<Formik initialValues={{ birthdate: '' }} onSubmit={() => {}}>
|
|
73
|
-
<Form>
|
|
74
|
-
<PatientRegistrationContext.Provider
|
|
75
|
-
value={{
|
|
76
|
-
identifierTypes: [],
|
|
77
|
-
values: formValues,
|
|
78
|
-
validationSchema: null,
|
|
79
|
-
inEditMode: false,
|
|
80
|
-
setFieldValue: () => {},
|
|
81
|
-
setCapturePhotoProps: (value) => {},
|
|
82
|
-
currentPhoto: '',
|
|
83
|
-
isOffline: false,
|
|
84
|
-
initialFormValues: formValues,
|
|
85
|
-
}}>
|
|
86
|
-
<DobField />
|
|
87
|
-
</PatientRegistrationContext.Provider>
|
|
88
|
-
</Form>
|
|
89
|
-
</Formik>,
|
|
90
|
-
);
|
|
91
|
-
}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
@use '@carbon/
|
|
2
|
-
@use '@carbon/
|
|
3
|
-
@
|
|
1
|
+
@use '@carbon/colors';
|
|
2
|
+
@use '@carbon/layout';
|
|
3
|
+
@use '@carbon/type';
|
|
4
|
+
@use '@openmrs/esm-styleguide/src/vars' as *;
|
|
4
5
|
|
|
5
6
|
.productiveHeading02 {
|
|
6
7
|
@include type.type-style('heading-compact-02');
|
|
7
|
-
margin-bottom:
|
|
8
|
+
margin-bottom: layout.$spacing-05;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
.productiveHeading02Light {
|
|
11
12
|
@include type.type-style('heading-compact-02');
|
|
12
|
-
margin-bottom:
|
|
13
|
-
color:
|
|
13
|
+
margin-bottom: layout.$spacing-05;
|
|
14
|
+
color: colors.$gray-70;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
.label01 {
|
|
@@ -20,11 +21,11 @@
|
|
|
20
21
|
.grid {
|
|
21
22
|
display: grid;
|
|
22
23
|
grid-template-columns: 1fr 1fr;
|
|
23
|
-
column-gap:
|
|
24
|
+
column-gap: layout.$spacing-05;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
.halfWidthInDesktopView {
|
|
27
|
-
width: calc(50% -
|
|
28
|
+
width: calc(50% - layout.$spacing-05);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
.patientPhoto {
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
.contentSwitcher {
|
|
48
|
-
margin-bottom:
|
|
49
|
+
margin-bottom: layout.$spacing-05;
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
.dobField > :global(.cds--content-switcher) {
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
.photoExtension {
|
|
59
|
-
margin-bottom:
|
|
60
|
+
margin-bottom: layout.$spacing-05;
|
|
60
61
|
grid-row: 1;
|
|
61
62
|
grid-column: 2;
|
|
62
63
|
justify-self: center;
|
|
@@ -64,11 +65,11 @@
|
|
|
64
65
|
|
|
65
66
|
.sexField,
|
|
66
67
|
.dobField {
|
|
67
|
-
margin-bottom:
|
|
68
|
+
margin-bottom: layout.$spacing-05;
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
.dobContentSwitcherLabel {
|
|
71
|
-
margin-bottom:
|
|
72
|
+
margin-bottom: layout.$spacing-03;
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
.identifierLabelText {
|
|
@@ -76,20 +77,20 @@
|
|
|
76
77
|
align-items: center;
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
.
|
|
80
|
-
margin
|
|
81
|
-
}
|
|
80
|
+
.configureIdentifiersButton {
|
|
81
|
+
margin: 0 0 layout.$spacing-05 layout.$spacing-05;
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
83
|
+
svg {
|
|
84
|
+
margin-left: layout.$spacing-03;
|
|
85
|
+
}
|
|
86
86
|
|
|
87
|
-
.customField {
|
|
88
|
-
|
|
87
|
+
.customField {
|
|
88
|
+
margin-bottom: layout.$spacing-05;
|
|
89
|
+
}
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
.attributeField {
|
|
92
|
-
margin-bottom:
|
|
93
|
+
margin-bottom: layout.$spacing-05;
|
|
93
94
|
}
|
|
94
95
|
|
|
95
96
|
:global(.omrs-breakpoint-lt-desktop) {
|
|
@@ -97,31 +98,35 @@
|
|
|
97
98
|
grid-template-columns: 1fr;
|
|
98
99
|
grid-template-rows: auto auto;
|
|
99
100
|
}
|
|
101
|
+
|
|
100
102
|
.nameField {
|
|
101
103
|
grid-row: 2;
|
|
102
104
|
grid-column: 1;
|
|
103
105
|
}
|
|
106
|
+
|
|
104
107
|
.photoExtension {
|
|
105
108
|
grid-column: 1;
|
|
106
109
|
grid-row: 1;
|
|
107
110
|
justify-self: start;
|
|
108
111
|
}
|
|
112
|
+
|
|
109
113
|
.radioButton label {
|
|
110
|
-
height:
|
|
114
|
+
height: layout.$spacing-09 !important;
|
|
111
115
|
}
|
|
116
|
+
|
|
112
117
|
.halfWidthInDesktopView {
|
|
113
118
|
width: 100%;
|
|
114
119
|
}
|
|
115
120
|
}
|
|
116
121
|
|
|
117
122
|
.radioFieldError {
|
|
118
|
-
color:
|
|
123
|
+
color: colors.$red-60;
|
|
119
124
|
display: block;
|
|
120
125
|
font-weight: 400;
|
|
121
126
|
max-height: 12.5rem;
|
|
122
127
|
overflow: visible;
|
|
123
|
-
font-size:
|
|
128
|
+
font-size: layout.$spacing-04;
|
|
124
129
|
letter-spacing: 0.32px;
|
|
125
130
|
line-height: 1.34;
|
|
126
|
-
margin:
|
|
131
|
+
margin: layout.$spacing-02 0 0;
|
|
127
132
|
}
|
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import dayjs from 'dayjs';
|
|
2
3
|
import { Form, Formik } from 'formik';
|
|
3
4
|
import { render, screen } from '@testing-library/react';
|
|
4
|
-
import { useConfig } from '@openmrs/esm-framework';
|
|
5
|
+
import { getDefaultsFromConfigSchema, OpenmrsDatePicker, useConfig } from '@openmrs/esm-framework';
|
|
5
6
|
import { Field } from './field.component';
|
|
6
|
-
import
|
|
7
|
+
import { esmPatientRegistrationSchema, type RegistrationConfig } from '../../config-schema';
|
|
7
8
|
import { type Resources, ResourcesContext } from '../../offline.resources';
|
|
9
|
+
import type { AddressTemplate, FormValues } from '../patient-registration.types';
|
|
8
10
|
import { PatientRegistrationContext } from '../patient-registration-context';
|
|
9
|
-
import dayjs from 'dayjs';
|
|
10
11
|
|
|
11
|
-
jest.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
12
|
+
const mockOpenmrsDatePicker = jest.mocked(OpenmrsDatePicker);
|
|
13
|
+
const mockUseConfig = jest.mocked(useConfig<RegistrationConfig>);
|
|
14
|
+
|
|
15
|
+
mockOpenmrsDatePicker.mockImplementation(({ id, labelText, value, onChange }) => {
|
|
16
|
+
return (
|
|
17
|
+
<>
|
|
18
|
+
<label htmlFor={id}>{labelText}</label>
|
|
19
|
+
<input
|
|
20
|
+
id={id}
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
value={value ? dayjs(value).format('DD/MM/YYYY') : ''}
|
|
23
|
+
onChange={(evt) => {
|
|
24
|
+
onChange(dayjs(evt.target.value).toDate());
|
|
25
|
+
}}
|
|
26
|
+
/>
|
|
27
|
+
</>
|
|
28
|
+
);
|
|
29
|
+
});
|
|
28
30
|
|
|
29
31
|
const predefinedAddressTemplate = {
|
|
30
32
|
uuid: 'test-address-template-uuid',
|
|
@@ -36,7 +38,7 @@ const predefinedAddressTemplate = {
|
|
|
36
38
|
'<org.openmrs.layout.address.AddressTemplate>\r\n <nameMappings class="properties">\r\n <property name="postalCode" value="Location.postalCode"/>\r\n <property name="address2" value="Location.address2"/>\r\n <property name="address1" value="Location.address1"/>\r\n <property name="country" value="Location.country"/>\r\n <property name="stateProvince" value="Location.stateProvince"/>\r\n <property name="cityVillage" value="Location.cityVillage"/>\r\n </nameMappings>\r\n <sizeMappings class="properties">\r\n <property name="postalCode" value="4"/>\r\n <property name="address1" value="40"/>\r\n <property name="address2" value="40"/>\r\n <property name="country" value="10"/>\r\n <property name="stateProvince" value="10"/>\r\n <property name="cityVillage" value="10"/>\r\n <asset name="cityVillage" value="10"/>\r\n </sizeMappings>\r\n <lineByLineFormat>\r\n <string>address1 address2</string>\r\n <string>cityVillage stateProvince postalCode</string>\r\n <string>country</string>\r\n </lineByLineFormat>\r\n <elementDefaults class="properties">\r\n <property name="country" value=""/>\r\n </elementDefaults>\r\n <elementRegex class="properties">\r\n <property name="address1" value="[a-zA-Z]+$"/>\r\n </elementRegex>\r\n <elementRegexFormats class="properties">\r\n <property name="address1" value="Countries can only be letters"/>\r\n </elementRegexFormats>\r\n </org.openmrs.layout.address.AddressTemplate>',
|
|
37
39
|
};
|
|
38
40
|
|
|
39
|
-
const
|
|
41
|
+
const mockIdentifierTypes = [
|
|
40
42
|
{
|
|
41
43
|
fieldName: 'openMrsId',
|
|
42
44
|
format: '',
|
|
@@ -105,7 +107,7 @@ const mockResourcesContextValue: Resources = {
|
|
|
105
107
|
currentProvider: { uuid: 'provider-uuid', identifier: 'PRO-123' },
|
|
106
108
|
},
|
|
107
109
|
relationshipTypes: [],
|
|
108
|
-
identifierTypes: [...
|
|
110
|
+
identifierTypes: [...mockIdentifierTypes],
|
|
109
111
|
};
|
|
110
112
|
|
|
111
113
|
const initialContextValues = {
|
|
@@ -136,31 +138,32 @@ describe('Field', () => {
|
|
|
136
138
|
</Formik>
|
|
137
139
|
</ResourcesContext.Provider>
|
|
138
140
|
);
|
|
139
|
-
});
|
|
140
141
|
|
|
141
|
-
|
|
142
|
-
|
|
142
|
+
mockUseConfig.mockReturnValue({
|
|
143
|
+
...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
|
|
144
|
+
});
|
|
143
145
|
});
|
|
144
146
|
|
|
145
147
|
it('should render NameField component when name prop is "name"', () => {
|
|
146
|
-
|
|
148
|
+
mockUseConfig.mockReturnValue({
|
|
149
|
+
...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
|
|
147
150
|
fieldConfigurations: {
|
|
148
151
|
name: {
|
|
152
|
+
allowUnidentifiedPatients: true,
|
|
149
153
|
displayMiddleName: true,
|
|
150
|
-
unidentifiedPatient: true,
|
|
151
154
|
defaultUnknownGivenName: 'UNKNOWN',
|
|
152
155
|
defaultUnknownFamilyName: 'UNKNOWN',
|
|
153
156
|
},
|
|
154
|
-
},
|
|
155
|
-
})
|
|
157
|
+
} as RegistrationConfig['fieldConfigurations'],
|
|
158
|
+
});
|
|
156
159
|
|
|
157
160
|
render(<Field name="name" />, { wrapper: ContextWrapper });
|
|
158
|
-
|
|
159
161
|
expect(screen.getByText('Full Name')).toBeInTheDocument();
|
|
160
162
|
});
|
|
161
163
|
|
|
162
164
|
it('should render GenderField component when name prop is "gender"', () => {
|
|
163
|
-
|
|
165
|
+
mockUseConfig.mockReturnValue({
|
|
166
|
+
...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
|
|
164
167
|
fieldConfigurations: {
|
|
165
168
|
gender: [
|
|
166
169
|
{
|
|
@@ -169,33 +172,26 @@ describe('Field', () => {
|
|
|
169
172
|
id: 'male',
|
|
170
173
|
},
|
|
171
174
|
],
|
|
172
|
-
},
|
|
173
|
-
})
|
|
175
|
+
} as unknown as RegistrationConfig['fieldConfigurations'],
|
|
176
|
+
});
|
|
174
177
|
|
|
175
178
|
render(<Field name="gender" />, { wrapper: ContextWrapper });
|
|
176
|
-
|
|
177
179
|
expect(screen.getByLabelText('Male')).toBeInTheDocument();
|
|
178
180
|
});
|
|
179
181
|
|
|
180
182
|
it('should render DobField component when name prop is "dob"', () => {
|
|
181
|
-
(useConfig as jest.Mock).mockImplementation(() => ({
|
|
182
|
-
fieldConfigurations: {
|
|
183
|
-
dob: {
|
|
184
|
-
minAgeLimit: 0,
|
|
185
|
-
maxAgeLimit: 120,
|
|
186
|
-
},
|
|
187
|
-
},
|
|
188
|
-
}));
|
|
189
183
|
render(<Field name="dob" />, { wrapper: ContextWrapper });
|
|
190
184
|
expect(screen.getByText('Birth')).toBeInTheDocument();
|
|
191
185
|
});
|
|
192
186
|
|
|
193
187
|
it('should render AddressComponent component when name prop is "address"', () => {
|
|
194
188
|
jest.mock('./address/address-hierarchy.resource', () => ({
|
|
195
|
-
...
|
|
189
|
+
...jest.requireActual('../address-hierarchy.resource'),
|
|
196
190
|
useOrderedAddressHierarchyLevels: jest.fn(),
|
|
197
191
|
}));
|
|
198
|
-
|
|
192
|
+
|
|
193
|
+
mockUseConfig.mockReturnValue({
|
|
194
|
+
...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
|
|
199
195
|
fieldConfigurations: {
|
|
200
196
|
address: {
|
|
201
197
|
useAddressHierarchy: {
|
|
@@ -204,18 +200,18 @@ describe('Field', () => {
|
|
|
204
200
|
searchAddressByLevel: false,
|
|
205
201
|
},
|
|
206
202
|
},
|
|
207
|
-
},
|
|
208
|
-
})
|
|
203
|
+
} as RegistrationConfig['fieldConfigurations'],
|
|
204
|
+
});
|
|
209
205
|
|
|
210
206
|
render(<Field name="address" />, { wrapper: ContextWrapper });
|
|
211
|
-
|
|
212
207
|
expect(screen.getByText('Address')).toBeInTheDocument();
|
|
213
208
|
});
|
|
214
209
|
|
|
215
210
|
it('should render Identifiers component when name prop is "id"', () => {
|
|
216
|
-
|
|
211
|
+
mockUseConfig.mockReturnValue({
|
|
212
|
+
...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
|
|
217
213
|
defaultPatientIdentifierTypes: ['OpenMRS ID'],
|
|
218
|
-
})
|
|
214
|
+
});
|
|
219
215
|
|
|
220
216
|
const openmrsID = {
|
|
221
217
|
name: 'OpenMRS ID',
|
|
@@ -289,9 +285,11 @@ describe('Field', () => {
|
|
|
289
285
|
it('should return null and report an error for an invalid field name', () => {
|
|
290
286
|
const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {});
|
|
291
287
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
288
|
+
mockUseConfig.mockReturnValue({
|
|
289
|
+
...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
|
|
290
|
+
fieldDefinitions: [{ id: 'weight' }] as RegistrationConfig['fieldDefinitions'],
|
|
291
|
+
});
|
|
292
|
+
|
|
295
293
|
let error = null;
|
|
296
294
|
|
|
297
295
|
try {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import React, { useContext } from 'react';
|
|
2
2
|
import { RadioButton, RadioButtonGroup } from '@carbon/react';
|
|
3
|
-
import styles from '../field.scss';
|
|
4
3
|
import { useTranslation } from 'react-i18next';
|
|
5
4
|
import { PatientRegistrationContext } from '../../patient-registration-context';
|
|
6
5
|
import { useField } from 'formik';
|
|
7
6
|
import { type RegistrationConfig } from '../../../config-schema';
|
|
8
7
|
import { useConfig } from '@openmrs/esm-framework';
|
|
8
|
+
import styles from '../field.scss';
|
|
9
9
|
|
|
10
10
|
export const GenderField: React.FC = () => {
|
|
11
|
-
const { fieldConfigurations } = useConfig()
|
|
11
|
+
const { fieldConfigurations } = useConfig<RegistrationConfig>();
|
|
12
12
|
const { t } = useTranslation();
|
|
13
13
|
const [field, meta] = useField('gender');
|
|
14
14
|
const { setFieldValue } = useContext(PatientRegistrationContext);
|
|
@@ -1,28 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import userEvent from '@testing-library/user-event';
|
|
3
3
|
import { Formik, Form } from 'formik';
|
|
4
|
-
import { render } from '@testing-library/react';
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
import { getDefaultsFromConfigSchema, useConfig } from '@openmrs/esm-framework';
|
|
6
|
+
import { type RegistrationConfig, esmPatientRegistrationSchema } from '../../../config-schema';
|
|
5
7
|
import { GenderField } from './gender-field.component';
|
|
6
8
|
|
|
7
|
-
jest.
|
|
8
|
-
...(jest.requireActual('@openmrs/esm-framework') as any),
|
|
9
|
-
useConfig: jest.fn(() => ({
|
|
10
|
-
fieldConfigurations: {
|
|
11
|
-
gender: [
|
|
12
|
-
{
|
|
13
|
-
value: 'male',
|
|
14
|
-
label: 'Male',
|
|
15
|
-
},
|
|
16
|
-
],
|
|
17
|
-
name: {
|
|
18
|
-
displayMiddleName: false,
|
|
19
|
-
unidentifiedPatient: false,
|
|
20
|
-
defaultUnknownGivenName: '',
|
|
21
|
-
defaultUnknownFamilyName: '',
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
})),
|
|
25
|
-
}));
|
|
9
|
+
const mockUseConfig = jest.mocked(useConfig<RegistrationConfig>);
|
|
26
10
|
|
|
27
11
|
jest.mock('react', () => ({
|
|
28
12
|
...(jest.requireActual('react') as any),
|
|
@@ -37,23 +21,57 @@ jest.mock('formik', () => ({
|
|
|
37
21
|
}));
|
|
38
22
|
|
|
39
23
|
describe('GenderField', () => {
|
|
40
|
-
|
|
41
|
-
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
mockUseConfig.mockReturnValue({
|
|
26
|
+
...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
|
|
27
|
+
fieldConfigurations: {
|
|
28
|
+
gender: [
|
|
29
|
+
{
|
|
30
|
+
value: 'male',
|
|
31
|
+
label: 'Male',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
value: 'female',
|
|
35
|
+
label: 'Female',
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
name: {
|
|
39
|
+
displayMiddleName: false,
|
|
40
|
+
allowUnidentifiedPatients: false,
|
|
41
|
+
defaultUnknownGivenName: '',
|
|
42
|
+
defaultUnknownFamilyName: '',
|
|
43
|
+
displayCapturePhoto: false,
|
|
44
|
+
displayReverseFieldOrder: false,
|
|
45
|
+
},
|
|
46
|
+
} as RegistrationConfig['fieldConfigurations'],
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
it('has a label', () => {
|
|
50
|
+
render(
|
|
42
51
|
<Formik initialValues={{}} onSubmit={null}>
|
|
43
52
|
<Form>
|
|
44
53
|
<GenderField />
|
|
45
54
|
</Form>
|
|
46
55
|
</Formik>,
|
|
47
56
|
);
|
|
48
|
-
};
|
|
49
57
|
|
|
50
|
-
|
|
51
|
-
expect(
|
|
58
|
+
expect(screen.getByRole('heading', { name: /sex/i })).toBeInTheDocument();
|
|
59
|
+
expect(screen.getByLabelText(/^male/i)).toBeInTheDocument();
|
|
60
|
+
expect(screen.getByLabelText(/female/i)).toBeInTheDocument();
|
|
52
61
|
});
|
|
53
62
|
|
|
54
63
|
it('checks an option', async () => {
|
|
55
64
|
const user = userEvent.setup();
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
render(
|
|
66
|
+
<Formik initialValues={{}} onSubmit={null}>
|
|
67
|
+
<Form>
|
|
68
|
+
<GenderField />
|
|
69
|
+
</Form>
|
|
70
|
+
</Formik>,
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
await user.click(screen.getByText(/female/i));
|
|
74
|
+
expect(screen.getByLabelText(/female/i)).toBeChecked();
|
|
75
|
+
expect(screen.getByLabelText(/^male/i)).not.toBeChecked();
|
|
58
76
|
});
|
|
59
77
|
});
|
|
@@ -4,13 +4,13 @@ import { Button, SkeletonText } from '@carbon/react';
|
|
|
4
4
|
import { ArrowRight } from '@carbon/react/icons';
|
|
5
5
|
import { useLayoutType, useConfig, isDesktop, UserHasAccess } from '@openmrs/esm-framework';
|
|
6
6
|
import IdentifierSelectionOverlay from './identifier-selection-overlay.component';
|
|
7
|
-
import
|
|
7
|
+
import IdentifierInput from '../../input/custom-input/identifier/identifier-input.component';
|
|
8
8
|
import { PatientRegistrationContext } from '../../patient-registration-context';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
import type {
|
|
10
|
+
FormValues,
|
|
11
|
+
IdentifierSource,
|
|
12
|
+
PatientIdentifierType,
|
|
13
|
+
PatientIdentifierValue,
|
|
14
14
|
} from '../../patient-registration.types';
|
|
15
15
|
import { ResourcesContext } from '../../../offline.resources';
|
|
16
16
|
import styles from '../field.scss';
|
|
@@ -58,7 +58,7 @@ export function deleteIdentifierType(identifiers: FormValues['identifiers'], ide
|
|
|
58
58
|
|
|
59
59
|
export const Identifiers: React.FC = () => {
|
|
60
60
|
const { identifierTypes } = useContext(ResourcesContext);
|
|
61
|
-
const isLoading = !identifierTypes;
|
|
61
|
+
const isLoading = !identifierTypes?.length;
|
|
62
62
|
const { values, setFieldValue, initialFormValues, isOffline } = useContext(PatientRegistrationContext);
|
|
63
63
|
const { t } = useTranslation();
|
|
64
64
|
const layout = useLayoutType();
|
|
@@ -67,7 +67,6 @@ export const Identifiers: React.FC = () => {
|
|
|
67
67
|
const { defaultPatientIdentifierTypes } = config;
|
|
68
68
|
|
|
69
69
|
useEffect(() => {
|
|
70
|
-
// Initialization
|
|
71
70
|
if (identifierTypes) {
|
|
72
71
|
const identifiers = {};
|
|
73
72
|
identifierTypes
|
|
@@ -108,23 +107,23 @@ export const Identifiers: React.FC = () => {
|
|
|
108
107
|
|
|
109
108
|
if (isLoading && !isOffline) {
|
|
110
109
|
return (
|
|
111
|
-
<div
|
|
110
|
+
<div className={styles.halfWidthInDesktopView}>
|
|
112
111
|
<div className={styles.identifierLabelText}>
|
|
113
112
|
<h4 className={styles.productiveHeading02Light}>{t('idFieldLabelText', 'Identifiers')}</h4>
|
|
114
113
|
</div>
|
|
115
|
-
<SkeletonText />
|
|
114
|
+
<SkeletonText role="progressbar" />
|
|
116
115
|
</div>
|
|
117
116
|
);
|
|
118
117
|
}
|
|
119
118
|
|
|
120
119
|
return (
|
|
121
120
|
<div className={styles.halfWidthInDesktopView}>
|
|
122
|
-
<UserHasAccess privilege={['Get Identifier Types', 'Add
|
|
121
|
+
<UserHasAccess privilege={['Get Identifier Types', 'Add patient identifiers']}>
|
|
123
122
|
<div className={styles.identifierLabelText}>
|
|
124
123
|
<h4 className={styles.productiveHeading02Light}>{t('idFieldLabelText', 'Identifiers')}</h4>
|
|
125
124
|
<Button
|
|
126
125
|
kind="ghost"
|
|
127
|
-
className={styles.
|
|
126
|
+
className={styles.configureIdentifiersButton}
|
|
128
127
|
onClick={() => setShowIdentifierOverlay(true)}
|
|
129
128
|
size={isDesktop(layout) ? 'sm' : 'md'}>
|
|
130
129
|
{t('configure', 'Configure')} <ArrowRight size={16} />
|