@openmrs/esm-fast-data-entry-app 1.0.1-pre.99 → 1.1.0

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 (190) hide show
  1. package/__mocks__/react-i18next.js +9 -14
  2. package/dist/12.js +1 -0
  3. package/dist/12.js.map +1 -0
  4. package/dist/132.js +1 -0
  5. package/dist/151.js +2 -0
  6. package/dist/151.js.map +1 -0
  7. package/dist/195.js +1 -0
  8. package/dist/195.js.map +1 -0
  9. package/dist/197.js +1 -0
  10. package/dist/221.js +1 -0
  11. package/dist/221.js.map +1 -0
  12. package/dist/259.js +1 -0
  13. package/dist/259.js.map +1 -0
  14. package/dist/265.js +1 -0
  15. package/dist/265.js.map +1 -0
  16. package/dist/269.js +1 -0
  17. package/dist/269.js.map +1 -0
  18. package/dist/{574.js → 300.js} +1 -1
  19. package/dist/335.js +1 -0
  20. package/dist/367.js +1 -0
  21. package/dist/367.js.map +1 -0
  22. package/dist/384.js +1 -0
  23. package/dist/384.js.map +1 -0
  24. package/dist/{294.js → 540.js} +2 -2
  25. package/dist/{294.js.map → 540.js.map} +1 -1
  26. package/dist/55.js +1 -0
  27. package/dist/579.js +1 -0
  28. package/dist/579.js.map +1 -0
  29. package/dist/595.js +2 -0
  30. package/dist/{409.js.LICENSE.txt → 595.js.LICENSE.txt} +14 -6
  31. package/dist/595.js.map +1 -0
  32. package/dist/602.js +1 -0
  33. package/dist/602.js.map +1 -0
  34. package/dist/616.js +1 -0
  35. package/dist/616.js.map +1 -0
  36. package/dist/626.js +2 -0
  37. package/dist/626.js.map +1 -0
  38. package/dist/652.js +1 -0
  39. package/dist/77.js +1 -0
  40. package/dist/77.js.map +1 -0
  41. package/dist/773.js +2 -0
  42. package/dist/{897.js.LICENSE.txt → 773.js.LICENSE.txt} +13 -2
  43. package/dist/773.js.map +1 -0
  44. package/dist/88.js +1 -0
  45. package/dist/88.js.map +1 -0
  46. package/dist/930.js +1 -0
  47. package/dist/930.js.map +1 -0
  48. package/dist/961.js +2 -0
  49. package/dist/961.js.map +1 -0
  50. package/dist/983.js +1 -0
  51. package/dist/983.js.map +1 -0
  52. package/dist/99.js +1 -0
  53. package/dist/main.js +1 -1
  54. package/dist/main.js.map +1 -1
  55. package/dist/openmrs-esm-fast-data-entry-app.js +1 -1
  56. package/dist/openmrs-esm-fast-data-entry-app.js.buildmanifest.json +386 -154
  57. package/dist/openmrs-esm-fast-data-entry-app.js.map +1 -1
  58. package/dist/routes.json +1 -1
  59. package/jest.config.json +2 -1
  60. package/package.json +39 -36
  61. package/prettier.config.js +8 -0
  62. package/src/CancelModal.tsx +9 -15
  63. package/src/CompleteModal.tsx +7 -18
  64. package/src/FormBootstrap.tsx +31 -18
  65. package/src/Root.tsx +7 -12
  66. package/src/add-group-modal/AddGroupModal.tsx +73 -112
  67. package/src/add-group-modal/styles.scss +7 -3
  68. package/src/config-schema.ts +63 -24
  69. package/src/constant.ts +1 -1
  70. package/src/context/FormWorkflowContext.tsx +26 -39
  71. package/src/context/FormWorkflowReducer.ts +50 -74
  72. package/src/context/GroupFormWorkflowContext.tsx +40 -59
  73. package/src/context/GroupFormWorkflowReducer.ts +84 -109
  74. package/src/declarations.d.ts +3 -0
  75. package/src/empty-state/EmptyDataIllustration.tsx +4 -16
  76. package/src/empty-state/EmptyState.tsx +8 -13
  77. package/src/empty-state/styles.scss +14 -14
  78. package/src/form-entry-workflow/FormEntryWorkflow.tsx +43 -55
  79. package/src/form-entry-workflow/form-review-card/FormReviewCard.tsx +7 -7
  80. package/src/form-entry-workflow/form-review-card/index.ts +1 -1
  81. package/src/form-entry-workflow/form-review-card/styles.scss +9 -11
  82. package/src/form-entry-workflow/index.ts +1 -1
  83. package/src/form-entry-workflow/patient-banner/PatientBanner.test.tsx +5 -5
  84. package/src/form-entry-workflow/patient-banner/PatientBanner.tsx +14 -27
  85. package/src/form-entry-workflow/patient-banner/index.ts +1 -1
  86. package/src/form-entry-workflow/patient-banner/styles.scss +11 -12
  87. package/src/form-entry-workflow/patient-search-header/PatientSearchHeader.tsx +19 -28
  88. package/src/form-entry-workflow/patient-search-header/index.ts +1 -1
  89. package/src/form-entry-workflow/patient-search-header/styles.scss +13 -10
  90. package/src/form-entry-workflow/styles.scss +11 -13
  91. package/src/form-entry-workflow/workflow-review/WorkflowReview.tsx +13 -11
  92. package/src/form-entry-workflow/workflow-review/index.ts +1 -1
  93. package/src/form-entry-workflow/workflow-review/styles.scss +0 -4
  94. package/src/forms-app-menu-link.tsx +4 -6
  95. package/src/forms-page/FormsPage.tsx +23 -51
  96. package/src/forms-page/forms-table/FormsTable.tsx +22 -42
  97. package/src/forms-page/forms-table/index.ts +1 -1
  98. package/src/forms-page/forms-table/styles.scss +4 -5
  99. package/src/forms-page/index.ts +1 -1
  100. package/src/forms-page/styles.scss +3 -5
  101. package/src/group-form-entry-workflow/GroupFormEntryWorkflow.tsx +9 -9
  102. package/src/group-form-entry-workflow/GroupSessionWorkspace.tsx +77 -117
  103. package/src/group-form-entry-workflow/SessionDetailsForm.tsx +73 -50
  104. package/src/group-form-entry-workflow/SessionMetaWorkspace.tsx +20 -28
  105. package/src/group-form-entry-workflow/attendance-table/AttendanceTable.tsx +15 -29
  106. package/src/group-form-entry-workflow/attendance-table/index.ts +1 -1
  107. package/src/group-form-entry-workflow/configurable-questions/ConfigurableQuestionsSection.tsx +45 -0
  108. package/src/group-form-entry-workflow/group-display-header/GroupDisplayHeader.test.tsx +5 -5
  109. package/src/group-form-entry-workflow/group-display-header/GroupDisplayHeader.tsx +13 -21
  110. package/src/group-form-entry-workflow/group-display-header/index.ts +1 -1
  111. package/src/group-form-entry-workflow/group-display-header/styles.scss +20 -20
  112. package/src/group-form-entry-workflow/group-search/CompactGroupResults.tsx +24 -35
  113. package/src/group-form-entry-workflow/group-search/CompactGroupSearch.tsx +13 -15
  114. package/src/group-form-entry-workflow/group-search/GroupSearch.tsx +22 -38
  115. package/src/group-form-entry-workflow/group-search/compact-group-result.scss +16 -17
  116. package/src/group-form-entry-workflow/group-search/compact-group-search.scss +7 -8
  117. package/src/group-form-entry-workflow/group-search/group-search.scss +20 -23
  118. package/src/group-form-entry-workflow/group-search-header/GroupSearchHeader.tsx +20 -21
  119. package/src/group-form-entry-workflow/group-search-header/index.ts +1 -1
  120. package/src/group-form-entry-workflow/group-search-header/styles.scss +8 -8
  121. package/src/group-form-entry-workflow/index.ts +1 -1
  122. package/src/group-form-entry-workflow/styles.scss +13 -16
  123. package/src/hooks/index.ts +7 -6
  124. package/src/hooks/useFormState.ts +3 -3
  125. package/src/hooks/useGetAllForms.ts +7 -15
  126. package/src/hooks/useGetEncounter.ts +3 -3
  127. package/src/hooks/useGetPatient.ts +2 -2
  128. package/src/hooks/useGetPatients.ts +4 -6
  129. package/src/hooks/useGetSystemSetting.ts +3 -5
  130. package/src/hooks/useKeyPress.ts +5 -5
  131. package/src/hooks/usePostEndpoint.ts +10 -10
  132. package/src/hooks/useSearchEndpoint.ts +23 -40
  133. package/src/hooks/useSpecificQuestions.ts +75 -0
  134. package/src/hooks/useStartVisit.ts +18 -28
  135. package/src/index.ts +8 -20
  136. package/src/patient-card/PatientCard.tsx +8 -20
  137. package/src/patient-card/index.ts +1 -1
  138. package/src/patient-card/styles.scss +2 -4
  139. package/src/routes.json +2 -2
  140. package/src/setup-tests.ts +1 -1
  141. package/src/types.ts +25 -0
  142. package/tools/i18next-parser.config.js +19 -19
  143. package/translations/am.json +75 -0
  144. package/translations/ar.json +75 -0
  145. package/translations/en.json +7 -1
  146. package/translations/es.json +75 -0
  147. package/translations/fr.json +33 -8
  148. package/translations/he.json +75 -0
  149. package/translations/km.json +75 -0
  150. package/tsconfig.json +2 -1
  151. package/turbo.json +18 -0
  152. package/webpack.config.js +1 -1
  153. package/dist/136.js +0 -1
  154. package/dist/136.js.map +0 -1
  155. package/dist/141.js +0 -2
  156. package/dist/141.js.map +0 -1
  157. package/dist/233.js +0 -2
  158. package/dist/233.js.map +0 -1
  159. package/dist/242.js +0 -1
  160. package/dist/242.js.map +0 -1
  161. package/dist/327.js +0 -1
  162. package/dist/327.js.map +0 -1
  163. package/dist/387.js +0 -1
  164. package/dist/387.js.map +0 -1
  165. package/dist/405.js +0 -1
  166. package/dist/405.js.map +0 -1
  167. package/dist/409.js +0 -2
  168. package/dist/409.js.map +0 -1
  169. package/dist/431.js +0 -1
  170. package/dist/431.js.map +0 -1
  171. package/dist/559.js +0 -1
  172. package/dist/559.js.map +0 -1
  173. package/dist/757.js +0 -1
  174. package/dist/820.js +0 -1
  175. package/dist/820.js.map +0 -1
  176. package/dist/846.js +0 -1
  177. package/dist/846.js.map +0 -1
  178. package/dist/885.js +0 -1
  179. package/dist/885.js.map +0 -1
  180. package/dist/897.js +0 -2
  181. package/dist/897.js.map +0 -1
  182. package/dist/92.js +0 -1
  183. package/dist/92.js.map +0 -1
  184. package/dist/935.js +0 -2
  185. package/dist/935.js.map +0 -1
  186. package/src/declarations.d.tsx +0 -2
  187. /package/dist/{141.js.LICENSE.txt → 151.js.LICENSE.txt} +0 -0
  188. /package/dist/{294.js.LICENSE.txt → 540.js.LICENSE.txt} +0 -0
  189. /package/dist/{233.js.LICENSE.txt → 626.js.LICENSE.txt} +0 -0
  190. /package/dist/{935.js.LICENSE.txt → 961.js.LICENSE.txt} +0 -0
@@ -1,58 +1,31 @@
1
- import React, {
2
- useCallback,
3
- useContext,
4
- useEffect,
5
- useMemo,
6
- useState,
7
- } from "react";
8
- import {
9
- ComposedModal,
10
- Button,
11
- ModalHeader,
12
- ModalFooter,
13
- ModalBody,
14
- TextInput,
15
- FormLabel,
16
- } from "@carbon/react";
17
- import { TrashCan } from "@carbon/react/icons";
18
- import { useTranslation } from "react-i18next";
19
- import { ExtensionSlot, showToast } from "@openmrs/esm-framework";
20
- import styles from "./styles.scss";
21
- import GroupFormWorkflowContext from "../context/GroupFormWorkflowContext";
22
- import { usePostCohort } from "../hooks";
1
+ import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react';
2
+ import { ComposedModal, Button, ModalHeader, ModalFooter, ModalBody, TextInput, FormLabel } from '@carbon/react';
3
+ import { TrashCan } from '@carbon/react/icons';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { ExtensionSlot, fetchCurrentPatient, showToast, useConfig, usePatient } from '@openmrs/esm-framework';
6
+ import styles from './styles.scss';
7
+ import GroupFormWorkflowContext from '../context/GroupFormWorkflowContext';
8
+ import { usePostCohort } from '../hooks';
23
9
 
24
10
  const MemExtension = React.memo(ExtensionSlot);
25
11
 
26
- const buildPatientDisplay = (patient) => {
27
- const givenName = patient?.name?.[0]?.given?.[0];
28
- const familyName = patient?.name?.[0]?.family;
29
- const identifier = patient?.identifier?.[0]?.value;
30
-
31
- let display = identifier ? identifier + " - " : "";
32
- display += (givenName || "") + " " + (familyName || "");
33
- return display.replace(/\s+/g, " ");
34
- };
35
-
36
12
  const PatientRow = ({ patient, removePatient }) => {
37
13
  const { t } = useTranslation();
38
- const onClickHandler = useCallback(
39
- () => removePatient(patient?.uuid),
40
- [patient, removePatient]
41
- );
14
+ const { patient: patientInfo, error, isLoading } = usePatient(patient?.uuid);
15
+ const onClickHandler = useCallback(() => removePatient(patient?.uuid), [patient, removePatient]);
16
+
42
17
  const patientDisplay = useMemo(() => {
43
- if (!patient) {
44
- return "";
45
- }
18
+ if (isLoading || error || !patientInfo) return '';
46
19
 
47
- if (patient.display) {
48
- return patient.display;
49
- }
20
+ const { identifier, name } = patientInfo;
21
+ const displayIdentifier = identifier?.[0]?.value || '';
22
+ const givenNames = `${(name?.[0]?.given || []).join(' ')} ${name?.[0]?.family || ''}`;
50
23
 
51
- return buildPatientDisplay(patient);
52
- }, [patient]);
24
+ return `${displayIdentifier ? `${displayIdentifier} -` : ''}${givenNames ? ` ${givenNames}` : ''}`.trim();
25
+ }, [isLoading, error, patientInfo]);
53
26
 
54
27
  return (
55
- <li key={patient?.uuid} className={styles.patientRow}>
28
+ <li className={styles.patientRow}>
56
29
  <span>
57
30
  <Button
58
31
  kind="tertiary"
@@ -62,7 +35,7 @@ const PatientRow = ({ patient, removePatient }) => {
62
35
  renderIcon={TrashCan}
63
36
  tooltipAlignment="start"
64
37
  tooltipPosition="top"
65
- iconDescription={t("remove", "Remove")}
38
+ iconDescription={t('remove', 'Remove')}
66
39
  />
67
40
  </span>
68
41
  <span className={styles.patientName}>{patientDisplay}</span>
@@ -71,66 +44,50 @@ const PatientRow = ({ patient, removePatient }) => {
71
44
  };
72
45
 
73
46
  const NewGroupForm = (props) => {
74
- const {
75
- name,
76
- setName,
77
- patientList,
78
- updatePatientList,
79
- errors,
80
- validate,
81
- removePatient,
82
- } = props;
47
+ const { name, setName, patientList, updatePatientList, errors, validate, removePatient } = props;
83
48
  const { t } = useTranslation();
84
49
 
85
50
  return (
86
51
  <div
87
52
  style={{
88
- display: "flex",
89
- flexDirection: "column",
90
- rowGap: "1rem",
53
+ display: 'flex',
54
+ flexDirection: 'column',
55
+ rowGap: '1rem',
91
56
  }}
92
57
  >
93
58
  <TextInput
94
- labelText={t("newGroupName", "New Group Name")}
59
+ labelText={t('newGroupName', 'New Group Name')}
95
60
  value={name}
96
61
  onChange={(e) => setName(e.target.value)}
97
- onBlur={() => validate("name")}
62
+ onBlur={() => validate('name')}
98
63
  />
99
64
  {errors?.name && (
100
65
  <p className={styles.formError}>
101
- {errors.name === "required"
102
- ? t("groupNameError", "Please enter a group name.")
103
- : errors.name}
66
+ {errors.name === 'required' ? t('groupNameError', 'Please enter a group name.') : errors.name}
104
67
  </p>
105
68
  )}
106
69
  <FormLabel>
107
- {patientList.length} {t("patientsInGroup", "Patients in group")}
70
+ {patientList.length} {t('patientsInGroup', 'Patients in group')}
108
71
  </FormLabel>
109
72
  {errors?.patientList && (
110
- <p className={styles.formError}>
111
- {t("noPatientError", "Please enter at least one patient.")}
112
- </p>
73
+ <p className={styles.formError}>{t('noPatientError', 'Please enter at least one patient.')}</p>
113
74
  )}
114
75
  {!errors?.patientList && (
115
76
  <ul className={styles.patientList}>
116
77
  {patientList?.map((patient, index) => (
117
- <PatientRow
118
- patient={patient}
119
- removePatient={removePatient}
120
- key={index}
121
- />
78
+ <PatientRow patient={patient} removePatient={removePatient} key={patient.uuid} />
122
79
  ))}
123
80
  </ul>
124
81
  )}
125
82
 
126
- <FormLabel>Search for patients to add to group</FormLabel>
83
+ <FormLabel>{t('searchForPatientsToAddToGroup', 'Search for patients to add to group')}</FormLabel>
127
84
  <div className={styles.searchBar}>
128
85
  <MemExtension
129
86
  extensionSlotName="patient-search-bar-slot"
130
87
  state={{
131
88
  selectPatientAction: updatePatientList,
132
89
  buttonProps: {
133
- kind: "secondary",
90
+ kind: 'secondary',
134
91
  },
135
92
  }}
136
93
  />
@@ -142,10 +99,10 @@ const NewGroupForm = (props) => {
142
99
  const AddGroupModal = ({
143
100
  patients = undefined,
144
101
  isCreate = undefined,
145
- groupName = "",
102
+ groupName = '',
146
103
  cohortUuid = undefined,
147
104
  isOpen,
148
- handleCancel,
105
+ onPostCancel,
149
106
  onPostSubmit,
150
107
  }) => {
151
108
  const { setGroup } = useContext(GroupFormWorkflowContext);
@@ -154,33 +111,32 @@ const AddGroupModal = ({
154
111
  const [name, setName] = useState(groupName);
155
112
  const [patientList, setPatientList] = useState(patients || []);
156
113
  const { post, result, error } = usePostCohort();
114
+ const config = useConfig();
157
115
 
158
116
  const removePatient = useCallback(
159
117
  (patientUuid: string) =>
160
- setPatientList((patientList) =>
161
- patientList.filter((patient) => patient.uuid !== patientUuid)
162
- ),
163
- [setPatientList]
118
+ setPatientList((patientList) => patientList.filter((patient) => patient.uuid !== patientUuid)),
119
+ [setPatientList],
164
120
  );
165
121
 
166
122
  const validate = useCallback(
167
123
  (field?: string | undefined) => {
168
124
  let valid = true;
169
125
  if (field) {
170
- valid = field === "name" ? !!name : !!patientList.length;
126
+ valid = field === 'name' ? !!name : !!patientList.length;
171
127
  setErrors((errors) => ({
172
128
  ...errors,
173
- [field]: valid ? null : "required",
129
+ [field]: valid ? null : 'required',
174
130
  }));
175
131
  } else {
176
132
  if (!name) {
177
- setErrors((errors) => ({ ...errors, name: "required" }));
133
+ setErrors((errors) => ({ ...errors, name: 'required' }));
178
134
  valid = false;
179
135
  } else {
180
136
  setErrors((errors) => ({ ...errors, name: null }));
181
137
  }
182
138
  if (!patientList.length) {
183
- setErrors((errors) => ({ ...errors, patientList: "required" }));
139
+ setErrors((errors) => ({ ...errors, patientList: 'required' }));
184
140
  valid = false;
185
141
  } else {
186
142
  setErrors((errors) => ({ ...errors, patientList: null }));
@@ -188,21 +144,29 @@ const AddGroupModal = ({
188
144
  }
189
145
  return valid;
190
146
  },
191
- [name, patientList.length]
147
+ [name, patientList.length],
192
148
  );
193
149
 
194
150
  const updatePatientList = useCallback(
195
- (patient) => {
196
- setPatientList((patientList) => {
197
- if (!patientList.find((p) => p.uuid === patient.uuid)) {
198
- return [...patientList, patient];
199
- } else {
200
- return patientList;
201
- }
202
- });
151
+ (patientUuid) => {
152
+ function getPatientName(patient) {
153
+ return [patient?.name?.[0]?.given, patient?.name?.[0]?.family].join(' ');
154
+ }
155
+ if (!patientList.find((p) => p.uuid === patientUuid)) {
156
+ fetchCurrentPatient(patientUuid).then((result) => {
157
+ const newPatient = { uuid: patientUuid, ...result };
158
+ setPatientList(
159
+ [...patientList, newPatient].sort((a, b) =>
160
+ getPatientName(a).localeCompare(getPatientName(b), undefined, {
161
+ sensitivity: 'base',
162
+ }),
163
+ ),
164
+ );
165
+ });
166
+ }
203
167
  setErrors((errors) => ({ ...errors, patientList: null }));
204
168
  },
205
- [setPatientList]
169
+ [patientList, setPatientList],
206
170
  );
207
171
 
208
172
  const handleSubmit = () => {
@@ -210,6 +174,7 @@ const AddGroupModal = ({
210
174
  post({
211
175
  uuid: cohortUuid,
212
176
  name: name,
177
+ cohortType: config?.groupSessionConcepts?.cohortTypeId,
213
178
  cohortMembers: patientList.map((p) => ({ patient: p.uuid })),
214
179
  });
215
180
  if (onPostSubmit) {
@@ -218,6 +183,13 @@ const AddGroupModal = ({
218
183
  }
219
184
  };
220
185
 
186
+ const handleCancel = () => {
187
+ setPatientList(patients || []);
188
+ if (onPostCancel) {
189
+ onPostCancel();
190
+ }
191
+ };
192
+
221
193
  useEffect(() => {
222
194
  if (result) {
223
195
  setGroup({
@@ -232,20 +204,13 @@ const AddGroupModal = ({
232
204
  useEffect(() => {
233
205
  if (error) {
234
206
  showToast({
235
- kind: "error",
236
- title: t("postError", "POST Error"),
237
- description:
238
- error.message ??
239
- t("unknownPostError", "An unknown error occurred while saving data"),
207
+ kind: 'error',
208
+ title: t('postError', 'POST Error'),
209
+ description: error.message ?? t('unknownPostError', 'An unknown error occurred while saving data'),
240
210
  });
241
211
  if (error.fieldErrors) {
242
212
  setErrors(
243
- Object.fromEntries(
244
- Object.entries(error.fieldErrors).map(([key, value]) => [
245
- key,
246
- value?.[0]?.message,
247
- ])
248
- )
213
+ Object.fromEntries(Object.entries(error.fieldErrors).map(([key, value]) => [key, value?.[0]?.message])),
249
214
  );
250
215
  }
251
216
  }
@@ -254,11 +219,7 @@ const AddGroupModal = ({
254
219
  return (
255
220
  <div className={styles.modal}>
256
221
  <ComposedModal open={isOpen} onClose={handleCancel}>
257
- <ModalHeader>
258
- {isCreate
259
- ? t("createNewGroup", "Create New Group")
260
- : t("editGroup", "Edit Group")}
261
- </ModalHeader>
222
+ <ModalHeader>{isCreate ? t('createNewGroup', 'Create New Group') : t('editGroup', 'Edit Group')}</ModalHeader>
262
223
  <ModalBody>
263
224
  <NewGroupForm
264
225
  {...{
@@ -274,10 +235,10 @@ const AddGroupModal = ({
274
235
  </ModalBody>
275
236
  <ModalFooter>
276
237
  <Button kind="secondary" onClick={handleCancel}>
277
- {t("cancel", "Cancel")}
238
+ {t('cancel', 'Cancel')}
278
239
  </Button>
279
240
  <Button kind="primary" onClick={handleSubmit}>
280
- {isCreate ? t("createGroup", "Create Group") : t("save", "Save")}
241
+ {isCreate ? t('createGroup', 'Create Group') : t('save', 'Save')}
281
242
  </Button>
282
243
  </ModalFooter>
283
244
  </ComposedModal>
@@ -1,5 +1,5 @@
1
- @use '@carbon/styles/scss/spacing';
2
1
  @use '@carbon/colors';
2
+ @use '@carbon/layout';
3
3
 
4
4
  .modal {
5
5
  :global(.cds--modal) {
@@ -17,6 +17,10 @@
17
17
  width: 100%
18
18
  }
19
19
 
20
+ .searchBar > div button {
21
+ height: auto;
22
+ }
23
+
20
24
  .formError {
21
25
  color: red;
22
26
  }
@@ -32,7 +36,7 @@
32
36
 
33
37
  .patientName {
34
38
  flex-grow: 1;
35
- padding-left: spacing.$spacing-05;
39
+ padding-left: layout.$spacing-05;
36
40
  }
37
41
 
38
42
  .loading {
@@ -41,5 +45,5 @@
41
45
  flex-direction: column;
42
46
  justify-content: center;
43
47
  align-items: center;
44
- row-gap: spacing.$spacing-05;
48
+ row-gap: layout.$spacing-05;
45
49
  }
@@ -1,4 +1,4 @@
1
- import { Type } from "@openmrs/esm-framework";
1
+ import { Type } from '@openmrs/esm-framework';
2
2
 
3
3
  /**
4
4
  * This is the config schema.
@@ -8,44 +8,43 @@ import { Type } from "@openmrs/esm-framework";
8
8
  export const configSchema = {
9
9
  formCategories: {
10
10
  _type: Type.Array,
11
- _description:
12
- "Organize forms into categories. A form can belong to multiple categories.",
11
+ _description: 'Organize forms into categories. A form can belong to multiple categories.',
13
12
  _elements: {
14
13
  name: {
15
14
  _type: Type.String,
16
- _description: "Category name",
15
+ _description: 'Category name',
17
16
  },
18
17
  forms: {
19
18
  _type: Type.Array,
20
- _description: "List of forms for this category.",
19
+ _description: 'List of forms for this category.',
21
20
  _elements: {
22
21
  formUUID: {
23
22
  _type: Type.UUID,
24
- _description: "UUID of form",
23
+ _description: 'UUID of form',
25
24
  },
26
25
  name: {
27
26
  _type: Type.String,
28
- _description: "Name of form",
27
+ _description: 'Name of form',
29
28
  },
30
29
  },
31
30
  },
32
31
  },
33
32
  _default: [
34
33
  {
35
- name: "ICRC Forms",
34
+ name: 'ICRC Forms',
36
35
  forms: [
37
36
  {
38
- formUUID: "0cefb866-110c-4f16-af58-560932a1db1f",
39
- name: "Adult Triage",
37
+ formUUID: '0cefb866-110c-4f16-af58-560932a1db1f',
38
+ name: 'Adult Triage',
40
39
  },
41
40
  ],
42
41
  },
43
42
  {
44
- name: "Distress Scales",
43
+ name: 'Distress Scales',
45
44
  forms: [
46
45
  {
47
- formUUID: "9f26aad4-244a-46ca-be49-1196df1a8c9a",
48
- name: "POC Sample Form 1",
46
+ formUUID: '9f26aad4-244a-46ca-be49-1196df1a8c9a',
47
+ name: 'POC Sample Form 1',
49
48
  },
50
49
  ],
51
50
  },
@@ -53,34 +52,74 @@ export const configSchema = {
53
52
  },
54
53
  formCategoriesToShow: {
55
54
  _type: Type.Array,
56
- _description: "Forms to show by default on the forms app home page.",
55
+ _description: 'Forms to show by default on the forms app home page.',
57
56
  _elements: {
58
57
  _type: Type.String,
59
- _description: "Name of category",
58
+ _description: 'Name of category',
60
59
  },
61
- _default: ["ICRC Forms", "Distress Scales"],
60
+ _default: ['ICRC Forms', 'Distress Scales'],
62
61
  },
63
62
  groupSessionConcepts: {
64
63
  sessionName: {
65
64
  _type: Type.UUID,
66
- _description: "UUID of concept for Session Name",
67
- _default: "e2559620-900b-4f66-ae41-0b9c4adfb654",
65
+ _description: 'UUID of concept for Session Name',
66
+ _default: 'e2559620-900b-4f66-ae41-0b9c4adfb654',
68
67
  },
69
68
  sessionDate: {
70
69
  _type: Type.UUID,
71
- _description: "UUID of concept for Session Date",
72
- _default: "ceaca505-6dff-4940-8a43-8c060a0924d7",
70
+ _description: 'UUID of concept for Session Date',
71
+ _default: 'ceaca505-6dff-4940-8a43-8c060a0924d7',
73
72
  },
74
73
  practitionerName: {
75
74
  _type: Type.UUID,
76
- _description: "UUID of concept for Practitioner Name",
77
- _default: "f1a2d58c-1a0e-4148-931a-aac224649fdc",
75
+ _description: 'UUID of concept for Practitioner Name',
76
+ _default: 'f1a2d58c-1a0e-4148-931a-aac224649fdc',
78
77
  },
79
78
  sessionNotes: {
80
79
  _type: Type.UUID,
81
- _description: "UUID of concept for Session Notes",
82
- _default: "fa8fedc0-c066-4da3-8dc1-2ad8621fc480",
80
+ _description: 'UUID of concept for Session Notes',
81
+ _default: 'fa8fedc0-c066-4da3-8dc1-2ad8621fc480',
83
82
  },
83
+ cohortTypeId: {
84
+ _type: Type.UUID,
85
+ _description: 'UUID of cohort type',
86
+ _default: 'eee9970e-7ca0-4e8c-a280-c33e9d5f6a04',
87
+ },
88
+ cohortId: {
89
+ _type: Type.UUID,
90
+ _description: 'UUID of concept for cohort identifier',
91
+ _default: '5461f231-7e59-4be8-93a4-6d49fd13c00a',
92
+ },
93
+ cohortName: {
94
+ _type: Type.UUID,
95
+ _description: 'UUID of concept for cohort name',
96
+ _default: '6029f289-92a6-4a68-80f1-3078d0152449',
97
+ },
98
+ sessionUuid: {
99
+ _type: Type.UUID,
100
+ _description: 'UUID of concept for session identifier',
101
+ _default: '6a803908-8a5b-4598-adea-19358c83529a',
102
+ },
103
+ },
104
+ specificQuestions: {
105
+ _type: Type.Array,
106
+ _description: 'List of specific questions to populate forms.',
107
+ _elements: {
108
+ forms: {
109
+ _type: Type.Array,
110
+ _description: 'List of form UUIDs for which the question applies.',
111
+ _elements: {
112
+ _type: Type.UUID,
113
+ },
114
+ _default: [],
115
+ },
116
+ questionId: {
117
+ _type: Type.String,
118
+ _description: 'ID of the question.',
119
+ _default: '',
120
+ },
121
+ },
122
+ _default: [],
84
123
  },
85
124
  };
86
125
 
package/src/constant.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export const routes = {
2
- allForms: "all-forms",
2
+ allForms: 'all-forms',
3
3
  };
4
4
 
5
5
  export const spaBase = window.spaBase;
@@ -1,8 +1,8 @@
1
- import React, { useEffect, useMemo, useReducer } from "react";
2
- import reducer from "./FormWorkflowReducer";
3
- import { useParams, useLocation } from "react-router-dom";
4
- import useGetSystemSetting from "../hooks/useGetSystemSetting";
5
- import { useSession } from "@openmrs/esm-framework";
1
+ import React, { useEffect, useMemo, useReducer } from 'react';
2
+ import reducer from './FormWorkflowReducer';
3
+ import { useParams, useLocation } from 'react-router-dom';
4
+ import useGetSystemSetting from '../hooks/useGetSystemSetting';
5
+ import { useSession } from '@openmrs/esm-framework';
6
6
  interface ParamTypes {
7
7
  formUuid?: string;
8
8
  }
@@ -44,46 +44,41 @@ const FormWorkflowContext = React.createContext({
44
44
  const FormWorkflowProvider = ({ children }) => {
45
45
  const { user } = useSession();
46
46
  const { formUuid } = useParams() as ParamTypes;
47
- const activeFormUuid = formUuid.split("&")[0];
47
+ const activeFormUuid = formUuid.split('&')[0];
48
48
  const { search } = useLocation();
49
- const newPatientUuid = new URLSearchParams(search).get("patientUuid");
49
+ const newPatientUuid = new URLSearchParams(search).get('patientUuid');
50
50
  const [state, dispatch] = useReducer(reducer, {
51
51
  ...initialWorkflowState,
52
52
  ...initialActions,
53
53
  });
54
- const systemSetting = useGetSystemSetting(
55
- "@openmrs/esm-fast-data-entry-app.groupSessionVisitTypeUuid"
56
- );
57
- const singleSessionVisitTypeUuid =
58
- systemSetting?.result?.data?.results?.[0]?.value;
54
+ const systemSetting = useGetSystemSetting('@openmrs/esm-fast-data-entry-app.groupSessionVisitTypeUuid');
55
+ const singleSessionVisitTypeUuid = systemSetting?.result?.data?.results?.[0]?.value;
59
56
 
60
57
  const actions = useMemo(
61
58
  () => ({
62
59
  initializeWorkflowState: ({ activeFormUuid, newPatientUuid }) =>
63
60
  dispatch({
64
- type: "INITIALIZE_WORKFLOW_STATE",
61
+ type: 'INITIALIZE_WORKFLOW_STATE',
65
62
  activeFormUuid,
66
63
  newPatientUuid,
67
64
  userUuid: user.uuid,
68
65
  }),
69
- addPatient: (patientUuid) =>
70
- dispatch({ type: "ADD_PATIENT", patientUuid }),
71
- openPatientSearch: () => dispatch({ type: "OPEN_PATIENT_SEARCH" }),
66
+ addPatient: (patientUuid) => dispatch({ type: 'ADD_PATIENT', patientUuid }),
67
+ openPatientSearch: () => dispatch({ type: 'OPEN_PATIENT_SEARCH' }),
72
68
  saveEncounter: (encounterUuid) =>
73
69
  dispatch({
74
- type: "SAVE_ENCOUNTER",
70
+ type: 'SAVE_ENCOUNTER',
75
71
  encounterUuid,
76
72
  }),
77
- submitForNext: () => dispatch({ type: "SUBMIT_FOR_NEXT" }),
78
- submitForReview: () => dispatch({ type: "SUBMIT_FOR_REVIEW" }),
79
- submitForComplete: () => dispatch({ type: "SUBMIT_FOR_COMPLETE" }),
80
- editEncounter: (patientUuid) =>
81
- dispatch({ type: "EDIT_ENCOUNTER", patientUuid }),
82
- goToReview: () => dispatch({ type: "GO_TO_REVIEW" }),
83
- destroySession: () => dispatch({ type: "DESTROY_SESSION" }),
84
- closeSession: () => dispatch({ type: "CLOSE_SESSION" }),
73
+ submitForNext: () => dispatch({ type: 'SUBMIT_FOR_NEXT' }),
74
+ submitForReview: () => dispatch({ type: 'SUBMIT_FOR_REVIEW' }),
75
+ submitForComplete: () => dispatch({ type: 'SUBMIT_FOR_COMPLETE' }),
76
+ editEncounter: (patientUuid) => dispatch({ type: 'EDIT_ENCOUNTER', patientUuid }),
77
+ goToReview: () => dispatch({ type: 'GO_TO_REVIEW' }),
78
+ destroySession: () => dispatch({ type: 'DESTROY_SESSION' }),
79
+ closeSession: () => dispatch({ type: 'CLOSE_SESSION' }),
85
80
  }),
86
- [user]
81
+ [user],
87
82
  );
88
83
 
89
84
  // if formUuid isn't a part of state yet, grab it from the url params
@@ -99,21 +94,13 @@ const FormWorkflowProvider = ({ children }) => {
99
94
  value={{
100
95
  ...state,
101
96
  ...actions,
102
- workflowState:
103
- state.forms?.[state.activeFormUuid]?.workflowState ??
104
- initialWorkflowState.workflowState,
97
+ workflowState: state.forms?.[state.activeFormUuid]?.workflowState ?? initialWorkflowState.workflowState,
105
98
  activePatientUuid:
106
- state.forms?.[state.activeFormUuid]?.activePatientUuid ??
107
- initialWorkflowState.activePatientUuid,
99
+ state.forms?.[state.activeFormUuid]?.activePatientUuid ?? initialWorkflowState.activePatientUuid,
108
100
  activeEncounterUuid:
109
- state.forms?.[state.activeFormUuid]?.activeEncounterUuid ??
110
- initialWorkflowState.activeEncounterUuid,
111
- patientUuids:
112
- state.forms?.[state.activeFormUuid]?.patientUuids ??
113
- initialWorkflowState.patientUuids,
114
- encounters:
115
- state.forms?.[state.activeFormUuid]?.encounters ??
116
- initialWorkflowState.encounters,
101
+ state.forms?.[state.activeFormUuid]?.activeEncounterUuid ?? initialWorkflowState.activeEncounterUuid,
102
+ patientUuids: state.forms?.[state.activeFormUuid]?.patientUuids ?? initialWorkflowState.patientUuids,
103
+ encounters: state.forms?.[state.activeFormUuid]?.encounters ?? initialWorkflowState.encounters,
117
104
  singleSessionVisitTypeUuid,
118
105
  }}
119
106
  >