@evoke-platform/ui-components 1.6.0-dev.7 → 1.6.0-testing.1
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/core/index.d.ts +1 -1
- package/dist/published/components/core/index.js +1 -1
- package/dist/published/components/custom/BuilderGrid/BuilderGrid.js +27 -27
- package/dist/published/components/custom/Form/FormComponents/RepeatableFieldComponent/RepeatableField.js +57 -87
- package/dist/published/components/custom/FormField/Select/Select.js +5 -17
- package/dist/published/index.d.ts +1 -1
- package/dist/published/index.js +1 -1
- package/package.json +1 -1
@@ -47,7 +47,7 @@ export { Tooltip } from './Tooltip';
|
|
47
47
|
export { Typography } from './Typography';
|
48
48
|
export { TabContext, TabList, TabPanel, TreeItem, TreeView } from '@mui/lab';
|
49
49
|
export { CardActionArea, CardActions, CardContent, CardHeader, CardMedia, Input, InputAdornment, InputLabel, ListItemButton, ListItemText, MenuList, SvgIcon, TableBody, TableCell, TableContainer, TableHead, TablePagination, TableRow, TableSortLabel, } from '@mui/material';
|
50
|
-
export {
|
50
|
+
export { useGridApiRef } from '@mui/x-data-grid';
|
51
51
|
export { TreeItem as RichTreeItem, RichTreeView, TreeItem2Content, TreeItem2DragAndDropOverlay, TreeItem2GroupTransition, TreeItem2Icon, TreeItem2IconContainer, TreeItem2Label, TreeItem2Provider, TreeItem2Root, useTreeItem2, } from '@mui/x-tree-view';
|
52
52
|
export type { GridSize } from '@mui/material';
|
53
53
|
export type { GridCellParams, GridColDef, GridEventListener, GridFilterModel, GridInitialState, GridRowParams, GridSortModel, GridValueFormatterParams, GridValueGetterParams, } from '@mui/x-data-grid';
|
@@ -48,5 +48,5 @@ export { Typography } from './Typography';
|
|
48
48
|
//TODO: Review following components. They also need theme control:
|
49
49
|
export { TabContext, TabList, TabPanel, TreeItem, TreeView } from '@mui/lab';
|
50
50
|
export { CardActionArea, CardActions, CardContent, CardHeader, CardMedia, Input, InputAdornment, InputLabel, ListItemButton, ListItemText, MenuList, SvgIcon, TableBody, TableCell, TableContainer, TableHead, TablePagination, TableRow, TableSortLabel, } from '@mui/material';
|
51
|
-
export {
|
51
|
+
export { useGridApiRef } from '@mui/x-data-grid';
|
52
52
|
export { TreeItem as RichTreeItem, RichTreeView, TreeItem2Content, TreeItem2DragAndDropOverlay, TreeItem2GroupTransition, TreeItem2Icon, TreeItem2IconContainer, TreeItem2Label, TreeItem2Provider, TreeItem2Root, useTreeItem2, } from '@mui/x-tree-view';
|
@@ -17,32 +17,7 @@ const BuilderGrid = (props) => {
|
|
17
17
|
borderBottom: 'none',
|
18
18
|
boxShadow: 'rgba(145, 158, 171, 0.2) 0px 8px 16px',
|
19
19
|
} },
|
20
|
-
React.createElement(MuiDataGrid, { autoPageSize: !disablePagination, hideFooterPagination: disablePagination, hideFooter: disablePagination, onMenuOpen: (env) => setAnchorEl(env.target), loading: loading, rows: rows,
|
21
|
-
sorting: {
|
22
|
-
sortModel: initialSort ? [initialSort] : [],
|
23
|
-
},
|
24
|
-
}, componentsProps: {
|
25
|
-
panel: {
|
26
|
-
anchorEl: anchorEl,
|
27
|
-
placement: 'bottom-end',
|
28
|
-
sx: {
|
29
|
-
'& .MuiPaper-root': {
|
30
|
-
borderRadius: '6px',
|
31
|
-
boxShadow: '0px 24px 48px rgba(145, 158, 171, 0.4)',
|
32
|
-
padding: '8px',
|
33
|
-
stop: -120,
|
34
|
-
},
|
35
|
-
},
|
36
|
-
},
|
37
|
-
}, slots: {
|
38
|
-
toolbar: hideToolbar ? null : toolbar,
|
39
|
-
noResultsOverlay: () => {
|
40
|
-
return React.createElement(Box, null);
|
41
|
-
},
|
42
|
-
noRowsOverlay: () => {
|
43
|
-
return noRowsOverlay ? noRowsOverlay : null;
|
44
|
-
},
|
45
|
-
}, rowHeight: 60, columnHeaderHeight: 62, ...rest, sx: {
|
20
|
+
React.createElement(MuiDataGrid, { autoPageSize: !disablePagination, hideFooterPagination: disablePagination, hideFooter: disablePagination, onMenuOpen: (env) => setAnchorEl(env.target), loading: loading, rows: rows, ...rest, sx: {
|
46
21
|
border: 'none',
|
47
22
|
'& .MuiDataGrid-toolbarContainer': {
|
48
23
|
padding: '0',
|
@@ -89,7 +64,32 @@ const BuilderGrid = (props) => {
|
|
89
64
|
},
|
90
65
|
height: disablePagination && !loading ? 'auto' : 'calc(100vh - 240px)',
|
91
66
|
...rest.sx,
|
92
|
-
}
|
67
|
+
}, getRowId: (row) => row.id, disableColumnMenu: true, initialState: {
|
68
|
+
sorting: {
|
69
|
+
sortModel: initialSort ? [initialSort] : [],
|
70
|
+
},
|
71
|
+
}, componentsProps: {
|
72
|
+
panel: {
|
73
|
+
anchorEl: anchorEl,
|
74
|
+
placement: 'bottom-end',
|
75
|
+
sx: {
|
76
|
+
'& .MuiPaper-root': {
|
77
|
+
borderRadius: '6px',
|
78
|
+
boxShadow: '0px 24px 48px rgba(145, 158, 171, 0.4)',
|
79
|
+
padding: '8px',
|
80
|
+
stop: -120,
|
81
|
+
},
|
82
|
+
},
|
83
|
+
},
|
84
|
+
}, slots: {
|
85
|
+
toolbar: hideToolbar ? null : toolbar,
|
86
|
+
noResultsOverlay: () => {
|
87
|
+
return React.createElement(Box, null);
|
88
|
+
},
|
89
|
+
noRowsOverlay: () => {
|
90
|
+
return noRowsOverlay ? noRowsOverlay : null;
|
91
|
+
},
|
92
|
+
}, rowHeight: 60, columnHeaderHeight: 62 }))) : (React.createElement(React.Fragment, null, error ? (React.createElement(Box, { sx: {
|
93
93
|
backgroundColor: '#fff',
|
94
94
|
borderRadius: '6px',
|
95
95
|
display: 'flex',
|
@@ -7,7 +7,6 @@ import sift from 'sift';
|
|
7
7
|
import { Edit, TrashCan } from '../../../../../icons';
|
8
8
|
import { Button, IconButton, Skeleton, Snackbar, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Tooltip, Typography, } from '../../../../core';
|
9
9
|
import { Box } from '../../../../layout';
|
10
|
-
import { getReadableQuery } from '../../../CriteriaBuilder';
|
11
10
|
import { getPrefixedUrl, normalizeDateTime, retrieveCustomErrorMessage } from '../../utils';
|
12
11
|
import { ActionDialog } from './ActionDialog';
|
13
12
|
import { DocumentViewerCell } from './DocumentViewerCell';
|
@@ -38,7 +37,6 @@ const RepeatableField = (props) => {
|
|
38
37
|
const [relatedObject, setRelatedObject] = useState();
|
39
38
|
const [hasCreateAction, setHasCreateAction] = useState(false);
|
40
39
|
const [users, setUsers] = useState();
|
41
|
-
const [criteriaObjects, setCriteriaObjects] = useState([]);
|
42
40
|
const [openDialog, setOpenDialog] = useState(false);
|
43
41
|
const [dialogType, setDialogType] = useState();
|
44
42
|
const [selectedRow, setSelectedRow] = useState();
|
@@ -52,7 +50,9 @@ const RepeatableField = (props) => {
|
|
52
50
|
const [error, setError] = useState(false);
|
53
51
|
const DEFAULT_CREATE_ACTION = '_create';
|
54
52
|
const { instanceChanges } = useNotification();
|
55
|
-
const
|
53
|
+
const fetchRelatedInstances = useCallback(async () => {
|
54
|
+
if (openDialog)
|
55
|
+
return;
|
56
56
|
let relatedObject;
|
57
57
|
if (property.objectId) {
|
58
58
|
try {
|
@@ -80,86 +80,31 @@ const RepeatableField = (props) => {
|
|
80
80
|
catch (err) {
|
81
81
|
console.error(error);
|
82
82
|
}
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
83
|
+
if (property.relatedPropertyId && instance?.id) {
|
84
|
+
const filterProperty = `${property.relatedPropertyId}.id`;
|
85
|
+
const filter = { where: { [filterProperty]: instance?.id }, limit: 100 };
|
86
|
+
const objectId = property.objectId;
|
87
|
+
try {
|
88
|
+
const timeout = setTimeout(() => {
|
89
|
+
setLoading(false);
|
90
|
+
}, 300);
|
91
|
+
setLoading(true);
|
92
|
+
const instances = await apiServices.get(getPrefixedUrl(`/objects/${objectId}/instances`), {
|
93
|
+
params: { filter: JSON.stringify(filter) },
|
94
|
+
});
|
95
|
+
clearTimeout(timeout);
|
95
96
|
setLoading(false);
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
setLoading(false);
|
103
|
-
if (instances) {
|
104
|
-
setRelatedInstances(instances);
|
97
|
+
if (instances) {
|
98
|
+
setRelatedInstances(instances);
|
99
|
+
}
|
100
|
+
}
|
101
|
+
catch (error) {
|
102
|
+
setError(true);
|
105
103
|
}
|
106
104
|
}
|
107
|
-
catch (error) {
|
108
|
-
setError(true);
|
109
|
-
}
|
110
|
-
}
|
111
|
-
}, [apiServices, property]);
|
112
|
-
const fetchCriteriaObjects = useCallback(async () => {
|
113
|
-
let objectIds = [];
|
114
|
-
const criteriaProperties = relatedObject?.properties?.filter((property) => property.type === 'criteria' && property.objectId) ?? [];
|
115
|
-
if (tableViewLayout) {
|
116
|
-
objectIds = criteriaProperties
|
117
|
-
.filter((p) => tableViewLayout.properties.some((column) => column.id === p.id))
|
118
|
-
.map((property) => property.objectId);
|
119
|
-
}
|
120
|
-
else {
|
121
|
-
objectIds = criteriaProperties.map((p) => p.objectId);
|
122
|
-
}
|
123
|
-
const objects = [];
|
124
|
-
for (const objectId of new Set(objectIds)) {
|
125
|
-
try {
|
126
|
-
const criteriaObject = await apiServices.get(getPrefixedUrl(`/objects/${objectId}/effective`), {
|
127
|
-
params: { fields: ['id', 'name', 'properties'] },
|
128
|
-
});
|
129
|
-
objects.push(criteriaObject);
|
130
|
-
}
|
131
|
-
catch (error) {
|
132
|
-
console.error(`Error fetching criteria object with ID ${objectId}:`, error);
|
133
|
-
}
|
134
|
-
}
|
135
|
-
setCriteriaObjects(objects);
|
136
|
-
}, [apiServices, relatedObject, tableViewLayout]);
|
137
|
-
useEffect(() => {
|
138
|
-
(async () => {
|
139
|
-
try {
|
140
|
-
const users = await apiServices.get(getPrefixedUrl(`/users`));
|
141
|
-
setUsers(users);
|
142
|
-
}
|
143
|
-
catch (error) {
|
144
|
-
console.error(error);
|
145
|
-
}
|
146
|
-
})();
|
147
|
-
}, [apiServices]);
|
148
|
-
useEffect(() => {
|
149
|
-
fetchRelatedObject();
|
150
|
-
fetchRelatedInstances();
|
151
|
-
}, [fetchRelatedInstances, fetchRelatedObject, reloadOnErrorTrigger, instance]);
|
152
|
-
useEffect(() => {
|
153
|
-
if (relatedObject)
|
154
|
-
fetchCriteriaObjects();
|
155
|
-
}, [fetchCriteriaObjects, relatedObject]);
|
156
|
-
useEffect(() => {
|
157
|
-
if (relatedObject?.rootObjectId) {
|
158
|
-
const callback = () => fetchRelatedInstances();
|
159
|
-
instanceChanges?.subscribe(relatedObject?.rootObjectId, callback);
|
160
|
-
return () => instanceChanges?.unsubscribe(relatedObject?.rootObjectId, callback);
|
161
105
|
}
|
162
|
-
|
106
|
+
relatedObject && checkCreateAccess(relatedObject);
|
107
|
+
}, [apiServices, property, viewLayout]);
|
163
108
|
const retrieveCriteria = (relatedObjProperty, action, object) => {
|
164
109
|
let property;
|
165
110
|
if (action.parameters) {
|
@@ -226,6 +171,27 @@ const RepeatableField = (props) => {
|
|
226
171
|
});
|
227
172
|
}
|
228
173
|
};
|
174
|
+
useEffect(() => {
|
175
|
+
(async () => {
|
176
|
+
try {
|
177
|
+
const users = await apiServices.get(getPrefixedUrl(`/users`));
|
178
|
+
setUsers(users);
|
179
|
+
}
|
180
|
+
catch (error) {
|
181
|
+
console.error(error);
|
182
|
+
}
|
183
|
+
})();
|
184
|
+
}, [apiServices]);
|
185
|
+
useEffect(() => {
|
186
|
+
fetchRelatedInstances();
|
187
|
+
}, [fetchRelatedInstances, reloadOnErrorTrigger, instance]);
|
188
|
+
useEffect(() => {
|
189
|
+
if (relatedObject?.rootObjectId) {
|
190
|
+
const callback = () => fetchRelatedInstances();
|
191
|
+
instanceChanges?.subscribe(relatedObject?.rootObjectId, callback);
|
192
|
+
return () => instanceChanges?.unsubscribe(relatedObject?.rootObjectId, callback);
|
193
|
+
}
|
194
|
+
}, [instanceChanges, relatedObject]);
|
229
195
|
const deleteRow = (id) => {
|
230
196
|
setDialogType('delete');
|
231
197
|
setSelectedRow(id);
|
@@ -368,24 +334,28 @@ const RepeatableField = (props) => {
|
|
368
334
|
};
|
369
335
|
const getValue = (relatedInstance, propertyId, propertyType) => {
|
370
336
|
const value = get(relatedInstance, propertyId);
|
337
|
+
// If the property is not date-like then just return the
|
338
|
+
// value found at the given path.
|
339
|
+
if (!['date', 'date-time', 'time'].includes(propertyType)) {
|
340
|
+
return value;
|
341
|
+
}
|
371
342
|
// If the date-like value is empty then there is no need to format.
|
372
343
|
if (!value) {
|
373
344
|
return value;
|
374
345
|
}
|
346
|
+
// At this point it has been asserted that there is a value
|
347
|
+
// and since the property is date-like the value must be
|
348
|
+
// a string.
|
349
|
+
const stringValue = value;
|
375
350
|
if (propertyType === 'date') {
|
376
|
-
return DateTime.fromISO(
|
351
|
+
return DateTime.fromISO(stringValue).toLocaleString(DateTime.DATE_SHORT);
|
377
352
|
}
|
378
353
|
if (propertyType === 'date-time') {
|
379
|
-
return DateTime.fromISO(
|
354
|
+
return DateTime.fromISO(stringValue).toLocaleString(DateTime.DATETIME_SHORT);
|
380
355
|
}
|
381
356
|
if (propertyType === 'time') {
|
382
|
-
return DateTime.fromISO(
|
383
|
-
}
|
384
|
-
if (propertyType === 'criteria' && typeof value === 'object') {
|
385
|
-
const property = relatedObject?.properties?.find((p) => p.id === propertyId);
|
386
|
-
return getReadableQuery(value, criteriaObjects.find((o) => o.id === property?.objectId)?.properties ?? []);
|
357
|
+
return DateTime.fromISO(stringValue).toLocaleString(DateTime.TIME_SIMPLE);
|
387
358
|
}
|
388
|
-
return value;
|
389
359
|
};
|
390
360
|
const columns = retrieveViewLayout();
|
391
361
|
return loading ? (React.createElement(React.Fragment, null,
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import { createFilterOptions, List, ListSubheader } from '@mui/material';
|
2
|
-
import { uniq } from 'lodash';
|
3
2
|
import React, { forwardRef, useEffect, useRef, useState } from 'react';
|
4
3
|
import { Clear } from '../../../../icons';
|
5
4
|
import { Autocomplete, FormControl, FormControlLabel, IconButton, Radio, RadioGroup, TextField, Typography, } from '../../../core';
|
@@ -16,7 +15,7 @@ const Select = (props) => {
|
|
16
15
|
const [isOtherFocused, setIsOtherFocused] = useState(false);
|
17
16
|
const [value, setValue] = useState(defaultValue);
|
18
17
|
const [inputValue, setInputValue] = useState(!selectOptions?.some((option) => (typeof option === 'string' && option === defaultValue) ||
|
19
|
-
option.value === defaultValue)
|
18
|
+
option.value === defaultValue)
|
20
19
|
? defaultValue
|
21
20
|
: '');
|
22
21
|
const [errorState, setErrorState] = useState();
|
@@ -28,14 +27,11 @@ const Select = (props) => {
|
|
28
27
|
otherInputRef.current.focus();
|
29
28
|
}
|
30
29
|
}, [isOther, value]);
|
31
|
-
useEffect(() => {
|
32
|
-
setValue(defaultValue);
|
33
|
-
}, [defaultValue]);
|
34
30
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
35
31
|
const handleChange = (event, selected) => {
|
36
32
|
if (Array.isArray(selected)) {
|
37
33
|
const newValues = selected.map((option) => option.value ?? option);
|
38
|
-
setValue(
|
34
|
+
setValue(newValues);
|
39
35
|
onChange && onChange(property.id, newValues, property);
|
40
36
|
}
|
41
37
|
else {
|
@@ -148,7 +144,6 @@ const Select = (props) => {
|
|
148
144
|
filtered.push({
|
149
145
|
value: inputValue,
|
150
146
|
label: `Add "${inputValue}"`,
|
151
|
-
isCustomValue: true,
|
152
147
|
});
|
153
148
|
}
|
154
149
|
return filtered;
|
@@ -156,19 +151,12 @@ const Select = (props) => {
|
|
156
151
|
? (option, value) => isOptionEqualToValue(option, value)
|
157
152
|
: undefined, getOptionLabel: getOptionLabel && !isCombobox
|
158
153
|
? (option) => getOptionLabel(option)
|
159
|
-
: (option) =>
|
160
|
-
if (typeof option === 'string')
|
161
|
-
return option;
|
162
|
-
// If the option is a custom value, return the value without the prepended "Add" text.
|
163
|
-
if (option.isCustomValue)
|
164
|
-
return option.value;
|
165
|
-
return option.label ?? '';
|
166
|
-
}, renderOption: renderOption
|
154
|
+
: (option) => (typeof option === 'string' ? option : option.label), renderOption: renderOption
|
167
155
|
? (props, option, state) => renderOption(props, option, state)
|
168
|
-
:
|
156
|
+
: undefined, ListboxComponent: ListboxComponent, disableCloseOnSelect: disableCloseOnSelect, sx: {
|
169
157
|
'& button.MuiButtonBase-root': {
|
170
158
|
visibility: 'visible',
|
171
159
|
},
|
172
|
-
},
|
160
|
+
}, ...(isCombobox ? { selectOnFocus: true, handleHomeEndKeys: true, freeSolo: true } : {}), ...(additionalProps ?? {}) }));
|
173
161
|
};
|
174
162
|
export default Select;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
export { ClickAwayListener, createTheme, darken, lighten, styled, Toolbar
|
1
|
+
export { ClickAwayListener, createTheme, darken, lighten, styled, Toolbar } from '@mui/material';
|
2
2
|
export { CalendarPicker, DateTimePicker, MonthPicker, PickersDay, StaticDateTimePicker, StaticTimePicker, TimePicker, YearPicker, } from '@mui/x-date-pickers';
|
3
3
|
export * from './colors';
|
4
4
|
export * from './components/core';
|
package/dist/published/index.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
export { ClickAwayListener, createTheme, darken, lighten, styled, Toolbar
|
1
|
+
export { ClickAwayListener, createTheme, darken, lighten, styled, Toolbar } from '@mui/material';
|
2
2
|
export { CalendarPicker, DateTimePicker, MonthPicker, PickersDay, StaticDateTimePicker, StaticTimePicker, TimePicker, YearPicker, } from '@mui/x-date-pickers';
|
3
3
|
export * from './colors';
|
4
4
|
export * from './components/core';
|