@evoke-platform/ui-components 1.13.0-dev.4 → 1.13.0-dev.6

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.
Files changed (32) hide show
  1. package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.d.ts +4 -4
  2. package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.js +145 -72
  3. package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.test.js +189 -67
  4. package/dist/published/components/custom/CriteriaBuilder/PropertyTree.d.ts +6 -6
  5. package/dist/published/components/custom/CriteriaBuilder/PropertyTree.js +12 -25
  6. package/dist/published/components/custom/CriteriaBuilder/PropertyTreeItem.d.ts +4 -5
  7. package/dist/published/components/custom/CriteriaBuilder/PropertyTreeItem.js +34 -22
  8. package/dist/published/components/custom/CriteriaBuilder/types.d.ts +2 -11
  9. package/dist/published/components/custom/CriteriaBuilder/utils.d.ts +6 -34
  10. package/dist/published/components/custom/CriteriaBuilder/utils.js +18 -89
  11. package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.js +1 -1
  12. package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentList.js +6 -3
  13. package/dist/published/components/custom/Form/utils.d.ts +1 -0
  14. package/dist/published/components/custom/FormV2/FormRenderer.d.ts +1 -0
  15. package/dist/published/components/custom/FormV2/FormRendererContainer.d.ts +1 -0
  16. package/dist/published/components/custom/FormV2/FormRendererContainer.js +25 -22
  17. package/dist/published/components/custom/FormV2/components/FormContext.d.ts +1 -0
  18. package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/ActionDialog.d.ts +1 -0
  19. package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.d.ts +3 -2
  20. package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.js +46 -10
  21. package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.d.ts +4 -3
  22. package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.js +29 -23
  23. package/dist/published/components/custom/FormV2/components/RecursiveEntryRenderer.js +4 -2
  24. package/dist/published/components/custom/FormV2/components/types.d.ts +6 -1
  25. package/dist/published/components/custom/FormV2/components/utils.d.ts +5 -7
  26. package/dist/published/components/custom/FormV2/components/utils.js +146 -69
  27. package/dist/published/components/custom/ViewDetailsV2/InstanceEntryRenderer.js +20 -8
  28. package/dist/published/stories/CriteriaBuilder.stories.js +70 -22
  29. package/dist/published/stories/FormRenderer.stories.d.ts +3 -0
  30. package/dist/published/stories/FormRendererContainer.stories.d.ts +5 -0
  31. package/dist/published/theme/hooks.d.ts +2 -1
  32. package/package.json +1 -1
@@ -1,10 +1,10 @@
1
+ import { Property } from '@evoke-platform/context';
1
2
  import React from 'react';
2
3
  import 'react-querybuilder/dist/query-builder.css';
3
- import { EvokeObject } from '../../../types';
4
- import { ObjectProperty, Operator, PresetValue, TreeViewObject } from './types';
4
+ import { Operator, PresetValue, TreeViewObject } from './types';
5
5
  import { ValueEditorProps } from './ValueEditor';
6
6
  export type CriteriaInputProps = {
7
- properties: ObjectProperty[];
7
+ properties: Property[];
8
8
  setCriteria: (criteria?: Record<string, unknown> | undefined) => void;
9
9
  criteria?: Record<string, unknown>;
10
10
  originalCriteria?: Record<string, unknown>;
@@ -23,7 +23,7 @@ export type CriteriaInputProps = {
23
23
  hideBorder?: boolean;
24
24
  presetGroupLabel?: string;
25
25
  treeViewOpts?: {
26
- fetchObject?: (objectId: string) => Promise<EvokeObject | undefined>;
26
+ fetchObject?: (objectId: string) => Promise<TreeViewObject | undefined>;
27
27
  object: TreeViewObject;
28
28
  };
29
29
  /**
@@ -11,7 +11,7 @@ import { Box } from '../../layout';
11
11
  import { OverflowTextField } from '../OverflowTextField';
12
12
  import { difference } from '../util';
13
13
  import PropertyTree from './PropertyTree';
14
- import { ALL_OPERATORS, parseMongoDB, traversePropertyPath } from './utils';
14
+ import { ALL_OPERATORS, parseMongoDB } from './utils';
15
15
  import ValueEditor from './ValueEditor';
16
16
  const styles = {
17
17
  buttons: {
@@ -103,6 +103,7 @@ const customSelector = (props) => {
103
103
  const isTreeViewEnabled = context.treeViewOpts && title === 'Fields';
104
104
  const fetchObject = context.treeViewOpts?.fetchObject;
105
105
  const object = context.treeViewOpts?.object;
106
+ const setObject = context.treeViewOpts?.setObject;
106
107
  let readOnly = context.disabled;
107
108
  if (!readOnly && context.disabledCriteria) {
108
109
  readOnly =
@@ -173,14 +174,7 @@ const customSelector = (props) => {
173
174
  val = options.find((option) => option.name === val)?.name;
174
175
  break;
175
176
  }
176
- const handleTreePropertySelect = async (propertyId) => {
177
- const propertyInfo = await traversePropertyPath(propertyId, object, fetchObject);
178
- context.setPropertyTreeMap((prev) => {
179
- return { ...prev, [propertyId]: propertyInfo };
180
- });
181
- handleOnChange(propertyId);
182
- };
183
- return (React.createElement(React.Fragment, null, isTreeViewEnabled ? (React.createElement(PropertyTree, { value: val ?? value, rootObject: object, fetchObject: fetchObject, propertyTreeMap: context.propertyTreeMap ?? {}, handleTreePropertySelect: handleTreePropertySelect })) : (React.createElement(Autocomplete, { options: opts, value: val ?? null, getOptionLabel: (option) => {
177
+ return (React.createElement(React.Fragment, null, isTreeViewEnabled ? (React.createElement(PropertyTree, { value: val ?? value, rootObject: object, setRootObject: setObject, fetchObject: fetchObject, propertyTreeMap: context.propertyTreeMap ?? {}, handleTreePropertySelect: handleOnChange })) : (React.createElement(Autocomplete, { options: opts, value: val ?? null, getOptionLabel: (option) => {
184
178
  if (typeof option === 'string') {
185
179
  return opts.find((o) => option === o.name)?.label || option;
186
180
  }
@@ -275,77 +269,159 @@ const getAllRuleIds = (rules) => {
275
269
  });
276
270
  return ids;
277
271
  };
278
- const CriteriaBuilder = (props) => {
279
- const { properties, criteria, setCriteria, originalCriteria, enablePresetValues, presetValues, operators, disabled, disabledCriteria, hideBorder, presetGroupLabel, customValueEditor, treeViewOpts, disableRegexEscapeChars, } = props;
280
- const [propertyTreeMap, setPropertyTreeMap] = useState();
281
- const processRules = (rules) => {
282
- return rules.map((rule) => {
283
- if ('rules' in rule) {
284
- return {
285
- ...rule,
286
- rules: processRules(rule.rules),
287
- };
288
- }
289
- else {
290
- const propertyType = properties.find((property) => property.id === rule.field)?.type;
291
- let adjustedValue = rule.value;
292
- if ((rule.operator === 'null' || rule.operator === 'notNull') && rule.value) {
293
- adjustedValue = null;
294
- }
295
- return {
296
- ...rule,
297
- operator: propertyType === 'array' && rule.operator === '=' ? 'in' : rule.operator,
298
- value: adjustedValue,
299
- };
272
+ const processRules = (rules, properties) => {
273
+ return rules.map((rule) => {
274
+ if ('rules' in rule) {
275
+ return {
276
+ ...rule,
277
+ rules: processRules(rule.rules, properties),
278
+ };
279
+ }
280
+ else {
281
+ const propertyType = properties.find((property) => property.id === rule.field)?.type;
282
+ let adjustedValue = rule.value;
283
+ if ((rule.operator === 'null' || rule.operator === 'notNull') && rule.value) {
284
+ adjustedValue = null;
300
285
  }
301
- });
286
+ return {
287
+ ...rule,
288
+ operator: propertyType === 'array' && rule.operator === '=' ? 'in' : rule.operator,
289
+ value: adjustedValue,
290
+ };
291
+ }
292
+ });
293
+ };
294
+ const insertChangesOnly = (prev, newObject) => {
295
+ const mergedProperties = newObject.properties.map((newProp) => {
296
+ const prevProp = prev.properties.find((prop) => prop.id === newProp.id);
297
+ if (prevProp) {
298
+ return {
299
+ ...newProp,
300
+ children: newProp.children &&
301
+ newProp.children[0].type === 'loading' &&
302
+ prevProp.children
303
+ ? prevProp.children
304
+ : newProp.children && prevProp.children
305
+ ? insertChangesOnly({ id: prevProp.id, name: prevProp.name, properties: prevProp.children }, { id: newProp.id, name: newProp.name, properties: newProp.children }).properties
306
+ : newProp.children,
307
+ };
308
+ }
309
+ else {
310
+ return newProp;
311
+ }
312
+ });
313
+ return {
314
+ ...newObject,
315
+ properties: mergedProperties,
302
316
  };
317
+ };
318
+ const CriteriaBuilder = (props) => {
319
+ const { properties, criteria, setCriteria, originalCriteria, enablePresetValues, presetValues, operators, disabled, disabledCriteria, hideBorder, presetGroupLabel, customValueEditor, treeViewOpts, disableRegexEscapeChars, } = props;
320
+ const [propertyTreeMap, setPropertyTreeMap] = useState({});
321
+ const [treeViewObject, setTreeViewObject] = useState();
303
322
  useEffect(() => {
304
- if ((criteria || originalCriteria) &&
305
- !isEmpty(treeViewOpts) &&
306
- treeViewOpts.object &&
307
- treeViewOpts.fetchObject) {
308
- const { object, fetchObject } = treeViewOpts;
309
- // this retrieves the properties from a treeview for each property in the query
310
- // they are then used in the custom query builder components to determine the input type etc
311
- const updatePropertyTreeMap = async () => {
312
- const newQuery = parseMongoDB(criteria || originalCriteria || {});
323
+ let obj;
324
+ if (treeViewOpts?.object) {
325
+ obj = {
326
+ ...treeViewOpts.object,
327
+ properties: treeViewOpts.object.properties
328
+ .filter((prop) => prop.type !== 'collection')
329
+ .map((prop) => ({
330
+ ...prop,
331
+ children: prop.children
332
+ ?.filter((child) => child.type !== 'collection')
333
+ .map((child) => ({
334
+ ...child,
335
+ id: `${prop.id}.${child.id}`,
336
+ })),
337
+ })),
338
+ };
339
+ }
340
+ if ((criteria || originalCriteria) && obj && treeViewOpts?.fetchObject) {
341
+ const updateTreeViewObject = async (criteria, treeViewObject, fetchObject) => {
342
+ const newQuery = parseMongoDB(criteria);
313
343
  const ids = getAllRuleIds(newQuery.rules);
314
- let newPropertyTreeMap = {};
315
- const newPropertyTreeMapPromises = [];
316
- for (const id of ids) {
317
- if (!propertyTreeMap?.[id]) {
318
- newPropertyTreeMapPromises.push(traversePropertyPath(id, object, fetchObject)
319
- .then((property) => {
320
- if (property) {
321
- return {
322
- [id]: property,
323
- };
344
+ const newTreeViewObject = { ...treeViewObject };
345
+ const traversePath = async (path, properties, fetchObject) => {
346
+ const prop = properties?.find((prop) => path.startsWith(`${prop.id}.`) || path === prop.id);
347
+ if (prop?.type === 'object' && prop.objectId && prop.children) {
348
+ if (prop.children.length === 1 &&
349
+ prop.children[0]?.type === 'loading') {
350
+ try {
351
+ const fetchedObject = await fetchObject(prop.objectId);
352
+ prop.children = fetchedObject?.properties
353
+ ?.filter((item) => item.type !== 'collection')
354
+ .map((item) => {
355
+ return {
356
+ ...item,
357
+ id: `${prop.id}.${item.id}`,
358
+ children: item.children?.map((child) => ({
359
+ ...child,
360
+ id: `${prop.id}.${item.id}.${child.id}`,
361
+ })),
362
+ };
363
+ });
364
+ fetchedObject && (await traversePath(path, fetchedObject.properties, fetchObject));
324
365
  }
325
- return {};
326
- })
327
- .catch((err) => {
328
- console.error(err);
329
- return {};
330
- }));
366
+ catch (error) {
367
+ prop.children = [
368
+ {
369
+ id: `${prop.id}-failed`,
370
+ name: 'Loading Failed',
371
+ type: 'loadingFailed',
372
+ },
373
+ ];
374
+ console.error('Error fetching object for criteria builder:', error);
375
+ }
376
+ }
377
+ else {
378
+ await traversePath(path, prop.children, fetchObject);
379
+ }
331
380
  }
381
+ };
382
+ for (const id of ids) {
383
+ await traversePath(id, newTreeViewObject.properties, fetchObject);
332
384
  }
333
- newPropertyTreeMap = (await Promise.all(newPropertyTreeMapPromises)).reduce((acc, currentProperty) => ({ ...acc, ...currentProperty }), {});
334
- setPropertyTreeMap((prevPropertyTreeMap) => ({
335
- ...prevPropertyTreeMap,
336
- ...newPropertyTreeMap,
337
- }));
385
+ setTreeViewObject((prevTreeViewObject) => prevTreeViewObject ? insertChangesOnly(prevTreeViewObject, newTreeViewObject) : newTreeViewObject);
338
386
  };
339
- updatePropertyTreeMap().catch((err) => console.error(err));
387
+ updateTreeViewObject(criteria || originalCriteria || {}, obj, treeViewOpts.fetchObject);
388
+ }
389
+ }, [treeViewOpts, criteria, originalCriteria]);
390
+ useEffect(() => {
391
+ if (!treeViewObject)
392
+ return;
393
+ const getNamePath = (path, object) => {
394
+ const helper = (path, object) => {
395
+ let namePath = '';
396
+ const prop = (object.properties ?? []).find((prop) => path.startsWith(`${prop.id}.`) || path === prop.id);
397
+ if (prop) {
398
+ if (prop.children) {
399
+ const result = helper(path, { id: prop.id, name: prop.name, properties: prop.children });
400
+ namePath = result ? prop.name + ' / ' + result : '';
401
+ }
402
+ else {
403
+ namePath = prop.name;
404
+ }
405
+ }
406
+ return namePath;
407
+ };
408
+ return helper(path, object) || path;
409
+ };
410
+ const newQuery = parseMongoDB(criteria || originalCriteria || {});
411
+ const ids = getAllRuleIds(newQuery.rules);
412
+ const result = {};
413
+ for (const id of ids) {
414
+ result[id] = getNamePath(id, treeViewObject);
340
415
  }
341
- }, [criteria, originalCriteria, treeViewOpts]);
416
+ setPropertyTreeMap(result);
417
+ }, [criteria, originalCriteria, treeViewObject]);
342
418
  const initializeQuery = () => {
343
419
  const criteriaToParse = criteria || originalCriteria;
344
420
  const updatedQuery = criteriaToParse ? parseMongoDB(criteriaToParse || {}) : undefined;
345
421
  return updatedQuery
346
422
  ? {
347
423
  ...updatedQuery,
348
- rules: processRules(updatedQuery.rules),
424
+ rules: processRules(updatedQuery.rules, properties),
349
425
  }
350
426
  : { combinator: 'and', rules: [] };
351
427
  };
@@ -371,7 +447,7 @@ const CriteriaBuilder = (props) => {
371
447
  const handleQueryChange = (q) => {
372
448
  const processedQuery = {
373
449
  ...q,
374
- rules: processRules(q.rules),
450
+ rules: processRules(q.rules, properties),
375
451
  };
376
452
  setQuery(processedQuery);
377
453
  const newCriteria = JSON.parse(formatQuery(processedQuery, {
@@ -525,17 +601,14 @@ const CriteriaBuilder = (props) => {
525
601
  presetGroupLabel,
526
602
  disabled,
527
603
  disabledCriteria,
528
- treeViewOpts: treeViewOpts
604
+ treeViewOpts: treeViewObject && treeViewOpts
529
605
  ? {
530
606
  ...treeViewOpts,
531
- object: {
532
- ...treeViewOpts?.object,
533
- properties: treeViewOpts?.object.properties.filter(({ type }) => type !== 'collection'),
534
- },
607
+ object: treeViewObject,
608
+ setObject: setTreeViewObject,
535
609
  }
536
610
  : undefined,
537
611
  propertyTreeMap,
538
- setPropertyTreeMap,
539
612
  }, controlClassnames: {
540
613
  ruleGroup: 'container',
541
614
  }, operators: operators
@@ -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 { expect, it } from 'vitest';
4
+ import { beforeEach, describe, it, vi } from 'vitest';
5
5
  import CriteriaBuilder from './CriteriaBuilder';
6
- const mockProperties = [
7
- {
8
- id: 'name',
9
- name: 'Name',
10
- type: 'string',
11
- },
12
- {
13
- id: 'age',
14
- name: 'Age',
15
- type: 'integer',
16
- },
17
- {
18
- id: 'birthDate',
19
- name: 'Birth Date',
20
- type: 'date',
21
- },
22
- {
23
- id: 'createdTime',
24
- name: 'Created Time',
25
- type: 'time',
26
- },
27
- {
28
- id: 'tags',
29
- name: 'Tags',
30
- type: 'array',
31
- enum: ['tag1', 'tag2', 'tag3'],
32
- },
33
- {
34
- id: 'status',
35
- name: 'Status',
36
- type: 'string',
37
- enum: ['active', 'inactive', 'pending'],
38
- },
39
- {
40
- id: 'profilePic',
41
- name: 'Profile Picture',
42
- type: 'image',
43
- },
44
- {
45
- id: 'metadata',
46
- name: 'Metadata',
47
- type: 'document',
48
- },
49
- {
50
- id: 'percentCompleted',
51
- name: 'Percent Completed',
52
- type: 'number',
53
- },
54
- {
55
- id: 'boolean',
56
- name: 'Boolean',
57
- type: 'boolean',
58
- },
59
- {
60
- id: 'regularRelatedObject',
61
- name: 'Regular Related Object',
62
- type: 'object',
63
- objectId: 'relatedObjectId',
64
- },
65
- {
66
- id: 'dynamicRelatedObject',
67
- name: 'Dynamic Related Object',
68
- type: 'object',
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 { EvokeObject } from '../../../types';
2
+ import { TreeViewObject } from './types';
4
3
  type PropertyTreeProps = {
5
- fetchObject: (id: string) => Promise<EvokeObject | undefined>;
6
- rootObject: EvokeObject;
7
- handleTreePropertySelect: (propertyId: string) => Promise<void>;
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, Property>;
9
+ propertyTreeMap: Record<string, string>;
10
10
  };
11
11
  declare const PropertyTree: (props: PropertyTreeProps) => React.JSX.Element;
12
12
  export default PropertyTree;