@evoke-platform/ui-components 1.0.0-dev.217 → 1.0.0-dev.219
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.d.ts +38 -0
- package/dist/published/components/custom/Form/Common/Form.js +413 -0
- package/dist/published/components/custom/Form/Common/FormComponentWrapper.d.ts +26 -0
- package/dist/published/components/custom/Form/Common/FormComponentWrapper.js +79 -0
- package/dist/published/components/custom/Form/Common/index.d.ts +2 -0
- package/dist/published/components/custom/Form/Common/index.js +2 -0
- package/dist/published/components/custom/Form/FormComponents/ButtonComponent.d.ts +37 -0
- package/dist/published/components/custom/Form/FormComponents/ButtonComponent.js +150 -0
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.d.ts +17 -0
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.js +80 -0
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentComponent.d.ts +23 -0
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentComponent.js +154 -0
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentList.d.ts +15 -0
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentList.js +172 -0
- package/dist/published/components/custom/Form/FormComponents/FormFieldComponent.d.ts +41 -0
- package/dist/published/components/custom/Form/FormComponents/FormFieldComponent.js +409 -0
- package/dist/published/components/custom/Form/FormComponents/ImageComponent/Image.d.ts +15 -0
- package/dist/published/components/custom/Form/FormComponents/ImageComponent/Image.js +111 -0
- package/dist/published/components/custom/Form/FormComponents/ImageComponent/ImageComponent.d.ts +23 -0
- package/dist/published/components/custom/Form/FormComponents/ImageComponent/ImageComponent.js +112 -0
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/InstanceLookup.d.ts +20 -0
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/InstanceLookup.js +229 -0
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectComponent.d.ts +34 -0
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectComponent.js +150 -0
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectPropertyInput.d.ts +3 -0
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectPropertyInput.js +306 -0
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/RelatedObjectInstance.d.ts +24 -0
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/RelatedObjectInstance.js +126 -0
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ActionDialog.d.ts +21 -0
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ActionDialog.js +96 -0
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ManyToMany/DropdownRepeatableField.d.ts +15 -0
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ManyToMany/DropdownRepeatableField.js +158 -0
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ManyToMany/DropdownRepeatableFieldInput.d.ts +39 -0
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ManyToMany/DropdownRepeatableFieldInput.js +89 -0
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableField.d.ts +12 -0
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableField.js +369 -0
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableFieldComponent.d.ts +20 -0
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableFieldComponent.js +57 -0
- package/dist/published/components/custom/Form/FormComponents/UserComponent/UserComponent.d.ts +26 -0
- package/dist/published/components/custom/Form/FormComponents/UserComponent/UserComponent.js +99 -0
- package/dist/published/components/custom/Form/FormComponents/UserComponent/UserProperty.d.ts +23 -0
- package/dist/published/components/custom/Form/FormComponents/UserComponent/UserProperty.js +115 -0
- package/dist/published/components/custom/Form/FormComponents/ViewOnlyComponent.d.ts +20 -0
- package/dist/published/components/custom/Form/FormComponents/ViewOnlyComponent.js +83 -0
- package/dist/published/components/custom/Form/FormComponents/index.d.ts +8 -0
- package/dist/published/components/custom/Form/FormComponents/index.js +8 -0
- package/dist/published/components/custom/Form/index.d.ts +3 -0
- package/dist/published/components/custom/Form/index.js +3 -0
- package/dist/published/components/custom/Form/types.d.ts +109 -0
- package/dist/published/components/custom/Form/types.js +1 -0
- package/dist/published/components/custom/Form/utils.d.ts +45 -0
- package/dist/published/components/custom/Form/utils.js +1036 -0
- package/dist/published/components/custom/HistoryLog/DisplayedProperty.d.ts +8 -0
- package/dist/published/components/custom/HistoryLog/DisplayedProperty.js +70 -0
- package/dist/published/components/custom/HistoryLog/Filter.d.ts +11 -0
- package/dist/published/components/custom/HistoryLog/Filter.js +55 -0
- package/dist/published/components/custom/HistoryLog/HistoryData.d.ts +10 -0
- package/dist/published/components/custom/HistoryLog/HistoryData.js +83 -0
- package/dist/published/components/custom/HistoryLog/HistoryLoading.d.ts +3 -0
- package/dist/published/components/custom/HistoryLog/HistoryLoading.js +39 -0
- package/dist/published/components/custom/HistoryLog/index.d.ts +22 -0
- package/dist/published/components/custom/HistoryLog/index.js +92 -0
- package/dist/published/components/custom/RichTextViewer/index.d.ts +15 -0
- package/dist/published/components/custom/RichTextViewer/index.js +47 -0
- package/dist/published/components/custom/index.d.ts +3 -0
- package/dist/published/components/custom/index.js +3 -0
- package/dist/published/index.d.ts +1 -1
- package/dist/published/index.js +1 -1
- package/dist/published/stories/HistoryLog.stories.d.ts +6 -0
- package/dist/published/stories/HistoryLog.stories.js +79 -0
- package/dist/published/stories/RichTextViewer.stories.d.ts +6 -0
- package/dist/published/stories/RichTextViewer.stories.js +12 -0
- package/dist/published/styles/form-component.css +152 -0
- package/dist/published/types.d.ts +20 -0
- package/package.json +21 -5
package/dist/published/components/custom/Form/FormComponents/ObjectComponent/InstanceLookup.d.ts
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
/// <reference types="react" />
|
2
|
+
import { ApiServices, Obj, ObjectInstance, Property } from '@evoke-platform/context';
|
3
|
+
export declare type InstanceLookUpProps = {
|
4
|
+
object: Obj;
|
5
|
+
instanceId?: string;
|
6
|
+
apiServices: ApiServices;
|
7
|
+
setSelectedInstance: (selectedInstance: ObjectInstance) => void;
|
8
|
+
setRelationType: (relationType: 'new' | 'existing') => void;
|
9
|
+
mode: 'default' | 'existingOnly';
|
10
|
+
nestedFieldsView?: boolean;
|
11
|
+
filter?: Record<string, unknown>;
|
12
|
+
};
|
13
|
+
export declare type SearchFieldProps = {
|
14
|
+
searchableColumns: Property[];
|
15
|
+
filter: Record<string, unknown> | undefined;
|
16
|
+
setFilter: (filter: Record<string, unknown> | undefined) => void;
|
17
|
+
searchString: string;
|
18
|
+
setSearchString: (searchStrig: string) => void;
|
19
|
+
};
|
20
|
+
export declare const InstanceLookup: (props: InstanceLookUpProps) => JSX.Element;
|
package/dist/published/components/custom/Form/FormComponents/ObjectComponent/InstanceLookup.js
ADDED
@@ -0,0 +1,229 @@
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8
|
+
});
|
9
|
+
};
|
10
|
+
import { Clear, Search } from '@mui/icons-material';
|
11
|
+
import { debounce, get, startCase } from 'lodash';
|
12
|
+
import { DateTime } from 'luxon';
|
13
|
+
import React, { useEffect, useState } from 'react';
|
14
|
+
import { Button, IconButton, InputAdornment, TextField, Typography, } from '../../../../core';
|
15
|
+
import { BuilderGrid } from '../../../../custom';
|
16
|
+
import { Box, Grid } from '../../../../layout';
|
17
|
+
import { getPrefixedUrl } from '../../utils';
|
18
|
+
const SearchField = (props) => {
|
19
|
+
const { searchableColumns, filter, setFilter, searchString, setSearchString } = props;
|
20
|
+
const clearSearch = () => {
|
21
|
+
setSearchString('');
|
22
|
+
setFilter(undefined);
|
23
|
+
};
|
24
|
+
const handleSearch = (e) => __awaiter(void 0, void 0, void 0, function* () {
|
25
|
+
const searchProperties = searchableColumns.map((column) => {
|
26
|
+
const columnId = column.id;
|
27
|
+
return {
|
28
|
+
[columnId]: {
|
29
|
+
like: e.target.value,
|
30
|
+
options: 'i',
|
31
|
+
},
|
32
|
+
};
|
33
|
+
});
|
34
|
+
if (e.target.value.trim() === '' || !e.target.value) {
|
35
|
+
clearSearch();
|
36
|
+
}
|
37
|
+
else {
|
38
|
+
setSearchString(e.target.value);
|
39
|
+
setFilter(Object.assign(Object.assign({}, filter), { where: {
|
40
|
+
or: searchProperties,
|
41
|
+
}, limit: 100 }));
|
42
|
+
}
|
43
|
+
});
|
44
|
+
return (React.createElement(TextField, { autoFocus: true, placeholder: "Search", value: searchString, onChange: (e) => handleSearch(e), size: "medium", fullWidth: true, sx: { marginBottom: '15px', marginTop: '15px' }, InputProps: {
|
45
|
+
endAdornment: (React.createElement(InputAdornment, { position: "end" },
|
46
|
+
React.createElement(IconButton, { sx: {
|
47
|
+
visibility: searchString.length > 0 ? 'visible' : 'hidden',
|
48
|
+
}, onClick: () => clearSearch() },
|
49
|
+
React.createElement(Clear, { sx: {
|
50
|
+
fontSize: '22px',
|
51
|
+
} })))),
|
52
|
+
startAdornment: (React.createElement(InputAdornment, { position: "start" },
|
53
|
+
React.createElement(Search, { sx: { fontSize: '22px', color: '#637381' } }))),
|
54
|
+
} }));
|
55
|
+
};
|
56
|
+
export const InstanceLookup = (props) => {
|
57
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
58
|
+
const { object, apiServices, setSelectedInstance, mode, nestedFieldsView, setRelationType, filter: criteriaFilter, } = props;
|
59
|
+
const [rows, setRows] = useState([]);
|
60
|
+
const [loading, setLoading] = useState(false);
|
61
|
+
const [filter, setFilter] = useState();
|
62
|
+
const [searchString, setSearchString] = useState('');
|
63
|
+
const [searchableColumns] = useState((_b = (_a = object.properties) === null || _a === void 0 ? void 0 : _a.filter((property) => property.searchable)) !== null && _b !== void 0 ? _b : []);
|
64
|
+
const retrieveColumns = (tableViewLayout) => {
|
65
|
+
var _a, _b, _c;
|
66
|
+
let columns = [];
|
67
|
+
if (tableViewLayout === null || tableViewLayout === void 0 ? void 0 : tableViewLayout.properties) {
|
68
|
+
for (const prop of tableViewLayout.properties) {
|
69
|
+
const propertyId = prop.id.split('.')[0];
|
70
|
+
const property = (_a = object.properties) === null || _a === void 0 ? void 0 : _a.find((p) => p.id === propertyId);
|
71
|
+
if (property) {
|
72
|
+
if (property.type === 'address') {
|
73
|
+
columns.push({
|
74
|
+
field: prop.id,
|
75
|
+
headerName: `${property.name} - ${startCase(prop.id.split('.')[1])}`,
|
76
|
+
type: 'string',
|
77
|
+
flex: 1,
|
78
|
+
valueGetter: (params) => {
|
79
|
+
var _a;
|
80
|
+
return (_a = get(params.row, prop.id)) !== null && _a !== void 0 ? _a : '';
|
81
|
+
},
|
82
|
+
});
|
83
|
+
}
|
84
|
+
else if (property.type === 'object' || property.type === 'user') {
|
85
|
+
columns.push({
|
86
|
+
field: prop.id,
|
87
|
+
headerName: property.name,
|
88
|
+
type: 'string',
|
89
|
+
flex: 1,
|
90
|
+
valueGetter: (params) => {
|
91
|
+
var _a;
|
92
|
+
return ((_a = get(params.row, !prop.id.includes('.') ? `${prop.id}.name` : prop.id)) !== null && _a !== void 0 ? _a : '');
|
93
|
+
},
|
94
|
+
});
|
95
|
+
}
|
96
|
+
else if (property.type === 'document') {
|
97
|
+
columns.push({
|
98
|
+
field: prop.id,
|
99
|
+
headerName: property.name,
|
100
|
+
type: 'string',
|
101
|
+
flex: 1,
|
102
|
+
valueGetter: (params) => {
|
103
|
+
var _a, _b;
|
104
|
+
const row = params.row;
|
105
|
+
return ((_b = (_a = row[prop.id]) === null || _a === void 0 ? void 0 : _a.map((v) => v.name).join(', ')) !== null && _b !== void 0 ? _b : '');
|
106
|
+
},
|
107
|
+
});
|
108
|
+
}
|
109
|
+
else if (property.type === 'date') {
|
110
|
+
columns.push({
|
111
|
+
field: prop.id,
|
112
|
+
headerName: property.name,
|
113
|
+
type: 'string',
|
114
|
+
flex: 1,
|
115
|
+
valueFormatter: (params) => {
|
116
|
+
if (!params.value) {
|
117
|
+
return params.value;
|
118
|
+
}
|
119
|
+
// The value should really be typed as string | undefined so once asserted as defined
|
120
|
+
// the value must be a string.
|
121
|
+
return DateTime.fromISO(params.value).toLocaleString(DateTime.DATE_SHORT);
|
122
|
+
},
|
123
|
+
});
|
124
|
+
}
|
125
|
+
else if (property.type === 'date-time') {
|
126
|
+
columns.push({
|
127
|
+
field: prop.id,
|
128
|
+
headerName: property.name,
|
129
|
+
type: 'string',
|
130
|
+
flex: 1,
|
131
|
+
valueFormatter: (params) => {
|
132
|
+
if (!params.value) {
|
133
|
+
return params.value;
|
134
|
+
}
|
135
|
+
// The value should really be typed as string | undefined so once asserted as defined
|
136
|
+
// the value must be a string.
|
137
|
+
return DateTime.fromISO(params.value).toLocaleString(DateTime.DATETIME_SHORT);
|
138
|
+
},
|
139
|
+
});
|
140
|
+
}
|
141
|
+
else if (property.type === 'time') {
|
142
|
+
columns.push({
|
143
|
+
field: prop.id,
|
144
|
+
headerName: property.name,
|
145
|
+
type: 'string',
|
146
|
+
flex: 1,
|
147
|
+
valueFormatter: (params) => {
|
148
|
+
if (!params.value) {
|
149
|
+
return params.value;
|
150
|
+
}
|
151
|
+
// The value should really be typed as string | undefined so once asserted as defined
|
152
|
+
// the value must be a string.
|
153
|
+
return DateTime.fromISO(params.value).toLocaleString(DateTime.TIME_SIMPLE);
|
154
|
+
},
|
155
|
+
});
|
156
|
+
}
|
157
|
+
else {
|
158
|
+
columns.push({
|
159
|
+
field: prop.id,
|
160
|
+
headerName: property.name,
|
161
|
+
type: 'string',
|
162
|
+
flex: 1,
|
163
|
+
});
|
164
|
+
}
|
165
|
+
}
|
166
|
+
}
|
167
|
+
}
|
168
|
+
else {
|
169
|
+
const name = (_b = object.properties) === null || _b === void 0 ? void 0 : _b.find((property) => property.id == 'name');
|
170
|
+
columns = [{ field: 'name', headerName: (_c = name === null || name === void 0 ? void 0 : name.name) !== null && _c !== void 0 ? _c : 'Name', type: 'string', flex: 1 }];
|
171
|
+
}
|
172
|
+
return columns;
|
173
|
+
};
|
174
|
+
function fetchObjectInstance() {
|
175
|
+
var _a;
|
176
|
+
setLoading(true);
|
177
|
+
const combinedFilter = Object.assign(Object.assign(Object.assign({}, criteriaFilter), filter), { where: (criteriaFilter === null || criteriaFilter === void 0 ? void 0 : criteriaFilter.where)
|
178
|
+
? {
|
179
|
+
and: [criteriaFilter.where, filter === null || filter === void 0 ? void 0 : filter.where],
|
180
|
+
}
|
181
|
+
: filter === null || filter === void 0 ? void 0 : filter.where });
|
182
|
+
apiServices.get(getPrefixedUrl(`/objects/${object.id}/instances`), (_a = { params: { filter: JSON.stringify(combinedFilter) } }) !== null && _a !== void 0 ? _a : {}, (error, objectInstances) => {
|
183
|
+
if (error) {
|
184
|
+
console.error(error);
|
185
|
+
}
|
186
|
+
else {
|
187
|
+
!!objectInstances && setRows(objectInstances);
|
188
|
+
}
|
189
|
+
setLoading(false);
|
190
|
+
});
|
191
|
+
}
|
192
|
+
useEffect(() => {
|
193
|
+
if (filter || searchString.length) {
|
194
|
+
debounce(() => fetchObjectInstance(), 500)();
|
195
|
+
}
|
196
|
+
else if (searchString === '') {
|
197
|
+
setRows([]);
|
198
|
+
}
|
199
|
+
}, [filter, searchString.length]);
|
200
|
+
return (React.createElement(Grid, { container: true, sx: { paddingBottom: '30px' } },
|
201
|
+
React.createElement(Grid, { item: true, xs: 12 }, searchableColumns.length ? (React.createElement(SearchField, { searchString: searchString, setSearchString: setSearchString, filter: filter, setFilter: setFilter, searchableColumns: searchableColumns })) : (React.createElement(Typography, { sx: { fontSize: '16px', fontWeight: '700' } }, "There are no searchable properties configured for this object"))),
|
202
|
+
React.createElement(BuilderGrid, { item: 'instances', rows: rows, columns: retrieveColumns((_c = object.viewLayout) === null || _c === void 0 ? void 0 : _c.table), onRowClick: (params) => setSelectedInstance(params.row), initialSort: {
|
203
|
+
field: (_g = (_f = (_e = (_d = object.viewLayout) === null || _d === void 0 ? void 0 : _d.table) === null || _e === void 0 ? void 0 : _e.sort) === null || _f === void 0 ? void 0 : _f.colId) !== null && _g !== void 0 ? _g : 'name',
|
204
|
+
sort: (_l = (_k = (_j = (_h = object.viewLayout) === null || _h === void 0 ? void 0 : _h.table) === null || _j === void 0 ? void 0 : _j.sort) === null || _k === void 0 ? void 0 : _k.sort) !== null && _l !== void 0 ? _l : 'asc',
|
205
|
+
}, sx: {
|
206
|
+
height: '360px',
|
207
|
+
width: '100%',
|
208
|
+
}, hideToolbar: true, loading: loading, hideEmptyContent: true, localeText: {
|
209
|
+
noRowsLabel: searchString.length > 0
|
210
|
+
? `No Results Found. Refine your search ${mode !== 'existingOnly' ? 'or create a new record.' : '.'}`
|
211
|
+
: 'Search to view results',
|
212
|
+
}, noRowsOverlay: React.createElement(Box, { sx: { height: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center' } }, searchString.length > 0 ? (React.createElement(React.Fragment, null,
|
213
|
+
React.createElement(Box, null,
|
214
|
+
React.createElement(Typography, { sx: {
|
215
|
+
fontSize: '14px',
|
216
|
+
fontWeight: 700,
|
217
|
+
textAlign: 'center',
|
218
|
+
} }, "No Results Found"),
|
219
|
+
React.createElement(Typography, { sx: {
|
220
|
+
fontSize: '14px',
|
221
|
+
textAlign: 'center',
|
222
|
+
} },
|
223
|
+
"Refine your search",
|
224
|
+
!nestedFieldsView && mode !== 'existingOnly' && (React.createElement(React.Fragment, null,
|
225
|
+
' or ',
|
226
|
+
React.createElement(Button, { variant: "text", onClick: () => setRelationType('new'), sx: {
|
227
|
+
padding: '3px 5px',
|
228
|
+
} }, "enter a new record"))))))) : (React.createElement(Typography, { sx: { fontSize: '16px' } }, "Search to view results"))) })));
|
229
|
+
};
|
package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectComponent.d.ts
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
import { Obj, Reference } from '@evoke-platform/context';
|
2
|
+
import { ReactComponent } from '@formio/react';
|
3
|
+
import { Root } from 'react-dom/client';
|
4
|
+
import { BaseFormComponentProps } from '../../types';
|
5
|
+
declare type ObjectComponentProps = BaseFormComponentProps & {
|
6
|
+
mode: 'default' | 'existingOnly';
|
7
|
+
defaultValueCriteria?: Record<string, unknown>;
|
8
|
+
};
|
9
|
+
export declare class ObjectComponent extends ReactComponent {
|
10
|
+
relatedObject?: Obj;
|
11
|
+
[x: string]: any;
|
12
|
+
static schema: any;
|
13
|
+
component: ObjectComponentProps;
|
14
|
+
errorDetails: any;
|
15
|
+
componentRoot?: Root;
|
16
|
+
criteria?: Record<string, unknown>;
|
17
|
+
updatedCriteria: Record<string, unknown>;
|
18
|
+
defaultValueCriteria?: Record<string, unknown>;
|
19
|
+
updatedDefaultValueCriteria: Record<string, unknown>;
|
20
|
+
constructor(component: ObjectComponentProps, options: any, data: any);
|
21
|
+
init(): void;
|
22
|
+
clearErrors(): void;
|
23
|
+
handleValidation(): void;
|
24
|
+
hasErrors(): boolean;
|
25
|
+
errorMessages(): string;
|
26
|
+
/**
|
27
|
+
* Synchronizes out-of-the-box formio errors with this field's errorDetails object
|
28
|
+
*/
|
29
|
+
manageFormErrors(): void;
|
30
|
+
handleChangeObjectProperty: (key: string, value?: Reference | null) => void;
|
31
|
+
beforeSubmit(): void;
|
32
|
+
attachReact(element: Element): void;
|
33
|
+
}
|
34
|
+
export {};
|
package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectComponent.js
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
import { ReactComponent } from '@formio/react';
|
2
|
+
import dot from 'dot-object';
|
3
|
+
import { cloneDeep, isEmpty } from 'lodash';
|
4
|
+
import React from 'react';
|
5
|
+
import { createRoot } from 'react-dom/client';
|
6
|
+
import { FormComponentWrapper } from '../../Common';
|
7
|
+
import { getAllCriteriaInputs, isPropertyVisible, transformToWhere, updateCriteriaInputs } from '../../utils';
|
8
|
+
import { ObjectPropertyInput } from './ObjectPropertyInput';
|
9
|
+
export class ObjectComponent extends ReactComponent {
|
10
|
+
constructor(component, options, data) {
|
11
|
+
var _a, _b;
|
12
|
+
super(Object.assign(Object.assign({}, component), { canUpdateProperty: !component.readOnly, hideLabel: true }), options, data);
|
13
|
+
this.handleChangeObjectProperty = (key, value) => {
|
14
|
+
// set the value on the form instance at this.root.data
|
15
|
+
this.setValue(value !== null && value !== void 0 ? value : '');
|
16
|
+
// update the value in the component instance
|
17
|
+
this.updateValue(value !== null && value !== void 0 ? value : {}, { modified: true });
|
18
|
+
this.handleValidation();
|
19
|
+
this.emit('changed-' + this.component.key, value);
|
20
|
+
this.attach(this.element);
|
21
|
+
this.component.autoSave && this.component.autoSave({ [key]: value });
|
22
|
+
};
|
23
|
+
this.errorDetails = {};
|
24
|
+
this.criteria = component.validate.criteria;
|
25
|
+
this.updatedCriteria = (_a = cloneDeep(component.validate.criteria)) !== null && _a !== void 0 ? _a : {};
|
26
|
+
this.defaultValueCriteria = component.defaultValueCriteria;
|
27
|
+
this.updatedDefaultValueCriteria = (_b = cloneDeep(component.defaultValueCriteria)) !== null && _b !== void 0 ? _b : {};
|
28
|
+
this.handleChangeObjectProperty = this.handleChangeObjectProperty.bind(this);
|
29
|
+
}
|
30
|
+
init() {
|
31
|
+
var _a, _b;
|
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
|
+
const data = dot.dot(this.root._data);
|
52
|
+
if (this.criteria) {
|
53
|
+
const inputProps = getAllCriteriaInputs(this.criteria);
|
54
|
+
for (const inputProp of inputProps) {
|
55
|
+
// Parse data to update criteria when form is loaded.
|
56
|
+
updateCriteriaInputs(this.updatedCriteria, inputProp, data[inputProp], true);
|
57
|
+
// Parse data to update criteria when form field is updated
|
58
|
+
// Need to parse all fields again.
|
59
|
+
const compKeyFragments = inputProp.split('.');
|
60
|
+
let compKey = compKeyFragments[0];
|
61
|
+
if (['line1', 'line2', 'city', 'state', 'zipCode'].includes(compKeyFragments[1])) {
|
62
|
+
compKey = inputProp;
|
63
|
+
}
|
64
|
+
this.on(`changed-${compKey}`, () => {
|
65
|
+
var _a;
|
66
|
+
const data = dot.dot(this.root._data);
|
67
|
+
this.updatedCriteria = (_a = cloneDeep(this.criteria)) !== null && _a !== void 0 ? _a : {};
|
68
|
+
for (const inputProp of inputProps) {
|
69
|
+
updateCriteriaInputs(this.updatedCriteria, inputProp, data[inputProp], true);
|
70
|
+
}
|
71
|
+
this.attachReact(this.element);
|
72
|
+
});
|
73
|
+
}
|
74
|
+
}
|
75
|
+
if (this.defaultValueCriteria) {
|
76
|
+
const inputProps = getAllCriteriaInputs(this.defaultValueCriteria);
|
77
|
+
updateCriteriaInputs(this.updatedDefaultValueCriteria, 'user.id', (_b = (_a = this.component.user) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : '');
|
78
|
+
for (const inputProp of inputProps) {
|
79
|
+
// Parse data to update criteria when form is loaded.
|
80
|
+
updateCriteriaInputs(this.updatedDefaultValueCriteria, inputProp, data[inputProp], true);
|
81
|
+
// Parse data to update criteria when form field is updated
|
82
|
+
// Need to parse all fields again.
|
83
|
+
const compKeyFragments = inputProp.split('.');
|
84
|
+
let compKey = compKeyFragments[0];
|
85
|
+
if (['line1', 'line2', 'city', 'state', 'zipCode'].includes(compKeyFragments[1])) {
|
86
|
+
compKey = inputProp;
|
87
|
+
}
|
88
|
+
this.on(`changed-${compKey}`, () => {
|
89
|
+
var _a, _b, _c;
|
90
|
+
const data = dot.dot(this.root._data);
|
91
|
+
this.updatedDefaultValueCriteria = (_a = cloneDeep(this.defaultValueCriteria)) !== null && _a !== void 0 ? _a : {};
|
92
|
+
updateCriteriaInputs(this.updatedDefaultValueCriteria, 'user.id', (_c = (_b = this.component.user) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : '');
|
93
|
+
for (const inputProp of inputProps) {
|
94
|
+
updateCriteriaInputs(this.updatedDefaultValueCriteria, inputProp, data[inputProp], true);
|
95
|
+
}
|
96
|
+
this.attachReact(this.element);
|
97
|
+
});
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}
|
101
|
+
clearErrors() {
|
102
|
+
this.errorDetails = {};
|
103
|
+
this.root.customErrors = this.root.customErrors.filter((error) => error.formattedKeyOrPath !== this.component.key);
|
104
|
+
}
|
105
|
+
handleValidation() {
|
106
|
+
if (!isPropertyVisible(this.component.conditional, this.root.data)) {
|
107
|
+
return;
|
108
|
+
}
|
109
|
+
//check for out-of-the-box formio errors which store on this.root.errors
|
110
|
+
this.checkValidity(this.dataValue, true, this.data);
|
111
|
+
this.manageFormErrors();
|
112
|
+
}
|
113
|
+
hasErrors() {
|
114
|
+
return !isEmpty(this.errorDetails);
|
115
|
+
}
|
116
|
+
errorMessages() {
|
117
|
+
return Object.values(this.errorDetails).join(', ');
|
118
|
+
}
|
119
|
+
/**
|
120
|
+
* Synchronizes out-of-the-box formio errors with this field's errorDetails object
|
121
|
+
*/
|
122
|
+
manageFormErrors() {
|
123
|
+
var _a;
|
124
|
+
const outOfTheBoxError = (_a = this.root.errors.find((error) => {
|
125
|
+
return error.component.key === this.component.key;
|
126
|
+
})) === null || _a === void 0 ? void 0 : _a.message;
|
127
|
+
//add OoB formio error to errorDetails object to show under field
|
128
|
+
if (outOfTheBoxError) {
|
129
|
+
this.errorDetails['rootError'] = outOfTheBoxError;
|
130
|
+
}
|
131
|
+
else {
|
132
|
+
delete this.errorDetails['rootError'];
|
133
|
+
}
|
134
|
+
}
|
135
|
+
beforeSubmit() {
|
136
|
+
this.handleValidation();
|
137
|
+
this.element && this.attach(this.element);
|
138
|
+
}
|
139
|
+
attachReact(element) {
|
140
|
+
const updatedComponent = Object.assign(Object.assign({}, this.component), { instance: Object.assign(Object.assign({}, this.component.instance), { [this.component.key]: isEmpty(this.dataValue) ? null : this.dataValue }), defaultValueCriteria: this.updatedDefaultValueCriteria });
|
141
|
+
if (!this.componentRoot) {
|
142
|
+
this.componentRoot = createRoot(element);
|
143
|
+
}
|
144
|
+
// FormIO uses id for an enclosing div, so we need to give the input field a different id.
|
145
|
+
const inputId = `${this.component.id}-input`;
|
146
|
+
return this.componentRoot.render(React.createElement("div", null,
|
147
|
+
React.createElement(FormComponentWrapper, Object.assign({}, updatedComponent, { inputId: inputId, errorMessage: this.errorMessages() }),
|
148
|
+
React.createElement(ObjectPropertyInput, Object.assign({}, updatedComponent, { id: inputId, handleChangeObjectProperty: this.handleChangeObjectProperty, error: this.hasErrors(), filter: this.criteria ? { where: transformToWhere(this.updatedCriteria) } : undefined })))));
|
149
|
+
}
|
150
|
+
}
|