@openmrs/esm-form-engine-lib 3.0.0 → 3.0.1-pre.1649
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 +65 -30
- package/__mocks__/forms/rfe-forms/obs-group-test_form.json +188 -124
- package/dist/openmrs-esm-form-engine-lib.js +1 -1
- package/package.json +5 -4
- package/src/components/group/obs-group.component.tsx +5 -5
- package/src/components/inputs/content-switcher/content-switcher.component.tsx +6 -1
- package/src/components/inputs/date/date.component.tsx +1 -1
- package/src/components/inputs/multi-select/multi-select.component.tsx +4 -4
- package/src/components/inputs/number/number.component.tsx +2 -2
- package/src/components/inputs/radio/radio.component.tsx +1 -1
- package/src/components/inputs/select/dropdown.component.tsx +2 -2
- package/src/components/inputs/ui-select-extended/ui-select-extended.component.tsx +39 -18
- package/src/components/inputs/ui-select-extended/ui-select-extended.test.tsx +0 -1
- package/src/components/inputs/workspace-launcher/workspace-launcher.component.tsx +3 -1
- package/src/components/sidebar/sidebar.component.tsx +5 -6
- package/src/components/sidebar/sidebar.scss +5 -0
- package/src/components/value/value.component.tsx +4 -1
- package/src/form-engine.component.tsx +17 -13
- package/src/form-engine.scss +8 -0
- package/src/form-engine.test.tsx +44 -1
- package/src/hooks/{useConcepts.tsx → useConcepts.ts} +1 -2
- package/src/hooks/useDataSourceDependentValue.ts +1 -1
- package/src/hooks/{useEncounter.tsx → useEncounter.ts} +9 -1
- package/src/hooks/{useFormJson.tsx → useFormJson.ts} +12 -2
- package/src/hooks/{usePatientData.tsx → usePatientData.ts} +1 -1
- package/src/hooks/usePatientPrograms.ts +13 -3
- package/src/hooks/useProcessorDependencies.ts +14 -4
- package/src/types/schema.ts +5 -0
- package/src/utils/common-expression-helpers.test.ts +1 -1
- package/src/utils/common-expression-helpers.ts +10 -7
- package/translations/en.json +3 -3
- package/src/hooks/useClobData.tsx +0 -21
- package/src/hooks/useFieldValidationResults.ts +0 -18
- package/src/hooks/useFormsConfig.tsx +0 -27
- package/src/hooks/useRestMaxResultsCount.ts +0 -5
- package/src/hooks/useSystemSetting.ts +0 -36
- package/src/hooks/{useEncounterRole.tsx → useEncounterRole.ts} +1 -1
- package/src/hooks/{useFormCollapse.tsx → useFormCollapse.ts} +1 -1
package/README.md
CHANGED
@@ -6,20 +6,16 @@
|
|
6
6
|
|
7
7
|
<img src="readme/form-engine.jpeg" alt="https://raw.githubusercontent.com/openmrs/openmrs-esm-form-engine-lib/main/readme/form-engine.jpeg" >
|
8
8
|
|
9
|
-
The
|
9
|
+
The OpenMRS Form Engine is a React library that enables the creation and rendering of standardized medical forms within the OpenMRS 3 (O3) ecosystem. It provides a flexible, JSON-based form schema system with built-in validation, conditional rendering, and multilingual support - making it ideal for complex healthcare data collection needs.
|
10
10
|
|
11
|
-
and
|
11
|
+
O3 form schemas are written in JSON and conform to the [O3 standard JSON schema spec](https://github.com/openmrs/openmrs-contrib-json-schemas/blob/main/form.schema.json) which defines the structure and constraints of the form data. The [O3 reference application](https://o3.openmrs.org/openmrs/spa) ships an embedded [Form Builder](https://github.com/openmrs/openmrs-esm-form-builder) that users can leverage to build forms interactively, using the interactive schema builder, or by writing code into the built-in JSON schema editor.
|
12
12
|
|
13
|
-
|
14
|
-
- **Edit Mode** - This mode allows the user to edit data that has already been entered into the form. The form is rendered in a read-write mode.
|
15
|
-
- **View Mode** - This mode allows the user to view data that has already been entered into the form. The form is rendered in a read-only mode.
|
16
|
-
- **Embedded View** - This mode is a condensed version of the `view mode` without the section headers and form actions. It can be used to display entered form data within a widget.
|
13
|
+
The Form Engine is a versatile library that can be integrated into any frontend module within the O3 ecosystem that requires form rendering capabilities. It's currently used in the following modules:
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
You can find the full documentation for the OpenMRS Form Engine in the [OpenMRS Wiki](https://openmrs.atlassian.net/wiki/spaces/projects/pages/68747273/O3+Form+Docs).
|
15
|
+
- [Form Builder](https://github.com/openmrs/openmrs-esm-form-builder) - where the form rendering in the Form Preview component is powered by the Form Engine
|
16
|
+
- [Patient Chart](https://github.com/openmrs/openmrs-esm-patient-chart) - specifically in the form engine wrapper app where the form engine is used to render clinical forms in the patient chart workspace
|
21
17
|
|
22
|
-
Key features include:
|
18
|
+
Key features of the Form Engine include:
|
23
19
|
|
24
20
|
- **Validation** - The form engine enables the validation of form data based on the form schema. Arbitrarily complex validation rules can be defined within the schema and evaluated by the form engine.
|
25
21
|
- **Subforms** - The form engine supports the rendering of subforms within a form. This allows for the creation of complex forms that can be reused across multiple forms.
|
@@ -30,15 +26,25 @@ Key features include:
|
|
30
26
|
- **Drug orders** - The form engine facilitates drug orders by enabling the launch of the drug order basket. This feature allows users to add drugs along with medication details contained in the template for the specified drug.
|
31
27
|
- **Lab orders** - The form engine supports lab orders created using observations (obs) by utilizing the testOrders type on a specific question.
|
32
28
|
- **Markdown/ Read only fields** - The form engine includes support for read-only fields embedded within forms. These fields are utilized to provide additional information or guide users without allowing input.
|
29
|
+
- **Multiple form rendering modes** - The form engine provides several rendering modes that can be used to render forms in different contexts, including:
|
30
|
+
- **Enter Mode** - This is the default mode that allows the user to enter data into the form. The form is rendered in a read-write mode.
|
31
|
+
- **Edit Mode** - This mode allows the user to edit data that has already been entered into the form. The form is rendered in a read-write mode.
|
32
|
+
- **View Mode** - This mode allows the user to view data that has already been entered into the form. The form is rendered in a read-only mode.
|
33
|
+
- **Embedded View** - This mode is a condensed version of the `view mode` without the section headers and form actions. It can be used to display entered form data within a widget.
|
34
|
+
|
35
|
+
## Documentation
|
36
|
+
|
37
|
+
Read the full docs in the OpenMRS Wiki [here](https://openmrs.atlassian.net/wiki/spaces/projects/pages/68747273/O3+Form+Docs).
|
33
38
|
|
34
39
|
## Getting started
|
35
40
|
|
36
|
-
|
41
|
+
*NB: The Form Engine is a React library, not a standalone [O3 frontend module](https://openmrs.atlassian.net/wiki/spaces/docs/pages/151093806/Overview+of+Frontend+Modules). It can only be consumed by bundling it within a frontend module that incorporates it within a UI workflow.*
|
37
42
|
|
38
43
|
### Prerequisites
|
39
44
|
|
40
|
-
-
|
41
|
-
-
|
45
|
+
- [Node.js](https://nodejs.org/en/about/releases) 18 or later (LTS version recommended)
|
46
|
+
- [Yarn](https://yarnpkg.com/) 4.x or later (We use Yarn as our package manager)
|
47
|
+
- [Git](https://git-scm.com) (for local development)
|
42
48
|
|
43
49
|
### Installation
|
44
50
|
|
@@ -48,53 +54,75 @@ yarn add @openmrs/esm-form-engine-lib@latest
|
|
48
54
|
|
49
55
|
### Local development
|
50
56
|
|
57
|
+
#### Clone the repository
|
58
|
+
|
51
59
|
```bash
|
52
60
|
git clone git@github.com:openmrs/openmrs-esm-form-engine-lib.git
|
61
|
+
```
|
53
62
|
|
54
|
-
|
63
|
+
Or using https:
|
55
64
|
|
65
|
+
```bash
|
56
66
|
git clone https://github.com/openmrs/openmrs-esm-form-engine-lib.git
|
57
67
|
```
|
58
68
|
|
59
|
-
#### Install
|
69
|
+
#### Install dependencies
|
60
70
|
|
61
71
|
```bash
|
62
72
|
yarn
|
63
73
|
```
|
64
74
|
|
65
75
|
#### Build the library
|
76
|
+
|
77
|
+
```bash
|
78
|
+
yarn build
|
79
|
+
```
|
80
|
+
|
81
|
+
#### Link the library to the consuming frontend module
|
82
|
+
|
83
|
+
To test your local Form Engine changes, you'll need to link the library to a frontend module that uses it (like Form Builder or Patient Chart). Here's how:
|
84
|
+
|
85
|
+
1. Build the library
|
86
|
+
|
66
87
|
```bash
|
67
88
|
yarn build
|
68
89
|
```
|
69
90
|
|
70
|
-
|
91
|
+
2. Copy the relative path to the built library
|
71
92
|
|
72
|
-
|
93
|
+
Copy the relative path to the built library by running the following command on Mac:
|
73
94
|
|
74
|
-
|
75
|
-
|
95
|
+
```bash
|
96
|
+
pwd | pbcopy # copy the path to form-engine-lib to the clipboard
|
97
|
+
```
|
76
98
|
|
77
|
-
|
99
|
+
Or the equivalent command on Linux:
|
78
100
|
|
79
101
|
```bash
|
80
|
-
|
102
|
+
# Copy the path to clipboard
|
103
|
+
pwd | xclip
|
104
|
+
|
105
|
+
# Link the library using the copied path
|
106
|
+
yarn link `xclip -o`
|
81
107
|
```
|
82
108
|
|
83
|
-
|
109
|
+
3. Symlink the library to the consuming frontend module
|
110
|
+
|
111
|
+
Then run the following command from the root of the consuming frontend module. For example, if you are working on the `openmrs-esm-form-builder` module, you would navigate to the root of the module and run:
|
84
112
|
|
85
113
|
```bash
|
86
|
-
|
87
|
-
cd `path/to/openmrs-esm-form-builder`
|
88
|
-
yarn link `pbpaste` # paste the path to the openmrs-form-engine-lib
|
114
|
+
yarn link `pbpaste` # paste the path to the openmrs-form-engine-lib where `pbpaste` is the command to paste the clipboard content
|
89
115
|
```
|
90
116
|
|
91
|
-
|
117
|
+
4. Run the consuming frontend module
|
118
|
+
|
119
|
+
After linking the library, run the relevant `start` command from the frontend module. For example, if you're working on the form builder module, you would run:
|
92
120
|
|
93
121
|
```bash
|
94
122
|
yarn start
|
95
123
|
```
|
96
124
|
|
97
|
-
Whereas for the patient chart you would have to start the
|
125
|
+
Whereas for the patient chart you would have to start the Form Engine Lib frontend module like so:
|
98
126
|
|
99
127
|
```bash
|
100
128
|
yarn start --sources packages/esm-form-engine-app
|
@@ -107,7 +135,13 @@ yarn start --sources packages/esm-form-engine-app --backend https://link-to-my-b
|
|
107
135
|
```
|
108
136
|
|
109
137
|
### Production
|
110
|
-
|
138
|
+
|
139
|
+
Note that in addition to this library, other form engine alternatives exist within the O3 ecosystem, including:
|
140
|
+
|
141
|
+
- [The HTML Form Entry module](https://github.com/openmrs/openmrs-module-htmlformentry)
|
142
|
+
- [The Angular Form Engine](https://github.com/openmrs/openmrs-ngx-formentry)
|
143
|
+
|
144
|
+
To use this library as the default form engine in your O3 instance, you will need to add this to your [spa-assemble-config.json](https://github.com/openmrs/openmrs-distro-referenceapplication/blob/main/frontend/spa-assemble-config.json) file:
|
111
145
|
|
112
146
|
```json
|
113
147
|
{
|
@@ -119,11 +153,12 @@ To use the form engine as your default in your O3 instance, you will need to add
|
|
119
153
|
}
|
120
154
|
```
|
121
155
|
|
122
|
-
**NB**: *If you are currently using the
|
156
|
+
**NB**: *If you are currently using the Angular Form Engine (@openmrs/esm-form-entry-app), you will need to remove it from your importmap and replace it with the Form Engine App (@openmrs/esm-form-engine-app). The two libraries are not compatible.*
|
123
157
|
|
124
158
|
### Report an issue
|
125
159
|
|
126
|
-
https://github.com/openmrs/openmrs-esm-form-engine-lib/issues
|
160
|
+
- [File an issue](https://github.com/openmrs/openmrs-esm-form-engine-lib/issues)
|
161
|
+
- [Post in the react-form-engine Slack channel](https://openmrs.slack.com/archives/C04QZ5DDVMG)
|
127
162
|
|
128
163
|
## Contributing
|
129
164
|
|
@@ -1,137 +1,201 @@
|
|
1
1
|
{
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
"
|
20
|
-
"
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
2
|
+
"name": "ObsGroup Test Form",
|
3
|
+
"version": "1",
|
4
|
+
"published": true,
|
5
|
+
"retired": false,
|
6
|
+
"pages": [
|
7
|
+
{
|
8
|
+
"label": "Obs Group Page",
|
9
|
+
"sections": [
|
10
|
+
{
|
11
|
+
"label": "Group Section",
|
12
|
+
"isExpanded": "true",
|
13
|
+
"questions": [
|
14
|
+
{
|
15
|
+
"id": "myGroup",
|
16
|
+
"label": "My Group",
|
17
|
+
"type": "obsGroup",
|
18
|
+
"questionOptions": {
|
19
|
+
"rendering": "repeating",
|
20
|
+
"concept": "1c70c490-cafa-4c95-9fdd-a30b62bb78b8"
|
21
|
+
},
|
22
|
+
"behaviours": [
|
23
|
+
{
|
24
|
+
"intent": "*",
|
25
|
+
"required": "false",
|
26
|
+
"unspecified": "false",
|
27
|
+
"hide": {
|
28
|
+
"hideWhenExpression": ""
|
29
|
+
},
|
30
|
+
"validators": []
|
31
|
+
}
|
32
|
+
],
|
33
|
+
"questions": [
|
34
|
+
{
|
35
|
+
"label": "Sex",
|
36
|
+
"type": "obs",
|
37
|
+
"required": "true",
|
38
|
+
"questionOptions": {
|
39
|
+
"rendering": "radio",
|
40
|
+
"concept": "1587AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
41
|
+
"answers": [
|
42
|
+
{
|
43
|
+
"concept": "1535AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
44
|
+
"label": "Female"
|
45
|
+
},
|
46
|
+
{
|
47
|
+
"concept": "1534AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
48
|
+
"label": "Male"
|
49
|
+
}
|
50
|
+
]
|
51
|
+
},
|
52
|
+
"id": "childSex",
|
53
|
+
"behaviours": [
|
54
|
+
{
|
55
|
+
"intent": "*",
|
56
|
+
"required": "true",
|
57
|
+
"unspecified": "true",
|
58
|
+
"hide": {
|
59
|
+
"hideWhenExpression": "false"
|
60
|
+
},
|
61
|
+
"validators": []
|
62
|
+
}
|
63
|
+
]
|
42
64
|
},
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
"
|
48
|
-
"
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
"
|
61
|
-
"concept":"1587AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
62
|
-
"answers":[
|
65
|
+
{
|
66
|
+
"label": "Date of Birth",
|
67
|
+
"type": "obs",
|
68
|
+
"questionOptions": {
|
69
|
+
"rendering": "date",
|
70
|
+
"concept": "164802AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
71
|
+
"weeksList": ""
|
72
|
+
},
|
73
|
+
"id": "birthDate",
|
74
|
+
"behaviours": [
|
75
|
+
{
|
76
|
+
"intent": "*",
|
77
|
+
"required": "true",
|
78
|
+
"unspecified": "true",
|
79
|
+
"hide": {
|
80
|
+
"hideWhenExpression": "false"
|
81
|
+
},
|
82
|
+
"validators": [
|
63
83
|
{
|
64
|
-
"
|
65
|
-
"
|
84
|
+
"type": "date",
|
85
|
+
"allowFutureDates": "false"
|
66
86
|
},
|
67
87
|
{
|
68
|
-
"
|
69
|
-
"
|
88
|
+
"type": "js_expression",
|
89
|
+
"failsWhenExpression": "!isDateEqualTo(myValue, useFieldValue('visit_date'))",
|
90
|
+
"message": "Child birth date should be the same as the visit date!"
|
70
91
|
}
|
71
92
|
]
|
72
|
-
}
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
93
|
+
}
|
94
|
+
]
|
95
|
+
}
|
96
|
+
]
|
97
|
+
}
|
98
|
+
]
|
99
|
+
},
|
100
|
+
{
|
101
|
+
"label": "Screening Section",
|
102
|
+
"questions": [
|
103
|
+
{
|
104
|
+
"label": "Do you have dependents?",
|
105
|
+
"id": "hasDependents",
|
106
|
+
"type": "obs",
|
107
|
+
"questionOptions": {
|
108
|
+
"rendering": "radio",
|
109
|
+
"concept": "a89e3f94-1350-11df-a1f1-0026b9348837",
|
110
|
+
"answers": [
|
111
|
+
{
|
112
|
+
"concept": "a89ce50e-1350-11df-a1f1-0026b9348839",
|
113
|
+
"label": "Yes"
|
85
114
|
},
|
86
115
|
{
|
87
|
-
"
|
88
|
-
"
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
116
|
+
"concept": "a89ce50e-1350-11df-a1f1-0026b9348838",
|
117
|
+
"label": "No"
|
118
|
+
}
|
119
|
+
]
|
120
|
+
}
|
121
|
+
}
|
122
|
+
]
|
123
|
+
},
|
124
|
+
{
|
125
|
+
"label": "Groups with Hide logic",
|
126
|
+
"questions": [
|
127
|
+
{
|
128
|
+
"type": "obsGroup",
|
129
|
+
"label": "Dependents Group",
|
130
|
+
"id": "dependentGroup",
|
131
|
+
"questionOptions": {
|
132
|
+
"concept": "3665d0ef-3718-47b2-9091-8b685bda412d",
|
133
|
+
"rendering": "group"
|
134
|
+
},
|
135
|
+
"questions": [
|
136
|
+
{
|
137
|
+
"label": "Dependent Type",
|
138
|
+
"id": "dependentType",
|
139
|
+
"type": "obs",
|
140
|
+
"questionOptions": {
|
141
|
+
"rendering": "radio",
|
142
|
+
"concept": "a89e3f94-1350-11df-a1f1-0026b9348838",
|
143
|
+
"answers": [
|
96
144
|
{
|
97
|
-
"
|
98
|
-
"
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
"validators": [
|
104
|
-
{
|
105
|
-
"type": "date",
|
106
|
-
"allowFutureDates": "false"
|
107
|
-
},
|
108
|
-
{
|
109
|
-
"type": "js_expression",
|
110
|
-
"failsWhenExpression": "!isDateEqualTo(myValue, useFieldValue('visit_date'))",
|
111
|
-
"message": "Child birth date should be the same as the visit date!"
|
112
|
-
}
|
113
|
-
]
|
145
|
+
"concept": "6daff4ce-bce7-41f5-9141-17e694155180",
|
146
|
+
"label": "Child"
|
147
|
+
},
|
148
|
+
{
|
149
|
+
"concept": "a89ce50e-1350-11df-a1f1-0026b9348838",
|
150
|
+
"label": "Spouse"
|
114
151
|
}
|
115
152
|
]
|
153
|
+
},
|
154
|
+
"hide": {
|
155
|
+
"hideWhenExpression": "hasDependents !== 'a89ce50e-1350-11df-a1f1-0026b9348839'"
|
116
156
|
}
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
157
|
+
},
|
158
|
+
{
|
159
|
+
"label": "Dependent Name",
|
160
|
+
"id": "dependentName",
|
161
|
+
"type": "obs",
|
162
|
+
"questionOptions": {
|
163
|
+
"rendering": "text",
|
164
|
+
"concept": "a8a06fc6-1350-11df-a1f1-0026b9348838"
|
165
|
+
},
|
166
|
+
"hide": {
|
167
|
+
"hideWhenExpression": "isEmpty(dependentType)"
|
168
|
+
}
|
169
|
+
},
|
170
|
+
{
|
171
|
+
"label": "Dependent Age",
|
172
|
+
"id": "dependentAge",
|
173
|
+
"type": "obs",
|
174
|
+
"questionOptions": {
|
175
|
+
"rendering": "number",
|
176
|
+
"concept": "a8a06fc6-1350-11df-a1f1-0026b9348839"
|
177
|
+
},
|
178
|
+
"hide": {
|
179
|
+
"hideWhenExpression": "dependentType !== '6daff4ce-bce7-41f5-9141-17e694155180'"
|
180
|
+
}
|
181
|
+
}
|
182
|
+
]
|
183
|
+
}
|
184
|
+
]
|
185
|
+
}
|
186
|
+
]
|
187
|
+
}
|
188
|
+
],
|
189
|
+
"availableIntents": [
|
190
|
+
{
|
191
|
+
"intent": "*",
|
192
|
+
"display": "ObsGroup Test Form"
|
193
|
+
}
|
194
|
+
],
|
195
|
+
"processor": "EncounterFormProcessor",
|
196
|
+
"uuid": "8f713e0e-94a0-3c57-9024-69520933802a",
|
197
|
+
"referencedForms": [],
|
198
|
+
"encounterType": "7e54cd64-f9c3-11eb-8e6a-57478ce139b0",
|
199
|
+
"encounter": "Obs Group Test",
|
200
|
+
"allowUnspecifiedAll": true
|
201
|
+
}
|
@@ -1 +1 @@
|
|
1
|
-
var _openmrs_esm_form_engine_lib;(()=>{"use strict";var e,r,t,n,o,i,a,l,s,u,f,p,d,c,h,m,v,g,b,y,w,_={8008:(e,r,t)=>{var n={"./start":()=>Promise.all([t.e(690),t.e(585),t.e(72),t.e(
|
1
|
+
var _openmrs_esm_form_engine_lib;(()=>{"use strict";var e,r,t,n,o,i,a,l,s,u,f,p,d,c,h,m,v,g,b,y,w,_={8008:(e,r,t)=>{var n={"./start":()=>Promise.all([t.e(690),t.e(585),t.e(72),t.e(299),t.e(219)]).then((()=>()=>t(7219)))},o=(e,r)=>(t.R=r,r=t.o(n,e)?n[e]():Promise.resolve().then((()=>{throw new Error('Module "'+e+'" does not exist in container.')})),t.R=void 0,r),i=(e,r)=>{if(t.S){var n="default",o=t.S[n];if(o&&o!==e)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return t.S[n]=e,t.I(n,r)}};t.d(r,{get:()=>o,init:()=>i})}},P={};function S(e){var r=P[e];if(void 0!==r)return r.exports;var t=P[e]={id:e,loaded:!1,exports:{}};return _[e].call(t.exports,t,t.exports,S),t.loaded=!0,t.exports}S.m=_,S.c=P,S.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return S.d(r,{a:r}),r},r=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,S.t=function(t,n){if(1&n&&(t=this(t)),8&n)return t;if("object"==typeof t&&t){if(4&n&&t.__esModule)return t;if(16&n&&"function"==typeof t.then)return t}var o=Object.create(null);S.r(o);var i={};e=e||[null,r({}),r([]),r(r)];for(var a=2&n&&t;"object"==typeof a&&!~e.indexOf(a);a=r(a))Object.getOwnPropertyNames(a).forEach((e=>i[e]=()=>t[e]));return i.default=()=>t,S.d(o,i),o},S.d=(e,r)=>{for(var t in r)S.o(r,t)&&!S.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},S.f={},S.e=e=>Promise.all(Object.keys(S.f).reduce(((r,t)=>(S.f[t](e,r),r)),[])),S.u=e=>e+".js",S.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),S.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),t={},n="@openmrs/esm-form-engine-lib:",S.l=(e,r,o,i)=>{if(t[e])t[e].push(r);else{var a,l;if(void 0!==o)for(var s=document.getElementsByTagName("script"),u=0;u<s.length;u++){var f=s[u];if(f.getAttribute("src")==e||f.getAttribute("data-webpack")==n+o){a=f;break}}a||(l=!0,(a=document.createElement("script")).charset="utf-8",a.timeout=120,S.nc&&a.setAttribute("nonce",S.nc),a.setAttribute("data-webpack",n+o),a.src=e),t[e]=[r];var p=(r,n)=>{a.onerror=a.onload=null,clearTimeout(d);var o=t[e];if(delete t[e],a.parentNode&&a.parentNode.removeChild(a),o&&o.forEach((e=>e(n))),r)return r(n)},d=setTimeout(p.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=p.bind(null,a.onerror),a.onload=p.bind(null,a.onload),l&&document.head.appendChild(a)}},S.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},S.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{S.S={};var e={},r={};S.I=(t,n)=>{n||(n=[]);var o=r[t];if(o||(o=r[t]={}),!(n.indexOf(o)>=0)){if(n.push(o),e[t])return e[t];S.o(S.S,t)||(S.S[t]={});var i=S.S[t],a="@openmrs/esm-form-engine-lib",l=(e,r,t,n)=>{var o=i[e]=i[e]||{},l=o[r];(!l||!l.loaded&&(!n!=!l.eager?n:a>l.from))&&(o[r]={get:t,from:a,eager:!!n})},s=[];return"default"===t&&(l("@openmrs/esm-framework","6.0.3-pre.2587",(()=>Promise.all([S.e(151),S.e(72),S.e(766)]).then((()=>()=>S(5151))))),l("@openmrs/esm-patient-common-lib","9.0.1-pre.6367",(()=>Promise.all([S.e(806),S.e(690),S.e(72),S.e(465),S.e(299),S.e(70)]).then((()=>()=>S(806))))),l("dayjs","1.11.13",(()=>S.e(353).then((()=>()=>S(4353))))),l("i18next","23.16.0",(()=>S.e(635).then((()=>()=>S(2635))))),l("react-i18next","11.18.6",(()=>Promise.all([S.e(979),S.e(72)]).then((()=>()=>S(2979))))),l("react","18.3.1",(()=>S.e(540).then((()=>()=>S(6540))))),l("swr/_internal","2.2.5",(()=>Promise.all([S.e(993),S.e(72)]).then((()=>()=>S(4993))))),l("swr/immutable","2.2.5",(()=>Promise.all([S.e(225),S.e(72),S.e(465)]).then((()=>()=>S(4225))))),l("swr/infinite","2.2.5",(()=>Promise.all([S.e(41),S.e(72),S.e(465)]).then((()=>()=>S(3041)))))),e[t]=s.length?Promise.all(s).then((()=>e[t]=1)):1}}})(),(()=>{var e;S.g.importScripts&&(e=S.g.location+"");var r=S.g.document;if(!e&&r&&(r.currentScript&&"SCRIPT"===r.currentScript.tagName.toUpperCase()&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var n=t.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=t[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),S.p=e})(),o=e=>{var r=e=>e.split(".").map((e=>+e==e?+e:e)),t=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(e),n=t[1]?r(t[1]):[];return t[2]&&(n.length++,n.push.apply(n,r(t[2]))),t[3]&&(n.push([]),n.push.apply(n,r(t[3]))),n},i=(e,r)=>{e=o(e),r=o(r);for(var t=0;;){if(t>=e.length)return t<r.length&&"u"!=(typeof r[t])[0];var n=e[t],i=(typeof n)[0];if(t>=r.length)return"u"==i;var a=r[t],l=(typeof a)[0];if(i!=l)return"o"==i&&"n"==l||"s"==l||"u"==i;if("o"!=i&&"u"!=i&&n!=a)return n<a;t++}},a=e=>{var r=e[0],t="";if(1===e.length)return"*";if(r+.5){t+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var n=1,o=1;o<e.length;o++)n--,t+="u"==(typeof(l=e[o]))[0]?"-":(n>0?".":"")+(n=2,l);return t}var i=[];for(o=1;o<e.length;o++){var l=e[o];i.push(0===l?"not("+s()+")":1===l?"("+s()+" || "+s()+")":2===l?i.pop()+" "+i.pop():a(l))}return s();function s(){return i.pop().replace(/^\((.+)\)$/,"$1")}},l=(e,r)=>{if(0 in e){r=o(r);var t=e[0],n=t<0;n&&(t=-t-1);for(var i=0,a=1,s=!0;;a++,i++){var u,f,p=a<e.length?(typeof e[a])[0]:"";if(i>=r.length||"o"==(f=(typeof(u=r[i]))[0]))return!s||("u"==p?a>t&&!n:""==p!=n);if("u"==f){if(!s||"u"!=p)return!1}else if(s)if(p==f)if(a<=t){if(u!=e[a])return!1}else{if(n?u>e[a]:u<e[a])return!1;u!=e[a]&&(s=!1)}else if("s"!=p&&"n"!=p){if(n||a<=t)return!1;s=!1,a--}else{if(a<=t||f<p!=n)return!1;s=!1}else"s"!=p&&"n"!=p&&(s=!1,a--)}}var d=[],c=d.pop.bind(d);for(i=1;i<e.length;i++){var h=e[i];d.push(1==h?c()|c():2==h?c()&c():h?l(h,r):!c())}return!!c()},s=(e,r)=>e&&S.o(e,r),u=e=>(e.loaded=1,e.get()),f=e=>Object.keys(e).reduce(((r,t)=>(e[t].eager&&(r[t]=e[t]),r)),{}),p=(e,r,t)=>{var n=t?f(e[r]):e[r];return Object.keys(n).reduce(((e,r)=>!e||!n[e].loaded&&i(e,r)?r:e),0)},d=(e,r,t,n)=>"Unsatisfied version "+t+" from "+(t&&e[r][t].from)+" of shared singleton module "+r+" (required "+a(n)+")",c=e=>{throw new Error(e)},h=e=>{"undefined"!=typeof console&&console.warn&&console.warn(e)},m=(e,r,t)=>t?t():((e,r)=>c("Shared module "+r+" doesn't exist in shared scope "+e))(e,r),v=(e=>function(r,t,n,o,i){var a=S.I(r);return a&&a.then&&!n?a.then(e.bind(e,r,S.S[r],t,!1,o,i)):e(r,S.S[r],t,n,o,i)})(((e,r,t,n,o,i)=>{if(!s(r,t))return m(e,t,i);var a=p(r,t,n);return l(o,a)||h(d(r,t,a,o)),u(r[t][a])})),g={},b={6072:()=>v("default","react",!1,[1,18],(()=>S.e(540).then((()=>()=>S(6540))))),6766:()=>v("default","i18next",!1,[1,23],(()=>S.e(635).then((()=>()=>S(2635))))),8465:()=>v("default","swr/_internal",!1,[1,2],(()=>S.e(993).then((()=>()=>S(4993))))),2731:()=>v("default","@openmrs/esm-patient-common-lib",!1,[1,9],(()=>Promise.all([S.e(806),S.e(465)]).then((()=>()=>S(806))))),3941:()=>v("default","react-i18next",!1,[1,11],(()=>S.e(979).then((()=>()=>S(2979))))),9197:()=>v("default","@openmrs/esm-framework",!1,[1,6],(()=>Promise.all([S.e(151),S.e(766)]).then((()=>()=>S(5151))))),4209:()=>v("default","swr/immutable",!1,[1,2],(()=>Promise.all([S.e(225),S.e(465)]).then((()=>()=>S(4225))))),231:()=>v("default","dayjs",!1,[1,1],(()=>S.e(353).then((()=>()=>S(4353))))),6339:()=>v("default","swr/infinite",!1,[1,2],(()=>Promise.all([S.e(41),S.e(465)]).then((()=>()=>S(3041)))))},y={70:[4209],72:[6072],219:[231,4209,6339],299:[2731,3941,9197],465:[8465],766:[6766]},w={},S.f.consumes=(e,r)=>{S.o(y,e)&&y[e].forEach((e=>{if(S.o(g,e))return r.push(g[e]);if(!w[e]){var t=r=>{g[e]=0,S.m[e]=t=>{delete S.c[e],t.exports=r()}};w[e]=!0;var n=r=>{delete g[e],S.m[e]=t=>{throw delete S.c[e],r}};try{var o=b[e]();o.then?r.push(g[e]=o.then(t).catch(n)):t(o)}catch(e){n(e)}}}))},(()=>{var e={719:0};S.f.j=(r,t)=>{var n=S.o(e,r)?e[r]:void 0;if(0!==n)if(n)t.push(n[2]);else if(/^(299|465|72|766)$/.test(r))e[r]=0;else{var o=new Promise(((t,o)=>n=e[r]=[t,o]));t.push(n[2]=o);var i=S.p+S.u(r),a=new Error;S.l(i,(t=>{if(S.o(e,r)&&(0!==(n=e[r])&&(e[r]=void 0),n)){var o=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;a.message="Loading chunk "+r+" failed.\n("+o+": "+i+")",a.name="ChunkLoadError",a.type=o,a.request=i,n[1](a)}}),"chunk-"+r,r)}};var r=(r,t)=>{var n,o,[i,a,l]=t,s=0;if(i.some((r=>0!==e[r]))){for(n in a)S.o(a,n)&&(S.m[n]=a[n]);l&&l(S)}for(r&&r(t);s<i.length;s++)o=i[s],S.o(e,o)&&e[o]&&e[o][0](),e[o]=0},t=globalThis.webpackChunk_openmrs_esm_form_engine_lib=globalThis.webpackChunk_openmrs_esm_form_engine_lib||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),S.nc=void 0;var j=S(8008);_openmrs_esm_form_engine_lib=j})();
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@openmrs/esm-form-engine-lib",
|
3
|
-
"version": "3.0.
|
3
|
+
"version": "3.0.1-pre.1649",
|
4
4
|
"description": "React Form Engine for O3",
|
5
5
|
"browser": "dist/openmrs-esm-form-engine-lib.js",
|
6
6
|
"main": "src/index.ts",
|
@@ -39,8 +39,8 @@
|
|
39
39
|
"react-webcam": "^7.2.0"
|
40
40
|
},
|
41
41
|
"peerDependencies": {
|
42
|
-
"@openmrs/esm-framework": "
|
43
|
-
"@openmrs/esm-patient-common-lib": "
|
42
|
+
"@openmrs/esm-framework": "6.x",
|
43
|
+
"@openmrs/esm-patient-common-lib": "9.x",
|
44
44
|
"dayjs": "1.x",
|
45
45
|
"i18next": "23.x",
|
46
46
|
"react": "18.x",
|
@@ -50,6 +50,7 @@
|
|
50
50
|
"devDependencies": {
|
51
51
|
"@openmrs/esm-framework": "next",
|
52
52
|
"@openmrs/esm-patient-common-lib": "next",
|
53
|
+
"@openmrs/esm-styleguide": "next",
|
53
54
|
"@swc/cli": "^0.1.65",
|
54
55
|
"@swc/core": "^1.5.7",
|
55
56
|
"@swc/jest": "^0.2.36",
|
@@ -74,7 +75,7 @@
|
|
74
75
|
"fork-ts-checker-webpack-plugin": "^6.5.3",
|
75
76
|
"husky": "^8.0.3",
|
76
77
|
"i18next": "^23.11.4",
|
77
|
-
"i18next-parser": "^
|
78
|
+
"i18next-parser": "^9.0.2",
|
78
79
|
"identity-obj-proxy": "^3.0.0",
|
79
80
|
"jest": "^29.7.0",
|
80
81
|
"jest-cli": "^29.7.0",
|
@@ -9,13 +9,13 @@ import { useTranslation } from 'react-i18next';
|
|
9
9
|
|
10
10
|
export const ObsGroup: React.FC<FormFieldInputProps> = ({ field, ...restProps }) => {
|
11
11
|
const { t } = useTranslation();
|
12
|
-
const { formFieldAdapters } = useFormProviderContext();
|
13
|
-
const showLabel = useMemo(() => field.questions?.length > 1, [field]);
|
12
|
+
const { formFieldAdapters, formFields } = useFormProviderContext();
|
14
13
|
|
15
14
|
const content = useMemo(
|
16
15
|
() =>
|
17
16
|
field.questions
|
18
|
-
|
17
|
+
.map((child) => formFields.find((field) => field.id === child.id))
|
18
|
+
.filter((child) => !child.isHidden)
|
19
19
|
.map((child, index) => {
|
20
20
|
const key = `${child.id}_${index}`;
|
21
21
|
|
@@ -35,12 +35,12 @@ export const ObsGroup: React.FC<FormFieldInputProps> = ({ field, ...restProps })
|
|
35
35
|
);
|
36
36
|
}
|
37
37
|
}),
|
38
|
-
[field],
|
38
|
+
[field, formFields],
|
39
39
|
);
|
40
40
|
|
41
41
|
return (
|
42
42
|
<div className={styles.groupContainer}>
|
43
|
-
{
|
43
|
+
{content.length > 1 ? (
|
44
44
|
<FormGroup legendText={t(field.label)} className={styles.boldLegend}>
|
45
45
|
{content}
|
46
46
|
</FormGroup>
|