@kenyaemr/esm-patient-registration-app 7.0.3-pre.89 → 8.0.1-pre.95
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 +2 -2
- 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,55 +1,47 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { Form, Formik } from 'formik';
|
|
2
3
|
import { render, screen } from '@testing-library/react';
|
|
3
4
|
import { usePersonAttributeType } from './person-attributes.resource';
|
|
4
|
-
import { PersonAttributeField } from './person-attribute-field.component';
|
|
5
5
|
import { useConceptAnswers } from '../field.resource';
|
|
6
|
-
import { Form, Formik } from 'formik';
|
|
7
6
|
import { type FieldDefinition } from '../../../config-schema';
|
|
7
|
+
import { PersonAttributeField } from './person-attribute-field.component';
|
|
8
8
|
|
|
9
|
-
jest.mock('./person-attributes.resource');
|
|
10
|
-
jest.mock('../field.resource');
|
|
11
|
-
|
|
12
|
-
jest.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
9
|
+
jest.mock('./person-attributes.resource');
|
|
10
|
+
jest.mock('../field.resource');
|
|
11
|
+
|
|
12
|
+
const mockUsePersonAttributeType = jest.mocked(usePersonAttributeType);
|
|
13
|
+
const mockUseConceptAnswers = jest.mocked(useConceptAnswers);
|
|
14
|
+
|
|
15
|
+
const mockPersonAttributeType = {
|
|
16
|
+
format: 'java.lang.String',
|
|
17
|
+
display: 'Referred by',
|
|
18
|
+
uuid: '4dd56a75-14ab-4148-8700-1f4f704dc5b0',
|
|
19
|
+
name: 'Referred by',
|
|
20
|
+
description: 'The person who referred the patient',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
let fieldDefinition: FieldDefinition = {
|
|
24
|
+
id: 'referredby',
|
|
25
|
+
label: 'Referred by',
|
|
26
|
+
type: 'person attribute',
|
|
27
|
+
uuid: '4dd56a75-14ab-4148-8700-1f4f704dc5b0',
|
|
28
|
+
answerConceptSetUuid: '6682d17f-0777-45e4-a39b-93f77eb3531c',
|
|
29
|
+
validation: {
|
|
30
|
+
matches: '',
|
|
31
|
+
required: true,
|
|
32
|
+
},
|
|
33
|
+
showHeading: true,
|
|
34
|
+
};
|
|
20
35
|
|
|
21
36
|
describe('PersonAttributeField', () => {
|
|
22
|
-
let mockPersonAttributeType = {
|
|
23
|
-
format: 'java.lang.String',
|
|
24
|
-
display: 'Referred by',
|
|
25
|
-
uuid: '4dd56a75-14ab-4148-8700-1f4f704dc5b0',
|
|
26
|
-
};
|
|
27
|
-
|
|
28
37
|
beforeEach(() => {
|
|
29
|
-
|
|
30
|
-
id: 'referredby',
|
|
31
|
-
name: 'Referred by',
|
|
32
|
-
type: 'person attribute',
|
|
33
|
-
uuid: '4dd56a75-14ab-4148-8700-1f4f704dc5b0',
|
|
34
|
-
answerConceptSetUuid: '6682d17f-0777-45e4-a39b-93f77eb3531c',
|
|
35
|
-
validation: {
|
|
36
|
-
matches: '',
|
|
37
|
-
required: true,
|
|
38
|
-
},
|
|
39
|
-
showHeading: true,
|
|
40
|
-
};
|
|
41
|
-
mockedUsePersonAttributeType.mockReturnValue({
|
|
38
|
+
mockUsePersonAttributeType.mockReturnValue({
|
|
42
39
|
data: mockPersonAttributeType,
|
|
43
40
|
isLoading: false,
|
|
44
41
|
error: null,
|
|
45
|
-
uuid: '14d4f066-15f5-102d-96e4-000c29c2a5d7d',
|
|
46
42
|
});
|
|
47
43
|
});
|
|
48
44
|
|
|
49
|
-
afterEach(() => {
|
|
50
|
-
jest.resetAllMocks();
|
|
51
|
-
});
|
|
52
|
-
|
|
53
45
|
it('renders the text input field for String format', () => {
|
|
54
46
|
render(
|
|
55
47
|
<Formik initialValues={{}} onSubmit={() => {}}>
|
|
@@ -78,23 +70,24 @@ describe('PersonAttributeField', () => {
|
|
|
78
70
|
</Form>
|
|
79
71
|
</Formik>,
|
|
80
72
|
);
|
|
73
|
+
|
|
81
74
|
expect(screen.queryByRole('heading')).not.toBeInTheDocument();
|
|
82
75
|
});
|
|
83
76
|
|
|
84
77
|
it('renders the coded attribute field for Concept format', () => {
|
|
85
|
-
mockedUsePersonAttributeType.mockReturnValue({
|
|
86
|
-
data: { ...mockPersonAttributeType, format: 'org.openmrs.Concept' },
|
|
87
|
-
isLoading: false,
|
|
88
|
-
error: null,
|
|
89
|
-
});
|
|
90
|
-
|
|
91
78
|
fieldDefinition = {
|
|
92
79
|
id: 'referredby',
|
|
93
80
|
...fieldDefinition,
|
|
94
81
|
label: 'Referred by',
|
|
95
82
|
};
|
|
96
83
|
|
|
97
|
-
|
|
84
|
+
mockUsePersonAttributeType.mockReturnValue({
|
|
85
|
+
data: { ...mockPersonAttributeType, format: 'org.openmrs.Concept' },
|
|
86
|
+
isLoading: false,
|
|
87
|
+
error: null,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
mockUseConceptAnswers.mockReturnValueOnce({
|
|
98
91
|
data: [
|
|
99
92
|
{ uuid: '1', display: 'Option 1' },
|
|
100
93
|
{ uuid: '2', display: 'Option 2' },
|
|
@@ -118,7 +111,7 @@ describe('PersonAttributeField', () => {
|
|
|
118
111
|
});
|
|
119
112
|
|
|
120
113
|
it('renders an error notification if attribute type has unknown format', () => {
|
|
121
|
-
|
|
114
|
+
mockUsePersonAttributeType.mockReturnValue({
|
|
122
115
|
data: { ...mockPersonAttributeType, format: 'unknown' },
|
|
123
116
|
isLoading: false,
|
|
124
117
|
error: null,
|
|
@@ -135,17 +128,20 @@ describe('PersonAttributeField', () => {
|
|
|
135
128
|
expect(screen.getByText('Error')).toBeInTheDocument();
|
|
136
129
|
expect(screen.getByText(/Patient attribute type has unknown format/i)).toBeInTheDocument();
|
|
137
130
|
});
|
|
131
|
+
|
|
138
132
|
it('renders an error notification if unable to fetch attribute type', () => {
|
|
139
|
-
|
|
133
|
+
mockUsePersonAttributeType.mockReturnValue({
|
|
140
134
|
data: null,
|
|
141
135
|
isLoading: false,
|
|
142
136
|
error: new Error('Failed to fetch attribute type'),
|
|
143
137
|
});
|
|
144
138
|
|
|
145
139
|
fieldDefinition = {
|
|
140
|
+
id: 'referredBy',
|
|
146
141
|
uuid: 'attribute-uuid',
|
|
147
142
|
label: 'Attribute',
|
|
148
143
|
showHeading: false,
|
|
144
|
+
type: 'person attribute',
|
|
149
145
|
};
|
|
150
146
|
|
|
151
147
|
render(
|
|
@@ -160,17 +156,19 @@ describe('PersonAttributeField', () => {
|
|
|
160
156
|
expect(screen.getByText(/Unable to fetch person attribute type/i)).toBeInTheDocument();
|
|
161
157
|
});
|
|
162
158
|
|
|
163
|
-
it('renders a skeleton if attribute type is loading', () => {
|
|
164
|
-
|
|
159
|
+
it('renders a skeleton if attribute type is loading', async () => {
|
|
160
|
+
mockUsePersonAttributeType.mockReturnValue({
|
|
165
161
|
data: null,
|
|
166
162
|
isLoading: true,
|
|
167
163
|
error: null,
|
|
168
164
|
});
|
|
169
165
|
|
|
170
166
|
fieldDefinition = {
|
|
167
|
+
id: 'referredBy',
|
|
171
168
|
uuid: 'attribute-uuid',
|
|
172
169
|
label: 'Attribute',
|
|
173
170
|
showHeading: true,
|
|
171
|
+
type: 'person attribute',
|
|
174
172
|
};
|
|
175
173
|
|
|
176
174
|
render(
|
|
@@ -180,8 +178,8 @@ describe('PersonAttributeField', () => {
|
|
|
180
178
|
</Form>
|
|
181
179
|
</Formik>,
|
|
182
180
|
);
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
expect(
|
|
181
|
+
|
|
182
|
+
await screen.findByRole('heading', { name: /attribute/i });
|
|
183
|
+
expect(screen.queryByLabelText(/Referred by/i)).not.toBeInTheDocument();
|
|
186
184
|
});
|
|
187
185
|
});
|
package/src/patient-registration/field/person-attributes/text-person-attribute-field.test.tsx
CHANGED
|
@@ -9,6 +9,8 @@ describe('TextPersonAttributeField', () => {
|
|
|
9
9
|
format: 'java.lang.String',
|
|
10
10
|
display: 'Referred by',
|
|
11
11
|
uuid: '4dd56a75-14ab-4148-8700-1f4f704dc5b0',
|
|
12
|
+
description: 'Referred by',
|
|
13
|
+
name: 'Referred by',
|
|
12
14
|
};
|
|
13
15
|
|
|
14
16
|
it('renders the input field with a label', () => {
|
|
@@ -40,7 +40,7 @@ describe('the select input', () => {
|
|
|
40
40
|
</Formik>,
|
|
41
41
|
);
|
|
42
42
|
|
|
43
|
-
await
|
|
43
|
+
await screen.findByRole('combobox');
|
|
44
44
|
|
|
45
45
|
const selectInput = screen.getByRole('combobox', { name: 'Select (optional)' }) as HTMLSelectElement;
|
|
46
46
|
expect(selectInput.labels).toHaveLength(1);
|
|
@@ -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
|
.label01 {
|
|
6
6
|
@include type.type-style('label-01');
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
position: absolute;
|
|
19
19
|
left: 0;
|
|
20
20
|
background-color: #fff;
|
|
21
|
-
margin-bottom:
|
|
21
|
+
margin-bottom: 1.25rem;
|
|
22
22
|
z-index: 99;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
.suggestions li {
|
|
26
|
-
padding:
|
|
26
|
+
padding: layout.$spacing-05;
|
|
27
27
|
line-height: 1.29;
|
|
28
28
|
color: #525252;
|
|
29
29
|
border-bottom: 1px solid #8d8d8d;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { Autosuggest } from './autosuggest.component';
|
|
3
2
|
import { BrowserRouter } from 'react-router-dom';
|
|
4
3
|
import { render, screen } from '@testing-library/react';
|
|
5
4
|
import userEvent from '@testing-library/user-event';
|
|
5
|
+
import { Autosuggest } from './autosuggest.component';
|
|
6
6
|
|
|
7
7
|
const mockPersons = [
|
|
8
8
|
{
|
|
@@ -23,28 +23,50 @@ const mockPersons = [
|
|
|
23
23
|
},
|
|
24
24
|
];
|
|
25
25
|
|
|
26
|
-
const
|
|
26
|
+
const mockGetSearchResults = async (query: string) => {
|
|
27
27
|
return mockPersons.filter((person) => {
|
|
28
28
|
return person.display.toUpperCase().includes(query.toUpperCase());
|
|
29
29
|
});
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
-
const
|
|
32
|
+
const mockHandleSuggestionSelected = jest.fn((field, value) => [field, value]);
|
|
33
33
|
|
|
34
34
|
describe('Autosuggest', () => {
|
|
35
|
-
afterEach(() => mockedHandleSuggestionSelected.mockClear());
|
|
36
|
-
|
|
37
35
|
it('renders a search box', () => {
|
|
38
|
-
|
|
36
|
+
render(
|
|
37
|
+
<BrowserRouter>
|
|
38
|
+
<Autosuggest
|
|
39
|
+
getSearchResults={mockGetSearchResults}
|
|
40
|
+
getDisplayValue={(item) => item.display}
|
|
41
|
+
getFieldValue={(item) => item.uuid}
|
|
42
|
+
id="person"
|
|
43
|
+
labelText=""
|
|
44
|
+
onSuggestionSelected={mockHandleSuggestionSelected}
|
|
45
|
+
placeholder="Find Person"
|
|
46
|
+
/>
|
|
47
|
+
</BrowserRouter>,
|
|
48
|
+
);
|
|
39
49
|
|
|
40
50
|
expect(screen.getByRole('searchbox')).toBeInTheDocument();
|
|
41
|
-
expect(screen.queryByRole('list')).
|
|
51
|
+
expect(screen.queryByRole('list')).not.toBeInTheDocument();
|
|
42
52
|
});
|
|
43
53
|
|
|
44
54
|
it('renders matching search results in a list when the user types a query', async () => {
|
|
45
55
|
const user = userEvent.setup();
|
|
46
56
|
|
|
47
|
-
|
|
57
|
+
render(
|
|
58
|
+
<BrowserRouter>
|
|
59
|
+
<Autosuggest
|
|
60
|
+
getSearchResults={mockGetSearchResults}
|
|
61
|
+
getDisplayValue={(item) => item.display}
|
|
62
|
+
getFieldValue={(item) => item.uuid}
|
|
63
|
+
id="person"
|
|
64
|
+
labelText=""
|
|
65
|
+
onSuggestionSelected={mockHandleSuggestionSelected}
|
|
66
|
+
placeholder="Find Person"
|
|
67
|
+
/>
|
|
68
|
+
</BrowserRouter>,
|
|
69
|
+
);
|
|
48
70
|
|
|
49
71
|
const searchbox = screen.getByRole('searchbox');
|
|
50
72
|
await user.type(searchbox, 'john');
|
|
@@ -52,7 +74,7 @@ describe('Autosuggest', () => {
|
|
|
52
74
|
const list = screen.getByRole('list');
|
|
53
75
|
|
|
54
76
|
expect(list).toBeInTheDocument();
|
|
55
|
-
expect(
|
|
77
|
+
expect(screen.getAllByRole('listitem').length).toEqual(2);
|
|
56
78
|
expect(screen.getAllByRole('listitem')[0]).toHaveTextContent('John Doe');
|
|
57
79
|
expect(screen.getAllByRole('listitem')[1]).toHaveTextContent('John Smith');
|
|
58
80
|
});
|
|
@@ -60,10 +82,22 @@ describe('Autosuggest', () => {
|
|
|
60
82
|
it('clears the list of suggestions when a suggestion is selected', async () => {
|
|
61
83
|
const user = userEvent.setup();
|
|
62
84
|
|
|
63
|
-
|
|
85
|
+
render(
|
|
86
|
+
<BrowserRouter>
|
|
87
|
+
<Autosuggest
|
|
88
|
+
getSearchResults={mockGetSearchResults}
|
|
89
|
+
getDisplayValue={(item) => item.display}
|
|
90
|
+
getFieldValue={(item) => item.uuid}
|
|
91
|
+
id="person"
|
|
92
|
+
labelText=""
|
|
93
|
+
onSuggestionSelected={mockHandleSuggestionSelected}
|
|
94
|
+
placeholder="Find Person"
|
|
95
|
+
/>
|
|
96
|
+
</BrowserRouter>,
|
|
97
|
+
);
|
|
64
98
|
|
|
65
99
|
let list = screen.queryByRole('list');
|
|
66
|
-
expect(list).
|
|
100
|
+
expect(list).not.toBeInTheDocument();
|
|
67
101
|
|
|
68
102
|
const searchbox = screen.getByRole('searchbox');
|
|
69
103
|
await user.type(searchbox, 'john');
|
|
@@ -74,19 +108,31 @@ describe('Autosuggest', () => {
|
|
|
74
108
|
const listitems = screen.getAllByRole('listitem');
|
|
75
109
|
await user.click(listitems[0]);
|
|
76
110
|
|
|
77
|
-
expect(
|
|
111
|
+
expect(mockHandleSuggestionSelected).toHaveBeenLastCalledWith('person', 'randomuuid1');
|
|
78
112
|
|
|
79
113
|
list = screen.queryByRole('list');
|
|
80
|
-
expect(list).
|
|
114
|
+
expect(list).not.toBeInTheDocument();
|
|
81
115
|
});
|
|
82
116
|
|
|
83
117
|
it('changes suggestions when a search input is changed', async () => {
|
|
84
118
|
const user = userEvent.setup();
|
|
85
119
|
|
|
86
|
-
|
|
120
|
+
render(
|
|
121
|
+
<BrowserRouter>
|
|
122
|
+
<Autosuggest
|
|
123
|
+
getSearchResults={mockGetSearchResults}
|
|
124
|
+
getDisplayValue={(item) => item.display}
|
|
125
|
+
getFieldValue={(item) => item.uuid}
|
|
126
|
+
id="person"
|
|
127
|
+
labelText=""
|
|
128
|
+
onSuggestionSelected={mockHandleSuggestionSelected}
|
|
129
|
+
placeholder="Find Person"
|
|
130
|
+
/>
|
|
131
|
+
</BrowserRouter>,
|
|
132
|
+
);
|
|
87
133
|
|
|
88
134
|
let list = screen.queryByRole('list');
|
|
89
|
-
expect(list).
|
|
135
|
+
expect(list).not.toBeInTheDocument();
|
|
90
136
|
|
|
91
137
|
const searchbox = screen.getByRole('searchbox');
|
|
92
138
|
await user.type(searchbox, 'john');
|
|
@@ -97,13 +143,25 @@ describe('Autosuggest', () => {
|
|
|
97
143
|
await user.clear(searchbox);
|
|
98
144
|
|
|
99
145
|
list = screen.queryByRole('list');
|
|
100
|
-
expect(list).
|
|
146
|
+
expect(list).not.toBeInTheDocument();
|
|
101
147
|
});
|
|
102
148
|
|
|
103
149
|
it('hides the list of suggestions when the user clicks outside of the component', async () => {
|
|
104
150
|
const user = userEvent.setup();
|
|
105
151
|
|
|
106
|
-
|
|
152
|
+
render(
|
|
153
|
+
<BrowserRouter>
|
|
154
|
+
<Autosuggest
|
|
155
|
+
getSearchResults={mockGetSearchResults}
|
|
156
|
+
getDisplayValue={(item) => item.display}
|
|
157
|
+
getFieldValue={(item) => item.uuid}
|
|
158
|
+
id="person"
|
|
159
|
+
labelText=""
|
|
160
|
+
onSuggestionSelected={mockHandleSuggestionSelected}
|
|
161
|
+
placeholder="Find Person"
|
|
162
|
+
/>
|
|
163
|
+
</BrowserRouter>,
|
|
164
|
+
);
|
|
107
165
|
|
|
108
166
|
const input = screen.getByRole('searchbox');
|
|
109
167
|
|
|
@@ -114,19 +172,3 @@ describe('Autosuggest', () => {
|
|
|
114
172
|
expect(screen.queryByText('John Doe')).not.toBeInTheDocument();
|
|
115
173
|
});
|
|
116
174
|
});
|
|
117
|
-
|
|
118
|
-
function renderAutosuggest() {
|
|
119
|
-
render(
|
|
120
|
-
<BrowserRouter>
|
|
121
|
-
<Autosuggest
|
|
122
|
-
getSearchResults={mockedGetSearchResults}
|
|
123
|
-
getDisplayValue={(item) => item.display}
|
|
124
|
-
getFieldValue={(item) => item.uuid}
|
|
125
|
-
id="person"
|
|
126
|
-
labelText=""
|
|
127
|
-
onSuggestionSelected={mockedHandleSuggestionSelected}
|
|
128
|
-
placeholder="Find Person"
|
|
129
|
-
/>
|
|
130
|
-
</BrowserRouter>,
|
|
131
|
-
);
|
|
132
|
-
}
|
package/src/patient-registration/input/custom-input/identifier/identifier-input.component.tsx
CHANGED
|
@@ -17,7 +17,7 @@ interface IdentifierInputProps {
|
|
|
17
17
|
fieldName: string;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
const IdentifierInput: React.FC<IdentifierInputProps> = ({ patientIdentifier, fieldName }) => {
|
|
21
21
|
const { t } = useTranslation();
|
|
22
22
|
const { defaultPatientIdentifierTypes } = useConfig();
|
|
23
23
|
const { identifierTypes } = useContext(ResourcesContext);
|
|
@@ -154,3 +154,5 @@ export const IdentifierInput: React.FC<IdentifierInputProps> = ({ patientIdentif
|
|
|
154
154
|
</div>
|
|
155
155
|
);
|
|
156
156
|
};
|
|
157
|
+
|
|
158
|
+
export default IdentifierInput;
|
|
@@ -1,20 +1,13 @@
|
|
|
1
|
+
/* eslint-disable testing-library/no-node-access */
|
|
1
2
|
import React from 'react';
|
|
2
3
|
import { render, screen } from '@testing-library/react';
|
|
3
4
|
import { Formik, Form } from 'formik';
|
|
4
|
-
import {
|
|
5
|
+
import { type PatientIdentifierType } from '../../../patient-registration.types';
|
|
5
6
|
import { initialFormValues } from '../../../patient-registration.component';
|
|
6
|
-
import
|
|
7
|
+
import IdentifierInput from './identifier-input.component';
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return {
|
|
12
|
-
...originalModule,
|
|
13
|
-
validator: jest.fn(),
|
|
14
|
-
};
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
describe.skip('identifier input', () => {
|
|
9
|
+
// TODO: Fix this test
|
|
10
|
+
xdescribe('identifier input', () => {
|
|
18
11
|
const openmrsID = {
|
|
19
12
|
name: 'OpenMRS ID',
|
|
20
13
|
fieldName: 'openMrsId',
|
|
@@ -42,8 +35,10 @@ describe.skip('identifier input', () => {
|
|
|
42
35
|
],
|
|
43
36
|
autoGenerationSource: null,
|
|
44
37
|
};
|
|
38
|
+
|
|
45
39
|
const setupIdentifierInput = async (identifierType: PatientIdentifierType) => {
|
|
46
40
|
initialFormValues['source-for-' + identifierType.fieldName] = identifierType.identifierSources[0].name;
|
|
41
|
+
|
|
47
42
|
render(
|
|
48
43
|
<Formik initialValues={initialFormValues} onSubmit={null}>
|
|
49
44
|
<Form>
|
|
@@ -61,12 +56,14 @@ describe.skip('identifier input', () => {
|
|
|
61
56
|
|
|
62
57
|
it('exists', async () => {
|
|
63
58
|
const { identifierInput, identifierSourceSelectInput } = await setupIdentifierInput(openmrsID);
|
|
59
|
+
|
|
64
60
|
expect(identifierInput.type).toBe('text');
|
|
65
61
|
expect(identifierSourceSelectInput.type).toBe('select-one');
|
|
66
62
|
});
|
|
67
63
|
|
|
68
64
|
it('has correct props for identifier source select input', async () => {
|
|
69
65
|
const { identifierSourceSelectInput } = await setupIdentifierInput(openmrsID);
|
|
66
|
+
|
|
70
67
|
expect(identifierSourceSelectInput.childElementCount).toBe(3);
|
|
71
68
|
expect(identifierSourceSelectInput.value).toBe('Generator 1 for OpenMRS ID');
|
|
72
69
|
});
|
|
@@ -3,18 +3,9 @@ import { render, screen } from '@testing-library/react';
|
|
|
3
3
|
import userEvent from '@testing-library/user-event';
|
|
4
4
|
import { DummyDataInput, dummyFormValues } from './dummy-data-input.component';
|
|
5
5
|
import { initialFormValues } from '../../patient-registration.component';
|
|
6
|
-
import { type FormValues } from '../../patient-registration
|
|
6
|
+
import { type FormValues } from '../../patient-registration.types';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
const originalModule = jest.requireActual('@openmrs/esm-framework');
|
|
10
|
-
|
|
11
|
-
return {
|
|
12
|
-
...originalModule,
|
|
13
|
-
validator: jest.fn(),
|
|
14
|
-
};
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
describe('dummy data input', () => {
|
|
8
|
+
describe('Dummy data input', () => {
|
|
18
9
|
let formValues: FormValues = initialFormValues;
|
|
19
10
|
|
|
20
11
|
const setupInput = async () => {
|
|
@@ -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
|
.fieldRow {
|
|
6
6
|
display: flex;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
.subFieldRow {
|
|
13
|
-
margin-bottom:
|
|
13
|
+
margin-bottom: 0.3125rem;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
.label {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
.textID,
|
|
22
22
|
.comboInput {
|
|
23
|
-
margin-bottom:
|
|
23
|
+
margin-bottom: layout.$spacing-05;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
.requiredField {
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
.input {
|
|
31
|
-
margin-right:
|
|
31
|
+
margin-right: 0.3125rem;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
.checkboxField {
|
|
35
35
|
display: flex;
|
|
36
36
|
flex-direction: row;
|
|
37
37
|
justify-content: flex-start;
|
|
38
|
-
width:
|
|
39
|
-
margin-left:
|
|
38
|
+
width: 25rem;
|
|
39
|
+
margin-left: 0.625rem;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
.textInput {
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
.checkboxInput {
|
|
53
|
-
height:
|
|
54
|
-
width:
|
|
55
|
-
margin-top:
|
|
53
|
+
height: layout.$spacing-06 !important;
|
|
54
|
+
width: layout.$spacing-06 !important;
|
|
55
|
+
margin-top: layout.$spacing-03;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
.selectInput {
|
|
@@ -114,5 +114,5 @@
|
|
|
114
114
|
|
|
115
115
|
.comboInputItemOption {
|
|
116
116
|
margin: 0;
|
|
117
|
-
padding-left:
|
|
117
|
+
padding-left: layout.$spacing-05;
|
|
118
118
|
}
|
|
@@ -4,16 +4,16 @@ import { type RegistrationConfig } from '../config-schema';
|
|
|
4
4
|
import { type FormValues, type CapturePhotoProps } from './patient-registration.types';
|
|
5
5
|
|
|
6
6
|
export interface PatientRegistrationContextProps {
|
|
7
|
+
currentPhoto: string;
|
|
7
8
|
identifierTypes: Array<any>;
|
|
8
|
-
values: FormValues;
|
|
9
|
-
validationSchema: any;
|
|
10
9
|
inEditMode: boolean;
|
|
11
|
-
setFieldValue(field: string, value: any, shouldValidate?: boolean): void;
|
|
12
|
-
setCapturePhotoProps(value: SetStateAction<CapturePhotoProps>): void;
|
|
13
|
-
currentPhoto: string;
|
|
14
|
-
isOffline: boolean;
|
|
15
10
|
initialFormValues: FormValues;
|
|
11
|
+
isOffline: boolean;
|
|
12
|
+
setCapturePhotoProps(value: SetStateAction<CapturePhotoProps>): void;
|
|
13
|
+
setFieldValue(field: string, value: any, shouldValidate?: boolean): void;
|
|
16
14
|
setInitialFormValues?: React.Dispatch<SetStateAction<FormValues>>;
|
|
15
|
+
validationSchema: any;
|
|
16
|
+
values: FormValues;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const PatientRegistrationContext = createContext<PatientRegistrationContextProps | undefined>(undefined);
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import * as Yup from 'yup';
|
|
2
|
+
import camelCase from 'lodash-es/camelCase';
|
|
3
|
+
import { parseDate } from '@openmrs/esm-framework';
|
|
2
4
|
import {
|
|
3
5
|
type AddressValidationSchemaType,
|
|
4
6
|
type FormValues,
|
|
@@ -7,9 +9,6 @@ import {
|
|
|
7
9
|
type PatientIdentifierValue,
|
|
8
10
|
type Encounter,
|
|
9
11
|
} from './patient-registration.types';
|
|
10
|
-
import { parseDate } from '@openmrs/esm-framework';
|
|
11
|
-
import camelCase from 'lodash-es/camelCase';
|
|
12
|
-
import capitalize from 'lodash-es/capitalize';
|
|
13
12
|
|
|
14
13
|
export function parseAddressTemplateXml(addressTemplate: string) {
|
|
15
14
|
const templateXmlDoc = new DOMParser().parseFromString(addressTemplate, 'text/xml');
|
|
@@ -205,9 +204,9 @@ export function getPhonePersonAttributeValueFromFhirPatient(patient: fhir.Patien
|
|
|
205
204
|
return result;
|
|
206
205
|
}
|
|
207
206
|
|
|
208
|
-
export const
|
|
207
|
+
export const filterOutUndefinedPatientIdentifiers = (patientIdentifiers) =>
|
|
209
208
|
Object.fromEntries(
|
|
210
|
-
Object.entries<PatientIdentifierValue>(
|
|
209
|
+
Object.entries<PatientIdentifierValue>(patientIdentifiers).filter(
|
|
211
210
|
([key, value]) => value.identifierValue !== undefined,
|
|
212
211
|
),
|
|
213
212
|
);
|
|
@@ -18,18 +18,8 @@ import { type FormValues, type CapturePhotoProps } from './patient-registration.
|
|
|
18
18
|
import { PatientRegistrationContext } from './patient-registration-context';
|
|
19
19
|
import { type SavePatientForm, SavePatientTransactionManager } from './form-manager';
|
|
20
20
|
import { DummyDataInput } from './input/dummy-data/dummy-data-input.component';
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
filterUndefinedPatientIdenfier,
|
|
24
|
-
parseAddressTemplateXml,
|
|
25
|
-
scrollIntoView,
|
|
26
|
-
} from './patient-registration-utils';
|
|
27
|
-
import {
|
|
28
|
-
useInitialAddressFieldValues,
|
|
29
|
-
useInitialFormValues,
|
|
30
|
-
usePatientObs,
|
|
31
|
-
usePatientUuidMap,
|
|
32
|
-
} from './patient-registration-hooks';
|
|
21
|
+
import { cancelRegistration, filterOutUndefinedPatientIdentifiers, scrollIntoView } from './patient-registration-utils';
|
|
22
|
+
import { useInitialAddressFieldValues, useInitialFormValues, usePatientUuidMap,usePatientObs } from './patient-registration-hooks';
|
|
33
23
|
import { ResourcesContext } from '../offline.resources';
|
|
34
24
|
import { builtInSections, type RegistrationConfig, type SectionDefinition } from '../config-schema';
|
|
35
25
|
import { SectionWrapper } from './section/section-wrapper.component';
|
|
@@ -46,7 +36,7 @@ export interface PatientRegistrationProps {
|
|
|
46
36
|
}
|
|
47
37
|
|
|
48
38
|
export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePatientForm, isOffline }) => {
|
|
49
|
-
const { currentSession,
|
|
39
|
+
const { currentSession, identifierTypes } = useContext(ResourcesContext);
|
|
50
40
|
const { search } = useLocation();
|
|
51
41
|
const config = useConfig() as RegistrationConfig;
|
|
52
42
|
const [target, setTarget] = useState<undefined | string>();
|
|
@@ -86,7 +76,7 @@ export const PatientRegistration: React.FC<PatientRegistrationProps> = ({ savePa
|
|
|
86
76
|
const abortController = new AbortController();
|
|
87
77
|
helpers.setSubmitting(true);
|
|
88
78
|
|
|
89
|
-
const updatedFormValues = { ...values, identifiers:
|
|
79
|
+
const updatedFormValues = { ...values, identifiers: filterOutUndefinedPatientIdentifiers(values.identifiers) };
|
|
90
80
|
try {
|
|
91
81
|
await savePatientForm(
|
|
92
82
|
!inEditMode,
|
|
@@ -8,10 +8,6 @@ jest.mock('@openmrs/esm-framework', () => ({
|
|
|
8
8
|
}));
|
|
9
9
|
|
|
10
10
|
describe('savePatient', () => {
|
|
11
|
-
afterEach(() => {
|
|
12
|
-
jest.resetAllMocks();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
11
|
it('appends patient uuid in url if provided', () => {
|
|
16
12
|
mockOpenmrsFetch.mockImplementationOnce((url) => url);
|
|
17
13
|
savePatient(null, '1234');
|