@tsed/react-formio 1.11.0 → 1.12.0
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/.env +2 -1
- package/craco.config.js +11 -1
- package/dist/components/alert/alert.component.spec.d.ts +1 -0
- package/dist/components/alert/alert.stories.d.ts +15 -0
- package/dist/components/card/card.component.d.ts +2 -1
- package/dist/components/form-action/formAction.stories.d.ts +90 -414
- package/dist/components/input-text/inputText.component.d.ts +1 -1
- package/dist/components/input-text/inputText.component.spec.d.ts +1 -0
- package/dist/components/loader/loader.component.d.ts +3 -3
- package/dist/components/loader/loader.stories.d.ts +15 -0
- package/dist/components/pagination/pagination.component.spec.d.ts +1 -0
- package/dist/components/pagination/pagination.stories.d.ts +0 -27
- package/dist/components/select/select.component.spec.d.ts +1 -0
- package/dist/components/tabs/tabs.component.spec.d.ts +1 -0
- package/dist/index.js +64 -32
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +62 -33
- package/dist/index.modern.js.map +1 -1
- package/jest.config.js +1 -1
- package/package.json +5 -9
- package/readme.md +74 -79
- package/src/components/__fixtures__/form-schema.json +10 -42
- package/src/components/__fixtures__/form.fixture.json +1 -1
- package/src/components/actions-table/actionsTable.component.spec.tsx +4 -13
- package/src/components/actions-table/actionsTable.component.tsx +3 -11
- package/src/components/alert/alert.component.spec.tsx +97 -0
- package/src/components/alert/alert.component.tsx +2 -8
- package/src/components/alert/alert.stories.tsx +17 -0
- package/src/components/card/card.component.tsx +2 -5
- package/src/components/form/form.component.tsx +1 -7
- package/src/components/form/useForm.hook.ts +4 -13
- package/src/components/form-access/formAccess.component.tsx +19 -82
- package/src/components/form-access/formAccess.schema.ts +7 -23
- package/src/components/form-access/formAccess.stories.tsx +2 -9
- package/src/components/form-access/formAccess.utils.spec.ts +4 -22
- package/src/components/form-access/formAccess.utils.ts +7 -29
- package/src/components/form-action/formAction.component.tsx +3 -19
- package/src/components/form-action/formAction.stories.tsx +251 -672
- package/src/components/form-builder/formBuilder.component.tsx +4 -13
- package/src/components/form-builder/formBuilder.stories.tsx +12 -24
- package/src/components/form-control/formControl.component.tsx +2 -8
- package/src/components/form-edit/formCtas.component.tsx +5 -23
- package/src/components/form-edit/formEdit.component.tsx +2 -20
- package/src/components/form-edit/formEdit.reducer.ts +2 -8
- package/src/components/form-edit/formEdit.stories.tsx +3 -15
- package/src/components/form-edit/formParameters.component.tsx +3 -20
- package/src/components/form-edit/useFormEdit.hook.ts +2 -9
- package/src/components/form-settings/formSettings.component.spec.tsx +2 -9
- package/src/components/form-settings/formSettings.component.tsx +6 -34
- package/src/components/form-settings/formSettings.stories.tsx +1 -6
- package/src/components/form-settings/formSettings.utils.spec.ts +1 -4
- package/src/components/form-settings/formSettings.utils.ts +2 -7
- package/src/components/forms-table/components/formCell.component.tsx +2 -6
- package/src/components/forms-table/formsTable.component.tsx +2 -7
- package/src/components/input-tags/inputTags.component.tsx +10 -34
- package/src/components/input-tags/inputTags.stories.tsx +4 -14
- package/src/components/input-text/inputText.component.spec.tsx +56 -0
- package/src/components/input-text/inputText.component.tsx +4 -5
- package/src/components/input-text/inputText.stories.tsx +6 -26
- package/src/components/loader/loader.component.spec.tsx +7 -6
- package/src/components/loader/loader.component.tsx +4 -13
- package/src/components/loader/loader.stories.tsx +17 -0
- package/src/components/modal/modal.component.spec.tsx +8 -14
- package/src/components/modal/modal.component.tsx +6 -27
- package/src/components/modal/modal.stories.tsx +1 -5
- package/src/components/modal/removeModal.component.tsx +4 -22
- package/src/components/pagination/pagination.component.spec.tsx +111 -0
- package/src/components/pagination/pagination.component.tsx +10 -42
- package/src/components/pagination/pagination.stories.tsx +9 -29
- package/src/components/react-component/reactComponent.component.tsx +3 -11
- package/src/components/select/select.component.spec.tsx +86 -0
- package/src/components/select/select.component.tsx +11 -15
- package/src/components/select/select.stories.tsx +6 -26
- package/src/components/submissions-table/submissionsTable.component.tsx +1 -3
- package/src/components/submissions-table/submissionsTable.stories.tsx +1 -1
- package/src/components/table/components/defaultArrowSort.component.tsx +1 -10
- package/src/components/table/components/defaultCell.component.tsx +1 -4
- package/src/components/table/components/defaultCellHeader.component.tsx +4 -14
- package/src/components/table/components/defaultCellOperations.component.tsx +14 -25
- package/src/components/table/components/defaultOperationButton.component.tsx +2 -10
- package/src/components/table/filters/defaultColumnFilter.component.spec.tsx +1 -1
- package/src/components/table/filters/selectColumnFilter.component.spec.tsx +2 -10
- package/src/components/table/filters/selectColumnFilter.component.tsx +2 -6
- package/src/components/table/table.component.tsx +13 -53
- package/src/components/table/table.stories.tsx +1 -1
- package/src/components/table/utils/getPageNumbers.ts +3 -11
- package/src/components/table/utils/mapFormToColumns.tsx +14 -22
- package/src/components/table/utils/useOperations.hook.tsx +2 -12
- package/src/components/tabs/tabs.component.spec.tsx +86 -0
- package/src/components/tabs/tabs.component.stories.tsx +2 -9
- package/src/components/tabs/tabs.component.tsx +9 -43
- package/src/interfaces/Operation.ts +1 -4
- package/src/react-table.d.ts +9 -28
- package/src/stores/action/action.actions.ts +31 -33
- package/src/stores/action/action.reducers.spec.ts +1 -8
- package/src/stores/action/action.reducers.ts +1 -8
- package/src/stores/action/action.selectors.ts +1 -2
- package/src/stores/action-info/action-info.actions.spec.ts +1 -5
- package/src/stores/action-info/action-info.actions.ts +16 -19
- package/src/stores/action-info/action-info.reducers.spec.ts +1 -6
- package/src/stores/action-info/action-info.reducers.ts +1 -6
- package/src/stores/action-info/action-info.selectors.ts +1 -4
- package/src/stores/actions/actions.actions.spec.ts +1 -6
- package/src/stores/actions/actions.actions.ts +16 -19
- package/src/stores/actions/actions.reducers.spec.ts +1 -6
- package/src/stores/actions/actions.reducers.ts +1 -6
- package/src/stores/actions/actions.selectors.ts +2 -4
- package/src/stores/auth/auth.reducers.ts +1 -4
- package/src/stores/auth/auth.selectors.spec.ts +1 -5
- package/src/stores/auth/auth.selectors.ts +3 -6
- package/src/stores/auth/auth.utils.tsx +2 -8
- package/src/stores/auth/getAccess.action.spec.ts +11 -54
- package/src/stores/auth/getAccess.action.ts +1 -6
- package/src/stores/auth/initAuth.action.ts +15 -17
- package/src/stores/form/form.actions.spec.ts +8 -39
- package/src/stores/form/form.actions.ts +55 -64
- package/src/stores/form/form.reducers.spec.ts +1 -7
- package/src/stores/form/form.reducers.ts +1 -8
- package/src/stores/form/form.selectors.ts +1 -2
- package/src/stores/forms/forms.actions.spec.ts +5 -18
- package/src/stores/forms/forms.actions.ts +17 -21
- package/src/stores/forms/forms.reducers.spec.ts +1 -6
- package/src/stores/forms/forms.reducers.ts +2 -13
- package/src/stores/forms/forms.selectors.ts +2 -4
- package/src/stores/index.spec.ts +6 -9
- package/src/stores/root/root.selectors.spec.ts +1 -6
- package/src/stores/root/root.selectors.ts +6 -24
- package/src/stores/submission/submission.actions.spec.ts +11 -33
- package/src/stores/submission/submission.actions.ts +57 -66
- package/src/stores/submission/submission.reducers.spec.ts +17 -27
- package/src/stores/submission/submission.reducers.ts +1 -4
- package/src/stores/submission/submission.selectors.ts +1 -4
- package/src/stores/submissions/submissions.actions.spec.ts +5 -18
- package/src/stores/submissions/submissions.actions.ts +17 -26
- package/src/stores/submissions/submissions.reducers.spec.ts +3 -12
- package/src/stores/submissions/submissions.reducers.ts +3 -17
- package/src/stores/submissions/submissions.selectors.spec.ts +1 -4
- package/src/stores/submissions/submissions.selectors.ts +2 -4
- package/src/utils/getEventValue.ts +1 -4
- package/src/utils/iconClass.ts +2 -10
- package/src/utils/mapPagination.ts +1 -6
- package/src/utils/mapRequestParams.ts +2 -12
- package/src/utils/url.test.ts +4 -12
- package/src/utils/url.ts +2 -7
- package/tsconfig.json +4 -12
- package/tsconfig.test.json +1 -1
- package/.eslintrc +0 -47
- package/.prettierrc +0 -10
package/jest.config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports = require("@tsed/config/jest.config");
|
|
1
|
+
module.exports = require("@tsed/config/jest.config")("react-formio");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsed/react-formio",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "Provide a react formio wrapper. Written in TypeScript.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.modern.js",
|
|
@@ -8,13 +8,10 @@
|
|
|
8
8
|
"scripts": {
|
|
9
9
|
"test": "cross-env CI=1 yarn craco test --coverage",
|
|
10
10
|
"build": "microbundle --no-compress --format modern,cjs --jsx React.createElement",
|
|
11
|
-
"watch": "microbundle watch --no-compress --format modern,cjs --jsx React.createElement"
|
|
12
|
-
"lint:fix": "yarn lint --fix",
|
|
13
|
-
"lint": "yarn eslint --config .eslintrc --cache --quiet \"./src/**/*.{ts,tsx}\"",
|
|
14
|
-
"prettier": "prettier '{src,test}/**/*.{ts,tsx}' --write"
|
|
11
|
+
"watch": "microbundle watch --no-compress --format modern,cjs --jsx React.createElement"
|
|
15
12
|
},
|
|
16
13
|
"dependencies": {
|
|
17
|
-
"@tsed/redux-utils": "1.
|
|
14
|
+
"@tsed/redux-utils": "1.12.0",
|
|
18
15
|
"eventemitter2": "^6.4.3",
|
|
19
16
|
"prop-types": "^15.7.2"
|
|
20
17
|
},
|
|
@@ -29,9 +26,8 @@
|
|
|
29
26
|
"tooltip.js": ">=1.3.3"
|
|
30
27
|
},
|
|
31
28
|
"devDependencies": {
|
|
32
|
-
"@tsed/tailwind": "1.
|
|
33
|
-
"@tsed/tailwind-formio": "1.
|
|
34
|
-
"eslint-plugin-jsx-a11y": "^6.5.1"
|
|
29
|
+
"@tsed/tailwind": "1.12.0",
|
|
30
|
+
"@tsed/tailwind-formio": "1.12.0"
|
|
35
31
|
},
|
|
36
32
|
"repository": "https://github.com/TypedProject/tsed-formio",
|
|
37
33
|
"bugs": {
|
package/readme.md
CHANGED
|
@@ -33,23 +33,23 @@ See our [storybook](https://formio.tsed.io/) to see all available components.
|
|
|
33
33
|
|
|
34
34
|
## Features
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
36
|
+
- Many components are provided to build your own backoffice based on Formio.js API:
|
|
37
|
+
- [ActionsTable](https://formio.tsed.io/?path=/story/reactformio-actionstable--sandbox),
|
|
38
|
+
- [FormAccess](https://formio.tsed.io/?path=/story/reactformio-formaccess--sandbox),
|
|
39
|
+
- [FormAction](https://formio.tsed.io/?path=/story/reactformio-formaction--sandbox),
|
|
40
|
+
- [Form](https://formio.tsed.io/?path=/story/reactformio-form--sandbox),
|
|
41
|
+
- [FormBuilder](https://formio.tsed.io/?path=/story/reactformio-formbuilder--sandbox),
|
|
42
|
+
- [FormEdit](https://formio.tsed.io/?path=/story/reactformio-formedit--sandbox),
|
|
43
|
+
- [FormsTable](https://formio.tsed.io/?path=/story/reactformio-formstable--sandbox),
|
|
44
|
+
- [InputTags](https://formio.tsed.io/?path=/story/reactformio-inputtags--sandbox),
|
|
45
|
+
- [InputText](https://formio.tsed.io/?path=/story/reactformio-inputtext--sandbox),
|
|
46
|
+
- [Pagination](https://formio.tsed.io/?path=/story/reactformio-pagination--sandbox),
|
|
47
|
+
- [Select](https://formio.tsed.io/?path=/story/reactformio-select--sandbox),
|
|
48
|
+
- [SubmissionsTable](https://formio.tsed.io/?path=/story/reactformio-subssionsstable--sandbox).
|
|
49
|
+
- [Table](https://formio.tsed.io/?path=/story/reactformio-table--sandbox),
|
|
50
|
+
- Predefined Reducers for Actions, Action, Form, Forms, Submission, Submissions, etc...,
|
|
51
|
+
- TypeScript support.
|
|
52
|
+
- Tailwind support.
|
|
53
53
|
|
|
54
54
|
## Install
|
|
55
55
|
|
|
@@ -66,30 +66,29 @@ npm install formiojs choices.js --save // Install formiojs since it is a peerDep
|
|
|
66
66
|
|
|
67
67
|
```tsx
|
|
68
68
|
import React from "react";
|
|
69
|
-
import {FormBuilder} from "@tsed/react-formio";
|
|
69
|
+
import { FormBuilder } from "@tsed/react-formio";
|
|
70
70
|
|
|
71
71
|
function App() {
|
|
72
72
|
return (
|
|
73
|
-
<div className=
|
|
74
|
-
<FormBuilder display={
|
|
73
|
+
<div className='App'>
|
|
74
|
+
<FormBuilder display={"form"} components={[]} />
|
|
75
75
|
</div>
|
|
76
76
|
);
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export default App;
|
|
80
|
-
|
|
81
80
|
```
|
|
82
81
|
|
|
83
82
|
## Components
|
|
84
83
|
|
|
85
84
|
### Form
|
|
86
85
|
|
|
87
|
-
The form component is the primary component of the system. It is what takes the form definition (json) and renders the form into html. There are multiple ways to send the form to the Form component. The two main ways are to pass the
|
|
86
|
+
The form component is the primary component of the system. It is what takes the form definition (json) and renders the form into html. There are multiple ways to send the form to the Form component. The two main ways are to pass the `src` prop with a url to the form definition, usually a form.io server. The other is to pass the `form` prop with the json definition and optionally a `url` prop with the location of the form.
|
|
88
87
|
|
|
89
88
|
#### Props
|
|
90
89
|
|
|
91
90
|
| Name | Type | Default | Description |
|
|
92
|
-
|
|
91
|
+
| ------------ | ------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
93
92
|
| `src` | url | | The url of the form definition. This is commonly from a form.io server. When using src, the form will automatically submit the data to that url as well. |
|
|
94
93
|
| `url` | url | | The url of the form definition. The form will not be loaded from this url and the submission will not be saved here either. This is used for file upload, oauth and other components or actions that need to know where the server is. Use this in connection with `form` |
|
|
95
94
|
| `form` | object | | Instead of loading a form from the `src` url, you can preload the form definition and pass it in with the `form` prop. You should also set `url` if you are using any advanced components like file upload or oauth. |
|
|
@@ -101,13 +100,13 @@ The form component is the primary component of the system. It is what takes the
|
|
|
101
100
|
You can respond to various events in the form. Simply pass in a prop with a function for one of these events.
|
|
102
101
|
|
|
103
102
|
| Name | Parameters | Description |
|
|
104
|
-
|
|
103
|
+
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
105
104
|
| `onSubmit` | `submission`: object | When the submit button is pressed and the submission has started. If `src` is not provided, this will be the final submit event. |
|
|
106
105
|
| `onSubmitDone` | `submission`: object | When the submission has successfully been made to the server. This will only fire if `src` is set. |
|
|
107
106
|
| `onChange` | `submission`: object, `submission.changed`: object of what changed, `submission.isValid`: boolean - if the submission passes validations. | A value in the submission has changed. |
|
|
108
107
|
| `onError` | `errors`: array or string or boolean | Called when an error occurs during submission such as a validation issue. |
|
|
109
108
|
| `onRender` | | Triggers when the form is finished rendering. |
|
|
110
|
-
| `onCustomEvent` | { `type`: string - event type, `component`: object - triggering component, `data`: object - data for component, `event`: string - raw event } | Event that is triggered from a button configured with "Event" type. |
|
|
109
|
+
| `onCustomEvent` | { `type`: string - event type, `component`: object - triggering component, `data`: object - data for component, `event`: string - raw event } | Event that is triggered from a button configured with "Event" type. |
|
|
111
110
|
| `onPrevPage` | { `page`: integer - new page number, `submission`: object - submission data } | Triggered for wizards when "Previous" button is pressed |
|
|
112
111
|
| `onNextPage` | { `page`: integer - new page number, `submission`: object - submission data } | Triggered for wizards when "Next" button is pressed |
|
|
113
112
|
| `onFormReady` | `formInstance`: Webform/Wizard - form class instance | Called when the form gets ready state |
|
|
@@ -119,14 +118,11 @@ You can respond to various events in the form. Simply pass in a prop with a func
|
|
|
119
118
|
Give `Form` a `src` property and render:
|
|
120
119
|
|
|
121
120
|
```tsx
|
|
122
|
-
import React from
|
|
123
|
-
import ReactDOM from
|
|
124
|
-
import {Form} from
|
|
121
|
+
import React from "react";
|
|
122
|
+
import ReactDOM from "react-dom";
|
|
123
|
+
import { Form } from "@tsed/react-formio";
|
|
125
124
|
|
|
126
|
-
ReactDOM.render(
|
|
127
|
-
<Form src="https://example.form.io/example" onSubmit={console.log} />
|
|
128
|
-
, document.getElementById('example')
|
|
129
|
-
);
|
|
125
|
+
ReactDOM.render(<Form src='https://example.form.io/example' onSubmit={console.log} />, document.getElementById("example"));
|
|
130
126
|
```
|
|
131
127
|
|
|
132
128
|
##### With form
|
|
@@ -134,53 +130,56 @@ ReactDOM.render(
|
|
|
134
130
|
Give `Form` a `src` property and render:
|
|
135
131
|
|
|
136
132
|
```tsx
|
|
137
|
-
import React from
|
|
138
|
-
import ReactDOM from
|
|
139
|
-
import {Form} from
|
|
140
|
-
|
|
133
|
+
import React from "react";
|
|
134
|
+
import ReactDOM from "react-dom";
|
|
135
|
+
import { Form } from "@tsed/react-formio";
|
|
136
|
+
|
|
141
137
|
interface MyFormData {
|
|
142
138
|
title: string;
|
|
143
|
-
}
|
|
139
|
+
}
|
|
144
140
|
|
|
145
141
|
const form = {
|
|
146
|
-
display:
|
|
142
|
+
display: "form",
|
|
147
143
|
components: [
|
|
148
144
|
{
|
|
149
|
-
key:
|
|
150
|
-
type:
|
|
145
|
+
key: "title",
|
|
146
|
+
type: "textfield"
|
|
151
147
|
}
|
|
152
148
|
]
|
|
153
|
-
}
|
|
149
|
+
};
|
|
154
150
|
|
|
155
151
|
ReactDOM.render(
|
|
156
|
-
<Form<MyFormData>
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
152
|
+
<Form<MyFormData>
|
|
153
|
+
form={form}
|
|
154
|
+
onSubmit={(submission) => {
|
|
155
|
+
console.log(submission);
|
|
156
|
+
}}
|
|
157
|
+
/>,
|
|
158
|
+
document.getElementById("example")
|
|
160
159
|
);
|
|
161
160
|
```
|
|
162
161
|
|
|
163
162
|
### FormBuilder
|
|
164
163
|
|
|
165
|
-
The [FormBuilder]([FormsTable](https://formio.tsed.io/?path=/story/reactformio-formbuilder--sandbox)) class can be used
|
|
166
|
-
to embed a form builder directly in your react application.
|
|
164
|
+
The [FormBuilder](<[FormsTable](https://formio.tsed.io/?path=/story/reactformio-formbuilder--sandbox)>) class can be used
|
|
165
|
+
to embed a form builder directly in your react application.
|
|
167
166
|
Please note that you'll need to include the CSS for the form builder from formio.js as well.
|
|
168
167
|
|
|
169
|
-
Please note that the [FormBuilder]([FormsTable](https://formio.tsed.io/?path=/story/reactformio-formbuilder--sandbox)) component
|
|
170
|
-
does not load and save from/to a url. You must handle the form definition loading and saving yourself or use
|
|
168
|
+
Please note that the [FormBuilder](<[FormsTable](https://formio.tsed.io/?path=/story/reactformio-formbuilder--sandbox)>) component
|
|
169
|
+
does not load and save from/to a url. You must handle the form definition loading and saving yourself or use
|
|
171
170
|
the [FormEdit](https://formio.tsed.io/?path=/story/reactformio-formedit--sandbox) component.
|
|
172
171
|
|
|
173
172
|
#### Props
|
|
174
173
|
|
|
175
174
|
| Name | Type | Default | Description |
|
|
176
|
-
|
|
175
|
+
| --------- | ------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
177
176
|
| `form` | object | | This is the form definition object. It should at least have a `display` property set to form, wizard or pdf. |
|
|
178
177
|
| `options` | object | | an options object that can pass options to the formio.js Form that is rendered. There are many options to be found in the formio.js library. |
|
|
179
178
|
|
|
180
179
|
#### Event Props
|
|
181
180
|
|
|
182
181
|
| Name | Parameters | Description |
|
|
183
|
-
|
|
182
|
+
| ------------------- | ------------------- | ---------------------------------------------------------------- |
|
|
184
183
|
| `onChange` | `schema`: object | Triggered any time the form definition changes |
|
|
185
184
|
| `onEditComponent` | `component`: object | Triggered when the component settings dialog is opened |
|
|
186
185
|
| `onSaveComponent` | `component`: object | Triggered when the component settings dialog is saved and closed |
|
|
@@ -191,33 +190,30 @@ the [FormEdit](https://formio.tsed.io/?path=/story/reactformio-formedit--sandbox
|
|
|
191
190
|
#### Example
|
|
192
191
|
|
|
193
192
|
```tsx
|
|
194
|
-
import React from
|
|
195
|
-
import ReactDOM from
|
|
196
|
-
import {FormBuilder} from
|
|
193
|
+
import React from "react";
|
|
194
|
+
import ReactDOM from "react-dom";
|
|
195
|
+
import { FormBuilder } from "@tsed/react-formio";
|
|
197
196
|
|
|
198
|
-
ReactDOM.render(
|
|
199
|
-
<FormBuilder form={{display: 'form'}} onChange={(schema) => console.log(schema)} />
|
|
200
|
-
, document.getElementById('builder')
|
|
201
|
-
);
|
|
197
|
+
ReactDOM.render(<FormBuilder form={{ display: "form" }} onChange={(schema) => console.log(schema)} />, document.getElementById("builder"));
|
|
202
198
|
```
|
|
203
199
|
|
|
204
200
|
### FormEdit
|
|
205
201
|
|
|
206
|
-
The [FormEdit](https://formio.tsed.io/?path=/story/reactformio-formedit--sandbox) component wraps
|
|
207
|
-
the [FormBuilder]([FormsTable](https://formio.tsed.io/?path=/story/reactformio-formbuilder--sandbox)) component and adds the title, display, name and path fields at the top along with a save button.
|
|
202
|
+
The [FormEdit](https://formio.tsed.io/?path=/story/reactformio-formedit--sandbox) component wraps
|
|
203
|
+
the [FormBuilder](<[FormsTable](https://formio.tsed.io/?path=/story/reactformio-formbuilder--sandbox)>) component and adds the title, display, name and path fields at the top along with a save button.
|
|
208
204
|
|
|
209
205
|
#### Props
|
|
210
206
|
|
|
211
|
-
| Name | Type | Default
|
|
212
|
-
|
|
213
|
-
| `form` | object | {display: 'form' \
|
|
214
|
-
| `options` | object | {}
|
|
215
|
-
| `saveText` | string | ''
|
|
207
|
+
| Name | Type | Default | Description |
|
|
208
|
+
| ---------- | ------ | ------------------- | ---------------------------------------------------- | --------------------------------------------------------------- |
|
|
209
|
+
| `form` | object | {display: 'form' \ | 'wizard'} | The form definition of the exiting form that is to be modified. |
|
|
210
|
+
| `options` | object | {} | The options to be passed to FormBuilder |
|
|
211
|
+
| `saveText` | string | '' | The string that will be displayed in the save-button |
|
|
216
212
|
|
|
217
213
|
#### Event Props
|
|
218
214
|
|
|
219
215
|
| Name | Parameters | Description |
|
|
220
|
-
|
|
216
|
+
| ---------- | ---------- | -------------------------------------------------------------------------------------- |
|
|
221
217
|
| `onSubmit` | form | Called when the save button is pressed. Will pass the form definition to the callback. |
|
|
222
218
|
|
|
223
219
|
### FormsTable
|
|
@@ -227,7 +223,7 @@ The [FormsTable](https://formio.tsed.io/?path=/story/reactformio-formstable--san
|
|
|
227
223
|
#### Props
|
|
228
224
|
|
|
229
225
|
| Name | Type | Default | Description |
|
|
230
|
-
|
|
226
|
+
| ------ | -------------- | ------- | ------------------------------------------- |
|
|
231
227
|
| `data` | array of forms | [] | A list of forms to be rendered in the grid. |
|
|
232
228
|
|
|
233
229
|
### SubmissionsTable
|
|
@@ -237,7 +233,7 @@ The submisison grid will render a list of submissions and allow clicking on one
|
|
|
237
233
|
#### Props
|
|
238
234
|
|
|
239
235
|
| Name | Type | Default | Description |
|
|
240
|
-
|
|
236
|
+
| ------ | -------------------- | ------- | -------------------------------------------------------------------------------- |
|
|
241
237
|
| `data` | array of submissions | [] | A list of submissions to be rendered in the grid. |
|
|
242
238
|
| `form` | object | {} | The form definition for the submissions. This is used to render the submissions. |
|
|
243
239
|
|
|
@@ -287,30 +283,29 @@ import { connectRouter } from "connected-react-router";
|
|
|
287
283
|
import { combineReducers } from "redux";
|
|
288
284
|
|
|
289
285
|
export const rootReducers = (history: any) =>
|
|
290
|
-
combineReducers({
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
});
|
|
286
|
+
combineReducers({
|
|
287
|
+
router: connectRouter(history),
|
|
288
|
+
...defaultFormioReducer,
|
|
289
|
+
// override defaultFormioReducer can done as following
|
|
290
|
+
...combine(
|
|
291
|
+
formsReducer("forms", { query: { type: "form", tags: ["common"] } }), // return only forms with the common tags
|
|
292
|
+
formsReducer("resources", { query: { type: "resource", tags: ["common"] } }) // return only resources with the common tags
|
|
293
|
+
)
|
|
294
|
+
});
|
|
299
295
|
```
|
|
300
296
|
|
|
301
297
|
## Contributors
|
|
298
|
+
|
|
302
299
|
Please read [contributing guidelines here](./CONTRIBUTING.md).
|
|
303
300
|
|
|
304
301
|
<a href="https://github.com/TypedProject/tsed/graphs/contributors"><img src="https://opencollective.com/tsed/contributors.svg?width=890" /></a>
|
|
305
302
|
|
|
306
|
-
|
|
307
303
|
## Backers
|
|
308
304
|
|
|
309
305
|
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/tsed#backer)]
|
|
310
306
|
|
|
311
307
|
<a href="https://opencollective.com/tsed#backers" target="_blank"><img src="https://opencollective.com/tsed/tiers/backer.svg?width=890"></a>
|
|
312
308
|
|
|
313
|
-
|
|
314
309
|
## Sponsors
|
|
315
310
|
|
|
316
311
|
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/tsed#sponsor)]
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_id": "5e972ae7a1a692917cf54f9e",
|
|
3
3
|
"type": "resource",
|
|
4
|
-
"tags": [
|
|
5
|
-
"common",
|
|
6
|
-
"products"
|
|
7
|
-
],
|
|
4
|
+
"tags": ["common", "products"],
|
|
8
5
|
"owner": null,
|
|
9
6
|
"components": [
|
|
10
7
|
{
|
|
@@ -430,70 +427,41 @@
|
|
|
430
427
|
"modified": "2020-04-15T15:40:23.647Z",
|
|
431
428
|
"access": [
|
|
432
429
|
{
|
|
433
|
-
"roles": [
|
|
434
|
-
"5e97026c50bcd9815878809a",
|
|
435
|
-
"5e97026c50bcd98158788099",
|
|
436
|
-
"5e97026c50bcd98158788098"
|
|
437
|
-
],
|
|
430
|
+
"roles": ["5e97026c50bcd9815878809a", "5e97026c50bcd98158788099", "5e97026c50bcd98158788098"],
|
|
438
431
|
"type": "read_all"
|
|
439
432
|
}
|
|
440
433
|
],
|
|
441
434
|
"submissionAccess": [
|
|
442
435
|
{
|
|
443
|
-
"roles": [
|
|
444
|
-
"5e97026c50bcd98158788098",
|
|
445
|
-
"5e97026c50bcd98158788099"
|
|
446
|
-
],
|
|
436
|
+
"roles": ["5e97026c50bcd98158788098", "5e97026c50bcd98158788099"],
|
|
447
437
|
"type": "create_all"
|
|
448
438
|
},
|
|
449
439
|
{
|
|
450
|
-
"roles": [
|
|
451
|
-
"5e97026c50bcd98158788098",
|
|
452
|
-
"5e97026c50bcd98158788099",
|
|
453
|
-
"5e97026c50bcd9815878809a"
|
|
454
|
-
],
|
|
440
|
+
"roles": ["5e97026c50bcd98158788098", "5e97026c50bcd98158788099", "5e97026c50bcd9815878809a"],
|
|
455
441
|
"type": "read_all"
|
|
456
442
|
},
|
|
457
443
|
{
|
|
458
|
-
"roles": [
|
|
459
|
-
"5e97026c50bcd98158788098",
|
|
460
|
-
"5e97026c50bcd98158788099"
|
|
461
|
-
],
|
|
444
|
+
"roles": ["5e97026c50bcd98158788098", "5e97026c50bcd98158788099"],
|
|
462
445
|
"type": "update_all"
|
|
463
446
|
},
|
|
464
447
|
{
|
|
465
|
-
"roles": [
|
|
466
|
-
"5e97026c50bcd98158788098",
|
|
467
|
-
"5e97026c50bcd98158788099"
|
|
468
|
-
],
|
|
448
|
+
"roles": ["5e97026c50bcd98158788098", "5e97026c50bcd98158788099"],
|
|
469
449
|
"type": "delete_all"
|
|
470
450
|
},
|
|
471
451
|
{
|
|
472
|
-
"roles": [
|
|
473
|
-
"5e97026c50bcd98158788098",
|
|
474
|
-
"5e97026c50bcd98158788099"
|
|
475
|
-
],
|
|
452
|
+
"roles": ["5e97026c50bcd98158788098", "5e97026c50bcd98158788099"],
|
|
476
453
|
"type": "create_own"
|
|
477
454
|
},
|
|
478
455
|
{
|
|
479
|
-
"roles": [
|
|
480
|
-
"5e97026c50bcd98158788098",
|
|
481
|
-
"5e97026c50bcd98158788099"
|
|
482
|
-
],
|
|
456
|
+
"roles": ["5e97026c50bcd98158788098", "5e97026c50bcd98158788099"],
|
|
483
457
|
"type": "read_own"
|
|
484
458
|
},
|
|
485
459
|
{
|
|
486
|
-
"roles": [
|
|
487
|
-
"5e97026c50bcd98158788098",
|
|
488
|
-
"5e97026c50bcd98158788099"
|
|
489
|
-
],
|
|
460
|
+
"roles": ["5e97026c50bcd98158788098", "5e97026c50bcd98158788099"],
|
|
490
461
|
"type": "update_own"
|
|
491
462
|
},
|
|
492
463
|
{
|
|
493
|
-
"roles": [
|
|
494
|
-
"5e97026c50bcd98158788098",
|
|
495
|
-
"5e97026c50bcd98158788099"
|
|
496
|
-
],
|
|
464
|
+
"roles": ["5e97026c50bcd98158788098", "5e97026c50bcd98158788099"],
|
|
497
465
|
"type": "delete_own"
|
|
498
466
|
}
|
|
499
467
|
],
|
|
@@ -8,9 +8,7 @@ describe("ActionsTable", () => {
|
|
|
8
8
|
it("should render the table actions", async () => {
|
|
9
9
|
const onAddAction = jest.fn();
|
|
10
10
|
|
|
11
|
-
const { getByRole, getAllByRole } = render(
|
|
12
|
-
<Sandbox {...Sandbox.args} onAddAction={onAddAction} />
|
|
13
|
-
);
|
|
11
|
+
const { getByRole, getAllByRole } = render(<Sandbox {...Sandbox.args} onAddAction={onAddAction} />);
|
|
14
12
|
|
|
15
13
|
const btn = getByRole("button", { name: /add action/i });
|
|
16
14
|
const cells = getAllByRole("cell");
|
|
@@ -27,9 +25,7 @@ describe("ActionsTable", () => {
|
|
|
27
25
|
it("should not call addAction when the default item is selected", async () => {
|
|
28
26
|
const onAddAction = jest.fn();
|
|
29
27
|
|
|
30
|
-
const { getByRole } = render(
|
|
31
|
-
<Sandbox {...Sandbox.args} onAddAction={onAddAction} />
|
|
32
|
-
);
|
|
28
|
+
const { getByRole } = render(<Sandbox {...Sandbox.args} onAddAction={onAddAction} />);
|
|
33
29
|
|
|
34
30
|
const btn = getByRole("button", { name: /add action/i });
|
|
35
31
|
|
|
@@ -39,17 +35,12 @@ describe("ActionsTable", () => {
|
|
|
39
35
|
it("should call addAction with the selected action", async () => {
|
|
40
36
|
const onAddAction = jest.fn();
|
|
41
37
|
|
|
42
|
-
const { getByRole } = render(
|
|
43
|
-
<Sandbox {...Sandbox.args} onAddAction={onAddAction} />
|
|
44
|
-
);
|
|
38
|
+
const { getByRole } = render(<Sandbox {...Sandbox.args} onAddAction={onAddAction} />);
|
|
45
39
|
|
|
46
40
|
const btn = getByRole("button", { name: /add action/i });
|
|
47
41
|
const select = getByRole("combobox");
|
|
48
42
|
|
|
49
|
-
await userEvent.selectOptions(
|
|
50
|
-
select,
|
|
51
|
-
String(Sandbox.args.availableActions[1].value)
|
|
52
|
-
);
|
|
43
|
+
await userEvent.selectOptions(select, String(Sandbox.args.availableActions[1].value));
|
|
53
44
|
|
|
54
45
|
await fireEvent.click(btn);
|
|
55
46
|
|
|
@@ -32,19 +32,12 @@ export function ActionsTable({
|
|
|
32
32
|
}, []);
|
|
33
33
|
|
|
34
34
|
return (
|
|
35
|
-
<Table
|
|
36
|
-
{...props}
|
|
37
|
-
disableFilters={disableFilters}
|
|
38
|
-
disablePagination={disablePagination}
|
|
39
|
-
columns={columns}
|
|
40
|
-
>
|
|
35
|
+
<Table {...props} disableFilters={disableFilters} disablePagination={disablePagination} columns={columns}>
|
|
41
36
|
<div className={"pagination-group"}>
|
|
42
37
|
<Select
|
|
43
38
|
name={"actions"}
|
|
44
39
|
value={currentAction}
|
|
45
|
-
choices={[{ label: i18n("Select an action"), value: "" }].concat(
|
|
46
|
-
availableActions
|
|
47
|
-
)}
|
|
40
|
+
choices={[{ label: i18n("Select an action"), value: "" }].concat(availableActions)}
|
|
48
41
|
onChange={(name: string, action: string) => setAction(action)}
|
|
49
42
|
/>
|
|
50
43
|
<div className={"pl-3"}>
|
|
@@ -55,8 +48,7 @@ export function ActionsTable({
|
|
|
55
48
|
onClick={() => currentAction && onAddAction(currentAction)}
|
|
56
49
|
type={"submit"}
|
|
57
50
|
>
|
|
58
|
-
<i className={classnames(iconClass(undefined, "plus"), "mr-1")} />{" "}
|
|
59
|
-
{i18n("Add action")}
|
|
51
|
+
<i className={classnames(iconClass(undefined, "plus"), "mr-1")} /> {i18n("Add action")}
|
|
60
52
|
</button>
|
|
61
53
|
</div>
|
|
62
54
|
</div>
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@testing-library/react";
|
|
3
|
+
import { Sandbox } from "./alert.stories";
|
|
4
|
+
|
|
5
|
+
describe("Alert component", () => {
|
|
6
|
+
it("should NOT display the alert component when no error is received.", () => {
|
|
7
|
+
const { container } = render(<Sandbox {...Sandbox.args} error={null} />);
|
|
8
|
+
|
|
9
|
+
expect(container).toBeEmptyDOMElement();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("should display an error when the error is in string format", () => {
|
|
13
|
+
const error = "error in string format";
|
|
14
|
+
const { getByRole } = render(<Sandbox {...Sandbox.args} error={error} />);
|
|
15
|
+
|
|
16
|
+
const alert = getByRole("alert") as HTMLDivElement;
|
|
17
|
+
|
|
18
|
+
expect(alert).toBeInTheDocument();
|
|
19
|
+
expect(alert).toHaveClass("alert alert-danger");
|
|
20
|
+
expect(alert).toHaveTextContent(error);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("should display error(s) when the error is an array", () => {
|
|
24
|
+
const arrayOfErrors = ["first error", "second error", "third error"];
|
|
25
|
+
const joinedErrors = arrayOfErrors.map((error) => error).join("");
|
|
26
|
+
const { getByRole, getByText } = render(<Sandbox {...Sandbox.args} error={arrayOfErrors} />);
|
|
27
|
+
|
|
28
|
+
const alert = getByRole("alert") as HTMLDivElement;
|
|
29
|
+
|
|
30
|
+
expect(alert).toBeInTheDocument();
|
|
31
|
+
expect(alert).toHaveClass("alert alert-danger");
|
|
32
|
+
expect(getByText(joinedErrors)).toBeInTheDocument();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("should display error's names paths and messages when the error is an object that has an 'errors' property that contains an array of error objects", () => {
|
|
36
|
+
const arrayOfErrors = {
|
|
37
|
+
errors: [
|
|
38
|
+
{ name: "first error", path: "/path", message: "message" },
|
|
39
|
+
{ name: "second error", path: "/path", message: "message" },
|
|
40
|
+
{ name: "third error", path: "/path", message: "message" }
|
|
41
|
+
]
|
|
42
|
+
};
|
|
43
|
+
const { getByRole } = render(<Sandbox {...Sandbox.args} error={arrayOfErrors} />);
|
|
44
|
+
|
|
45
|
+
const alert = getByRole("alert") as HTMLDivElement;
|
|
46
|
+
|
|
47
|
+
expect(alert).toBeInTheDocument();
|
|
48
|
+
expect(alert).toHaveClass("alert alert-danger");
|
|
49
|
+
expect(alert).toHaveTextContent(arrayOfErrors.errors.map((error) => `${error.name} (${error.path}) - ${error.message}`).join(""));
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("should display an error message when the error is a standard error", () => {
|
|
53
|
+
const standardError = { message: "first error" };
|
|
54
|
+
const { getByRole, getByText } = render(<Sandbox {...Sandbox.args} error={standardError} />);
|
|
55
|
+
|
|
56
|
+
const alert = getByRole("alert") as HTMLDivElement;
|
|
57
|
+
|
|
58
|
+
expect(alert).toBeInTheDocument();
|
|
59
|
+
expect(alert).toHaveClass("alert alert-danger");
|
|
60
|
+
expect(getByText(standardError.message)).toBeInTheDocument();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("should display error(s) message(s) when the error is a joi validation error", () => {
|
|
64
|
+
const joiValidationError = { name: "ValidationError", details: [{ message: "message 1" }, { message: "message 2" }] };
|
|
65
|
+
const { getByRole, getByText } = render(<Sandbox {...Sandbox.args} error={joiValidationError} />);
|
|
66
|
+
|
|
67
|
+
const alert = getByRole("alert") as HTMLDivElement;
|
|
68
|
+
|
|
69
|
+
expect(alert).toBeInTheDocument();
|
|
70
|
+
expect(alert).toHaveClass("alert alert-danger");
|
|
71
|
+
expect(getByText("message 1")).toBeInTheDocument();
|
|
72
|
+
expect(getByText("message 2")).toBeInTheDocument();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("should display a custom error message that asks to reload the form when a conflict error occurs in a form", () => {
|
|
76
|
+
const error = { _id: "some id", display: "some value" };
|
|
77
|
+
const messageReturned = "Another user has saved this form already. Please reload and re-apply your changes.";
|
|
78
|
+
const { getByRole } = render(<Sandbox {...Sandbox.args} error={error} />);
|
|
79
|
+
|
|
80
|
+
const alert = getByRole("alert") as HTMLDivElement;
|
|
81
|
+
|
|
82
|
+
expect(alert).toBeInTheDocument();
|
|
83
|
+
expect(alert).toHaveClass("alert alert-danger");
|
|
84
|
+
expect(alert).toHaveTextContent(messageReturned);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("should display an error message by default when the error format does not match any of the conditions of the formatError() handler", () => {
|
|
88
|
+
const messageError: string = "An error occurred. See console logs for details.";
|
|
89
|
+
const { getByRole } = render(<Sandbox {...Sandbox.args} error={true} />);
|
|
90
|
+
|
|
91
|
+
const alert = getByRole("alert") as HTMLDivElement;
|
|
92
|
+
|
|
93
|
+
expect(alert).toBeInTheDocument();
|
|
94
|
+
expect(alert).toHaveClass("alert alert-danger");
|
|
95
|
+
expect(alert).toHaveTextContent(messageError);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
@@ -29,20 +29,14 @@ function formatError(error: any): any {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
// If this is a joy validation error.
|
|
32
|
-
if (
|
|
33
|
-
Object.prototype.hasOwnProperty.call(error, "name") &&
|
|
34
|
-
error.name === "ValidationError"
|
|
35
|
-
) {
|
|
32
|
+
if (Object.prototype.hasOwnProperty.call(error, "name") && error.name === "ValidationError") {
|
|
36
33
|
return error.details.map((item: any, index: number) => {
|
|
37
34
|
return <div key={index}>{item.message}</div>;
|
|
38
35
|
});
|
|
39
36
|
}
|
|
40
37
|
|
|
41
38
|
// If a conflict error occurs on a form, the form is returned.
|
|
42
|
-
if (
|
|
43
|
-
Object.prototype.hasOwnProperty.call(error, "_id") &&
|
|
44
|
-
Object.prototype.hasOwnProperty.call(error, "display")
|
|
45
|
-
) {
|
|
39
|
+
if (Object.prototype.hasOwnProperty.call(error, "_id") && Object.prototype.hasOwnProperty.call(error, "display")) {
|
|
46
40
|
return "Another user has saved this form already. Please reload and re-apply your changes.";
|
|
47
41
|
}
|
|
48
42
|
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Alert } from "./alert.component";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: "ReactFormio/Alert",
|
|
6
|
+
component: Alert,
|
|
7
|
+
argTypes: {},
|
|
8
|
+
parameters: {}
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const Sandbox = (args: any) => {
|
|
12
|
+
return <Alert {...args} />;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
Sandbox.args = {
|
|
16
|
+
error: "error placeholder"
|
|
17
|
+
};
|