@openmrs/esm-fast-data-entry-app 1.0.1-pre.8 → 1.0.1-pre.82

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 (84) hide show
  1. package/README.md +21 -2
  2. package/dist/132.js +1 -0
  3. package/dist/168.js +1 -0
  4. package/dist/229.js +1 -0
  5. package/dist/247.js +1 -0
  6. package/dist/255.js +1 -0
  7. package/dist/294.js +2 -0
  8. package/dist/294.js.LICENSE.txt +9 -0
  9. package/dist/32.js +1 -0
  10. package/dist/327.js +1 -0
  11. package/dist/403.js +2 -0
  12. package/dist/403.js.LICENSE.txt +14 -0
  13. package/dist/553.js +2 -0
  14. package/dist/553.js.LICENSE.txt +14 -0
  15. package/dist/569.js +2 -0
  16. package/dist/569.js.LICENSE.txt +27 -0
  17. package/dist/574.js +1 -0
  18. package/dist/595.js +2 -0
  19. package/dist/595.js.LICENSE.txt +1 -0
  20. package/dist/617.js +1 -0
  21. package/dist/68.js +2 -0
  22. package/dist/68.js.LICENSE.txt +21 -0
  23. package/dist/74.js +1 -0
  24. package/dist/757.js +1 -0
  25. package/dist/776.js +1 -0
  26. package/dist/804.js +1 -0
  27. package/dist/820.js +1 -0
  28. package/dist/935.js +2 -0
  29. package/dist/935.js.LICENSE.txt +19 -0
  30. package/dist/main.js +1 -0
  31. package/dist/openmrs-esm-fast-data-entry-app.js +1 -1
  32. package/dist/openmrs-esm-fast-data-entry-app.js.buildmanifest.json +612 -0
  33. package/dist/openmrs-esm-fast-data-entry-app.old +1 -0
  34. package/package.json +9 -9
  35. package/src/CancelModal.tsx +48 -0
  36. package/src/CompleteModal.tsx +46 -0
  37. package/src/FormBootstrap.tsx +18 -3
  38. package/src/add-group-modal/AddGroupModal.tsx +80 -27
  39. package/src/add-group-modal/styles.scss +14 -4
  40. package/src/config-schema.ts +22 -0
  41. package/src/context/FormWorkflowContext.tsx +13 -1
  42. package/src/context/FormWorkflowReducer.ts +13 -3
  43. package/src/context/GroupFormWorkflowContext.tsx +41 -6
  44. package/src/context/GroupFormWorkflowReducer.ts +170 -12
  45. package/src/form-entry-workflow/FormEntryWorkflow.tsx +67 -101
  46. package/src/form-entry-workflow/styles.scss +2 -1
  47. package/src/forms-page/FormsPage.tsx +8 -3
  48. package/src/forms-page/forms-table/FormsTable.tsx +11 -5
  49. package/src/group-form-entry-workflow/GroupFormEntryWorkflow.tsx +13 -400
  50. package/src/group-form-entry-workflow/GroupSessionWorkspace.tsx +247 -0
  51. package/src/group-form-entry-workflow/SessionDetailsForm.tsx +122 -0
  52. package/src/group-form-entry-workflow/SessionMetaWorkspace.tsx +107 -0
  53. package/src/group-form-entry-workflow/attendance-table/AttendanceTable.tsx +105 -0
  54. package/src/group-form-entry-workflow/attendance-table/index.ts +1 -0
  55. package/src/group-form-entry-workflow/{group-banner/GroupBanner.test.tsx → group-display-header/GroupDisplayHeader.test.tsx} +2 -2
  56. package/src/group-form-entry-workflow/{group-banner/GroupBanner.tsx → group-display-header/GroupDisplayHeader.tsx} +23 -5
  57. package/src/group-form-entry-workflow/group-display-header/index.ts +3 -0
  58. package/src/group-form-entry-workflow/group-search/CompactGroupResults.tsx +61 -28
  59. package/src/group-form-entry-workflow/group-search/CompactGroupSearch.tsx +5 -0
  60. package/src/group-form-entry-workflow/group-search/GroupSearch.tsx +65 -8
  61. package/src/group-form-entry-workflow/group-search/group-search.scss +8 -6
  62. package/src/group-form-entry-workflow/group-search-header/GroupSearchHeader.tsx +11 -7
  63. package/src/group-form-entry-workflow/styles.scss +12 -1
  64. package/src/hooks/index.ts +1 -0
  65. package/src/hooks/useGetSystemSetting.ts +38 -0
  66. package/src/hooks/usePostEndpoint.ts +70 -0
  67. package/src/hooks/useSearchEndpoint.ts +120 -0
  68. package/src/hooks/useStartVisit.ts +92 -0
  69. package/src/patient-card/styles.scss +1 -0
  70. package/tools/i18next-parser.config.js +93 -0
  71. package/translations/en.json +27 -9
  72. package/translations/fr.json +50 -0
  73. package/.editorconfig +0 -12
  74. package/.eslintignore +0 -2
  75. package/.eslintrc.js +0 -10
  76. package/.husky/pre-push +0 -1
  77. package/.prettierignore +0 -14
  78. package/.yarn/plugins/@yarnpkg/plugin-version.cjs +0 -550
  79. package/.yarn/versions/7ee3eceb.yml +0 -0
  80. package/src/group-form-entry-workflow/group-banner/index.ts +0 -3
  81. package/src/group-form-entry-workflow/group-search/mock-group-data.ts +0 -79
  82. package/src/group-form-entry-workflow/group-search/useGroupSearch.ts +0 -14
  83. package/src/hooks/usePostCohort.ts +0 -18
  84. /package/src/group-form-entry-workflow/{group-banner → group-display-header}/styles.scss +0 -0
@@ -5,23 +5,31 @@ export const fdeGroupWorkflowStorageVersion = "1.0.5";
5
5
  export const fdeGroupWorkflowStorageName =
6
6
  "openmrs:fastDataEntryGroupWorkflowState";
7
7
  const persistData = (data) => {
8
- localStorage.setItem(fdeGroupWorkflowStorageName, JSON.stringify(data));
8
+ localStorage.setItem(
9
+ fdeGroupWorkflowStorageName + ":" + data.userUuid,
10
+ JSON.stringify(data)
11
+ );
9
12
  };
10
13
 
11
14
  const initialFormState = {
12
15
  workflowState: "NEW_GROUP_SESSION",
13
16
  groupUuid: null,
14
17
  groupName: null,
18
+ groupMembers: [],
15
19
  activePatientUuid: null,
16
20
  activeEncounterUuid: null,
21
+ activeVisitUuid: null,
17
22
  patientUuids: [],
18
23
  encounters: {},
24
+ visits: {},
19
25
  };
20
26
 
21
27
  const reducer = (state, action) => {
22
28
  switch (action.type) {
23
29
  case "INITIALIZE_WORKFLOW_STATE": {
24
- const savedData = localStorage.getItem(fdeGroupWorkflowStorageName);
30
+ const savedData = localStorage.getItem(
31
+ fdeGroupWorkflowStorageName + ":" + action.userUuid
32
+ );
25
33
  const savedDataObject = savedData ? JSON.parse(savedData) : {};
26
34
  let newState: { [key: string]: unknown } = {};
27
35
  if (
@@ -50,6 +58,8 @@ const reducer = (state, action) => {
50
58
  activePatientUuid: activePatientUuid,
51
59
  activeEncounterUuid:
52
60
  thisSavedForm?.encounters?.[activePatientUuid] || null,
61
+ activeVisitUuid:
62
+ thisSavedForm?.visits?.[activePatientUuid] || null,
53
63
  },
54
64
  },
55
65
  };
@@ -62,6 +72,7 @@ const reducer = (state, action) => {
62
72
  [action.activeFormUuid]: initialFormState,
63
73
  },
64
74
  activeFormUuid: action.activeFormUuid,
75
+ userUuid: action.userUuid,
65
76
  };
66
77
  }
67
78
  persistData(newState);
@@ -75,11 +86,42 @@ const reducer = (state, action) => {
75
86
  ...state.forms,
76
87
  [state.activeFormUuid]: {
77
88
  ...state.forms[state.activeFormUuid],
78
- groupUuid: action.group.id,
89
+ groupUuid: action.group.uuid,
79
90
  groupName: action.group.name,
80
- patientUuids: action.group.members.map((member) => member.uuid),
91
+ patientUuids:
92
+ // this translation is not preferred
93
+ // the only reason we tollerate it here is beause it should be the only time
94
+ // we add cohort information to state
95
+ action.group.cohortMembers?.map(
96
+ (member) => member?.patient?.uuid
97
+ ) ?? [],
98
+ groupMembers:
99
+ action.group.cohortMembers?.map(
100
+ (member) => member?.patient?.uuid
101
+ ) ?? [],
102
+ activePatientUuid: null,
103
+ activeEncounterUuid: null,
104
+ activeVisitUuid: null,
105
+ },
106
+ },
107
+ };
108
+ persistData(newState);
109
+ return newState;
110
+ }
111
+ case "UNSET_GROUP": {
112
+ const newState = {
113
+ ...state,
114
+ forms: {
115
+ ...state.forms,
116
+ [state.activeFormUuid]: {
117
+ ...state.forms[state.activeFormUuid],
118
+ groupUuid: null,
119
+ groupName: null,
120
+ patientUuids: [],
121
+ groupMembers: [],
81
122
  activePatientUuid: null,
82
123
  activeEncounterUuid: null,
124
+ activeVisitUuid: null,
83
125
  },
84
126
  },
85
127
  };
@@ -101,6 +143,10 @@ const reducer = (state, action) => {
101
143
  state.forms[state.activeFormUuid].encounters[
102
144
  state.forms[state.activeFormUuid].patientUuids?.[0]
103
145
  ] || null,
146
+ activeVisitUuid:
147
+ state.forms[state.activeFormUuid].visits[
148
+ state.forms[state.activeFormUuid].patientUuids?.[0]
149
+ ] || null,
104
150
  workflowState: "EDIT_FORM",
105
151
  },
106
152
  },
@@ -108,7 +154,47 @@ const reducer = (state, action) => {
108
154
  persistData(newState);
109
155
  return newState;
110
156
  }
157
+ case "ADD_PATIENT_UUID": {
158
+ if (
159
+ state.forms[state.activeFormUuid].patientUuids.includes(
160
+ action.patientUuid
161
+ )
162
+ ) {
163
+ return state;
164
+ }
111
165
 
166
+ const newState = {
167
+ ...state,
168
+ forms: {
169
+ ...state.forms,
170
+ [state.activeFormUuid]: {
171
+ ...state.forms[state.activeFormUuid],
172
+ patientUuids: [
173
+ ...state.forms[state.activeFormUuid].patientUuids,
174
+ action.patientUuid,
175
+ ],
176
+ },
177
+ },
178
+ };
179
+ persistData(newState);
180
+ return newState;
181
+ }
182
+ case "REMOVE_PATIENT_UUID": {
183
+ const newState = {
184
+ ...state,
185
+ forms: {
186
+ ...state.forms,
187
+ [state.activeFormUuid]: {
188
+ ...state.forms[state.activeFormUuid],
189
+ patientUuids: state.forms[
190
+ state.activeFormUuid
191
+ ].patientUuids?.filter((uuid) => action.patientUuid !== uuid),
192
+ },
193
+ },
194
+ };
195
+ persistData(newState);
196
+ return newState;
197
+ }
112
198
  case "SAVE_ENCOUNTER": {
113
199
  const thisForm = state.forms[state.activeFormUuid];
114
200
  if (thisForm.workflowState === "SUBMIT_FOR_COMPLETE") {
@@ -123,13 +209,14 @@ const reducer = (state, action) => {
123
209
  navigate({ to: "${openmrsSpaBase}/forms" });
124
210
  return newState;
125
211
  } else if (thisForm.workflowState === "SUBMIT_FOR_NEXT") {
126
- const nextPatientUuid =
127
- thisForm.patientUuids[
128
- Math.min(
129
- thisForm.patientUuids.indexOf(thisForm.activePatientUuid) + 1,
130
- thisForm.patientUuids.length - 1
131
- )
132
- ];
212
+ const nextPatientUuid = state.nextPatientUuid
213
+ ? state.nextPatientUuid
214
+ : thisForm.patientUuids[
215
+ Math.min(
216
+ thisForm.patientUuids.indexOf(thisForm.activePatientUuid) + 1,
217
+ thisForm.patientUuids.length - 1
218
+ )
219
+ ];
133
220
  const newState = {
134
221
  ...state,
135
222
  forms: {
@@ -142,6 +229,7 @@ const reducer = (state, action) => {
142
229
  },
143
230
  activePatientUuid: nextPatientUuid,
144
231
  activeEncounterUuid: thisForm.encounters[nextPatientUuid] || null,
232
+ activeVisitUuid: thisForm.visits[nextPatientUuid] || null,
145
233
  workflowState: "EDIT_FORM",
146
234
  },
147
235
  },
@@ -159,6 +247,8 @@ const reducer = (state, action) => {
159
247
  ...state.forms[state.activeFormUuid],
160
248
  activeEncounterUuid:
161
249
  state.forms[state.activeFormUuid].encounters[action.patientUuid],
250
+ activeVisitUuid:
251
+ state.forms[state.activeFormUuid].visits[action.patientUuid],
162
252
  activePatientUuid: action.patientUuid,
163
253
  workflowState: "EDIT_FORM",
164
254
  },
@@ -167,6 +257,46 @@ const reducer = (state, action) => {
167
257
  persistData(newState);
168
258
  return newState;
169
259
  }
260
+ case "VALIDATE_FOR_NEXT":
261
+ // this state should not be persisted
262
+ window.dispatchEvent(
263
+ new CustomEvent("ampath-form-action", {
264
+ detail: {
265
+ formUuid: state.activeFormUuid,
266
+ patientUuid: state.forms[state.activeFormUuid].activePatientUuid,
267
+ action: "validateForm",
268
+ },
269
+ })
270
+ );
271
+ return {
272
+ ...state,
273
+ forms: {
274
+ ...state.forms,
275
+ [state.activeFormUuid]: {
276
+ ...state.forms[state.activeFormUuid],
277
+ workflowState: "VALIDATE_FOR_NEXT",
278
+ },
279
+ },
280
+ };
281
+ case "UPDATE_VISIT_UUID":
282
+ // this state should not be persisted
283
+ // we don't pers
284
+ return {
285
+ ...state,
286
+ forms: {
287
+ ...state.forms,
288
+ [state.activeFormUuid]: {
289
+ ...state.forms[state.activeFormUuid],
290
+ visits: {
291
+ ...state.forms[state.activeFormUuid].visits,
292
+ [state.forms[state.activeFormUuid].activePatientUuid]:
293
+ action.visitUuid,
294
+ },
295
+ activeVisitUuid: action.visitUuid,
296
+ },
297
+ },
298
+ };
299
+
170
300
  case "SUBMIT_FOR_NEXT":
171
301
  // this state should not be persisted
172
302
  window.dispatchEvent(
@@ -187,6 +317,7 @@ const reducer = (state, action) => {
187
317
  workflowState: "SUBMIT_FOR_NEXT",
188
318
  },
189
319
  },
320
+ nextPatientUuid: action.nextPatientUuid,
190
321
  };
191
322
  case "SUBMIT_FOR_REVIEW":
192
323
  // this state should not be persisted
@@ -209,6 +340,28 @@ const reducer = (state, action) => {
209
340
  },
210
341
  },
211
342
  };
343
+
344
+ case "VALIDATE_FOR_COMPLETE":
345
+ // this state should not be persisted
346
+ window.dispatchEvent(
347
+ new CustomEvent("ampath-form-action", {
348
+ detail: {
349
+ formUuid: state.activeFormUuid,
350
+ patientUuid: state.forms[state.activeFormUuid].activePatientUuid,
351
+ action: "validateForm",
352
+ },
353
+ })
354
+ );
355
+ return {
356
+ ...state,
357
+ forms: {
358
+ ...state.forms,
359
+ [state.activeFormUuid]: {
360
+ ...state.forms[state.activeFormUuid],
361
+ workflowState: "VALIDATE_FOR_COMPLETE",
362
+ },
363
+ },
364
+ };
212
365
  case "SUBMIT_FOR_COMPLETE":
213
366
  // this state should not be persisted
214
367
  window.dispatchEvent(
@@ -238,6 +391,7 @@ const reducer = (state, action) => {
238
391
  [state.activeFormUuid]: {
239
392
  ...state.forms[state.activeFormUuid],
240
393
  activeEncounterUuid: null,
394
+ activVisitUuid: null,
241
395
  activePatientUuid: null,
242
396
  workflowState: "REVIEW",
243
397
  },
@@ -254,7 +408,9 @@ const reducer = (state, action) => {
254
408
  activeFormUuid: null,
255
409
  };
256
410
  persistData(newState);
257
- return newState;
411
+ //eslint-disable-next-line
412
+ navigate({ to: "${openmrsSpaBase}/forms" });
413
+ return { ...newState, formDestroyed: true };
258
414
  }
259
415
  case "CLOSE_SESSION": {
260
416
  const newState = {
@@ -262,6 +418,8 @@ const reducer = (state, action) => {
262
418
  activeFormUuid: null,
263
419
  };
264
420
  persistData(newState);
421
+ //eslint-disable-next-line
422
+ navigate({ to: "${openmrsSpaBase}/forms" });
265
423
  return newState;
266
424
  }
267
425
  default:
@@ -1,17 +1,6 @@
1
- import {
2
- ExtensionSlot,
3
- getGlobalStore,
4
- useStore,
5
- } from "@openmrs/esm-framework";
6
- import {
7
- Button,
8
- ComposedModal,
9
- ModalBody,
10
- ModalFooter,
11
- ModalHeader,
12
- } from "@carbon/react";
13
- import React, { useContext, useState } from "react";
14
- import { useNavigate } from "react-router-dom";
1
+ import { ExtensionSlot, useSession } from "@openmrs/esm-framework";
2
+ import { Button } from "@carbon/react";
3
+ import React, { useCallback, useContext, useEffect, useState } from "react";
15
4
  import FormBootstrap from "../FormBootstrap";
16
5
  import PatientCard from "../patient-card/PatientCard";
17
6
  import styles from "./styles.scss";
@@ -22,86 +11,13 @@ import FormWorkflowContext, {
22
11
  } from "../context/FormWorkflowContext";
23
12
  import WorkflowReview from "./workflow-review";
24
13
  import PatientBanner from "./patient-banner";
25
-
26
- const formStore = getGlobalStore("ampath-form-state");
27
-
28
- const CancelModal = ({ open, setOpen }) => {
29
- const { destroySession, closeSession } = useContext(FormWorkflowContext);
30
- const { t } = useTranslation();
31
- const navigate = useNavigate();
32
-
33
- const discard = async () => {
34
- await destroySession();
35
- setOpen(false);
36
- navigate("../");
37
- };
38
-
39
- const saveAndClose = async () => {
40
- await closeSession();
41
- setOpen(false);
42
- navigate("../");
43
- };
44
-
45
- return (
46
- <ComposedModal open={open}>
47
- <ModalHeader>{t("areYouSure", "Are you sure?")}</ModalHeader>
48
- <ModalBody>
49
- {t(
50
- "cancelExplanation",
51
- "You will lose any unsaved changes on the current form. Do you want to discard the current session?"
52
- )}
53
- </ModalBody>
54
- <ModalFooter>
55
- <Button kind="secondary" onClick={() => setOpen(false)}>
56
- {t("cancel", "Cancel")}
57
- </Button>
58
- <Button kind="danger" onClick={discard}>
59
- {t("discard", "Discard")}
60
- </Button>
61
- <Button kind="primary" onClick={saveAndClose}>
62
- {t("saveSession", "Save Session")}
63
- </Button>
64
- </ModalFooter>
65
- </ComposedModal>
66
- );
67
- };
68
-
69
- const CompleteModal = ({ open, setOpen }) => {
70
- const { submitForComplete } = useContext(FormWorkflowContext);
71
- const { t } = useTranslation();
72
-
73
- const completeSession = () => {
74
- submitForComplete();
75
- setOpen(false);
76
- };
77
-
78
- return (
79
- <ComposedModal open={open}>
80
- <ModalHeader>{t("areYouSure", "Are you sure?")}</ModalHeader>
81
- <ModalBody>
82
- {t(
83
- "saveExplanation",
84
- "Do you want to save the current form and exit the workflow?"
85
- )}
86
- </ModalBody>
87
- <ModalFooter>
88
- <Button kind="secondary" onClick={() => setOpen(false)}>
89
- {t("cancel", "Cancel")}
90
- </Button>
91
- <Button kind="primary" onClick={completeSession}>
92
- {t("complete", "Complete")}
93
- </Button>
94
- </ModalFooter>
95
- </ComposedModal>
96
- );
97
- };
14
+ import CompleteModal from "../CompleteModal";
15
+ import CancelModal from "../CancelModal";
16
+ import useStartVisit from "../hooks/useStartVisit";
98
17
 
99
18
  const WorkflowNavigationButtons = () => {
100
- const { activeFormUuid, submitForNext, workflowState, destroySession } =
101
- useContext(FormWorkflowContext);
102
- const store = useStore(formStore);
103
- const formState = store[activeFormUuid];
104
- const navigationDisabled = formState !== "ready";
19
+ const context = useContext(FormWorkflowContext);
20
+ const { workflowState, destroySession } = context;
105
21
  const [cancelModalOpen, setCancelModalOpen] = useState(false);
106
22
  const [completeModalOpen, setCompleteModalOpen] = useState(false);
107
23
  const { t } = useTranslation();
@@ -111,13 +27,6 @@ const WorkflowNavigationButtons = () => {
111
27
  return (
112
28
  <>
113
29
  <div className={styles.rightPanelActionButtons}>
114
- <Button
115
- kind="primary"
116
- onClick={() => submitForNext()}
117
- disabled={navigationDisabled || workflowState === "NEW_PATIENT"}
118
- >
119
- {t("nextPatient", "Next Patient")}
120
- </Button>
121
30
  <Button
122
31
  kind="secondary"
123
32
  onClick={
@@ -132,8 +41,16 @@ const WorkflowNavigationButtons = () => {
132
41
  {t("cancel", "Cancel")}
133
42
  </Button>
134
43
  </div>
135
- <CancelModal open={cancelModalOpen} setOpen={setCancelModalOpen} />
136
- <CompleteModal open={completeModalOpen} setOpen={setCompleteModalOpen} />
44
+ <CancelModal
45
+ open={cancelModalOpen}
46
+ setOpen={setCancelModalOpen}
47
+ context={context}
48
+ />
49
+ <CompleteModal
50
+ open={completeModalOpen}
51
+ setOpen={setCompleteModalOpen}
52
+ context={context}
53
+ />
137
54
  </>
138
55
  );
139
56
  };
@@ -147,15 +64,63 @@ const FormWorkspace = () => {
147
64
  activeFormUuid,
148
65
  editEncounter,
149
66
  encounters,
67
+ singleSessionVisitTypeUuid,
150
68
  } = useContext(FormWorkflowContext);
151
69
  const { t } = useTranslation();
152
70
 
71
+ const [encounter, setEncounter] = useState(null);
72
+ const [visit, setVisit] = useState(null);
73
+ const { sessionLocation } = useSession();
74
+
75
+ const {
76
+ saveVisit,
77
+ updateEncounter,
78
+ success: visitSaveSuccess,
79
+ } = useStartVisit({
80
+ showSuccessNotification: false,
81
+ showErrorNotification: true,
82
+ });
83
+
153
84
  const handlePostResponse = (encounter) => {
154
85
  if (encounter && encounter.uuid) {
155
86
  saveEncounter(encounter.uuid);
87
+ setEncounter(encounter);
156
88
  }
157
89
  };
158
90
 
91
+ useEffect(() => {
92
+ if (encounter && visit) {
93
+ // Update encounter so that it belongs to the created visit
94
+ updateEncounter({ uuid: encounter.uuid, visit: visit.uuid });
95
+ }
96
+ }, [encounter, visit, updateEncounter]);
97
+
98
+ useEffect(() => {
99
+ if (visitSaveSuccess) {
100
+ setVisit(visitSaveSuccess.data);
101
+ }
102
+ }, [visitSaveSuccess]);
103
+
104
+ const handleEncounterCreate = useCallback(
105
+ (payload) => {
106
+ payload.location = sessionLocation?.uuid;
107
+ payload.encounterDatetime = payload.encounterDatetime
108
+ ? payload.encounterDatetime
109
+ : new Date().toISOString();
110
+ // Create a visit with the same date as the encounter being saved
111
+ const visitStartDatetime = new Date(payload.encounterDatetime);
112
+ const visitStopDatetime = new Date(payload.encounterDatetime);
113
+ saveVisit({
114
+ patientUuid: activePatientUuid,
115
+ startDatetime: visitStartDatetime.toISOString(),
116
+ stopDatetime: visitStopDatetime.toISOString(),
117
+ visitType: singleSessionVisitTypeUuid,
118
+ location: sessionLocation?.uuid,
119
+ });
120
+ },
121
+ [activePatientUuid, singleSessionVisitTypeUuid, saveVisit, sessionLocation]
122
+ );
123
+
159
124
  return (
160
125
  <div className={styles.workspace}>
161
126
  {!patientUuids.length && (
@@ -172,6 +137,7 @@ const FormWorkspace = () => {
172
137
  {...{
173
138
  formUuid: activeFormUuid,
174
139
  handlePostResponse,
140
+ handleEncounterCreate,
175
141
  }}
176
142
  />
177
143
  </div>
@@ -36,6 +36,7 @@
36
36
  flex-grow: 1;
37
37
  max-height: calc(100vh - 14rem);
38
38
  overflow-y: scroll;
39
+ text-align: left;
39
40
  }
40
41
 
41
42
  .formContainer :global(.cds--form-item) :global(.question-area) {
@@ -43,7 +44,7 @@
43
44
  }
44
45
 
45
46
  .rightPanel {
46
- width: 13rem;
47
+ min-width: 13rem;
47
48
  text-align: left;
48
49
  overflow-y: scroll;
49
50
  }
@@ -1,4 +1,4 @@
1
- import { useConfig } from "@openmrs/esm-framework";
1
+ import { useConfig, useSession } from "@openmrs/esm-framework";
2
2
  import { Tab, Tabs, TabList, TabPanels, TabPanel } from "@carbon/react";
3
3
  import React from "react";
4
4
  import { Config } from "../config-schema";
@@ -49,8 +49,13 @@ const FormsPage = () => {
49
49
  const { formCategories, formCategoriesToShow } = config;
50
50
  const { forms, isLoading, error } = useGetAllForms();
51
51
  const cleanRows = prepareRowsForTable(forms);
52
- const savedFormsData = localStorage.getItem(fdeWorkflowStorageName);
53
- const savedGroupFormsData = localStorage.getItem(fdeGroupWorkflowStorageName);
52
+ const { user } = useSession();
53
+ const savedFormsData = localStorage.getItem(
54
+ fdeWorkflowStorageName + ":" + user?.uuid
55
+ );
56
+ const savedGroupFormsData = localStorage.getItem(
57
+ fdeGroupWorkflowStorageName + ":" + user?.uuid
58
+ );
54
59
  const activeForms = [];
55
60
  const activeGroupForms = [];
56
61
 
@@ -28,10 +28,11 @@ const FormsTable = ({
28
28
  }) => {
29
29
  const { t } = useTranslation();
30
30
 
31
- const formsHeader = [
31
+ const tableHeaders = [
32
32
  {
33
33
  key: "display",
34
34
  header: t("formName", "Form Name"),
35
+ isSortable: true,
35
36
  },
36
37
  {
37
38
  key: "actions",
@@ -43,7 +44,7 @@ const FormsTable = ({
43
44
  },
44
45
  ];
45
46
 
46
- const augmenteRows = rows?.map((row) => ({
47
+ const augmentedRows = rows?.map((row) => ({
47
48
  ...row,
48
49
  actions: (
49
50
  <Link to={`form/${row.uuid}`}>
@@ -70,7 +71,7 @@ const FormsTable = ({
70
71
  />
71
72
  );
72
73
  }
73
- if (augmenteRows.length === 0) {
74
+ if (augmentedRows.length === 0) {
74
75
  return (
75
76
  <EmptyState
76
77
  headerTitle={t("noFormsFound", "No Forms To Show")}
@@ -82,7 +83,7 @@ const FormsTable = ({
82
83
  );
83
84
  }
84
85
  return (
85
- <DataTable rows={augmenteRows} headers={formsHeader} isSortable>
86
+ <DataTable rows={augmentedRows} headers={tableHeaders}>
86
87
  {({
87
88
  rows,
88
89
  headers,
@@ -104,7 +105,12 @@ const FormsTable = ({
104
105
  <TableHead>
105
106
  <TableRow>
106
107
  {headers.map((header) => (
107
- <TableHeader {...getHeaderProps({ header })}>
108
+ <TableHeader
109
+ {...getHeaderProps({
110
+ header,
111
+ isSortable: header.isSortable,
112
+ })}
113
+ >
108
114
  {header.header}
109
115
  </TableHeader>
110
116
  ))}