@openmrs/esm-fast-data-entry-app 1.0.1-pre.171 → 1.0.1-pre.176
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.
- package/__mocks__/react-i18next.js +9 -14
- package/dist/101.js.map +1 -1
- package/dist/188.js.map +1 -1
- package/dist/219.js.map +1 -1
- package/dist/326.js.map +1 -1
- package/dist/564.js.map +1 -1
- package/dist/91.js.map +1 -1
- package/dist/99.js.map +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-fast-data-entry-app.js.buildmanifest.json +8 -8
- package/dist/routes.json +1 -1
- package/package.json +1 -3
- package/prettier.config.js +8 -0
- package/src/CancelModal.tsx +9 -15
- package/src/CompleteModal.tsx +7 -18
- package/src/FormBootstrap.tsx +9 -9
- package/src/Root.tsx +7 -12
- package/src/add-group-modal/AddGroupModal.tsx +46 -109
- package/src/config-schema.ts +35 -36
- package/src/constant.ts +1 -1
- package/src/context/FormWorkflowContext.tsx +26 -39
- package/src/context/FormWorkflowReducer.ts +50 -74
- package/src/context/GroupFormWorkflowContext.tsx +36 -61
- package/src/context/GroupFormWorkflowReducer.ts +69 -105
- package/src/declarations.d.ts +3 -3
- package/src/empty-state/EmptyDataIllustration.tsx +4 -16
- package/src/empty-state/EmptyState.tsx +8 -13
- package/src/form-entry-workflow/FormEntryWorkflow.tsx +26 -44
- package/src/form-entry-workflow/form-review-card/FormReviewCard.tsx +7 -7
- package/src/form-entry-workflow/form-review-card/index.ts +1 -1
- package/src/form-entry-workflow/index.ts +1 -1
- package/src/form-entry-workflow/patient-banner/PatientBanner.test.tsx +5 -5
- package/src/form-entry-workflow/patient-banner/PatientBanner.tsx +14 -27
- package/src/form-entry-workflow/patient-banner/index.ts +1 -1
- package/src/form-entry-workflow/patient-search-header/PatientSearchHeader.tsx +17 -26
- package/src/form-entry-workflow/patient-search-header/index.ts +1 -1
- package/src/form-entry-workflow/workflow-review/WorkflowReview.tsx +12 -12
- package/src/form-entry-workflow/workflow-review/index.ts +1 -1
- package/src/forms-app-menu-link.tsx +4 -6
- package/src/forms-page/FormsPage.tsx +22 -50
- package/src/forms-page/forms-table/FormsTable.tsx +22 -42
- package/src/forms-page/forms-table/index.ts +1 -1
- package/src/forms-page/index.ts +1 -1
- package/src/group-form-entry-workflow/GroupFormEntryWorkflow.tsx +8 -8
- package/src/group-form-entry-workflow/GroupSessionWorkspace.tsx +27 -58
- package/src/group-form-entry-workflow/SessionDetailsForm.tsx +43 -66
- package/src/group-form-entry-workflow/SessionMetaWorkspace.tsx +20 -28
- package/src/group-form-entry-workflow/attendance-table/AttendanceTable.tsx +13 -27
- package/src/group-form-entry-workflow/attendance-table/index.ts +1 -1
- package/src/group-form-entry-workflow/configurable-questions/ConfigurableQuestionsSection.tsx +6 -12
- package/src/group-form-entry-workflow/group-display-header/GroupDisplayHeader.test.tsx +5 -5
- package/src/group-form-entry-workflow/group-display-header/GroupDisplayHeader.tsx +13 -21
- package/src/group-form-entry-workflow/group-display-header/index.ts +1 -1
- package/src/group-form-entry-workflow/group-search/CompactGroupResults.tsx +24 -35
- package/src/group-form-entry-workflow/group-search/CompactGroupSearch.tsx +13 -15
- package/src/group-form-entry-workflow/group-search/GroupSearch.tsx +22 -38
- package/src/group-form-entry-workflow/group-search-header/GroupSearchHeader.tsx +18 -25
- package/src/group-form-entry-workflow/group-search-header/index.ts +1 -1
- package/src/group-form-entry-workflow/index.ts +1 -1
- package/src/hooks/index.ts +7 -13
- package/src/hooks/useForm.ts +13 -30
- package/src/hooks/useFormState.ts +3 -3
- package/src/hooks/useGetAllForms.ts +5 -14
- package/src/hooks/useGetEncounter.ts +2 -2
- package/src/hooks/useGetPatient.ts +2 -2
- package/src/hooks/useGetPatients.ts +4 -6
- package/src/hooks/useGetSystemSetting.ts +3 -5
- package/src/hooks/useKeyPress.ts +5 -5
- package/src/hooks/usePostEndpoint.ts +8 -8
- package/src/hooks/useSearchEndpoint.ts +15 -38
- package/src/hooks/useStartVisit.ts +16 -27
- package/src/index.ts +8 -20
- package/src/patient-card/PatientCard.tsx +8 -20
- package/src/patient-card/index.ts +1 -1
- package/src/setup-tests.ts +1 -1
- package/tools/i18next-parser.config.js +19 -19
- package/webpack.config.js +1 -1
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
import { navigate } from
|
|
2
|
-
import { initialWorkflowState } from
|
|
3
|
-
import { v4 as uuid } from
|
|
1
|
+
import { navigate } from '@openmrs/esm-framework';
|
|
2
|
+
import { initialWorkflowState } from './FormWorkflowContext';
|
|
3
|
+
import { v4 as uuid } from 'uuid';
|
|
4
4
|
|
|
5
|
-
export const fdeGroupWorkflowStorageVersion =
|
|
6
|
-
export const fdeGroupWorkflowStorageName =
|
|
7
|
-
"openmrs:fastDataEntryGroupWorkflowState";
|
|
5
|
+
export const fdeGroupWorkflowStorageVersion = '1.0.5';
|
|
6
|
+
export const fdeGroupWorkflowStorageName = 'openmrs:fastDataEntryGroupWorkflowState';
|
|
8
7
|
const persistData = (data) => {
|
|
9
|
-
localStorage.setItem(
|
|
10
|
-
fdeGroupWorkflowStorageName + ":" + data.userUuid,
|
|
11
|
-
JSON.stringify(data)
|
|
12
|
-
);
|
|
8
|
+
localStorage.setItem(fdeGroupWorkflowStorageName + ':' + data.userUuid, JSON.stringify(data));
|
|
13
9
|
};
|
|
14
10
|
|
|
15
11
|
const initialFormState = {
|
|
16
|
-
workflowState:
|
|
12
|
+
workflowState: 'NEW_GROUP_SESSION',
|
|
17
13
|
groupUuid: null,
|
|
18
14
|
groupName: null,
|
|
19
15
|
groupMembers: [],
|
|
@@ -28,16 +24,11 @@ const initialFormState = {
|
|
|
28
24
|
|
|
29
25
|
const reducer = (state, action) => {
|
|
30
26
|
switch (action.type) {
|
|
31
|
-
case
|
|
32
|
-
const savedData = localStorage.getItem(
|
|
33
|
-
fdeGroupWorkflowStorageName + ":" + action.userUuid
|
|
34
|
-
);
|
|
27
|
+
case 'INITIALIZE_WORKFLOW_STATE': {
|
|
28
|
+
const savedData = localStorage.getItem(fdeGroupWorkflowStorageName + ':' + action.userUuid);
|
|
35
29
|
const savedDataObject = savedData ? JSON.parse(savedData) : {};
|
|
36
30
|
let newState: { [key: string]: unknown } = {};
|
|
37
|
-
if (
|
|
38
|
-
savedData &&
|
|
39
|
-
savedDataObject["_storageVersion"] === fdeGroupWorkflowStorageVersion
|
|
40
|
-
) {
|
|
31
|
+
if (savedData && savedDataObject['_storageVersion'] === fdeGroupWorkflowStorageVersion) {
|
|
41
32
|
// there is localStorage data and it is still valid
|
|
42
33
|
const thisSavedForm = savedDataObject.forms?.[action.activeFormUuid];
|
|
43
34
|
// set active patient to the last one we were on
|
|
@@ -59,10 +50,8 @@ const reducer = (state, action) => {
|
|
|
59
50
|
...initialFormState,
|
|
60
51
|
...thisSavedForm,
|
|
61
52
|
activePatientUuid: activePatientUuid,
|
|
62
|
-
activeEncounterUuid:
|
|
63
|
-
|
|
64
|
-
activeVisitUuid:
|
|
65
|
-
thisSavedForm?.visits?.[activePatientUuid] || null,
|
|
53
|
+
activeEncounterUuid: thisSavedForm?.encounters?.[activePatientUuid] || null,
|
|
54
|
+
activeVisitUuid: thisSavedForm?.visits?.[activePatientUuid] || null,
|
|
66
55
|
activeSessionUuid: activeSessionUuid,
|
|
67
56
|
},
|
|
68
57
|
},
|
|
@@ -83,7 +72,7 @@ const reducer = (state, action) => {
|
|
|
83
72
|
return newState;
|
|
84
73
|
}
|
|
85
74
|
|
|
86
|
-
case
|
|
75
|
+
case 'SET_GROUP': {
|
|
87
76
|
const newState = {
|
|
88
77
|
...state,
|
|
89
78
|
forms: {
|
|
@@ -96,13 +85,8 @@ const reducer = (state, action) => {
|
|
|
96
85
|
// this translation is not preferred
|
|
97
86
|
// the only reason we tollerate it here is beause it should be the only time
|
|
98
87
|
// we add cohort information to state
|
|
99
|
-
action.group.cohortMembers?.map(
|
|
100
|
-
|
|
101
|
-
) ?? [],
|
|
102
|
-
groupMembers:
|
|
103
|
-
action.group.cohortMembers?.map(
|
|
104
|
-
(member) => member?.patient?.uuid
|
|
105
|
-
) ?? [],
|
|
88
|
+
action.group.cohortMembers?.map((member) => member?.patient?.uuid) ?? [],
|
|
89
|
+
groupMembers: action.group.cohortMembers?.map((member) => member?.patient?.uuid) ?? [],
|
|
106
90
|
activePatientUuid: null,
|
|
107
91
|
activeEncounterUuid: null,
|
|
108
92
|
activeVisitUuid: null,
|
|
@@ -113,7 +97,7 @@ const reducer = (state, action) => {
|
|
|
113
97
|
persistData(newState);
|
|
114
98
|
return newState;
|
|
115
99
|
}
|
|
116
|
-
case
|
|
100
|
+
case 'UNSET_GROUP': {
|
|
117
101
|
const newState = {
|
|
118
102
|
...state,
|
|
119
103
|
forms: {
|
|
@@ -134,7 +118,7 @@ const reducer = (state, action) => {
|
|
|
134
118
|
persistData(newState);
|
|
135
119
|
return newState;
|
|
136
120
|
}
|
|
137
|
-
case
|
|
121
|
+
case 'SET_SESSION_META': {
|
|
138
122
|
// requires that group is already entered and contains patientUuids
|
|
139
123
|
const newState = {
|
|
140
124
|
...state,
|
|
@@ -143,30 +127,21 @@ const reducer = (state, action) => {
|
|
|
143
127
|
[state.activeFormUuid]: {
|
|
144
128
|
...state.forms[state.activeFormUuid],
|
|
145
129
|
sessionMeta: action.meta,
|
|
146
|
-
activePatientUuid:
|
|
147
|
-
state.forms[state.activeFormUuid].patientUuids?.[0],
|
|
130
|
+
activePatientUuid: state.forms[state.activeFormUuid].patientUuids?.[0],
|
|
148
131
|
activeEncounterUuid:
|
|
149
|
-
state.forms[state.activeFormUuid].encounters[
|
|
150
|
-
state.forms[state.activeFormUuid].patientUuids?.[0]
|
|
151
|
-
] || null,
|
|
132
|
+
state.forms[state.activeFormUuid].encounters[state.forms[state.activeFormUuid].patientUuids?.[0]] || null,
|
|
152
133
|
activeVisitUuid:
|
|
153
|
-
state.forms[state.activeFormUuid].visits[
|
|
154
|
-
state.forms[state.activeFormUuid].patientUuids?.[0]
|
|
155
|
-
] || null,
|
|
134
|
+
state.forms[state.activeFormUuid].visits[state.forms[state.activeFormUuid].patientUuids?.[0]] || null,
|
|
156
135
|
activeSessionUuid: uuid(),
|
|
157
|
-
workflowState:
|
|
136
|
+
workflowState: 'EDIT_FORM',
|
|
158
137
|
},
|
|
159
138
|
},
|
|
160
139
|
};
|
|
161
140
|
persistData(newState);
|
|
162
141
|
return newState;
|
|
163
142
|
}
|
|
164
|
-
case
|
|
165
|
-
if (
|
|
166
|
-
state.forms[state.activeFormUuid].patientUuids.includes(
|
|
167
|
-
action.patientUuid
|
|
168
|
-
)
|
|
169
|
-
) {
|
|
143
|
+
case 'ADD_PATIENT_UUID': {
|
|
144
|
+
if (state.forms[state.activeFormUuid].patientUuids.includes(action.patientUuid)) {
|
|
170
145
|
return state;
|
|
171
146
|
}
|
|
172
147
|
|
|
@@ -176,35 +151,30 @@ const reducer = (state, action) => {
|
|
|
176
151
|
...state.forms,
|
|
177
152
|
[state.activeFormUuid]: {
|
|
178
153
|
...state.forms[state.activeFormUuid],
|
|
179
|
-
patientUuids: [
|
|
180
|
-
...state.forms[state.activeFormUuid].patientUuids,
|
|
181
|
-
action.patientUuid,
|
|
182
|
-
],
|
|
154
|
+
patientUuids: [...state.forms[state.activeFormUuid].patientUuids, action.patientUuid],
|
|
183
155
|
},
|
|
184
156
|
},
|
|
185
157
|
};
|
|
186
158
|
persistData(newState);
|
|
187
159
|
return newState;
|
|
188
160
|
}
|
|
189
|
-
case
|
|
161
|
+
case 'REMOVE_PATIENT_UUID': {
|
|
190
162
|
const newState = {
|
|
191
163
|
...state,
|
|
192
164
|
forms: {
|
|
193
165
|
...state.forms,
|
|
194
166
|
[state.activeFormUuid]: {
|
|
195
167
|
...state.forms[state.activeFormUuid],
|
|
196
|
-
patientUuids: state.forms[
|
|
197
|
-
state.activeFormUuid
|
|
198
|
-
].patientUuids?.filter((uuid) => action.patientUuid !== uuid),
|
|
168
|
+
patientUuids: state.forms[state.activeFormUuid].patientUuids?.filter((uuid) => action.patientUuid !== uuid),
|
|
199
169
|
},
|
|
200
170
|
},
|
|
201
171
|
};
|
|
202
172
|
persistData(newState);
|
|
203
173
|
return newState;
|
|
204
174
|
}
|
|
205
|
-
case
|
|
175
|
+
case 'SAVE_ENCOUNTER': {
|
|
206
176
|
const thisForm = state.forms[state.activeFormUuid];
|
|
207
|
-
if (thisForm.workflowState ===
|
|
177
|
+
if (thisForm.workflowState === 'SUBMIT_FOR_COMPLETE') {
|
|
208
178
|
const { [state.activeFormUuid]: activeForm, ...formRest } = state.forms;
|
|
209
179
|
const newState = {
|
|
210
180
|
...state,
|
|
@@ -213,16 +183,13 @@ const reducer = (state, action) => {
|
|
|
213
183
|
};
|
|
214
184
|
persistData(newState);
|
|
215
185
|
// eslint-disable-next-line
|
|
216
|
-
navigate({ to:
|
|
186
|
+
navigate({ to: '${openmrsSpaBase}/forms' });
|
|
217
187
|
return newState;
|
|
218
|
-
} else if (thisForm.workflowState ===
|
|
188
|
+
} else if (thisForm.workflowState === 'SUBMIT_FOR_NEXT') {
|
|
219
189
|
const nextPatientUuid = state.nextPatientUuid
|
|
220
190
|
? state.nextPatientUuid
|
|
221
191
|
: thisForm.patientUuids[
|
|
222
|
-
Math.min(
|
|
223
|
-
thisForm.patientUuids.indexOf(thisForm.activePatientUuid) + 1,
|
|
224
|
-
thisForm.patientUuids.length - 1
|
|
225
|
-
)
|
|
192
|
+
Math.min(thisForm.patientUuids.indexOf(thisForm.activePatientUuid) + 1, thisForm.patientUuids.length - 1)
|
|
226
193
|
];
|
|
227
194
|
const encounters = {
|
|
228
195
|
...thisForm.encounters,
|
|
@@ -239,7 +206,7 @@ const reducer = (state, action) => {
|
|
|
239
206
|
activeEncounterUuid: encounters[nextPatientUuid] || null,
|
|
240
207
|
activeVisitUuid: thisForm.visits[nextPatientUuid] || null,
|
|
241
208
|
activeSessionUuid: thisForm.activeSessionUuid,
|
|
242
|
-
workflowState:
|
|
209
|
+
workflowState: 'EDIT_FORM',
|
|
243
210
|
},
|
|
244
211
|
},
|
|
245
212
|
};
|
|
@@ -247,36 +214,34 @@ const reducer = (state, action) => {
|
|
|
247
214
|
return newState;
|
|
248
215
|
} else return state;
|
|
249
216
|
}
|
|
250
|
-
case
|
|
217
|
+
case 'EDIT_ENCOUNTER': {
|
|
251
218
|
const newState = {
|
|
252
219
|
...state,
|
|
253
220
|
forms: {
|
|
254
221
|
...state.forms,
|
|
255
222
|
[state.activeFormUuid]: {
|
|
256
223
|
...state.forms[state.activeFormUuid],
|
|
257
|
-
activeEncounterUuid:
|
|
258
|
-
|
|
259
|
-
activeVisitUuid:
|
|
260
|
-
state.forms[state.activeFormUuid].visits[action.patientUuid],
|
|
224
|
+
activeEncounterUuid: state.forms[state.activeFormUuid].encounters[action.patientUuid],
|
|
225
|
+
activeVisitUuid: state.forms[state.activeFormUuid].visits[action.patientUuid],
|
|
261
226
|
activePatientUuid: action.patientUuid,
|
|
262
227
|
activeSessionUuid: action.activeSessionUuid,
|
|
263
|
-
workflowState:
|
|
228
|
+
workflowState: 'EDIT_FORM',
|
|
264
229
|
},
|
|
265
230
|
},
|
|
266
231
|
};
|
|
267
232
|
persistData(newState);
|
|
268
233
|
return newState;
|
|
269
234
|
}
|
|
270
|
-
case
|
|
235
|
+
case 'VALIDATE_FOR_NEXT':
|
|
271
236
|
// this state should not be persisted
|
|
272
237
|
window.dispatchEvent(
|
|
273
|
-
new CustomEvent(
|
|
238
|
+
new CustomEvent('ampath-form-action', {
|
|
274
239
|
detail: {
|
|
275
240
|
formUuid: state.activeFormUuid,
|
|
276
241
|
patientUuid: state.forms[state.activeFormUuid].activePatientUuid,
|
|
277
|
-
action:
|
|
242
|
+
action: 'validateForm',
|
|
278
243
|
},
|
|
279
|
-
})
|
|
244
|
+
}),
|
|
280
245
|
);
|
|
281
246
|
return {
|
|
282
247
|
...state,
|
|
@@ -284,11 +249,11 @@ const reducer = (state, action) => {
|
|
|
284
249
|
...state.forms,
|
|
285
250
|
[state.activeFormUuid]: {
|
|
286
251
|
...state.forms[state.activeFormUuid],
|
|
287
|
-
workflowState:
|
|
252
|
+
workflowState: 'VALIDATE_FOR_NEXT',
|
|
288
253
|
},
|
|
289
254
|
},
|
|
290
255
|
};
|
|
291
|
-
case
|
|
256
|
+
case 'UPDATE_VISIT_UUID':
|
|
292
257
|
// this state should not be persisted
|
|
293
258
|
// we don't pers
|
|
294
259
|
return {
|
|
@@ -299,24 +264,23 @@ const reducer = (state, action) => {
|
|
|
299
264
|
...state.forms[state.activeFormUuid],
|
|
300
265
|
visits: {
|
|
301
266
|
...state.forms[state.activeFormUuid].visits,
|
|
302
|
-
[state.forms[state.activeFormUuid].activePatientUuid]:
|
|
303
|
-
action.visitUuid,
|
|
267
|
+
[state.forms[state.activeFormUuid].activePatientUuid]: action.visitUuid,
|
|
304
268
|
},
|
|
305
269
|
activeVisitUuid: action.visitUuid,
|
|
306
270
|
},
|
|
307
271
|
},
|
|
308
272
|
};
|
|
309
273
|
|
|
310
|
-
case
|
|
274
|
+
case 'SUBMIT_FOR_NEXT':
|
|
311
275
|
// this state should not be persisted
|
|
312
276
|
window.dispatchEvent(
|
|
313
|
-
new CustomEvent(
|
|
277
|
+
new CustomEvent('ampath-form-action', {
|
|
314
278
|
detail: {
|
|
315
279
|
formUuid: state.activeFormUuid,
|
|
316
280
|
patientUuid: state.forms[state.activeFormUuid].activePatientUuid,
|
|
317
|
-
action:
|
|
281
|
+
action: 'onSubmit',
|
|
318
282
|
},
|
|
319
|
-
})
|
|
283
|
+
}),
|
|
320
284
|
);
|
|
321
285
|
return {
|
|
322
286
|
...state,
|
|
@@ -324,21 +288,21 @@ const reducer = (state, action) => {
|
|
|
324
288
|
...state.forms,
|
|
325
289
|
[state.activeFormUuid]: {
|
|
326
290
|
...state.forms[state.activeFormUuid],
|
|
327
|
-
workflowState:
|
|
291
|
+
workflowState: 'SUBMIT_FOR_NEXT',
|
|
328
292
|
},
|
|
329
293
|
},
|
|
330
294
|
nextPatientUuid: action.nextPatientUuid,
|
|
331
295
|
};
|
|
332
|
-
case
|
|
296
|
+
case 'SUBMIT_FOR_REVIEW':
|
|
333
297
|
// this state should not be persisted
|
|
334
298
|
window.dispatchEvent(
|
|
335
|
-
new CustomEvent(
|
|
299
|
+
new CustomEvent('ampath-form-action', {
|
|
336
300
|
detail: {
|
|
337
301
|
formUuid: state.activeFormUuid,
|
|
338
302
|
patientUuid: state.forms[state.activeFormUuid].activePatientUuid,
|
|
339
|
-
action:
|
|
303
|
+
action: 'onSubmit',
|
|
340
304
|
},
|
|
341
|
-
})
|
|
305
|
+
}),
|
|
342
306
|
);
|
|
343
307
|
return {
|
|
344
308
|
...state,
|
|
@@ -346,21 +310,21 @@ const reducer = (state, action) => {
|
|
|
346
310
|
...state.forms,
|
|
347
311
|
[state.activeFormUuid]: {
|
|
348
312
|
...state.forms[state.activeFormUuid],
|
|
349
|
-
workflowState:
|
|
313
|
+
workflowState: 'SUBMIT_FOR_REVIEW',
|
|
350
314
|
},
|
|
351
315
|
},
|
|
352
316
|
};
|
|
353
317
|
|
|
354
|
-
case
|
|
318
|
+
case 'VALIDATE_FOR_COMPLETE':
|
|
355
319
|
// this state should not be persisted
|
|
356
320
|
window.dispatchEvent(
|
|
357
|
-
new CustomEvent(
|
|
321
|
+
new CustomEvent('ampath-form-action', {
|
|
358
322
|
detail: {
|
|
359
323
|
formUuid: state.activeFormUuid,
|
|
360
324
|
patientUuid: state.forms[state.activeFormUuid].activePatientUuid,
|
|
361
|
-
action:
|
|
325
|
+
action: 'validateForm',
|
|
362
326
|
},
|
|
363
|
-
})
|
|
327
|
+
}),
|
|
364
328
|
);
|
|
365
329
|
return {
|
|
366
330
|
...state,
|
|
@@ -368,20 +332,20 @@ const reducer = (state, action) => {
|
|
|
368
332
|
...state.forms,
|
|
369
333
|
[state.activeFormUuid]: {
|
|
370
334
|
...state.forms[state.activeFormUuid],
|
|
371
|
-
workflowState:
|
|
335
|
+
workflowState: 'VALIDATE_FOR_COMPLETE',
|
|
372
336
|
},
|
|
373
337
|
},
|
|
374
338
|
};
|
|
375
|
-
case
|
|
339
|
+
case 'SUBMIT_FOR_COMPLETE':
|
|
376
340
|
// this state should not be persisted
|
|
377
341
|
window.dispatchEvent(
|
|
378
|
-
new CustomEvent(
|
|
342
|
+
new CustomEvent('ampath-form-action', {
|
|
379
343
|
detail: {
|
|
380
344
|
formUuid: state.activeFormUuid,
|
|
381
345
|
patientUuid: state.forms[state.activeFormUuid].activePatientUuid,
|
|
382
|
-
action:
|
|
346
|
+
action: 'onSubmit',
|
|
383
347
|
},
|
|
384
|
-
})
|
|
348
|
+
}),
|
|
385
349
|
);
|
|
386
350
|
return {
|
|
387
351
|
...state,
|
|
@@ -389,11 +353,11 @@ const reducer = (state, action) => {
|
|
|
389
353
|
...state.forms,
|
|
390
354
|
[state.activeFormUuid]: {
|
|
391
355
|
...state.forms[state.activeFormUuid],
|
|
392
|
-
workflowState:
|
|
356
|
+
workflowState: 'SUBMIT_FOR_COMPLETE',
|
|
393
357
|
},
|
|
394
358
|
},
|
|
395
359
|
};
|
|
396
|
-
case
|
|
360
|
+
case 'GO_TO_REVIEW': {
|
|
397
361
|
const newState = {
|
|
398
362
|
...state,
|
|
399
363
|
forms: {
|
|
@@ -404,14 +368,14 @@ const reducer = (state, action) => {
|
|
|
404
368
|
activVisitUuid: null,
|
|
405
369
|
activePatientUuid: null,
|
|
406
370
|
activeSessionUuid: null,
|
|
407
|
-
workflowState:
|
|
371
|
+
workflowState: 'REVIEW',
|
|
408
372
|
},
|
|
409
373
|
},
|
|
410
374
|
};
|
|
411
375
|
persistData(newState);
|
|
412
376
|
return newState;
|
|
413
377
|
}
|
|
414
|
-
case
|
|
378
|
+
case 'DESTROY_SESSION': {
|
|
415
379
|
const { [state.activeFormUuid]: activeForm, ...formRest } = state.forms;
|
|
416
380
|
const newState = {
|
|
417
381
|
...state,
|
|
@@ -420,17 +384,17 @@ const reducer = (state, action) => {
|
|
|
420
384
|
};
|
|
421
385
|
persistData(newState);
|
|
422
386
|
//eslint-disable-next-line
|
|
423
|
-
navigate({ to:
|
|
387
|
+
navigate({ to: '${openmrsSpaBase}/forms' });
|
|
424
388
|
return { ...newState, formDestroyed: true };
|
|
425
389
|
}
|
|
426
|
-
case
|
|
390
|
+
case 'CLOSE_SESSION': {
|
|
427
391
|
const newState = {
|
|
428
392
|
...state,
|
|
429
393
|
activeFormUuid: null,
|
|
430
394
|
};
|
|
431
395
|
persistData(newState);
|
|
432
396
|
//eslint-disable-next-line
|
|
433
|
-
navigate({ to:
|
|
397
|
+
navigate({ to: '${openmrsSpaBase}/forms' });
|
|
434
398
|
return newState;
|
|
435
399
|
}
|
|
436
400
|
default:
|
package/src/declarations.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
declare module
|
|
2
|
-
declare module
|
|
3
|
-
declare module
|
|
1
|
+
declare module '@carbon/react';
|
|
2
|
+
declare module '*.css';
|
|
3
|
+
declare module '*.scss';
|
|
4
4
|
declare type SideNavProps = object;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import React from
|
|
1
|
+
import React from 'react';
|
|
2
2
|
|
|
3
|
-
export const EmptyDataIllustration = ({ width =
|
|
3
|
+
export const EmptyDataIllustration = ({ width = '64', height = '64' }) => {
|
|
4
4
|
return (
|
|
5
5
|
<svg width={width} height={height} viewBox="0 0 64 64">
|
|
6
6
|
<title>Empty data illustration</title>
|
|
@@ -18,13 +18,7 @@ export const EmptyDataIllustration = ({ width = "64", height = "64" }) => {
|
|
|
18
18
|
fill="#C6C6C6"
|
|
19
19
|
/>
|
|
20
20
|
<circle fill="#C6C6C6" cx={17.636} cy={2.314} r={1.855} />
|
|
21
|
-
<circle
|
|
22
|
-
fill="#FFF"
|
|
23
|
-
fillRule="nonzero"
|
|
24
|
-
cx={17.636}
|
|
25
|
-
cy={2.314}
|
|
26
|
-
r={1.175}
|
|
27
|
-
/>
|
|
21
|
+
<circle fill="#FFF" fillRule="nonzero" cx={17.636} cy={2.314} r={1.175} />
|
|
28
22
|
<path
|
|
29
23
|
d="M55.893 53.995H24.544a.79.79 0 01-.788-.789V15.644a.79.79 0 01.788-.788h31.349a.79.79 0 01.788.788v37.562a.79.79 0 01-.788.789z"
|
|
30
24
|
fill="#F4F4F4"
|
|
@@ -38,13 +32,7 @@ export const EmptyDataIllustration = ({ width = "64", height = "64" }) => {
|
|
|
38
32
|
fill="#C6C6C6"
|
|
39
33
|
/>
|
|
40
34
|
<circle fill="#C6C6C6" cx={40.218} cy={9.755} r={1.855} />
|
|
41
|
-
<circle
|
|
42
|
-
fill="#FFF"
|
|
43
|
-
fillRule="nonzero"
|
|
44
|
-
cx={40.218}
|
|
45
|
-
cy={9.755}
|
|
46
|
-
r={1.13}
|
|
47
|
-
/>
|
|
35
|
+
<circle fill="#FFF" fillRule="nonzero" cx={40.218} cy={9.755} r={1.13} />
|
|
48
36
|
</g>
|
|
49
37
|
</svg>
|
|
50
38
|
);
|
|
@@ -1,25 +1,20 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { Tile, Layer } from
|
|
3
|
-
import styles from
|
|
4
|
-
import { useLayoutType } from
|
|
5
|
-
import { EmptyDataIllustration } from
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Tile, Layer } from '@carbon/react';
|
|
3
|
+
import styles from './styles.scss';
|
|
4
|
+
import { useLayoutType } from '@openmrs/esm-framework';
|
|
5
|
+
import { EmptyDataIllustration } from './EmptyDataIllustration';
|
|
6
6
|
|
|
7
7
|
export interface EmptyStateProps {
|
|
8
8
|
headerTitle: string;
|
|
9
9
|
displayText: string;
|
|
10
10
|
}
|
|
11
|
-
const EmptyState: React.FC<EmptyStateProps> = ({
|
|
12
|
-
|
|
13
|
-
displayText,
|
|
14
|
-
}) => {
|
|
15
|
-
const isTablet = useLayoutType() === "tablet";
|
|
11
|
+
const EmptyState: React.FC<EmptyStateProps> = ({ headerTitle, displayText }) => {
|
|
12
|
+
const isTablet = useLayoutType() === 'tablet';
|
|
16
13
|
|
|
17
14
|
return (
|
|
18
15
|
<Layer>
|
|
19
16
|
<Tile className={styles.tile}>
|
|
20
|
-
<div
|
|
21
|
-
className={isTablet ? styles.tabletHeading : styles.desktopHeading}
|
|
22
|
-
>
|
|
17
|
+
<div className={isTablet ? styles.tabletHeading : styles.desktopHeading}>
|
|
23
18
|
<h4>{headerTitle}</h4>
|
|
24
19
|
</div>
|
|
25
20
|
<EmptyDataIllustration />
|
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import { ExtensionSlot, useSession } from
|
|
2
|
-
import { Button } from
|
|
3
|
-
import React, { useCallback, useContext, useEffect, useState } from
|
|
4
|
-
import FormBootstrap from
|
|
5
|
-
import PatientCard from
|
|
6
|
-
import styles from
|
|
7
|
-
import PatientSearchHeader from
|
|
8
|
-
import { useTranslation } from
|
|
9
|
-
import { v4 as uuid } from
|
|
10
|
-
import FormWorkflowContext, {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import CancelModal from "../CancelModal";
|
|
17
|
-
import useStartVisit from "../hooks/useStartVisit";
|
|
1
|
+
import { ExtensionSlot, useSession } from '@openmrs/esm-framework';
|
|
2
|
+
import { Button } from '@carbon/react';
|
|
3
|
+
import React, { useCallback, useContext, useEffect, useState } from 'react';
|
|
4
|
+
import FormBootstrap from '../FormBootstrap';
|
|
5
|
+
import PatientCard from '../patient-card/PatientCard';
|
|
6
|
+
import styles from './styles.scss';
|
|
7
|
+
import PatientSearchHeader from './patient-search-header';
|
|
8
|
+
import { useTranslation } from 'react-i18next';
|
|
9
|
+
import { v4 as uuid } from 'uuid';
|
|
10
|
+
import FormWorkflowContext, { FormWorkflowProvider } from '../context/FormWorkflowContext';
|
|
11
|
+
import WorkflowReview from './workflow-review';
|
|
12
|
+
import PatientBanner from './patient-banner';
|
|
13
|
+
import CompleteModal from '../CompleteModal';
|
|
14
|
+
import CancelModal from '../CancelModal';
|
|
15
|
+
import useStartVisit from '../hooks/useStartVisit';
|
|
18
16
|
|
|
19
17
|
const WorkflowNavigationButtons = () => {
|
|
20
18
|
const context = useContext(FormWorkflowContext);
|
|
@@ -30,28 +28,16 @@ const WorkflowNavigationButtons = () => {
|
|
|
30
28
|
<div className={styles.rightPanelActionButtons}>
|
|
31
29
|
<Button
|
|
32
30
|
kind="secondary"
|
|
33
|
-
onClick={
|
|
34
|
-
workflowState === "NEW_PATIENT"
|
|
35
|
-
? () => destroySession()
|
|
36
|
-
: () => setCompleteModalOpen(true)
|
|
37
|
-
}
|
|
31
|
+
onClick={workflowState === 'NEW_PATIENT' ? () => destroySession() : () => setCompleteModalOpen(true)}
|
|
38
32
|
>
|
|
39
|
-
{t(
|
|
33
|
+
{t('saveAndComplete', 'Save & Complete')}
|
|
40
34
|
</Button>
|
|
41
35
|
<Button kind="tertiary" onClick={() => setCancelModalOpen(true)}>
|
|
42
|
-
{t(
|
|
36
|
+
{t('cancel', 'Cancel')}
|
|
43
37
|
</Button>
|
|
44
38
|
</div>
|
|
45
|
-
<CancelModal
|
|
46
|
-
|
|
47
|
-
setOpen={setCancelModalOpen}
|
|
48
|
-
context={context}
|
|
49
|
-
/>
|
|
50
|
-
<CompleteModal
|
|
51
|
-
open={completeModalOpen}
|
|
52
|
-
setOpen={setCompleteModalOpen}
|
|
53
|
-
context={context}
|
|
54
|
-
/>
|
|
39
|
+
<CancelModal open={cancelModalOpen} setOpen={setCancelModalOpen} context={context} />
|
|
40
|
+
<CompleteModal open={completeModalOpen} setOpen={setCompleteModalOpen} context={context} />
|
|
55
41
|
</>
|
|
56
42
|
);
|
|
57
43
|
};
|
|
@@ -101,9 +87,7 @@ const FormWorkspace = () => {
|
|
|
101
87
|
const handleEncounterCreate = useCallback(
|
|
102
88
|
(payload) => {
|
|
103
89
|
payload.location = sessionLocation?.uuid;
|
|
104
|
-
payload.encounterDatetime = payload.encounterDatetime
|
|
105
|
-
? payload.encounterDatetime
|
|
106
|
-
: new Date().toISOString();
|
|
90
|
+
payload.encounterDatetime = payload.encounterDatetime ? payload.encounterDatetime : new Date().toISOString();
|
|
107
91
|
// Create a visit with the same date as the encounter being saved
|
|
108
92
|
const visitStartDatetime = new Date(payload.encounterDatetime);
|
|
109
93
|
const visitStopDatetime = new Date(payload.encounterDatetime);
|
|
@@ -124,15 +108,13 @@ const FormWorkspace = () => {
|
|
|
124
108
|
|
|
125
109
|
payload.visit = visitInfo;
|
|
126
110
|
},
|
|
127
|
-
[activePatientUuid, singleSessionVisitTypeUuid, sessionLocation]
|
|
111
|
+
[activePatientUuid, singleSessionVisitTypeUuid, sessionLocation],
|
|
128
112
|
);
|
|
129
113
|
|
|
130
114
|
return (
|
|
131
115
|
<div className={styles.workspace}>
|
|
132
116
|
{!patientUuids.length && (
|
|
133
|
-
<div className={styles.selectPatientMessage}>
|
|
134
|
-
{t("selectPatientFirst", "Please select a patient first")}
|
|
135
|
-
</div>
|
|
117
|
+
<div className={styles.selectPatientMessage}>{t('selectPatientFirst', 'Please select a patient first')}</div>
|
|
136
118
|
)}
|
|
137
119
|
{!!patientUuids.length && (
|
|
138
120
|
<div className={styles.formMainContent}>
|
|
@@ -148,7 +130,7 @@ const FormWorkspace = () => {
|
|
|
148
130
|
/>
|
|
149
131
|
</div>
|
|
150
132
|
<div className={styles.rightPanel}>
|
|
151
|
-
<h4>{t(
|
|
133
|
+
<h4>{t('formsFilled', 'Forms filled')}</h4>
|
|
152
134
|
<div className={styles.patientCardsSection}>
|
|
153
135
|
{patientUuids.map((patientUuid) => (
|
|
154
136
|
<PatientCard
|
|
@@ -177,8 +159,8 @@ const FormEntryWorkflow = () => {
|
|
|
177
159
|
<div className={styles.breadcrumbsContainer}>
|
|
178
160
|
<ExtensionSlot extensionSlotName="breadcrumbs-slot" />
|
|
179
161
|
</div>
|
|
180
|
-
{workflowState ===
|
|
181
|
-
{workflowState !==
|
|
162
|
+
{workflowState === 'REVIEW' && <WorkflowReview />}
|
|
163
|
+
{workflowState !== 'REVIEW' && (
|
|
182
164
|
<>
|
|
183
165
|
<PatientSearchHeader />
|
|
184
166
|
<PatientBanner />
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Accordion, AccordionItem, Button } from
|
|
2
|
-
import React, { useContext } from
|
|
3
|
-
import { useTranslation } from
|
|
4
|
-
import FormWorkflowContext from
|
|
5
|
-
import { useGetPatient, useGetEncounter } from
|
|
6
|
-
import styles from
|
|
1
|
+
import { Accordion, AccordionItem, Button } from '@carbon/react';
|
|
2
|
+
import React, { useContext } from 'react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import FormWorkflowContext from '../../context/FormWorkflowContext';
|
|
5
|
+
import { useGetPatient, useGetEncounter } from '../../hooks';
|
|
6
|
+
import styles from './styles.scss';
|
|
7
7
|
|
|
8
8
|
const FormReviewCard = ({ patientUuid }) => {
|
|
9
9
|
const { encounters, editEncounter } = useContext(FormWorkflowContext);
|
|
@@ -39,7 +39,7 @@ const FormReviewCard = ({ patientUuid }) => {
|
|
|
39
39
|
</div>
|
|
40
40
|
)}
|
|
41
41
|
<Button kind="primary" onClick={() => editEncounter(patientUuid)}>
|
|
42
|
-
{t(
|
|
42
|
+
{t('goToForm', 'Go To Form')}
|
|
43
43
|
</Button>
|
|
44
44
|
</AccordionItem>
|
|
45
45
|
</Accordion>
|