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

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 (133) hide show
  1. package/.eslintrc.js +10 -0
  2. package/.husky/pre-push +1 -6
  3. package/.yarn/plugins/@yarnpkg/plugin-version.cjs +550 -0
  4. package/.yarn/versions/7ee3eceb.yml +0 -0
  5. package/README.md +39 -12
  6. package/dist/openmrs-esm-fast-data-entry-app.js +1 -1
  7. package/docs/config-icrc-forms.png +0 -0
  8. package/docs/config-other-forms.png +0 -0
  9. package/docs/configuring-form-categories.md +77 -0
  10. package/docs/fde-workflow.mov +0 -0
  11. package/docs/form-workflow-state-diagram.png +0 -0
  12. package/jest.config.json +20 -18
  13. package/package.json +97 -106
  14. package/src/FormBootstrap.tsx +151 -0
  15. package/src/Root.tsx +14 -3
  16. package/src/add-group-modal/AddGroupModal.tsx +209 -0
  17. package/src/add-group-modal/styles.scss +35 -0
  18. package/src/config-schema.ts +63 -31
  19. package/src/context/FormWorkflowContext.tsx +114 -0
  20. package/src/context/FormWorkflowReducer.ts +277 -0
  21. package/src/context/GroupFormWorkflowContext.tsx +141 -0
  22. package/src/context/GroupFormWorkflowReducer.ts +272 -0
  23. package/src/empty-state/EmptyDataIllustration.tsx +51 -0
  24. package/src/empty-state/EmptyState.tsx +33 -0
  25. package/src/empty-state/styles.scss +55 -0
  26. package/src/form-entry-workflow/FormEntryWorkflow.tsx +230 -0
  27. package/src/form-entry-workflow/form-review-card/FormReviewCard.tsx +50 -0
  28. package/src/form-entry-workflow/form-review-card/index.ts +3 -0
  29. package/src/form-entry-workflow/form-review-card/styles.scss +39 -0
  30. package/src/form-entry-workflow/index.ts +3 -0
  31. package/src/form-entry-workflow/patient-banner/PatientBanner.test.tsx +9 -0
  32. package/src/form-entry-workflow/patient-banner/PatientBanner.tsx +86 -0
  33. package/src/form-entry-workflow/patient-banner/index.ts +3 -0
  34. package/src/form-entry-workflow/patient-banner/styles.scss +45 -0
  35. package/src/form-entry-workflow/patient-search-header/PatientSearchHeader.tsx +63 -0
  36. package/src/form-entry-workflow/patient-search-header/index.ts +3 -0
  37. package/src/form-entry-workflow/patient-search-header/styles.scss +22 -0
  38. package/src/form-entry-workflow/styles.scss +64 -0
  39. package/src/form-entry-workflow/workflow-review/WorkflowReview.tsx +35 -0
  40. package/src/form-entry-workflow/workflow-review/index.ts +3 -0
  41. package/src/form-entry-workflow/workflow-review/styles.scss +34 -0
  42. package/src/forms-app-menu-link.tsx +3 -2
  43. package/src/forms-page/FormsPage.tsx +129 -0
  44. package/src/forms-page/forms-table/FormsTable.tsx +131 -0
  45. package/src/forms-page/forms-table/index.ts +3 -0
  46. package/src/forms-page/forms-table/styles.scss +20 -0
  47. package/src/forms-page/index.ts +3 -0
  48. package/src/forms-page/styles.scss +11 -0
  49. package/src/group-form-entry-workflow/GroupFormEntryWorkflow.tsx +413 -0
  50. package/src/group-form-entry-workflow/group-banner/GroupBanner.test.tsx +9 -0
  51. package/src/group-form-entry-workflow/group-banner/GroupBanner.tsx +45 -0
  52. package/src/group-form-entry-workflow/group-banner/index.ts +3 -0
  53. package/src/group-form-entry-workflow/group-banner/styles.scss +60 -0
  54. package/src/group-form-entry-workflow/group-search/CompactGroupResults.tsx +106 -0
  55. package/src/group-form-entry-workflow/group-search/CompactGroupSearch.tsx +63 -0
  56. package/src/group-form-entry-workflow/group-search/GroupSearch.tsx +93 -0
  57. package/src/group-form-entry-workflow/group-search/compact-group-result.scss +64 -0
  58. package/src/group-form-entry-workflow/group-search/compact-group-search.scss +35 -0
  59. package/src/group-form-entry-workflow/group-search/group-search.scss +94 -0
  60. package/src/group-form-entry-workflow/group-search/mock-group-data.ts +79 -0
  61. package/src/group-form-entry-workflow/group-search/useGroupSearch.ts +14 -0
  62. package/src/group-form-entry-workflow/group-search-header/GroupSearchHeader.tsx +42 -0
  63. package/src/group-form-entry-workflow/group-search-header/index.ts +3 -0
  64. package/src/group-form-entry-workflow/group-search-header/styles.scss +20 -0
  65. package/src/group-form-entry-workflow/index.ts +3 -0
  66. package/src/group-form-entry-workflow/styles.scss +86 -0
  67. package/src/hooks/index.ts +6 -0
  68. package/src/hooks/useFormState.ts +23 -0
  69. package/src/hooks/useGetAllForms.ts +45 -0
  70. package/src/hooks/useGetEncounter.ts +21 -0
  71. package/src/hooks/useGetPatient.ts +23 -0
  72. package/src/hooks/useKeyPress.ts +31 -0
  73. package/src/hooks/usePostCohort.ts +18 -0
  74. package/src/index.ts +20 -4
  75. package/src/patient-card/PatientCard.tsx +67 -0
  76. package/src/patient-card/index.ts +3 -0
  77. package/src/patient-card/styles.scss +45 -0
  78. package/translations/en.json +49 -4
  79. package/tsconfig.json +26 -23
  80. package/.eslintrc +0 -4
  81. package/.github/workflows/node.js.yml +0 -79
  82. package/.husky/pre-commit +0 -6
  83. package/dist/24.js +0 -3
  84. package/dist/24.js.LICENSE.txt +0 -16
  85. package/dist/24.js.map +0 -1
  86. package/dist/294.js +0 -3
  87. package/dist/294.js.LICENSE.txt +0 -14
  88. package/dist/294.js.map +0 -1
  89. package/dist/296.js +0 -2
  90. package/dist/296.js.map +0 -1
  91. package/dist/299.js +0 -2
  92. package/dist/299.js.map +0 -1
  93. package/dist/382.js +0 -3
  94. package/dist/382.js.LICENSE.txt +0 -8
  95. package/dist/382.js.map +0 -1
  96. package/dist/415.js +0 -2
  97. package/dist/415.js.map +0 -1
  98. package/dist/574.js +0 -1
  99. package/dist/595.js +0 -3
  100. package/dist/595.js.LICENSE.txt +0 -1
  101. package/dist/595.js.map +0 -1
  102. package/dist/69.js +0 -2
  103. package/dist/69.js.map +0 -1
  104. package/dist/735.js +0 -3
  105. package/dist/735.js.LICENSE.txt +0 -29
  106. package/dist/735.js.map +0 -1
  107. package/dist/777.js +0 -2
  108. package/dist/777.js.map +0 -1
  109. package/dist/860.js +0 -2
  110. package/dist/860.js.map +0 -1
  111. package/dist/906.js +0 -2
  112. package/dist/906.js.map +0 -1
  113. package/dist/openmrs-esm-fast-data-entry-app.js.buildmanifest.json +0 -369
  114. package/dist/openmrs-esm-fast-data-entry-app.js.map +0 -1
  115. package/dist/openmrs-esm-fast-data-entry-app.old +0 -2
  116. package/src/boxes/extensions/blue-box.tsx +0 -15
  117. package/src/boxes/extensions/box.scss +0 -23
  118. package/src/boxes/extensions/brand-box.tsx +0 -15
  119. package/src/boxes/extensions/red-box.tsx +0 -15
  120. package/src/boxes/slot/boxes.css +0 -23
  121. package/src/boxes/slot/boxes.tsx +0 -19
  122. package/src/forms/FormsRoot.tsx +0 -32
  123. package/src/forms/FormsTable.tsx +0 -64
  124. package/src/forms/mockData.ts +0 -43
  125. package/src/greeter/greeter.css +0 -4
  126. package/src/greeter/greeter.test.tsx +0 -29
  127. package/src/greeter/greeter.tsx +0 -25
  128. package/src/hello.css +0 -3
  129. package/src/hello.test.tsx +0 -45
  130. package/src/hello.tsx +0 -30
  131. package/src/patient-getter/patient-getter.resource.ts +0 -31
  132. package/src/patient-getter/patient-getter.test.tsx +0 -28
  133. package/src/patient-getter/patient-getter.tsx +0 -28
@@ -0,0 +1,209 @@
1
+ import React, { useCallback, useContext, useState } from "react";
2
+ import {
3
+ ComposedModal,
4
+ Button,
5
+ ModalHeader,
6
+ ModalFooter,
7
+ ModalBody,
8
+ TextInput,
9
+ FormLabel,
10
+ } from "@carbon/react";
11
+ import { Add, Close } from "@carbon/react/icons";
12
+ import { useTranslation } from "react-i18next";
13
+ import { ExtensionSlot } from "@openmrs/esm-framework";
14
+ import styles from "./styles.scss";
15
+ import GroupFormWorkflowContext from "../context/GroupFormWorkflowContext";
16
+
17
+ const MemExtension = React.memo(ExtensionSlot);
18
+
19
+ const PatientRow = ({ patient, removePatient }) => {
20
+ const { t } = useTranslation();
21
+ return (
22
+ <li key={patient.uuid} className={styles.patientRow}>
23
+ <span className={styles.patientName}>{patient?.display}</span>
24
+ <span>
25
+ <Button
26
+ kind="tertiary"
27
+ size="sm"
28
+ onClick={() => removePatient(patient.uuid)}
29
+ renderIcon={Close}
30
+ tooltipPosition="right"
31
+ >
32
+ {t("remove", "Remove")}
33
+ </Button>
34
+ </span>
35
+ </li>
36
+ );
37
+ };
38
+
39
+ const NewGroupForm = (props) => {
40
+ const {
41
+ name,
42
+ setName,
43
+ patientList,
44
+ updatePatientList,
45
+ errors,
46
+ validate,
47
+ removePatient,
48
+ } = props;
49
+ const { t } = useTranslation();
50
+
51
+ return (
52
+ <div
53
+ style={{
54
+ display: "flex",
55
+ flexDirection: "column",
56
+ rowGap: "1rem",
57
+ }}
58
+ >
59
+ <TextInput
60
+ labelText={t("newGroupName", "New Group Name")}
61
+ value={name}
62
+ onChange={(e) => setName(e.target.value)}
63
+ onBlur={() => validate("name")}
64
+ />
65
+ {errors?.name && (
66
+ <p className={styles.formError}>
67
+ {t("groupNameError", "Please enter a group name.")}
68
+ </p>
69
+ )}
70
+ <FormLabel>Patients in group</FormLabel>
71
+ {errors?.patientList && (
72
+ <p className={styles.formError}>
73
+ {t("noPatientError", "Please enter at least one patient.")}
74
+ </p>
75
+ )}
76
+ {!errors?.patientList && (
77
+ <ul>
78
+ {patientList?.map((patient, index) => (
79
+ <PatientRow
80
+ patient={patient}
81
+ removePatient={removePatient}
82
+ key={index}
83
+ />
84
+ ))}
85
+ </ul>
86
+ )}
87
+
88
+ <FormLabel>Search for patients to add to group</FormLabel>
89
+ <div className={styles.searchBar}>
90
+ <MemExtension
91
+ extensionSlotName="patient-search-bar-slot"
92
+ state={{
93
+ selectPatientAction: updatePatientList,
94
+ buttonProps: {
95
+ kind: "primary",
96
+ },
97
+ }}
98
+ />
99
+ </div>
100
+ </div>
101
+ );
102
+ };
103
+
104
+ const AddGroupModal = () => {
105
+ const { setGroup } = useContext(GroupFormWorkflowContext);
106
+ const { t } = useTranslation();
107
+ const [open, setOpen] = useState(false);
108
+ const [errors, setErrors] = useState({});
109
+ const [name, setName] = useState("");
110
+ const [patientList, setPatientList] = useState([]);
111
+
112
+ const handleCancel = () => {
113
+ setOpen(false);
114
+ };
115
+
116
+ const removePatient = useCallback(
117
+ (patientUuid: string) =>
118
+ setPatientList((patientList) =>
119
+ patientList.filter((patient) => patient.uuid !== patientUuid)
120
+ ),
121
+ [setPatientList]
122
+ );
123
+
124
+ const validate = useCallback(
125
+ (field?: string | undefined) => {
126
+ let valid = true;
127
+ if (field) {
128
+ valid = field === "name" ? !!name : !!patientList.length;
129
+ setErrors((errors) => ({
130
+ ...errors,
131
+ [field]: valid ? null : "required",
132
+ }));
133
+ } else {
134
+ if (!name) {
135
+ setErrors((errors) => ({ ...errors, name: "required" }));
136
+ valid = false;
137
+ } else {
138
+ setErrors((errors) => ({ ...errors, name: null }));
139
+ }
140
+ if (!patientList.length) {
141
+ setErrors((errors) => ({ ...errors, patientList: "required" }));
142
+ valid = false;
143
+ } else {
144
+ setErrors((errors) => ({ ...errors, patientList: null }));
145
+ }
146
+ }
147
+ return valid;
148
+ },
149
+ [name, patientList.length]
150
+ );
151
+
152
+ const updatePatientList = useCallback(
153
+ (patient) => {
154
+ setPatientList((patientList) => {
155
+ if (!patientList.find((p) => p.uuid === patient.uuid)) {
156
+ return [...patientList, patient];
157
+ } else {
158
+ return patientList;
159
+ }
160
+ });
161
+ setErrors((errors) => ({ ...errors, patientList: null }));
162
+ },
163
+ [setPatientList]
164
+ );
165
+
166
+ const handleSubmit = () => {
167
+ if (validate()) {
168
+ setGroup({ id: "1234", name: name, members: patientList });
169
+ }
170
+ };
171
+
172
+ return (
173
+ <div className={styles.modal}>
174
+ <Button
175
+ onClick={() => setOpen(true)}
176
+ renderIcon={Add}
177
+ iconDescription="Add"
178
+ >
179
+ {t("createNewGroup", "Create New Group")}
180
+ </Button>
181
+ <ComposedModal open={open} onClose={() => setOpen(false)}>
182
+ <ModalHeader>{t("createNewGroup", "Create New Group")}</ModalHeader>
183
+ <ModalBody>
184
+ <NewGroupForm
185
+ {...{
186
+ name,
187
+ setName,
188
+ patientList,
189
+ updatePatientList,
190
+ errors,
191
+ validate,
192
+ removePatient,
193
+ }}
194
+ />
195
+ </ModalBody>
196
+ <ModalFooter>
197
+ <Button kind="secondary" onClick={handleCancel}>
198
+ {t("cancel", "Cancel")}
199
+ </Button>
200
+ <Button kind="primary" onClick={handleSubmit}>
201
+ {t("createGroup", "Create Group")}
202
+ </Button>
203
+ </ModalFooter>
204
+ </ComposedModal>
205
+ </div>
206
+ );
207
+ };
208
+
209
+ export default AddGroupModal;
@@ -0,0 +1,35 @@
1
+ @use '@carbon/styles/scss/spacing';
2
+ @use '@carbon/colors';
3
+
4
+ .modal {
5
+ :global(.cds--modal) {
6
+ z-index: 90;
7
+ }
8
+ :global(.cds--modal-container) {
9
+ height: 600px;
10
+ }
11
+ :global(.cds--modal-content) {
12
+ height: 100%;
13
+ }
14
+ }
15
+
16
+ .searchBar > div > div > div {
17
+ width: 100%
18
+ }
19
+
20
+ .formError {
21
+ color: red;
22
+ }
23
+
24
+ .patientRow {
25
+ display: flex;
26
+ width: "100%";
27
+ }
28
+
29
+ .patientName {
30
+ flex-grow: 1;
31
+ padding: spacing.$spacing-02;
32
+ &:hover {
33
+ background-color: colors.$gray-20;
34
+ }
35
+ }
@@ -1,46 +1,78 @@
1
- import { Type, validator } from "@openmrs/esm-framework";
1
+ import { Type } from "@openmrs/esm-framework";
2
2
 
3
3
  /**
4
- * This is the config schema. It expects a configuration object which
5
- * looks like this:
4
+ * This is the config schema.
6
5
  *
7
- * ```json
8
- * { "casualGreeting": true, "whoToGreet": ["Mom"] }
9
- * ```
10
- *
11
- * In OpenMRS Microfrontends, all config parameters are optional. Thus,
12
- * all elements must have a reasonable default. A good default is one
13
- * that works well with the reference application.
14
- *
15
- * To understand the schema below, please read the configuration system
16
- * documentation:
17
- * https://openmrs.github.io/openmrs-esm-core/#/main/config
18
- * Note especially the section "How do I make my module configurable?"
19
- * https://openmrs.github.io/openmrs-esm-core/#/main/config?id=im-developing-an-esm-module-how-do-i-make-it-configurable
20
- * and the Schema Reference
21
- * https://openmrs.github.io/openmrs-esm-core/#/main/config?id=schema-reference
22
6
  */
7
+
23
8
  export const configSchema = {
24
- casualGreeting: {
25
- _type: Type.Boolean,
26
- _default: false,
27
- _description: "Whether to use a casual greeting (or a formal one).",
28
- },
29
- whoToGreet: {
9
+ formCategories: {
30
10
  _type: Type.Array,
31
- _default: ["World"],
32
11
  _description:
33
- "Who should be greeted. Names will be separated by a comma and space.",
12
+ "Organize forms into categories. A form can belong to multiple categories.",
34
13
  _elements: {
35
- _type: Type.String,
14
+ name: {
15
+ _type: Type.String,
16
+ _description: "Category name",
17
+ },
18
+ forms: {
19
+ _type: Type.Array,
20
+ _description: "List of forms for this category.",
21
+ _elements: {
22
+ formUUID: {
23
+ _type: Type.UUID,
24
+ _description: "UUID of form",
25
+ },
26
+ name: {
27
+ _type: Type.String,
28
+ _description: "Name of form",
29
+ },
30
+ },
31
+ },
36
32
  },
37
- _validators: [
38
- validator((v) => v.length > 0, "At least one person must be greeted."),
33
+ _default: [
34
+ {
35
+ name: "ICRC Forms",
36
+ forms: [
37
+ {
38
+ formUUID: "0cefb866-110c-4f16-af58-560932a1db1f",
39
+ name: "Adult Triage",
40
+ },
41
+ ],
42
+ },
43
+ {
44
+ name: "Distress Scales",
45
+ forms: [
46
+ {
47
+ formUUID: "9f26aad4-244a-46ca-be49-1196df1a8c9a",
48
+ name: "POC Sample Form 1",
49
+ },
50
+ ],
51
+ },
39
52
  ],
40
53
  },
54
+ formCategoriesToShow: {
55
+ _type: Type.Array,
56
+ _description: "Forms to show by default on the forms app home page.",
57
+ _elements: {
58
+ _type: Type.String,
59
+ _description: "Name of category",
60
+ },
61
+ _default: ["ICRC Forms", "Distress Scales"],
62
+ },
63
+ };
64
+
65
+ export type Form = {
66
+ formUUID: Type.UUID;
67
+ name: Type.String;
68
+ };
69
+
70
+ export type Category = {
71
+ name: string;
72
+ forms: Array<Form>;
41
73
  };
42
74
 
43
75
  export type Config = {
44
- casualGreeting: boolean;
45
- whoToGreet: Array<String>;
76
+ formCategories: Array<Category>;
77
+ formCategoriesToShow: Array<string>;
46
78
  };
@@ -0,0 +1,114 @@
1
+ import React, { useEffect, useMemo, useReducer } from "react";
2
+ import reducer from "./FormWorkflowReducer";
3
+ import { useParams, useLocation } from "react-router-dom";
4
+ interface ParamTypes {
5
+ formUuid?: string;
6
+ }
7
+
8
+ const initialActions = {
9
+ addPatient: (uuid: string | number) => undefined,
10
+ openPatientSearch: () => undefined,
11
+ saveEncounter: (encounterUuid: string | number) => undefined,
12
+ editEncounter: (patientUuid: string | number) => undefined,
13
+ submitForNext: () => undefined,
14
+ submitForReview: () => undefined,
15
+ submitForComplete: () => undefined,
16
+ goToReview: () => undefined,
17
+ destroySession: () => undefined,
18
+ closeSession: () => undefined,
19
+ };
20
+
21
+ export const initialWorkflowState = {
22
+ // activeFormUuid and forms are the only two real values stored at state root level
23
+ activeFormUuid: null, // the corrently open form
24
+ forms: {}, // object containing all forms session data
25
+ // the following fields will be available in context but are not stored at the
26
+ // state root level, but refer to nested values for the current
27
+ // aciveFormUuid
28
+ workflowState: null, // pseudo field from state[activeFormUuid].workflowState
29
+ activePatientUuid: null, // pseudo field from state[activeFormUuid].activePatientUuid
30
+ activeEncounterUuid: null, // pseudo field from state[activeFormUuid].encounterUuid
31
+ patientUuids: [], // pseudo field from state[activeFormUuid].patientUuids
32
+ encounters: {}, // pseudo field from state[activeFormUuid].encounters
33
+ };
34
+
35
+ const FormWorkflowContext = React.createContext({
36
+ ...initialWorkflowState,
37
+ ...initialActions,
38
+ });
39
+
40
+ const FormWorkflowProvider = ({ children }) => {
41
+ const { formUuid } = useParams() as ParamTypes;
42
+ const activeFormUuid = formUuid.split("&")[0];
43
+ const { search } = useLocation();
44
+ const newPatientUuid = new URLSearchParams(search).get("patientUuid");
45
+ const [state, dispatch] = useReducer(reducer, {
46
+ ...initialWorkflowState,
47
+ ...initialActions,
48
+ });
49
+
50
+ const actions = useMemo(
51
+ () => ({
52
+ initializeWorkflowState: ({ activeFormUuid, newPatientUuid }) =>
53
+ dispatch({
54
+ type: "INITIALIZE_WORKFLOW_STATE",
55
+ activeFormUuid,
56
+ newPatientUuid,
57
+ }),
58
+ addPatient: (patientUuid) =>
59
+ dispatch({ type: "ADD_PATIENT", patientUuid }),
60
+ openPatientSearch: () => dispatch({ type: "OPEN_PATIENT_SEARCH" }),
61
+ saveEncounter: (encounterUuid) =>
62
+ dispatch({
63
+ type: "SAVE_ENCOUNTER",
64
+ encounterUuid,
65
+ }),
66
+ submitForNext: () => dispatch({ type: "SUBMIT_FOR_NEXT" }),
67
+ submitForReview: () => dispatch({ type: "SUBMIT_FOR_REVIEW" }),
68
+ submitForComplete: () => dispatch({ type: "SUBMIT_FOR_COMPLETE" }),
69
+ editEncounter: (patientUuid) =>
70
+ dispatch({ type: "EDIT_ENCOUNTER", patientUuid }),
71
+ goToReview: () => dispatch({ type: "GO_TO_REVIEW" }),
72
+ destroySession: () => dispatch({ type: "DESTROY_SESSION" }),
73
+ closeSession: () => dispatch({ type: "CLOSE_SESSION" }),
74
+ }),
75
+ []
76
+ );
77
+
78
+ // if formUuid isn't a part of state yet, grab it from the url params
79
+ // this is the entry into the workflow system
80
+ useEffect(() => {
81
+ if (state?.workflowState === null && activeFormUuid) {
82
+ actions.initializeWorkflowState({ activeFormUuid, newPatientUuid });
83
+ }
84
+ }, [activeFormUuid, newPatientUuid, state?.workflowState, actions]);
85
+
86
+ return (
87
+ <FormWorkflowContext.Provider
88
+ value={{
89
+ ...state,
90
+ ...actions,
91
+ workflowState:
92
+ state.forms?.[state.activeFormUuid]?.workflowState ??
93
+ initialWorkflowState.workflowState,
94
+ activePatientUuid:
95
+ state.forms?.[state.activeFormUuid]?.activePatientUuid ??
96
+ initialWorkflowState.activePatientUuid,
97
+ activeEncounterUuid:
98
+ state.forms?.[state.activeFormUuid]?.activeEncounterUuid ??
99
+ initialWorkflowState.activeEncounterUuid,
100
+ patientUuids:
101
+ state.forms?.[state.activeFormUuid]?.patientUuids ??
102
+ initialWorkflowState.patientUuids,
103
+ encounters:
104
+ state.forms?.[state.activeFormUuid]?.encounters ??
105
+ initialWorkflowState.encounters,
106
+ }}
107
+ >
108
+ {children}
109
+ </FormWorkflowContext.Provider>
110
+ );
111
+ };
112
+
113
+ export default FormWorkflowContext;
114
+ export { FormWorkflowProvider };