@evoke-platform/ui-components 1.16.0 → 1.17.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 +4 -8
- package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.js +144 -238
- package/dist/published/components/custom/CriteriaBuilder/CriteriaBuilder.test.js +67 -189
- package/dist/published/components/custom/CriteriaBuilder/PropertyTree.d.ts +6 -6
- package/dist/published/components/custom/CriteriaBuilder/PropertyTree.js +25 -12
- package/dist/published/components/custom/CriteriaBuilder/PropertyTreeItem.d.ts +5 -4
- package/dist/published/components/custom/CriteriaBuilder/PropertyTreeItem.js +22 -34
- package/dist/published/components/custom/CriteriaBuilder/types.d.ts +11 -2
- package/dist/published/components/custom/CriteriaBuilder/utils.d.ts +34 -6
- package/dist/published/components/custom/CriteriaBuilder/utils.js +89 -18
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/Document.js +1 -1
- package/dist/published/components/custom/Form/FormComponents/DocumentComponent/DocumentList.js +3 -6
- package/dist/published/components/custom/Form/utils.d.ts +2 -3
- package/dist/published/components/custom/FormField/AddressFieldComponent/addressFieldComponent.js +1 -1
- package/dist/published/components/custom/FormField/BooleanSelect/BooleanSelect.js +15 -7
- package/dist/published/components/custom/FormField/InputFieldComponent/InputFieldComponent.js +1 -1
- package/dist/published/components/custom/FormField/Select/Select.js +1 -1
- package/dist/published/components/custom/FormV2/FormRenderer.d.ts +1 -2
- package/dist/published/components/custom/FormV2/FormRenderer.js +7 -7
- package/dist/published/components/custom/FormV2/FormRendererContainer.d.ts +0 -4
- package/dist/published/components/custom/FormV2/FormRendererContainer.js +49 -91
- package/dist/published/components/custom/FormV2/components/FormContext.d.ts +0 -1
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/ActionDialog.d.ts +0 -1
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/DropdownRepeatableFieldInput.js +3 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/CollectionFiles/RepeatableField.js +17 -44
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.d.ts +2 -3
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/Document.js +12 -44
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.d.ts +3 -4
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/DocumentFiles/DocumentList.js +29 -41
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/Image.js +1 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/UserProperty.js +2 -0
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/relatedObjectFiles/InstanceLookup.js +0 -14
- package/dist/published/components/custom/FormV2/components/FormletRenderer.d.ts +6 -0
- package/dist/published/components/custom/FormV2/components/FormletRenderer.js +30 -0
- package/dist/published/components/custom/FormV2/components/HtmlView.js +12 -9
- package/dist/published/components/custom/FormV2/components/RecursiveEntryRenderer.js +13 -19
- package/dist/published/components/custom/FormV2/components/types.d.ts +1 -6
- package/dist/published/components/custom/FormV2/components/utils.d.ts +14 -12
- package/dist/published/components/custom/FormV2/components/utils.js +123 -159
- package/dist/published/components/custom/FormV2/tests/FormRenderer.test.js +48 -5
- package/dist/published/components/custom/FormV2/tests/FormRendererContainer.test.js +279 -35
- package/dist/published/components/custom/ViewDetailsV2/InstanceEntryRenderer.js +1 -6
- package/dist/published/components/custom/index.d.ts +0 -1
- package/dist/published/index.d.ts +1 -1
- package/dist/published/stories/CriteriaBuilder.stories.js +22 -70
- package/dist/published/stories/FormRenderer.stories.d.ts +3 -6
- package/dist/published/stories/FormRendererContainer.stories.d.ts +0 -20
- package/dist/published/stories/FormRendererData.d.ts +15 -0
- package/dist/published/stories/FormRendererData.js +63 -0
- package/dist/published/stories/sharedMswHandlers.js +4 -2
- package/dist/published/theme/hooks.d.ts +0 -1
- package/package.json +2 -3
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/FileContent.d.ts +0 -12
- package/dist/published/components/custom/FormV2/components/FormFieldTypes/FileContent.js +0 -197
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import { Property } from '@evoke-platform/context';
|
|
2
1
|
import React from 'react';
|
|
3
2
|
import 'react-querybuilder/dist/query-builder.css';
|
|
4
|
-
import {
|
|
3
|
+
import { EvokeObject } from '../../../types';
|
|
4
|
+
import { ObjectProperty, Operator, PresetValue, TreeViewObject } from './types';
|
|
5
5
|
import { ValueEditorProps } from './ValueEditor';
|
|
6
6
|
export type CriteriaInputProps = {
|
|
7
|
-
|
|
8
|
-
* The ability to input free text for property selection.
|
|
9
|
-
*/
|
|
10
|
-
propertyFreeSolo?: boolean;
|
|
11
|
-
properties: Property[];
|
|
7
|
+
properties: ObjectProperty[];
|
|
12
8
|
setCriteria: (criteria?: Record<string, unknown> | undefined) => void;
|
|
13
9
|
criteria?: Record<string, unknown>;
|
|
14
10
|
originalCriteria?: Record<string, unknown>;
|
|
@@ -27,7 +23,7 @@ export type CriteriaInputProps = {
|
|
|
27
23
|
hideBorder?: boolean;
|
|
28
24
|
presetGroupLabel?: string;
|
|
29
25
|
treeViewOpts?: {
|
|
30
|
-
fetchObject?: (objectId: string) => Promise<
|
|
26
|
+
fetchObject?: (objectId: string) => Promise<EvokeObject | undefined>;
|
|
31
27
|
object: TreeViewObject;
|
|
32
28
|
};
|
|
33
29
|
/**
|
|
@@ -11,7 +11,7 @@ import { Box } from '../../layout';
|
|
|
11
11
|
import { OverflowTextField } from '../OverflowTextField';
|
|
12
12
|
import { difference, parseMongoDB } from '../util';
|
|
13
13
|
import PropertyTree from './PropertyTree';
|
|
14
|
-
import { ALL_OPERATORS } from './utils';
|
|
14
|
+
import { ALL_OPERATORS, traversePropertyPath } from './utils';
|
|
15
15
|
import ValueEditor from './ValueEditor';
|
|
16
16
|
const styles = {
|
|
17
17
|
buttons: {
|
|
@@ -88,114 +88,99 @@ const customButton = (props) => {
|
|
|
88
88
|
},
|
|
89
89
|
} }, buttonLabel))));
|
|
90
90
|
};
|
|
91
|
-
const
|
|
92
|
-
const { options, value, handleOnChange, context, level } = props;
|
|
91
|
+
const customSelector = (props) => {
|
|
92
|
+
const { options, value, handleOnChange, title, context, level } = props;
|
|
93
93
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
94
94
|
const rule = props.rule;
|
|
95
|
+
let width = '90px';
|
|
95
96
|
let val = value;
|
|
96
97
|
let opts = options;
|
|
97
|
-
const placeholder = 'Select Operator';
|
|
98
|
-
const width = '25%';
|
|
99
98
|
let inputType = props.fieldData?.inputType;
|
|
100
99
|
// for tree view / related object properties, the properties are stored in the propertyTreeMap upon selection
|
|
101
100
|
if (!!context.treeViewOpts && !!context.propertyTreeMap?.[rule.field]) {
|
|
102
101
|
inputType = context.propertyTreeMap[rule.field].type;
|
|
103
102
|
}
|
|
103
|
+
const isTreeViewEnabled = context.treeViewOpts && title === 'Fields';
|
|
104
|
+
const fetchObject = context.treeViewOpts?.fetchObject;
|
|
105
|
+
const object = context.treeViewOpts?.object;
|
|
104
106
|
let readOnly = context.disabled;
|
|
105
107
|
if (!readOnly && context.disabledCriteria) {
|
|
106
108
|
readOnly =
|
|
107
109
|
Object.entries(context.disabledCriteria.criteria).some(([key, value]) => key === rule.field && value === rule.value && rule.operator === '=') && level === context.disabledCriteria.level;
|
|
110
|
+
const keys = Object.keys(context.disabledCriteria.criteria);
|
|
111
|
+
if (title === 'Fields') {
|
|
112
|
+
opts = opts.filter((o) => readOnly || !keys.includes(o.name));
|
|
113
|
+
}
|
|
108
114
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
? 'Later than or at'
|
|
133
|
-
: 'After or on'
|
|
134
|
-
: option.name === '<'
|
|
115
|
+
let placeholder = '';
|
|
116
|
+
switch (title) {
|
|
117
|
+
case 'Operators':
|
|
118
|
+
width = '25%';
|
|
119
|
+
placeholder = 'Select Operator';
|
|
120
|
+
if (inputType === 'array') {
|
|
121
|
+
opts = options
|
|
122
|
+
.filter((option) => ['null', 'notNull', 'in'].includes(option.name))
|
|
123
|
+
.map((option) => ({ name: option.name, label: option.label }));
|
|
124
|
+
val = val === '=' ? '' : options.find((option) => option.name === val).name;
|
|
125
|
+
}
|
|
126
|
+
else if (inputType === 'document' || inputType === 'criteria') {
|
|
127
|
+
opts = options
|
|
128
|
+
.filter((option) => ['null', 'notNull'].includes(option.name))
|
|
129
|
+
.map((option) => ({ name: option.name, label: option.label }));
|
|
130
|
+
val = val === '=' ? '' : options.find((option) => option.name === val).name;
|
|
131
|
+
}
|
|
132
|
+
else if (inputType === 'date' || inputType === 'date-time' || inputType === 'time') {
|
|
133
|
+
opts = options
|
|
134
|
+
.filter((option) => ['=', '!=', '<', '>', '<=', '>=', 'null', 'notNull'].includes(option.name))
|
|
135
|
+
.map((option) => ({
|
|
136
|
+
...option,
|
|
137
|
+
label: option.name === '>'
|
|
135
138
|
? inputType === 'time'
|
|
136
|
-
? '
|
|
137
|
-
: '
|
|
138
|
-
: option.name === '
|
|
139
|
+
? 'Later than'
|
|
140
|
+
: 'After'
|
|
141
|
+
: option.name === '>='
|
|
139
142
|
? inputType === 'time'
|
|
140
|
-
? '
|
|
141
|
-
: '
|
|
142
|
-
: option.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
else if (inputType === 'string') {
|
|
153
|
-
opts = options.filter((option) => !['>', '<', '<=', '>='].includes(option.name));
|
|
154
|
-
}
|
|
155
|
-
else if (inputType === 'image' || inputType === 'boolean') {
|
|
156
|
-
opts = options.filter((option) => ['=', '!=', 'null', 'notNull'].includes(option.name));
|
|
157
|
-
}
|
|
158
|
-
return (React.createElement(Autocomplete, { options: opts, value: val ?? null, getOptionLabel: (option) => {
|
|
159
|
-
if (typeof option === 'string') {
|
|
160
|
-
return opts.find((o) => option === o.name)?.label || option;
|
|
143
|
+
? 'Later than or at'
|
|
144
|
+
: 'After or on'
|
|
145
|
+
: option.name === '<'
|
|
146
|
+
? inputType === 'time'
|
|
147
|
+
? 'Earlier than'
|
|
148
|
+
: 'Before'
|
|
149
|
+
: option.name === '<='
|
|
150
|
+
? inputType === 'time'
|
|
151
|
+
? 'Earlier than or at'
|
|
152
|
+
: 'Before or on'
|
|
153
|
+
: option.label,
|
|
154
|
+
}));
|
|
161
155
|
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
return option === value;
|
|
156
|
+
else if (inputType === 'integer' || inputType === 'number') {
|
|
157
|
+
opts = options.filter((option) => ['=', '!=', '<', '<=', '>', '>=', 'null', 'notNull', 'in', 'notIn'].includes(option.name));
|
|
158
|
+
// checks if it is a single-select property
|
|
166
159
|
}
|
|
167
|
-
else {
|
|
168
|
-
|
|
160
|
+
else if (inputType === 'string' && isArray(props.fieldData?.values)) {
|
|
161
|
+
opts = options.filter((option) => ['in', 'notIn', '=', '!=', 'notNull', 'null'].includes(option.name));
|
|
169
162
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const rule = props.rule;
|
|
183
|
-
const val = options.find((option) => option.name === value)?.name || value;
|
|
184
|
-
let opts = options;
|
|
185
|
-
const placeholder = 'Select Property';
|
|
186
|
-
const width = '37%';
|
|
187
|
-
const isTreeViewEnabled = context.treeViewOpts;
|
|
188
|
-
const fetchObject = context.treeViewOpts?.fetchObject;
|
|
189
|
-
const object = context.treeViewOpts?.object;
|
|
190
|
-
const setObject = context.treeViewOpts?.setObject;
|
|
191
|
-
let readOnly = context.disabled;
|
|
192
|
-
if (!readOnly && context.disabledCriteria) {
|
|
193
|
-
readOnly =
|
|
194
|
-
Object.entries(context.disabledCriteria.criteria).some(([key, value]) => key === rule.field && value === rule.value && rule.operator === '=') && level === context.disabledCriteria.level;
|
|
195
|
-
const keys = Object.keys(context.disabledCriteria.criteria);
|
|
196
|
-
opts = opts.filter((o) => readOnly || !keys.includes(o.name));
|
|
163
|
+
else if (inputType === 'string') {
|
|
164
|
+
opts = options.filter((option) => !['>', '<', '<=', '>='].includes(option.name));
|
|
165
|
+
}
|
|
166
|
+
else if (inputType === 'image' || inputType === 'boolean') {
|
|
167
|
+
opts = options.filter((option) => ['=', '!=', 'null', 'notNull'].includes(option.name));
|
|
168
|
+
}
|
|
169
|
+
break;
|
|
170
|
+
case 'Fields':
|
|
171
|
+
placeholder = 'Select Property';
|
|
172
|
+
width = '37%';
|
|
173
|
+
val = options.find((option) => option.name === val)?.name;
|
|
174
|
+
break;
|
|
197
175
|
}
|
|
198
|
-
|
|
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) => {
|
|
199
184
|
if (typeof option === 'string') {
|
|
200
185
|
return opts.find((o) => option === o.name)?.label || option;
|
|
201
186
|
}
|
|
@@ -210,10 +195,8 @@ const customFieldSelector = (props) => {
|
|
|
210
195
|
},
|
|
211
196
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
212
197
|
onChange: (event, newValue) => {
|
|
213
|
-
handleOnChange(
|
|
214
|
-
},
|
|
215
|
-
? (event, newInputValue) => handleOnChange(newInputValue)
|
|
216
|
-
: undefined, renderInput: (params) => (React.createElement(OverflowTextField, { value: val || '', ...params, placeholder: placeholder, size: "small", inputProps: {
|
|
198
|
+
handleOnChange(newValue?.value.name);
|
|
199
|
+
}, renderInput: (params) => (React.createElement(OverflowTextField, { value: opts.find((o) => value === o.name)?.label || '', ...params, placeholder: placeholder, size: "small", inputProps: {
|
|
217
200
|
...params.inputProps,
|
|
218
201
|
'aria-label': placeholder,
|
|
219
202
|
} })), sx: { width: width, background: readOnly ? '#f4f6f8' : '#fff' }, disableClearable: true, readOnly: readOnly }))));
|
|
@@ -292,159 +275,77 @@ const getAllRuleIds = (rules) => {
|
|
|
292
275
|
});
|
|
293
276
|
return ids;
|
|
294
277
|
};
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
let adjustedValue = rule.value;
|
|
306
|
-
if ((rule.operator === 'null' || rule.operator === 'notNull') && rule.value) {
|
|
307
|
-
adjustedValue = null;
|
|
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
|
+
};
|
|
308
288
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
value
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
...newProp,
|
|
323
|
-
children: newProp.children &&
|
|
324
|
-
newProp.children[0].type === 'loading' &&
|
|
325
|
-
prevProp.children
|
|
326
|
-
? prevProp.children
|
|
327
|
-
: newProp.children && prevProp.children
|
|
328
|
-
? insertChangesOnly({ id: prevProp.id, name: prevProp.name, properties: prevProp.children }, { id: newProp.id, name: newProp.name, properties: newProp.children }).properties
|
|
329
|
-
: newProp.children,
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
else {
|
|
333
|
-
return newProp;
|
|
334
|
-
}
|
|
335
|
-
});
|
|
336
|
-
return {
|
|
337
|
-
...newObject,
|
|
338
|
-
properties: mergedProperties,
|
|
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
|
+
};
|
|
300
|
+
}
|
|
301
|
+
});
|
|
339
302
|
};
|
|
340
|
-
};
|
|
341
|
-
const CriteriaBuilder = (props) => {
|
|
342
|
-
const { propertyFreeSolo, properties, criteria, setCriteria, originalCriteria, enablePresetValues, presetValues, operators, disabled, disabledCriteria, hideBorder, presetGroupLabel, customValueEditor, treeViewOpts, disableRegexEscapeChars, } = props;
|
|
343
|
-
const [propertyTreeMap, setPropertyTreeMap] = useState({});
|
|
344
|
-
const [treeViewObject, setTreeViewObject] = useState();
|
|
345
303
|
useEffect(() => {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
?.filter((child) => child.type !== 'collection')
|
|
356
|
-
.map((child) => ({
|
|
357
|
-
...child,
|
|
358
|
-
id: `${prop.id}.${child.id}`,
|
|
359
|
-
})),
|
|
360
|
-
})),
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
if ((criteria || originalCriteria) && obj && treeViewOpts?.fetchObject) {
|
|
364
|
-
const updateTreeViewObject = async (criteria, treeViewObject, fetchObject) => {
|
|
365
|
-
const newQuery = parseMongoDB(criteria);
|
|
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 || {});
|
|
366
313
|
const ids = getAllRuleIds(newQuery.rules);
|
|
367
|
-
|
|
368
|
-
const
|
|
369
|
-
const prop = properties?.find((prop) => path.startsWith(`${prop.id}.`) || path === prop.id);
|
|
370
|
-
if (prop?.type === 'object' && prop.objectId && prop.children) {
|
|
371
|
-
if (prop.children.length === 1 &&
|
|
372
|
-
prop.children[0]?.type === 'loading') {
|
|
373
|
-
try {
|
|
374
|
-
const fetchedObject = await fetchObject(prop.objectId);
|
|
375
|
-
prop.children = fetchedObject?.properties
|
|
376
|
-
?.filter((item) => item.type !== 'collection')
|
|
377
|
-
.map((item) => {
|
|
378
|
-
return {
|
|
379
|
-
...item,
|
|
380
|
-
id: `${prop.id}.${item.id}`,
|
|
381
|
-
children: item.children?.map((child) => ({
|
|
382
|
-
...child,
|
|
383
|
-
id: `${prop.id}.${item.id}.${child.id}`,
|
|
384
|
-
})),
|
|
385
|
-
};
|
|
386
|
-
});
|
|
387
|
-
fetchedObject && (await traversePath(path, fetchedObject.properties, fetchObject));
|
|
388
|
-
}
|
|
389
|
-
catch (error) {
|
|
390
|
-
prop.children = [
|
|
391
|
-
{
|
|
392
|
-
id: `${prop.id}-failed`,
|
|
393
|
-
name: 'Loading Failed',
|
|
394
|
-
type: 'loadingFailed',
|
|
395
|
-
},
|
|
396
|
-
];
|
|
397
|
-
console.error('Error fetching object for criteria builder:', error);
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
else {
|
|
401
|
-
await traversePath(path, prop.children, fetchObject);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
};
|
|
314
|
+
let newPropertyTreeMap = {};
|
|
315
|
+
const newPropertyTreeMapPromises = [];
|
|
405
316
|
for (const id of ids) {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
if (prop) {
|
|
421
|
-
if (prop.children) {
|
|
422
|
-
const result = helper(path, { id: prop.id, name: prop.name, properties: prop.children });
|
|
423
|
-
namePath = result ? prop.name + ' / ' + result : '';
|
|
424
|
-
}
|
|
425
|
-
else {
|
|
426
|
-
namePath = prop.name;
|
|
317
|
+
if (!propertyTreeMap?.[id]) {
|
|
318
|
+
newPropertyTreeMapPromises.push(traversePropertyPath(id, object, fetchObject)
|
|
319
|
+
.then((property) => {
|
|
320
|
+
if (property) {
|
|
321
|
+
return {
|
|
322
|
+
[id]: property,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
return {};
|
|
326
|
+
})
|
|
327
|
+
.catch((err) => {
|
|
328
|
+
console.error(err);
|
|
329
|
+
return {};
|
|
330
|
+
}));
|
|
427
331
|
}
|
|
428
332
|
}
|
|
429
|
-
|
|
333
|
+
newPropertyTreeMap = (await Promise.all(newPropertyTreeMapPromises)).reduce((acc, currentProperty) => ({ ...acc, ...currentProperty }), {});
|
|
334
|
+
setPropertyTreeMap((prevPropertyTreeMap) => ({
|
|
335
|
+
...prevPropertyTreeMap,
|
|
336
|
+
...newPropertyTreeMap,
|
|
337
|
+
}));
|
|
430
338
|
};
|
|
431
|
-
|
|
432
|
-
};
|
|
433
|
-
const newQuery = parseMongoDB(criteria || originalCriteria || {});
|
|
434
|
-
const ids = getAllRuleIds(newQuery.rules);
|
|
435
|
-
const result = {};
|
|
436
|
-
for (const id of ids) {
|
|
437
|
-
result[id] = getNamePath(id, treeViewObject);
|
|
339
|
+
updatePropertyTreeMap().catch((err) => console.error(err));
|
|
438
340
|
}
|
|
439
|
-
|
|
440
|
-
}, [criteria, originalCriteria, treeViewObject]);
|
|
341
|
+
}, [criteria, originalCriteria, treeViewOpts]);
|
|
441
342
|
const initializeQuery = () => {
|
|
442
343
|
const criteriaToParse = criteria || originalCriteria;
|
|
443
344
|
const updatedQuery = criteriaToParse ? parseMongoDB(criteriaToParse || {}) : undefined;
|
|
444
345
|
return updatedQuery
|
|
445
346
|
? {
|
|
446
347
|
...updatedQuery,
|
|
447
|
-
rules: processRules(updatedQuery.rules
|
|
348
|
+
rules: processRules(updatedQuery.rules),
|
|
448
349
|
}
|
|
449
350
|
: { combinator: 'and', rules: [] };
|
|
450
351
|
};
|
|
@@ -470,7 +371,7 @@ const CriteriaBuilder = (props) => {
|
|
|
470
371
|
const handleQueryChange = (q) => {
|
|
471
372
|
const processedQuery = {
|
|
472
373
|
...q,
|
|
473
|
-
rules: processRules(q.rules
|
|
374
|
+
rules: processRules(q.rules),
|
|
474
375
|
};
|
|
475
376
|
setQuery(processedQuery);
|
|
476
377
|
const newCriteria = JSON.parse(formatQuery(processedQuery, {
|
|
@@ -562,6 +463,9 @@ const CriteriaBuilder = (props) => {
|
|
|
562
463
|
borderStyle: 'hidden',
|
|
563
464
|
background: '#fff',
|
|
564
465
|
},
|
|
466
|
+
'.ruleGroup:not(:has(.rule, .ruleGroup .ruleGroup))': {
|
|
467
|
+
backgroundColor: 'transparent',
|
|
468
|
+
},
|
|
565
469
|
'.ruleGroup-header': {
|
|
566
470
|
display: 'block',
|
|
567
471
|
},
|
|
@@ -612,8 +516,8 @@ const CriteriaBuilder = (props) => {
|
|
|
612
516
|
},
|
|
613
517
|
}, showCombinatorsBetweenRules: true, listsAsArrays: true, disabled: disabled, addRuleToNewGroups: true, controlElements: {
|
|
614
518
|
combinatorSelector: customCombinator,
|
|
615
|
-
fieldSelector:
|
|
616
|
-
operatorSelector:
|
|
519
|
+
fieldSelector: customSelector,
|
|
520
|
+
operatorSelector: customSelector,
|
|
617
521
|
addGroupAction: customButton,
|
|
618
522
|
addRuleAction: customButton,
|
|
619
523
|
ruleGroup: CustomRuleGroup,
|
|
@@ -627,15 +531,17 @@ const CriteriaBuilder = (props) => {
|
|
|
627
531
|
presetGroupLabel,
|
|
628
532
|
disabled,
|
|
629
533
|
disabledCriteria,
|
|
630
|
-
treeViewOpts:
|
|
534
|
+
treeViewOpts: treeViewOpts
|
|
631
535
|
? {
|
|
632
536
|
...treeViewOpts,
|
|
633
|
-
object:
|
|
634
|
-
|
|
537
|
+
object: {
|
|
538
|
+
...treeViewOpts?.object,
|
|
539
|
+
properties: treeViewOpts?.object.properties.filter(({ type }) => type !== 'collection'),
|
|
540
|
+
},
|
|
635
541
|
}
|
|
636
542
|
: undefined,
|
|
637
543
|
propertyTreeMap,
|
|
638
|
-
|
|
544
|
+
setPropertyTreeMap,
|
|
639
545
|
}, controlClassnames: {
|
|
640
546
|
ruleGroup: 'container',
|
|
641
547
|
}, operators: operators
|