@openmrs/esm-form-builder-app 2.0.2-pre.574 → 2.0.2-pre.586
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/README.md +43 -17
- package/dist/127.js +1 -1
- package/dist/127.js.map +1 -1
- package/dist/150.js +1 -1
- package/dist/150.js.map +1 -1
- package/dist/153.js +1 -1
- package/dist/153.js.map +1 -1
- package/dist/164.js +1 -1
- package/dist/256.js +1 -1
- package/dist/319.js +1 -1
- package/dist/447.js +1 -1
- package/dist/447.js.map +1 -1
- package/dist/515.js +2 -0
- package/dist/{773.js.LICENSE.txt → 515.js.LICENSE.txt} +9 -0
- package/dist/515.js.map +1 -0
- package/dist/527.js +1 -0
- package/dist/527.js.map +1 -0
- package/dist/574.js +1 -1
- package/dist/757.js +1 -1
- package/dist/788.js +1 -1
- package/dist/800.js +1 -1
- package/dist/800.js.map +1 -1
- package/dist/807.js +1 -1
- package/dist/833.js +1 -1
- package/dist/878.js +2 -0
- package/dist/{208.js.LICENSE.txt → 878.js.LICENSE.txt} +2 -1
- package/dist/878.js.map +1 -0
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-form-builder-app.js +1 -1
- package/dist/openmrs-esm-form-builder-app.js.buildmanifest.json +154 -175
- package/dist/openmrs-esm-form-builder-app.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +35 -32
- package/src/components/action-buttons/action-buttons.component.tsx +65 -101
- package/src/components/dashboard/dashboard.component.tsx +98 -174
- package/src/components/dashboard/dashboard.test.tsx +51 -81
- package/src/components/empty-state/empty-data-illustration.component.tsx +4 -16
- package/src/components/empty-state/empty-state.component.tsx +11 -15
- package/src/components/error-state/error-state.component.tsx +11 -13
- package/src/components/form-editor/form-editor.component.tsx +97 -128
- package/src/components/form-renderer/form-renderer.component.tsx +30 -41
- package/src/components/interactive-builder/add-question-modal.component.tsx +129 -167
- package/src/components/interactive-builder/delete-page-modal.component.tsx +24 -37
- package/src/components/interactive-builder/delete-question-modal.component.tsx +25 -47
- package/src/components/interactive-builder/delete-section-modal.component.tsx +24 -37
- package/src/components/interactive-builder/draggable-question.component.tsx +21 -34
- package/src/components/interactive-builder/droppable-container.component.tsx +5 -5
- package/src/components/interactive-builder/edit-question-modal.component.tsx +191 -233
- package/src/components/interactive-builder/editable-value.component.tsx +12 -17
- package/src/components/interactive-builder/interactive-builder.component.tsx +134 -184
- package/src/components/interactive-builder/new-form-modal.component.tsx +35 -49
- package/src/components/interactive-builder/page-modal.component.tsx +29 -45
- package/src/components/interactive-builder/question-modal.scss +7 -0
- package/src/components/interactive-builder/section-modal.component.tsx +29 -40
- package/src/components/interactive-builder/value-editor.component.tsx +11 -16
- package/src/components/modals/save-form-modal.component.tsx +112 -165
- package/src/components/pagination/index.ts +2 -2
- package/src/components/pagination/pagination.component.tsx +8 -13
- package/src/components/pagination/usePaginationInfo.ts +4 -9
- package/src/components/schema-editor/schema-editor.component.tsx +11 -17
- package/src/config-schema.ts +28 -30
- package/src/declarations.d.ts +4 -3
- package/src/form-builder-admin-card-link.component.tsx +7 -11
- package/src/forms.resource.ts +66 -87
- package/src/hooks/useClobdata.ts +10 -12
- package/src/hooks/useConceptLookup.ts +5 -8
- package/src/hooks/useConceptName.ts +6 -9
- package/src/hooks/useEncounterTypes.ts +8 -8
- package/src/hooks/useForm.ts +7 -7
- package/src/hooks/useForms.ts +5 -8
- package/src/index.ts +11 -23
- package/src/root.component.tsx +4 -4
- package/src/setup-tests.ts +1 -9
- package/src/test-helpers.tsx +8 -15
- package/src/types.ts +16 -8
- package/dist/208.js +0 -2
- package/dist/208.js.map +0 -1
- package/dist/536.js +0 -1
- package/dist/536.js.map +0 -1
- package/dist/62.js +0 -1
- package/dist/62.js.map +0 -1
- package/dist/773.js +0 -2
- package/dist/773.js.map +0 -1
- package/src/constants.ts +0 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import React, { SyntheticEvent, useCallback, useEffect, useState } from
|
|
2
|
-
import { useTranslation } from
|
|
3
|
-
import { useParams } from
|
|
1
|
+
import React, { type SyntheticEvent, useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { useParams } from 'react-router-dom';
|
|
4
4
|
import {
|
|
5
5
|
Button,
|
|
6
6
|
ComposedModal,
|
|
@@ -15,8 +15,8 @@ import {
|
|
|
15
15
|
Stack,
|
|
16
16
|
TextArea,
|
|
17
17
|
TextInput,
|
|
18
|
-
} from
|
|
19
|
-
import { navigate, showNotification, showToast } from
|
|
18
|
+
} from '@carbon/react';
|
|
19
|
+
import { navigate, showNotification, showToast } from '@openmrs/esm-framework';
|
|
20
20
|
|
|
21
21
|
import {
|
|
22
22
|
deleteClobdata,
|
|
@@ -25,46 +25,44 @@ import {
|
|
|
25
25
|
saveNewForm,
|
|
26
26
|
updateForm,
|
|
27
27
|
uploadSchema,
|
|
28
|
-
} from
|
|
29
|
-
import type { EncounterType
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
import
|
|
28
|
+
} from '../../forms.resource';
|
|
29
|
+
import type { EncounterType } from '../../types';
|
|
30
|
+
import type { Resource, Schema } from '../../types';
|
|
31
|
+
import { useEncounterTypes } from '../../hooks/useEncounterTypes';
|
|
32
|
+
import { useForm } from '../../hooks/useForm';
|
|
33
|
+
import styles from './save-form-modal.scss';
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
interface FormGroupData {
|
|
35
36
|
name: string;
|
|
36
37
|
uuid: string;
|
|
37
38
|
version: string;
|
|
38
39
|
encounterType: EncounterType;
|
|
39
40
|
description: string;
|
|
40
41
|
resources: Array<Resource>;
|
|
41
|
-
}
|
|
42
|
+
}
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
interface SaveFormModalProps {
|
|
44
45
|
form: FormGroupData;
|
|
45
46
|
schema: Schema;
|
|
46
|
-
}
|
|
47
|
+
}
|
|
47
48
|
|
|
48
49
|
const SaveFormModal: React.FC<SaveFormModalProps> = ({ form, schema }) => {
|
|
49
50
|
const { t } = useTranslation();
|
|
50
|
-
const {
|
|
51
|
+
const { encounterTypes } = useEncounterTypes();
|
|
52
|
+
const { formUuid } = useParams<{ formUuid: string }>();
|
|
51
53
|
const { mutate } = useForm(formUuid);
|
|
52
54
|
const isSavingNewForm = !formUuid;
|
|
53
|
-
const
|
|
54
|
-
const [
|
|
55
|
-
const [openConfirmSaveModal, setOpenConfirmSaveModal] = useState(false);
|
|
56
|
-
const [saveState, setSaveState] = useState("");
|
|
57
|
-
const [isSavingForm, setIsSavingForm] = useState(false);
|
|
55
|
+
const [description, setDescription] = useState('');
|
|
56
|
+
const [encounterType, setEncounterType] = useState('');
|
|
58
57
|
const [isInvalidVersion, setIsInvalidVersion] = useState(false);
|
|
59
|
-
const [
|
|
60
|
-
const [
|
|
61
|
-
const [
|
|
62
|
-
const [
|
|
58
|
+
const [isSavingForm, setIsSavingForm] = useState(false);
|
|
59
|
+
const [name, setName] = useState('');
|
|
60
|
+
const [openConfirmSaveModal, setOpenConfirmSaveModal] = useState(false);
|
|
61
|
+
const [openSaveFormModal, setOpenSaveFormModal] = useState(false);
|
|
62
|
+
const [saveState, setSaveState] = useState('');
|
|
63
|
+
const [version, setVersion] = useState('');
|
|
63
64
|
|
|
64
|
-
const clearDraftFormSchema = useCallback(
|
|
65
|
-
() => localStorage.removeItem("formSchema"),
|
|
66
|
-
[]
|
|
67
|
-
);
|
|
65
|
+
const clearDraftFormSchema = useCallback(() => localStorage.removeItem('formSchema'), []);
|
|
68
66
|
|
|
69
67
|
useEffect(() => {
|
|
70
68
|
if (schema) {
|
|
@@ -82,23 +80,21 @@ const SaveFormModal: React.FC<SaveFormModalProps> = ({ form, schema }) => {
|
|
|
82
80
|
};
|
|
83
81
|
|
|
84
82
|
const openModal = useCallback((option: string) => {
|
|
85
|
-
if (option ===
|
|
86
|
-
setSaveState(
|
|
83
|
+
if (option === 'newVersion') {
|
|
84
|
+
setSaveState('newVersion');
|
|
87
85
|
setOpenConfirmSaveModal(false);
|
|
88
86
|
setOpenSaveFormModal(true);
|
|
89
|
-
} else if (option ===
|
|
90
|
-
setSaveState(
|
|
87
|
+
} else if (option === 'new') {
|
|
88
|
+
setSaveState('newVersion');
|
|
91
89
|
setOpenSaveFormModal(true);
|
|
92
|
-
} else if (option ===
|
|
93
|
-
setSaveState(
|
|
90
|
+
} else if (option === 'update') {
|
|
91
|
+
setSaveState('update');
|
|
94
92
|
setOpenConfirmSaveModal(false);
|
|
95
93
|
setOpenSaveFormModal(true);
|
|
96
94
|
}
|
|
97
95
|
}, []);
|
|
98
96
|
|
|
99
|
-
const handleSubmit = async (
|
|
100
|
-
event: SyntheticEvent<{ name: { value: string } }>
|
|
101
|
-
) => {
|
|
97
|
+
const handleSubmit = async (event: SyntheticEvent<{ name: { value: string } }>) => {
|
|
102
98
|
event.preventDefault();
|
|
103
99
|
setIsSavingForm(true);
|
|
104
100
|
|
|
@@ -109,20 +105,14 @@ const SaveFormModal: React.FC<SaveFormModalProps> = ({ form, schema }) => {
|
|
|
109
105
|
description: { value: string };
|
|
110
106
|
};
|
|
111
107
|
|
|
112
|
-
if (saveState ===
|
|
108
|
+
if (saveState === 'new' || saveState === 'newVersion') {
|
|
113
109
|
const name = target.name.value,
|
|
114
110
|
version = target.version.value,
|
|
115
111
|
encounterType = target.encounterType.value,
|
|
116
112
|
description = target.description.value;
|
|
117
113
|
|
|
118
114
|
try {
|
|
119
|
-
const newForm = await saveNewForm(
|
|
120
|
-
name,
|
|
121
|
-
version,
|
|
122
|
-
false,
|
|
123
|
-
description,
|
|
124
|
-
encounterType
|
|
125
|
-
);
|
|
115
|
+
const newForm = await saveNewForm(name, version, false, description, encounterType);
|
|
126
116
|
|
|
127
117
|
const updatedSchema = {
|
|
128
118
|
...schema,
|
|
@@ -135,32 +125,32 @@ const SaveFormModal: React.FC<SaveFormModalProps> = ({ form, schema }) => {
|
|
|
135
125
|
|
|
136
126
|
const newValueReference = await uploadSchema(updatedSchema);
|
|
137
127
|
await getResourceUuid(newForm.uuid, newValueReference.toString());
|
|
128
|
+
|
|
138
129
|
showToast({
|
|
139
|
-
title: t(
|
|
140
|
-
kind:
|
|
130
|
+
title: t('formCreated', 'New form created'),
|
|
131
|
+
kind: 'success',
|
|
141
132
|
critical: true,
|
|
142
133
|
description:
|
|
143
|
-
name +
|
|
144
|
-
" " +
|
|
145
|
-
t(
|
|
146
|
-
"saveSuccessMessage",
|
|
147
|
-
"was created successfully. It is now visible on the Forms dashboard."
|
|
148
|
-
),
|
|
134
|
+
name + ' ' + t('saveSuccessMessage', 'was created successfully. It is now visible on the Forms dashboard.'),
|
|
149
135
|
});
|
|
150
136
|
clearDraftFormSchema();
|
|
151
137
|
setOpenSaveFormModal(false);
|
|
152
|
-
mutate();
|
|
138
|
+
await mutate();
|
|
139
|
+
|
|
153
140
|
navigate({
|
|
154
141
|
to: `${window.spaBase}/form-builder/edit/${newForm.uuid}`,
|
|
155
142
|
});
|
|
143
|
+
|
|
156
144
|
setIsSavingForm(false);
|
|
157
145
|
} catch (error) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
146
|
+
if (error instanceof Error) {
|
|
147
|
+
showNotification({
|
|
148
|
+
title: t('errorCreatingForm', 'Error creating form'),
|
|
149
|
+
kind: 'error',
|
|
150
|
+
critical: true,
|
|
151
|
+
description: error?.message,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
164
154
|
setIsSavingForm(false);
|
|
165
155
|
}
|
|
166
156
|
} else {
|
|
@@ -176,75 +166,59 @@ const SaveFormModal: React.FC<SaveFormModalProps> = ({ form, schema }) => {
|
|
|
176
166
|
await updateForm(form.uuid, name, version, description, encounterType);
|
|
177
167
|
|
|
178
168
|
if (form?.resources?.length !== 0) {
|
|
179
|
-
const existingValueReferenceUuid =
|
|
180
|
-
({ name }) => name ===
|
|
181
|
-
)?.valueReference;
|
|
169
|
+
const existingValueReferenceUuid =
|
|
170
|
+
form?.resources?.find(({ name }) => name === 'JSON schema')?.valueReference ?? '';
|
|
182
171
|
|
|
183
172
|
await deleteClobdata(existingValueReferenceUuid)
|
|
184
|
-
.catch((error) =>
|
|
185
|
-
console.error("Unable to delete clobdata: ", error)
|
|
186
|
-
)
|
|
173
|
+
.catch((error) => console.error('Unable to delete clobdata: ', error))
|
|
187
174
|
.then(() => {
|
|
188
|
-
const resourceUuidToDelete = form?.resources?.find(
|
|
189
|
-
({ name }) => name === "JSON schema"
|
|
190
|
-
)?.uuid;
|
|
175
|
+
const resourceUuidToDelete = form?.resources?.find(({ name }) => name === 'JSON schema')?.uuid ?? '';
|
|
191
176
|
|
|
192
177
|
deleteResource(form?.uuid, resourceUuidToDelete)
|
|
193
178
|
.then(() => {
|
|
194
179
|
uploadSchema(updatedSchema)
|
|
195
180
|
.then((result) => {
|
|
196
181
|
getResourceUuid(form?.uuid, result.toString())
|
|
197
|
-
.then(() => {
|
|
182
|
+
.then(async () => {
|
|
198
183
|
showToast({
|
|
199
|
-
title: t(
|
|
200
|
-
kind:
|
|
184
|
+
title: t('success', 'Success!'),
|
|
185
|
+
kind: 'success',
|
|
201
186
|
critical: true,
|
|
202
|
-
description:
|
|
203
|
-
form?.name +
|
|
204
|
-
" " +
|
|
205
|
-
t("saveSuccess", "was updated successfully"),
|
|
187
|
+
description: form?.name + ' ' + t('saveSuccess', 'was updated successfully'),
|
|
206
188
|
});
|
|
207
189
|
setOpenSaveFormModal(false);
|
|
208
|
-
mutate();
|
|
190
|
+
await mutate();
|
|
209
191
|
|
|
210
192
|
setIsSavingForm(false);
|
|
211
193
|
})
|
|
212
194
|
.catch((err) => {
|
|
213
|
-
console.error(
|
|
214
|
-
"Error associating form with new schema: ",
|
|
215
|
-
err
|
|
216
|
-
);
|
|
195
|
+
console.error('Error associating form with new schema: ', err);
|
|
217
196
|
|
|
218
197
|
showNotification({
|
|
219
|
-
title: t(
|
|
220
|
-
kind:
|
|
198
|
+
title: t('errorSavingForm', 'Unable to save form'),
|
|
199
|
+
kind: 'error',
|
|
221
200
|
critical: true,
|
|
222
201
|
description: t(
|
|
223
|
-
|
|
224
|
-
|
|
202
|
+
'saveError',
|
|
203
|
+
'There was a problem saving your form. Try saving again. To ensure you don’t lose your changes, copy them, reload the page and then paste them back into the editor.',
|
|
225
204
|
),
|
|
226
205
|
});
|
|
227
206
|
});
|
|
228
207
|
})
|
|
229
|
-
.catch((err) =>
|
|
230
|
-
console.error("Error uploading new schema: ", err)
|
|
231
|
-
);
|
|
208
|
+
.catch((err) => console.error('Error uploading new schema: ', err));
|
|
232
209
|
})
|
|
233
|
-
.catch((error) =>
|
|
234
|
-
console.error(
|
|
235
|
-
"Unable to create new clobdata resource: ",
|
|
236
|
-
error
|
|
237
|
-
)
|
|
238
|
-
);
|
|
210
|
+
.catch((error) => console.error('Unable to create new clobdata resource: ', error));
|
|
239
211
|
});
|
|
240
212
|
}
|
|
241
213
|
} catch (error) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
214
|
+
if (error instanceof Error) {
|
|
215
|
+
showNotification({
|
|
216
|
+
title: t('errorUpdatingForm', 'Error updating form'),
|
|
217
|
+
kind: 'error',
|
|
218
|
+
critical: true,
|
|
219
|
+
description: error?.message,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
248
222
|
|
|
249
223
|
setIsSavingForm(false);
|
|
250
224
|
}
|
|
@@ -259,74 +233,62 @@ const SaveFormModal: React.FC<SaveFormModalProps> = ({ form, schema }) => {
|
|
|
259
233
|
onClose={() => setOpenConfirmSaveModal(false)}
|
|
260
234
|
preventCloseOnClickOutside
|
|
261
235
|
>
|
|
262
|
-
<ModalHeader title={t(
|
|
236
|
+
<ModalHeader title={t('saveConfirmation', 'Save or Update form')} />
|
|
263
237
|
<ModalBody>
|
|
264
238
|
<p>
|
|
265
239
|
{t(
|
|
266
|
-
|
|
267
|
-
"A version of the form you're working on already exists on the server. Do you want to update the form or to save it as a new version?"
|
|
240
|
+
'saveAsModal',
|
|
241
|
+
"A version of the form you're working on already exists on the server. Do you want to update the form or to save it as a new version?",
|
|
268
242
|
)}
|
|
269
243
|
</p>
|
|
270
244
|
</ModalBody>
|
|
271
245
|
<ModalFooter>
|
|
272
|
-
<Button kind={
|
|
273
|
-
{t(
|
|
246
|
+
<Button kind={'tertiary'} onClick={() => openModal('update')}>
|
|
247
|
+
{t('updateExistingForm', 'Update existing version')}
|
|
274
248
|
</Button>
|
|
275
|
-
<Button kind={
|
|
276
|
-
{t(
|
|
249
|
+
<Button kind={'primary'} onClick={() => openModal('newVersion')}>
|
|
250
|
+
{t('saveAsNewForm', 'Save as a new')}
|
|
277
251
|
</Button>
|
|
278
|
-
<Button
|
|
279
|
-
|
|
280
|
-
onClick={() => setOpenConfirmSaveModal(false)}
|
|
281
|
-
>
|
|
282
|
-
{t("close", "Close")}
|
|
252
|
+
<Button kind={'secondary'} onClick={() => setOpenConfirmSaveModal(false)}>
|
|
253
|
+
{t('close', 'Close')}
|
|
283
254
|
</Button>
|
|
284
255
|
</ModalFooter>
|
|
285
256
|
</ComposedModal>
|
|
286
257
|
) : null}
|
|
287
258
|
|
|
288
|
-
<ComposedModal
|
|
289
|
-
|
|
290
|
-
onClose={() => setOpenSaveFormModal(false)}
|
|
291
|
-
preventCloseOnClickOutside
|
|
292
|
-
>
|
|
293
|
-
<ModalHeader
|
|
294
|
-
title={t("saveFormToServer", "Save form to server")}
|
|
295
|
-
></ModalHeader>
|
|
259
|
+
<ComposedModal open={openSaveFormModal} onClose={() => setOpenSaveFormModal(false)} preventCloseOnClickOutside>
|
|
260
|
+
<ModalHeader title={t('saveFormToServer', 'Save form to server')}></ModalHeader>
|
|
296
261
|
<Form onSubmit={handleSubmit} className={styles.saveFormBody}>
|
|
297
262
|
<ModalBody>
|
|
298
263
|
<p>
|
|
299
264
|
{t(
|
|
300
|
-
|
|
301
|
-
|
|
265
|
+
'saveExplainerText',
|
|
266
|
+
'Clicking the Save button saves your form schema to the database. To see your form in your frontend, you first need to publish it. Click the Publish button to publish your form.',
|
|
302
267
|
)}
|
|
303
268
|
</p>
|
|
304
|
-
<FormGroup legendText={
|
|
269
|
+
<FormGroup legendText={''}>
|
|
305
270
|
<Stack gap={5}>
|
|
306
271
|
<TextInput
|
|
307
272
|
id="name"
|
|
308
|
-
labelText={t(
|
|
309
|
-
onChange={(event) => setName(event.target.value)}
|
|
310
|
-
placeholder={t(
|
|
311
|
-
"formNamePlaceholder",
|
|
312
|
-
"e.g. OHRI Express Care Patient Encounter Form"
|
|
313
|
-
)}
|
|
273
|
+
labelText={t('formName', 'Form name')}
|
|
274
|
+
onChange={(event: React.ChangeEvent<HTMLInputElement>) => setName(event.target.value)}
|
|
275
|
+
placeholder={t('formNamePlaceholder', 'e.g. OHRI Express Care Patient Encounter Form')}
|
|
314
276
|
required
|
|
315
277
|
value={name}
|
|
316
278
|
/>
|
|
317
|
-
{saveState ===
|
|
279
|
+
{saveState === 'update' ? (
|
|
318
280
|
<TextInput
|
|
319
281
|
id="uuid"
|
|
320
|
-
labelText={t(
|
|
282
|
+
labelText={t('autogeneratedUuid', 'UUID (auto-generated')}
|
|
321
283
|
disabled
|
|
322
284
|
value={form?.uuid}
|
|
323
285
|
/>
|
|
324
286
|
) : null}
|
|
325
287
|
<TextInput
|
|
326
288
|
id="version"
|
|
327
|
-
labelText={t(
|
|
289
|
+
labelText={t('version', 'Version')}
|
|
328
290
|
placeholder="e.g. 1.0"
|
|
329
|
-
onChange={(event) => {
|
|
291
|
+
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
330
292
|
checkVersionValidity(event.target.value);
|
|
331
293
|
|
|
332
294
|
if (!isInvalidVersion) {
|
|
@@ -334,49 +296,39 @@ const SaveFormModal: React.FC<SaveFormModalProps> = ({ form, schema }) => {
|
|
|
334
296
|
}
|
|
335
297
|
}}
|
|
336
298
|
invalid={isInvalidVersion}
|
|
337
|
-
invalidText={t(
|
|
338
|
-
"invalidVersionWarning",
|
|
339
|
-
"Version can only start with with a number"
|
|
340
|
-
)}
|
|
299
|
+
invalidText={t('invalidVersionWarning', 'Version can only start with with a number')}
|
|
341
300
|
required
|
|
342
301
|
value={version}
|
|
343
302
|
/>
|
|
344
303
|
<Select
|
|
345
304
|
id="encounterType"
|
|
346
|
-
labelText={t(
|
|
347
|
-
onChange={(event) => setEncounterType(event.target.value)}
|
|
305
|
+
labelText={t('encounterType', 'Encounter Type')}
|
|
306
|
+
onChange={(event: React.ChangeEvent<HTMLSelectElement>) => setEncounterType(event.target.value)}
|
|
348
307
|
required
|
|
349
308
|
value={encounterType}
|
|
350
309
|
>
|
|
351
310
|
{!encounterType ? (
|
|
352
311
|
<SelectItem
|
|
353
|
-
text={t(
|
|
354
|
-
"chooseEncounterType",
|
|
355
|
-
"Choose an encounter type to link your form to"
|
|
356
|
-
)}
|
|
312
|
+
text={t('chooseEncounterType', 'Choose an encounter type to link your form to')}
|
|
357
313
|
value=""
|
|
358
314
|
/>
|
|
359
315
|
) : null}
|
|
360
316
|
{encounterTypes?.length > 0 &&
|
|
361
317
|
encounterTypes.map((encounterType) => (
|
|
362
|
-
<SelectItem
|
|
363
|
-
key={encounterType.uuid}
|
|
364
|
-
value={encounterType.uuid}
|
|
365
|
-
text={encounterType.name}
|
|
366
|
-
>
|
|
318
|
+
<SelectItem key={encounterType.uuid} value={encounterType.uuid} text={encounterType.name}>
|
|
367
319
|
{encounterType.name}
|
|
368
320
|
</SelectItem>
|
|
369
321
|
))}
|
|
370
322
|
</Select>
|
|
371
323
|
<TextArea
|
|
372
|
-
labelText={t(
|
|
373
|
-
onChange={(event) => setDescription(event.target.value)}
|
|
324
|
+
labelText={t('description', 'Description')}
|
|
325
|
+
onChange={(event: React.ChangeEvent<HTMLTextAreaElement>) => setDescription(event.target.value)}
|
|
374
326
|
cols={6}
|
|
375
327
|
rows={3}
|
|
376
328
|
id="description"
|
|
377
329
|
placeholder={t(
|
|
378
|
-
|
|
379
|
-
|
|
330
|
+
'descriptionPlaceholderText',
|
|
331
|
+
'e.g. A form used to collect encounter data for clients in the Express Care program.',
|
|
380
332
|
)}
|
|
381
333
|
required
|
|
382
334
|
value={description}
|
|
@@ -385,22 +337,19 @@ const SaveFormModal: React.FC<SaveFormModalProps> = ({ form, schema }) => {
|
|
|
385
337
|
</FormGroup>
|
|
386
338
|
</ModalBody>
|
|
387
339
|
<ModalFooter>
|
|
388
|
-
<Button
|
|
389
|
-
|
|
390
|
-
onClick={() => setOpenSaveFormModal(false)}
|
|
391
|
-
>
|
|
392
|
-
{t("close", "Close")}
|
|
340
|
+
<Button kind={'secondary'} onClick={() => setOpenSaveFormModal(false)}>
|
|
341
|
+
{t('close', 'Close')}
|
|
393
342
|
</Button>
|
|
394
343
|
<Button
|
|
395
344
|
disabled={isSavingForm || isInvalidVersion}
|
|
396
345
|
className={styles.spinner}
|
|
397
|
-
type={
|
|
398
|
-
kind={
|
|
346
|
+
type={'submit'}
|
|
347
|
+
kind={'primary'}
|
|
399
348
|
>
|
|
400
349
|
{isSavingForm ? (
|
|
401
|
-
<InlineLoading description={t(
|
|
350
|
+
<InlineLoading description={t('saving', 'Saving') + '...'} />
|
|
402
351
|
) : (
|
|
403
|
-
<span>{t(
|
|
352
|
+
<span>{t('save', 'Save')}</span>
|
|
404
353
|
)}
|
|
405
354
|
</Button>
|
|
406
355
|
</ModalFooter>
|
|
@@ -410,11 +359,9 @@ const SaveFormModal: React.FC<SaveFormModalProps> = ({ form, schema }) => {
|
|
|
410
359
|
<Button
|
|
411
360
|
disabled={!schema}
|
|
412
361
|
kind="primary"
|
|
413
|
-
onClick={() =>
|
|
414
|
-
isSavingNewForm ? openModal("new") : setOpenConfirmSaveModal(true)
|
|
415
|
-
}
|
|
362
|
+
onClick={() => (isSavingNewForm ? openModal('new') : setOpenConfirmSaveModal(true))}
|
|
416
363
|
>
|
|
417
|
-
{t(
|
|
364
|
+
{t('saveForm', 'Save form')}
|
|
418
365
|
</Button>
|
|
419
366
|
</>
|
|
420
367
|
);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
1
|
+
export * from './pagination.component';
|
|
2
|
+
export * from './usePaginationInfo';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { Pagination } from
|
|
3
|
-
import { useLayoutType } from
|
|
4
|
-
import { usePaginationInfo } from
|
|
5
|
-
import styles from
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Pagination } from '@carbon/react';
|
|
3
|
+
import { useLayoutType } from '@openmrs/esm-framework';
|
|
4
|
+
import { usePaginationInfo } from './usePaginationInfo';
|
|
5
|
+
import styles from './pagination.scss';
|
|
6
6
|
|
|
7
7
|
interface FormBuilderPaginationProps {
|
|
8
8
|
currentItems: number;
|
|
@@ -19,13 +19,8 @@ export const FormBuilderPagination: React.FC<FormBuilderPaginationProps> = ({
|
|
|
19
19
|
pageNumber,
|
|
20
20
|
currentItems,
|
|
21
21
|
}) => {
|
|
22
|
-
const { itemsDisplayed, pageSizes } = usePaginationInfo(
|
|
23
|
-
|
|
24
|
-
totalItems,
|
|
25
|
-
pageNumber,
|
|
26
|
-
currentItems
|
|
27
|
-
);
|
|
28
|
-
const isTablet = useLayoutType() === "tablet";
|
|
22
|
+
const { itemsDisplayed, pageSizes } = usePaginationInfo(pageSize, totalItems, pageNumber, currentItems);
|
|
23
|
+
const isTablet = useLayoutType() === 'tablet';
|
|
29
24
|
|
|
30
25
|
return (
|
|
31
26
|
<>
|
|
@@ -39,7 +34,7 @@ export const FormBuilderPagination: React.FC<FormBuilderPaginationProps> = ({
|
|
|
39
34
|
pageSizes={pageSizes}
|
|
40
35
|
totalItems={totalItems}
|
|
41
36
|
onChange={onPageNumberChange}
|
|
42
|
-
size={isTablet ?
|
|
37
|
+
size={isTablet ? 'lg' : 'sm'}
|
|
43
38
|
/>
|
|
44
39
|
</div>
|
|
45
40
|
)}
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
import { useMemo } from
|
|
2
|
-
import { useTranslation } from
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
3
|
|
|
4
|
-
export function usePaginationInfo(
|
|
5
|
-
pageSize: number,
|
|
6
|
-
totalItems: number,
|
|
7
|
-
pageNumber: number,
|
|
8
|
-
currentItems: number
|
|
9
|
-
) {
|
|
4
|
+
export function usePaginationInfo(pageSize: number, totalItems: number, pageNumber: number, currentItems: number) {
|
|
10
5
|
const { t } = useTranslation();
|
|
11
6
|
|
|
12
7
|
const pageSizes = useMemo(() => {
|
|
@@ -32,6 +27,6 @@ export function usePaginationInfo(
|
|
|
32
27
|
|
|
33
28
|
return {
|
|
34
29
|
pageSizes,
|
|
35
|
-
itemsDisplayed: `${numberOfItemsDisplayed} ${t(
|
|
30
|
+
itemsDisplayed: `${numberOfItemsDisplayed} ${t('items', ' items')}`,
|
|
36
31
|
};
|
|
37
32
|
}
|
|
@@ -1,37 +1,31 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import AceEditor from
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import { useTranslation } from
|
|
6
|
-
import styles from
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import AceEditor from 'react-ace';
|
|
3
|
+
import 'ace-builds/webpack-resolver';
|
|
4
|
+
import 'ace-builds/src-noconflict/ext-language_tools';
|
|
5
|
+
import { useTranslation } from 'react-i18next';
|
|
6
|
+
import styles from './schema-editor.scss';
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
interface SchemaEditorProps {
|
|
9
9
|
isLoading: boolean;
|
|
10
10
|
invalidJsonErrorMessage: string;
|
|
11
11
|
onSchemaChange: (stringifiedSchema: string) => void;
|
|
12
12
|
stringifiedSchema: string;
|
|
13
|
-
}
|
|
13
|
+
}
|
|
14
14
|
|
|
15
|
-
const SchemaEditor: React.FC<SchemaEditorProps> = ({
|
|
16
|
-
invalidJsonErrorMessage,
|
|
17
|
-
onSchemaChange,
|
|
18
|
-
stringifiedSchema,
|
|
19
|
-
}) => {
|
|
15
|
+
const SchemaEditor: React.FC<SchemaEditorProps> = ({ invalidJsonErrorMessage, onSchemaChange, stringifiedSchema }) => {
|
|
20
16
|
const { t } = useTranslation();
|
|
21
17
|
|
|
22
18
|
return (
|
|
23
19
|
<>
|
|
24
20
|
{invalidJsonErrorMessage ? (
|
|
25
21
|
<div className={styles.errorContainer}>
|
|
26
|
-
<p className={styles.heading}>
|
|
27
|
-
{t("schemaError", "There's an error in your schema.")}
|
|
28
|
-
</p>
|
|
22
|
+
<p className={styles.heading}>{t('schemaError', "There's an error in your schema.")}</p>
|
|
29
23
|
<p>{invalidJsonErrorMessage}</p>
|
|
30
24
|
</div>
|
|
31
25
|
) : null}
|
|
32
26
|
|
|
33
27
|
<AceEditor
|
|
34
|
-
style={{ height:
|
|
28
|
+
style={{ height: '100vh', width: '100%' }}
|
|
35
29
|
mode="json"
|
|
36
30
|
theme="textmate"
|
|
37
31
|
name="schemaEditor"
|