@kenyaemr/esm-patient-registration-app 8.1.1-pre.116 → 8.1.1-pre.119
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 +13 -13
- package/dist/10.js +1 -0
- package/dist/10.js.map +1 -0
- package/dist/130.js +1 -1
- package/dist/130.js.map +1 -1
- package/dist/574.js +1 -1
- package/dist/kenyaemr-esm-patient-registration-app.js +1 -1
- package/dist/kenyaemr-esm-patient-registration-app.js.buildmanifest.json +37 -37
- package/dist/kenyaemr-esm-patient-registration-app.js.map +1 -1
- 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/client-registry/hie-client-registry/hie-resource.ts +5 -12
- package/src/config-schema.ts +7 -0
- package/src/patient-registration/field/field.scss +17 -0
- package/src/patient-registration/field/id/id-field.component.tsx +8 -6
- package/src/patient-registration/field/id/id-field.test.tsx +27 -8
- package/src/patient-registration/field/person-attributes/location-person-attribute-field.component.tsx +105 -0
- package/src/patient-registration/field/person-attributes/location-person-attribute-field.resource.tsx +48 -0
- package/src/patient-registration/field/person-attributes/person-attribute-field.component.tsx +12 -1
- package/src/patient-registration/form-manager.test.ts +18 -0
- package/src/patient-registration/form-manager.ts +10 -5
- package/src/patient-registration/input/custom-input/identifier/identifier-input.component.tsx +17 -9
- package/src/patient-registration/input/custom-input/identifier/identifier-input.test.tsx +106 -58
- package/src/patient-registration/input/input.scss +5 -0
- package/translations/en.json +2 -0
- package/dist/471.js +0 -1
- package/dist/471.js.map +0 -1
|
@@ -2,25 +2,22 @@
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { render, screen } from '@testing-library/react';
|
|
4
4
|
import { Form, Formik } from 'formik';
|
|
5
|
+
import { getDefaultsFromConfigSchema, useConfig } from '@openmrs/esm-framework';
|
|
6
|
+
import { esmPatientRegistrationSchema, type RegistrationConfig } from '../../../../config-schema';
|
|
5
7
|
import { ResourcesContext, type Resources } from '../../../../offline.resources';
|
|
6
8
|
import {
|
|
7
9
|
PatientRegistrationContext,
|
|
8
10
|
type PatientRegistrationContextProps,
|
|
9
11
|
} from '../../../patient-registration-context';
|
|
10
|
-
import type {
|
|
12
|
+
import type {
|
|
13
|
+
AddressTemplate,
|
|
14
|
+
FormValues,
|
|
15
|
+
IdentifierSource,
|
|
16
|
+
PatientIdentifierValue,
|
|
17
|
+
} from '../../../patient-registration.types';
|
|
11
18
|
import IdentifierInput from './identifier-input.component';
|
|
12
19
|
import userEvent from '@testing-library/user-event';
|
|
13
20
|
|
|
14
|
-
const predefinedAddressTemplate = {
|
|
15
|
-
uuid: 'test-address-template-uuid',
|
|
16
|
-
property: 'layout.address.format',
|
|
17
|
-
description: 'Test Address Template',
|
|
18
|
-
display:
|
|
19
|
-
'Layout - Address Format = <org.openmrs.layout.address.AddressTemplate>\n <nameMappings class="properties">\n <property name="postalCode" value="Location.postalCode"/>\n <property name="address2" value="Location.address2"/>\n <property name="address1" value="Location.address1"/>\n <property name="country" value="Location.country"/>\n <property name="stateProvince" value="Location.stateProvince"/>\n <property name="cityVillage" value="Location.cityVillage"/>\n </nameMappings>\n <sizeMappings class="properties">\n <property name="postalCode" value="10"/>\n <property name="address2" value="40"/>\n <property name="address1" value="40"/>\n <property name="country" value="10"/>\n <property name="stateProvince" value="10"/>\n <property name="cityVillage" value="10"/>\n </sizeMappings>\n <lineByLineFormat>\n <string>address1</string>\n <string>address2</string>\n <string>cityVillage stateProvince country postalCode</string>\n </lineByLineFormat>\n </org.openmrs.layout.address.AddressTemplate>',
|
|
20
|
-
value:
|
|
21
|
-
'<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>',
|
|
22
|
-
};
|
|
23
|
-
|
|
24
21
|
const mockIdentifierTypes = [
|
|
25
22
|
{
|
|
26
23
|
fieldName: 'openMrsId',
|
|
@@ -44,7 +41,7 @@ const mockIdentifierTypes = [
|
|
|
44
41
|
];
|
|
45
42
|
|
|
46
43
|
const mockResourcesContextValue: Resources = {
|
|
47
|
-
addressTemplate:
|
|
44
|
+
addressTemplate: {} as AddressTemplate,
|
|
48
45
|
currentSession: {
|
|
49
46
|
authenticated: true,
|
|
50
47
|
sessionId: 'JSESSION',
|
|
@@ -68,30 +65,35 @@ const mockContextValues: PatientRegistrationContextProps = {
|
|
|
68
65
|
values: {} as FormValues,
|
|
69
66
|
};
|
|
70
67
|
|
|
68
|
+
const mockUseConfig = jest.mocked(useConfig<RegistrationConfig>);
|
|
69
|
+
|
|
71
70
|
describe('identifier input', () => {
|
|
71
|
+
mockUseConfig.mockReturnValue({
|
|
72
|
+
...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
|
|
73
|
+
});
|
|
74
|
+
|
|
72
75
|
const fieldName = 'openMrsId';
|
|
73
76
|
const openmrsID = {
|
|
74
77
|
identifierTypeUuid: '05a29f94-c0ed-11e2-94be-8c13b969e334',
|
|
75
78
|
initialValue: '',
|
|
76
|
-
identifierValue: '',
|
|
77
79
|
identifierName: 'OpenMRS ID',
|
|
78
80
|
selectedSource: {
|
|
79
81
|
uuid: '01af8526-cea4-4175-aa90-340acb411771',
|
|
80
82
|
name: 'Generator 2 for OpenMRS ID',
|
|
81
83
|
autoGenerationOption: {
|
|
82
|
-
manualEntryEnabled:
|
|
84
|
+
manualEntryEnabled: false,
|
|
83
85
|
automaticGenerationEnabled: true,
|
|
84
86
|
},
|
|
85
|
-
},
|
|
87
|
+
} as IdentifierSource,
|
|
86
88
|
autoGeneration: false,
|
|
87
89
|
preferred: true,
|
|
88
90
|
required: true,
|
|
89
|
-
};
|
|
91
|
+
} as PatientIdentifierValue;
|
|
90
92
|
|
|
91
|
-
const setupIdentifierInput =
|
|
93
|
+
const setupIdentifierInput = (patientIdentifier: PatientIdentifierValue, initialValues = {}) => {
|
|
92
94
|
render(
|
|
93
95
|
<ResourcesContext.Provider value={mockResourcesContextValue}>
|
|
94
|
-
<Formik initialValues={
|
|
96
|
+
<Formik initialValues={initialValues} onSubmit={jest.fn()}>
|
|
95
97
|
<Form>
|
|
96
98
|
<PatientRegistrationContext.Provider value={mockContextValues}>
|
|
97
99
|
<IdentifierInput patientIdentifier={patientIdentifier} fieldName={fieldName} />
|
|
@@ -100,56 +102,102 @@ describe('identifier input', () => {
|
|
|
100
102
|
</Formik>
|
|
101
103
|
</ResourcesContext.Provider>,
|
|
102
104
|
);
|
|
103
|
-
|
|
104
|
-
let identifierLabel: HTMLParagraphElement;
|
|
105
|
-
let identifierInput: HTMLInputElement;
|
|
106
|
-
if (patientIdentifier.autoGeneration) {
|
|
107
|
-
identifierLabel = screen.getByTestId('identifier-label');
|
|
108
|
-
identifierInput = screen.getByTestId('identifier-input');
|
|
109
|
-
} else {
|
|
110
|
-
identifierLabel = screen.getByText(patientIdentifier.identifierName);
|
|
111
|
-
identifierInput = screen.getByLabelText(patientIdentifier.identifierName);
|
|
112
|
-
}
|
|
113
|
-
return {
|
|
114
|
-
identifierLabel,
|
|
115
|
-
identifierInput,
|
|
116
|
-
};
|
|
117
105
|
};
|
|
118
106
|
|
|
119
|
-
it('shows the identifier input',
|
|
120
|
-
|
|
121
|
-
|
|
107
|
+
it('shows the identifier input', () => {
|
|
108
|
+
openmrsID.autoGeneration = false;
|
|
109
|
+
setupIdentifierInput(openmrsID as PatientIdentifierValue);
|
|
110
|
+
expect(screen.getByLabelText(openmrsID.identifierName)).toBeInTheDocument();
|
|
122
111
|
});
|
|
123
112
|
|
|
124
|
-
|
|
125
|
-
|
|
113
|
+
it('displays an edit button when there is an initial value', async () => {
|
|
114
|
+
// setup
|
|
115
|
+
openmrsID.autoGeneration = false;
|
|
116
|
+
openmrsID.required = false;
|
|
117
|
+
openmrsID.initialValue = '1002UU9';
|
|
118
|
+
openmrsID.identifierValue = '1002UU9';
|
|
119
|
+
// replay
|
|
120
|
+
setupIdentifierInput(openmrsID as PatientIdentifierValue);
|
|
121
|
+
expect(screen.getByText('Edit')).toBeInTheDocument();
|
|
122
|
+
});
|
|
126
123
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
124
|
+
it('hides the edit button when the identifier is required', async () => {
|
|
125
|
+
// setup
|
|
126
|
+
openmrsID.autoGeneration = false;
|
|
127
|
+
openmrsID.required = true;
|
|
128
|
+
openmrsID.initialValue = '1002UU9';
|
|
129
|
+
openmrsID.identifierValue = '1002UU9';
|
|
130
|
+
// replay
|
|
131
|
+
setupIdentifierInput(openmrsID);
|
|
132
|
+
expect(screen.queryByText('Edit')).not.toBeInTheDocument();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('displays a delete button when the identifier is not a default type', () => {
|
|
136
|
+
// setup
|
|
137
|
+
openmrsID.required = false;
|
|
138
|
+
// replay
|
|
139
|
+
setupIdentifierInput(openmrsID);
|
|
140
|
+
expect(screen.getByText('Delete')).toBeInTheDocument();
|
|
141
|
+
});
|
|
131
142
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
143
|
+
describe('auto-generated identifier', () => {
|
|
144
|
+
it('hides the input when the identifier is auto-generated', () => {
|
|
145
|
+
openmrsID.autoGeneration = true;
|
|
146
|
+
setupIdentifierInput(openmrsID);
|
|
147
|
+
expect(screen.getByTestId('identifier-input')).toHaveAttribute('type', 'hidden');
|
|
136
148
|
});
|
|
137
149
|
|
|
138
|
-
it(
|
|
139
|
-
|
|
140
|
-
openmrsID
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
await setupIdentifierInput(openmrsID);
|
|
144
|
-
expect(screen.getByText('Edit')).toBeInTheDocument();
|
|
150
|
+
it("displays 'Auto-Generated' when the indentifier has auto generation", () => {
|
|
151
|
+
openmrsID.autoGeneration = true;
|
|
152
|
+
setupIdentifierInput(openmrsID);
|
|
153
|
+
expect(screen.getByTestId('identifier-placeholder').innerHTML).toBe('Auto-generated');
|
|
154
|
+
expect(screen.getByTestId('identifier-input')).toBeDisabled();
|
|
145
155
|
});
|
|
146
156
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
157
|
+
describe('manual entry allowed', () => {
|
|
158
|
+
openmrsID.selectedSource = {
|
|
159
|
+
autoGenerationOption: {
|
|
160
|
+
manualEntryEnabled: true,
|
|
161
|
+
},
|
|
162
|
+
} as IdentifierSource;
|
|
163
|
+
|
|
164
|
+
it('shows the edit button', () => {
|
|
165
|
+
openmrsID.autoGeneration = true;
|
|
166
|
+
setupIdentifierInput(openmrsID);
|
|
167
|
+
expect(screen.getByText('Edit')).toBeInTheDocument();
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
describe('edit button clicked', () => {
|
|
171
|
+
it('displays an empty input field', async () => {
|
|
172
|
+
const user = userEvent.setup();
|
|
173
|
+
openmrsID.autoGeneration = true;
|
|
174
|
+
openmrsID.required = false;
|
|
175
|
+
openmrsID.selectedSource = {
|
|
176
|
+
autoGenerationOption: {
|
|
177
|
+
manualEntryEnabled: true,
|
|
178
|
+
},
|
|
179
|
+
} as IdentifierSource;
|
|
180
|
+
setupIdentifierInput(openmrsID);
|
|
181
|
+
const editButton = screen.getByTestId('edit-button');
|
|
182
|
+
await user.click(editButton);
|
|
183
|
+
expect(screen.getByLabelText(new RegExp(`${openmrsID.identifierName}`))).toHaveValue('');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('displays an input field with the identifier value if it exists', async () => {
|
|
187
|
+
const user = userEvent.setup();
|
|
188
|
+
openmrsID.autoGeneration = true;
|
|
189
|
+
openmrsID.required = false;
|
|
190
|
+
openmrsID.selectedSource = {
|
|
191
|
+
autoGenerationOption: {
|
|
192
|
+
manualEntryEnabled: true,
|
|
193
|
+
},
|
|
194
|
+
} as IdentifierSource;
|
|
195
|
+
setupIdentifierInput(openmrsID, { identifiers: { [fieldName]: { identifierValue: '10001V' } } });
|
|
196
|
+
const editButton = screen.getByTestId('edit-button');
|
|
197
|
+
await user.click(editButton);
|
|
198
|
+
expect(screen.getByLabelText(new RegExp(`${openmrsID.identifierName}`))).toHaveValue('10001V');
|
|
199
|
+
});
|
|
200
|
+
});
|
|
153
201
|
});
|
|
154
202
|
});
|
|
155
203
|
});
|
package/translations/en.json
CHANGED
|
@@ -95,6 +95,7 @@
|
|
|
95
95
|
"nupi": "NUPI",
|
|
96
96
|
"obsFieldUnknownDatatype": "Concept for obs field '{{fieldDefinitionId}}' has unknown datatype '{{datatypeName}}'",
|
|
97
97
|
"optional": "optional",
|
|
98
|
+
"optionalIdentifierLabel": "{{identifierName}} (optional)",
|
|
98
99
|
"other": "Other",
|
|
99
100
|
"patientDetailsFound": "Patient information found in the registry, do you want to use the information to continue with registration?",
|
|
100
101
|
"patientName": "Patient name",
|
|
@@ -123,6 +124,7 @@
|
|
|
123
124
|
"searchClientRegistry": "Search client registry",
|
|
124
125
|
"searchIdentifierPlaceholder": "Search identifier",
|
|
125
126
|
"searchingRegistry": "Searching registry...",
|
|
127
|
+
"searchLocationPersonAttribute": "Search location",
|
|
126
128
|
"searchRegistry": "Search registry",
|
|
127
129
|
"selectAnOption": "Select an option",
|
|
128
130
|
"selectCountry": "Select country",
|