@openmrs/esm-fast-data-entry-app 1.0.0-pre.59 → 1.0.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 (193) hide show
  1. package/README.md +21 -2
  2. package/__mocks__/react-i18next.js +9 -14
  3. package/dist/101.js +1 -0
  4. package/dist/101.js.map +1 -0
  5. package/dist/132.js +1 -1
  6. package/dist/188.js +1 -0
  7. package/dist/188.js.map +1 -0
  8. package/dist/197.js +1 -0
  9. package/dist/219.js +1 -0
  10. package/dist/219.js.map +1 -0
  11. package/dist/221.js +1 -0
  12. package/dist/221.js.map +1 -0
  13. package/dist/259.js +1 -0
  14. package/dist/259.js.map +1 -0
  15. package/dist/29.js +2 -0
  16. package/dist/29.js.LICENSE.txt +3 -0
  17. package/dist/29.js.map +1 -0
  18. package/dist/300.js +1 -0
  19. package/dist/326.js +1 -0
  20. package/dist/326.js.map +1 -0
  21. package/dist/335.js +1 -0
  22. package/dist/367.js +1 -0
  23. package/dist/367.js.map +1 -0
  24. package/dist/480.js +1 -0
  25. package/dist/540.js +2 -0
  26. package/dist/{536.js.LICENSE.txt → 540.js.LICENSE.txt} +3 -2
  27. package/dist/540.js.map +1 -0
  28. package/dist/55.js +1 -0
  29. package/dist/564.js +1 -0
  30. package/dist/564.js.map +1 -0
  31. package/dist/602.js +1 -0
  32. package/dist/602.js.map +1 -0
  33. package/dist/626.js +2 -0
  34. package/dist/{294.js.LICENSE.txt → 626.js.LICENSE.txt} +3 -8
  35. package/dist/626.js.map +1 -0
  36. package/dist/652.js +1 -0
  37. package/dist/685.js +1 -0
  38. package/dist/685.js.map +1 -0
  39. package/dist/773.js +2 -0
  40. package/dist/773.js.LICENSE.txt +32 -0
  41. package/dist/773.js.map +1 -0
  42. package/dist/893.js +1 -0
  43. package/dist/893.js.map +1 -0
  44. package/dist/91.js +1 -0
  45. package/dist/91.js.map +1 -0
  46. package/dist/941.js +2 -0
  47. package/dist/941.js.LICENSE.txt +30 -0
  48. package/dist/941.js.map +1 -0
  49. package/dist/961.js +2 -0
  50. package/dist/{935.js.LICENSE.txt → 961.js.LICENSE.txt} +6 -10
  51. package/dist/961.js.map +1 -0
  52. package/dist/99.js +1 -0
  53. package/dist/99.js.map +1 -0
  54. package/dist/991.js +1 -0
  55. package/dist/991.js.map +1 -0
  56. package/dist/main.js +1 -0
  57. package/dist/main.js.map +1 -0
  58. package/dist/openmrs-esm-fast-data-entry-app.js +1 -1
  59. package/dist/openmrs-esm-fast-data-entry-app.js.buildmanifest.json +500 -122
  60. package/dist/openmrs-esm-fast-data-entry-app.js.map +1 -0
  61. package/dist/routes.json +1 -0
  62. package/jest.config.json +21 -18
  63. package/package.json +59 -62
  64. package/prettier.config.js +8 -0
  65. package/src/CancelModal.tsx +42 -0
  66. package/src/CompleteModal.tsx +35 -0
  67. package/src/FormBootstrap.tsx +45 -10
  68. package/src/Root.tsx +11 -9
  69. package/src/add-group-modal/AddGroupModal.tsx +249 -0
  70. package/src/add-group-modal/styles.scss +49 -0
  71. package/src/config-schema.ts +77 -16
  72. package/src/constant.ts +1 -1
  73. package/src/context/FormWorkflowContext.tsx +32 -33
  74. package/src/context/FormWorkflowReducer.ts +53 -67
  75. package/src/context/GroupFormWorkflowContext.tsx +155 -0
  76. package/src/context/GroupFormWorkflowReducer.ts +405 -0
  77. package/src/declarations.d.ts +4 -0
  78. package/src/empty-state/EmptyDataIllustration.tsx +4 -16
  79. package/src/empty-state/EmptyState.tsx +16 -17
  80. package/src/empty-state/styles.scss +14 -14
  81. package/src/form-entry-workflow/FormEntryWorkflow.tsx +89 -125
  82. package/src/{form-review-card → form-entry-workflow/form-review-card}/FormReviewCard.tsx +7 -7
  83. package/src/form-entry-workflow/form-review-card/index.ts +3 -0
  84. package/src/form-entry-workflow/form-review-card/styles.scss +37 -0
  85. package/src/form-entry-workflow/index.ts +1 -1
  86. package/src/form-entry-workflow/patient-banner/PatientBanner.test.tsx +9 -0
  87. package/src/{patient-banner → form-entry-workflow/patient-banner}/PatientBanner.tsx +14 -27
  88. package/src/form-entry-workflow/patient-banner/index.ts +3 -0
  89. package/src/form-entry-workflow/patient-banner/styles.scss +44 -0
  90. package/src/form-entry-workflow/patient-search-header/PatientSearchHeader.tsx +54 -0
  91. package/src/form-entry-workflow/patient-search-header/index.ts +3 -0
  92. package/src/form-entry-workflow/patient-search-header/styles.scss +25 -0
  93. package/src/form-entry-workflow/styles.scss +16 -16
  94. package/src/form-entry-workflow/workflow-review/WorkflowReview.tsx +37 -0
  95. package/src/form-entry-workflow/workflow-review/index.ts +3 -0
  96. package/src/{workflow-review → form-entry-workflow/workflow-review}/styles.scss +0 -4
  97. package/src/forms-app-menu-link.tsx +5 -7
  98. package/src/forms-page/FormsPage.tsx +48 -37
  99. package/src/forms-page/forms-table/FormsTable.tsx +117 -0
  100. package/src/forms-page/forms-table/index.ts +3 -0
  101. package/src/forms-page/forms-table/styles.scss +19 -0
  102. package/src/forms-page/index.ts +1 -1
  103. package/src/forms-page/styles.scss +3 -5
  104. package/src/group-form-entry-workflow/GroupFormEntryWorkflow.tsx +26 -0
  105. package/src/group-form-entry-workflow/GroupSessionWorkspace.tsx +207 -0
  106. package/src/group-form-entry-workflow/SessionDetailsForm.tsx +154 -0
  107. package/src/group-form-entry-workflow/SessionMetaWorkspace.tsx +99 -0
  108. package/src/group-form-entry-workflow/attendance-table/AttendanceTable.tsx +130 -0
  109. package/src/group-form-entry-workflow/attendance-table/index.ts +1 -0
  110. package/src/group-form-entry-workflow/configurable-questions/ConfigurableQuestionsSection.tsx +41 -0
  111. package/src/group-form-entry-workflow/group-display-header/GroupDisplayHeader.test.tsx +9 -0
  112. package/src/group-form-entry-workflow/group-display-header/GroupDisplayHeader.tsx +55 -0
  113. package/src/group-form-entry-workflow/group-display-header/index.ts +3 -0
  114. package/src/group-form-entry-workflow/group-display-header/styles.scss +60 -0
  115. package/src/group-form-entry-workflow/group-search/CompactGroupResults.tsx +128 -0
  116. package/src/group-form-entry-workflow/group-search/CompactGroupSearch.tsx +66 -0
  117. package/src/group-form-entry-workflow/group-search/GroupSearch.tsx +134 -0
  118. package/src/group-form-entry-workflow/group-search/compact-group-result.scss +63 -0
  119. package/src/group-form-entry-workflow/group-search/compact-group-search.scss +34 -0
  120. package/src/group-form-entry-workflow/group-search/group-search.scss +93 -0
  121. package/src/group-form-entry-workflow/group-search-header/GroupSearchHeader.tsx +72 -0
  122. package/src/group-form-entry-workflow/group-search-header/index.ts +3 -0
  123. package/src/group-form-entry-workflow/group-search-header/styles.scss +20 -0
  124. package/src/group-form-entry-workflow/index.ts +3 -0
  125. package/src/group-form-entry-workflow/styles.scss +94 -0
  126. package/src/hooks/index.ts +7 -5
  127. package/src/hooks/useForm.ts +56 -0
  128. package/src/hooks/useFormState.ts +3 -3
  129. package/src/hooks/useGetAllForms.ts +7 -15
  130. package/src/hooks/useGetEncounter.ts +3 -3
  131. package/src/hooks/useGetPatient.ts +3 -3
  132. package/src/hooks/useGetPatients.ts +32 -0
  133. package/src/hooks/useGetSystemSetting.ts +36 -0
  134. package/src/hooks/useKeyPress.ts +31 -0
  135. package/src/hooks/usePostEndpoint.ts +76 -0
  136. package/src/hooks/useSearchEndpoint.ts +103 -0
  137. package/src/hooks/useStartVisit.ts +82 -0
  138. package/src/index.ts +12 -72
  139. package/src/patient-card/PatientCard.tsx +10 -20
  140. package/src/patient-card/index.ts +1 -1
  141. package/src/patient-card/styles.scss +8 -8
  142. package/src/routes.json +24 -0
  143. package/src/setup-tests.ts +1 -1
  144. package/src/types.ts +20 -0
  145. package/tools/i18next-parser.config.js +93 -0
  146. package/translations/am.json +75 -0
  147. package/translations/ar.json +75 -0
  148. package/translations/en.json +57 -2
  149. package/translations/es.json +75 -0
  150. package/translations/fr.json +75 -0
  151. package/translations/he.json +75 -0
  152. package/translations/km.json +75 -0
  153. package/turbo.json +18 -0
  154. package/webpack.config.js +1 -1
  155. package/.editorconfig +0 -12
  156. package/.eslintignore +0 -2
  157. package/.eslintrc.js +0 -10
  158. package/.github/pull_request_template.md +0 -18
  159. package/.github/workflows/node.js.yml +0 -121
  160. package/.husky/pre-push +0 -1
  161. package/.prettierignore +0 -14
  162. package/dist/187.js +0 -1
  163. package/dist/247.js +0 -1
  164. package/dist/294.js +0 -2
  165. package/dist/312.js +0 -1
  166. package/dist/412.js +0 -1
  167. package/dist/536.js +0 -2
  168. package/dist/574.js +0 -1
  169. package/dist/592.js +0 -1
  170. package/dist/595.js +0 -2
  171. package/dist/595.js.LICENSE.txt +0 -1
  172. package/dist/776.js +0 -1
  173. package/dist/804.js +0 -1
  174. package/dist/880.js +0 -2
  175. package/dist/880.js.LICENSE.txt +0 -20
  176. package/dist/906.js +0 -1
  177. package/dist/935.js +0 -2
  178. package/dist/990.js +0 -1
  179. package/dist/openmrs-esm-fast-data-entry-app.old +0 -1
  180. package/src/declarations.d.tsx +0 -2
  181. package/src/form-review-card/index.ts +0 -3
  182. package/src/form-review-card/styles.scss +0 -38
  183. package/src/forms-table/FormsTable.tsx +0 -123
  184. package/src/forms-table/index.ts +0 -3
  185. package/src/forms-table/styles.scss +0 -20
  186. package/src/patient-banner/PatientBanner.test.tsx +0 -9
  187. package/src/patient-banner/index.ts +0 -3
  188. package/src/patient-banner/styles.scss +0 -44
  189. package/src/patient-search-header/PatientSearchHeader.tsx +0 -61
  190. package/src/patient-search-header/index.ts +0 -3
  191. package/src/patient-search-header/styles.scss +0 -21
  192. package/src/workflow-review/WorkflowReview.tsx +0 -35
  193. package/src/workflow-review/index.ts +0 -3
@@ -1,14 +1,14 @@
1
- import { navigate } from "@openmrs/esm-framework";
2
- import { initialWorkflowState } from "./FormWorkflowContext";
1
+ import { navigate } from '@openmrs/esm-framework';
2
+ import { initialWorkflowState } from './FormWorkflowContext';
3
3
 
4
- export const fdeWorkflowStorageVersion = "1.0.12";
5
- export const fdeWorkflowStorageName = "openmrs:fastDataEntryWorkflowState";
4
+ export const fdeWorkflowStorageVersion = '1.1.0';
5
+ export const fdeWorkflowStorageName = 'openmrs:fastDataEntryWorkflowState';
6
6
  const persistData = (data) => {
7
- localStorage.setItem(fdeWorkflowStorageName, JSON.stringify(data));
7
+ localStorage.setItem(fdeWorkflowStorageName + ':' + data.userUuid, JSON.stringify(data));
8
8
  };
9
9
 
10
10
  const initialFormState = {
11
- workflowState: "NEW_PATIENT",
11
+ workflowState: 'NEW_PATIENT',
12
12
  activePatientUuid: null,
13
13
  activeEncounterUuid: null,
14
14
  patientUuids: [],
@@ -17,21 +17,18 @@ const initialFormState = {
17
17
 
18
18
  const reducer = (state, action) => {
19
19
  switch (action.type) {
20
- case "INITIALIZE_WORKFLOW_STATE": {
21
- const savedData = localStorage.getItem(fdeWorkflowStorageName);
20
+ case 'INITIALIZE_WORKFLOW_STATE': {
21
+ const savedData = localStorage.getItem(fdeWorkflowStorageName + ':' + action.userUuid);
22
22
  const savedDataObject = savedData ? JSON.parse(savedData) : {};
23
23
  let newState: { [key: string]: unknown } = {};
24
24
  const newPatient = action.newPatientUuid
25
25
  ? {
26
26
  activePatientUuid: action.newPatientUuid,
27
- workflowState: "EDIT_FORM",
27
+ workflowState: 'EDIT_FORM',
28
28
  }
29
29
  : {};
30
30
 
31
- if (
32
- savedData &&
33
- savedDataObject["_storageVersion"] === fdeWorkflowStorageVersion
34
- ) {
31
+ if (savedData && savedDataObject['_storageVersion'] === fdeWorkflowStorageVersion) {
35
32
  // there is localStorage data and it is still valid
36
33
  newState = {
37
34
  ...savedDataObject,
@@ -44,21 +41,15 @@ const reducer = (state, action) => {
44
41
  ...savedDataObject.forms[action.activeFormUuid],
45
42
  // if we receive activePatientUuid from a query parameter use that one
46
43
  ...newPatient,
47
- patientUuids:
48
- savedDataObject.forms[action.activeFormUuid]?.patientUuids ||
49
- initialFormState.patientUuids,
44
+ patientUuids: savedDataObject.forms[action.activeFormUuid]?.patientUuids || initialFormState.patientUuids,
50
45
  },
51
46
  },
52
47
  };
53
48
  if (
54
49
  action.newPatientUuid &&
55
- !newState.forms[action.activeFormUuid].patientUuids.includes(
56
- action.newPatientUuid
57
- )
50
+ !newState.forms[action.activeFormUuid].patientUuids.includes(action.newPatientUuid)
58
51
  ) {
59
- newState.forms[action.activeFormUuid].patientUuids.push(
60
- action.newPatientUuid
61
- );
52
+ newState.forms[action.activeFormUuid].patientUuids.push(action.newPatientUuid);
62
53
  }
63
54
  } else {
64
55
  // no localStorage data, or we should void it
@@ -69,32 +60,30 @@ const reducer = (state, action) => {
69
60
  [action.activeFormUuid]: initialFormState,
70
61
  },
71
62
  activeFormUuid: action.activeFormUuid,
63
+ userUuid: action.userUuid,
72
64
  };
73
65
  }
74
66
  persistData(newState);
75
67
  return { ...newState };
76
68
  }
77
- case "ADD_PATIENT": {
69
+ case 'ADD_PATIENT': {
78
70
  const newState = {
79
71
  ...state,
80
72
  forms: {
81
73
  ...state.forms,
82
74
  [state.activeFormUuid]: {
83
75
  ...state.forms[state.activeFormUuid],
84
- patientUuids: [
85
- ...state.forms[state.activeFormUuid].patientUuids,
86
- action.patientUuid,
87
- ],
76
+ patientUuids: [...state.forms[state.activeFormUuid].patientUuids, action.patientUuid],
88
77
  activePatientUuid: action.patientUuid,
89
78
  activeEncounterUuid: null,
90
- workflowState: "EDIT_FORM",
79
+ workflowState: 'EDIT_FORM',
91
80
  },
92
81
  },
93
82
  };
94
83
  persistData(newState);
95
84
  return newState;
96
85
  }
97
- case "OPEN_PATIENT_SEARCH": {
86
+ case 'OPEN_PATIENT_SEARCH': {
98
87
  const newState = {
99
88
  ...state,
100
89
  forms: {
@@ -103,7 +92,7 @@ const reducer = (state, action) => {
103
92
  ...state.forms[state.activeFormUuid],
104
93
  activePatientUuid: null,
105
94
  activeEncounterUuid: null,
106
- workflowState: "NEW_PATIENT",
95
+ workflowState: 'NEW_PATIENT',
107
96
  },
108
97
  },
109
98
  };
@@ -111,11 +100,8 @@ const reducer = (state, action) => {
111
100
  persistData(newState);
112
101
  return newState;
113
102
  }
114
- case "SAVE_ENCOUNTER": {
115
- if (
116
- state.forms[state.activeFormUuid].workflowState ===
117
- "SUBMIT_FOR_COMPLETE"
118
- ) {
103
+ case 'SAVE_ENCOUNTER': {
104
+ if (state.forms[state.activeFormUuid].workflowState === 'SUBMIT_FOR_COMPLETE') {
119
105
  const { [state.activeFormUuid]: activeForm, ...formRest } = state.forms;
120
106
  const newState = {
121
107
  ...state,
@@ -124,7 +110,7 @@ const reducer = (state, action) => {
124
110
  };
125
111
  persistData(newState);
126
112
  // eslint-disable-next-line
127
- navigate({ to: "${openmrsSpaBase}/forms" });
113
+ navigate({ to: '${openmrsSpaBase}/forms' });
128
114
  return newState;
129
115
  } else {
130
116
  const newState = {
@@ -135,18 +121,15 @@ const reducer = (state, action) => {
135
121
  ...state.forms[state.activeFormUuid],
136
122
  encounters: {
137
123
  ...state.forms[state.activeFormUuid].encounters,
138
- [state.forms[state.activeFormUuid].activePatientUuid]:
139
- action.encounterUuid,
124
+ [state.forms[state.activeFormUuid].activePatientUuid]: action.encounterUuid,
140
125
  },
141
126
  activePatientUuid: null,
142
127
  activeEncounterUuid: null,
143
128
  workflowState:
144
- state.forms[state.activeFormUuid].workflowState ===
145
- "SUBMIT_FOR_NEXT"
146
- ? "NEW_PATIENT"
147
- : state.forms[state.activeFormUuid].workflowState ===
148
- "SUBMIT_FOR_REVIEW"
149
- ? "REVIEW"
129
+ state.forms[state.activeFormUuid].workflowState === 'SUBMIT_FOR_NEXT'
130
+ ? 'NEW_PATIENT'
131
+ : state.forms[state.activeFormUuid].workflowState === 'SUBMIT_FOR_REVIEW'
132
+ ? 'REVIEW'
150
133
  : state.forms[state.activeFormUuid].workflowState,
151
134
  },
152
135
  },
@@ -155,33 +138,32 @@ const reducer = (state, action) => {
155
138
  return newState;
156
139
  }
157
140
  }
158
- case "EDIT_ENCOUNTER": {
141
+ case 'EDIT_ENCOUNTER': {
159
142
  const newState = {
160
143
  ...state,
161
144
  forms: {
162
145
  ...state.forms,
163
146
  [state.activeFormUuid]: {
164
147
  ...state.forms[state.activeFormUuid],
165
- activeEncounterUuid:
166
- state.forms[state.activeFormUuid].encounters[action.patientUuid],
148
+ activeEncounterUuid: state.forms[state.activeFormUuid].encounters[action.patientUuid],
167
149
  activePatientUuid: action.patientUuid,
168
- workflowState: "EDIT_FORM",
150
+ workflowState: 'EDIT_FORM',
169
151
  },
170
152
  },
171
153
  };
172
154
  persistData(newState);
173
155
  return newState;
174
156
  }
175
- case "SUBMIT_FOR_NEXT":
157
+ case 'SUBMIT_FOR_NEXT':
176
158
  // this state should not be persisted
177
159
  window.dispatchEvent(
178
- new CustomEvent("ampath-form-action", {
160
+ new CustomEvent('ampath-form-action', {
179
161
  detail: {
180
162
  formUuid: state.activeFormUuid,
181
163
  patientUuid: state.forms[state.activeFormUuid].activePatientUuid,
182
- action: "onSubmit",
164
+ action: 'onSubmit',
183
165
  },
184
- })
166
+ }),
185
167
  );
186
168
  return {
187
169
  ...state,
@@ -189,20 +171,20 @@ const reducer = (state, action) => {
189
171
  ...state.forms,
190
172
  [state.activeFormUuid]: {
191
173
  ...state.forms[state.activeFormUuid],
192
- workflowState: "SUBMIT_FOR_NEXT",
174
+ workflowState: 'SUBMIT_FOR_NEXT',
193
175
  },
194
176
  },
195
177
  };
196
- case "SUBMIT_FOR_REVIEW":
178
+ case 'SUBMIT_FOR_REVIEW':
197
179
  // this state should not be persisted
198
180
  window.dispatchEvent(
199
- new CustomEvent("ampath-form-action", {
181
+ new CustomEvent('ampath-form-action', {
200
182
  detail: {
201
183
  formUuid: state.activeFormUuid,
202
184
  patientUuid: state.forms[state.activeFormUuid].activePatientUuid,
203
- action: "onSubmit",
185
+ action: 'onSubmit',
204
186
  },
205
- })
187
+ }),
206
188
  );
207
189
  return {
208
190
  ...state,
@@ -210,20 +192,20 @@ const reducer = (state, action) => {
210
192
  ...state.forms,
211
193
  [state.activeFormUuid]: {
212
194
  ...state.forms[state.activeFormUuid],
213
- workflowState: "SUBMIT_FOR_REVIEW",
195
+ workflowState: 'SUBMIT_FOR_REVIEW',
214
196
  },
215
197
  },
216
198
  };
217
- case "SUBMIT_FOR_COMPLETE":
199
+ case 'SUBMIT_FOR_COMPLETE':
218
200
  // this state should not be persisted
219
201
  window.dispatchEvent(
220
- new CustomEvent("ampath-form-action", {
202
+ new CustomEvent('ampath-form-action', {
221
203
  detail: {
222
204
  formUuid: state.activeFormUuid,
223
205
  patientUuid: state.forms[state.activeFormUuid].activePatientUuid,
224
- action: "onSubmit",
206
+ action: 'onSubmit',
225
207
  },
226
- })
208
+ }),
227
209
  );
228
210
  return {
229
211
  ...state,
@@ -231,11 +213,11 @@ const reducer = (state, action) => {
231
213
  ...state.forms,
232
214
  [state.activeFormUuid]: {
233
215
  ...state.forms[state.activeFormUuid],
234
- workflowState: "SUBMIT_FOR_COMPLETE",
216
+ workflowState: 'SUBMIT_FOR_COMPLETE',
235
217
  },
236
218
  },
237
219
  };
238
- case "GO_TO_REVIEW": {
220
+ case 'GO_TO_REVIEW': {
239
221
  const newState = {
240
222
  ...state,
241
223
  forms: {
@@ -244,14 +226,14 @@ const reducer = (state, action) => {
244
226
  ...state.forms[state.activeFormUuid],
245
227
  activeEncounterUuid: null,
246
228
  activePatientUuid: null,
247
- workflowState: "REVIEW",
229
+ workflowState: 'REVIEW',
248
230
  },
249
231
  },
250
232
  };
251
233
  persistData(newState);
252
234
  return newState;
253
235
  }
254
- case "DESTROY_SESSION": {
236
+ case 'DESTROY_SESSION': {
255
237
  const { [state.activeFormUuid]: activeForm, ...formRest } = state.forms;
256
238
  const newState = {
257
239
  ...state,
@@ -259,14 +241,18 @@ const reducer = (state, action) => {
259
241
  activeFormUuid: null,
260
242
  };
261
243
  persistData(newState);
244
+ //eslint-disable-next-line
245
+ navigate({ to: '${openmrsSpaBase}/forms' });
262
246
  return newState;
263
247
  }
264
- case "CLOSE_SESSION": {
248
+ case 'CLOSE_SESSION': {
265
249
  const newState = {
266
250
  ...state,
267
251
  activeFormUuid: null,
268
252
  };
269
253
  persistData(newState);
254
+ //eslint-disable-next-line
255
+ navigate({ to: '${openmrsSpaBase}/forms' });
270
256
  return newState;
271
257
  }
272
258
  default:
@@ -0,0 +1,155 @@
1
+ import React, { useEffect, useMemo, useReducer } from 'react';
2
+ import reducer from './GroupFormWorkflowReducer';
3
+ import { useParams } from 'react-router-dom';
4
+ import { type Type, useSession } from '@openmrs/esm-framework';
5
+ import useGetSystemSetting from '../hooks/useGetSystemSetting';
6
+ interface ParamTypes {
7
+ formUuid?: string;
8
+ }
9
+
10
+ export interface GroupType {
11
+ id: string;
12
+ name: string;
13
+ members: Array<Type.Object>;
14
+ }
15
+ export interface MetaType {
16
+ sessionName: string;
17
+ sessionDate: string;
18
+ practitionerName: string;
19
+ sessionNotes: string;
20
+ }
21
+
22
+ const initialActions = {
23
+ setGroup: (group: GroupType) => undefined,
24
+ unsetGroup: () => undefined,
25
+ setSessionMeta: (meta: MetaType) => undefined,
26
+ openPatientSearch: () => undefined,
27
+ saveEncounter: (encounterUuid: string | number) => undefined,
28
+ editEncounter: (patientUuid: string | number) => undefined,
29
+ validateForNext: () => undefined,
30
+ validateForComplete: () => undefined,
31
+ updateVisitUuid: (visitUuid: string) => undefined,
32
+ submitForNext: (nextPatientUuid: string = null) => undefined,
33
+ submitForReview: () => undefined,
34
+ submitForComplete: () => undefined,
35
+ addPatientUuid: (patientUuid: string) => undefined,
36
+ removePatientUuid: (patientUuid: string) => undefined,
37
+ goToReview: () => undefined,
38
+ destroySession: () => undefined,
39
+ closeSession: () => undefined,
40
+ };
41
+
42
+ export const initialWorkflowState = {
43
+ // activeFormUuid and forms are the only two real values stored at state root level
44
+ activeFormUuid: null, // the corrently open form
45
+ forms: {}, // object containing all forms session data
46
+ // the following fields will be available in context but are not stored at the
47
+ // state root level, but refer to nested values for the current
48
+ // aciveFormUuid
49
+ workflowState: null, // pseudo field from state[activeFormUuid].workflowState
50
+ activePatientUuid: null, // pseudo field from state[activeFormUuid].activePatientUuid
51
+ activeEncounterUuid: null, // pseudo field from state[activeFormUuid].activeEncounterUuid
52
+ activeSessionUuid: null, // pseudo field from state[activeFormUuid].activeSessionUuid
53
+ activeVisitUuid: null, // pseudo field from state[activeFormUuid].activeVisitUuid
54
+ patientUuids: [], // pseudo field from state[activeFormUuid].patientUuids
55
+ encounters: {}, // pseudo field from state[activeFormUuid].encounters
56
+ visits: {}, // pseudo field from state[activeFormUuid].visits
57
+ activeGroupUuid: null, // pseudo field from state[activeFormUuid].groupUuid
58
+ activeGroupName: null, // pseudo field from state[activeFormUuid].groupName
59
+ activeGroupMembers: [], // pseudo field from state[activeFormUuid].groupMembers
60
+ activeSessionMeta: {
61
+ sessionName: null,
62
+ practitionerName: null,
63
+ sessionDate: null,
64
+ sessionNotes: null,
65
+ },
66
+ groupVisitTypeUuid: null,
67
+ userUuid: null, // UUID of the user to which this workflow state belongs to
68
+ };
69
+
70
+ const GroupFormWorkflowContext = React.createContext({
71
+ ...initialWorkflowState,
72
+ ...initialActions,
73
+ });
74
+
75
+ const GroupFormWorkflowProvider = ({ children }) => {
76
+ const { user } = useSession();
77
+ const { formUuid } = useParams() as ParamTypes;
78
+ const activeFormUuid = formUuid.split('&')[0];
79
+ const systemSetting = useGetSystemSetting('@openmrs/esm-fast-data-entry-app.groupSessionVisitTypeUuid');
80
+ const groupVisitTypeUuid = systemSetting?.result?.data?.results?.[0]?.value;
81
+ const [state, dispatch] = useReducer(reducer, {
82
+ ...initialWorkflowState,
83
+ ...initialActions,
84
+ });
85
+
86
+ const actions = useMemo(
87
+ () => ({
88
+ initializeWorkflowState: ({ activeFormUuid }) =>
89
+ dispatch({
90
+ type: 'INITIALIZE_WORKFLOW_STATE',
91
+ activeFormUuid,
92
+ userUuid: user.uuid,
93
+ }),
94
+ setGroup: (group) => dispatch({ type: 'SET_GROUP', group }),
95
+ unsetGroup: () => dispatch({ type: 'UNSET_GROUP' }),
96
+ setSessionMeta: (meta) => dispatch({ type: 'SET_SESSION_META', meta }),
97
+ addPatientUuid: (patientUuid) => dispatch({ type: 'ADD_PATIENT_UUID', patientUuid }),
98
+ removePatientUuid: (patientUuid) => dispatch({ type: 'REMOVE_PATIENT_UUID', patientUuid }),
99
+ openPatientSearch: () => dispatch({ type: 'OPEN_PATIENT_SEARCH' }),
100
+ saveEncounter: (encounterUuid) =>
101
+ dispatch({
102
+ type: 'SAVE_ENCOUNTER',
103
+ encounterUuid,
104
+ }),
105
+ validateForNext: () => dispatch({ type: 'VALIDATE_FOR_NEXT' }),
106
+ validateForComplete: () => dispatch({ type: 'VALIDATE_FOR_COMPLETE' }),
107
+ updateVisitUuid: (visitUuid) => dispatch({ type: 'UPDATE_VISIT_UUID', visitUuid }),
108
+ submitForNext: (nextPatientUuid) => dispatch({ type: 'SUBMIT_FOR_NEXT', nextPatientUuid }),
109
+ submitForComplete: () => dispatch({ type: 'SUBMIT_FOR_COMPLETE' }),
110
+ editEncounter: (patientUuid) => dispatch({ type: 'EDIT_ENCOUNTER', patientUuid }),
111
+ goToReview: () => dispatch({ type: 'GO_TO_REVIEW' }),
112
+ destroySession: () => dispatch({ type: 'DESTROY_SESSION' }),
113
+ closeSession: () => dispatch({ type: 'CLOSE_SESSION' }),
114
+ }),
115
+ [user],
116
+ );
117
+
118
+ // if formUuid isn't a part of state yet, grab it from the url params
119
+ // this is the entry into the workflow system
120
+ useEffect(() => {
121
+ if (state?.workflowState === null && activeFormUuid) {
122
+ actions.initializeWorkflowState({ activeFormUuid });
123
+ }
124
+ }, [activeFormUuid, state?.workflowState, actions]);
125
+
126
+ return (
127
+ <GroupFormWorkflowContext.Provider
128
+ value={{
129
+ groupVisitTypeUuid,
130
+ ...state,
131
+ ...actions,
132
+ workflowState: state.forms?.[state.activeFormUuid]?.workflowState ?? initialWorkflowState.workflowState,
133
+ activeSessionUuid:
134
+ state.forms?.[state.activeFormUuid]?.activeSessionUuid ?? initialWorkflowState.activeSessionUuid,
135
+ activePatientUuid:
136
+ state.forms?.[state.activeFormUuid]?.activePatientUuid ?? initialWorkflowState.activePatientUuid,
137
+ activeEncounterUuid:
138
+ state.forms?.[state.activeFormUuid]?.activeEncounterUuid ?? initialWorkflowState.activeEncounterUuid,
139
+ activeVisitUuid: state.forms?.[state.activeFormUuid]?.activeVisitUuid ?? initialWorkflowState.activeVisitUuid,
140
+ patientUuids: state.forms?.[state.activeFormUuid]?.patientUuids ?? initialWorkflowState.patientUuids,
141
+ encounters: state.forms?.[state.activeFormUuid]?.encounters ?? initialWorkflowState.encounters,
142
+ activeGroupUuid: state.forms?.[state.activeFormUuid]?.groupUuid ?? initialWorkflowState.activeGroupUuid,
143
+ activeGroupName: state.forms?.[state.activeFormUuid]?.groupName ?? initialWorkflowState.activeGroupName,
144
+ activeGroupMembers:
145
+ state.forms?.[state.activeFormUuid]?.groupMembers ?? initialWorkflowState.activeGroupMembers,
146
+ activeSessionMeta: state.forms?.[state.activeFormUuid]?.sessionMeta ?? initialWorkflowState.activeSessionMeta,
147
+ }}
148
+ >
149
+ {children}
150
+ </GroupFormWorkflowContext.Provider>
151
+ );
152
+ };
153
+
154
+ export default GroupFormWorkflowContext;
155
+ export { GroupFormWorkflowProvider };