@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
package/src/config-schema.ts
CHANGED
|
@@ -1,48 +1,46 @@
|
|
|
1
|
-
import { Type } from
|
|
1
|
+
import { Type } from '@openmrs/esm-framework';
|
|
2
2
|
|
|
3
3
|
export const configSchema = {
|
|
4
4
|
questionTypes: {
|
|
5
5
|
_type: Type.Array,
|
|
6
|
-
_description:
|
|
7
|
-
"Provides information that the processor uses to render a field",
|
|
6
|
+
_description: 'Provides information that the processor uses to render a field',
|
|
8
7
|
_default: [
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
'complex-obs',
|
|
9
|
+
'control',
|
|
10
|
+
'encounterDatetime',
|
|
11
|
+
'encounterLocation',
|
|
12
|
+
'encounterProvider',
|
|
13
|
+
'obs',
|
|
14
|
+
'obsGroup',
|
|
15
|
+
'personAttribute',
|
|
16
|
+
'testOrder',
|
|
17
|
+
'patientIdentifier',
|
|
19
18
|
],
|
|
20
19
|
},
|
|
21
20
|
fieldTypes: {
|
|
22
21
|
_type: Type.Array,
|
|
23
22
|
_description:
|
|
24
|
-
|
|
23
|
+
'An array of available field types. A question can have only one field type, and the field type determines how the question is rendered.',
|
|
25
24
|
_default: [
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
25
|
+
'date',
|
|
26
|
+
'drug',
|
|
27
|
+
'field-set',
|
|
28
|
+
'file',
|
|
29
|
+
'group',
|
|
30
|
+
'multiCheckbox',
|
|
31
|
+
'number',
|
|
32
|
+
'problem',
|
|
33
|
+
'radio',
|
|
34
|
+
'repeating',
|
|
35
|
+
'select',
|
|
36
|
+
'text',
|
|
37
|
+
'textarea',
|
|
38
|
+
'ui-select-extended',
|
|
40
39
|
],
|
|
41
40
|
},
|
|
42
41
|
showSchemaSaveWarning: {
|
|
43
42
|
_type: Type.Boolean,
|
|
44
43
|
_default: true,
|
|
45
|
-
_description:
|
|
46
|
-
"Whether to show a warning about possibly losing data in the forms dashboard",
|
|
44
|
+
_description: 'Whether to show a warning about possibly losing data in the forms dashboard',
|
|
47
45
|
},
|
|
48
46
|
};
|
package/src/declarations.d.ts
CHANGED
|
@@ -1,21 +1,17 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { useTranslation } from
|
|
3
|
-
import { Layer, ClickableTile } from
|
|
4
|
-
import { ArrowRight } from
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { Layer, ClickableTile } from '@carbon/react';
|
|
4
|
+
import { ArrowRight } from '@carbon/react/icons';
|
|
5
5
|
|
|
6
6
|
const FormBuilderCardLink: React.FC = () => {
|
|
7
7
|
const { t } = useTranslation();
|
|
8
|
-
const header = t(
|
|
8
|
+
const header = t('manageForms', 'Manage Forms');
|
|
9
9
|
return (
|
|
10
10
|
<Layer>
|
|
11
|
-
<ClickableTile
|
|
12
|
-
href={`${window.spaBase}/form-builder`}
|
|
13
|
-
target="_blank"
|
|
14
|
-
rel="noopener noreferrer"
|
|
15
|
-
>
|
|
11
|
+
<ClickableTile href={`${window.spaBase}/form-builder`} target="_blank" rel="noopener noreferrer">
|
|
16
12
|
<div>
|
|
17
13
|
<div className="heading">{header}</div>
|
|
18
|
-
<div className="content">{t(
|
|
14
|
+
<div className="content">{t('formBuilder', 'Form Builder')}</div>
|
|
19
15
|
</div>
|
|
20
16
|
<div className="iconWrapper">
|
|
21
17
|
<ArrowRight size={16} />
|
package/src/forms.resource.ts
CHANGED
|
@@ -1,43 +1,38 @@
|
|
|
1
|
-
import { openmrsFetch, FetchResponse } from
|
|
2
|
-
import type { Form, Schema } from
|
|
1
|
+
import { openmrsFetch, type FetchResponse } from '@openmrs/esm-framework';
|
|
2
|
+
import type { Form, Schema } from './types';
|
|
3
|
+
|
|
4
|
+
interface SavePayload {
|
|
5
|
+
name: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
version?: string;
|
|
8
|
+
published?: boolean;
|
|
9
|
+
encounterType?: string;
|
|
10
|
+
}
|
|
3
11
|
|
|
4
|
-
export async function deleteClobdata(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
{
|
|
10
|
-
method: "DELETE",
|
|
11
|
-
headers: { "Content-Type": "application/json" },
|
|
12
|
-
}
|
|
13
|
-
);
|
|
12
|
+
export async function deleteClobdata(valueReference: string): Promise<FetchResponse<Schema>> {
|
|
13
|
+
const response: FetchResponse = await openmrsFetch(`/ws/rest/v1/clobdata/${valueReference}`, {
|
|
14
|
+
method: 'DELETE',
|
|
15
|
+
headers: { 'Content-Type': 'application/json' },
|
|
16
|
+
});
|
|
14
17
|
return response;
|
|
15
18
|
}
|
|
16
19
|
|
|
17
|
-
export async function deleteForm(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
{
|
|
23
|
-
method: "DELETE",
|
|
24
|
-
headers: { "Content-Type": "application/json" },
|
|
25
|
-
}
|
|
26
|
-
);
|
|
20
|
+
export async function deleteForm(formUuid: string): Promise<FetchResponse<Record<string, never>>> {
|
|
21
|
+
const response: FetchResponse = await openmrsFetch(`/ws/rest/v1/form/${formUuid}`, {
|
|
22
|
+
method: 'DELETE',
|
|
23
|
+
headers: { 'Content-Type': 'application/json' },
|
|
24
|
+
});
|
|
27
25
|
return response;
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
export async function deleteResource(
|
|
31
29
|
formUuid: string,
|
|
32
|
-
resourceUuid: string
|
|
30
|
+
resourceUuid: string,
|
|
33
31
|
): Promise<FetchResponse<Record<string, never>>> {
|
|
34
|
-
const response: FetchResponse = await openmrsFetch(
|
|
35
|
-
|
|
36
|
-
{
|
|
37
|
-
|
|
38
|
-
headers: { "Content-Type": "application/json" },
|
|
39
|
-
}
|
|
40
|
-
);
|
|
32
|
+
const response: FetchResponse = await openmrsFetch(`/ws/rest/v1/form/${formUuid}/resource/${resourceUuid}`, {
|
|
33
|
+
method: 'DELETE',
|
|
34
|
+
headers: { 'Content-Type': 'application/json' },
|
|
35
|
+
});
|
|
41
36
|
return response;
|
|
42
37
|
}
|
|
43
38
|
|
|
@@ -46,12 +41,12 @@ export async function uploadSchema(schema: Schema): Promise<string> {
|
|
|
46
41
|
type: undefined,
|
|
47
42
|
});
|
|
48
43
|
const body = new FormData();
|
|
49
|
-
body.append(
|
|
44
|
+
body.append('file', schemaBlob);
|
|
50
45
|
|
|
51
46
|
const response = await window
|
|
52
47
|
.fetch(`${window.openmrsBase}/ws/rest/v1/clobdata`, {
|
|
53
48
|
body,
|
|
54
|
-
method:
|
|
49
|
+
method: 'POST',
|
|
55
50
|
})
|
|
56
51
|
.then((response) => {
|
|
57
52
|
return response.text();
|
|
@@ -60,34 +55,28 @@ export async function uploadSchema(schema: Schema): Promise<string> {
|
|
|
60
55
|
return response;
|
|
61
56
|
}
|
|
62
57
|
|
|
63
|
-
export async function getResourceUuid(
|
|
64
|
-
formUuid: string,
|
|
65
|
-
valueReference: string
|
|
66
|
-
): Promise<FetchResponse<Schema>> {
|
|
58
|
+
export async function getResourceUuid(formUuid: string, valueReference: string): Promise<FetchResponse<Schema>> {
|
|
67
59
|
const body = {
|
|
68
|
-
name:
|
|
69
|
-
dataType:
|
|
60
|
+
name: 'JSON schema',
|
|
61
|
+
dataType: 'AmpathJsonSchema',
|
|
70
62
|
valueReference: valueReference,
|
|
71
63
|
};
|
|
72
64
|
|
|
73
|
-
const response: FetchResponse = await openmrsFetch(
|
|
74
|
-
|
|
75
|
-
{
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
body: body,
|
|
79
|
-
}
|
|
80
|
-
);
|
|
65
|
+
const response: FetchResponse = await openmrsFetch(`/ws/rest/v1/form/${formUuid}/resource`, {
|
|
66
|
+
method: 'POST',
|
|
67
|
+
headers: { 'Content-Type': 'application/json' },
|
|
68
|
+
body: body,
|
|
69
|
+
});
|
|
81
70
|
|
|
82
71
|
return response;
|
|
83
72
|
}
|
|
84
73
|
|
|
85
74
|
export async function updateForm(
|
|
86
|
-
formUuid,
|
|
87
|
-
name,
|
|
88
|
-
version,
|
|
89
|
-
description,
|
|
90
|
-
encounterTypeUuid
|
|
75
|
+
formUuid: string,
|
|
76
|
+
name: string,
|
|
77
|
+
version: string,
|
|
78
|
+
description: string,
|
|
79
|
+
encounterTypeUuid: string,
|
|
91
80
|
): Promise<FetchResponse<Schema>> {
|
|
92
81
|
const abortController = new AbortController();
|
|
93
82
|
const body = {
|
|
@@ -99,15 +88,12 @@ export async function updateForm(
|
|
|
99
88
|
},
|
|
100
89
|
};
|
|
101
90
|
|
|
102
|
-
const response: FetchResponse = await openmrsFetch(
|
|
103
|
-
|
|
104
|
-
{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
signal: abortController.signal,
|
|
109
|
-
}
|
|
110
|
-
);
|
|
91
|
+
const response: FetchResponse = await openmrsFetch(`/ws/rest/v1/form/${formUuid}`, {
|
|
92
|
+
method: 'POST',
|
|
93
|
+
headers: { 'Content-Type': 'application/json' },
|
|
94
|
+
body: body,
|
|
95
|
+
signal: abortController.signal,
|
|
96
|
+
});
|
|
111
97
|
|
|
112
98
|
return response;
|
|
113
99
|
}
|
|
@@ -117,25 +103,26 @@ export async function saveNewForm(
|
|
|
117
103
|
version: string,
|
|
118
104
|
published?: boolean,
|
|
119
105
|
description?: string,
|
|
120
|
-
encounterType?: string
|
|
106
|
+
encounterType?: string,
|
|
121
107
|
): Promise<Form> {
|
|
122
108
|
const abortController = new AbortController();
|
|
123
109
|
|
|
124
|
-
const body = {
|
|
110
|
+
const body: SavePayload = {
|
|
125
111
|
name: name,
|
|
126
112
|
version: version,
|
|
127
|
-
published: published
|
|
128
|
-
description: description
|
|
113
|
+
published: published ?? false,
|
|
114
|
+
description: description ?? '',
|
|
129
115
|
};
|
|
116
|
+
|
|
130
117
|
if (encounterType) {
|
|
131
|
-
body
|
|
118
|
+
body.encounterType = encounterType;
|
|
132
119
|
}
|
|
133
120
|
const headers = {
|
|
134
|
-
|
|
121
|
+
'Content-Type': 'application/json',
|
|
135
122
|
};
|
|
136
123
|
|
|
137
|
-
const response: FetchResponse = await openmrsFetch(`/ws/rest/v1/form`, {
|
|
138
|
-
method:
|
|
124
|
+
const response: FetchResponse<Form> = await openmrsFetch(`/ws/rest/v1/form`, {
|
|
125
|
+
method: 'POST',
|
|
139
126
|
headers: headers,
|
|
140
127
|
body: body,
|
|
141
128
|
signal: abortController.signal,
|
|
@@ -146,28 +133,20 @@ export async function saveNewForm(
|
|
|
146
133
|
|
|
147
134
|
export async function publishForm(uuid: string): Promise<FetchResponse<Form>> {
|
|
148
135
|
const body = { published: true };
|
|
149
|
-
const response: FetchResponse = await openmrsFetch(
|
|
150
|
-
|
|
151
|
-
{
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
body: body,
|
|
155
|
-
}
|
|
156
|
-
);
|
|
136
|
+
const response: FetchResponse = await openmrsFetch(`/ws/rest/v1/form/${uuid}`, {
|
|
137
|
+
method: 'POST',
|
|
138
|
+
headers: { 'Content-Type': 'application/json' },
|
|
139
|
+
body: body,
|
|
140
|
+
});
|
|
157
141
|
return response;
|
|
158
142
|
}
|
|
159
143
|
|
|
160
|
-
export async function unpublishForm(
|
|
161
|
-
uuid: string
|
|
162
|
-
): Promise<FetchResponse<Form>> {
|
|
144
|
+
export async function unpublishForm(uuid: string): Promise<FetchResponse<Form>> {
|
|
163
145
|
const body = { published: false };
|
|
164
|
-
const response: FetchResponse = await openmrsFetch(
|
|
165
|
-
|
|
166
|
-
{
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
body: body,
|
|
170
|
-
}
|
|
171
|
-
);
|
|
146
|
+
const response: FetchResponse = await openmrsFetch(`/ws/rest/v1/form/${uuid}`, {
|
|
147
|
+
method: 'POST',
|
|
148
|
+
headers: { 'Content-Type': 'application/json' },
|
|
149
|
+
body: body,
|
|
150
|
+
});
|
|
172
151
|
return response;
|
|
173
152
|
}
|
package/src/hooks/useClobdata.ts
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
import useSWRImmutable from
|
|
2
|
-
import { openmrsFetch } from
|
|
3
|
-
import type { Form, Schema } from
|
|
1
|
+
import useSWRImmutable from 'swr/immutable';
|
|
2
|
+
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
3
|
+
import type { Form, Schema } from '../types';
|
|
4
4
|
|
|
5
5
|
export const useClobdata = (form?: Form) => {
|
|
6
|
-
const valueReferenceUuid = form?.resources?.find(
|
|
7
|
-
|
|
8
|
-
)?.valueReference;
|
|
9
|
-
const formHasResources = form?.resources.length > 0 && valueReferenceUuid;
|
|
6
|
+
const valueReferenceUuid = form?.resources?.find(({ name }) => name === 'JSON schema')?.valueReference;
|
|
7
|
+
const formHasResources = form && form?.resources?.length > 0 && valueReferenceUuid;
|
|
10
8
|
const url = `/ws/rest/v1/clobdata/${valueReferenceUuid}`;
|
|
11
9
|
|
|
12
|
-
const { data, error, isLoading, isValidating, mutate } = useSWRImmutable<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
const { data, error, isLoading, isValidating, mutate } = useSWRImmutable<{ data: Schema }, Error>(
|
|
11
|
+
formHasResources ? url : null,
|
|
12
|
+
openmrsFetch,
|
|
13
|
+
);
|
|
16
14
|
|
|
17
15
|
return {
|
|
18
16
|
clobdata: data?.data,
|
|
19
|
-
clobdataError: error
|
|
17
|
+
clobdataError: error,
|
|
20
18
|
isLoadingClobdata: isLoading,
|
|
21
19
|
isValidatingClobdata: isValidating,
|
|
22
20
|
mutate: mutate,
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import useSWR from
|
|
2
|
-
import { openmrsFetch } from
|
|
3
|
-
import type { Concept } from
|
|
1
|
+
import useSWR from 'swr';
|
|
2
|
+
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
3
|
+
import type { Concept } from '../types';
|
|
4
4
|
|
|
5
5
|
export function useConceptLookup(conceptId: string) {
|
|
6
6
|
const url = `/ws/rest/v1/concept?q=${conceptId}&v=full`;
|
|
7
7
|
|
|
8
|
-
const { data, error } = useSWR<{ data: { results: Array<Concept> } }, Error>(
|
|
9
|
-
conceptId ? url : null,
|
|
10
|
-
openmrsFetch
|
|
11
|
-
);
|
|
8
|
+
const { data, error } = useSWR<{ data: { results: Array<Concept> } }, Error>(conceptId ? url : null, openmrsFetch);
|
|
12
9
|
|
|
13
10
|
return {
|
|
14
11
|
concepts: data?.data?.results ?? [],
|
|
15
|
-
conceptLookupError: error
|
|
12
|
+
conceptLookupError: error,
|
|
16
13
|
isLoadingConcepts: (!data && !error) || false,
|
|
17
14
|
};
|
|
18
15
|
}
|
|
@@ -1,18 +1,15 @@
|
|
|
1
|
-
import useSWR from
|
|
2
|
-
import { openmrsFetch } from
|
|
1
|
+
import useSWR from 'swr';
|
|
2
|
+
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
3
3
|
|
|
4
|
-
export function useConceptName(conceptId: string) {
|
|
5
|
-
const customRepresentation =
|
|
4
|
+
export function useConceptName(conceptId: string | undefined) {
|
|
5
|
+
const customRepresentation = 'custom:(name:(display))';
|
|
6
6
|
const url = `/ws/rest/v1/concept/${conceptId}?v=${customRepresentation}`;
|
|
7
7
|
|
|
8
|
-
const { data, error } = useSWR<
|
|
9
|
-
{ data: { name: { display: string } } },
|
|
10
|
-
Error
|
|
11
|
-
>(conceptId ? url : null, openmrsFetch);
|
|
8
|
+
const { data, error } = useSWR<{ data: { name: { display: string } } }, Error>(conceptId ? url : null, openmrsFetch);
|
|
12
9
|
|
|
13
10
|
return {
|
|
14
11
|
conceptName: data?.data?.name?.display ?? null,
|
|
15
|
-
conceptNameLookupError: error
|
|
12
|
+
conceptNameLookupError: error,
|
|
16
13
|
isLoadingConceptName: (!data && !error) || false,
|
|
17
14
|
};
|
|
18
15
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import useSWRImmutable from
|
|
2
|
-
import { openmrsFetch } from
|
|
3
|
-
import type { EncounterType } from
|
|
1
|
+
import useSWRImmutable from 'swr/immutable';
|
|
2
|
+
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
3
|
+
import type { EncounterType } from '../types';
|
|
4
4
|
|
|
5
5
|
export const useEncounterTypes = () => {
|
|
6
6
|
const url = `/ws/rest/v1/encountertype?v=custom:(uuid,name)`;
|
|
7
7
|
|
|
8
|
-
const { data, error, isLoading } = useSWRImmutable<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
const { data, error, isLoading } = useSWRImmutable<{ data: { results: Array<EncounterType> } }, Error>(
|
|
9
|
+
url,
|
|
10
|
+
openmrsFetch,
|
|
11
|
+
);
|
|
12
12
|
|
|
13
13
|
return {
|
|
14
14
|
encounterTypes: data?.data?.results ?? [],
|
|
15
|
-
encounterTypesError: error
|
|
15
|
+
encounterTypesError: error,
|
|
16
16
|
isEncounterTypesLoading: isLoading,
|
|
17
17
|
};
|
|
18
18
|
};
|
package/src/hooks/useForm.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import useSWR from
|
|
2
|
-
import { openmrsFetch } from
|
|
3
|
-
import type { Form } from
|
|
1
|
+
import useSWR from 'swr/immutable';
|
|
2
|
+
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
3
|
+
import type { Form } from '../types';
|
|
4
4
|
|
|
5
5
|
export const useForm = (uuid: string) => {
|
|
6
6
|
const url = `/ws/rest/v1/form/${uuid}?v=full`;
|
|
7
7
|
|
|
8
|
-
const { data, error, isLoading, isValidating, mutate } = useSWR<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
const { data, error, isLoading, isValidating, mutate } = useSWR<{ data: Form }, Error>(
|
|
9
|
+
uuid ? url : null,
|
|
10
|
+
openmrsFetch,
|
|
11
|
+
);
|
|
12
12
|
|
|
13
13
|
return {
|
|
14
14
|
form: data?.data,
|
package/src/hooks/useForms.ts
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import useSWR from
|
|
2
|
-
import { openmrsFetch } from
|
|
3
|
-
import type { Form } from
|
|
1
|
+
import useSWR from 'swr';
|
|
2
|
+
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
3
|
+
import type { Form } from '../types';
|
|
4
4
|
|
|
5
5
|
export function useForms() {
|
|
6
6
|
const url =
|
|
7
|
-
|
|
7
|
+
'/ws/rest/v1/form?v=custom:(uuid,name,encounterType:(uuid,name),version,published,retired,resources:(uuid,name,dataType,valueReference))';
|
|
8
8
|
|
|
9
|
-
const { data, error, isValidating, mutate } = useSWR<
|
|
10
|
-
{ data: { results: Array<Form> } },
|
|
11
|
-
Error
|
|
12
|
-
>(url, openmrsFetch);
|
|
9
|
+
const { data, error, isValidating, mutate } = useSWR<{ data: { results: Array<Form> } }, Error>(url, openmrsFetch);
|
|
13
10
|
|
|
14
11
|
return {
|
|
15
12
|
forms: data?.data?.results ?? [],
|
package/src/index.ts
CHANGED
|
@@ -1,32 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
getAsyncLifecycle,
|
|
4
|
-
registerBreadcrumbs,
|
|
5
|
-
} from "@openmrs/esm-framework";
|
|
6
|
-
import { configSchema } from "./config-schema";
|
|
1
|
+
import { defineConfigSchema, getAsyncLifecycle, registerBreadcrumbs } from '@openmrs/esm-framework';
|
|
2
|
+
import { configSchema } from './config-schema';
|
|
7
3
|
|
|
8
|
-
const moduleName =
|
|
4
|
+
const moduleName = '@openmrs/esm-form-builder-app';
|
|
9
5
|
|
|
10
6
|
const options = {
|
|
11
|
-
featureName:
|
|
7
|
+
featureName: 'form-builder',
|
|
12
8
|
moduleName,
|
|
13
9
|
};
|
|
14
10
|
|
|
15
|
-
export const importTranslation = require.context(
|
|
16
|
-
"../translations",
|
|
17
|
-
true,
|
|
18
|
-
/.json$/,
|
|
19
|
-
"lazy"
|
|
20
|
-
);
|
|
11
|
+
export const importTranslation = require.context('../translations', true, /.json$/, 'lazy');
|
|
21
12
|
|
|
22
|
-
export const root = getAsyncLifecycle(
|
|
23
|
-
() => import("./root.component"),
|
|
24
|
-
options
|
|
25
|
-
);
|
|
13
|
+
export const root = getAsyncLifecycle(() => import('./root.component'), options);
|
|
26
14
|
|
|
27
15
|
export const systemAdministrationFormBuilderCardLink = getAsyncLifecycle(
|
|
28
|
-
() => import(
|
|
29
|
-
options
|
|
16
|
+
() => import('./form-builder-admin-card-link.component'),
|
|
17
|
+
options,
|
|
30
18
|
);
|
|
31
19
|
|
|
32
20
|
export function startupApp() {
|
|
@@ -35,17 +23,17 @@ export function startupApp() {
|
|
|
35
23
|
registerBreadcrumbs([
|
|
36
24
|
{
|
|
37
25
|
path: `${window.spaBase}/form-builder`,
|
|
38
|
-
title:
|
|
26
|
+
title: 'Form Builder',
|
|
39
27
|
parent: `${window.spaBase}/home`,
|
|
40
28
|
},
|
|
41
29
|
{
|
|
42
30
|
path: `${window.spaBase}/form-builder/new`,
|
|
43
|
-
title:
|
|
31
|
+
title: 'Form Editor',
|
|
44
32
|
parent: `${window.spaBase}/form-builder`,
|
|
45
33
|
},
|
|
46
34
|
{
|
|
47
35
|
path: `${window.spaBase}/form-builder/edit/:uuid`,
|
|
48
|
-
title:
|
|
36
|
+
title: 'Form Editor',
|
|
49
37
|
parent: `${window.spaBase}/form-builder`,
|
|
50
38
|
},
|
|
51
39
|
]);
|
package/src/root.component.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { BrowserRouter, Route, Routes } from
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { BrowserRouter, Route, Routes } from 'react-router-dom';
|
|
3
3
|
|
|
4
|
-
import Dashboard from
|
|
5
|
-
import FormEditor from
|
|
4
|
+
import Dashboard from './components/dashboard/dashboard.component';
|
|
5
|
+
import FormEditor from './components/form-editor/form-editor.component';
|
|
6
6
|
|
|
7
7
|
const RootComponent: React.FC = () => {
|
|
8
8
|
return (
|
package/src/setup-tests.ts
CHANGED
package/src/test-helpers.tsx
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { SWRConfig } from
|
|
3
|
-
import {
|
|
4
|
-
render,
|
|
5
|
-
screen,
|
|
6
|
-
waitForElementToBeRemoved,
|
|
7
|
-
} from "@testing-library/react";
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SWRConfig } from 'swr';
|
|
3
|
+
import { type RenderOptions, render, screen, waitForElementToBeRemoved } from '@testing-library/react';
|
|
8
4
|
|
|
9
5
|
// This component wraps whatever component is passed to it with an SWRConfig context which provides a global configuration for all SWR hooks.
|
|
10
|
-
const swrWrapper = ({ children }) => {
|
|
6
|
+
const swrWrapper = ({ children }: { children: React.ReactNode }) => {
|
|
11
7
|
return (
|
|
12
8
|
<SWRConfig
|
|
13
9
|
value={{
|
|
@@ -23,15 +19,12 @@ const swrWrapper = ({ children }) => {
|
|
|
23
19
|
};
|
|
24
20
|
|
|
25
21
|
// Render the provided component within the wrapper we created above
|
|
26
|
-
export const renderWithSwr = (ui, options
|
|
22
|
+
export const renderWithSwr = (ui: React.ReactElement, options?: RenderOptions) =>
|
|
27
23
|
render(ui, { wrapper: swrWrapper, ...options });
|
|
28
24
|
|
|
29
25
|
// Helper function that waits for a loading state to disappear from the screen
|
|
30
26
|
export function waitForLoadingToFinish() {
|
|
31
|
-
return waitForElementToBeRemoved(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
timeout: 4000,
|
|
35
|
-
}
|
|
36
|
-
);
|
|
27
|
+
return waitForElementToBeRemoved(() => [...screen.queryAllByRole('progressbar')], {
|
|
28
|
+
timeout: 4000,
|
|
29
|
+
});
|
|
37
30
|
}
|