@finos/legend-query-builder 4.14.72 → 4.14.73
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/lib/components/explorer/QueryBuilderPropertySearchPanel.d.ts.map +1 -1
- package/lib/components/explorer/QueryBuilderPropertySearchPanel.js +108 -36
- package/lib/components/explorer/QueryBuilderPropertySearchPanel.js.map +1 -1
- package/lib/components/result/QueryBuilderResultPanel.d.ts.map +1 -1
- package/lib/components/result/QueryBuilderResultPanel.js +3 -1
- package/lib/components/result/QueryBuilderResultPanel.js.map +1 -1
- package/lib/index.css +1 -17
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/QueryBuilderConfig.d.ts +2 -1
- package/lib/stores/QueryBuilderConfig.d.ts.map +1 -1
- package/lib/stores/QueryBuilderConfig.js +2 -1
- package/lib/stores/QueryBuilderConfig.js.map +1 -1
- package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
- package/lib/stores/QueryBuilderResultState.js +4 -1
- package/lib/stores/QueryBuilderResultState.js.map +1 -1
- package/lib/stores/explorer/QueryBuilderExplorerState.d.ts +4 -3
- package/lib/stores/explorer/QueryBuilderExplorerState.d.ts.map +1 -1
- package/lib/stores/explorer/QueryBuilderExplorerState.js +22 -7
- package/lib/stores/explorer/QueryBuilderExplorerState.js.map +1 -1
- package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.d.ts.map +1 -1
- package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.js +1 -1
- package/lib/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.js.map +1 -1
- package/lib/stores/explorer/QueryBuilderPropertySearchState.d.ts +7 -1
- package/lib/stores/explorer/QueryBuilderPropertySearchState.d.ts.map +1 -1
- package/lib/stores/explorer/QueryBuilderPropertySearchState.js +160 -74
- package/lib/stores/explorer/QueryBuilderPropertySearchState.js.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +1 -1
- package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.d.ts +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.d.ts.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.js +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
- package/package.json +3 -3
- package/src/components/explorer/QueryBuilderPropertySearchPanel.tsx +249 -226
- package/src/components/result/QueryBuilderResultPanel.tsx +3 -1
- package/src/stores/QueryBuilderConfig.ts +2 -1
- package/src/stores/QueryBuilderResultState.ts +4 -0
- package/src/stores/explorer/QueryBuilderExplorerState.ts +58 -5
- package/src/stores/explorer/QueryBuilderFuzzySearchAdvancedConfigState.ts +1 -1
- package/src/stores/explorer/QueryBuilderPropertySearchState.ts +194 -92
- package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +4 -3
- package/src/stores/filter/QueryBuilderFilterState.ts +5 -4
@@ -31,6 +31,7 @@ import {
|
|
31
31
|
type MappingModelCoverageAnalysisResult,
|
32
32
|
type EnumMappedProperty,
|
33
33
|
type MappedEntity,
|
34
|
+
type ExecutionResultWithMetadata,
|
34
35
|
AbstractPropertyExpression,
|
35
36
|
Class,
|
36
37
|
VariableExpression,
|
@@ -55,7 +56,6 @@ import {
|
|
55
56
|
Association,
|
56
57
|
PRIMITIVE_TYPE,
|
57
58
|
TDSExecutionResult,
|
58
|
-
type ExecutionResult,
|
59
59
|
getAllSubclasses,
|
60
60
|
PropertyExplicitReference,
|
61
61
|
reportGraphAnalytics,
|
@@ -115,6 +115,7 @@ export abstract class QueryBuilderExplorerTreeNodeData implements TreeNodeData {
|
|
115
115
|
isPartOfDerivedPropertyBranch: boolean,
|
116
116
|
type: Type,
|
117
117
|
mappingData: QueryBuilderExplorerTreeNodeMappingData,
|
118
|
+
childrenIds?: string[] | undefined,
|
118
119
|
) {
|
119
120
|
makeObservable(this, {
|
120
121
|
isHighlighting: observable,
|
@@ -131,6 +132,9 @@ export abstract class QueryBuilderExplorerTreeNodeData implements TreeNodeData {
|
|
131
132
|
this.isPartOfDerivedPropertyBranch = isPartOfDerivedPropertyBranch;
|
132
133
|
this.type = type;
|
133
134
|
this.mappingData = mappingData;
|
135
|
+
if (childrenIds) {
|
136
|
+
this.childrenIds = childrenIds;
|
137
|
+
}
|
134
138
|
this.elementRef = createRef();
|
135
139
|
}
|
136
140
|
|
@@ -169,6 +173,7 @@ export class QueryBuilderExplorerTreePropertyNodeData extends QueryBuilderExplor
|
|
169
173
|
isPartOfDerivedPropertyBranch: boolean,
|
170
174
|
mappingData: QueryBuilderExplorerTreeNodeMappingData,
|
171
175
|
type?: Type | undefined,
|
176
|
+
childrenIds?: string[],
|
172
177
|
) {
|
173
178
|
super(
|
174
179
|
id,
|
@@ -177,6 +182,7 @@ export class QueryBuilderExplorerTreePropertyNodeData extends QueryBuilderExplor
|
|
177
182
|
isPartOfDerivedPropertyBranch,
|
178
183
|
type ?? property.genericType.value.rawType,
|
179
184
|
mappingData,
|
185
|
+
childrenIds,
|
180
186
|
);
|
181
187
|
this.property = property;
|
182
188
|
this.parentId = parentId;
|
@@ -197,6 +203,7 @@ export class QueryBuilderExplorerTreeSubTypeNodeData extends QueryBuilderExplore
|
|
197
203
|
isPartOfDerivedPropertyBranch: boolean,
|
198
204
|
mappingData: QueryBuilderExplorerTreeNodeMappingData,
|
199
205
|
multiplicity: Multiplicity,
|
206
|
+
childrenIds?: string[],
|
200
207
|
) {
|
201
208
|
super(
|
202
209
|
id,
|
@@ -205,6 +212,7 @@ export class QueryBuilderExplorerTreeSubTypeNodeData extends QueryBuilderExplore
|
|
205
212
|
isPartOfDerivedPropertyBranch,
|
206
213
|
subclass,
|
207
214
|
mappingData,
|
215
|
+
childrenIds,
|
208
216
|
);
|
209
217
|
this.subclass = subclass;
|
210
218
|
this.parentId = parentId;
|
@@ -652,6 +660,49 @@ const getQueryBuilderTreeData = (
|
|
652
660
|
return { rootIds, nodes };
|
653
661
|
};
|
654
662
|
|
663
|
+
export const cloneQueryBuilderExplorerTreeNodeData = (
|
664
|
+
node: QueryBuilderExplorerTreeNodeData,
|
665
|
+
): QueryBuilderExplorerTreeNodeData => {
|
666
|
+
if (node instanceof QueryBuilderExplorerTreeRootNodeData) {
|
667
|
+
return new QueryBuilderExplorerTreeRootNodeData(
|
668
|
+
node.id,
|
669
|
+
node.label,
|
670
|
+
node.dndText,
|
671
|
+
node.isPartOfDerivedPropertyBranch,
|
672
|
+
node.type,
|
673
|
+
node.mappingData,
|
674
|
+
node.childrenIds,
|
675
|
+
);
|
676
|
+
} else if (node instanceof QueryBuilderExplorerTreePropertyNodeData) {
|
677
|
+
return new QueryBuilderExplorerTreePropertyNodeData(
|
678
|
+
node.id,
|
679
|
+
node.label,
|
680
|
+
node.dndText,
|
681
|
+
node.property,
|
682
|
+
node.parentId,
|
683
|
+
node.isPartOfDerivedPropertyBranch,
|
684
|
+
node.mappingData,
|
685
|
+
node.type,
|
686
|
+
node.childrenIds,
|
687
|
+
);
|
688
|
+
} else if (node instanceof QueryBuilderExplorerTreeSubTypeNodeData) {
|
689
|
+
return new QueryBuilderExplorerTreeSubTypeNodeData(
|
690
|
+
node.id,
|
691
|
+
node.label,
|
692
|
+
node.dndText,
|
693
|
+
node.subclass,
|
694
|
+
node.parentId,
|
695
|
+
node.isPartOfDerivedPropertyBranch,
|
696
|
+
node.mappingData,
|
697
|
+
node.multiplicity,
|
698
|
+
node.childrenIds,
|
699
|
+
);
|
700
|
+
}
|
701
|
+
throw new UnsupportedOperationError(
|
702
|
+
`Unable to clone node of type ${node.constructor.name}`,
|
703
|
+
);
|
704
|
+
};
|
705
|
+
|
655
706
|
export class QueryBuilderExplorerPreviewDataState {
|
656
707
|
isGeneratingPreviewData = false;
|
657
708
|
propertyName = '(unknown)';
|
@@ -957,7 +1008,7 @@ export class QueryBuilderExplorerState {
|
|
957
1008
|
case PRIMITIVE_TYPE.INTEGER:
|
958
1009
|
case PRIMITIVE_TYPE.DECIMAL:
|
959
1010
|
case PRIMITIVE_TYPE.FLOAT: {
|
960
|
-
const previewResult =
|
1011
|
+
const previewResult = (
|
961
1012
|
(yield this.queryBuilderState.graphManagerState.graphManager.runQuery(
|
962
1013
|
buildNumericPreviewDataQuery(
|
963
1014
|
this.queryBuilderState,
|
@@ -970,7 +1021,8 @@ export class QueryBuilderExplorerState {
|
|
970
1021
|
abortController:
|
971
1022
|
this.previewDataState.previewDataAbortController,
|
972
1023
|
},
|
973
|
-
)) as
|
1024
|
+
)) as ExecutionResultWithMetadata
|
1025
|
+
).executionResult;
|
974
1026
|
assertType(
|
975
1027
|
previewResult,
|
976
1028
|
TDSExecutionResult,
|
@@ -998,7 +1050,7 @@ export class QueryBuilderExplorerState {
|
|
998
1050
|
case PRIMITIVE_TYPE.DATE:
|
999
1051
|
case PRIMITIVE_TYPE.STRICTDATE:
|
1000
1052
|
case PRIMITIVE_TYPE.DATETIME: {
|
1001
|
-
const previewResult =
|
1053
|
+
const previewResult = (
|
1002
1054
|
(yield this.queryBuilderState.graphManagerState.graphManager.runQuery(
|
1003
1055
|
buildNonNumericPreviewDataQuery(
|
1004
1056
|
this.queryBuilderState,
|
@@ -1011,7 +1063,8 @@ export class QueryBuilderExplorerState {
|
|
1011
1063
|
abortController:
|
1012
1064
|
this.previewDataState.previewDataAbortController,
|
1013
1065
|
},
|
1014
|
-
)) as
|
1066
|
+
)) as ExecutionResultWithMetadata
|
1067
|
+
).executionResult;
|
1015
1068
|
assertType(
|
1016
1069
|
previewResult,
|
1017
1070
|
TDSExecutionResult,
|
@@ -18,7 +18,7 @@ import { FuzzySearchAdvancedConfigState } from '@finos/legend-shared';
|
|
18
18
|
import { action, makeObservable, observable } from 'mobx';
|
19
19
|
|
20
20
|
export class QueryBuilderFuzzySearchAdvancedConfigState extends FuzzySearchAdvancedConfigState {
|
21
|
-
includeSubTypes =
|
21
|
+
includeSubTypes = true;
|
22
22
|
includeDocumentation = false;
|
23
23
|
|
24
24
|
constructor(
|
@@ -23,15 +23,16 @@ import {
|
|
23
23
|
PRIMITIVE_TYPE,
|
24
24
|
CORE_PURE_PATH,
|
25
25
|
PURE_DOC_TAG,
|
26
|
+
Enumeration,
|
26
27
|
} from '@finos/legend-graph';
|
27
28
|
import {
|
29
|
+
type FuzzySearchEngineSortFunctionArg,
|
28
30
|
ActionState,
|
29
31
|
FuzzySearchEngine,
|
30
32
|
addUniqueEntry,
|
31
33
|
deleteEntry,
|
32
34
|
guaranteeNonNullable,
|
33
35
|
isNonNullable,
|
34
|
-
type FuzzySearchEngineSortFunctionArg,
|
35
36
|
} from '@finos/legend-shared';
|
36
37
|
import {
|
37
38
|
observable,
|
@@ -47,11 +48,13 @@ import {
|
|
47
48
|
QUERY_BUILDER_PROPERTY_SEARCH_MAX_NODES,
|
48
49
|
} from '../QueryBuilderConfig.js';
|
49
50
|
import {
|
51
|
+
type QueryBuilderExplorerTreeNodeData,
|
50
52
|
getQueryBuilderPropertyNodeData,
|
51
53
|
getQueryBuilderSubTypeNodeData,
|
52
|
-
type QueryBuilderExplorerTreeNodeData,
|
53
54
|
QueryBuilderExplorerTreePropertyNodeData,
|
54
55
|
QueryBuilderExplorerTreeSubTypeNodeData,
|
56
|
+
cloneQueryBuilderExplorerTreeNodeData,
|
57
|
+
QueryBuilderExplorerTreeRootNodeData,
|
55
58
|
} from './QueryBuilderExplorerState.js';
|
56
59
|
import type { QueryBuilderState } from '../QueryBuilderState.js';
|
57
60
|
import { QueryBuilderFuzzySearchAdvancedConfigState } from './QueryBuilderFuzzySearchAdvancedConfigState.js';
|
@@ -74,7 +77,8 @@ export class QueryBuilderPropertySearchState {
|
|
74
77
|
* is that we could interact with the searched nodes, i.e. drag them to
|
75
78
|
* various panels to create filter, fetch-structure, etc.
|
76
79
|
*/
|
77
|
-
|
80
|
+
indexedExplorerTreeNodeMap: Map<string, QueryBuilderExplorerTreeNodeData> =
|
81
|
+
new Map();
|
78
82
|
|
79
83
|
// search
|
80
84
|
searchEngine: FuzzySearchEngine<QueryBuilderExplorerTreeNodeData>;
|
@@ -89,8 +93,10 @@ export class QueryBuilderPropertySearchState {
|
|
89
93
|
showSearchConfigurationMenu = false;
|
90
94
|
|
91
95
|
// filter
|
96
|
+
includeOneMany = false;
|
92
97
|
typeFilters = [
|
93
98
|
QUERY_BUILDER_PROPERTY_SEARCH_TYPE.CLASS,
|
99
|
+
QUERY_BUILDER_PROPERTY_SEARCH_TYPE.ENUMERATION,
|
94
100
|
QUERY_BUILDER_PROPERTY_SEARCH_TYPE.STRING,
|
95
101
|
QUERY_BUILDER_PROPERTY_SEARCH_TYPE.BOOLEAN,
|
96
102
|
QUERY_BUILDER_PROPERTY_SEARCH_TYPE.NUMBER,
|
@@ -99,14 +105,16 @@ export class QueryBuilderPropertySearchState {
|
|
99
105
|
|
100
106
|
constructor(queryBuilderState: QueryBuilderState) {
|
101
107
|
makeObservable(this, {
|
102
|
-
|
108
|
+
indexedExplorerTreeNodeMap: observable,
|
103
109
|
searchText: observable,
|
104
110
|
searchResults: observable,
|
105
111
|
isOverSearchLimit: observable,
|
106
112
|
isSearchPanelOpen: observable,
|
107
113
|
isSearchPanelHidden: observable,
|
108
114
|
showSearchConfigurationMenu: observable,
|
115
|
+
includeOneMany: observable,
|
109
116
|
typeFilters: observable,
|
117
|
+
indexedExplorerTreeNodes: computed,
|
110
118
|
filteredSearchResults: computed,
|
111
119
|
search: action,
|
112
120
|
resetSearch: action,
|
@@ -116,6 +124,8 @@ export class QueryBuilderPropertySearchState {
|
|
116
124
|
setShowSearchConfigurationMenu: action,
|
117
125
|
setIsSearchPanelOpen: action,
|
118
126
|
setIsSearchPanelHidden: action,
|
127
|
+
setIncludeOneMany: action,
|
128
|
+
setFilterOnlyType: action,
|
119
129
|
toggleFilterForType: action,
|
120
130
|
initialize: action,
|
121
131
|
});
|
@@ -156,9 +166,22 @@ export class QueryBuilderPropertySearchState {
|
|
156
166
|
resetSearch(): void {
|
157
167
|
this.searchText = '';
|
158
168
|
this.searchResults = [];
|
169
|
+
this.indexedExplorerTreeNodes.forEach((node) => {
|
170
|
+
if (!(node instanceof QueryBuilderExplorerTreeRootNodeData)) {
|
171
|
+
node.setIsOpen(false);
|
172
|
+
}
|
173
|
+
});
|
159
174
|
this.searchState.complete();
|
160
175
|
}
|
161
176
|
|
177
|
+
setIncludeOneMany(val: boolean): void {
|
178
|
+
this.includeOneMany = val;
|
179
|
+
}
|
180
|
+
|
181
|
+
setFilterOnlyType(val: QUERY_BUILDER_PROPERTY_SEARCH_TYPE): void {
|
182
|
+
this.typeFilters = [val];
|
183
|
+
}
|
184
|
+
|
162
185
|
toggleFilterForType(val: QUERY_BUILDER_PROPERTY_SEARCH_TYPE): void {
|
163
186
|
if (this.typeFilters.includes(val)) {
|
164
187
|
deleteEntry(this.typeFilters, val);
|
@@ -167,6 +190,29 @@ export class QueryBuilderPropertySearchState {
|
|
167
190
|
}
|
168
191
|
}
|
169
192
|
|
193
|
+
isNodeMultiple(node: QueryBuilderExplorerTreeNodeData): boolean {
|
194
|
+
// Check if node or any ancestors are one-many nodes.
|
195
|
+
let currNode: QueryBuilderExplorerTreeNodeData | undefined = node;
|
196
|
+
while (currNode) {
|
197
|
+
if (
|
198
|
+
(currNode instanceof QueryBuilderExplorerTreeSubTypeNodeData &&
|
199
|
+
(currNode.multiplicity.upperBound === undefined ||
|
200
|
+
currNode.multiplicity.upperBound > 1)) ||
|
201
|
+
(currNode instanceof QueryBuilderExplorerTreePropertyNodeData &&
|
202
|
+
(currNode.property.multiplicity.upperBound === undefined ||
|
203
|
+
currNode.property.multiplicity.upperBound > 1))
|
204
|
+
) {
|
205
|
+
return true;
|
206
|
+
}
|
207
|
+
currNode =
|
208
|
+
currNode instanceof QueryBuilderExplorerTreePropertyNodeData ||
|
209
|
+
currNode instanceof QueryBuilderExplorerTreeSubTypeNodeData
|
210
|
+
? this.indexedExplorerTreeNodeMap.get(currNode.parentId)
|
211
|
+
: undefined;
|
212
|
+
}
|
213
|
+
return false;
|
214
|
+
}
|
215
|
+
|
170
216
|
async search(): Promise<void> {
|
171
217
|
if (!this.searchText) {
|
172
218
|
this.setSearchResults([]);
|
@@ -175,6 +221,12 @@ export class QueryBuilderPropertySearchState {
|
|
175
221
|
|
176
222
|
this.searchState.inProgress();
|
177
223
|
|
224
|
+
this.indexedExplorerTreeNodes.forEach((node) => {
|
225
|
+
if (!(node instanceof QueryBuilderExplorerTreeRootNodeData)) {
|
226
|
+
node.setIsOpen(false);
|
227
|
+
}
|
228
|
+
});
|
229
|
+
|
178
230
|
// Perform the search in a setTimeout so we can execute it asynchronously and
|
179
231
|
// show the loading indicator while search is in progress.
|
180
232
|
return new Promise((resolve) =>
|
@@ -210,18 +262,13 @@ export class QueryBuilderPropertySearchState {
|
|
210
262
|
return node;
|
211
263
|
})
|
212
264
|
.filter((node) => {
|
213
|
-
// Filter out
|
214
|
-
if (
|
215
|
-
|
216
|
-
|
217
|
-
node
|
265
|
+
// Filter out nodes if their parent class node is already in the results.
|
266
|
+
if (
|
267
|
+
(node instanceof QueryBuilderExplorerTreePropertyNodeData ||
|
268
|
+
node instanceof QueryBuilderExplorerTreeSubTypeNodeData) &&
|
269
|
+
classNodes.has(node.parentId)
|
218
270
|
) {
|
219
|
-
|
220
|
-
return true;
|
221
|
-
} else if (classNodes.has(node.parentId)) {
|
222
|
-
classNodes.get(node.parentId)?.setIsOpen(true);
|
223
|
-
return false;
|
224
|
-
}
|
271
|
+
return false;
|
225
272
|
}
|
226
273
|
return true;
|
227
274
|
});
|
@@ -260,22 +307,26 @@ export class QueryBuilderPropertySearchState {
|
|
260
307
|
// show the loading indicator while initialization is in progress.
|
261
308
|
return new Promise((resolve) =>
|
262
309
|
setTimeout(() => {
|
263
|
-
|
310
|
+
const treeData =
|
311
|
+
this.queryBuilderState.explorerState.nonNullableTreeData;
|
312
|
+
const rootNodeMap = new Map(
|
313
|
+
treeData.rootIds
|
314
|
+
.map((rootId) => treeData.nodes.get(rootId))
|
315
|
+
.filter(isNonNullable)
|
316
|
+
.map((rootNode) => [rootNode.id, rootNode]),
|
317
|
+
);
|
318
|
+
this.indexedExplorerTreeNodeMap = new Map();
|
264
319
|
|
265
320
|
let currentLevelPropertyNodes: QueryBuilderExplorerTreeNodeData[] = [];
|
266
321
|
let nextLevelPropertyNodes: QueryBuilderExplorerTreeNodeData[] = [];
|
267
322
|
|
268
323
|
// Get all the children of the root node(s)
|
269
324
|
Array.from(
|
270
|
-
|
325
|
+
treeData.rootIds
|
271
326
|
.map((rootId) =>
|
272
|
-
|
327
|
+
treeData.nodes
|
273
328
|
.get(rootId)
|
274
|
-
?.childrenIds.map((childId) =>
|
275
|
-
this.queryBuilderState.explorerState.nonNullableTreeData.nodes.get(
|
276
|
-
childId,
|
277
|
-
),
|
278
|
-
),
|
329
|
+
?.childrenIds.map((childId) => treeData.nodes.get(childId)),
|
279
330
|
)
|
280
331
|
.flat()
|
281
332
|
.filter(isNonNullable)
|
@@ -287,24 +338,54 @@ export class QueryBuilderPropertySearchState {
|
|
287
338
|
),
|
288
339
|
).forEach((node) => {
|
289
340
|
if (node.mappingData.mapped && !node.isPartOfDerivedPropertyBranch) {
|
290
|
-
|
291
|
-
|
341
|
+
const clonedNode = cloneQueryBuilderExplorerTreeNodeData(node);
|
342
|
+
currentLevelPropertyNodes.push(clonedNode);
|
343
|
+
this.indexedExplorerTreeNodeMap.set(clonedNode.id, clonedNode);
|
292
344
|
}
|
293
345
|
});
|
294
346
|
|
295
347
|
// ensure we don't navigate more nodes than the limit so we could
|
296
348
|
// keep the initialization/indexing time within acceptable range
|
297
349
|
const NODE_LIMIT =
|
298
|
-
this.
|
350
|
+
this.indexedExplorerTreeNodeMap.size +
|
299
351
|
QUERY_BUILDER_PROPERTY_SEARCH_MAX_NODES;
|
300
352
|
const addNode = (node: QueryBuilderExplorerTreeNodeData): void =>
|
301
353
|
runInAction(() => {
|
302
|
-
if (this.
|
354
|
+
if (this.indexedExplorerTreeNodeMap.size > NODE_LIMIT) {
|
303
355
|
return;
|
304
356
|
}
|
305
|
-
|
357
|
+
const clonedNode = cloneQueryBuilderExplorerTreeNodeData(node);
|
358
|
+
this.indexedExplorerTreeNodeMap.set(clonedNode.id, clonedNode);
|
306
359
|
});
|
307
360
|
|
361
|
+
// helper function to check if a node has the same type as one of its
|
362
|
+
// ancestor nodes. This allows us to avoid including circular dependencies
|
363
|
+
// in the indexed nodes list.
|
364
|
+
const nodeHasSameTypeAsAncestor = (
|
365
|
+
node: QueryBuilderExplorerTreeNodeData,
|
366
|
+
): boolean => {
|
367
|
+
if (
|
368
|
+
node instanceof QueryBuilderExplorerTreePropertyNodeData ||
|
369
|
+
node instanceof QueryBuilderExplorerTreeSubTypeNodeData
|
370
|
+
) {
|
371
|
+
let ancestor =
|
372
|
+
this.indexedExplorerTreeNodeMap.get(node.parentId) ??
|
373
|
+
rootNodeMap.get(node.parentId);
|
374
|
+
while (ancestor) {
|
375
|
+
if (node.type === ancestor.type) {
|
376
|
+
return true;
|
377
|
+
}
|
378
|
+
ancestor =
|
379
|
+
ancestor instanceof QueryBuilderExplorerTreePropertyNodeData ||
|
380
|
+
ancestor instanceof QueryBuilderExplorerTreeSubTypeNodeData
|
381
|
+
? (this.indexedExplorerTreeNodeMap.get(ancestor.parentId) ??
|
382
|
+
rootNodeMap.get(ancestor.parentId))
|
383
|
+
: undefined;
|
384
|
+
}
|
385
|
+
}
|
386
|
+
return false;
|
387
|
+
};
|
388
|
+
|
308
389
|
// limit the depth of navigation to keep the initialization/indexing
|
309
390
|
// time within acceptable range
|
310
391
|
let currentDepth = 1;
|
@@ -336,8 +417,10 @@ export class QueryBuilderPropertySearchState {
|
|
336
417
|
),
|
337
418
|
);
|
338
419
|
if (
|
339
|
-
propertyTreeNodeData
|
340
|
-
|
420
|
+
propertyTreeNodeData &&
|
421
|
+
propertyTreeNodeData.mappingData.mapped &&
|
422
|
+
!propertyTreeNodeData.isPartOfDerivedPropertyBranch &&
|
423
|
+
!nodeHasSameTypeAsAncestor(propertyTreeNodeData)
|
341
424
|
) {
|
342
425
|
nextLevelPropertyNodes.push(propertyTreeNodeData);
|
343
426
|
addNode(propertyTreeNodeData);
|
@@ -353,7 +436,10 @@ export class QueryBuilderPropertySearchState {
|
|
353
436
|
.mappingModelCoverageAnalysisResult,
|
354
437
|
),
|
355
438
|
);
|
356
|
-
if (
|
439
|
+
if (
|
440
|
+
subTypeTreeNodeData.mappingData.mapped &&
|
441
|
+
!nodeHasSameTypeAsAncestor(subTypeTreeNodeData)
|
442
|
+
) {
|
357
443
|
nextLevelPropertyNodes.push(subTypeTreeNodeData);
|
358
444
|
addNode(subTypeTreeNodeData);
|
359
445
|
}
|
@@ -365,7 +451,7 @@ export class QueryBuilderPropertySearchState {
|
|
365
451
|
// number of indexed nodes to figure out if we should proceed further
|
366
452
|
if (
|
367
453
|
!currentLevelPropertyNodes.length &&
|
368
|
-
this.
|
454
|
+
this.indexedExplorerTreeNodeMap.size < NODE_LIMIT
|
369
455
|
) {
|
370
456
|
currentLevelPropertyNodes = nextLevelPropertyNodes;
|
371
457
|
nextLevelPropertyNodes = [];
|
@@ -388,21 +474,25 @@ export class QueryBuilderPropertySearchState {
|
|
388
474
|
threshold: 0.2,
|
389
475
|
keys: [
|
390
476
|
{
|
391
|
-
name: '
|
477
|
+
name: 'label',
|
392
478
|
weight: 4,
|
479
|
+
},
|
480
|
+
{
|
481
|
+
name: 'path',
|
482
|
+
weight: 2,
|
393
483
|
getFn: (node) => {
|
394
|
-
const parentNode =
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
QueryBuilderExplorerTreeSubTypeNodeData
|
484
|
+
const parentNode =
|
485
|
+
node instanceof QueryBuilderExplorerTreePropertyNodeData ||
|
486
|
+
node instanceof QueryBuilderExplorerTreeSubTypeNodeData
|
487
|
+
? this.indexedExplorerTreeNodeMap.get(node.parentId)
|
488
|
+
: undefined;
|
489
|
+
|
490
|
+
const fullPath = parentNode
|
491
|
+
? parentNode instanceof
|
492
|
+
QueryBuilderExplorerTreeSubTypeNodeData
|
404
493
|
? prettyPropertyNameForSubType(node.id)
|
405
|
-
: prettyPropertyNameFromNodeId(node.id)
|
494
|
+
: prettyPropertyNameFromNodeId(node.id)
|
495
|
+
: '';
|
406
496
|
|
407
497
|
return fullPath;
|
408
498
|
},
|
@@ -471,61 +561,73 @@ export class QueryBuilderPropertySearchState {
|
|
471
561
|
);
|
472
562
|
}
|
473
563
|
|
474
|
-
get
|
475
|
-
return this.
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
564
|
+
get indexedExplorerTreeNodes(): QueryBuilderExplorerTreeNodeData[] {
|
565
|
+
return Array.from(this.indexedExplorerTreeNodeMap.values());
|
566
|
+
}
|
567
|
+
|
568
|
+
isNodeIncludedInFilter(node: QueryBuilderExplorerTreeNodeData): boolean {
|
569
|
+
if (!this.includeOneMany && this.isNodeMultiple(node)) {
|
570
|
+
return false;
|
571
|
+
}
|
572
|
+
if (this.typeFilters.includes(QUERY_BUILDER_PROPERTY_SEARCH_TYPE.CLASS)) {
|
573
|
+
if (node.type instanceof Class) {
|
574
|
+
return true;
|
480
575
|
}
|
481
|
-
|
482
|
-
|
483
|
-
)
|
484
|
-
|
485
|
-
|
486
|
-
|
576
|
+
}
|
577
|
+
if (
|
578
|
+
this.typeFilters.includes(QUERY_BUILDER_PROPERTY_SEARCH_TYPE.ENUMERATION)
|
579
|
+
) {
|
580
|
+
if (node.type instanceof Enumeration) {
|
581
|
+
return true;
|
487
582
|
}
|
583
|
+
}
|
584
|
+
if (this.typeFilters.includes(QUERY_BUILDER_PROPERTY_SEARCH_TYPE.STRING)) {
|
585
|
+
if (node.type === PrimitiveType.STRING) {
|
586
|
+
return true;
|
587
|
+
}
|
588
|
+
}
|
589
|
+
if (this.typeFilters.includes(QUERY_BUILDER_PROPERTY_SEARCH_TYPE.NUMBER)) {
|
488
590
|
if (
|
489
|
-
|
591
|
+
node.type instanceof PrimitiveType &&
|
592
|
+
(
|
593
|
+
[
|
594
|
+
PRIMITIVE_TYPE.NUMBER,
|
595
|
+
PRIMITIVE_TYPE.DECIMAL,
|
596
|
+
PRIMITIVE_TYPE.INTEGER,
|
597
|
+
PRIMITIVE_TYPE.FLOAT,
|
598
|
+
] as string[]
|
599
|
+
).includes(node.type.name)
|
490
600
|
) {
|
491
|
-
|
492
|
-
node.type instanceof PrimitiveType &&
|
493
|
-
(
|
494
|
-
[
|
495
|
-
PRIMITIVE_TYPE.NUMBER,
|
496
|
-
PRIMITIVE_TYPE.DECIMAL,
|
497
|
-
PRIMITIVE_TYPE.INTEGER,
|
498
|
-
PRIMITIVE_TYPE.FLOAT,
|
499
|
-
] as string[]
|
500
|
-
).includes(node.type.name)
|
501
|
-
) {
|
502
|
-
return true;
|
503
|
-
}
|
601
|
+
return true;
|
504
602
|
}
|
603
|
+
}
|
604
|
+
if (this.typeFilters.includes(QUERY_BUILDER_PROPERTY_SEARCH_TYPE.BOOLEAN)) {
|
605
|
+
if (node.type === PrimitiveType.BOOLEAN) {
|
606
|
+
return true;
|
607
|
+
}
|
608
|
+
}
|
609
|
+
if (this.typeFilters.includes(QUERY_BUILDER_PROPERTY_SEARCH_TYPE.DATE)) {
|
505
610
|
if (
|
506
|
-
|
611
|
+
node.type instanceof PrimitiveType &&
|
612
|
+
(
|
613
|
+
[
|
614
|
+
PRIMITIVE_TYPE.DATE,
|
615
|
+
PRIMITIVE_TYPE.DATETIME,
|
616
|
+
PRIMITIVE_TYPE.STRICTDATE,
|
617
|
+
PRIMITIVE_TYPE.STRICTTIME,
|
618
|
+
PRIMITIVE_TYPE.LATESTDATE,
|
619
|
+
] as string[]
|
620
|
+
).includes(node.type.name)
|
507
621
|
) {
|
508
|
-
|
509
|
-
return true;
|
510
|
-
}
|
622
|
+
return true;
|
511
623
|
}
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
PRIMITIVE_TYPE.STRICTTIME,
|
521
|
-
PRIMITIVE_TYPE.LATESTDATE,
|
522
|
-
] as string[]
|
523
|
-
).includes(node.type.name)
|
524
|
-
) {
|
525
|
-
return true;
|
526
|
-
}
|
527
|
-
}
|
528
|
-
return false;
|
529
|
-
});
|
624
|
+
}
|
625
|
+
return false;
|
626
|
+
}
|
627
|
+
|
628
|
+
get filteredSearchResults(): QueryBuilderExplorerTreeNodeData[] {
|
629
|
+
return this.searchResults.filter((node) =>
|
630
|
+
this.isNodeIncludedInFilter(node),
|
631
|
+
);
|
530
632
|
}
|
531
633
|
}
|
@@ -19,8 +19,8 @@ import {
|
|
19
19
|
type PureModel,
|
20
20
|
type Type,
|
21
21
|
type ValueSpecification,
|
22
|
-
type ExecutionResult,
|
23
22
|
type SimpleFunctionExpression,
|
23
|
+
type ExecutionResultWithMetadata,
|
24
24
|
observe_ValueSpecification,
|
25
25
|
PrimitiveType,
|
26
26
|
CollectionInstanceValue,
|
@@ -490,7 +490,7 @@ export class PostFilterConditionState implements Hashable {
|
|
490
490
|
);
|
491
491
|
const value = searchValue ?? rightConditionValue.value;
|
492
492
|
if (performTypeahead(value)) {
|
493
|
-
const result =
|
493
|
+
const result = (
|
494
494
|
(yield this.postFilterState.tdsState.queryBuilderState.graphManagerState.graphManager.runQuery(
|
495
495
|
buildProjectionColumnTypeaheadQuery(
|
496
496
|
this.postFilterState.tdsState.queryBuilderState,
|
@@ -507,7 +507,8 @@ export class PostFilterConditionState implements Hashable {
|
|
507
507
|
),
|
508
508
|
this.postFilterState.tdsState.queryBuilderState.graphManagerState
|
509
509
|
.graph,
|
510
|
-
)) as
|
510
|
+
)) as ExecutionResultWithMetadata
|
511
|
+
).executionResult;
|
511
512
|
this.typeaheadSearchResults = buildTypeaheadOptions(result);
|
512
513
|
}
|
513
514
|
this.typeaheadSearchState.pass();
|
@@ -37,10 +37,10 @@ import type { QueryBuilderExplorerTreeDragSource } from '../explorer/QueryBuilde
|
|
37
37
|
import { QueryBuilderPropertyExpressionState } from '../QueryBuilderPropertyEditorState.js';
|
38
38
|
import type { QueryBuilderState } from '../QueryBuilderState.js';
|
39
39
|
import {
|
40
|
-
type ExecutionResult,
|
41
|
-
AbstractPropertyExpression,
|
42
40
|
type ValueSpecification,
|
43
41
|
type Type,
|
42
|
+
type ExecutionResultWithMetadata,
|
43
|
+
AbstractPropertyExpression,
|
44
44
|
observe_ValueSpecification,
|
45
45
|
CollectionInstanceValue,
|
46
46
|
InstanceValue,
|
@@ -300,7 +300,7 @@ export class FilterConditionState implements Hashable {
|
|
300
300
|
);
|
301
301
|
const value = searchValue ?? rightConditionValue.value;
|
302
302
|
if (performTypeahead(value)) {
|
303
|
-
const result =
|
303
|
+
const result = (
|
304
304
|
(yield this.filterState.queryBuilderState.graphManagerState.graphManager.runQuery(
|
305
305
|
buildPropertyTypeaheadQuery(
|
306
306
|
this.filterState.queryBuilderState,
|
@@ -315,7 +315,8 @@ export class FilterConditionState implements Hashable {
|
|
315
315
|
.runtimeValue,
|
316
316
|
),
|
317
317
|
this.filterState.queryBuilderState.graphManagerState.graph,
|
318
|
-
)) as
|
318
|
+
)) as ExecutionResultWithMetadata
|
319
|
+
).executionResult;
|
319
320
|
this.typeaheadSearchResults = buildTypeaheadOptions(result);
|
320
321
|
}
|
321
322
|
this.typeaheadSearchState.pass();
|