@ampath/esm-patient-registration-app 6.0.1-pre.98 → 9.2.0-next.14

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.
Files changed (285) hide show
  1. package/dist/1119.js +1 -0
  2. package/dist/1197.js +1 -0
  3. package/dist/1909.js +2 -0
  4. package/dist/{629.js.LICENSE.txt → 1909.js.LICENSE.txt} +9 -3
  5. package/dist/1909.js.map +1 -0
  6. package/dist/2146.js +1 -0
  7. package/dist/2372.js +1 -0
  8. package/dist/2372.js.map +1 -0
  9. package/dist/2470.js +1 -0
  10. package/dist/2470.js.map +1 -0
  11. package/dist/2690.js +1 -0
  12. package/dist/2913.js +2 -0
  13. package/dist/{913.js.LICENSE.txt → 2913.js.LICENSE.txt} +3 -23
  14. package/dist/2913.js.map +1 -0
  15. package/dist/3093.js +1 -0
  16. package/dist/3093.js.map +1 -0
  17. package/dist/3099.js +1 -0
  18. package/dist/3144.js +2 -0
  19. package/dist/3144.js.LICENSE.txt +19 -0
  20. package/dist/3144.js.map +1 -0
  21. package/dist/320.js +2 -0
  22. package/dist/{876.js.LICENSE.txt → 320.js.LICENSE.txt} +2 -3
  23. package/dist/320.js.map +1 -0
  24. package/dist/3464.js +1 -0
  25. package/dist/3464.js.map +1 -0
  26. package/dist/3474.js +2 -0
  27. package/dist/3474.js.LICENSE.txt +8 -0
  28. package/dist/3474.js.map +1 -0
  29. package/dist/3584.js +1 -0
  30. package/dist/4041.js +2 -0
  31. package/dist/4041.js.map +1 -0
  32. package/dist/4055.js +1 -0
  33. package/dist/4132.js +1 -0
  34. package/dist/4300.js +1 -0
  35. package/dist/4335.js +1 -0
  36. package/dist/4463.js +1 -0
  37. package/dist/4463.js.map +1 -0
  38. package/dist/4618.js +1 -0
  39. package/dist/4652.js +1 -0
  40. package/dist/4944.js +1 -0
  41. package/dist/5173.js +1 -0
  42. package/dist/5239.js +2 -0
  43. package/dist/5239.js.LICENSE.txt +29 -0
  44. package/dist/5239.js.map +1 -0
  45. package/dist/5241.js +1 -0
  46. package/dist/5442.js +1 -0
  47. package/dist/5661.js +1 -0
  48. package/dist/6022.js +1 -0
  49. package/dist/627.js +1 -0
  50. package/dist/627.js.map +1 -0
  51. package/dist/6276.js +1 -0
  52. package/dist/6276.js.map +1 -0
  53. package/dist/6336.js +1 -0
  54. package/dist/6336.js.map +1 -0
  55. package/dist/6468.js +1 -0
  56. package/dist/6679.js +1 -0
  57. package/dist/6840.js +1 -0
  58. package/dist/6859.js +1 -0
  59. package/dist/7071.js +1 -0
  60. package/dist/7071.js.map +1 -0
  61. package/dist/7097.js +1 -0
  62. package/dist/7159.js +1 -0
  63. package/dist/723.js +1 -0
  64. package/dist/729.js +2 -0
  65. package/dist/729.js.LICENSE.txt +9 -0
  66. package/dist/729.js.map +1 -0
  67. package/dist/7495.js +2 -0
  68. package/dist/7495.js.LICENSE.txt +9 -0
  69. package/dist/7495.js.map +1 -0
  70. package/dist/7617.js +1 -0
  71. package/dist/795.js +1 -0
  72. package/dist/8163.js +1 -0
  73. package/dist/8349.js +1 -0
  74. package/dist/8434.js +1 -0
  75. package/dist/8434.js.map +1 -0
  76. package/dist/8618.js +1 -0
  77. package/dist/89.js +2 -0
  78. package/dist/89.js.LICENSE.txt +9 -0
  79. package/dist/89.js.map +1 -0
  80. package/dist/890.js +1 -0
  81. package/dist/9214.js +1 -0
  82. package/dist/9538.js +1 -0
  83. package/dist/9569.js +1 -0
  84. package/dist/986.js +1 -0
  85. package/dist/9876.js +1 -0
  86. package/dist/9876.js.map +1 -0
  87. package/dist/9879.js +1 -0
  88. package/dist/9895.js +1 -0
  89. package/dist/9900.js +1 -0
  90. package/dist/9913.js +1 -0
  91. package/dist/main.js +1 -1
  92. package/dist/main.js.LICENSE.txt +36 -1
  93. package/dist/main.js.map +1 -1
  94. package/dist/openmrs-esm-patient-registration-app.js +1 -0
  95. package/dist/openmrs-esm-patient-registration-app.js.buildmanifest.json +1549 -0
  96. package/dist/openmrs-esm-patient-registration-app.js.map +1 -0
  97. package/dist/routes.json +1 -1
  98. package/package.json +15 -13
  99. package/src/{add-patient-link.tsx → add-patient-link.extension.tsx} +4 -2
  100. package/src/add-patient-link.test.tsx +6 -10
  101. package/src/config-schema.ts +109 -55
  102. package/src/constants.ts +1 -1
  103. package/src/declarations.d.ts +5 -4
  104. package/src/index.ts +10 -29
  105. package/src/nav-link.test.tsx +3 -3
  106. package/src/offline.resources.ts +26 -18
  107. package/src/patient-photo.extension.tsx +3 -1
  108. package/src/patient-registration/field/address/address-field.component.tsx +58 -37
  109. package/src/patient-registration/field/address/address-hierarchy-levels.component.tsx +16 -18
  110. package/src/patient-registration/field/address/address-hierarchy.resource.tsx +3 -3
  111. package/src/patient-registration/field/address/address-hierarchy.test.tsx +290 -0
  112. package/src/patient-registration/field/address/address-search.component.tsx +7 -5
  113. package/src/patient-registration/field/address/address-search.scss +5 -5
  114. package/src/patient-registration/field/address/address-search.test.tsx +140 -0
  115. package/src/patient-registration/field/cause-of-death/cause-of-death.component.tsx +98 -0
  116. package/src/patient-registration/field/custom-field.component.tsx +3 -9
  117. package/src/patient-registration/field/date-and-time-of-death/date-and-time-of-death.component.tsx +84 -0
  118. package/src/patient-registration/field/dob/dob.component.tsx +55 -50
  119. package/src/patient-registration/field/dob/dob.test.tsx +90 -0
  120. package/src/patient-registration/field/field.component.tsx +12 -6
  121. package/src/patient-registration/field/field.resource.ts +11 -4
  122. package/src/patient-registration/field/field.scss +69 -25
  123. package/src/patient-registration/field/field.test.tsx +329 -0
  124. package/src/patient-registration/field/gender/gender-field.component.tsx +14 -9
  125. package/src/patient-registration/field/gender/gender-field.test.tsx +73 -33
  126. package/src/patient-registration/field/id/id-field.component.tsx +24 -23
  127. package/src/patient-registration/field/id/id-field.test.tsx +147 -0
  128. package/src/patient-registration/field/id/identifier-selection-overlay.component.tsx +12 -10
  129. package/src/patient-registration/field/id/identifier-selection.scss +12 -8
  130. package/src/patient-registration/field/name/name-field.component.tsx +10 -5
  131. package/src/patient-registration/field/obs/obs-field.component.tsx +59 -2
  132. package/src/patient-registration/field/obs/obs-field.test.tsx +133 -39
  133. package/src/patient-registration/field/person-attributes/coded-person-attribute-field.component.tsx +3 -3
  134. package/src/patient-registration/field/person-attributes/coded-person-attribute-field.test.tsx +141 -0
  135. package/src/patient-registration/field/person-attributes/location-person-attribute-field.component.tsx +105 -0
  136. package/src/patient-registration/field/person-attributes/location-person-attribute-field.resource.tsx +48 -0
  137. package/src/patient-registration/field/person-attributes/person-attribute-field.component.tsx +19 -22
  138. package/src/patient-registration/field/person-attributes/person-attribute-field.test.tsx +193 -0
  139. package/src/patient-registration/field/person-attributes/text-person-attribute-field.test.tsx +90 -0
  140. package/src/patient-registration/form-manager.test.ts +91 -0
  141. package/src/patient-registration/form-manager.ts +49 -23
  142. package/src/patient-registration/input/basic-input/input/input.component.tsx +6 -2
  143. package/src/patient-registration/input/basic-input/select/select-input.test.tsx +49 -0
  144. package/src/patient-registration/input/custom-input/autosuggest/autosuggest.scss +5 -5
  145. package/src/patient-registration/input/custom-input/autosuggest/autosuggest.test.tsx +164 -0
  146. package/src/patient-registration/input/custom-input/identifier/identifier-input.component.tsx +73 -36
  147. package/src/patient-registration/input/custom-input/identifier/identifier-input.test.tsx +335 -0
  148. package/src/patient-registration/input/dummy-data/dummy-data-input.component.tsx +3 -0
  149. package/src/patient-registration/input/dummy-data/dummy-data-input.test.tsx +2 -11
  150. package/src/patient-registration/input/input.scss +17 -13
  151. package/src/patient-registration/patient-registration-context.ts +22 -11
  152. package/src/patient-registration/patient-registration-hooks.ts +158 -193
  153. package/src/patient-registration/patient-registration-utils.test.ts +33 -0
  154. package/src/patient-registration/patient-registration-utils.ts +11 -13
  155. package/src/patient-registration/patient-registration.component.tsx +87 -103
  156. package/src/patient-registration/{patient-registration.resource.testt.tsx → patient-registration.resource.test.tsx} +0 -4
  157. package/src/patient-registration/patient-registration.resource.ts +27 -3
  158. package/src/patient-registration/patient-registration.scss +27 -38
  159. package/src/patient-registration/patient-registration.test.tsx +579 -0
  160. package/src/patient-registration/patient-registration.types.ts +23 -25
  161. package/src/patient-registration/section/death-info/death-info-section.component.tsx +22 -17
  162. package/src/patient-registration/section/death-info/death-info-section.test.tsx +47 -0
  163. package/src/patient-registration/section/demographics/demographics-section.component.tsx +5 -5
  164. package/src/patient-registration/section/demographics/demographics-section.test.tsx +98 -0
  165. package/src/patient-registration/section/patient-relationships/relationships-section.component.tsx +8 -7
  166. package/src/patient-registration/section/patient-relationships/relationships-section.test.tsx +113 -0
  167. package/src/patient-registration/section/patient-relationships/relationships.resource.tsx +28 -28
  168. package/src/patient-registration/section/patient-relationships/relationships.scss +4 -4
  169. package/src/patient-registration/section/section-wrapper.component.tsx +1 -1
  170. package/src/patient-registration/section/section.component.tsx +1 -1
  171. package/src/patient-registration/section/section.scss +21 -1
  172. package/src/patient-registration/ui-components/overlay/overlay.scss +8 -8
  173. package/src/patient-registration/validation/{patient-registration-validation.test.tsx → patient-registration-validation.test.ts} +71 -23
  174. package/src/patient-registration/validation/patient-registration-validation.ts +123 -0
  175. package/src/resources-context.ts +14 -0
  176. package/src/root.component.tsx +3 -3
  177. package/src/routes.json +10 -24
  178. package/src/widgets/cancel-patient-edit.modal.tsx +33 -0
  179. package/src/widgets/cancel-patient-edit.test.tsx +22 -0
  180. package/src/widgets/delete-identifier-confirmation.modal.tsx +48 -0
  181. package/src/widgets/{delete-identifier-confirmation-modal.testt.tsx → delete-identifier-confirmation.test.tsx} +5 -7
  182. package/src/widgets/edit-patient-details-button.component.tsx +0 -1
  183. package/src/widgets/edit-patient-details-button.test.tsx +35 -0
  184. package/translations/am.json +43 -35
  185. package/translations/ar.json +41 -33
  186. package/translations/ar_SY.json +119 -0
  187. package/translations/bn.json +119 -0
  188. package/translations/de.json +119 -0
  189. package/translations/en.json +44 -42
  190. package/translations/en_US.json +119 -0
  191. package/translations/es.json +69 -57
  192. package/translations/es_MX.json +119 -0
  193. package/translations/fr.json +74 -58
  194. package/translations/he.json +44 -40
  195. package/translations/hi.json +119 -0
  196. package/translations/hi_IN.json +119 -0
  197. package/translations/id.json +119 -0
  198. package/translations/it.json +119 -0
  199. package/translations/ka.json +119 -0
  200. package/translations/km.json +44 -40
  201. package/translations/ku.json +119 -0
  202. package/translations/ky.json +119 -0
  203. package/translations/lg.json +119 -0
  204. package/translations/ne.json +119 -0
  205. package/translations/pl.json +119 -0
  206. package/translations/pt.json +119 -0
  207. package/translations/pt_BR.json +119 -0
  208. package/translations/qu.json +119 -0
  209. package/translations/ro_RO.json +119 -0
  210. package/translations/ru_RU.json +119 -0
  211. package/translations/si.json +119 -0
  212. package/translations/sw.json +119 -0
  213. package/translations/sw_KE.json +119 -0
  214. package/translations/tr.json +119 -0
  215. package/translations/tr_TR.json +119 -0
  216. package/translations/uk.json +119 -0
  217. package/translations/uz.json +119 -0
  218. package/translations/uz@Latn.json +119 -0
  219. package/translations/uz_UZ.json +119 -0
  220. package/translations/vi.json +119 -0
  221. package/translations/zh.json +45 -23
  222. package/translations/zh_CN.json +39 -17
  223. package/.turbo/turbo-build.log +0 -40
  224. package/dist/132.js +0 -1
  225. package/dist/197.js +0 -1
  226. package/dist/236.js +0 -1
  227. package/dist/236.js.map +0 -1
  228. package/dist/300.js +0 -1
  229. package/dist/335.js +0 -1
  230. package/dist/372.js +0 -1
  231. package/dist/372.js.map +0 -1
  232. package/dist/41.js +0 -2
  233. package/dist/41.js.map +0 -1
  234. package/dist/449.js +0 -1
  235. package/dist/449.js.map +0 -1
  236. package/dist/464.js +0 -1
  237. package/dist/464.js.map +0 -1
  238. package/dist/495.js +0 -1
  239. package/dist/495.js.map +0 -1
  240. package/dist/55.js +0 -1
  241. package/dist/56.js +0 -1
  242. package/dist/56.js.map +0 -1
  243. package/dist/621.js +0 -1
  244. package/dist/621.js.map +0 -1
  245. package/dist/629.js +0 -2
  246. package/dist/629.js.map +0 -1
  247. package/dist/652.js +0 -1
  248. package/dist/661.js +0 -1
  249. package/dist/757.js +0 -1
  250. package/dist/757.js.map +0 -1
  251. package/dist/828.js +0 -1
  252. package/dist/828.js.map +0 -1
  253. package/dist/830.js +0 -1
  254. package/dist/830.js.map +0 -1
  255. package/dist/831.js +0 -2
  256. package/dist/831.js.LICENSE.txt +0 -3
  257. package/dist/831.js.map +0 -1
  258. package/dist/876.js +0 -2
  259. package/dist/876.js.map +0 -1
  260. package/dist/879.js +0 -1
  261. package/dist/913.js +0 -2
  262. package/dist/913.js.map +0 -1
  263. package/dist/927.js +0 -1
  264. package/dist/927.js.map +0 -1
  265. package/dist/99.js +0 -1
  266. package/dist/ampath-esm-patient-registration-app.js +0 -1
  267. package/dist/ampath-esm-patient-registration-app.js.buildmanifest.json +0 -694
  268. package/dist/ampath-esm-patient-registration-app.js.map +0 -1
  269. package/src/patient-registration/date-util.ts +0 -52
  270. package/src/patient-registration/field/person-attributes/custom-person-attribute-field.component.tsx +0 -56
  271. package/src/patient-registration/validation/patient-registration-validation.tsx +0 -60
  272. package/src/patient-verification/assets/counties.json +0 -236
  273. package/src/patient-verification/assets/verification-assets.ts +0 -11
  274. package/src/patient-verification/patient-verification-hook.tsx +0 -176
  275. package/src/patient-verification/patient-verification-utils.ts +0 -179
  276. package/src/patient-verification/patient-verification.component.tsx +0 -124
  277. package/src/patient-verification/patient-verification.scss +0 -25
  278. package/src/patient-verification/verification-modal/confirm-prompt.component.tsx +0 -72
  279. package/src/patient-verification/verification-modal/empty-prompt.component.tsx +0 -35
  280. package/src/patient-verification/verification-types.ts +0 -50
  281. package/src/widgets/cancel-patient-edit.component.tsx +0 -37
  282. package/src/widgets/delete-identifier-confirmation-modal.tsx +0 -41
  283. package/src/widgets/delete-identifier-modal.scss +0 -34
  284. /package/dist/{41.js.LICENSE.txt → 4041.js.LICENSE.txt} +0 -0
  285. /package/src/patient-registration/input/custom-input/identifier/{utils.testt.ts → utils.test.ts} +0 -0
@@ -1,30 +1,35 @@
1
1
  import React from 'react';
2
- import classNames from 'classnames';
3
2
  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';
3
+ import { Checkbox, Layer } from '@carbon/react';
4
+ import { useField } from 'formik';
5
+ import { usePatientRegistrationContext } from '../../patient-registration-context';
6
+ import { Field } from '../../field/field.component';
7
7
  import styles from './../section.scss';
8
8
 
9
- export const DeathInfoSection = () => {
10
- const { values } = React.useContext(PatientRegistrationContext);
9
+ export interface DeathInfoSectionProps {
10
+ fields: Array<string>;
11
+ }
12
+
13
+ export const DeathInfoSection: React.FC<DeathInfoSectionProps> = ({ fields }) => {
11
14
  const { t } = useTranslation();
15
+ const { values, setFieldValue } = usePatientRegistrationContext();
16
+ const [deathDate, deathDateMeta] = useField('deathDate');
17
+ const today = new Date();
12
18
 
13
19
  return (
14
20
  <section className={styles.formSection} aria-label="Death Info Section">
15
- <h5 className={classNames('omrs-type-title-5', styles.formSectionTitle)}>Death Info</h5>
16
21
  <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"
22
+ <Layer>
23
+ <div className={styles.isDeadFieldContainer}>
24
+ <Checkbox
25
+ checked={values.isDead}
26
+ id="isDead"
27
+ labelText={t('isDeadInputLabel', 'Is dead')}
28
+ onChange={(event, { checked, id }) => setFieldValue(id, checked)}
25
29
  />
26
- </>
27
- )}
30
+ </div>
31
+ </Layer>
32
+ {values.isDead ? fields.map((field) => <Field key={`death-info-${field}`} name={field} />) : null}
28
33
  </section>
29
34
  </section>
30
35
  );
@@ -0,0 +1,47 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { Form, Formik } from 'formik';
4
+ import { type FormValues } from '../../patient-registration.types';
5
+ import { renderWithContext } from 'tools';
6
+ import { initialFormValues } from '../../patient-registration.component';
7
+ import { PatientRegistrationContextProvider } from '../../patient-registration-context';
8
+ import { DeathInfoSection } from './death-info-section.component';
9
+
10
+ const initialContextValues = {
11
+ currentPhoto: 'data:image/png;base64,1234567890',
12
+ identifierTypes: [],
13
+ inEditMode: false,
14
+ initialFormValues: {} as FormValues,
15
+ isOffline: false,
16
+ setCapturePhotoProps: jest.fn(),
17
+ setFieldValue: jest.fn(),
18
+ setFieldTouched: jest.fn(),
19
+ setInitialFormValues: jest.fn(),
20
+ validationSchema: null,
21
+ values: {
22
+ isDead: true,
23
+ } as FormValues,
24
+ };
25
+
26
+ describe('Death info section', () => {
27
+ const renderDeathInfoSection = (isDead) => {
28
+ initialContextValues.values.isDead = isDead;
29
+
30
+ renderWithContext(
31
+ <Formik initialValues={initialFormValues} onSubmit={jest.fn()}>
32
+ <Form>
33
+ <DeathInfoSection fields={[]} />
34
+ </Form>
35
+ </Formik>,
36
+ PatientRegistrationContextProvider,
37
+ initialContextValues,
38
+ );
39
+ };
40
+
41
+ it('shows fields for recording death info when the patient is marked as dead', () => {
42
+ renderDeathInfoSection(true);
43
+
44
+ expect(screen.getByRole('region', { name: /death info section/i })).toBeInTheDocument();
45
+ expect(screen.getByRole('checkbox', { name: /is dead/i })).toBeInTheDocument();
46
+ });
47
+ });
@@ -1,8 +1,8 @@
1
- import React, { useContext, useEffect } from 'react';
2
- import styles from './../section.scss';
1
+ import React, { useEffect } from 'react';
3
2
  import { useField } from 'formik';
4
- import { PatientRegistrationContext } from '../../patient-registration-context';
5
3
  import { Field } from '../../field/field.component';
4
+ import { usePatientRegistrationContext } from '../../patient-registration-context';
5
+ import styles from './../section.scss';
6
6
 
7
7
  export interface DemographicsSectionProps {
8
8
  fields: Array<string>;
@@ -10,7 +10,7 @@ export interface DemographicsSectionProps {
10
10
 
11
11
  export const DemographicsSection: React.FC<DemographicsSectionProps> = ({ fields }) => {
12
12
  const [field, meta] = useField('addNameInLocalLanguage');
13
- const { setFieldValue } = useContext(PatientRegistrationContext);
13
+ const { setFieldValue } = usePatientRegistrationContext();
14
14
 
15
15
  useEffect(() => {
16
16
  if (!field.value && meta.touched) {
@@ -18,7 +18,7 @@ export const DemographicsSection: React.FC<DemographicsSectionProps> = ({ fields
18
18
  setFieldValue('additionalMiddleName', '');
19
19
  setFieldValue('additionalFamilyName', '');
20
20
  }
21
- }, [field.value, meta.touched]);
21
+ }, [field.value, meta.touched, setFieldValue]);
22
22
 
23
23
  return (
24
24
  <section className={styles.formSection} aria-label="Demographics Section">
@@ -0,0 +1,98 @@
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 { getDefaultsFromConfigSchema, useConfig } from '@openmrs/esm-framework';
6
+ import { DemographicsSection } from './demographics-section.component';
7
+ import { PatientRegistrationContext } from '../../patient-registration-context';
8
+ import { type RegistrationConfig, esmPatientRegistrationSchema } from '../../../config-schema';
9
+
10
+ const mockUseConfig = jest.mocked(useConfig<RegistrationConfig>);
11
+
12
+ jest.mock('../../field/name/name-field.component', () => {
13
+ return {
14
+ NameField: () => (
15
+ <div>
16
+ <input type="text" name="name" />
17
+ </div>
18
+ ),
19
+ };
20
+ });
21
+
22
+ jest.mock('../../field/gender/gender-field.component', () => {
23
+ return {
24
+ GenderField: () => (
25
+ <div>
26
+ <input type="text" name="name" />
27
+ </div>
28
+ ),
29
+ };
30
+ });
31
+
32
+ jest.mock('../../field/id/id-field.component', () => {
33
+ return {
34
+ IdField: () => (
35
+ <div>
36
+ <input type="text" name="name" />
37
+ </div>
38
+ ),
39
+ };
40
+ });
41
+
42
+ describe('Demographics section', () => {
43
+ beforeEach(() => {
44
+ mockUseConfig.mockReturnValue({
45
+ ...getDefaultsFromConfigSchema(esmPatientRegistrationSchema),
46
+ fieldConfigurations: {
47
+ dateOfBirth: {
48
+ allowEstimatedDateOfBirth: true,
49
+ useEstimatedDateOfBirth: { enabled: true, dayOfMonth: 0, month: 0 },
50
+ },
51
+ } as RegistrationConfig['fieldConfigurations'],
52
+ });
53
+ });
54
+
55
+ const setupSection = async (birthdateEstimated?: boolean, addNameInLocalLanguage?: boolean) => {
56
+ render(
57
+ <Formik initialValues={{ ...initialFormValues, birthdateEstimated, addNameInLocalLanguage }} onSubmit={null}>
58
+ <Form>
59
+ <PatientRegistrationContext.Provider
60
+ value={{
61
+ initialFormValues: null,
62
+ identifierTypes: [],
63
+ validationSchema: {},
64
+ values: { ...initialFormValues, birthdateEstimated, addNameInLocalLanguage },
65
+ inEditMode: false,
66
+ setFieldValue: () => {},
67
+ currentPhoto: 'TEST',
68
+ isOffline: true,
69
+ setCapturePhotoProps: (value) => {},
70
+ setFieldTouched: () => {},
71
+ }}>
72
+ <DemographicsSection fields={['name', 'gender', 'dob']} />
73
+ </PatientRegistrationContext.Provider>
74
+ </Form>
75
+ </Formik>,
76
+ );
77
+ const allInputs = screen.getAllByRole('textbox') as Array<HTMLInputElement>;
78
+ return allInputs.map((input) => input.name);
79
+ };
80
+
81
+ it('renders demographics fields and date of birth inputs', async () => {
82
+ const inputNames = await setupSection();
83
+ expect(inputNames.length).toBe(3);
84
+
85
+ expect(screen.getByText(/date of birth known\?/i)).toBeInTheDocument();
86
+ expect(
87
+ screen.getByRole('tab', {
88
+ name: /yes/i,
89
+ }),
90
+ ).toBeInTheDocument();
91
+ expect(
92
+ screen.getByRole('tab', {
93
+ name: /no/i,
94
+ }),
95
+ ).toBeInTheDocument();
96
+ expect(screen.getByLabelText(/date of birth/i)).toBeInTheDocument();
97
+ });
98
+ });
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useContext, useEffect, useState } from 'react';
1
+ import React, { useCallback, useEffect, useId, useState } from 'react';
2
2
  import {
3
3
  Button,
4
4
  Layer,
@@ -12,9 +12,9 @@ import { TrashCan } from '@carbon/react/icons';
12
12
  import { FieldArray } from 'formik';
13
13
  import { useTranslation } from 'react-i18next';
14
14
  import { Autosuggest } from '../../input/custom-input/autosuggest/autosuggest.component';
15
- import { PatientRegistrationContext } from '../../patient-registration-context';
16
- import { ResourcesContext } from '../../../offline.resources';
15
+ import { usePatientRegistrationContext } from '../../patient-registration-context';
17
16
  import { fetchPerson } from '../../patient-registration.resource';
17
+ import { useResourcesContext } from '../../../resources-context';
18
18
  import { type RelationshipValue } from '../../patient-registration.types';
19
19
  import sectionStyles from '../section.scss';
20
20
  import styles from './relationships.scss';
@@ -39,9 +39,10 @@ const RelationshipView: React.FC<RelationshipViewProps> = ({
39
39
  remove,
40
40
  }) => {
41
41
  const { t } = useTranslation();
42
- const { setFieldValue } = React.useContext(PatientRegistrationContext);
43
- const [isInvalid, setIsInvalid] = useState<boolean>(false);
42
+ const { setFieldValue } = usePatientRegistrationContext();
43
+ const [isInvalid, setIsInvalid] = useState(false);
44
44
  const newRelationship = !relationship.uuid;
45
+ const selectId = useId();
45
46
 
46
47
  const handleRelationshipTypeChange = useCallback(
47
48
  (event) => {
@@ -123,7 +124,7 @@ const RelationshipView: React.FC<RelationshipViewProps> = ({
123
124
  <div className={styles.selectRelationshipType} style={{ marginBottom: '1rem' }}>
124
125
  <Layer>
125
126
  <Select
126
- id="select"
127
+ id={selectId}
127
128
  labelText={t('relationship', 'Relationship')}
128
129
  onChange={handleRelationshipTypeChange}
129
130
  name={`relationships[${index}].relationshipType`}
@@ -159,7 +160,7 @@ const RelationshipView: React.FC<RelationshipViewProps> = ({
159
160
  };
160
161
 
161
162
  export const RelationshipsSection = () => {
162
- const { relationshipTypes } = useContext(ResourcesContext);
163
+ const { relationshipTypes } = useResourcesContext();
163
164
  const [displayRelationshipTypes, setDisplayRelationshipTypes] = useState<RelationshipType[]>([]);
164
165
  const { t } = useTranslation();
165
166
 
@@ -0,0 +1,113 @@
1
+ import React from 'react';
2
+ import { Form, Formik } from 'formik';
3
+ import { screen } from '@testing-library/react';
4
+ import { type Resources } from '../../../offline.resources';
5
+ import { type FormValues } from '../../patient-registration.types';
6
+ import { PatientRegistrationContextProvider } from '../../patient-registration-context';
7
+ import { RelationshipsSection } from './relationships-section.component';
8
+ import { ResourcesContextProvider } from '../../../resources-context';
9
+ import { renderWithContext } from 'tools';
10
+
11
+ jest.mock('../../patient-registration.resource', () => ({
12
+ fetchPerson: jest.fn().mockResolvedValue({
13
+ data: {
14
+ results: [
15
+ { uuid: '42ae5ce0-d64b-11ea-9064-5adc43bbdd24', display: 'Person 1' },
16
+ { uuid: '691eed12-c0f1-11e2-94be-8c13b969e334', display: 'Person 2' },
17
+ ],
18
+ },
19
+ }),
20
+ }));
21
+
22
+ let mockResourcesContextValue = {
23
+ addressTemplate: null,
24
+ currentSession: {
25
+ authenticated: true,
26
+ sessionId: 'JSESSION',
27
+ currentProvider: { uuid: '45ce6c2e-dd5a-11e6-9d9c-0242ac150002', identifier: 'PRO-123' },
28
+ },
29
+ identifierTypes: [],
30
+ relationshipTypes: null,
31
+ } as Resources;
32
+
33
+ const initialContextValues = {
34
+ currentPhoto: 'data:image/png;base64,1234567890',
35
+ identifierTypes: [],
36
+ inEditMode: false,
37
+ initialFormValues: {} as FormValues,
38
+ isOffline: false,
39
+ setCapturePhotoProps: jest.fn(),
40
+ setFieldValue: jest.fn(),
41
+ setFieldTouched: jest.fn(),
42
+ setInitialFormValues: jest.fn(),
43
+ validationSchema: null,
44
+ values: {} as FormValues,
45
+ };
46
+
47
+ describe('RelationshipsSection', () => {
48
+ it('renders a loader when relationshipTypes are not available', () => {
49
+ renderWithContext(
50
+ <Formik initialValues={{}} onSubmit={null}>
51
+ <Form>
52
+ <RelationshipsSection />
53
+ </Form>
54
+ </Formik>,
55
+ ResourcesContextProvider,
56
+ mockResourcesContextValue,
57
+ );
58
+
59
+ expect(screen.getByLabelText(/loading relationships section/i)).toBeInTheDocument();
60
+ expect(screen.getByRole('progressbar')).toBeInTheDocument();
61
+ expect(screen.queryByText(/add relationship/i)).not.toBeInTheDocument();
62
+ });
63
+
64
+ it('renders relationships when relationshipTypes are available', () => {
65
+ const relationshipTypes = {
66
+ results: [
67
+ {
68
+ displayAIsToB: 'Mother',
69
+ aIsToB: 'Mother',
70
+ bIsToA: 'Child',
71
+ displayBIsToA: 'Child',
72
+ uuid: '42ae5ce0-d64b-11ea-9064-5adc43bbdd34',
73
+ },
74
+ {
75
+ displayAIsToB: 'Father',
76
+ aIsToB: 'Father',
77
+ bIsToA: 'Child',
78
+ displayBIsToA: 'Child',
79
+ uuid: '52ae5ce0-d64b-11ea-9064-5adc43bbdd24',
80
+ },
81
+ ],
82
+ };
83
+ mockResourcesContextValue = {
84
+ ...mockResourcesContextValue,
85
+ relationshipTypes: relationshipTypes,
86
+ };
87
+
88
+ renderWithContext(
89
+ <Formik
90
+ initialValues={{
91
+ relationships: [{ action: 'ADD', relatedPersonUuid: '11524ae7-3ef6-4ab6-aff6-804ffc58704a' }],
92
+ }}
93
+ onSubmit={null}>
94
+ <Form>
95
+ <PatientRegistrationContextProvider value={initialContextValues}>
96
+ <RelationshipsSection />
97
+ </PatientRegistrationContextProvider>
98
+ </Form>
99
+ </Formik>,
100
+ ResourcesContextProvider,
101
+ mockResourcesContextValue,
102
+ );
103
+
104
+ expect(screen.getByLabelText(/relationships section/i)).toBeInTheDocument();
105
+ expect(screen.getByRole('heading', { name: /relationship/i })).toBeInTheDocument();
106
+ expect(screen.getByRole('button', { name: /delete/i })).toBeInTheDocument();
107
+ expect(screen.getByRole('button', { name: /add relationship/i })).toBeInTheDocument();
108
+ expect(screen.getByRole('searchbox', { name: /full name/i })).toBeInTheDocument();
109
+ expect(screen.getByRole('option', { name: /mother/i })).toBeInTheDocument();
110
+ expect(screen.getByRole('option', { name: /father/i })).toBeInTheDocument();
111
+ expect(screen.getAllByRole('option', { name: /child/i }).length).toEqual(2);
112
+ });
113
+ });
@@ -4,6 +4,33 @@ import { type FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-fram
4
4
  import { type RelationshipValue } from '../../patient-registration.types';
5
5
  import { personRelationshipRepresentation } from '../../../constants';
6
6
 
7
+ export interface Relationship {
8
+ display: string;
9
+ uuid: string;
10
+ personA: {
11
+ age: number;
12
+ display: string;
13
+ birthdate: string;
14
+ uuid: string;
15
+ };
16
+ personB: {
17
+ age: number;
18
+ display: string;
19
+ birthdate: string;
20
+ uuid: string;
21
+ };
22
+ relationshipType: {
23
+ uuid: string;
24
+ display: string;
25
+ aIsToB: string;
26
+ bIsToA: string;
27
+ };
28
+ }
29
+
30
+ interface RelationshipsResponse {
31
+ results: Array<Relationship>;
32
+ }
33
+
7
34
  export function useInitialPatientRelationships(patientUuid: string): {
8
35
  data: Array<RelationshipValue>;
9
36
  isLoading: boolean;
@@ -45,34 +72,7 @@ export function useInitialPatientRelationships(patientUuid: string): {
45
72
  error,
46
73
  isLoading,
47
74
  };
48
- }, [patientUuid, data, error]);
75
+ }, [data?.data?.results, error, isLoading, patientUuid]);
49
76
 
50
77
  return result;
51
78
  }
52
-
53
- export interface Relationship {
54
- display: string;
55
- uuid: string;
56
- personA: {
57
- age: number;
58
- display: string;
59
- birthdate: string;
60
- uuid: string;
61
- };
62
- personB: {
63
- age: number;
64
- display: string;
65
- birthdate: string;
66
- uuid: string;
67
- };
68
- relationshipType: {
69
- uuid: string;
70
- display: string;
71
- aIsToB: string;
72
- bIsToA: string;
73
- };
74
- }
75
-
76
- interface RelationshipsResponse {
77
- results: Array<Relationship>;
78
- }
@@ -1,6 +1,6 @@
1
- @use '@carbon/styles/scss/spacing';
2
- @use '@carbon/styles/scss/type';
3
- @import '../../patient-registration.scss';
1
+ @use '@carbon/layout';
2
+ @use '@carbon/type';
3
+ @use '@openmrs/esm-styleguide/src/vars' as *;
4
4
 
5
5
  .labelText {
6
6
  @include type.type-style('label-01');
@@ -11,7 +11,7 @@
11
11
  }
12
12
 
13
13
  .searchBox {
14
- margin-bottom: spacing.$spacing-05;
14
+ margin-bottom: layout.$spacing-05;
15
15
  }
16
16
 
17
17
  .relationshipHeader {
@@ -1,9 +1,9 @@
1
1
  import React from 'react';
2
- import styles from '../patient-registration.scss';
3
2
  import { Tile } from '@carbon/react';
4
3
  import { useTranslation } from 'react-i18next';
5
4
  import { type SectionDefinition } from '../../config-schema';
6
5
  import { Section } from './section.component';
6
+ import styles from './section.scss';
7
7
 
8
8
  export interface SectionWrapperProps {
9
9
  sectionDefinition: SectionDefinition;
@@ -14,7 +14,7 @@ export function Section({ sectionDefinition }: SectionProps) {
14
14
  case 'demographics':
15
15
  return <DemographicsSection fields={sectionDefinition.fields} />;
16
16
  case 'death':
17
- return <DeathInfoSection />;
17
+ return <DeathInfoSection fields={sectionDefinition.fields} />;
18
18
  case 'relationships':
19
19
  return <RelationshipsSection />;
20
20
  default: // includes 'contact'
@@ -1 +1,21 @@
1
- @import '../patient-registration.scss';
1
+ @use '@carbon/colors';
2
+ @use '@carbon/layout';
3
+ @use '@carbon/type';
4
+ @use '@openmrs/esm-styleguide/src/vars' as *;
5
+
6
+ .label01 {
7
+ @include type.type-style('label-01');
8
+ margin-top: layout.$spacing-05;
9
+ margin-bottom: layout.$spacing-05;
10
+ color: $ui-05;
11
+ }
12
+
13
+ .productiveHeading02 {
14
+ @include type.type-style('heading-compact-02');
15
+ color: $ui-04;
16
+ cursor: pointer;
17
+ }
18
+
19
+ .isDeadFieldContainer {
20
+ margin-bottom: layout.$spacing-05;
21
+ }
@@ -1,12 +1,12 @@
1
- @use '@carbon/styles/scss/spacing';
2
- @use '@carbon/styles/scss/type';
3
- @import '../../patient-registration.scss';
1
+ @use '@carbon/layout';
2
+ @use '@carbon/type';
3
+ @use '@openmrs/esm-styleguide/src/vars' as *;
4
4
 
5
5
  .desktopOverlay {
6
6
  position: fixed;
7
- top: spacing.$spacing-09;
7
+ top: layout.$spacing-09;
8
8
  right: 0;
9
- height: calc(100vh - 3rem);
9
+ height: calc(100vh - layout.$spacing-09);
10
10
  min-width: 27rem;
11
11
  background-color: $ui-02;
12
12
  border-left: 1px solid $text-03;
@@ -25,7 +25,7 @@
25
25
  z-index: 9999;
26
26
  background-color: $ui-02;
27
27
  overflow: hidden;
28
- padding-top: spacing.$spacing-09;
28
+ padding-top: layout.$spacing-09;
29
29
  display: grid;
30
30
  grid-template-rows: 1fr auto;
31
31
  }
@@ -49,7 +49,7 @@
49
49
 
50
50
  .headerContent {
51
51
  @include type.type-style('heading-compact-02');
52
- padding: 0 spacing.$spacing-05;
52
+ padding: 0 layout.$spacing-05;
53
53
  color: $ui-05;
54
54
  }
55
55
 
@@ -58,6 +58,6 @@
58
58
  }
59
59
 
60
60
  .overlayContent {
61
- padding: spacing.$spacing-05;
61
+ padding: layout.$spacing-05;
62
62
  overflow-y: auto;
63
63
  }