@evoke-platform/ui-components 1.15.0 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.d.ts +8 -4
- package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.js +242 -142
- package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.test.js +189 -67
- package/dist/published/components/custom/CriteriaBuilder/PropertyTree.d.ts +6 -6
- package/dist/published/components/custom/CriteriaBuilder/PropertyTree.js +12 -25
- package/dist/published/components/custom/CriteriaBuilder/PropertyTreeItem.d.ts +4 -5
- package/dist/published/components/custom/CriteriaBuilder/PropertyTreeItem.js +34 -22
- package/dist/published/components/custom/CriteriaBuilder/types.d.ts +2 -11
- package/dist/published/components/custom/CriteriaBuilder/utils.d.ts +6 -34
- package/dist/published/components/custom/CriteriaBuilder/utils.js +18 -89
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.js +1 -1
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentList.js +6 -3
- package/dist/published/components/custom/Form/utils.d.ts +1 -0
- package/dist/published/components/custom/FormV2/FormRenderer.d.ts +2 -1
- package/dist/published/components/custom/FormV2/FormRenderer.js +2 -8
- package/dist/published/components/custom/FormV2/FormRendererContainer.d.ts +4 -0
- package/dist/published/components/custom/FormV2/FormRendererContainer.js +229 -126
- package/dist/published/components/custom/FormV2/components/DefaultValues.d.ts +1 -1
- package/dist/published/components/custom/FormV2/components/DefaultValues.js +60 -89
- package/dist/published/components/custom/FormV2/components/FormContext.d.ts +1 -1
- package/dist/published/components/custom/FormV2/components/FormContext.js +0 -1
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/ActionDialog.d.ts +1 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/RepeatableField.js +43 -16
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/Criteria.d.ts +2 -2
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/Criteria.js +3 -2
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.d.ts +3 -2
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.js +44 -11
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.d.ts +4 -3
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.js +41 -29
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/FileContent.d.ts +12 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/FileContent.js +197 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/Image.js +2 -4
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/InstanceLookup.js +14 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/RelatedObjectInstance.js +6 -2
- package/dist/published/components/custom/FormV2/components/RecursiveEntryRenderer.js +16 -13
- package/dist/published/components/custom/FormV2/components/types.d.ts +6 -1
- package/dist/published/components/custom/FormV2/components/utils.d.ts +10 -8
- package/dist/published/components/custom/FormV2/components/utils.js +168 -82
- package/dist/published/components/custom/ViewDetailsV2/InstanceEntryRenderer.js +6 -1
- package/dist/published/components/custom/index.d.ts +1 -0
- package/dist/published/index.d.ts +1 -1
- package/dist/published/stories/CriteriaBuilder.stories.js +70 -22
- package/dist/published/stories/FormRenderer.stories.d.ts +6 -3
- package/dist/published/stories/FormRendererContainer.stories.d.ts +20 -0
- package/dist/published/theme/hooks.d.ts +3 -3
- package/package.json +3 -1
|
@@ -1,74 +1,196 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
1
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
2
2
|
import userEvent from '@testing-library/user-event';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { beforeEach, describe, it, vi } from 'vitest';
|
|
5
5
|
import CriteriaBuilder from './CriteriaBuilder';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
name:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
6
|
+
describe('CriteriaBuilderWithTreeView', () => {
|
|
7
|
+
// Mock function for setCriteria
|
|
8
|
+
const setCriteriaMock = vi.fn();
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
// Reset the mock before each test
|
|
11
|
+
setCriteriaMock.mockReset();
|
|
12
|
+
});
|
|
13
|
+
it('expands related object property', async () => {
|
|
14
|
+
const user = userEvent.setup();
|
|
15
|
+
render(React.createElement(CriteriaBuilder, { treeViewOpts: {
|
|
16
|
+
object: {
|
|
17
|
+
id: 'objectA',
|
|
18
|
+
name: 'Object A',
|
|
19
|
+
properties: [
|
|
20
|
+
{
|
|
21
|
+
id: 'relatedObjectProp',
|
|
22
|
+
name: 'Related Object Prop',
|
|
23
|
+
type: 'object',
|
|
24
|
+
objectId: 'objectB',
|
|
25
|
+
children: [
|
|
26
|
+
{
|
|
27
|
+
id: 'relatedObjectProp-loading',
|
|
28
|
+
name: 'Loading...',
|
|
29
|
+
type: 'loading',
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
},
|
|
35
|
+
fetchObject: async (id) => {
|
|
36
|
+
if (id === 'objectB') {
|
|
37
|
+
// add delay to simulate network request
|
|
38
|
+
return new Promise((resolve) => setTimeout(() => {
|
|
39
|
+
resolve({
|
|
40
|
+
id: 'objectB',
|
|
41
|
+
name: 'Object B',
|
|
42
|
+
properties: [
|
|
43
|
+
{
|
|
44
|
+
id: 'id',
|
|
45
|
+
name: 'ID',
|
|
46
|
+
type: 'string',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: 'name',
|
|
50
|
+
name: 'Name',
|
|
51
|
+
type: 'string',
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
});
|
|
55
|
+
}, 5000));
|
|
56
|
+
}
|
|
57
|
+
return undefined;
|
|
58
|
+
},
|
|
59
|
+
}, properties: [], criteria: {}, setCriteria: setCriteriaMock }));
|
|
60
|
+
// Step 1: Click "Add Condition" button to create a new rule
|
|
61
|
+
const addConditionButton = screen.getByRole('button', { name: /^add condition$/i });
|
|
62
|
+
await user.click(addConditionButton);
|
|
63
|
+
// Step 2: Click on the property selector to open the dropdown
|
|
64
|
+
const propertySelector = screen.getByPlaceholderText(/select a property/i);
|
|
65
|
+
await user.click(propertySelector);
|
|
66
|
+
// Step 3: Click on "Related Object Prop" to expand it and fetch its children
|
|
67
|
+
const relatedObjectPropItem = screen.getByText('Related Object Prop');
|
|
68
|
+
await user.click(relatedObjectPropItem);
|
|
69
|
+
// Step 4: Verify loading indicator is shown
|
|
70
|
+
expect(screen.getByText('Loading...')).toBeInTheDocument();
|
|
71
|
+
// Step 5: Wait for the related object properties to load and verify ID and Name are visible
|
|
72
|
+
await waitFor(() => {
|
|
73
|
+
expect(screen.getByText('ID')).toBeInTheDocument();
|
|
74
|
+
// eslint-disable-next-line testing-library/no-wait-for-multiple-assertions
|
|
75
|
+
expect(screen.getByText('Name')).toBeInTheDocument();
|
|
76
|
+
}, { timeout: 6000 });
|
|
77
|
+
});
|
|
78
|
+
it('fails to expand related object property', async () => {
|
|
79
|
+
const user = userEvent.setup();
|
|
80
|
+
render(React.createElement(CriteriaBuilder, { treeViewOpts: {
|
|
81
|
+
object: {
|
|
82
|
+
id: 'objectA',
|
|
83
|
+
name: 'Object A',
|
|
84
|
+
properties: [
|
|
85
|
+
{
|
|
86
|
+
id: 'relatedObjectProp',
|
|
87
|
+
name: 'Related Object Prop',
|
|
88
|
+
type: 'object',
|
|
89
|
+
objectId: 'objectB',
|
|
90
|
+
children: [
|
|
91
|
+
{
|
|
92
|
+
id: 'relatedObjectProp-loading',
|
|
93
|
+
name: 'Loading...',
|
|
94
|
+
type: 'loading',
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
fetchObject: async (id) => {
|
|
101
|
+
if (id === 'objectB') {
|
|
102
|
+
return new Promise((resolve, reject) => {
|
|
103
|
+
setTimeout(() => {
|
|
104
|
+
reject('Failed to fetch objectB');
|
|
105
|
+
}, 5000);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
return undefined;
|
|
109
|
+
},
|
|
110
|
+
}, properties: [], criteria: {}, setCriteria: setCriteriaMock }));
|
|
111
|
+
// Step 1: Click "Add Condition" button to create a new rule
|
|
112
|
+
const addConditionButton = screen.getByRole('button', { name: /^add condition$/i });
|
|
113
|
+
await user.click(addConditionButton);
|
|
114
|
+
// Step 2: Click on the property selector to open the dropdown
|
|
115
|
+
const propertySelector = screen.getByPlaceholderText(/select a property/i);
|
|
116
|
+
await user.click(propertySelector);
|
|
117
|
+
// Step 3: Click on "Related Object Prop" to expand it and fetch its children
|
|
118
|
+
const relatedObjectPropItem = screen.getByText('Related Object Prop');
|
|
119
|
+
await user.click(relatedObjectPropItem);
|
|
120
|
+
// Step 4: Verify loading indicator is shown
|
|
121
|
+
expect(screen.getByText('Loading...')).toBeInTheDocument();
|
|
122
|
+
// Step 5: Wait for the related object properties to load and verify ID and Name are visible
|
|
123
|
+
await waitFor(() => {
|
|
124
|
+
expect(screen.getByText('Loading Failed')).toBeInTheDocument();
|
|
125
|
+
}, { timeout: 6000 });
|
|
126
|
+
});
|
|
127
|
+
});
|
|
71
128
|
describe('CriteriaBuilder', () => {
|
|
129
|
+
const mockProperties = [
|
|
130
|
+
{
|
|
131
|
+
id: 'name',
|
|
132
|
+
name: 'Name',
|
|
133
|
+
type: 'string',
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
id: 'age',
|
|
137
|
+
name: 'Age',
|
|
138
|
+
type: 'integer',
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
id: 'birthDate',
|
|
142
|
+
name: 'Birth Date',
|
|
143
|
+
type: 'date',
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
id: 'createdTime',
|
|
147
|
+
name: 'Created Time',
|
|
148
|
+
type: 'time',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: 'tags',
|
|
152
|
+
name: 'Tags',
|
|
153
|
+
type: 'array',
|
|
154
|
+
enum: ['tag1', 'tag2', 'tag3'],
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: 'status',
|
|
158
|
+
name: 'Status',
|
|
159
|
+
type: 'string',
|
|
160
|
+
enum: ['active', 'inactive', 'pending'],
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
id: 'profilePic',
|
|
164
|
+
name: 'Profile Picture',
|
|
165
|
+
type: 'image',
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
id: 'metadata',
|
|
169
|
+
name: 'Metadata',
|
|
170
|
+
type: 'document',
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
id: 'percentCompleted',
|
|
174
|
+
name: 'Percent Completed',
|
|
175
|
+
type: 'number',
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: 'boolean',
|
|
179
|
+
name: 'Boolean',
|
|
180
|
+
type: 'boolean',
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
id: 'regularRelatedObject',
|
|
184
|
+
name: 'Regular Related Object',
|
|
185
|
+
type: 'object',
|
|
186
|
+
objectId: 'relatedObjectId',
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
id: 'dynamicRelatedObject',
|
|
190
|
+
name: 'Dynamic Related Object',
|
|
191
|
+
type: 'object',
|
|
192
|
+
},
|
|
193
|
+
];
|
|
72
194
|
// Mock function for setCriteria
|
|
73
195
|
const setCriteriaMock = vi.fn();
|
|
74
196
|
beforeEach(() => {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { Property } from '@evoke-platform/context';
|
|
2
1
|
import React from 'react';
|
|
3
|
-
import {
|
|
2
|
+
import { TreeViewObject } from './types';
|
|
4
3
|
type PropertyTreeProps = {
|
|
5
|
-
fetchObject: (id: string) => Promise<
|
|
6
|
-
rootObject:
|
|
7
|
-
|
|
4
|
+
fetchObject: (id: string) => Promise<TreeViewObject | undefined>;
|
|
5
|
+
rootObject: TreeViewObject;
|
|
6
|
+
setRootObject: React.Dispatch<React.SetStateAction<TreeViewObject>>;
|
|
7
|
+
handleTreePropertySelect: (propertyId: string) => void;
|
|
8
8
|
value: string | undefined;
|
|
9
|
-
propertyTreeMap: Record<string,
|
|
9
|
+
propertyTreeMap: Record<string, string>;
|
|
10
10
|
};
|
|
11
11
|
declare const PropertyTree: (props: PropertyTreeProps) => React.JSX.Element;
|
|
12
12
|
export default PropertyTree;
|
|
@@ -4,38 +4,25 @@ import { Autocomplete, RichTreeView } from '../../core';
|
|
|
4
4
|
import { Box } from '../../layout';
|
|
5
5
|
import { OverflowTextField } from '../OverflowTextField';
|
|
6
6
|
import { PropertyTreeItem } from './PropertyTreeItem';
|
|
7
|
-
import { findTreeItemById, truncateNamePath,
|
|
7
|
+
import { convertTreeViewPropertyToTreeItem, findTreeItemById, truncateNamePath, updateTreeViewProperty } from './utils';
|
|
8
8
|
const NAME_PATH_LIMIT = 35;
|
|
9
9
|
const PropertyTree = (props) => {
|
|
10
|
-
const { fetchObject, handleTreePropertySelect, rootObject, value, propertyTreeMap } = props;
|
|
10
|
+
const { fetchObject, handleTreePropertySelect, rootObject, setRootObject, value, propertyTreeMap } = props;
|
|
11
11
|
const [options, setOptions] = useState([]);
|
|
12
12
|
const [expandedItems, setExpandedItems] = useState([]);
|
|
13
13
|
const [openDropdown, setOpenDropdown] = useState(false);
|
|
14
14
|
useEffect(() => {
|
|
15
15
|
// Transform rootObject properties to TreeItem format
|
|
16
|
-
setOptions(rootObject.properties.map(
|
|
17
|
-
id: property.id,
|
|
18
|
-
label: property.name,
|
|
19
|
-
value: property.id,
|
|
20
|
-
type: property.type,
|
|
21
|
-
objectId: property.objectId,
|
|
22
|
-
children: property.children
|
|
23
|
-
? property.children.map((child) => ({
|
|
24
|
-
id: child.id,
|
|
25
|
-
label: child.name,
|
|
26
|
-
value: child.id,
|
|
27
|
-
type: child.type,
|
|
28
|
-
objectId: child.objectId,
|
|
29
|
-
}))
|
|
30
|
-
: undefined,
|
|
31
|
-
})));
|
|
32
|
-
setExpandedItems([]);
|
|
16
|
+
setOptions(rootObject.properties.map(convertTreeViewPropertyToTreeItem));
|
|
33
17
|
}, [rootObject.properties]);
|
|
34
18
|
const handleExpandedItemsChange = (e, itemIds) => {
|
|
35
19
|
setExpandedItems(itemIds);
|
|
36
20
|
};
|
|
37
21
|
const handleUpdateNodeChildren = (nodeId, children) => {
|
|
38
|
-
|
|
22
|
+
setRootObject((prevObject) => ({
|
|
23
|
+
...prevObject,
|
|
24
|
+
properties: updateTreeViewProperty(prevObject.properties, nodeId, (node) => ({ ...node, children })),
|
|
25
|
+
}));
|
|
39
26
|
};
|
|
40
27
|
return (React.createElement(Autocomplete, { "aria-label": "Property Selector", value: value, fullWidth: true, sx: { width: '37%' }, size: "small", disableClearable: true, options: options, open: openDropdown, onBlur: (e) => {
|
|
41
28
|
const targetComponents = e.relatedTarget?.getAttribute('id')?.split('-');
|
|
@@ -58,11 +45,11 @@ const PropertyTree = (props) => {
|
|
|
58
45
|
}, onFocus: () => setOpenDropdown(true), getOptionLabel: (option) => {
|
|
59
46
|
// Retrieve the full name path from the map
|
|
60
47
|
const namePath = typeof option === 'string'
|
|
61
|
-
? (
|
|
62
|
-
:
|
|
48
|
+
? (propertyTreeMap[option] ?? '') || option
|
|
49
|
+
: propertyTreeMap[option.value] || option.value;
|
|
63
50
|
return truncateNamePath(namePath, NAME_PATH_LIMIT);
|
|
64
51
|
}, renderInput: (params) => {
|
|
65
|
-
const fullDisplayName = value && propertyTreeMap[value]
|
|
52
|
+
const fullDisplayName = value && propertyTreeMap[value];
|
|
66
53
|
return (React.createElement(OverflowTextField, { ...params, "aria-label": fullDisplayName, value: fullDisplayName, placeholder: "Select a property" }));
|
|
67
54
|
}, ListboxComponent: (props) => {
|
|
68
55
|
return (React.createElement(ClickAwayListener, { onClickAway: (e) => {
|
|
@@ -73,8 +60,8 @@ const PropertyTree = (props) => {
|
|
|
73
60
|
} },
|
|
74
61
|
React.createElement(Box, { ...props },
|
|
75
62
|
React.createElement(RichTreeView, { sx: { width: '100%', paddingLeft: 0 }, role: "menu", "aria-label": "Property Tree", expandedItems: expandedItems, onExpandedItemsChange: handleExpandedItemsChange, items: options, slots: {
|
|
76
|
-
item: (itemProps) => (React.createElement(PropertyTreeItem, { ...itemProps, items: options, expanded: expandedItems, setExpanded: setExpandedItems, fetchObject: fetchObject, updateNodeChildren: handleUpdateNodeChildren, handleTreePropertySelect:
|
|
77
|
-
|
|
63
|
+
item: (itemProps) => (React.createElement(PropertyTreeItem, { ...itemProps, items: options, expanded: expandedItems, setExpanded: setExpandedItems, fetchObject: fetchObject, updateNodeChildren: handleUpdateNodeChildren, handleTreePropertySelect: (propertyId) => {
|
|
64
|
+
handleTreePropertySelect(propertyId);
|
|
78
65
|
setOpenDropdown(false);
|
|
79
66
|
} })),
|
|
80
67
|
} }))));
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { TreeItemProps } from '@mui/x-tree-view';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import {
|
|
4
|
-
import { TreeItem } from './types';
|
|
3
|
+
import { TreeItem, TreeViewObject, TreeViewProperty } from './types';
|
|
5
4
|
type PropertyTreeItemProps = TreeItemProps & {
|
|
6
5
|
items: TreeItem[];
|
|
7
6
|
expanded: string[];
|
|
8
7
|
setExpanded: (expanded: string[]) => void;
|
|
9
|
-
updateNodeChildren: (nodeId: string, children:
|
|
10
|
-
fetchObject: (id: string) => Promise<
|
|
11
|
-
handleTreePropertySelect: (propertyId: string) =>
|
|
8
|
+
updateNodeChildren: (nodeId: string, children: TreeViewProperty[]) => void;
|
|
9
|
+
fetchObject: (id: string) => Promise<TreeViewObject | undefined>;
|
|
10
|
+
handleTreePropertySelect: (propertyId: string) => void;
|
|
12
11
|
};
|
|
13
12
|
export declare const PropertyTreeItem: (props: PropertyTreeItemProps) => React.JSX.Element;
|
|
14
13
|
export {};
|
|
@@ -11,35 +11,47 @@ export const PropertyTreeItem = (props) => {
|
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
13
|
const item = findTreeItemById(items, itemId);
|
|
14
|
-
if (item?.type === '
|
|
14
|
+
if (item?.type === 'loadingFailed') {
|
|
15
|
+
e.stopPropagation();
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (item?.children) {
|
|
15
19
|
e.stopPropagation();
|
|
16
20
|
// If the item has an associated "objectId", fetch the properties of the object and expand the item.
|
|
17
|
-
if (item
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
21
|
+
if (item?.type === 'object' &&
|
|
22
|
+
item.objectId &&
|
|
23
|
+
item.children?.length === 1 &&
|
|
24
|
+
item.children[0].type === 'loading') {
|
|
25
|
+
try {
|
|
26
|
+
const object = await fetchObject(item.objectId);
|
|
27
|
+
if (object) {
|
|
28
|
+
updateNodeChildren(itemId, object.properties
|
|
29
|
+
.filter((prop) => prop.type !== 'collection')
|
|
30
|
+
.map((prop) => ({
|
|
31
|
+
...prop,
|
|
32
|
+
id: `${itemId}.${prop.id}`,
|
|
33
|
+
children: prop.children?.map((child) => ({
|
|
34
|
+
...child,
|
|
35
|
+
id: `${itemId}.${prop.id}.${child.id}`,
|
|
36
|
+
})),
|
|
37
|
+
})));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
updateNodeChildren(itemId, [
|
|
42
|
+
{
|
|
43
|
+
id: `${itemId}-failed`,
|
|
44
|
+
name: 'Loading Failed',
|
|
45
|
+
type: 'loadingFailed',
|
|
46
|
+
},
|
|
47
|
+
]);
|
|
48
|
+
console.error('Error fetching object:', error);
|
|
37
49
|
}
|
|
38
50
|
}
|
|
39
51
|
setExpanded([...expanded, itemId]);
|
|
40
52
|
return;
|
|
41
53
|
}
|
|
42
|
-
|
|
54
|
+
handleTreePropertySelect(itemId);
|
|
43
55
|
};
|
|
44
56
|
return React.createElement(RichTreeItem, { itemId: itemId, label: label, children: children, onClick: onClick });
|
|
45
57
|
};
|
|
@@ -1,17 +1,8 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
+
import { Property } from '@evoke-platform/context';
|
|
2
3
|
import { BaseSelectorProps } from 'react-querybuilder';
|
|
3
4
|
import { ExpandedProperty } from '../../../types';
|
|
4
5
|
import { AutocompleteOption, TreeViewBaseItem } from '../../core';
|
|
5
|
-
export type ObjectProperty = {
|
|
6
|
-
id: string;
|
|
7
|
-
name: string;
|
|
8
|
-
type: string;
|
|
9
|
-
enum?: string[];
|
|
10
|
-
required?: boolean;
|
|
11
|
-
searchable?: boolean;
|
|
12
|
-
objectId?: string;
|
|
13
|
-
formula?: string;
|
|
14
|
-
};
|
|
15
6
|
export type CustomSelectorProps = BaseSelectorProps & {
|
|
16
7
|
options: AutocompleteOption[] | any[];
|
|
17
8
|
fieldData?: Record<string, any>;
|
|
@@ -28,7 +19,7 @@ export type PresetValue = {
|
|
|
28
19
|
};
|
|
29
20
|
type?: string;
|
|
30
21
|
};
|
|
31
|
-
export type TreeViewProperty =
|
|
22
|
+
export type TreeViewProperty = Property & {
|
|
32
23
|
children?: TreeViewProperty[];
|
|
33
24
|
};
|
|
34
25
|
export type TreeViewObject = {
|
|
@@ -1,42 +1,15 @@
|
|
|
1
1
|
import { Property } from '@evoke-platform/context';
|
|
2
|
-
import {
|
|
3
|
-
import { TreeItem } from './types';
|
|
2
|
+
import { TreeItem, TreeViewProperty } from './types';
|
|
4
3
|
/**
|
|
5
4
|
* Recursively updates a node in a tree structure by applying an updater function to the node with the specified ID.
|
|
6
5
|
*
|
|
7
|
-
* @param {
|
|
6
|
+
* @param {TreeViewProperty[]} tree - The tree structure to update.
|
|
8
7
|
* @param {string} nodeId - The ID of the node to update.
|
|
9
|
-
* @param {(node:
|
|
10
|
-
* @returns {
|
|
8
|
+
* @param {(node: TreeViewProperty) => TreeViewProperty} updater - The function to apply to the node.
|
|
9
|
+
* @returns {TreeViewProperty[]} - The updated tree structure.
|
|
11
10
|
*/
|
|
12
|
-
export declare const
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Fetches the display name path for a given property ID within an object hierarchy.
|
|
16
|
-
*
|
|
17
|
-
* @param {string} propertyId - The property ID to find the display name for.
|
|
18
|
-
* @param {Obj} rootObject - The root object to start the search from.
|
|
19
|
-
* @param {FetchObjectFunction} fetchObject - Function to fetch an object by its ID.
|
|
20
|
-
* @returns {Promise<string>} - A promise that resolves to the display name path.
|
|
21
|
-
*/
|
|
22
|
-
export declare const fetchDisplayNamePath: (propertyId: string, rootObject: Obj, fetchObject: FetchObjectFunction) => Promise<string>;
|
|
23
|
-
/**
|
|
24
|
-
* stores full dot-notation path to each property ID in the given array of properties.
|
|
25
|
-
*
|
|
26
|
-
* @param {ObjectProperty[]} properties - The array of properties to update.
|
|
27
|
-
* @param {string} parentPath - The parent path to attach to each property ID.
|
|
28
|
-
* @returns {ObjectProperty[]} The updated array of properties with the parent path attached to each property ID.
|
|
29
|
-
*/
|
|
30
|
-
export declare const setIdPaths: (properties: ObjectProperty[], parentPath: string) => ObjectProperty[];
|
|
31
|
-
/**
|
|
32
|
-
* Traverses a property path within an object hierarchy to retrieve detailed property information.
|
|
33
|
-
*
|
|
34
|
-
* @param {string} propertyPath - The dot-separated path of the property to traverse.
|
|
35
|
-
* @param {Obj} rootObject - The root object from which to start the traversal.
|
|
36
|
-
* @param {FetchObjectFunction} fetchObject - A function to fetch an object by its ID.
|
|
37
|
-
* @returns {Promise<ObjectProperty | null>} A promise that resolves to an ObjectProperty if found, or null otherwise.
|
|
38
|
-
*/
|
|
39
|
-
export declare const traversePropertyPath: (propertyPath: string, rootObject: Obj, fetchObject: (objectId: string) => Promise<Obj | undefined>) => Promise<ObjectProperty | null>;
|
|
11
|
+
export declare const updateTreeViewProperty: (tree: TreeViewProperty[], nodeId: string, updater: (node: TreeViewProperty) => TreeViewProperty) => TreeViewProperty[];
|
|
12
|
+
export declare const convertTreeViewPropertyToTreeItem: (property: TreeViewProperty) => TreeItem;
|
|
40
13
|
/**
|
|
41
14
|
* Truncates the name path if it exceeds the specified character limit.
|
|
42
15
|
*
|
|
@@ -58,4 +31,3 @@ export declare const ALL_OPERATORS: {
|
|
|
58
31
|
*/
|
|
59
32
|
export declare const getReadableQuery: (mongoQuery?: Record<string, unknown>, properties?: Property[]) => string;
|
|
60
33
|
export declare const findTreeItemById: (nodes: TreeItem[], nodeId: string) => TreeItem | null;
|
|
61
|
-
export {};
|