@evoke-platform/ui-components 1.0.0-dev.225 → 1.0.0-dev.226
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/FormComponents/ObjectComponent/InstanceLookup.d.ts +2 -1
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/InstanceLookup.js +12 -12
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectPropertyInput.js +26 -5
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/RelatedObjectInstance.d.ts +2 -1
- package/dist/published/components/custom/Form/FormComponents/ObjectComponent/RelatedObjectInstance.js +2 -2
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ManyToMany/DropdownRepeatableField.d.ts +2 -1
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ManyToMany/DropdownRepeatableField.js +15 -5
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ManyToMany/DropdownRepeatableFieldInput.d.ts +1 -1
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/ManyToMany/DropdownRepeatableFieldInput.js +6 -7
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableField.d.ts +2 -1
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableField.js +61 -42
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableFieldComponent.d.ts +2 -1
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableFieldComponent.js +2 -2
- package/dist/published/components/custom/Form/types.d.ts +2 -1
- package/dist/published/components/custom/Form/utils.js +1 -1
- package/package.json +2 -2
package/dist/published/components/custom/Form/FormComponents/ObjectComponent/InstanceLookup.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/// <reference types="react" />
|
2
|
-
import { ApiServices, Obj, ObjectInstance, Property } from '@evoke-platform/context';
|
2
|
+
import { ApiServices, Obj, ObjectInstance, Property, TableViewLayout } from '@evoke-platform/context';
|
3
3
|
export declare type InstanceLookUpProps = {
|
4
4
|
object: Obj;
|
5
5
|
instanceId?: string;
|
@@ -9,6 +9,7 @@ export declare type InstanceLookUpProps = {
|
|
9
9
|
mode: 'default' | 'existingOnly';
|
10
10
|
nestedFieldsView?: boolean;
|
11
11
|
filter?: Record<string, unknown>;
|
12
|
+
layout?: TableViewLayout;
|
12
13
|
};
|
13
14
|
export declare type SearchFieldProps = {
|
14
15
|
searchableColumns: Property[];
|
package/dist/published/components/custom/Form/FormComponents/ObjectComponent/InstanceLookup.js
CHANGED
@@ -54,20 +54,20 @@ const SearchField = (props) => {
|
|
54
54
|
} }));
|
55
55
|
};
|
56
56
|
export const InstanceLookup = (props) => {
|
57
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k
|
58
|
-
const { object, apiServices, setSelectedInstance, mode, nestedFieldsView, setRelationType, filter: criteriaFilter, } = props;
|
57
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
58
|
+
const { object, apiServices, setSelectedInstance, mode, nestedFieldsView, setRelationType, filter: criteriaFilter, layout, } = props;
|
59
59
|
const [rows, setRows] = useState([]);
|
60
60
|
const [loading, setLoading] = useState(false);
|
61
61
|
const [filter, setFilter] = useState();
|
62
62
|
const [searchString, setSearchString] = useState('');
|
63
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
64
|
const retrieveColumns = (tableViewLayout) => {
|
65
|
-
var _a, _b, _c;
|
65
|
+
var _a, _b, _c, _d;
|
66
66
|
let columns = [];
|
67
|
-
if (tableViewLayout === null || tableViewLayout === void 0 ? void 0 : tableViewLayout.properties) {
|
67
|
+
if ((_a = tableViewLayout === null || tableViewLayout === void 0 ? void 0 : tableViewLayout.properties) === null || _a === void 0 ? void 0 : _a.length) {
|
68
68
|
for (const prop of tableViewLayout.properties) {
|
69
69
|
const propertyId = prop.id.split('.')[0];
|
70
|
-
const property = (
|
70
|
+
const property = (_b = object.properties) === null || _b === void 0 ? void 0 : _b.find((p) => p.id === propertyId);
|
71
71
|
if (property) {
|
72
72
|
if (property.type === 'address') {
|
73
73
|
columns.push({
|
@@ -166,20 +166,19 @@ export const InstanceLookup = (props) => {
|
|
166
166
|
}
|
167
167
|
}
|
168
168
|
else {
|
169
|
-
const name = (
|
170
|
-
columns = [{ field: 'name', headerName: (
|
169
|
+
const name = (_c = object.properties) === null || _c === void 0 ? void 0 : _c.find((property) => property.id == 'name');
|
170
|
+
columns = [{ field: 'name', headerName: (_d = name === null || name === void 0 ? void 0 : name.name) !== null && _d !== void 0 ? _d : 'Name', type: 'string', flex: 1 }];
|
171
171
|
}
|
172
172
|
return columns;
|
173
173
|
};
|
174
174
|
function fetchObjectInstance() {
|
175
|
-
var _a;
|
176
175
|
setLoading(true);
|
177
176
|
const combinedFilter = Object.assign(Object.assign(Object.assign({}, criteriaFilter), filter), { where: (criteriaFilter === null || criteriaFilter === void 0 ? void 0 : criteriaFilter.where)
|
178
177
|
? {
|
179
178
|
and: [criteriaFilter.where, filter === null || filter === void 0 ? void 0 : filter.where],
|
180
179
|
}
|
181
180
|
: filter === null || filter === void 0 ? void 0 : filter.where });
|
182
|
-
apiServices.get(getPrefixedUrl(`/objects/${object.id}/instances`),
|
181
|
+
apiServices.get(getPrefixedUrl(`/objects/${object.id}/instances`), { params: { filter: JSON.stringify(combinedFilter) } }, (error, objectInstances) => {
|
183
182
|
if (error) {
|
184
183
|
console.error(error);
|
185
184
|
}
|
@@ -197,11 +196,12 @@ export const InstanceLookup = (props) => {
|
|
197
196
|
setRows([]);
|
198
197
|
}
|
199
198
|
}, [filter, searchString.length]);
|
199
|
+
const columns = retrieveColumns(layout);
|
200
200
|
return (React.createElement(Grid, { container: true, sx: { paddingBottom: '30px' } },
|
201
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:
|
203
|
-
field: (
|
204
|
-
sort: (
|
202
|
+
React.createElement(BuilderGrid, { item: 'instances', rows: rows, columns: columns, onRowClick: (params) => setSelectedInstance(params.row), initialSort: {
|
203
|
+
field: (_f = (_e = (_d = (_c = object.viewLayout) === null || _c === void 0 ? void 0 : _c.table) === null || _d === void 0 ? void 0 : _d.sort) === null || _e === void 0 ? void 0 : _e.colId) !== null && _f !== void 0 ? _f : 'name',
|
204
|
+
sort: (_k = (_j = (_h = (_g = object.viewLayout) === null || _g === void 0 ? void 0 : _g.table) === null || _h === void 0 ? void 0 : _h.sort) === null || _j === void 0 ? void 0 : _j.sort) !== null && _k !== void 0 ? _k : 'asc',
|
205
205
|
}, sx: {
|
206
206
|
height: '360px',
|
207
207
|
width: '100%',
|
package/dist/published/components/custom/Form/FormComponents/ObjectComponent/ObjectPropertyInput.js
CHANGED
@@ -9,7 +9,7 @@ import { getPrefixedUrl, normalizeDates, transformToWhere } from '../../utils';
|
|
9
9
|
import { RelatedObjectInstance } from './RelatedObjectInstance';
|
10
10
|
export const ObjectPropertyInput = (props) => {
|
11
11
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
12
|
-
const { id, instance, property, apiServices, defaultPages, handleChangeObjectProperty, nestedFieldsView, canUpdateProperty, error, navigateTo, mode, displayOption, filter, defaultValueCriteria, sortBy, orderBy, setSnackbarError, isModal, user, } = props;
|
12
|
+
const { id, instance, property, apiServices, defaultPages, handleChangeObjectProperty, nestedFieldsView, canUpdateProperty, error, navigateTo, mode, displayOption, filter, defaultValueCriteria, sortBy, orderBy, setSnackbarError, isModal, user, viewLayout, } = props;
|
13
13
|
const [relatedObject, setRelatedObject] = useState();
|
14
14
|
const [openCreateDialog, setOpenCreateDialog] = useState(false);
|
15
15
|
const [selectedInstance, setSelectedInstance] = useState();
|
@@ -17,7 +17,29 @@ export const ObjectPropertyInput = (props) => {
|
|
17
17
|
const [loadingOptions, setLoadingOptions] = useState(false);
|
18
18
|
const [options, setOptions] = useState([]);
|
19
19
|
const [openOptions, setOpenOptions] = useState(false);
|
20
|
+
const [layout, setLayout] = useState();
|
20
21
|
const DEFAULT_CREATE_ACTION = '_create';
|
22
|
+
useEffect(() => {
|
23
|
+
var _a, _b;
|
24
|
+
if (relatedObject) {
|
25
|
+
let defaultViewLayout;
|
26
|
+
if (((_a = relatedObject === null || relatedObject === void 0 ? void 0 : relatedObject.viewLayout) === null || _a === void 0 ? void 0 : _a.dropdown) && displayOption === 'dropdown') {
|
27
|
+
defaultViewLayout = Object.assign({ id: 'default', name: 'Default', objectId: relatedObject.id }, relatedObject.viewLayout.dropdown);
|
28
|
+
}
|
29
|
+
else if (((_b = relatedObject === null || relatedObject === void 0 ? void 0 : relatedObject.viewLayout) === null || _b === void 0 ? void 0 : _b.table) && displayOption === 'dialogBox') {
|
30
|
+
defaultViewLayout = Object.assign({ id: 'default', name: 'Default', objectId: relatedObject.id }, relatedObject.viewLayout.table);
|
31
|
+
}
|
32
|
+
if (viewLayout) {
|
33
|
+
apiServices
|
34
|
+
.get(getPrefixedUrl(`/objects/${viewLayout.objectId}/${displayOption === 'dropdown' ? 'dropdown' : 'table'}Layouts/${viewLayout.id}`))
|
35
|
+
.then(setLayout)
|
36
|
+
.catch((err) => setLayout(defaultViewLayout));
|
37
|
+
}
|
38
|
+
else {
|
39
|
+
setLayout(defaultViewLayout);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}, [displayOption, relatedObject, viewLayout]);
|
21
43
|
useEffect(() => {
|
22
44
|
var _a;
|
23
45
|
if (!isEmpty(defaultValueCriteria) && !selectedInstance && !instance[property.id]) {
|
@@ -160,11 +182,10 @@ export const ObjectPropertyInput = (props) => {
|
|
160
182
|
}
|
161
183
|
: {})),
|
162
184
|
}, noOptionsText: 'No options available', renderOption: (props, option) => {
|
163
|
-
var _a, _b, _c, _d;
|
164
185
|
return (React.createElement("li", Object.assign({}, props, { key: option.id }),
|
165
186
|
React.createElement(Box, null,
|
166
187
|
React.createElement(Typography, { sx: { marginLeft: '8px', fontSize: '14px' } }, option.label),
|
167
|
-
(
|
188
|
+
(layout === null || layout === void 0 ? void 0 : layout.secondaryTextExpression) ? (React.createElement(Typography, { sx: { marginLeft: '8px', fontSize: '14px', color: '#637381' } }, compileExpression(layout === null || layout === void 0 ? void 0 : layout.secondaryTextExpression, options.find((o) => o.id === option.value)))) : null)));
|
168
189
|
}, onOpen: () => {
|
169
190
|
var _a;
|
170
191
|
if (((_a = instance === null || instance === void 0 ? void 0 : instance[property.id]) === null || _a === void 0 ? void 0 : _a.id) || (selectedInstance === null || selectedInstance === void 0 ? void 0 : selectedInstance.id)) {
|
@@ -294,7 +315,7 @@ export const ObjectPropertyInput = (props) => {
|
|
294
315
|
event.stopPropagation();
|
295
316
|
setOpenCreateDialog(true);
|
296
317
|
}, "aria-label": `Add`, disabled: !canUpdateProperty }, "Add")))),
|
297
|
-
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 })) : (React.createElement(Dialog, { fullWidth: true, maxWidth: "md", open: openCreateDialog, onClose: (e, reason) => reason !== 'backdropClick' && handleClose },
|
318
|
+
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 },
|
298
319
|
React.createElement(Typography, { sx: {
|
299
320
|
marginTop: '28px',
|
300
321
|
fontSize: '22px',
|
@@ -302,5 +323,5 @@ export const ObjectPropertyInput = (props) => {
|
|
302
323
|
marginLeft: '24px',
|
303
324
|
marginBottom: '10px',
|
304
325
|
} }, `Add ${property.name}`),
|
305
|
-
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 })))))));
|
326
|
+
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 })))))));
|
306
327
|
};
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/// <reference types="react" />
|
2
|
-
import { ApiServices, Obj, ObjectInstance, Property, Reference, UserAccount } from '@evoke-platform/context';
|
2
|
+
import { ApiServices, Obj, ObjectInstance, Property, Reference, TableViewLayout, UserAccount } from '@evoke-platform/context';
|
3
3
|
export declare type RelatedObjectInstanceProps = {
|
4
4
|
relatedObject?: Obj;
|
5
5
|
property: Property;
|
@@ -20,5 +20,6 @@ export declare type RelatedObjectInstanceProps = {
|
|
20
20
|
options: ObjectInstance[];
|
21
21
|
filter?: Record<string, unknown>;
|
22
22
|
user?: UserAccount;
|
23
|
+
layout?: TableViewLayout;
|
23
24
|
};
|
24
25
|
export declare const RelatedObjectInstance: (props: RelatedObjectInstanceProps) => JSX.Element;
|
@@ -30,7 +30,7 @@ const styles = {
|
|
30
30
|
const DEFAULT_CREATE_ACTION = '_create';
|
31
31
|
export const RelatedObjectInstance = (props) => {
|
32
32
|
var _a;
|
33
|
-
const { relatedObject, property, setSelectedInstance, handleChangeObjectProperty, handleClose, apiServices, setSnackbarError, nestedFieldsView, mode, displayOption, setOptions, options, filter, user, } = props;
|
33
|
+
const { relatedObject, property, setSelectedInstance, handleChangeObjectProperty, handleClose, apiServices, setSnackbarError, nestedFieldsView, mode, displayOption, setOptions, options, filter, user, layout, } = props;
|
34
34
|
const [relationType, setRelationType] = useState(displayOption === 'dropdown' ? 'new' : 'existing');
|
35
35
|
const [selectedRow, setSelectedRow] = useState();
|
36
36
|
const [errors, setErrors] = useState([]);
|
@@ -114,7 +114,7 @@ export const RelatedObjectInstance = (props) => {
|
|
114
114
|
apiServices: apiServices,
|
115
115
|
setSnackbarError: setSnackbarError,
|
116
116
|
}, queryAddresses: queryAddresses, user: userAccount }))) : (relatedObject && (React.createElement(React.Fragment, null,
|
117
|
-
React.createElement(InstanceLookup, { apiServices: apiServices, nestedFieldsView: nestedFieldsView, setRelationType: setRelationType, object: relatedObject, setSelectedInstance: setSelectedRow, mode: mode, filter: filter }))))),
|
117
|
+
React.createElement(InstanceLookup, { apiServices: apiServices, nestedFieldsView: nestedFieldsView, setRelationType: setRelationType, object: relatedObject, setSelectedInstance: setSelectedRow, mode: mode, filter: filter, layout: layout }))))),
|
118
118
|
relationType !== 'new' && (React.createElement(Box, { sx: styles.actionButtons },
|
119
119
|
React.createElement(Button, { onClick: onClose, color: 'inherit', sx: {
|
120
120
|
border: '1px solid #ced4da',
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/// <reference types="react" />
|
2
|
-
import { ApiServices, ObjWithRoot, ObjectInstance, Property } from '@evoke-platform/context';
|
2
|
+
import { ApiServices, ObjWithRoot, ObjectInstance, Property, ViewLayoutEntityReference } from '@evoke-platform/context';
|
3
3
|
export declare type DropdownRepeatableFieldProps = {
|
4
4
|
id: string;
|
5
5
|
property: Property;
|
@@ -11,5 +11,6 @@ export declare type DropdownRepeatableFieldProps = {
|
|
11
11
|
middleObject: ObjWithRoot;
|
12
12
|
getMiddleObjectInstances: () => Promise<ObjectInstance[]>;
|
13
13
|
fieldHeight?: 'small' | 'medium';
|
14
|
+
viewLayout?: ViewLayoutEntityReference;
|
14
15
|
};
|
15
16
|
export declare const DropdownRepeatableField: (props: DropdownRepeatableFieldProps) => JSX.Element;
|
@@ -15,11 +15,11 @@ import { getMiddleObject, getPrefixedUrl, transformToWhere } from '../../../util
|
|
15
15
|
import { DropdownRepeatableFieldInput } from './DropdownRepeatableFieldInput';
|
16
16
|
export const DropdownRepeatableField = (props) => {
|
17
17
|
var _a;
|
18
|
-
const { id, property, criteria, instance, readOnly, apiServices, initialMiddleObjectInstances, middleObject, getMiddleObjectInstances, fieldHeight, } = props;
|
18
|
+
const { id, property, criteria, instance, readOnly, apiServices, initialMiddleObjectInstances, middleObject, getMiddleObjectInstances, fieldHeight, viewLayout, } = props;
|
19
19
|
const [middleObjectInstances, setMiddleObjectInstances] = useState(initialMiddleObjectInstances);
|
20
20
|
const [endObject, setEndObject] = useState();
|
21
21
|
const [endObjectInstances, setEndObjectInstances] = useState([]);
|
22
|
-
const [
|
22
|
+
const [layout, setLayout] = useState();
|
23
23
|
const [loading, setLoading] = useState(false);
|
24
24
|
const [initialLoading, setInitialLoading] = useState(true);
|
25
25
|
const [selectedOptions, setSelectedOptions] = useState([]);
|
@@ -60,13 +60,23 @@ export const DropdownRepeatableField = (props) => {
|
|
60
60
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
61
61
|
const endObject = effectiveObject;
|
62
62
|
setEndObject(endObject);
|
63
|
+
let defaultLayout;
|
63
64
|
if ((_a = endObject.viewLayout) === null || _a === void 0 ? void 0 : _a.dropdown) {
|
64
|
-
|
65
|
+
defaultLayout = Object.assign({ id: 'default', name: 'Default', objectId: endObject.id }, endObject.viewLayout.dropdown);
|
66
|
+
}
|
67
|
+
if (viewLayout) {
|
68
|
+
apiServices
|
69
|
+
.get(getPrefixedUrl(`/objects/${viewLayout.objectId}/dropdownLayouts/${viewLayout.id}`))
|
70
|
+
.then(setLayout)
|
71
|
+
.catch((err) => setLayout(defaultLayout));
|
72
|
+
}
|
73
|
+
else {
|
74
|
+
setLayout(defaultLayout);
|
65
75
|
}
|
66
76
|
}
|
67
77
|
});
|
68
78
|
}
|
69
|
-
}, [middleObject, apiServices]);
|
79
|
+
}, [middleObject, apiServices, viewLayout, property]);
|
70
80
|
useEffect(() => {
|
71
81
|
instanceChanges === null || instanceChanges === void 0 ? void 0 : instanceChanges.subscribe(middleObject.rootObjectId, () => {
|
72
82
|
fetchMiddleObjectInstances();
|
@@ -154,5 +164,5 @@ export const DropdownRepeatableField = (props) => {
|
|
154
164
|
}
|
155
165
|
});
|
156
166
|
};
|
157
|
-
return initialLoading ? (React.createElement(Skeleton, null)) : (React.createElement(React.Fragment, null, middleObjectInstances && endObject && (React.createElement(DropdownRepeatableFieldInput, { id: id, property: property, readOnly: readOnly || !((_a = middleObject.actions) === null || _a === void 0 ? void 0 : _a.some((action) => action.id === '_create')),
|
167
|
+
return initialLoading ? (React.createElement(Skeleton, null)) : (React.createElement(React.Fragment, null, middleObjectInstances && endObject && (React.createElement(DropdownRepeatableFieldInput, { id: id, property: property, readOnly: readOnly || !((_a = middleObject.actions) === null || _a === void 0 ? void 0 : _a.some((action) => action.id === '_create')), layout: layout, middleObjectInstances: middleObjectInstances, endObjectInstances: endObjectInstances !== null && endObjectInstances !== void 0 ? endObjectInstances : [], endObject: endObject, searchValue: searchValue, loading: loading, handleSaveMiddleInstance: saveMiddleInstance, handleRemoveMiddleInstance: removeMiddleInstance, setSearchValue: setSearchValue, setSnackbarError: setSnackbarError, snackbarError: snackbarError, selectedOptions: selectedOptions, setSelectedOptions: setSelectedOptions, setDropdownSelections: setDropDownSelections, fieldHeight: fieldHeight }))));
|
158
168
|
};
|
@@ -5,7 +5,7 @@ declare type DropdownRepeatableFieldInputProps = {
|
|
5
5
|
id: string;
|
6
6
|
property: Property;
|
7
7
|
readOnly: boolean;
|
8
|
-
|
8
|
+
layout?: DropdownViewLayout;
|
9
9
|
middleObjectInstances: ObjectInstance[];
|
10
10
|
endObjectInstances: ObjectInstance[];
|
11
11
|
endObject: Obj;
|
@@ -6,13 +6,12 @@ import { Snackbar, TextField, Typography } from '../../../../../core';
|
|
6
6
|
import { normalizeDates } from '../../../utils';
|
7
7
|
const isDropdownRepeatableFieldInputOption = (option) => isObject(option) && 'label' in option && 'endObjectId' in option;
|
8
8
|
export const DropdownRepeatableFieldInput = (props) => {
|
9
|
-
const { id, property, readOnly,
|
9
|
+
const { id, property, readOnly, layout, middleObjectInstances, endObjectInstances, endObject, searchValue, loading, handleSaveMiddleInstance, handleRemoveMiddleInstance, setSearchValue, selectedOptions, setSnackbarError, snackbarError, setDropdownSelections, fieldHeight, } = props;
|
10
10
|
const [selectOptions, setSelectOptions] = useState([]);
|
11
11
|
useEffect(() => {
|
12
12
|
setDropdownSelections && setDropdownSelections(middleObjectInstances);
|
13
13
|
}, [middleObjectInstances]);
|
14
14
|
useEffect(() => {
|
15
|
-
var _a;
|
16
15
|
const manyToManyPropertyId = property.manyToManyPropertyId;
|
17
16
|
if (manyToManyPropertyId) {
|
18
17
|
const enums = endObjectInstances
|
@@ -23,20 +22,20 @@ export const DropdownRepeatableFieldInput = (props) => {
|
|
23
22
|
})
|
24
23
|
.map((endObjectInstance) => ({
|
25
24
|
label: endObjectInstance.name,
|
26
|
-
subLabel: (
|
27
|
-
? compileExpression(endObjectInstance,
|
25
|
+
subLabel: (layout === null || layout === void 0 ? void 0 : layout.secondaryTextExpression)
|
26
|
+
? compileExpression(endObjectInstance, layout.secondaryTextExpression)
|
28
27
|
: undefined,
|
29
28
|
endObjectId: endObjectInstance.id,
|
30
29
|
value: undefined,
|
31
30
|
}));
|
32
|
-
setSelectOptions(
|
31
|
+
setSelectOptions([
|
33
32
|
...enums,
|
34
33
|
...selectedOptions
|
35
34
|
.filter((selectedOption) => !enums.find((availableOption) => availableOption.endObjectId === selectedOption.endObjectId))
|
36
35
|
.map((option) => (Object.assign(Object.assign({}, option), { hidden: true }))),
|
37
|
-
])
|
36
|
+
]);
|
38
37
|
}
|
39
|
-
}, [endObjectInstances,
|
38
|
+
}, [endObjectInstances, layout]);
|
40
39
|
const handleChange = (key, newSelectedOptions) => {
|
41
40
|
// Delete middle objects that have been removed
|
42
41
|
// Add middle objects that have been added
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/// <reference types="react" />
|
2
|
-
import { ApiServices, ObjectInstance, Property, UserAccount } from '@evoke-platform/context';
|
2
|
+
import { ApiServices, ObjectInstance, Property, UserAccount, ViewLayoutEntityReference } from '@evoke-platform/context';
|
3
3
|
export declare type ObjectPropertyInputProps = {
|
4
4
|
property: Property;
|
5
5
|
instance: ObjectInstance;
|
@@ -7,6 +7,7 @@ export declare type ObjectPropertyInputProps = {
|
|
7
7
|
apiServices: ApiServices;
|
8
8
|
queryAddresses?: unknown;
|
9
9
|
user?: UserAccount;
|
10
|
+
viewLayout?: ViewLayoutEntityReference;
|
10
11
|
};
|
11
12
|
declare const RepeatableField: (props: ObjectPropertyInputProps) => JSX.Element;
|
12
13
|
export default RepeatableField;
|
@@ -13,8 +13,8 @@ import { get, isObject, pick, startCase } from 'lodash';
|
|
13
13
|
import { DateTime } from 'luxon';
|
14
14
|
import React, { useCallback, useEffect, useState } from 'react';
|
15
15
|
import sift from 'sift';
|
16
|
-
import { TrashCan } from '../../../../../icons';
|
17
|
-
import { Button, IconButton, Skeleton, Snackbar, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography, } from '../../../../core';
|
16
|
+
import { Edit, TrashCan } from '../../../../../icons';
|
17
|
+
import { Button, IconButton, Skeleton, Snackbar, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Tooltip, Typography, } from '../../../../core';
|
18
18
|
import { Box } from '../../../../layout';
|
19
19
|
import { getPrefixedUrl, normalizeDateTime } from '../../utils';
|
20
20
|
import { ActionDialog } from './ActionDialog';
|
@@ -40,8 +40,8 @@ const styles = {
|
|
40
40
|
},
|
41
41
|
};
|
42
42
|
const RepeatableField = (props) => {
|
43
|
-
var _a, _b
|
44
|
-
const { property, instance, canUpdateProperty, apiServices, queryAddresses, user } = props;
|
43
|
+
var _a, _b;
|
44
|
+
const { property, instance, canUpdateProperty, apiServices, queryAddresses, user, viewLayout } = props;
|
45
45
|
const [relatedInstances, setRelatedInstances] = useState([]);
|
46
46
|
const [relatedObject, setRelatedObject] = useState();
|
47
47
|
const [hasCreateAction, setHasCreateAction] = useState(false);
|
@@ -51,6 +51,7 @@ const RepeatableField = (props) => {
|
|
51
51
|
const [selectedRow, setSelectedRow] = useState();
|
52
52
|
const [loading, setLoading] = useState(true);
|
53
53
|
const [reloadOnErrorTrigger, setReloadOnErrorTrigger] = useState(true);
|
54
|
+
const [tableViewLayout, setTableViewLayout] = useState();
|
54
55
|
const [snackbarError, setSnackbarError] = useState({
|
55
56
|
showAlert: false,
|
56
57
|
isError: false,
|
@@ -59,12 +60,26 @@ const RepeatableField = (props) => {
|
|
59
60
|
const DEFAULT_CREATE_ACTION = '_create';
|
60
61
|
const { instanceChanges } = useNotification();
|
61
62
|
const fetchRelatedInstances = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
|
63
|
+
var _c;
|
62
64
|
if (openDialog)
|
63
65
|
return;
|
64
66
|
let relatedObject;
|
65
67
|
if (property.objectId) {
|
66
68
|
try {
|
67
69
|
relatedObject = yield apiServices.get(getPrefixedUrl(`/objects/${property.objectId}/effective`));
|
70
|
+
let defaultTableViewLayout;
|
71
|
+
if ((_c = relatedObject.viewLayout) === null || _c === void 0 ? void 0 : _c.table) {
|
72
|
+
defaultTableViewLayout = Object.assign({ id: 'default', name: 'Default', objectId: relatedObject.id }, relatedObject === null || relatedObject === void 0 ? void 0 : relatedObject.viewLayout.table);
|
73
|
+
}
|
74
|
+
if (viewLayout) {
|
75
|
+
apiServices
|
76
|
+
.get(getPrefixedUrl(`/objects/${viewLayout.objectId}/tableLayouts/${viewLayout.id}`))
|
77
|
+
.then(setTableViewLayout)
|
78
|
+
.catch((err) => setTableViewLayout(defaultTableViewLayout));
|
79
|
+
}
|
80
|
+
else {
|
81
|
+
setTableViewLayout(defaultTableViewLayout);
|
82
|
+
}
|
68
83
|
setRelatedObject(relatedObject);
|
69
84
|
}
|
70
85
|
catch (err) {
|
@@ -94,7 +109,7 @@ const RepeatableField = (props) => {
|
|
94
109
|
}
|
95
110
|
}
|
96
111
|
relatedObject && checkCreateAccess(relatedObject);
|
97
|
-
}), [apiServices, property]);
|
112
|
+
}), [apiServices, property, viewLayout]);
|
98
113
|
const checkCreateAccess = (relatedObject) => {
|
99
114
|
if (property.objectId && canUpdateProperty) {
|
100
115
|
apiServices
|
@@ -193,7 +208,7 @@ const RepeatableField = (props) => {
|
|
193
208
|
'min-width': '44px',
|
194
209
|
}, variant: "text", onClick: () => setReloadOnErrorTrigger((prevState) => !prevState) }, "Retry")));
|
195
210
|
const save = (actionType, input, instanceId, setSubmitting) => __awaiter(void 0, void 0, void 0, function* () {
|
196
|
-
var _f, _g, _h, _j
|
211
|
+
var _d, _e, _f, _g, _h, _j;
|
197
212
|
setSubmitting && setSubmitting(true);
|
198
213
|
// date-time fields are stored in the database in ISO format so convert all
|
199
214
|
// LocalDateTime objects to ISO format.
|
@@ -227,7 +242,7 @@ const RepeatableField = (props) => {
|
|
227
242
|
isError: true,
|
228
243
|
});
|
229
244
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
230
|
-
error = (
|
245
|
+
error = (_e = (_d = err.response) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.error;
|
231
246
|
setSubmitting && setSubmitting(false);
|
232
247
|
}
|
233
248
|
}
|
@@ -236,7 +251,7 @@ const RepeatableField = (props) => {
|
|
236
251
|
try {
|
237
252
|
yield apiServices.post(getPrefixedUrl(`/objects/${relatedObjectId}/instances/${instanceId}/actions`), {
|
238
253
|
actionId: `_${actionType}`,
|
239
|
-
input: pick(input, (
|
254
|
+
input: pick(input, (_g = (_f = relatedObject === null || relatedObject === void 0 ? void 0 : relatedObject.properties) === null || _f === void 0 ? void 0 : _f.filter((property) => !property.formula && property.type !== 'collection').map((property) => property.id)) !== null && _g !== void 0 ? _g : []),
|
240
255
|
});
|
241
256
|
if (actionType === 'delete') {
|
242
257
|
setRelatedInstances((prevInstances) => prevInstances.filter((instance) => instance.id !== instanceId));
|
@@ -259,18 +274,18 @@ const RepeatableField = (props) => {
|
|
259
274
|
isError: true,
|
260
275
|
});
|
261
276
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
262
|
-
error = (
|
277
|
+
error = (_j = (_h = err.response) === null || _h === void 0 ? void 0 : _h.data) === null || _j === void 0 ? void 0 : _j.error;
|
263
278
|
}
|
264
279
|
}
|
265
280
|
return { isSuccessful, error };
|
266
281
|
});
|
267
282
|
const retrieveViewLayout = () => {
|
268
|
-
var _a, _b, _c, _d
|
283
|
+
var _a, _b, _c, _d;
|
269
284
|
let properties = [];
|
270
|
-
if ((
|
271
|
-
for (const prop of
|
285
|
+
if ((_a = tableViewLayout === null || tableViewLayout === void 0 ? void 0 : tableViewLayout.properties) === null || _a === void 0 ? void 0 : _a.length) {
|
286
|
+
for (const prop of tableViewLayout.properties) {
|
272
287
|
const propertyId = prop.id.split('.')[0];
|
273
|
-
const property = (
|
288
|
+
const property = (_b = relatedObject === null || relatedObject === void 0 ? void 0 : relatedObject.properties) === null || _b === void 0 ? void 0 : _b.find((p) => p.id === propertyId);
|
274
289
|
if (property) {
|
275
290
|
if ((property.type === 'object' && property.id !== property.relatedPropertyId) ||
|
276
291
|
property.type === 'address' ||
|
@@ -289,9 +304,9 @@ const RepeatableField = (props) => {
|
|
289
304
|
}
|
290
305
|
else {
|
291
306
|
properties =
|
292
|
-
(
|
307
|
+
(_d = (_c = relatedObject === null || relatedObject === void 0 ? void 0 : relatedObject.properties) === null || _c === void 0 ? void 0 : _c.filter((prop) => !['address', 'image', 'collection'].includes(prop.type)).map((prop) => (Object.assign(Object.assign({}, prop), { id: prop.type === 'object' || prop.type === 'user' ? `${prop.id}.name` : prop.id })))) !== null && _d !== void 0 ? _d : [];
|
293
308
|
}
|
294
|
-
return properties
|
309
|
+
return properties;
|
295
310
|
};
|
296
311
|
const getValue = (relatedInstance, propertyId, propertyType) => {
|
297
312
|
const value = get(relatedInstance, propertyId);
|
@@ -321,6 +336,7 @@ const RepeatableField = (props) => {
|
|
321
336
|
return Array.isArray(value) ? value.map((v) => v.name).join(', ') : value;
|
322
337
|
}
|
323
338
|
};
|
339
|
+
const columns = retrieveViewLayout();
|
324
340
|
return loading ? (React.createElement(React.Fragment, null,
|
325
341
|
React.createElement(Skeleton, null),
|
326
342
|
React.createElement(Skeleton, null),
|
@@ -334,35 +350,38 @@ const RepeatableField = (props) => {
|
|
334
350
|
} },
|
335
351
|
React.createElement(Table, { stickyHeader: true, sx: { minWidth: 650 } },
|
336
352
|
React.createElement(TableHead, { sx: { backgroundColor: '#F4F6F8' } },
|
337
|
-
React.createElement(TableRow, null,
|
338
|
-
React.createElement(TableCell, { sx: styles.tableCell },
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
353
|
+
React.createElement(TableRow, null, columns === null || columns === void 0 ? void 0 :
|
354
|
+
columns.map((prop) => React.createElement(TableCell, { sx: styles.tableCell }, prop.name)),
|
355
|
+
React.createElement(TableCell, { sx: Object.assign(Object.assign({}, styles.tableCell), { width: '80px' }) }))),
|
356
|
+
React.createElement(TableBody, null, relatedInstances === null || relatedInstances === void 0 ? void 0 : relatedInstances.map((relatedInstance, index) => (React.createElement(TableRow, { key: relatedInstance.id }, columns === null || columns === void 0 ? void 0 :
|
357
|
+
columns.map((prop) => {
|
358
|
+
var _a;
|
359
|
+
return (React.createElement(TableCell, { sx: { color: '#212B36', fontSize: '16px' } },
|
360
|
+
React.createElement(Typography, { key: prop.id, sx: prop.id === 'name'
|
361
|
+
? {
|
362
|
+
'&:hover': {
|
363
|
+
textDecoration: 'underline',
|
364
|
+
cursor: 'pointer',
|
365
|
+
},
|
366
|
+
}
|
367
|
+
: {}, onClick: canUpdateProperty && prop.id === 'name'
|
368
|
+
? () => editRow(relatedInstance.id)
|
369
|
+
: undefined },
|
370
|
+
getValue(relatedInstance, prop.id, prop.type),
|
371
|
+
prop.type === 'user' &&
|
372
|
+
((_a = users === null || users === void 0 ? void 0 : users.find((user) => get(relatedInstance, `${prop.id.split('.')[0]}.id`) === user.id)) === null || _a === void 0 ? void 0 : _a.status) === 'Inactive' && React.createElement("span", null, ' (Inactive)'))));
|
373
|
+
}),
|
374
|
+
canUpdateProperty && (React.createElement(TableCell, { sx: { width: '80px' } },
|
375
|
+
React.createElement(IconButton, { "aria-label": `edit-collection-instance-${index}`, onClick: () => editRow(relatedInstance.id) },
|
376
|
+
React.createElement(Tooltip, { title: "Edit" },
|
377
|
+
React.createElement(Edit, null))),
|
378
|
+
React.createElement(IconButton, { "aria-label": `delete-collection-instance-${index}`, onClick: () => deleteRow(relatedInstance.id) },
|
379
|
+
React.createElement(Tooltip, { title: "Delete" },
|
380
|
+
React.createElement(TrashCan, { sx: { ':hover': { color: '#A12723' } } })))))))))))),
|
362
381
|
hasCreateAction && (React.createElement(Button, { variant: "contained", sx: styles.addButton, onClick: addRow }, "Add"))),
|
363
|
-
relatedObject && openDialog && (React.createElement(ActionDialog, { object: relatedObject, open: openDialog, apiServices: apiServices, onClose: () => setOpenDialog(false), instanceInput: dialogType === 'update' ? (
|
382
|
+
relatedObject && openDialog && (React.createElement(ActionDialog, { object: relatedObject, open: openDialog, apiServices: apiServices, onClose: () => setOpenDialog(false), instanceInput: dialogType === 'update' ? (_a = relatedInstances.find((i) => i.id === selectedRow)) !== null && _a !== void 0 ? _a : {} : {}, handleSubmit: save,
|
364
383
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
365
|
-
objectInputCommonProps: { apiServices }, action: (
|
384
|
+
objectInputCommonProps: { apiServices }, action: (_b = relatedObject === null || relatedObject === void 0 ? void 0 : relatedObject.actions) === null || _b === void 0 ? void 0 : _b.find((a) => a.id ===
|
366
385
|
(dialogType === 'create' ? '_create' : dialogType === 'update' ? '_update' : '_delete')), instanceId: selectedRow, relatedProperty: property, queryAddresses: queryAddresses, user: user })),
|
367
386
|
React.createElement(Snackbar, { open: snackbarError.showAlert, handleClose: () => setSnackbarError({ isError: snackbarError.isError, showAlert: false }), message: snackbarError.message, error: snackbarError.isError })));
|
368
387
|
};
|
@@ -1,10 +1,11 @@
|
|
1
|
-
import { ObjWithRoot, ObjectInstance } from '@evoke-platform/context';
|
1
|
+
import { ObjWithRoot, ObjectInstance, ViewLayoutEntityReference } from '@evoke-platform/context';
|
2
2
|
import { ReactComponent } from '@formio/react';
|
3
3
|
import { BaseFormComponentProps } from '../../types';
|
4
4
|
declare type RepeatableFieldComponentProps = BaseFormComponentProps & {
|
5
5
|
middleObject: ObjWithRoot;
|
6
6
|
initialMiddleObjectInstances: ObjectInstance[];
|
7
7
|
getMiddleObjectInstances: () => Promise<ObjectInstance[]>;
|
8
|
+
viewLayout?: ViewLayoutEntityReference;
|
8
9
|
};
|
9
10
|
export declare class RepeatableFieldComponent extends ReactComponent {
|
10
11
|
[x: string]: any;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { ApiBaseUrlProvider, NotificationProvider } from '@evoke-platform/context';
|
1
|
+
import { ApiBaseUrlProvider, NotificationProvider, } from '@evoke-platform/context';
|
2
2
|
import { ReactComponent } from '@formio/react';
|
3
3
|
import dot from 'dot-object';
|
4
4
|
import { cloneDeep } from 'lodash';
|
@@ -49,7 +49,7 @@ export class RepeatableFieldComponent extends ReactComponent {
|
|
49
49
|
const inputId = `${this.component.id}-input`;
|
50
50
|
return ReactDOM.render(React.createElement("div", null, !this.component.hidden ? (React.createElement(ApiBaseUrlProvider, { url: apiBaseUrl },
|
51
51
|
React.createElement(NotificationProvider, null,
|
52
|
-
React.createElement(FormComponentWrapper, Object.assign({}, this.component, { inputId: inputId, viewOnly: !this.component.canUpdateProperty }), this.component.property.manyToManyPropertyId ? (React.createElement(DropdownRepeatableField, { id: inputId, property: this.component.property, instance: this.component.instance, apiServices: this.component.apiServices, criteria: this.updatedCriteria, readOnly: !this.component.canUpdateProperty, initialMiddleObjectInstances: this.component.initialMiddleObjectInstances, middleObject: this.component.middleObject, getMiddleObjectInstances: this.component.getMiddleObjectInstances, fieldHeight: this.component.fieldHeight })) : (React.createElement(RepeatableField, Object.assign({}, this.component))))))) : null), element);
|
52
|
+
React.createElement(FormComponentWrapper, Object.assign({}, this.component, { inputId: inputId, viewOnly: !this.component.canUpdateProperty }), this.component.property.manyToManyPropertyId ? (React.createElement(DropdownRepeatableField, { id: inputId, property: this.component.property, instance: this.component.instance, apiServices: this.component.apiServices, criteria: this.updatedCriteria, readOnly: !this.component.canUpdateProperty, initialMiddleObjectInstances: this.component.initialMiddleObjectInstances, middleObject: this.component.middleObject, getMiddleObjectInstances: this.component.getMiddleObjectInstances, fieldHeight: this.component.fieldHeight, viewLayout: this.component.viewLayout })) : (React.createElement(RepeatableField, Object.assign({}, this.component))))))) : null), element);
|
53
53
|
}
|
54
54
|
detachReact(element) {
|
55
55
|
ReactDOM.unmountComponentAtNode(element);
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { ApiServices, ObjectInstance, Property, Reference, UserAccount } from '@evoke-platform/context';
|
1
|
+
import { ApiServices, ObjectInstance, Property, Reference, UserAccount, ViewLayoutEntityReference } from '@evoke-platform/context';
|
2
2
|
import { AutocompleteOption } from '../../core';
|
3
3
|
export declare type BaseFormComponentProps = {
|
4
4
|
key: string;
|
@@ -75,6 +75,7 @@ export declare type ObjectPropertyInputProps = {
|
|
75
75
|
orderBy?: string;
|
76
76
|
isModal?: boolean;
|
77
77
|
label?: string;
|
78
|
+
viewLayout?: ViewLayoutEntityReference;
|
78
79
|
};
|
79
80
|
export declare type Address = {
|
80
81
|
line1?: string;
|
@@ -243,7 +243,7 @@ export function convertFormToComponents(entries, parameters, object) {
|
|
243
243
|
}
|
244
244
|
: {
|
245
245
|
json: displayOptions === null || displayOptions === void 0 ? void 0 : displayOptions.visibility,
|
246
|
-
} });
|
246
|
+
}, viewLayout: displayOptions === null || displayOptions === void 0 ? void 0 : displayOptions.viewLayout });
|
247
247
|
}
|
248
248
|
})
|
249
249
|
.filter((item) => item);
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@evoke-platform/ui-components",
|
3
|
-
"version": "1.0.0-dev.
|
3
|
+
"version": "1.0.0-dev.226",
|
4
4
|
"description": "",
|
5
5
|
"main": "dist/published/index.js",
|
6
6
|
"module": "dist/published/index.js",
|
@@ -95,7 +95,7 @@
|
|
95
95
|
"@dnd-kit/sortable": "^7.0.1",
|
96
96
|
"@emotion/react": "^11.13.5",
|
97
97
|
"@emotion/styled": "^11.8.1",
|
98
|
-
"@evoke-platform/context": "^1.0.0-dev.
|
98
|
+
"@evoke-platform/context": "^1.0.0-dev.118",
|
99
99
|
"@formio/react": "^5.2.4-rc.1",
|
100
100
|
"@js-joda/core": "^3.2.0",
|
101
101
|
"@js-joda/locale_en-us": "^3.2.2",
|