@evoke-platform/ui-components 1.0.0-dev.229 → 1.0.0-dev.231
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/dist/published/components/custom/Form/Common/Form.js +5 -5
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentComponent.d.ts +1 -0
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentComponent.js +3 -14
- package/dist/published/components/custom/Form/FormComponents/FormFieldComponent.d.ts +1 -0
- package/dist/published/components/custom/Form/FormComponents/FormFieldComponent.js +3 -14
- package/dist/published/components/custom/Form/FormComponents/ImageComponent/ImageComponent.d.ts +1 -0
- package/dist/published/components/custom/Form/FormComponents/ImageComponent/ImageComponent.js +12 -24
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectComponent.d.ts +2 -0
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectComponent.js +13 -25
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectPropertyInput.js +3 -3
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/RelatedObjectInstance.d.ts +2 -0
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/RelatedObjectInstance.js +2 -2
- package/dist/published/components/custom/Form/FormComponents/UserComponent/UserComponent.d.ts +1 -0
- package/dist/published/components/custom/Form/FormComponents/UserComponent/UserComponent.js +15 -27
- package/dist/published/components/custom/Form/FormComponents/ViewOnlyComponent.d.ts +1 -0
- package/dist/published/components/custom/Form/FormComponents/ViewOnlyComponent.js +8 -6
- package/dist/published/components/custom/Form/types.d.ts +2 -0
- package/dist/published/components/custom/Form/utils.d.ts +3 -2
- package/dist/published/components/custom/Form/utils.js +17 -4
- package/package.json +1 -1
@@ -36,7 +36,7 @@ export function Form(props) {
|
|
36
36
|
ViewOnlyTextField: ViewOnlyComponent,
|
37
37
|
ViewOnlyDecimal: ViewOnlyComponent,
|
38
38
|
ViewOnlyInteger: ViewOnlyComponent,
|
39
|
-
ViewOnlyRichText: richTextEditor,
|
39
|
+
ViewOnlyRichText: richTextEditor ?? ViewOnlyComponent,
|
40
40
|
ViewOnlySection: Components.components.fieldset,
|
41
41
|
ViewOnlyManyToManyRepeatableField: RepeatableFieldComponent,
|
42
42
|
ViewOnlyRepeatableField: RepeatableFieldComponent,
|
@@ -59,7 +59,7 @@ export function Form(props) {
|
|
59
59
|
Integer: FormFieldComponent,
|
60
60
|
Buttons: ButtonComponent,
|
61
61
|
Content: Components.components.content,
|
62
|
-
RichText: richTextEditor,
|
62
|
+
RichText: richTextEditor ?? FormFieldComponent,
|
63
63
|
Section: Components.components.tabs,
|
64
64
|
ManyToManyRepeatableField: RepeatableFieldComponent,
|
65
65
|
RepeatableField: RepeatableFieldComponent,
|
@@ -124,7 +124,7 @@ export function Form(props) {
|
|
124
124
|
navigateTo,
|
125
125
|
apiServices,
|
126
126
|
user: userAccount,
|
127
|
-
}, undefined, isReadOnly, allDefaultPages, navigateTo, queryAddresses, apiServices, !!closeModal, fieldHeight);
|
127
|
+
}, undefined, isReadOnly, allDefaultPages, navigateTo, queryAddresses, apiServices, !!closeModal, fieldHeight, richTextEditor);
|
128
128
|
const components = isReadOnly ? newComponentProps : [...newComponentProps, BottomButtons];
|
129
129
|
setComponentProps(components);
|
130
130
|
}
|
@@ -205,7 +205,7 @@ export function Form(props) {
|
|
205
205
|
navigateTo,
|
206
206
|
apiServices,
|
207
207
|
user: userAccount,
|
208
|
-
}, undefined, undefined, undefined, undefined, undefined, undefined, !!closeModal, fieldHeight)),
|
208
|
+
}, undefined, undefined, undefined, undefined, undefined, undefined, !!closeModal, fieldHeight, richTextEditor)),
|
209
209
|
BottomButtons,
|
210
210
|
]);
|
211
211
|
}
|
@@ -221,7 +221,7 @@ export function Form(props) {
|
|
221
221
|
navigateTo,
|
222
222
|
apiServices,
|
223
223
|
user,
|
224
|
-
}, !!action, undefined, isReadOnly, queryAddresses, !!closeModal, fieldHeight),
|
224
|
+
}, !!action, undefined, isReadOnly, queryAddresses, !!closeModal, fieldHeight, richTextEditor),
|
225
225
|
!isReadOnly && BottomButtons,
|
226
226
|
]);
|
227
227
|
}
|
package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentComponent.js
CHANGED
@@ -28,20 +28,6 @@ export class DocumentComponent extends ReactComponent {
|
|
28
28
|
this.handleChange = this.handleChange.bind(this);
|
29
29
|
}
|
30
30
|
init() {
|
31
|
-
this.on('changed-' + this.component.conditional.when, (value) => {
|
32
|
-
// set default value when conditional field is shown
|
33
|
-
if (this.component.defaultValue && value === this.component.conditional.eq) {
|
34
|
-
this.setValue(this.component.defaultValue);
|
35
|
-
this.updateValue(this.component.defaultValue, { modified: true });
|
36
|
-
}
|
37
|
-
// clear data and errors when a true conditional field is hidden
|
38
|
-
if (this.component.conditional.show && value !== this.component.conditional.eq) {
|
39
|
-
this.setValue('');
|
40
|
-
this.updateValue('', { modified: true });
|
41
|
-
this.clearErrors();
|
42
|
-
super.detach();
|
43
|
-
}
|
44
|
-
});
|
45
31
|
this.on(`api-error`, (details) => {
|
46
32
|
const error = details.find((detail) => detail.code === 'errorMessage' && detail.path.replace('/', '') === this.component.key);
|
47
33
|
if (error) {
|
@@ -147,4 +133,7 @@ export class DocumentComponent extends ReactComponent {
|
|
147
133
|
React.createElement(FormComponentWrapper, { ...this.component, inputId: inputId, viewOnly: !this.component.canUpdateProperty, errorMessage: this.errorMessages() },
|
148
134
|
React.createElement(Document, { ...this.component, id: inputId, handleChange: this.handleChange, error: this.hasErrors(), value: this.dataValue }))), root);
|
149
135
|
}
|
136
|
+
detachReact(element) {
|
137
|
+
ReactDOM.unmountComponentAtNode(element);
|
138
|
+
}
|
150
139
|
}
|
@@ -38,5 +38,6 @@ export declare class FormFieldComponent extends ReactComponent {
|
|
38
38
|
handleComponentChange: (components: any, value: any) => void;
|
39
39
|
handleChange: (key: string, value: any) => void;
|
40
40
|
attachReact(element: Element): void;
|
41
|
+
detachReact(element: Element): void;
|
41
42
|
}
|
42
43
|
export {};
|
@@ -145,20 +145,6 @@ export class FormFieldComponent extends ReactComponent {
|
|
145
145
|
this.handleChange = this.handleChange.bind(this);
|
146
146
|
}
|
147
147
|
init() {
|
148
|
-
this.on('changed-' + this.component.conditional.when, (value) => {
|
149
|
-
//set default value when conditional field is shown
|
150
|
-
if (this.component.defaultValue && value === this.component.conditional.eq) {
|
151
|
-
this.setValue(this.component.defaultValue);
|
152
|
-
this.updateValue(this.component.defaultValue, { modified: true });
|
153
|
-
}
|
154
|
-
//clear data and errors when a true conditional field is hidden
|
155
|
-
if (value !== this.component.conditional.eq) {
|
156
|
-
this.setValue('');
|
157
|
-
this.updateValue('', { modified: true });
|
158
|
-
this.clearErrors();
|
159
|
-
super.detach();
|
160
|
-
}
|
161
|
-
});
|
162
148
|
if (this.component.key.includes('.city') ||
|
163
149
|
this.component.key.includes('.county') ||
|
164
150
|
this.component.key.includes('.state') ||
|
@@ -481,4 +467,7 @@ export class FormFieldComponent extends ReactComponent {
|
|
481
467
|
this.emit('changed-' + this.component.key, e.target.value);
|
482
468
|
}, ...this.component, id: inputId, defaultValue: this.dataValue, mask: this.component.inputMask, error: this.hasErrors(), size: this.component.fieldHeight ?? 'medium' }))), root);
|
483
469
|
}
|
470
|
+
detachReact(element) {
|
471
|
+
ReactDOM.unmountComponentAtNode(element);
|
472
|
+
}
|
484
473
|
}
|
package/dist/published/components/custom/Form/FormComponents/ImageComponent/ImageComponent.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { ReactComponent } from '@formio/react';
|
2
2
|
import { isEmpty } from 'lodash';
|
3
3
|
import React from 'react';
|
4
|
-
import
|
4
|
+
import ReactDOM from 'react-dom';
|
5
5
|
import { FormComponentWrapper } from '../../Common';
|
6
6
|
import { isPropertyVisible } from '../../utils';
|
7
7
|
import { Image } from './Image';
|
@@ -27,25 +27,6 @@ export class ImageComponent extends ReactComponent {
|
|
27
27
|
this.handleChange = this.handleChange.bind(this);
|
28
28
|
}
|
29
29
|
init() {
|
30
|
-
this.on('changed-' + this.component.conditional.when, (value) => {
|
31
|
-
//set default value when conditional field is shown
|
32
|
-
if (this.component.defaultValue && value === this.component.conditional.eq) {
|
33
|
-
this.setValue(this.component.defaultValue);
|
34
|
-
this.updateValue(this.component.defaultValue, { modified: true });
|
35
|
-
}
|
36
|
-
//clear data and errors when a true conditional field is hidden
|
37
|
-
if (this.component.conditional.show && value !== this.component.conditional.eq) {
|
38
|
-
this.setValue('');
|
39
|
-
this.updateValue('', { modified: true });
|
40
|
-
this.clearErrors();
|
41
|
-
super.detach();
|
42
|
-
// Detach the componentRoot when the component is hidden
|
43
|
-
if (this.componentRoot) {
|
44
|
-
this.componentRoot.unmount();
|
45
|
-
this.componentRoot = undefined;
|
46
|
-
}
|
47
|
-
}
|
48
|
-
});
|
49
30
|
if (this.component.initialValue && /^{{.*}}$/.test(this.component.initialValue)) {
|
50
31
|
const regex = /^{{input\.(?<relatedObjectProperty>[a-zA-Z][a-zA-Z0-9_]*)\.(?<nestedProperty>[a-zA-Z][a-zA-Z0-9_]*)}}$/;
|
51
32
|
const groups = regex.exec(this.component.initialValue)?.groups;
|
@@ -122,12 +103,19 @@ export class ImageComponent extends ReactComponent {
|
|
122
103
|
this.element && this.attach(this.element);
|
123
104
|
}
|
124
105
|
attachReact(element) {
|
125
|
-
|
126
|
-
|
106
|
+
let root = ReactDOM.findDOMNode(element);
|
107
|
+
if (!root) {
|
108
|
+
root = element;
|
127
109
|
}
|
128
110
|
// FormIO uses id for an enclosing div, so we need to give the input field a different id.
|
129
111
|
const inputId = `${this.component.id}-input`;
|
130
|
-
|
131
|
-
|
112
|
+
/* TODO: You'll see warnings to upgrade to React 18's createRoot();
|
113
|
+
* It'll cause issues with: field-level errors not showing up, conditional visibility not working, focus moving out of the form on keypress
|
114
|
+
* Will need to be revisited later. Possibly look into using this.ref */
|
115
|
+
return ReactDOM.render(React.createElement("div", null, !this.component.hidden ? (React.createElement(FormComponentWrapper, { ...this.component, inputId: inputId, viewOnly: !this.component.canUpdateProperty, errorMessage: this.errorMessages() },
|
116
|
+
React.createElement(Image, { ...this.component, id: inputId, value: this.dataValue, handleChange: this.handleChange, error: this.hasErrors() }))) : null), root);
|
117
|
+
}
|
118
|
+
detachReact(element) {
|
119
|
+
ReactDOM.unmountComponentAtNode(element);
|
132
120
|
}
|
133
121
|
}
|
package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectComponent.d.ts
CHANGED
@@ -6,6 +6,7 @@ interface ObjectComponentProps extends BaseFormComponentProps {
|
|
6
6
|
mode: 'default' | 'existingOnly';
|
7
7
|
defaultValueCriteria?: Record<string, unknown>;
|
8
8
|
initialValue?: string;
|
9
|
+
richTextEditor?: typeof ReactComponent;
|
9
10
|
}
|
10
11
|
export declare class ObjectComponent extends ReactComponent {
|
11
12
|
relatedObject?: Obj;
|
@@ -31,5 +32,6 @@ export declare class ObjectComponent extends ReactComponent {
|
|
31
32
|
handleChangeObjectProperty: (key: string, value?: ObjectInstance | null) => void;
|
32
33
|
beforeSubmit(): void;
|
33
34
|
attachReact(element: Element): void;
|
35
|
+
detachReact(element: Element): void;
|
34
36
|
}
|
35
37
|
export {};
|
package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectComponent.js
CHANGED
@@ -2,7 +2,7 @@ import { ReactComponent } from '@formio/react';
|
|
2
2
|
import dot from 'dot-object';
|
3
3
|
import { cloneDeep, isEmpty, pick } from 'lodash';
|
4
4
|
import React from 'react';
|
5
|
-
import
|
5
|
+
import ReactDOM from 'react-dom';
|
6
6
|
import { FormComponentWrapper } from '../../Common';
|
7
7
|
import { getAllCriteriaInputs, getPrefixedUrl, isPropertyVisible, transformToWhere, updateCriteriaInputs, } from '../../utils';
|
8
8
|
import { ObjectPropertyInput } from './ObjectPropertyInput';
|
@@ -33,25 +33,6 @@ export class ObjectComponent extends ReactComponent {
|
|
33
33
|
this.handleChangeObjectProperty = this.handleChangeObjectProperty.bind(this);
|
34
34
|
}
|
35
35
|
init() {
|
36
|
-
this.on('changed-' + this.component.conditional.when, (value) => {
|
37
|
-
//set default value when conditional field is shown
|
38
|
-
if (this.component.defaultValue && value === this.component.conditional.eq) {
|
39
|
-
this.setValue(this.component.defaultValue);
|
40
|
-
this.updateValue(this.component.defaultValue, { modified: true });
|
41
|
-
}
|
42
|
-
//clear data and errors when a true conditional field is hidden
|
43
|
-
if (this.component.conditional.show && value !== this.component.conditional.eq) {
|
44
|
-
this.setValue('');
|
45
|
-
this.updateValue('', { modified: true });
|
46
|
-
this.clearErrors();
|
47
|
-
super.detach();
|
48
|
-
// Detach the componentRoot when the component is hidden
|
49
|
-
if (this.componentRoot) {
|
50
|
-
this.componentRoot.unmount();
|
51
|
-
this.componentRoot = undefined;
|
52
|
-
}
|
53
|
-
}
|
54
|
-
});
|
55
36
|
const data = dot.dot(this.root._data);
|
56
37
|
if (this.criteria) {
|
57
38
|
const inputProps = getAllCriteriaInputs(this.criteria);
|
@@ -182,6 +163,10 @@ export class ObjectComponent extends ReactComponent {
|
|
182
163
|
this.element && this.attach(this.element);
|
183
164
|
}
|
184
165
|
attachReact(element) {
|
166
|
+
let root = ReactDOM.findDOMNode(element);
|
167
|
+
if (!root) {
|
168
|
+
root = element;
|
169
|
+
}
|
185
170
|
const updatedComponent = {
|
186
171
|
...this.component,
|
187
172
|
instance: {
|
@@ -190,13 +175,16 @@ export class ObjectComponent extends ReactComponent {
|
|
190
175
|
},
|
191
176
|
defaultValueCriteria: this.updatedDefaultValueCriteria,
|
192
177
|
};
|
193
|
-
if (!this.componentRoot) {
|
194
|
-
this.componentRoot = createRoot(element);
|
195
|
-
}
|
196
178
|
// FormIO uses id for an enclosing div, so we need to give the input field a different id.
|
197
179
|
const inputId = `${this.component.id}-input`;
|
198
|
-
|
180
|
+
/* TODO: You'll see warnings to upgrade to React 18's createRoot();
|
181
|
+
* It'll cause issues with: field-level errors not showing up, conditional visibility not working, focus moving out of the form on keypress
|
182
|
+
* Will need to be revisited later. Possibly look into using this.ref */
|
183
|
+
return ReactDOM.render(React.createElement("div", null,
|
199
184
|
React.createElement(FormComponentWrapper, { ...updatedComponent, inputId: inputId, errorMessage: this.errorMessages() },
|
200
|
-
React.createElement(ObjectPropertyInput, { ...updatedComponent, id: inputId, handleChangeObjectProperty: this.handleChangeObjectProperty, error: this.hasErrors(), filter: this.criteria ? { where: transformToWhere(this.updatedCriteria) } : undefined }))));
|
185
|
+
React.createElement(ObjectPropertyInput, { ...updatedComponent, id: inputId, handleChangeObjectProperty: this.handleChangeObjectProperty, error: this.hasErrors(), filter: this.criteria ? { where: transformToWhere(this.updatedCriteria) } : undefined, richTextEditor: this.component.richTextEditor }))), root);
|
186
|
+
}
|
187
|
+
detachReact(element) {
|
188
|
+
ReactDOM.unmountComponentAtNode(element);
|
201
189
|
}
|
202
190
|
}
|
package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectPropertyInput.js
CHANGED
@@ -8,7 +8,7 @@ import { Box } from '../../../../layout';
|
|
8
8
|
import { getPrefixedUrl, normalizeDates, transformToWhere } from '../../utils';
|
9
9
|
import { RelatedObjectInstance } from './RelatedObjectInstance';
|
10
10
|
export const ObjectPropertyInput = (props) => {
|
11
|
-
const { id, instance, property, apiServices, defaultPages, handleChangeObjectProperty, nestedFieldsView, canUpdateProperty, error, navigateTo, mode, displayOption, filter, defaultValueCriteria, sortBy, orderBy, setSnackbarError, isModal, user, viewLayout, } = props;
|
11
|
+
const { id, instance, property, apiServices, defaultPages, handleChangeObjectProperty, nestedFieldsView, canUpdateProperty, error, navigateTo, mode, displayOption, filter, defaultValueCriteria, sortBy, orderBy, setSnackbarError, isModal, user, viewLayout, richTextEditor, } = props;
|
12
12
|
const [relatedObject, setRelatedObject] = useState();
|
13
13
|
const [openCreateDialog, setOpenCreateDialog] = useState(false);
|
14
14
|
const [selectedInstance, setSelectedInstance] = useState();
|
@@ -333,7 +333,7 @@ export const ObjectPropertyInput = (props) => {
|
|
333
333
|
event.stopPropagation();
|
334
334
|
setOpenCreateDialog(true);
|
335
335
|
}, "aria-label": `Add`, disabled: !canUpdateProperty }, "Add")))),
|
336
|
-
openCreateDialog && (React.createElement(React.Fragment, null, nestedFieldsView ? (React.createElement(RelatedObjectInstance, { apiServices: apiServices, handleClose: handleClose, handleChangeObjectProperty: handleChangeObjectProperty, instance: instance, setSelectedInstance: setSelectedInstance, relatedObject: relatedObject, property: property, nestedFieldsView: nestedFieldsView, mode: mode, setSnackbarError: setSnackbarError, displayOption: displayOption, setOptions: setOptions, options: options, filter: filter, user: user, layout: layout })) : (React.createElement(Dialog, { fullWidth: true, maxWidth: "md", open: openCreateDialog, onClose: (e, reason) => reason !== 'backdropClick' && handleClose },
|
336
|
+
openCreateDialog && (React.createElement(React.Fragment, null, nestedFieldsView ? (React.createElement(RelatedObjectInstance, { apiServices: apiServices, handleClose: handleClose, handleChangeObjectProperty: handleChangeObjectProperty, instance: instance, setSelectedInstance: setSelectedInstance, relatedObject: relatedObject, property: property, nestedFieldsView: nestedFieldsView, mode: mode, setSnackbarError: setSnackbarError, displayOption: displayOption, setOptions: setOptions, options: options, filter: filter, user: user, layout: layout, richTextEditor: richTextEditor })) : (React.createElement(Dialog, { fullWidth: true, maxWidth: "md", open: openCreateDialog, onClose: (e, reason) => reason !== 'backdropClick' && handleClose },
|
337
337
|
React.createElement(Typography, { sx: {
|
338
338
|
marginTop: '28px',
|
339
339
|
fontSize: '22px',
|
@@ -341,5 +341,5 @@ export const ObjectPropertyInput = (props) => {
|
|
341
341
|
marginLeft: '24px',
|
342
342
|
marginBottom: '10px',
|
343
343
|
} }, `Add ${property.name}`),
|
344
|
-
React.createElement(RelatedObjectInstance, { apiServices: apiServices, handleClose: handleClose, handleChangeObjectProperty: handleChangeObjectProperty, instance: instance, setSnackbarError: setSnackbarError, setSelectedInstance: setSelectedInstance, nestedFieldsView: nestedFieldsView, relatedObject: relatedObject, property: property, mode: mode, displayOption: displayOption, setOptions: setOptions, options: options, filter: filter, user: user, layout: layout })))))));
|
344
|
+
React.createElement(RelatedObjectInstance, { apiServices: apiServices, handleClose: handleClose, handleChangeObjectProperty: handleChangeObjectProperty, instance: instance, setSnackbarError: setSnackbarError, setSelectedInstance: setSelectedInstance, nestedFieldsView: nestedFieldsView, relatedObject: relatedObject, property: property, mode: mode, displayOption: displayOption, setOptions: setOptions, options: options, filter: filter, user: user, layout: layout, richTextEditor: richTextEditor })))))));
|
345
345
|
};
|
@@ -1,5 +1,6 @@
|
|
1
1
|
/// <reference types="react" />
|
2
2
|
import { ApiServices, Obj, ObjectInstance, Property, TableViewLayout, UserAccount } from '@evoke-platform/context';
|
3
|
+
import { ReactComponent } from '@formio/react';
|
3
4
|
export declare type RelatedObjectInstanceProps = {
|
4
5
|
relatedObject?: Obj;
|
5
6
|
property: Property;
|
@@ -21,5 +22,6 @@ export declare type RelatedObjectInstanceProps = {
|
|
21
22
|
filter?: Record<string, unknown>;
|
22
23
|
user?: UserAccount;
|
23
24
|
layout?: TableViewLayout;
|
25
|
+
richTextEditor?: typeof ReactComponent;
|
24
26
|
};
|
25
27
|
export declare const RelatedObjectInstance: (props: RelatedObjectInstanceProps) => JSX.Element;
|
@@ -20,7 +20,7 @@ const styles = {
|
|
20
20
|
};
|
21
21
|
const DEFAULT_CREATE_ACTION = '_create';
|
22
22
|
export const RelatedObjectInstance = (props) => {
|
23
|
-
const { relatedObject, property, setSelectedInstance, handleChangeObjectProperty, handleClose, apiServices, setSnackbarError, nestedFieldsView, mode, displayOption, setOptions, options, filter, user, layout, } = props;
|
23
|
+
const { relatedObject, property, setSelectedInstance, handleChangeObjectProperty, handleClose, apiServices, setSnackbarError, nestedFieldsView, mode, displayOption, setOptions, options, filter, user, layout, richTextEditor, } = props;
|
24
24
|
const [relationType, setRelationType] = useState(displayOption === 'dropdown' ? 'new' : 'existing');
|
25
25
|
const [selectedRow, setSelectedRow] = useState();
|
26
26
|
const [errors, setErrors] = useState([]);
|
@@ -104,7 +104,7 @@ export const RelatedObjectInstance = (props) => {
|
|
104
104
|
React.createElement(Form, { actionId: "_create", actionType: "create", object: relatedObject, onSave: createNewInstance, submitButtonLabel: 'Add', closeModal: onClose, apiServices: apiServices, clearable: true, objectInputCommonProps: {
|
105
105
|
apiServices: apiServices,
|
106
106
|
setSnackbarError: setSnackbarError,
|
107
|
-
}, queryAddresses: queryAddresses, user: userAccount }))) : (relatedObject && (React.createElement(React.Fragment, null,
|
107
|
+
}, queryAddresses: queryAddresses, user: userAccount, richTextEditor: richTextEditor }))) : (relatedObject && (React.createElement(React.Fragment, null,
|
108
108
|
React.createElement(InstanceLookup, { apiServices: apiServices, nestedFieldsView: nestedFieldsView, setRelationType: setRelationType, object: relatedObject, setSelectedInstance: setSelectedRow, mode: mode, filter: filter, layout: layout }))))),
|
109
109
|
relationType !== 'new' && (React.createElement(Box, { sx: styles.actionButtons },
|
110
110
|
React.createElement(Button, { onClick: onClose, color: 'inherit', sx: {
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import { ReactComponent } from '@formio/react';
|
2
2
|
import { cloneDeep, isEmpty } from 'lodash';
|
3
3
|
import React from 'react';
|
4
|
-
import
|
4
|
+
import ReactDOM from 'react-dom';
|
5
5
|
import { FormComponentWrapper } from '../../Common';
|
6
|
-
import {
|
6
|
+
import { transformToWhere } from '../../utils';
|
7
7
|
import { UserProperty } from './UserProperty';
|
8
8
|
export class UserComponent extends ReactComponent {
|
9
9
|
constructor(component, options, data) {
|
@@ -29,25 +29,6 @@ export class UserComponent extends ReactComponent {
|
|
29
29
|
this.handleChangeUserProperty = this.handleChangeUserProperty.bind(this);
|
30
30
|
}
|
31
31
|
init() {
|
32
|
-
this.on('changed-' + this.component.conditional.when, (value) => {
|
33
|
-
// set default value when conditional field is shown
|
34
|
-
if (this.component.defaultValue && value === this.component.conditional.eq) {
|
35
|
-
this.setValue(this.component.defaultValue);
|
36
|
-
this.updateValue(this.component.defaultValue, { modified: true });
|
37
|
-
}
|
38
|
-
// clear data and errors when a true conditional field is hidden
|
39
|
-
if (this.component.conditional.show && value !== this.component.conditional.eq) {
|
40
|
-
this.setValue('');
|
41
|
-
this.updateValue('', { modified: true });
|
42
|
-
this.clearErrors();
|
43
|
-
super.detach();
|
44
|
-
// Detach the componentRoot when the component is hidden
|
45
|
-
if (this.componentRoot) {
|
46
|
-
this.componentRoot.unmount();
|
47
|
-
this.componentRoot = undefined;
|
48
|
-
}
|
49
|
-
}
|
50
|
-
});
|
51
32
|
if (this.component.initialValue && /^{{.*}}$/.test(this.component.initialValue)) {
|
52
33
|
const regex = /^{{input\.(?<relatedObjectProperty>[a-zA-Z][a-zA-Z0-9_]*)\.(?<nestedProperty>[a-zA-Z][a-zA-Z0-9_]*)}}$/;
|
53
34
|
const groups = regex.exec(this.component.initialValue)?.groups;
|
@@ -90,7 +71,7 @@ export class UserComponent extends ReactComponent {
|
|
90
71
|
this.root.customErrors = this.root.customErrors.filter((error) => error.formattedKeyOrPath !== this.component.key);
|
91
72
|
}
|
92
73
|
handleValidation() {
|
93
|
-
if (!
|
74
|
+
if (!this.visible) {
|
94
75
|
return;
|
95
76
|
}
|
96
77
|
// check for out-of-the-box formio errors which store on this.root.errors
|
@@ -123,6 +104,10 @@ export class UserComponent extends ReactComponent {
|
|
123
104
|
this.element && this.attach(this.element);
|
124
105
|
}
|
125
106
|
attachReact(element) {
|
107
|
+
let root = ReactDOM.findDOMNode(element);
|
108
|
+
if (!root) {
|
109
|
+
root = element;
|
110
|
+
}
|
126
111
|
const updatedComponent = {
|
127
112
|
...this.component,
|
128
113
|
instance: {
|
@@ -130,13 +115,16 @@ export class UserComponent extends ReactComponent {
|
|
130
115
|
[this.component.key]: isEmpty(this.dataValue) ? null : this.dataValue,
|
131
116
|
},
|
132
117
|
};
|
133
|
-
if (!this.componentRoot) {
|
134
|
-
this.componentRoot = createRoot(element, { onRecoverableError: console.error });
|
135
|
-
}
|
136
118
|
// FormIO uses id for an enclosing div, so we need to give the input field a different id.
|
137
119
|
const inputId = `${this.component.id}-input`;
|
138
|
-
|
120
|
+
/* TODO: You'll see warnings to upgrade to React 18's createRoot();
|
121
|
+
* It'll cause issues with: field-level errors not showing up, conditional visibility not working, focus moving out of the form on keypress
|
122
|
+
* Will need to be revisited later. Possibly look into using this.ref */
|
123
|
+
return ReactDOM.render(React.createElement("div", null,
|
139
124
|
React.createElement(FormComponentWrapper, { ...updatedComponent, inputId: inputId, errorMessage: this.errorMessages() },
|
140
|
-
React.createElement(UserProperty, { ...updatedComponent, id: inputId, value: this.dataValue ?? '', handleChangeUserProperty: this.handleChangeUserProperty, error: this.hasErrors(), filter: this.criteria ? { where: transformToWhere(this.updatedCriteria) } : undefined }))));
|
125
|
+
React.createElement(UserProperty, { ...updatedComponent, id: inputId, value: this.dataValue ?? '', handleChangeUserProperty: this.handleChangeUserProperty, error: this.hasErrors(), filter: this.criteria ? { where: transformToWhere(this.updatedCriteria) } : undefined }))), root);
|
126
|
+
}
|
127
|
+
detachReact(element) {
|
128
|
+
ReactDOM.unmountComponentAtNode(element);
|
141
129
|
}
|
142
130
|
}
|
@@ -17,4 +17,5 @@ export declare class ViewOnlyComponent extends ReactComponent {
|
|
17
17
|
constructor(component: BaseFormComponentProps, options: any, data: any);
|
18
18
|
showValue(value: unknown): {} | undefined;
|
19
19
|
attachReact(element: Element): void;
|
20
|
+
detachReact(element: Element): void;
|
20
21
|
}
|
@@ -3,7 +3,6 @@ import { get, isEmpty } from 'lodash';
|
|
3
3
|
import { DateTime } from 'luxon';
|
4
4
|
import React from 'react';
|
5
5
|
import ReactDOM from 'react-dom';
|
6
|
-
import { createRoot } from 'react-dom/client';
|
7
6
|
import { Link, Typography } from '../../../core';
|
8
7
|
import { FormComponentWrapper } from '../Common/FormComponentWrapper';
|
9
8
|
export class ViewOnlyComponent extends ReactComponent {
|
@@ -74,13 +73,16 @@ export class ViewOnlyComponent extends ReactComponent {
|
|
74
73
|
if (!root) {
|
75
74
|
root = element;
|
76
75
|
}
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
return
|
76
|
+
/* TODO: You'll see warnings to upgrade to React 18's createRoot();
|
77
|
+
* It'll cause issues with: field-level errors not showing up, conditional visibility not working, focus moving out of the form on keypress
|
78
|
+
* Will need to be revisited later. Possibly look into using this.ref */
|
79
|
+
return ReactDOM.render(React.createElement("div", null,
|
81
80
|
React.createElement(FormComponentWrapper, { ...this.component, viewOnly: true },
|
82
81
|
React.createElement(Typography, { variant: "body1", key: this.component.key }, this.showValue(this.component.instance
|
83
82
|
? get(this.component.instance, this.component.key)
|
84
|
-
: this.component.defaultValue)))));
|
83
|
+
: this.component.defaultValue)))), root);
|
84
|
+
}
|
85
|
+
detachReact(element) {
|
86
|
+
ReactDOM.unmountComponentAtNode(element);
|
85
87
|
}
|
86
88
|
}
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { ApiServices, ObjectInstance, Property, UserAccount, ViewLayoutEntityReference } from '@evoke-platform/context';
|
2
|
+
import { ReactComponent } from '@formio/react';
|
2
3
|
import { AutocompleteOption } from '../../core';
|
3
4
|
export declare type BaseFormComponentProps = {
|
4
5
|
key: string;
|
@@ -76,6 +77,7 @@ export declare type ObjectPropertyInputProps = {
|
|
76
77
|
isModal?: boolean;
|
77
78
|
label?: string;
|
78
79
|
viewLayout?: ViewLayoutEntityReference;
|
80
|
+
richTextEditor?: typeof ReactComponent;
|
79
81
|
};
|
80
82
|
export declare type Address = {
|
81
83
|
line1?: string;
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { ActionInput, ActionInputType, ApiServices, FormEntry, InputParameter, InputParameterReference, Obj, ObjectInstance, Property, PropertyType } from '@evoke-platform/context';
|
2
|
+
import { ReactComponent } from '@formio/react';
|
2
3
|
import { LocalDateTime } from '@js-joda/core';
|
3
4
|
import { AutocompleteOption } from '../../core';
|
4
5
|
import { ObjectPropertyInputProps } from './types';
|
@@ -20,9 +21,9 @@ export declare function getMiddleObject(instance: ObjectInstance, property: Prop
|
|
20
21
|
} | undefined;
|
21
22
|
export declare function getMiddleInstance(instanceId: string, property: Property, middleObjectInstances: ObjectInstance[]): ObjectInstance | undefined;
|
22
23
|
export declare function getPrefixedUrl(url: string): string;
|
23
|
-
export declare function addObjectPropertiesToComponentProps(properties: Property[], formComponents: any[], instance?: ObjectInstance, objectPropertyInputProps?: ObjectPropertyInputProps, autoSave?: (data: Record<string, unknown>) => void, readOnly?: boolean, defaultPages?: Record<string, string>, navigateTo?: (path: string) => void, queryAddresses?: unknown, apiServices?: ApiServices, isModal?: boolean, fieldHeight?: 'small' | 'medium'): Promise<ActionInput[]>;
|
24
|
+
export declare function addObjectPropertiesToComponentProps(properties: Property[], formComponents: any[], instance?: ObjectInstance, objectPropertyInputProps?: ObjectPropertyInputProps, autoSave?: (data: Record<string, unknown>) => void, readOnly?: boolean, defaultPages?: Record<string, string>, navigateTo?: (path: string) => void, queryAddresses?: unknown, apiServices?: ApiServices, isModal?: boolean, fieldHeight?: 'small' | 'medium', richTextEditor?: typeof ReactComponent): Promise<ActionInput[]>;
|
24
25
|
export declare function getDefaultValue(initialValue: unknown, selectOptions?: AutocompleteOption[]): unknown;
|
25
|
-
export declare const buildComponentPropsFromObjectProperties: (properties: Property[], objectId: string, instance?: ObjectInstance, objectPropertyInputProps?: ObjectPropertyInputProps, hasActionPermissions?: boolean, autoSave?: ((data: Record<string, unknown>) => void) | undefined, readOnly?: boolean, queryAddresses?: unknown, isModal?: boolean, fieldHeight?: 'small' | 'medium') => unknown[];
|
26
|
+
export declare const buildComponentPropsFromObjectProperties: (properties: Property[], objectId: string, instance?: ObjectInstance, objectPropertyInputProps?: ObjectPropertyInputProps, hasActionPermissions?: boolean, autoSave?: ((data: Record<string, unknown>) => void) | undefined, readOnly?: boolean, queryAddresses?: unknown, isModal?: boolean, fieldHeight?: 'small' | 'medium', richTextEditor?: typeof ReactComponent) => unknown[];
|
26
27
|
export declare const buildComponentPropsFromDocumentProperties: (documentProperties: [string, unknown][], readOnly?: boolean, autoSave?: ((data: Record<string, unknown>) => void) | undefined, fieldHeight?: 'small' | 'medium') => {
|
27
28
|
type: string;
|
28
29
|
key: string;
|
@@ -468,7 +468,7 @@ export function getPrefixedUrl(url) {
|
|
468
468
|
// This function is used when there is no form configured in the form builder.
|
469
469
|
export async function addObjectPropertiesToComponentProps(properties,
|
470
470
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
471
|
-
formComponents, instance, objectPropertyInputProps, autoSave, readOnly, defaultPages, navigateTo, queryAddresses, apiServices, isModal, fieldHeight) {
|
471
|
+
formComponents, instance, objectPropertyInputProps, autoSave, readOnly, defaultPages, navigateTo, queryAddresses, apiServices, isModal, fieldHeight, richTextEditor) {
|
472
472
|
return [
|
473
473
|
...(await Promise.all(formComponents
|
474
474
|
?.filter((component) => !isUndefined(component) && !isNil(component))
|
@@ -625,6 +625,9 @@ formComponents, instance, objectPropertyInputProps, autoSave, readOnly, defaultP
|
|
625
625
|
middleObject,
|
626
626
|
getMiddleObjectInstances,
|
627
627
|
isModal,
|
628
|
+
richTextEditor: ['RepeatableField', 'Object'].includes(component.type)
|
629
|
+
? richTextEditor
|
630
|
+
: undefined,
|
628
631
|
};
|
629
632
|
}
|
630
633
|
const defaultValue = getDefaultValue(isNil(instanceValue) ? component.initialValue : instanceValue, component?.data?.values);
|
@@ -665,11 +668,14 @@ formComponents, instance, objectPropertyInputProps, autoSave, readOnly, defaultP
|
|
665
668
|
}
|
666
669
|
: undefined,
|
667
670
|
isModal,
|
671
|
+
richTextEditor: ['RepeatableField', 'Object'].includes(component.type)
|
672
|
+
? richTextEditor
|
673
|
+
: undefined,
|
668
674
|
};
|
669
675
|
}
|
670
676
|
if (component.columns) {
|
671
677
|
for (const column of component.columns) {
|
672
|
-
column.components = await addObjectPropertiesToComponentProps(properties, column.components, instance, objectPropertyInputProps, autoSave, readOnly, undefined, undefined, queryAddresses, apiServices, isModal, fieldHeight);
|
678
|
+
column.components = await addObjectPropertiesToComponentProps(properties, column.components, instance, objectPropertyInputProps, autoSave, readOnly, undefined, undefined, queryAddresses, apiServices, isModal, fieldHeight, richTextEditor);
|
673
679
|
}
|
674
680
|
return component;
|
675
681
|
}
|
@@ -703,6 +709,9 @@ formComponents, instance, objectPropertyInputProps, autoSave, readOnly, defaultP
|
|
703
709
|
item.navigateTo = navigateTo;
|
704
710
|
item.isModal = isModal;
|
705
711
|
item.fieldHeight = fieldHeight;
|
712
|
+
item.richTextEditor = ['RepeatableField', 'Object'].includes(item.type)
|
713
|
+
? richTextEditor
|
714
|
+
: undefined;
|
706
715
|
if (item.addressPropertyId) {
|
707
716
|
item.queryAddresses = queryAddresses;
|
708
717
|
}
|
@@ -724,7 +733,7 @@ formComponents, instance, objectPropertyInputProps, autoSave, readOnly, defaultP
|
|
724
733
|
}
|
725
734
|
}
|
726
735
|
return {
|
727
|
-
components: await addObjectPropertiesToComponentProps(properties, component.components, instance, objectPropertyInputProps, autoSave, readOnly, defaultPages, navigateTo, queryAddresses, apiServices, isModal, fieldHeight),
|
736
|
+
components: await addObjectPropertiesToComponentProps(properties, component.components, instance, objectPropertyInputProps, autoSave, readOnly, defaultPages, navigateTo, queryAddresses, apiServices, isModal, fieldHeight, richTextEditor),
|
728
737
|
...component,
|
729
738
|
...(component.type === 'Object' && objectPropertyInputProps),
|
730
739
|
type: `${readOnly ? 'ViewOnly' : ''}${component.type}`,
|
@@ -738,6 +747,9 @@ formComponents, instance, objectPropertyInputProps, autoSave, readOnly, defaultP
|
|
738
747
|
queryAddresses: component.isAddressLine1 ? queryAddresses : undefined,
|
739
748
|
isModal,
|
740
749
|
fieldHeight,
|
750
|
+
richTextEditor: ['RepeatableField', 'Object'].includes(component.type)
|
751
|
+
? richTextEditor
|
752
|
+
: undefined,
|
741
753
|
};
|
742
754
|
}
|
743
755
|
}))).filter((component) => !!component),
|
@@ -788,7 +800,7 @@ export function getDefaultValue(initialValue, selectOptions) {
|
|
788
800
|
}
|
789
801
|
// The following function adds the configured properties to the form components.
|
790
802
|
// This function is used when there is a form configured in the form builder.
|
791
|
-
export const buildComponentPropsFromObjectProperties = (properties, objectId, instance, objectPropertyInputProps, hasActionPermissions, autoSave, readOnly, queryAddresses, isModal, fieldHeight) => {
|
803
|
+
export const buildComponentPropsFromObjectProperties = (properties, objectId, instance, objectPropertyInputProps, hasActionPermissions, autoSave, readOnly, queryAddresses, isModal, fieldHeight, richTextEditor) => {
|
792
804
|
const matchType = (type) => {
|
793
805
|
switch (type) {
|
794
806
|
case 'boolean':
|
@@ -1049,6 +1061,7 @@ export const buildComponentPropsFromObjectProperties = (properties, objectId, in
|
|
1049
1061
|
autoSave,
|
1050
1062
|
queryAddresses: ['collection', 'object'].includes(property?.type) ? queryAddresses : undefined,
|
1051
1063
|
isModal,
|
1064
|
+
richTextEditor: property.type === 'object' ? richTextEditor : undefined,
|
1052
1065
|
};
|
1053
1066
|
});
|
1054
1067
|
};
|