@ampath/esm-patient-registration-app 6.0.1-pre.6
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 +41 -0
- package/README.md +7 -0
- package/dist/130.js +2 -0
- package/dist/130.js.LICENSE.txt +3 -0
- package/dist/130.js.map +1 -0
- package/dist/152.js +1 -0
- package/dist/152.js.map +1 -0
- package/dist/249.js +2 -0
- package/dist/249.js.LICENSE.txt +46 -0
- package/dist/249.js.map +1 -0
- package/dist/255.js +2 -0
- package/dist/255.js.LICENSE.txt +9 -0
- package/dist/255.js.map +1 -0
- package/dist/271.js +1 -0
- package/dist/303.js +1 -0
- package/dist/303.js.map +1 -0
- package/dist/319.js +1 -0
- package/dist/365.js +1 -0
- package/dist/365.js.map +1 -0
- package/dist/460.js +1 -0
- package/dist/525.js +1 -0
- package/dist/525.js.map +1 -0
- package/dist/537.js +1 -0
- package/dist/537.js.map +1 -0
- package/dist/574.js +1 -0
- package/dist/591.js +2 -0
- package/dist/591.js.LICENSE.txt +32 -0
- package/dist/591.js.map +1 -0
- package/dist/621.js +1 -0
- package/dist/621.js.map +1 -0
- package/dist/644.js +1 -0
- package/dist/729.js +1 -0
- package/dist/729.js.map +1 -0
- package/dist/735.js +1 -0
- package/dist/735.js.map +1 -0
- package/dist/757.js +1 -0
- package/dist/784.js +2 -0
- package/dist/784.js.LICENSE.txt +9 -0
- package/dist/784.js.map +1 -0
- package/dist/788.js +1 -0
- package/dist/807.js +1 -0
- package/dist/833.js +1 -0
- package/dist/879.js +1 -0
- package/dist/879.js.map +1 -0
- package/dist/ampath-esm-patient-registration-app.js +1 -0
- package/dist/ampath-esm-patient-registration-app.js.buildmanifest.json +649 -0
- package/dist/ampath-esm-patient-registration-app.js.map +1 -0
- package/dist/main.js +2 -0
- package/dist/main.js.LICENSE.txt +56 -0
- package/dist/main.js.map +1 -0
- package/dist/routes.json +1 -0
- package/docs/images/patient-registration-hierarchy.png +0 -0
- package/jest.config.js +3 -0
- package/package.json +61 -0
- package/src/add-patient-link.scss +3 -0
- package/src/add-patient-link.test.tsx +20 -0
- package/src/add-patient-link.tsx +21 -0
- package/src/config-schema.ts +410 -0
- package/src/constants.ts +14 -0
- package/src/declarations.d.ts +6 -0
- package/src/index.ts +71 -0
- package/src/nav-link.test.tsx +13 -0
- package/src/nav-link.tsx +10 -0
- package/src/offline.resources.ts +155 -0
- package/src/offline.ts +91 -0
- package/src/patient-registration/before-save-prompt.tsx +73 -0
- package/src/patient-registration/date-util.ts +52 -0
- package/src/patient-registration/field/__mocks__/field.resource.ts +60 -0
- package/src/patient-registration/field/address/address-field.component.tsx +153 -0
- package/src/patient-registration/field/address/address-hierarchy-levels.component.tsx +73 -0
- package/src/patient-registration/field/address/address-hierarchy.resource.tsx +157 -0
- package/src/patient-registration/field/address/address-search.component.tsx +85 -0
- package/src/patient-registration/field/address/address-search.scss +53 -0
- package/src/patient-registration/field/address/custom-address-field.component.tsx +31 -0
- package/src/patient-registration/field/address/tests/address-hierarchy.test.tsx +214 -0
- package/src/patient-registration/field/address/tests/address-search-component.test.tsx +135 -0
- package/src/patient-registration/field/custom-field.component.tsx +25 -0
- package/src/patient-registration/field/dob/dob.component.tsx +159 -0
- package/src/patient-registration/field/dob/dob.test.tsx +75 -0
- package/src/patient-registration/field/field.component.tsx +47 -0
- package/src/patient-registration/field/field.resource.ts +35 -0
- package/src/patient-registration/field/field.scss +127 -0
- package/src/patient-registration/field/field.test.tsx +294 -0
- package/src/patient-registration/field/gender/gender-field.component.tsx +49 -0
- package/src/patient-registration/field/gender/gender-field.test.tsx +59 -0
- package/src/patient-registration/field/id/id-field.component.tsx +144 -0
- package/src/patient-registration/field/id/id-field.test.tsx +107 -0
- package/src/patient-registration/field/id/identifier-selection-overlay.component.tsx +198 -0
- package/src/patient-registration/field/id/identifier-selection.scss +37 -0
- package/src/patient-registration/field/name/name-field.component.tsx +142 -0
- package/src/patient-registration/field/obs/obs-field.component.tsx +204 -0
- package/src/patient-registration/field/obs/obs-field.test.tsx +205 -0
- package/src/patient-registration/field/person-attributes/coded-attributes.component.tsx +60 -0
- package/src/patient-registration/field/person-attributes/coded-person-attribute-field.component.tsx +116 -0
- package/src/patient-registration/field/person-attributes/coded-person-attribute-field.test.tsx +127 -0
- package/src/patient-registration/field/person-attributes/person-attribute-field.component.tsx +88 -0
- package/src/patient-registration/field/person-attributes/person-attribute-field.test.tsx +187 -0
- package/src/patient-registration/field/person-attributes/person-attributes.resource.ts +20 -0
- package/src/patient-registration/field/person-attributes/text-person-attribute-field.component.tsx +58 -0
- package/src/patient-registration/field/person-attributes/text-person-attribute-field.test.tsx +88 -0
- package/src/patient-registration/field/phone/phone-field.component.tsx +16 -0
- package/src/patient-registration/form-manager.test.ts +67 -0
- package/src/patient-registration/form-manager.ts +414 -0
- package/src/patient-registration/input/basic-input/input/input.component.tsx +179 -0
- package/src/patient-registration/input/basic-input/input/input.test.tsx +72 -0
- package/src/patient-registration/input/basic-input/select/select-input.component.tsx +32 -0
- package/src/patient-registration/input/basic-input/select/select-input.test.tsx +49 -0
- package/src/patient-registration/input/combo-input/combo-input.component.tsx +128 -0
- package/src/patient-registration/input/combo-input/selection-tick.component.tsx +20 -0
- package/src/patient-registration/input/custom-input/autosuggest/autosuggest.component.tsx +187 -0
- package/src/patient-registration/input/custom-input/autosuggest/autosuggest.scss +62 -0
- package/src/patient-registration/input/custom-input/autosuggest/autosuggest.test.tsx +132 -0
- package/src/patient-registration/input/custom-input/identifier/identifier-input.component.tsx +156 -0
- package/src/patient-registration/input/custom-input/identifier/identifier-input.test.tsx +107 -0
- package/src/patient-registration/input/custom-input/identifier/utils.test.ts +81 -0
- package/src/patient-registration/input/custom-input/identifier/utils.ts +19 -0
- package/src/patient-registration/input/dummy-data/dummy-data-input.component.tsx +53 -0
- package/src/patient-registration/input/dummy-data/dummy-data-input.test.tsx +43 -0
- package/src/patient-registration/input/input.scss +118 -0
- package/src/patient-registration/patient-registration-context.ts +24 -0
- package/src/patient-registration/patient-registration-hooks.ts +287 -0
- package/src/patient-registration/patient-registration-utils.ts +216 -0
- package/src/patient-registration/patient-registration.component.tsx +240 -0
- package/src/patient-registration/patient-registration.resource.test.tsx +26 -0
- package/src/patient-registration/patient-registration.resource.ts +250 -0
- package/src/patient-registration/patient-registration.scss +122 -0
- package/src/patient-registration/patient-registration.test.tsx +471 -0
- package/src/patient-registration/patient-registration.types.ts +318 -0
- package/src/patient-registration/section/death-info/death-info-section.component.tsx +31 -0
- package/src/patient-registration/section/death-info/death-info-section.test.tsx +64 -0
- package/src/patient-registration/section/demographics/demographics-section.component.tsx +30 -0
- package/src/patient-registration/section/demographics/demographics-section.test.tsx +83 -0
- package/src/patient-registration/section/generic-section.component.tsx +17 -0
- package/src/patient-registration/section/patient-relationships/relationships-section.component.tsx +235 -0
- package/src/patient-registration/section/patient-relationships/relationships-section.test.tsx +100 -0
- package/src/patient-registration/section/patient-relationships/relationships.resource.tsx +78 -0
- package/src/patient-registration/section/patient-relationships/relationships.scss +35 -0
- package/src/patient-registration/section/section-wrapper.component.tsx +40 -0
- package/src/patient-registration/section/section.component.tsx +23 -0
- package/src/patient-registration/section/section.scss +1 -0
- package/src/patient-registration/ui-components/overlay/overlay.component.tsx +51 -0
- package/src/patient-registration/ui-components/overlay/overlay.scss +63 -0
- package/src/patient-registration/validation/patient-registration-validation.test.tsx +157 -0
- package/src/patient-registration/validation/patient-registration-validation.tsx +60 -0
- package/src/patient-verification/client-registry-constants.ts +13 -0
- package/src/patient-verification/client-registry.component.tsx +66 -0
- package/src/patient-verification/client-registry.scss +1 -0
- package/src/patient-verification/utils.tsx +56 -0
- package/src/patient-verification/verification-modal.scss +20 -0
- package/src/patient-verification/verification.component.tsx +48 -0
- package/src/resource.ts +12 -0
- package/src/root.component.tsx +63 -0
- package/src/root.scss +7 -0
- package/src/root.test.tsx +32 -0
- package/src/routes.json +66 -0
- package/src/widgets/cancel-patient-edit.component.tsx +37 -0
- package/src/widgets/cancel-patient-edit.test.tsx +27 -0
- package/src/widgets/delete-identifier-confirmation-modal.test.tsx +34 -0
- package/src/widgets/delete-identifier-confirmation-modal.tsx +41 -0
- package/src/widgets/delete-identifier-modal.scss +34 -0
- package/src/widgets/display-photo.component.tsx +30 -0
- package/src/widgets/display-photo.test.tsx +37 -0
- package/src/widgets/edit-patient-details-button.component.tsx +34 -0
- package/src/widgets/edit-patient-details-button.scss +3 -0
- package/src/widgets/edit-patient-details-button.test.tsx +41 -0
- package/translations/am.json +97 -0
- package/translations/ar.json +97 -0
- package/translations/en.json +103 -0
- package/translations/es.json +97 -0
- package/translations/fr.json +97 -0
- package/translations/he.json +97 -0
- package/translations/km.json +97 -0
- package/translations/zh.json +89 -0
- package/translations/zh_CN.json +89 -0
- package/tsconfig.json +5 -0
- package/webpack.config.js +1 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import { type OpenmrsResource, type Session } from '@openmrs/esm-framework';
|
|
2
|
+
import { type RegistrationConfig } from '../config-schema';
|
|
3
|
+
import { type SavePatientTransactionManager } from './form-manager';
|
|
4
|
+
|
|
5
|
+
interface NameValue {
|
|
6
|
+
uuid: string;
|
|
7
|
+
preferred: boolean;
|
|
8
|
+
givenName: string;
|
|
9
|
+
middleName: string;
|
|
10
|
+
familyName: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface AttributeValue {
|
|
14
|
+
attributeType: string;
|
|
15
|
+
value: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Patient Identifier data as it is fetched and composed from the APIs.
|
|
20
|
+
*/
|
|
21
|
+
export interface FetchedPatientIdentifierType {
|
|
22
|
+
name: string;
|
|
23
|
+
required: boolean;
|
|
24
|
+
uuid: string;
|
|
25
|
+
fieldName: string;
|
|
26
|
+
format: string;
|
|
27
|
+
isPrimary: boolean;
|
|
28
|
+
/** See: https://github.com/openmrs/openmrs-core/blob/e3fb1ac0a052aeff0f957a150731757dd319693b/api/src/main/java/org/openmrs/PatientIdentifierType.java#L41 */
|
|
29
|
+
uniquenessBehavior: undefined | null | 'UNIQUE' | 'NON_UNIQUE' | 'LOCATION';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface PatientIdentifierValue {
|
|
33
|
+
identifierUuid?: string;
|
|
34
|
+
identifierTypeUuid: string;
|
|
35
|
+
initialValue: string;
|
|
36
|
+
identifierValue: string;
|
|
37
|
+
identifierName: string;
|
|
38
|
+
selectedSource: IdentifierSource;
|
|
39
|
+
autoGeneration?: boolean;
|
|
40
|
+
preferred: boolean;
|
|
41
|
+
required: boolean;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Extends the `FetchedPatientIdentifierType` with aggregated data.
|
|
46
|
+
*/
|
|
47
|
+
export interface PatientIdentifierType extends FetchedPatientIdentifierType {
|
|
48
|
+
identifierSources: Array<IdentifierSource>;
|
|
49
|
+
autoGenerationSource?: IdentifierSource;
|
|
50
|
+
checked?: boolean;
|
|
51
|
+
source?: IdentifierSource;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface IdentifierSource {
|
|
55
|
+
uuid: string;
|
|
56
|
+
name: string;
|
|
57
|
+
autoGenerationOption?: IdentifierSourceAutoGenerationOption;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface IdentifierSourceAutoGenerationOption {
|
|
61
|
+
manualEntryEnabled: boolean;
|
|
62
|
+
automaticGenerationEnabled: boolean;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface PatientIdentifier {
|
|
66
|
+
uuid?: string;
|
|
67
|
+
identifier: string;
|
|
68
|
+
identifierType?: string;
|
|
69
|
+
location?: string;
|
|
70
|
+
preferred?: boolean;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface PatientRegistration {
|
|
74
|
+
id?: number;
|
|
75
|
+
/**
|
|
76
|
+
* The preliminary patient in the FHIR format.
|
|
77
|
+
*/
|
|
78
|
+
fhirPatient: fhir.Patient;
|
|
79
|
+
/**
|
|
80
|
+
* Internal data collected by patient-registration. Required for later syncing and editing.
|
|
81
|
+
* Not supposed to be used outside of this module.
|
|
82
|
+
*/
|
|
83
|
+
_patientRegistrationData: {
|
|
84
|
+
isNewPatient: boolean;
|
|
85
|
+
formValues: FormValues;
|
|
86
|
+
patientUuidMap: PatientUuidMapType;
|
|
87
|
+
initialAddressFieldValues: Record<string, any>;
|
|
88
|
+
capturePhotoProps: CapturePhotoProps;
|
|
89
|
+
currentLocation: string;
|
|
90
|
+
initialIdentifierValues: FormValues['identifiers'];
|
|
91
|
+
currentUser: Session;
|
|
92
|
+
config: RegistrationConfig;
|
|
93
|
+
savePatientTransactionManager: SavePatientTransactionManager;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export type Relationship = {
|
|
98
|
+
relationshipType: string;
|
|
99
|
+
personA: string;
|
|
100
|
+
personB: string;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export type Patient = {
|
|
104
|
+
uuid: string;
|
|
105
|
+
identifiers: Array<PatientIdentifier>;
|
|
106
|
+
person: {
|
|
107
|
+
uuid: string;
|
|
108
|
+
names: Array<NameValue>;
|
|
109
|
+
gender: string;
|
|
110
|
+
birthdate: string;
|
|
111
|
+
birthdateEstimated: boolean;
|
|
112
|
+
attributes: Array<AttributeValue>;
|
|
113
|
+
addresses: Array<Record<string, string>>;
|
|
114
|
+
dead: boolean;
|
|
115
|
+
deathDate?: string;
|
|
116
|
+
causeOfDeath?: string;
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export interface Encounter {
|
|
121
|
+
encounterDatetime: Date;
|
|
122
|
+
patient: string;
|
|
123
|
+
encounterType: string;
|
|
124
|
+
location: string;
|
|
125
|
+
encounterProviders: Array<{
|
|
126
|
+
provider: string;
|
|
127
|
+
encounterRole: string;
|
|
128
|
+
}>;
|
|
129
|
+
form: string;
|
|
130
|
+
obs: Array<{
|
|
131
|
+
concept: string | OpenmrsResource;
|
|
132
|
+
value: string | number | OpenmrsResource;
|
|
133
|
+
}>;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface RelationshipValue {
|
|
137
|
+
relatedPersonName?: string;
|
|
138
|
+
relatedPersonUuid: string;
|
|
139
|
+
relation?: string;
|
|
140
|
+
relationshipType: string;
|
|
141
|
+
/**
|
|
142
|
+
* Defines the action to be taken on the existing relationship
|
|
143
|
+
* @kind ADD -> adds a new relationship
|
|
144
|
+
* @kind UPDATE -> updates an existing relationship
|
|
145
|
+
* @kind DELETE -> deletes an existing relationship
|
|
146
|
+
* @kind undefined -> no operation on the existing relationship
|
|
147
|
+
*/
|
|
148
|
+
action?: 'ADD' | 'UPDATE' | 'DELETE';
|
|
149
|
+
/**
|
|
150
|
+
* Value kept for restoring initial relationshipType value
|
|
151
|
+
*/
|
|
152
|
+
initialrelationshipTypeValue?: string;
|
|
153
|
+
uuid?: string;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface FormValues {
|
|
157
|
+
patientUuid: string;
|
|
158
|
+
givenName: string;
|
|
159
|
+
middleName: string;
|
|
160
|
+
familyName: string;
|
|
161
|
+
additionalGivenName: string;
|
|
162
|
+
additionalMiddleName: string;
|
|
163
|
+
additionalFamilyName: string;
|
|
164
|
+
addNameInLocalLanguage: boolean;
|
|
165
|
+
gender: string;
|
|
166
|
+
birthdate: Date | string;
|
|
167
|
+
yearsEstimated: number;
|
|
168
|
+
monthsEstimated: number;
|
|
169
|
+
birthdateEstimated: boolean;
|
|
170
|
+
telephoneNumber: string;
|
|
171
|
+
isDead: boolean;
|
|
172
|
+
deathDate: string;
|
|
173
|
+
deathCause: string;
|
|
174
|
+
relationships: Array<RelationshipValue>;
|
|
175
|
+
identifiers: {
|
|
176
|
+
[identifierFieldName: string]: PatientIdentifierValue;
|
|
177
|
+
};
|
|
178
|
+
attributes?: {
|
|
179
|
+
[attributeTypeUuid: string]: string;
|
|
180
|
+
};
|
|
181
|
+
obs?: {
|
|
182
|
+
[conceptUuid: string]: string;
|
|
183
|
+
};
|
|
184
|
+
address: {
|
|
185
|
+
[addressField: string]: string;
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export interface PatientUuidMapType {
|
|
190
|
+
additionalNameUuid?: string;
|
|
191
|
+
preferredNameUuid?: string;
|
|
192
|
+
preferredAddressUuid?: string;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export interface CapturePhotoProps {
|
|
196
|
+
imageData: string;
|
|
197
|
+
dateTime: string;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export interface AddressValidationSchemaType {
|
|
201
|
+
name: string;
|
|
202
|
+
label: string;
|
|
203
|
+
regex: RegExp;
|
|
204
|
+
regexFormat: string;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export interface CodedPersonAttributeConfig {
|
|
208
|
+
personAttributeUuid: string;
|
|
209
|
+
conceptUuid: string;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export interface TextBasedPersonAttributeConfig {
|
|
213
|
+
personAttributeUuid: string;
|
|
214
|
+
validationRegex: string;
|
|
215
|
+
}
|
|
216
|
+
export interface PatientIdentifierResponse {
|
|
217
|
+
uuid: string;
|
|
218
|
+
identifier: string;
|
|
219
|
+
preferred: boolean;
|
|
220
|
+
identifierType: {
|
|
221
|
+
uuid: string;
|
|
222
|
+
required: boolean;
|
|
223
|
+
name: string;
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
export interface PersonAttributeTypeResponse {
|
|
227
|
+
uuid: string;
|
|
228
|
+
display: string;
|
|
229
|
+
name: string;
|
|
230
|
+
description: string;
|
|
231
|
+
format: string;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export interface PersonAttributeResponse {
|
|
235
|
+
display: string;
|
|
236
|
+
uuid: string;
|
|
237
|
+
value:
|
|
238
|
+
| string
|
|
239
|
+
| {
|
|
240
|
+
uuid: string;
|
|
241
|
+
display: string;
|
|
242
|
+
};
|
|
243
|
+
attributeType: {
|
|
244
|
+
display: string;
|
|
245
|
+
uuid: string;
|
|
246
|
+
format: 'org.openmrs.Concept' | string;
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export interface ConceptResponse {
|
|
251
|
+
uuid: string;
|
|
252
|
+
display: string;
|
|
253
|
+
datatype: {
|
|
254
|
+
uuid: string;
|
|
255
|
+
display: string;
|
|
256
|
+
};
|
|
257
|
+
answers: Array<ConceptAnswers>;
|
|
258
|
+
setMembers: Array<ConceptAnswers>;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export interface ConceptAnswers {
|
|
262
|
+
display: string;
|
|
263
|
+
uuid: string;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export type AddressProperties =
|
|
267
|
+
| 'cityVillage'
|
|
268
|
+
| 'stateProvince'
|
|
269
|
+
| 'countyDistrict'
|
|
270
|
+
| 'postalCode'
|
|
271
|
+
| 'country'
|
|
272
|
+
| 'address1'
|
|
273
|
+
| 'address2'
|
|
274
|
+
| 'address3'
|
|
275
|
+
| 'address4'
|
|
276
|
+
| 'address5'
|
|
277
|
+
| 'address6'
|
|
278
|
+
| 'address7'
|
|
279
|
+
| 'address8'
|
|
280
|
+
| 'address9'
|
|
281
|
+
| 'address10'
|
|
282
|
+
| 'address11'
|
|
283
|
+
| 'address12'
|
|
284
|
+
| 'address13'
|
|
285
|
+
| 'address14'
|
|
286
|
+
| 'address15';
|
|
287
|
+
|
|
288
|
+
export type ExtensibleAddressProperties = { [p in AddressProperties]?: string } | null;
|
|
289
|
+
|
|
290
|
+
export interface AddressTemplate {
|
|
291
|
+
displayName: string | null;
|
|
292
|
+
codeName: string | null;
|
|
293
|
+
country: string | null;
|
|
294
|
+
lines: Array<
|
|
295
|
+
Array<{
|
|
296
|
+
isToken: 'IS_NOT_ADDR_TOKEN' | 'IS_ADDR_TOKEN';
|
|
297
|
+
displayText: string;
|
|
298
|
+
codeName?: AddressProperties;
|
|
299
|
+
displaySize?: string;
|
|
300
|
+
}>
|
|
301
|
+
> | null;
|
|
302
|
+
lineByLineFormat: Array<string> | null;
|
|
303
|
+
nameMappings: ExtensibleAddressProperties;
|
|
304
|
+
sizeMappings: ExtensibleAddressProperties;
|
|
305
|
+
elementDefaults: ExtensibleAddressProperties;
|
|
306
|
+
elementRegex: ExtensibleAddressProperties;
|
|
307
|
+
elementRegexFormats: ExtensibleAddressProperties;
|
|
308
|
+
requiredElements: Array<AddressProperties> | null;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// https://rest.openmrs.org/#address-template
|
|
312
|
+
export interface RestAddressTemplate {
|
|
313
|
+
uuid: string;
|
|
314
|
+
description: string;
|
|
315
|
+
property: string;
|
|
316
|
+
display: string;
|
|
317
|
+
value: string;
|
|
318
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import { Input } from '../../input/basic-input/input/input.component';
|
|
5
|
+
import { SelectInput } from '../../input/basic-input/select/select-input.component';
|
|
6
|
+
import { PatientRegistrationContext } from '../../patient-registration-context';
|
|
7
|
+
import styles from './../section.scss';
|
|
8
|
+
|
|
9
|
+
export const DeathInfoSection = () => {
|
|
10
|
+
const { values } = React.useContext(PatientRegistrationContext);
|
|
11
|
+
const { t } = useTranslation();
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<section className={styles.formSection} aria-label="Death Info Section">
|
|
15
|
+
<h5 className={classNames('omrs-type-title-5', styles.formSectionTitle)}>Death Info</h5>
|
|
16
|
+
<section className={styles.fieldGroup}>
|
|
17
|
+
<Input labelText={t('isDeadInputLabel', 'Is Dead')} name="isDead" id="isDead" />
|
|
18
|
+
{values.isDead && (
|
|
19
|
+
<>
|
|
20
|
+
<Input labelText={t('deathDateInputLabel', 'Date of Death')} name="deathDate" id="deathDate" />
|
|
21
|
+
<SelectInput
|
|
22
|
+
options={[t('unknown', 'Unknown'), t('stroke', 'Stroke')]}
|
|
23
|
+
label={t('causeOfDeathInputLabel', 'Cause of Death')}
|
|
24
|
+
name="deathCause"
|
|
25
|
+
/>
|
|
26
|
+
</>
|
|
27
|
+
)}
|
|
28
|
+
</section>
|
|
29
|
+
</section>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { Formik, Form } from 'formik';
|
|
4
|
+
import { initialFormValues } from '../../patient-registration.component';
|
|
5
|
+
import { DeathInfoSection } from './death-info-section.component';
|
|
6
|
+
import { type FormValues } from '../../patient-registration.types';
|
|
7
|
+
import { PatientRegistrationContext } from '../../patient-registration-context';
|
|
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
|
+
const initialContextValues = {
|
|
19
|
+
currentPhoto: 'data:image/png;base64,1234567890',
|
|
20
|
+
identifierTypes: [],
|
|
21
|
+
inEditMode: false,
|
|
22
|
+
initialFormValues: {} as FormValues,
|
|
23
|
+
isOffline: false,
|
|
24
|
+
setCapturePhotoProps: jest.fn(),
|
|
25
|
+
setFieldValue: jest.fn(),
|
|
26
|
+
setInitialFormValues: jest.fn(),
|
|
27
|
+
validationSchema: null,
|
|
28
|
+
values: {
|
|
29
|
+
isDead: true,
|
|
30
|
+
} as FormValues,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
describe('Death info section', () => {
|
|
34
|
+
const renderDeathInfoSection = (isDead) => {
|
|
35
|
+
initialContextValues.values.isDead = isDead;
|
|
36
|
+
|
|
37
|
+
return render(
|
|
38
|
+
<PatientRegistrationContext.Provider value={initialContextValues}>
|
|
39
|
+
<Formik initialValues={initialFormValues} onSubmit={jest.fn()}>
|
|
40
|
+
<Form>
|
|
41
|
+
<DeathInfoSection />
|
|
42
|
+
</Form>
|
|
43
|
+
</Formik>
|
|
44
|
+
</PatientRegistrationContext.Provider>,
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
it('shows fields for recording death info when the patient is marked as dead', () => {
|
|
49
|
+
renderDeathInfoSection(true);
|
|
50
|
+
|
|
51
|
+
expect(screen.getByRole('region', { name: /death info section/i })).toBeInTheDocument();
|
|
52
|
+
expect(screen.getByRole('heading', { name: /death info/i })).toBeInTheDocument();
|
|
53
|
+
expect(screen.getByRole('textbox', { name: /is dead \(optional\)/i })).toBeInTheDocument();
|
|
54
|
+
expect(screen.getByRole('textbox', { name: /date of death \(optional\)/i })).toBeInTheDocument();
|
|
55
|
+
expect(screen.getByRole('combobox', { name: /cause of death \(optional\)/i })).toBeInTheDocument();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('has the correct number of inputs if is dead is not checked', async () => {
|
|
59
|
+
renderDeathInfoSection(false);
|
|
60
|
+
|
|
61
|
+
expect(screen.queryByRole('textbox', { name: /date of death \(optional\)/i })).not.toBeInTheDocument();
|
|
62
|
+
expect(screen.queryByRole('combobox', { name: /cause of death \(optional\)/i })).not.toBeInTheDocument();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React, { useContext, useEffect } from 'react';
|
|
2
|
+
import styles from './../section.scss';
|
|
3
|
+
import { useField } from 'formik';
|
|
4
|
+
import { PatientRegistrationContext } from '../../patient-registration-context';
|
|
5
|
+
import { Field } from '../../field/field.component';
|
|
6
|
+
|
|
7
|
+
export interface DemographicsSectionProps {
|
|
8
|
+
fields: Array<string>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const DemographicsSection: React.FC<DemographicsSectionProps> = ({ fields }) => {
|
|
12
|
+
const [field, meta] = useField('addNameInLocalLanguage');
|
|
13
|
+
const { setFieldValue } = useContext(PatientRegistrationContext);
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (!field.value && meta.touched) {
|
|
17
|
+
setFieldValue('additionalGivenName', '');
|
|
18
|
+
setFieldValue('additionalMiddleName', '');
|
|
19
|
+
setFieldValue('additionalFamilyName', '');
|
|
20
|
+
}
|
|
21
|
+
}, [field.value, meta.touched]);
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<section className={styles.formSection} aria-label="Demographics Section">
|
|
25
|
+
{fields.map((field) => (
|
|
26
|
+
<Field key={`demographics-${field}`} name={field} />
|
|
27
|
+
))}
|
|
28
|
+
</section>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { Formik, Form } from 'formik';
|
|
4
|
+
import { initialFormValues } from '../../patient-registration.component';
|
|
5
|
+
import { DemographicsSection } from './demographics-section.component';
|
|
6
|
+
import { PatientRegistrationContext } from '../../patient-registration-context';
|
|
7
|
+
import { type FormValues } from '../../patient-registration.types';
|
|
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
|
+
useConfig: jest.fn().mockImplementation(() => ({
|
|
16
|
+
fieldConfigurations: { dateOfBirth: { useEstimatedDateOfBirth: { enabled: true, dayOfMonth: 0, month: 0 } } },
|
|
17
|
+
})),
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
jest.mock('../../field/name/name-field.component', () => {
|
|
22
|
+
return {
|
|
23
|
+
NameField: () => (
|
|
24
|
+
<div>
|
|
25
|
+
<input type="text" name="name" />
|
|
26
|
+
</div>
|
|
27
|
+
),
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
jest.mock('../../field/gender/gender-field.component', () => {
|
|
32
|
+
return {
|
|
33
|
+
GenderField: () => (
|
|
34
|
+
<div>
|
|
35
|
+
<input type="text" name="name" />
|
|
36
|
+
</div>
|
|
37
|
+
),
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
jest.mock('../../field/id/id-field.component', () => {
|
|
42
|
+
return {
|
|
43
|
+
IdField: () => (
|
|
44
|
+
<div>
|
|
45
|
+
<input type="text" name="name" />
|
|
46
|
+
</div>
|
|
47
|
+
),
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('demographics section', () => {
|
|
52
|
+
const formValues: FormValues = initialFormValues;
|
|
53
|
+
|
|
54
|
+
const setupSection = async (birthdateEstimated?: boolean, addNameInLocalLanguage?: boolean) => {
|
|
55
|
+
render(
|
|
56
|
+
<Formik initialValues={{ ...initialFormValues, birthdateEstimated, addNameInLocalLanguage }} onSubmit={null}>
|
|
57
|
+
<Form>
|
|
58
|
+
<PatientRegistrationContext.Provider
|
|
59
|
+
value={{
|
|
60
|
+
initialFormValues: null,
|
|
61
|
+
identifierTypes: [],
|
|
62
|
+
validationSchema: {},
|
|
63
|
+
values: { ...initialFormValues, birthdateEstimated, addNameInLocalLanguage },
|
|
64
|
+
inEditMode: false,
|
|
65
|
+
setFieldValue: () => {},
|
|
66
|
+
currentPhoto: 'TEST',
|
|
67
|
+
isOffline: true,
|
|
68
|
+
setCapturePhotoProps: (value) => {},
|
|
69
|
+
}}>
|
|
70
|
+
<DemographicsSection fields={['name', 'gender', 'dob']} id="demographics" />
|
|
71
|
+
</PatientRegistrationContext.Provider>
|
|
72
|
+
</Form>
|
|
73
|
+
</Formik>,
|
|
74
|
+
);
|
|
75
|
+
const allInputs = screen.getAllByRole('textbox') as Array<HTMLInputElement>;
|
|
76
|
+
return allInputs.map((input) => input.name);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
it('inputs corresponding to number of fields', async () => {
|
|
80
|
+
const inputNames = await setupSection();
|
|
81
|
+
expect(inputNames.length).toBe(3);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type SectionDefinition } from '../../config-schema';
|
|
3
|
+
import { Field } from '../field/field.component';
|
|
4
|
+
|
|
5
|
+
export interface GenericSectionProps {
|
|
6
|
+
sectionDefinition: SectionDefinition;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const GenericSection = ({ sectionDefinition }: GenericSectionProps) => {
|
|
10
|
+
return (
|
|
11
|
+
<section aria-label={`${sectionDefinition.name} Section`}>
|
|
12
|
+
{sectionDefinition.fields.map((name) => (
|
|
13
|
+
<Field key={`${sectionDefinition.name}-${name}`} name={name} />
|
|
14
|
+
))}
|
|
15
|
+
</section>
|
|
16
|
+
);
|
|
17
|
+
};
|