@itwin/presentation-hierarchies 2.0.0-alpha.0 → 2.0.0-alpha.10
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/CHANGELOG.md +306 -7
- package/README.md +4 -22
- package/lib/cjs/hierarchies/HierarchyMerge.d.ts +19 -0
- package/lib/cjs/hierarchies/HierarchyMerge.d.ts.map +1 -0
- package/lib/cjs/hierarchies/HierarchyMerge.js +43 -0
- package/lib/cjs/hierarchies/HierarchyMerge.js.map +1 -0
- package/lib/cjs/hierarchies/HierarchyNode.d.ts +14 -24
- package/lib/cjs/hierarchies/HierarchyNode.d.ts.map +1 -1
- package/lib/cjs/hierarchies/HierarchyNode.js +1 -21
- package/lib/cjs/hierarchies/HierarchyNode.js.map +1 -1
- package/lib/cjs/hierarchies/HierarchyNodeKey.d.ts.map +1 -1
- package/lib/cjs/hierarchies/HierarchyNodeKey.js +8 -8
- package/lib/cjs/hierarchies/HierarchyNodeKey.js.map +1 -1
- package/lib/cjs/hierarchies/HierarchyProvider.d.ts +11 -29
- package/lib/cjs/hierarchies/HierarchyProvider.d.ts.map +1 -1
- package/lib/cjs/hierarchies/HierarchyProvider.js +0 -37
- package/lib/cjs/hierarchies/HierarchyProvider.js.map +1 -1
- package/lib/cjs/hierarchies/HierarchySearch.d.ts +167 -0
- package/lib/cjs/hierarchies/HierarchySearch.d.ts.map +1 -0
- package/lib/cjs/hierarchies/HierarchySearch.js +259 -0
- package/lib/cjs/hierarchies/HierarchySearch.js.map +1 -0
- package/lib/cjs/hierarchies/imodel/HierarchyCache.js +3 -3
- package/lib/cjs/hierarchies/imodel/HierarchyCache.js.map +1 -1
- package/lib/cjs/hierarchies/imodel/IModelHierarchyDefinition.d.ts +15 -4
- package/lib/cjs/hierarchies/imodel/IModelHierarchyDefinition.d.ts.map +1 -1
- package/lib/cjs/hierarchies/imodel/IModelHierarchyDefinition.js.map +1 -1
- package/lib/cjs/hierarchies/imodel/IModelHierarchyProvider.d.ts +46 -11
- package/lib/cjs/hierarchies/imodel/IModelHierarchyProvider.d.ts.map +1 -1
- package/lib/cjs/hierarchies/imodel/IModelHierarchyProvider.js +192 -72
- package/lib/cjs/hierarchies/imodel/IModelHierarchyProvider.js.map +1 -1
- package/lib/cjs/hierarchies/imodel/NodeSelectQueryFactory.d.ts +2 -2
- package/lib/cjs/hierarchies/imodel/NodeSelectQueryFactory.d.ts.map +1 -1
- package/lib/cjs/hierarchies/imodel/NodeSelectQueryFactory.js +99 -40
- package/lib/cjs/hierarchies/imodel/NodeSelectQueryFactory.js.map +1 -1
- package/lib/cjs/hierarchies/imodel/SearchHierarchyDefinition.d.ts +35 -0
- package/lib/cjs/hierarchies/imodel/SearchHierarchyDefinition.d.ts.map +1 -0
- package/lib/cjs/hierarchies/imodel/SearchHierarchyDefinition.js +285 -0
- package/lib/cjs/hierarchies/imodel/SearchHierarchyDefinition.js.map +1 -0
- package/lib/cjs/hierarchies/imodel/TreeNodesReader.d.ts +5 -7
- package/lib/cjs/hierarchies/imodel/TreeNodesReader.d.ts.map +1 -1
- package/lib/cjs/hierarchies/imodel/TreeNodesReader.js +15 -8
- package/lib/cjs/hierarchies/imodel/TreeNodesReader.js.map +1 -1
- package/lib/cjs/hierarchies/imodel/operators/HideIfNoChildren.d.ts.map +1 -1
- package/lib/cjs/hierarchies/imodel/operators/HideIfNoChildren.js +1 -0
- package/lib/cjs/hierarchies/imodel/operators/HideIfNoChildren.js.map +1 -1
- package/lib/cjs/hierarchies/imodel/operators/grouping/BaseClassGrouping.d.ts.map +1 -1
- package/lib/cjs/hierarchies/imodel/operators/grouping/BaseClassGrouping.js +6 -5
- package/lib/cjs/hierarchies/imodel/operators/grouping/BaseClassGrouping.js.map +1 -1
- package/lib/cjs/hierarchies/imodel/operators/grouping/ClassGrouping.d.ts.map +1 -1
- package/lib/cjs/hierarchies/imodel/operators/grouping/ClassGrouping.js +4 -3
- package/lib/cjs/hierarchies/imodel/operators/grouping/ClassGrouping.js.map +1 -1
- package/lib/cjs/hierarchies/imodel/operators/grouping/PropertiesGrouping.d.ts.map +1 -1
- package/lib/cjs/hierarchies/imodel/operators/grouping/PropertiesGrouping.js +21 -16
- package/lib/cjs/hierarchies/imodel/operators/grouping/PropertiesGrouping.js.map +1 -1
- package/lib/cjs/hierarchies/internal/Common.d.ts +3 -0
- package/lib/cjs/hierarchies/internal/Common.d.ts.map +1 -1
- package/lib/cjs/hierarchies/internal/Common.js +12 -1
- package/lib/cjs/hierarchies/internal/Common.js.map +1 -1
- package/lib/cjs/hierarchies/internal/EachValueFrom.d.ts.map +1 -1
- package/lib/cjs/hierarchies/internal/EachValueFrom.js +1 -0
- package/lib/cjs/hierarchies/internal/EachValueFrom.js.map +1 -1
- package/lib/cjs/hierarchies/internal/RxjsHierarchyDefinition.d.ts +68 -0
- package/lib/cjs/hierarchies/internal/RxjsHierarchyDefinition.d.ts.map +1 -0
- package/lib/cjs/hierarchies/internal/RxjsHierarchyDefinition.js +26 -0
- package/lib/cjs/hierarchies/internal/RxjsHierarchyDefinition.js.map +1 -0
- package/lib/cjs/presentation-hierarchies.d.ts +5 -4
- package/lib/cjs/presentation-hierarchies.d.ts.map +1 -1
- package/lib/cjs/presentation-hierarchies.js +7 -7
- package/lib/cjs/presentation-hierarchies.js.map +1 -1
- package/lib/esm/hierarchies/HierarchyMerge.d.ts +19 -0
- package/lib/esm/hierarchies/HierarchyMerge.d.ts.map +1 -0
- package/lib/esm/hierarchies/HierarchyMerge.js +40 -0
- package/lib/esm/hierarchies/HierarchyMerge.js.map +1 -0
- package/lib/esm/hierarchies/HierarchyNode.d.ts +14 -24
- package/lib/esm/hierarchies/HierarchyNode.d.ts.map +1 -1
- package/lib/esm/hierarchies/HierarchyNode.js +0 -20
- package/lib/esm/hierarchies/HierarchyNode.js.map +1 -1
- package/lib/esm/hierarchies/HierarchyNodeKey.d.ts.map +1 -1
- package/lib/esm/hierarchies/HierarchyNodeKey.js +9 -9
- package/lib/esm/hierarchies/HierarchyNodeKey.js.map +1 -1
- package/lib/esm/hierarchies/HierarchyProvider.d.ts +11 -29
- package/lib/esm/hierarchies/HierarchyProvider.d.ts.map +1 -1
- package/lib/esm/hierarchies/HierarchyProvider.js +1 -36
- package/lib/esm/hierarchies/HierarchyProvider.js.map +1 -1
- package/lib/esm/hierarchies/HierarchySearch.d.ts +167 -0
- package/lib/esm/hierarchies/HierarchySearch.d.ts.map +1 -0
- package/lib/esm/hierarchies/HierarchySearch.js +254 -0
- package/lib/esm/hierarchies/HierarchySearch.js.map +1 -0
- package/lib/esm/hierarchies/imodel/HierarchyCache.js +3 -3
- package/lib/esm/hierarchies/imodel/HierarchyCache.js.map +1 -1
- package/lib/esm/hierarchies/imodel/IModelHierarchyDefinition.d.ts +15 -4
- package/lib/esm/hierarchies/imodel/IModelHierarchyDefinition.d.ts.map +1 -1
- package/lib/esm/hierarchies/imodel/IModelHierarchyDefinition.js.map +1 -1
- package/lib/esm/hierarchies/imodel/IModelHierarchyProvider.d.ts +46 -11
- package/lib/esm/hierarchies/imodel/IModelHierarchyProvider.d.ts.map +1 -1
- package/lib/esm/hierarchies/imodel/IModelHierarchyProvider.js +194 -75
- package/lib/esm/hierarchies/imodel/IModelHierarchyProvider.js.map +1 -1
- package/lib/esm/hierarchies/imodel/NodeSelectQueryFactory.d.ts +2 -2
- package/lib/esm/hierarchies/imodel/NodeSelectQueryFactory.d.ts.map +1 -1
- package/lib/esm/hierarchies/imodel/NodeSelectQueryFactory.js +100 -41
- package/lib/esm/hierarchies/imodel/NodeSelectQueryFactory.js.map +1 -1
- package/lib/esm/hierarchies/imodel/SearchHierarchyDefinition.d.ts +35 -0
- package/lib/esm/hierarchies/imodel/SearchHierarchyDefinition.d.ts.map +1 -0
- package/lib/esm/hierarchies/imodel/SearchHierarchyDefinition.js +279 -0
- package/lib/esm/hierarchies/imodel/SearchHierarchyDefinition.js.map +1 -0
- package/lib/esm/hierarchies/imodel/TreeNodesReader.d.ts +5 -7
- package/lib/esm/hierarchies/imodel/TreeNodesReader.d.ts.map +1 -1
- package/lib/esm/hierarchies/imodel/TreeNodesReader.js +13 -7
- package/lib/esm/hierarchies/imodel/TreeNodesReader.js.map +1 -1
- package/lib/esm/hierarchies/imodel/operators/HideIfNoChildren.d.ts.map +1 -1
- package/lib/esm/hierarchies/imodel/operators/HideIfNoChildren.js +1 -0
- package/lib/esm/hierarchies/imodel/operators/HideIfNoChildren.js.map +1 -1
- package/lib/esm/hierarchies/imodel/operators/grouping/BaseClassGrouping.d.ts.map +1 -1
- package/lib/esm/hierarchies/imodel/operators/grouping/BaseClassGrouping.js +7 -6
- package/lib/esm/hierarchies/imodel/operators/grouping/BaseClassGrouping.js.map +1 -1
- package/lib/esm/hierarchies/imodel/operators/grouping/ClassGrouping.d.ts.map +1 -1
- package/lib/esm/hierarchies/imodel/operators/grouping/ClassGrouping.js +5 -4
- package/lib/esm/hierarchies/imodel/operators/grouping/ClassGrouping.js.map +1 -1
- package/lib/esm/hierarchies/imodel/operators/grouping/PropertiesGrouping.d.ts.map +1 -1
- package/lib/esm/hierarchies/imodel/operators/grouping/PropertiesGrouping.js +22 -17
- package/lib/esm/hierarchies/imodel/operators/grouping/PropertiesGrouping.js.map +1 -1
- package/lib/esm/hierarchies/internal/Common.d.ts +3 -0
- package/lib/esm/hierarchies/internal/Common.d.ts.map +1 -1
- package/lib/esm/hierarchies/internal/Common.js +11 -1
- package/lib/esm/hierarchies/internal/Common.js.map +1 -1
- package/lib/esm/hierarchies/internal/EachValueFrom.d.ts.map +1 -1
- package/lib/esm/hierarchies/internal/EachValueFrom.js +1 -0
- package/lib/esm/hierarchies/internal/EachValueFrom.js.map +1 -1
- package/lib/esm/hierarchies/internal/RxjsHierarchyDefinition.d.ts +68 -0
- package/lib/esm/hierarchies/internal/RxjsHierarchyDefinition.d.ts.map +1 -0
- package/lib/esm/hierarchies/internal/RxjsHierarchyDefinition.js +23 -0
- package/lib/esm/hierarchies/internal/RxjsHierarchyDefinition.js.map +1 -0
- package/lib/esm/presentation-hierarchies.d.ts +5 -4
- package/lib/esm/presentation-hierarchies.d.ts.map +1 -1
- package/lib/esm/presentation-hierarchies.js +3 -3
- package/lib/esm/presentation-hierarchies.js.map +1 -1
- package/package.json +19 -19
- package/lib/cjs/hierarchies/HierarchyFiltering.d.ts +0 -110
- package/lib/cjs/hierarchies/HierarchyFiltering.d.ts.map +0 -1
- package/lib/cjs/hierarchies/HierarchyFiltering.js +0 -210
- package/lib/cjs/hierarchies/HierarchyFiltering.js.map +0 -1
- package/lib/cjs/hierarchies/imodel/FilteringHierarchyDefinition.d.ts +0 -34
- package/lib/cjs/hierarchies/imodel/FilteringHierarchyDefinition.d.ts.map +0 -1
- package/lib/cjs/hierarchies/imodel/FilteringHierarchyDefinition.js +0 -270
- package/lib/cjs/hierarchies/imodel/FilteringHierarchyDefinition.js.map +0 -1
- package/lib/esm/hierarchies/HierarchyFiltering.d.ts +0 -110
- package/lib/esm/hierarchies/HierarchyFiltering.d.ts.map +0 -1
- package/lib/esm/hierarchies/HierarchyFiltering.js +0 -205
- package/lib/esm/hierarchies/HierarchyFiltering.js.map +0 -1
- package/lib/esm/hierarchies/imodel/FilteringHierarchyDefinition.d.ts +0 -34
- package/lib/esm/hierarchies/imodel/FilteringHierarchyDefinition.d.ts.map +0 -1
- package/lib/esm/hierarchies/imodel/FilteringHierarchyDefinition.js +0 -264
- package/lib/esm/hierarchies/imodel/FilteringHierarchyDefinition.js.map +0 -1
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*---------------------------------------------------------------------------------------------
|
|
3
|
-
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
-
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
-
*--------------------------------------------------------------------------------------------*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.ECSQL_COLUMN_NAME_FilterClassName = exports.ECSQL_COLUMN_NAME_FilterECInstanceId = exports.FilteringHierarchyDefinition = void 0;
|
|
8
|
-
exports.applyECInstanceIdsFilter = applyECInstanceIdsFilter;
|
|
9
|
-
exports.applyECInstanceIdsSelector = applyECInstanceIdsSelector;
|
|
10
|
-
const rxjs_1 = require("rxjs");
|
|
11
|
-
const HierarchyFiltering_js_1 = require("../HierarchyFiltering.js");
|
|
12
|
-
const HierarchyNodeIdentifier_js_1 = require("../HierarchyNodeIdentifier.js");
|
|
13
|
-
const Partition_js_1 = require("../internal/operators/Partition.js");
|
|
14
|
-
const IModelHierarchyDefinition_js_1 = require("./IModelHierarchyDefinition.js");
|
|
15
|
-
const IModelHierarchyNode_js_1 = require("./IModelHierarchyNode.js");
|
|
16
|
-
const NodeSelectQueryFactory_js_1 = require("./NodeSelectQueryFactory.js");
|
|
17
|
-
const TreeNodesReader_js_1 = require("./TreeNodesReader.js");
|
|
18
|
-
/** @internal */
|
|
19
|
-
class FilteringHierarchyDefinition {
|
|
20
|
-
_imodelAccess;
|
|
21
|
-
_source;
|
|
22
|
-
_nodeIdentifierPaths;
|
|
23
|
-
_nodesParser;
|
|
24
|
-
constructor(props) {
|
|
25
|
-
this._imodelAccess = props.imodelAccess;
|
|
26
|
-
this._source = props.source;
|
|
27
|
-
this._nodeIdentifierPaths = props.nodeIdentifierPaths;
|
|
28
|
-
this._nodesParser = props.nodesParser ?? this._source.parseNode ?? TreeNodesReader_js_1.defaultNodesParser;
|
|
29
|
-
}
|
|
30
|
-
get preProcessNode() {
|
|
31
|
-
return async (node) => {
|
|
32
|
-
const processedNode = this._source.preProcessNode ? await this._source.preProcessNode(node) : node;
|
|
33
|
-
if (processedNode?.processingParams?.hideInHierarchy && processedNode.filtering?.isFilterTarget && !processedNode.filtering.hasFilterTargetAncestor) {
|
|
34
|
-
// we want to hide target nodes if they have `hideInHierarchy` param, but only if they're not under another filter target
|
|
35
|
-
return undefined;
|
|
36
|
-
}
|
|
37
|
-
return processedNode;
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
shouldExpandGroupingNode(node) {
|
|
41
|
-
for (const child of node.children) {
|
|
42
|
-
/* c8 ignore next 3 */
|
|
43
|
-
if (!child.filtering) {
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
if (child.filtering.isFilterTarget) {
|
|
47
|
-
const childAutoExpand = child.filtering.filterTargetOptions?.autoExpand;
|
|
48
|
-
// If child is a filter target and is has no `autoExpand` flag, then it's always to be expanded.
|
|
49
|
-
if (childAutoExpand === true) {
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
// If it's not an object and not `true`, then it's falsy - continue looking
|
|
53
|
-
if (typeof childAutoExpand !== "object") {
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
// If grouping node's child has `autoExpandUntil` flag,
|
|
57
|
-
// auto-expand the grouping node only if it's depth is lower than that of the grouping node in associated with the target.
|
|
58
|
-
const nodeDepth = node.parentKeys.length;
|
|
59
|
-
const filterTargetDepth = childAutoExpand.depth;
|
|
60
|
-
if (nodeDepth < filterTargetDepth) {
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
if (!child.filtering.filteredChildrenIdentifierPaths) {
|
|
65
|
-
/* c8 ignore next */
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
for (const path of child.filtering.filteredChildrenIdentifierPaths) {
|
|
69
|
-
if ("path" in path && path.options?.autoExpand) {
|
|
70
|
-
return true;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
get postProcessNode() {
|
|
77
|
-
return async (node) => {
|
|
78
|
-
const processedNode = this._source.postProcessNode ? await this._source.postProcessNode(node) : node;
|
|
79
|
-
// instance nodes get the auto-expand flag in `parseNode`, but grouping ones need to be handled during post-processing
|
|
80
|
-
if (IModelHierarchyNode_js_1.ProcessedHierarchyNode.isGroupingNode(node) && this.shouldExpandGroupingNode(node)) {
|
|
81
|
-
Object.assign(processedNode, { autoExpand: true });
|
|
82
|
-
}
|
|
83
|
-
return processedNode;
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
get parseNode() {
|
|
87
|
-
return async (row, parentNode) => {
|
|
88
|
-
const parsedNode = await this._nodesParser(row);
|
|
89
|
-
const filteringHelper = (0, HierarchyFiltering_js_1.createHierarchyFilteringHelper)(this._nodeIdentifierPaths, parentNode);
|
|
90
|
-
const nodeExtraProps = row[exports.ECSQL_COLUMN_NAME_FilterECInstanceId] && row[exports.ECSQL_COLUMN_NAME_FilterClassName]
|
|
91
|
-
? await (async () => {
|
|
92
|
-
const rowInstanceKey = { className: row[exports.ECSQL_COLUMN_NAME_FilterClassName], id: row[exports.ECSQL_COLUMN_NAME_FilterECInstanceId] };
|
|
93
|
-
return filteringHelper.createChildNodePropsAsync({
|
|
94
|
-
pathMatcher: (identifier) => {
|
|
95
|
-
if (identifier.id !== rowInstanceKey.id) {
|
|
96
|
-
return false;
|
|
97
|
-
}
|
|
98
|
-
if (!HierarchyNodeIdentifier_js_1.HierarchyNodeIdentifier.isInstanceNodeIdentifier(identifier)) {
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
if (identifier.imodelKey && identifier.imodelKey !== this._imodelAccess.imodelKey) {
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
if (identifier.className === rowInstanceKey.className) {
|
|
105
|
-
return true;
|
|
106
|
-
}
|
|
107
|
-
return Promise.all([
|
|
108
|
-
this._imodelAccess.classDerivesFrom(identifier.className, rowInstanceKey.className),
|
|
109
|
-
this._imodelAccess.classDerivesFrom(rowInstanceKey.className, identifier.className),
|
|
110
|
-
]).then(([isDerivedFrom, isDerivedTo]) => isDerivedFrom || isDerivedTo);
|
|
111
|
-
},
|
|
112
|
-
});
|
|
113
|
-
})()
|
|
114
|
-
: undefined;
|
|
115
|
-
if (nodeExtraProps?.autoExpand) {
|
|
116
|
-
parsedNode.autoExpand = true;
|
|
117
|
-
}
|
|
118
|
-
if (nodeExtraProps?.filtering) {
|
|
119
|
-
parsedNode.filtering = nodeExtraProps.filtering;
|
|
120
|
-
}
|
|
121
|
-
return parsedNode;
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
async defineHierarchyLevel(props) {
|
|
125
|
-
const sourceDefinitions = await this._source.defineHierarchyLevel(props);
|
|
126
|
-
const filteringHelper = (0, HierarchyFiltering_js_1.createHierarchyFilteringHelper)(this._nodeIdentifierPaths, props.parentNode);
|
|
127
|
-
const childNodeFilteringIdentifiers = filteringHelper.getChildNodeFilteringIdentifiers();
|
|
128
|
-
if (!childNodeFilteringIdentifiers) {
|
|
129
|
-
return sourceDefinitions;
|
|
130
|
-
}
|
|
131
|
-
const [genericNodeDefinitions, instanceNodeDefinitions] = (0, Partition_js_1.partition)(sourceDefinitions, IModelHierarchyDefinition_js_1.HierarchyNodesDefinition.isGenericNode);
|
|
132
|
-
return (0, rxjs_1.firstValueFrom)((0, rxjs_1.merge)(genericNodeDefinitions.pipe((0, rxjs_1.map)((definition) => {
|
|
133
|
-
if (filteringHelper.hasFilterTargetAncestor ||
|
|
134
|
-
childNodeFilteringIdentifiers.some((identifier) => HierarchyNodeIdentifier_js_1.HierarchyNodeIdentifier.isGenericNodeIdentifier(identifier) &&
|
|
135
|
-
(!identifier.source || identifier.source === this._imodelAccess.imodelKey) &&
|
|
136
|
-
identifier.id === definition.node.key)) {
|
|
137
|
-
return {
|
|
138
|
-
...definition,
|
|
139
|
-
node: {
|
|
140
|
-
...definition.node,
|
|
141
|
-
...filteringHelper.createChildNodeProps({ pathMatcher: ({ id }) => id === definition.node.key }),
|
|
142
|
-
},
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
return undefined;
|
|
146
|
-
}), (0, rxjs_1.filter)((def) => !!def)), instanceNodeDefinitions.pipe((0, rxjs_1.mergeMap)((definition) => {
|
|
147
|
-
if (filteringHelper.hasFilterTargetAncestor) {
|
|
148
|
-
// if we have a filter target ancestor, we don't need to filter the definitions - we use all of them
|
|
149
|
-
return (0, rxjs_1.of)(applyECInstanceIdsSelector(definition));
|
|
150
|
-
}
|
|
151
|
-
return (0, rxjs_1.defer)(async () => {
|
|
152
|
-
const imodelAccess = this._imodelAccess;
|
|
153
|
-
const matches = new Map();
|
|
154
|
-
async function getEntries(x) {
|
|
155
|
-
let entries = matches.get(x.id);
|
|
156
|
-
if (!entries) {
|
|
157
|
-
entries = [];
|
|
158
|
-
matches.set(x.id, entries);
|
|
159
|
-
}
|
|
160
|
-
// make sure that we don't have path identifiers that only differ by class name, where
|
|
161
|
-
// class names are in the same class hierarchy, e.g.:
|
|
162
|
-
// [{ className: "bis.Element", id: "0x1" }, { className: "bis.Subject", id: "0x1" }]
|
|
163
|
-
// are actually the same instance, so we only need to keep one of them, or otherwise the query will
|
|
164
|
-
// duplicate it
|
|
165
|
-
for (const entry of entries) {
|
|
166
|
-
if (entry.className === x.className ||
|
|
167
|
-
(await imodelAccess.classDerivesFrom(entry.className, x.className)) ||
|
|
168
|
-
(await imodelAccess.classDerivesFrom(x.className, entry.className))) {
|
|
169
|
-
return undefined;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
return entries;
|
|
173
|
-
}
|
|
174
|
-
for (const id of childNodeFilteringIdentifiers) {
|
|
175
|
-
// take only identifiers that match the definition by type, source and class
|
|
176
|
-
if (!HierarchyNodeIdentifier_js_1.HierarchyNodeIdentifier.isInstanceNodeIdentifier(id)) {
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
if (id.imodelKey && id.imodelKey !== imodelAccess.imodelKey) {
|
|
180
|
-
continue;
|
|
181
|
-
}
|
|
182
|
-
if (id.className !== definition.fullClassName &&
|
|
183
|
-
!(await Promise.all([
|
|
184
|
-
imodelAccess.classDerivesFrom(id.className, definition.fullClassName),
|
|
185
|
-
imodelAccess.classDerivesFrom(definition.fullClassName, id.className),
|
|
186
|
-
]).then(([isDerivedFrom, isDerivedTo]) => isDerivedFrom || isDerivedTo))) {
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
const entriesTargetForPathIdentifier = await getEntries(id);
|
|
190
|
-
if (entriesTargetForPathIdentifier) {
|
|
191
|
-
entriesTargetForPathIdentifier.push(id);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return Array.from(matches.values()).flat();
|
|
195
|
-
}).pipe(
|
|
196
|
-
// only take definitions that have matching path identifiers
|
|
197
|
-
(0, rxjs_1.filter)((pathIdentifiers) => pathIdentifiers.length > 0),
|
|
198
|
-
// for each definition that we're going to use, apply query-level filter
|
|
199
|
-
(0, rxjs_1.map)((pathIdentifiers) => applyECInstanceIdsFilter(definition, pathIdentifiers)));
|
|
200
|
-
}))).pipe((0, rxjs_1.toArray)()));
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
exports.FilteringHierarchyDefinition = FilteringHierarchyDefinition;
|
|
204
|
-
/** @internal */
|
|
205
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
206
|
-
exports.ECSQL_COLUMN_NAME_FilterECInstanceId = "FilterECInstanceId";
|
|
207
|
-
/** @internal */
|
|
208
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
209
|
-
exports.ECSQL_COLUMN_NAME_FilterClassName = "FilterClassName";
|
|
210
|
-
function getClassECInstanceIds(filteredInstanceKeys) {
|
|
211
|
-
const classNameECInstanceIds = new Map();
|
|
212
|
-
for (const key of filteredInstanceKeys) {
|
|
213
|
-
const entry = classNameECInstanceIds.get(key.className);
|
|
214
|
-
if (entry === undefined) {
|
|
215
|
-
classNameECInstanceIds.set(key.className, [key.id]);
|
|
216
|
-
continue;
|
|
217
|
-
}
|
|
218
|
-
entry.push(key.id);
|
|
219
|
-
}
|
|
220
|
-
return classNameECInstanceIds;
|
|
221
|
-
}
|
|
222
|
-
/** @internal */
|
|
223
|
-
function applyECInstanceIdsFilter(def, filteredInstanceKeys) {
|
|
224
|
-
const instanceIdsByClass = getClassECInstanceIds(filteredInstanceKeys);
|
|
225
|
-
return {
|
|
226
|
-
...def,
|
|
227
|
-
query: {
|
|
228
|
-
...def.query,
|
|
229
|
-
ctes: [
|
|
230
|
-
...(def.query.ctes ?? []),
|
|
231
|
-
`FilteringInfo(ECInstanceId, FilterClassName) AS (
|
|
232
|
-
${Array.from(instanceIdsByClass)
|
|
233
|
-
.map(([className, ecInstanceIds]) => `
|
|
234
|
-
SELECT ECInstanceId, '${className}' AS FilterClassName
|
|
235
|
-
FROM ${className}
|
|
236
|
-
WHERE ECInstanceId IN (${ecInstanceIds.join(", ")})
|
|
237
|
-
`)
|
|
238
|
-
.join(" UNION ALL ")}
|
|
239
|
-
)`,
|
|
240
|
-
],
|
|
241
|
-
ecsql: `
|
|
242
|
-
SELECT
|
|
243
|
-
[q].*,
|
|
244
|
-
IdToHex([f].[ECInstanceId]) AS [${exports.ECSQL_COLUMN_NAME_FilterECInstanceId}],
|
|
245
|
-
[f].[FilterClassName] AS [${exports.ECSQL_COLUMN_NAME_FilterClassName}]
|
|
246
|
-
FROM (
|
|
247
|
-
${def.query.ecsql}
|
|
248
|
-
) [q]
|
|
249
|
-
JOIN FilteringInfo [f] ON [f].[ECInstanceId] = [q].[ECInstanceId]
|
|
250
|
-
`,
|
|
251
|
-
},
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
/** @internal */
|
|
255
|
-
function applyECInstanceIdsSelector(def) {
|
|
256
|
-
return {
|
|
257
|
-
...def,
|
|
258
|
-
query: {
|
|
259
|
-
...def.query,
|
|
260
|
-
ecsql: `
|
|
261
|
-
SELECT
|
|
262
|
-
[q].*,
|
|
263
|
-
IdToHex([q].[ECInstanceId]) AS [${exports.ECSQL_COLUMN_NAME_FilterECInstanceId}],
|
|
264
|
-
[q].[${NodeSelectQueryFactory_js_1.NodeSelectClauseColumnNames.FullClassName}] AS [${exports.ECSQL_COLUMN_NAME_FilterClassName}]
|
|
265
|
-
FROM (${def.query.ecsql}) [q]
|
|
266
|
-
`,
|
|
267
|
-
},
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
//# sourceMappingURL=FilteringHierarchyDefinition.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"FilteringHierarchyDefinition.js","sourceRoot":"","sources":["../../../../src/hierarchies/imodel/FilteringHierarchyDefinition.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { defer, filter, firstValueFrom, map, merge, mergeMap, of, toArray } from \"rxjs\";\nimport { Id64String } from \"@itwin/core-bentley\";\nimport { ECClassHierarchyInspector, InstanceKey } from \"@itwin/presentation-shared\";\nimport { createHierarchyFilteringHelper, HierarchyFilteringPath } from \"../HierarchyFiltering.js\";\nimport { HierarchyNodeIdentifier } from \"../HierarchyNodeIdentifier.js\";\nimport { IModelInstanceKey } from \"../HierarchyNodeKey.js\";\nimport { partition } from \"../internal/operators/Partition.js\";\nimport {\n DefineHierarchyLevelProps,\n GenericHierarchyNodeDefinition,\n HierarchyDefinition,\n HierarchyDefinitionParentNode,\n HierarchyLevelDefinition,\n HierarchyNodesDefinition,\n InstanceNodesQueryDefinition,\n NodeParser,\n NodePostProcessor,\n NodePreProcessor,\n} from \"./IModelHierarchyDefinition.js\";\nimport { ProcessedGroupingHierarchyNode, ProcessedHierarchyNode, SourceInstanceHierarchyNode } from \"./IModelHierarchyNode.js\";\nimport { NodeSelectClauseColumnNames } from \"./NodeSelectQueryFactory.js\";\nimport { defaultNodesParser } from \"./TreeNodesReader.js\";\n\ninterface FilteringHierarchyDefinitionProps {\n imodelAccess: ECClassHierarchyInspector & { imodelKey: string };\n source: HierarchyDefinition;\n nodeIdentifierPaths: HierarchyFilteringPath[];\n nodesParser?: NodeParser;\n}\n\n/** @internal */\nexport class FilteringHierarchyDefinition implements HierarchyDefinition {\n private _imodelAccess: ECClassHierarchyInspector & { imodelKey: string };\n private _source: HierarchyDefinition;\n private _nodeIdentifierPaths: HierarchyFilteringPath[];\n private _nodesParser: NodeParser;\n\n public constructor(props: FilteringHierarchyDefinitionProps) {\n this._imodelAccess = props.imodelAccess;\n this._source = props.source;\n this._nodeIdentifierPaths = props.nodeIdentifierPaths;\n this._nodesParser = props.nodesParser ?? this._source.parseNode ?? defaultNodesParser;\n }\n\n public get preProcessNode(): NodePreProcessor {\n return async (node) => {\n const processedNode = this._source.preProcessNode ? await this._source.preProcessNode(node) : node;\n if (processedNode?.processingParams?.hideInHierarchy && processedNode.filtering?.isFilterTarget && !processedNode.filtering.hasFilterTargetAncestor) {\n // we want to hide target nodes if they have `hideInHierarchy` param, but only if they're not under another filter target\n return undefined;\n }\n return processedNode;\n };\n }\n\n private shouldExpandGroupingNode(node: ProcessedGroupingHierarchyNode) {\n for (const child of node.children) {\n /* c8 ignore next 3 */\n if (!child.filtering) {\n continue;\n }\n\n if (child.filtering.isFilterTarget) {\n const childAutoExpand = child.filtering.filterTargetOptions?.autoExpand;\n\n // If child is a filter target and is has no `autoExpand` flag, then it's always to be expanded.\n if (childAutoExpand === true) {\n return true;\n }\n\n // If it's not an object and not `true`, then it's falsy - continue looking\n if (typeof childAutoExpand !== \"object\") {\n continue;\n }\n\n // If grouping node's child has `autoExpandUntil` flag,\n // auto-expand the grouping node only if it's depth is lower than that of the grouping node in associated with the target.\n const nodeDepth = node.parentKeys.length;\n const filterTargetDepth = childAutoExpand.depth;\n if (nodeDepth < filterTargetDepth) {\n return true;\n }\n }\n\n if (!child.filtering.filteredChildrenIdentifierPaths) {\n /* c8 ignore next */\n continue;\n }\n\n for (const path of child.filtering.filteredChildrenIdentifierPaths) {\n if (\"path\" in path && path.options?.autoExpand) {\n return true;\n }\n }\n }\n return false;\n }\n\n public get postProcessNode(): NodePostProcessor {\n return async (node: ProcessedHierarchyNode) => {\n const processedNode = this._source.postProcessNode ? await this._source.postProcessNode(node) : node;\n // instance nodes get the auto-expand flag in `parseNode`, but grouping ones need to be handled during post-processing\n if (ProcessedHierarchyNode.isGroupingNode(node) && this.shouldExpandGroupingNode(node)) {\n Object.assign(processedNode, { autoExpand: true });\n }\n return processedNode;\n };\n }\n\n public get parseNode(): NodeParser {\n return async (row: { [columnName: string]: any }, parentNode?: HierarchyDefinitionParentNode): Promise<SourceInstanceHierarchyNode> => {\n const parsedNode = await this._nodesParser(row);\n const filteringHelper = createHierarchyFilteringHelper(this._nodeIdentifierPaths, parentNode);\n const nodeExtraProps =\n row[ECSQL_COLUMN_NAME_FilterECInstanceId] && row[ECSQL_COLUMN_NAME_FilterClassName]\n ? await (async () => {\n const rowInstanceKey = { className: row[ECSQL_COLUMN_NAME_FilterClassName], id: row[ECSQL_COLUMN_NAME_FilterECInstanceId] };\n return filteringHelper.createChildNodePropsAsync({\n pathMatcher: (identifier): boolean | Promise<boolean> => {\n if (identifier.id !== rowInstanceKey.id) {\n return false;\n }\n if (!HierarchyNodeIdentifier.isInstanceNodeIdentifier(identifier)) {\n return false;\n }\n if (identifier.imodelKey && identifier.imodelKey !== this._imodelAccess.imodelKey) {\n return false;\n }\n if (identifier.className === rowInstanceKey.className) {\n return true;\n }\n return Promise.all([\n this._imodelAccess.classDerivesFrom(identifier.className, rowInstanceKey.className),\n this._imodelAccess.classDerivesFrom(rowInstanceKey.className, identifier.className),\n ]).then(([isDerivedFrom, isDerivedTo]) => isDerivedFrom || isDerivedTo);\n },\n });\n })()\n : undefined;\n if (nodeExtraProps?.autoExpand) {\n parsedNode.autoExpand = true;\n }\n if (nodeExtraProps?.filtering) {\n parsedNode.filtering = nodeExtraProps.filtering;\n }\n\n return parsedNode;\n };\n }\n\n public async defineHierarchyLevel(props: DefineHierarchyLevelProps): Promise<HierarchyLevelDefinition> {\n const sourceDefinitions = await this._source.defineHierarchyLevel(props);\n\n const filteringHelper = createHierarchyFilteringHelper(this._nodeIdentifierPaths, props.parentNode);\n const childNodeFilteringIdentifiers = filteringHelper.getChildNodeFilteringIdentifiers();\n if (!childNodeFilteringIdentifiers) {\n return sourceDefinitions;\n }\n\n const [genericNodeDefinitions, instanceNodeDefinitions] = partition(sourceDefinitions, HierarchyNodesDefinition.isGenericNode);\n return firstValueFrom(\n merge(\n genericNodeDefinitions.pipe(\n map((definition) => {\n if (\n filteringHelper.hasFilterTargetAncestor ||\n childNodeFilteringIdentifiers.some(\n (identifier) =>\n HierarchyNodeIdentifier.isGenericNodeIdentifier(identifier) &&\n (!identifier.source || identifier.source === this._imodelAccess.imodelKey) &&\n identifier.id === definition.node.key,\n )\n ) {\n return {\n ...definition,\n node: {\n ...definition.node,\n ...filteringHelper.createChildNodeProps({ pathMatcher: ({ id }) => id === definition.node.key }),\n },\n };\n }\n return undefined;\n }),\n filter((def): def is GenericHierarchyNodeDefinition => !!def),\n ),\n\n instanceNodeDefinitions.pipe(\n mergeMap((definition) => {\n if (filteringHelper.hasFilterTargetAncestor) {\n // if we have a filter target ancestor, we don't need to filter the definitions - we use all of them\n return of(applyECInstanceIdsSelector(definition));\n }\n return defer(async () => {\n const imodelAccess = this._imodelAccess;\n const matches = new Map<Id64String, IModelInstanceKey[]>();\n async function getEntries(x: IModelInstanceKey) {\n let entries = matches.get(x.id);\n if (!entries) {\n entries = [];\n matches.set(x.id, entries);\n }\n // make sure that we don't have path identifiers that only differ by class name, where\n // class names are in the same class hierarchy, e.g.:\n // [{ className: \"bis.Element\", id: \"0x1\" }, { className: \"bis.Subject\", id: \"0x1\" }]\n // are actually the same instance, so we only need to keep one of them, or otherwise the query will\n // duplicate it\n for (const entry of entries) {\n if (\n entry.className === x.className ||\n (await imodelAccess.classDerivesFrom(entry.className, x.className)) ||\n (await imodelAccess.classDerivesFrom(x.className, entry.className))\n ) {\n return undefined;\n }\n }\n return entries;\n }\n for (const id of childNodeFilteringIdentifiers) {\n // take only identifiers that match the definition by type, source and class\n if (!HierarchyNodeIdentifier.isInstanceNodeIdentifier(id)) {\n continue;\n }\n if (id.imodelKey && id.imodelKey !== imodelAccess.imodelKey) {\n continue;\n }\n if (\n id.className !== definition.fullClassName &&\n !(await Promise.all([\n imodelAccess.classDerivesFrom(id.className, definition.fullClassName),\n imodelAccess.classDerivesFrom(definition.fullClassName, id.className),\n ]).then(([isDerivedFrom, isDerivedTo]) => isDerivedFrom || isDerivedTo))\n ) {\n continue;\n }\n const entriesTargetForPathIdentifier = await getEntries(id);\n if (entriesTargetForPathIdentifier) {\n entriesTargetForPathIdentifier.push(id);\n }\n }\n return Array.from(matches.values()).flat();\n }).pipe(\n // only take definitions that have matching path identifiers\n filter((pathIdentifiers) => pathIdentifiers.length > 0),\n\n // for each definition that we're going to use, apply query-level filter\n map((pathIdentifiers) => applyECInstanceIdsFilter(definition, pathIdentifiers)),\n );\n }),\n ),\n ).pipe(toArray()),\n );\n }\n}\n\n/** @internal */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const ECSQL_COLUMN_NAME_FilterECInstanceId = \"FilterECInstanceId\";\n\n/** @internal */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const ECSQL_COLUMN_NAME_FilterClassName = \"FilterClassName\";\n\nfunction getClassECInstanceIds(filteredInstanceKeys: InstanceKey[]) {\n const classNameECInstanceIds = new Map<string, Id64String[]>();\n for (const key of filteredInstanceKeys) {\n const entry = classNameECInstanceIds.get(key.className);\n if (entry === undefined) {\n classNameECInstanceIds.set(key.className, [key.id]);\n continue;\n }\n entry.push(key.id);\n }\n return classNameECInstanceIds;\n}\n\n/** @internal */\nexport function applyECInstanceIdsFilter(def: InstanceNodesQueryDefinition, filteredInstanceKeys: InstanceKey[]): InstanceNodesQueryDefinition {\n const instanceIdsByClass = getClassECInstanceIds(filteredInstanceKeys);\n return {\n ...def,\n query: {\n ...def.query,\n ctes: [\n ...(def.query.ctes ?? []),\n `FilteringInfo(ECInstanceId, FilterClassName) AS (\n ${Array.from(instanceIdsByClass)\n .map(\n ([className, ecInstanceIds]) => `\n SELECT ECInstanceId, '${className}' AS FilterClassName\n FROM ${className}\n WHERE ECInstanceId IN (${ecInstanceIds.join(\", \")})\n `,\n )\n .join(\" UNION ALL \")}\n )`,\n ],\n ecsql: `\n SELECT\n [q].*,\n IdToHex([f].[ECInstanceId]) AS [${ECSQL_COLUMN_NAME_FilterECInstanceId}],\n [f].[FilterClassName] AS [${ECSQL_COLUMN_NAME_FilterClassName}]\n FROM (\n ${def.query.ecsql}\n ) [q]\n JOIN FilteringInfo [f] ON [f].[ECInstanceId] = [q].[ECInstanceId]\n `,\n },\n };\n}\n\n/** @internal */\nexport function applyECInstanceIdsSelector(def: InstanceNodesQueryDefinition): InstanceNodesQueryDefinition {\n return {\n ...def,\n query: {\n ...def.query,\n ecsql: `\n SELECT\n [q].*,\n IdToHex([q].[ECInstanceId]) AS [${ECSQL_COLUMN_NAME_FilterECInstanceId}],\n [q].[${NodeSelectClauseColumnNames.FullClassName}] AS [${ECSQL_COLUMN_NAME_FilterClassName}]\n FROM (${def.query.ecsql}) [q]\n `,\n },\n };\n}\n"]}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { HierarchyNode, NonGroupingHierarchyNode } from "./HierarchyNode.js";
|
|
2
|
-
import { HierarchyNodeIdentifier, HierarchyNodeIdentifiersPath } from "./HierarchyNodeIdentifier.js";
|
|
3
|
-
import { GenericNodeKey, GroupingNodeKey, InstancesNodeKey } from "./HierarchyNodeKey.js";
|
|
4
|
-
/** @public */
|
|
5
|
-
export interface FilterTargetGroupingNodeInfo {
|
|
6
|
-
/** Key of the grouping node. */
|
|
7
|
-
key: GroupingNodeKey;
|
|
8
|
-
/**
|
|
9
|
-
* Depth of the grouping node in the hierarchy.
|
|
10
|
-
* Generally, it can be retrieved from `parentKeys.length`.
|
|
11
|
-
*/
|
|
12
|
-
depth: number;
|
|
13
|
-
}
|
|
14
|
-
/** @public */
|
|
15
|
-
export interface HierarchyFilteringPathOptions {
|
|
16
|
-
/**
|
|
17
|
-
* This option specifies the way `autoExpand` flag should be assigned to nodes in the filtered hierarchy.
|
|
18
|
-
* - If it's `false` or `undefined`, nodes have no 'autoExpand' flag.
|
|
19
|
-
* - If it's `true`, then all nodes up to the filter target will have `autoExpand` flag.
|
|
20
|
-
* - If it's an instance of `FilterTargetGroupingNodeInfo`, then all nodes up to the grouping node that matches this property,
|
|
21
|
-
* will have `autoExpand` flag.
|
|
22
|
-
*/
|
|
23
|
-
autoExpand?: boolean | FilterTargetGroupingNodeInfo;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* A path of hierarchy node identifiers for filtering the hierarchy with additional options.
|
|
27
|
-
* @public
|
|
28
|
-
*/
|
|
29
|
-
export type HierarchyFilteringPath = HierarchyNodeIdentifiersPath | {
|
|
30
|
-
path: HierarchyNodeIdentifiersPath;
|
|
31
|
-
options?: HierarchyFilteringPathOptions;
|
|
32
|
-
};
|
|
33
|
-
/** @public */
|
|
34
|
-
export declare namespace HierarchyFilteringPath {
|
|
35
|
-
/**
|
|
36
|
-
* Normalizes the hierarchy filtering path to the object form.
|
|
37
|
-
* @public
|
|
38
|
-
*/
|
|
39
|
-
function normalize(source: HierarchyFilteringPath): Exclude<HierarchyFilteringPath, HierarchyNodeIdentifiersPath>;
|
|
40
|
-
/**
|
|
41
|
-
* Merges two given `HierarchyFilteringPathOptions` objects.
|
|
42
|
-
* - if both inputs are `undefined`, `undefined` is returned,
|
|
43
|
-
* - else if one of the inputs is `undefined`, the other one is returned.
|
|
44
|
-
* - else, merge each option individually.
|
|
45
|
-
*
|
|
46
|
-
* For the `autoExpand` attribute, the merge chooses to auto-expand as deep as the deepest input:
|
|
47
|
-
* - if any one of the inputs is `true`, return `true`,
|
|
48
|
-
* - else if both inputs are objects, return the one with the greater `depth` attribute.
|
|
49
|
-
* - else if one input is an object, return it.
|
|
50
|
-
* - else, return `false` or `undefined`.
|
|
51
|
-
*
|
|
52
|
-
* @public
|
|
53
|
-
*/
|
|
54
|
-
function mergeOptions(lhs: HierarchyFilteringPathOptions | undefined, rhs: HierarchyFilteringPathOptions | undefined): HierarchyFilteringPathOptions | undefined;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* An utility that extracts filtering properties from given root level filtering props or
|
|
58
|
-
* the parent node. Returns `undefined` if filtering props are not present.
|
|
59
|
-
* @public
|
|
60
|
-
* @deprecated in 1.3. Use `createHierarchyFilteringHelper` instead.
|
|
61
|
-
*/
|
|
62
|
-
export declare function extractFilteringProps(rootLevelFilteringProps: HierarchyFilteringPath[], parentNode: Pick<NonGroupingHierarchyNode, "filtering"> | undefined): {
|
|
63
|
-
filteredNodePaths: HierarchyFilteringPath[];
|
|
64
|
-
hasFilterTargetAncestor: boolean;
|
|
65
|
-
} | undefined;
|
|
66
|
-
/**
|
|
67
|
-
* Creates a set of utilities for making it easier to filter the given hierarchy
|
|
68
|
-
* level.
|
|
69
|
-
*
|
|
70
|
-
* @public
|
|
71
|
-
*/
|
|
72
|
-
export declare function createHierarchyFilteringHelper(rootLevelFilteringProps: HierarchyFilteringPath[] | undefined, parentNode: Pick<NonGroupingHierarchyNode, "filtering"> | undefined): {
|
|
73
|
-
/**
|
|
74
|
-
* Returns a flag indicating if the hierarchy level is filtered.
|
|
75
|
-
*/
|
|
76
|
-
hasFilter: boolean;
|
|
77
|
-
/**
|
|
78
|
-
* Returns a flag indicating whether this hierarchy level has an ancestor node
|
|
79
|
-
* that is a filter target. That generally means that this and all downstream hierarchy
|
|
80
|
-
* levels should be displayed without filter being applied to them, even if filter paths
|
|
81
|
-
* say otherwise.
|
|
82
|
-
*/
|
|
83
|
-
hasFilterTargetAncestor: boolean;
|
|
84
|
-
/**
|
|
85
|
-
* Returns a list of hierarchy node identifiers that apply specifically for this
|
|
86
|
-
* hierarchy level. Returns `undefined` if filtering is not applied to this level.
|
|
87
|
-
*/
|
|
88
|
-
getChildNodeFilteringIdentifiers: () => HierarchyNodeIdentifier[] | undefined;
|
|
89
|
-
/**
|
|
90
|
-
* When a hierarchy node is created for a filtered hierarchy level, it needs some attributes (e.g. `filtering`
|
|
91
|
-
* and `autoExpand`) to be set based on the filter paths and filtering options. This function calculates
|
|
92
|
-
* these props for a child node based on its key or path matcher.
|
|
93
|
-
*
|
|
94
|
-
* When using `pathMatcher` prop, callers have more flexibility to decide whether the given `HierarchyNodeIdentifier` applies
|
|
95
|
-
* to their node. For example, only some parts of the identifier can be checked for improved performance. Otherwise, the
|
|
96
|
-
* `nodeKey` prop can be used to check the whole identifier.
|
|
97
|
-
*/
|
|
98
|
-
createChildNodeProps: (props: {
|
|
99
|
-
nodeKey: InstancesNodeKey | GenericNodeKey;
|
|
100
|
-
} | {
|
|
101
|
-
pathMatcher: (identifier: HierarchyNodeIdentifier) => boolean;
|
|
102
|
-
}) => Pick<HierarchyNode, "filtering" | "autoExpand"> | undefined;
|
|
103
|
-
/**
|
|
104
|
-
* Similar to `createChildNodeProps`, but takes an async `pathMatcher` prop.
|
|
105
|
-
*/
|
|
106
|
-
createChildNodePropsAsync: (props: {
|
|
107
|
-
pathMatcher: (identifier: HierarchyNodeIdentifier) => boolean | Promise<boolean>;
|
|
108
|
-
}) => Promise<Pick<HierarchyNode, "filtering" | "autoExpand"> | undefined>;
|
|
109
|
-
};
|
|
110
|
-
//# sourceMappingURL=HierarchyFiltering.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HierarchyFiltering.d.ts","sourceRoot":"","sources":["../../../src/hierarchies/HierarchyFiltering.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AACrG,OAAO,EAAE,cAAc,EAAE,eAAe,EAAoB,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE5G,cAAc;AACd,MAAM,WAAW,4BAA4B;IAC3C,gCAAgC;IAChC,GAAG,EAAE,eAAe,CAAC;IAErB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED,cAAc;AACd,MAAM,WAAW,6BAA6B;IAC5C;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG,4BAA4B,CAAC;CACrD;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,4BAA4B,GAAG;IAAE,IAAI,EAAE,4BAA4B,CAAC;IAAC,OAAO,CAAC,EAAE,6BAA6B,CAAA;CAAE,CAAC;AACpJ,cAAc;AAEd,yBAAiB,sBAAsB,CAAC;IACtC;;;OAGG;IACH,SAAgB,SAAS,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,EAAE,4BAA4B,CAAC,CAKvH;IAED;;;;;;;;;;;;;OAaG;IACH,SAAgB,YAAY,CAC1B,GAAG,EAAE,6BAA6B,GAAG,SAAS,EAC9C,GAAG,EAAE,6BAA6B,GAAG,SAAS,GAC7C,6BAA6B,GAAG,SAAS,CAmB3C;CACF;AAED;;;;;GAKG;AAEH,wBAAgB,qBAAqB,CACnC,uBAAuB,EAAE,sBAAsB,EAAE,EACjD,UAAU,EAAE,IAAI,CAAC,wBAAwB,EAAE,WAAW,CAAC,GAAG,SAAS,GAEjE;IACE,iBAAiB,EAAE,sBAAsB,EAAE,CAAC;IAC5C,uBAAuB,EAAE,OAAO,CAAC;CAClC,GACD,SAAS,CAEZ;AAuBD;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,uBAAuB,EAAE,sBAAsB,EAAE,GAAG,SAAS,EAC7D,UAAU,EAAE,IAAI,CAAC,wBAAwB,EAAE,WAAW,CAAC,GAAG,SAAS;IAKjE;;OAEG;;IAGH;;;;;OAKG;;IAGH;;;OAGG;;IAWH;;;;;;;;OAQG;kCAGG;QACE,OAAO,EAAE,gBAAgB,GAAG,cAAc,CAAC;KAC5C,GACD;QACE,WAAW,EAAE,CAAC,UAAU,EAAE,uBAAuB,KAAK,OAAO,CAAC;KAC/D,KACJ,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,YAAY,CAAC,GAAG,SAAS;IAoB9D;;OAEG;uCACsC;QACvC,WAAW,EAAE,CAAC,UAAU,EAAE,uBAAuB,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAClF,KAAG,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,YAAY,CAAC,GAAG,SAAS,CAAC;EA2B3E"}
|
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
/*---------------------------------------------------------------------------------------------
|
|
2
|
-
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
-
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
-
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
import { HierarchyNodeIdentifier } from "./HierarchyNodeIdentifier.js";
|
|
6
|
-
import { HierarchyNodeKey } from "./HierarchyNodeKey.js";
|
|
7
|
-
/** @public */
|
|
8
|
-
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
9
|
-
export var HierarchyFilteringPath;
|
|
10
|
-
(function (HierarchyFilteringPath) {
|
|
11
|
-
/**
|
|
12
|
-
* Normalizes the hierarchy filtering path to the object form.
|
|
13
|
-
* @public
|
|
14
|
-
*/
|
|
15
|
-
function normalize(source) {
|
|
16
|
-
if (Array.isArray(source)) {
|
|
17
|
-
return { path: source };
|
|
18
|
-
}
|
|
19
|
-
return source;
|
|
20
|
-
}
|
|
21
|
-
HierarchyFilteringPath.normalize = normalize;
|
|
22
|
-
/**
|
|
23
|
-
* Merges two given `HierarchyFilteringPathOptions` objects.
|
|
24
|
-
* - if both inputs are `undefined`, `undefined` is returned,
|
|
25
|
-
* - else if one of the inputs is `undefined`, the other one is returned.
|
|
26
|
-
* - else, merge each option individually.
|
|
27
|
-
*
|
|
28
|
-
* For the `autoExpand` attribute, the merge chooses to auto-expand as deep as the deepest input:
|
|
29
|
-
* - if any one of the inputs is `true`, return `true`,
|
|
30
|
-
* - else if both inputs are objects, return the one with the greater `depth` attribute.
|
|
31
|
-
* - else if one input is an object, return it.
|
|
32
|
-
* - else, return `false` or `undefined`.
|
|
33
|
-
*
|
|
34
|
-
* @public
|
|
35
|
-
*/
|
|
36
|
-
function mergeOptions(lhs, rhs) {
|
|
37
|
-
if (!lhs || !rhs) {
|
|
38
|
-
return lhs ?? rhs;
|
|
39
|
-
}
|
|
40
|
-
return {
|
|
41
|
-
autoExpand: (() => {
|
|
42
|
-
if (rhs.autoExpand === true || lhs.autoExpand === true) {
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
if (typeof lhs.autoExpand === "object") {
|
|
46
|
-
if (typeof rhs.autoExpand === "object" && rhs.autoExpand.depth > lhs.autoExpand.depth) {
|
|
47
|
-
return rhs.autoExpand;
|
|
48
|
-
}
|
|
49
|
-
return lhs.autoExpand;
|
|
50
|
-
}
|
|
51
|
-
return rhs.autoExpand;
|
|
52
|
-
})(),
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
HierarchyFilteringPath.mergeOptions = mergeOptions;
|
|
56
|
-
})(HierarchyFilteringPath || (HierarchyFilteringPath = {}));
|
|
57
|
-
/**
|
|
58
|
-
* An utility that extracts filtering properties from given root level filtering props or
|
|
59
|
-
* the parent node. Returns `undefined` if filtering props are not present.
|
|
60
|
-
* @public
|
|
61
|
-
* @deprecated in 1.3. Use `createHierarchyFilteringHelper` instead.
|
|
62
|
-
*/
|
|
63
|
-
/* c8 ignore start */
|
|
64
|
-
export function extractFilteringProps(rootLevelFilteringProps, parentNode) {
|
|
65
|
-
return extractFilteringPropsInternal(rootLevelFilteringProps, parentNode);
|
|
66
|
-
}
|
|
67
|
-
/* c8 ignore end */
|
|
68
|
-
function extractFilteringPropsInternal(rootLevelFilteringProps, parentNode) {
|
|
69
|
-
if (!parentNode) {
|
|
70
|
-
return rootLevelFilteringProps ? { filteredNodePaths: rootLevelFilteringProps, hasFilterTargetAncestor: false } : undefined;
|
|
71
|
-
}
|
|
72
|
-
return parentNode.filtering?.filteredChildrenIdentifierPaths
|
|
73
|
-
? {
|
|
74
|
-
filteredNodePaths: parentNode.filtering.filteredChildrenIdentifierPaths,
|
|
75
|
-
hasFilterTargetAncestor: !!parentNode.filtering.hasFilterTargetAncestor || !!parentNode.filtering.isFilterTarget,
|
|
76
|
-
}
|
|
77
|
-
: undefined;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Creates a set of utilities for making it easier to filter the given hierarchy
|
|
81
|
-
* level.
|
|
82
|
-
*
|
|
83
|
-
* @public
|
|
84
|
-
*/
|
|
85
|
-
export function createHierarchyFilteringHelper(rootLevelFilteringProps, parentNode) {
|
|
86
|
-
const filteringProps = extractFilteringPropsInternal(rootLevelFilteringProps, parentNode);
|
|
87
|
-
const hasFilter = !!filteringProps;
|
|
88
|
-
return {
|
|
89
|
-
/**
|
|
90
|
-
* Returns a flag indicating if the hierarchy level is filtered.
|
|
91
|
-
*/
|
|
92
|
-
hasFilter,
|
|
93
|
-
/**
|
|
94
|
-
* Returns a flag indicating whether this hierarchy level has an ancestor node
|
|
95
|
-
* that is a filter target. That generally means that this and all downstream hierarchy
|
|
96
|
-
* levels should be displayed without filter being applied to them, even if filter paths
|
|
97
|
-
* say otherwise.
|
|
98
|
-
*/
|
|
99
|
-
hasFilterTargetAncestor: filteringProps?.hasFilterTargetAncestor ?? false,
|
|
100
|
-
/**
|
|
101
|
-
* Returns a list of hierarchy node identifiers that apply specifically for this
|
|
102
|
-
* hierarchy level. Returns `undefined` if filtering is not applied to this level.
|
|
103
|
-
*/
|
|
104
|
-
getChildNodeFilteringIdentifiers: () => {
|
|
105
|
-
if (!hasFilter) {
|
|
106
|
-
return undefined;
|
|
107
|
-
}
|
|
108
|
-
return filteringProps.filteredNodePaths
|
|
109
|
-
.map(HierarchyFilteringPath.normalize)
|
|
110
|
-
.filter(({ path }) => path.length > 0)
|
|
111
|
-
.map(({ path }) => path[0]);
|
|
112
|
-
},
|
|
113
|
-
/**
|
|
114
|
-
* When a hierarchy node is created for a filtered hierarchy level, it needs some attributes (e.g. `filtering`
|
|
115
|
-
* and `autoExpand`) to be set based on the filter paths and filtering options. This function calculates
|
|
116
|
-
* these props for a child node based on its key or path matcher.
|
|
117
|
-
*
|
|
118
|
-
* When using `pathMatcher` prop, callers have more flexibility to decide whether the given `HierarchyNodeIdentifier` applies
|
|
119
|
-
* to their node. For example, only some parts of the identifier can be checked for improved performance. Otherwise, the
|
|
120
|
-
* `nodeKey` prop can be used to check the whole identifier.
|
|
121
|
-
*/
|
|
122
|
-
createChildNodeProps: (props) => {
|
|
123
|
-
if (!hasFilter) {
|
|
124
|
-
return undefined;
|
|
125
|
-
}
|
|
126
|
-
const reducer = new MatchingFilteringPathsReducer(filteringProps?.hasFilterTargetAncestor);
|
|
127
|
-
filteringProps.filteredNodePaths.forEach((filteredPath) => {
|
|
128
|
-
const normalizedPath = HierarchyFilteringPath.normalize(filteredPath);
|
|
129
|
-
if ("nodeKey" in props &&
|
|
130
|
-
((HierarchyNodeKey.isGeneric(props.nodeKey) && HierarchyNodeIdentifier.equal(normalizedPath.path[0], props.nodeKey)) ||
|
|
131
|
-
(HierarchyNodeKey.isInstances(props.nodeKey) && props.nodeKey.instanceKeys.some((ik) => HierarchyNodeIdentifier.equal(normalizedPath.path[0], ik))))) {
|
|
132
|
-
reducer.accept(normalizedPath);
|
|
133
|
-
}
|
|
134
|
-
else if ("pathMatcher" in props && props.pathMatcher(normalizedPath.path[0])) {
|
|
135
|
-
reducer.accept(normalizedPath);
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
return reducer.getNodeProps();
|
|
139
|
-
},
|
|
140
|
-
/**
|
|
141
|
-
* Similar to `createChildNodeProps`, but takes an async `pathMatcher` prop.
|
|
142
|
-
*/
|
|
143
|
-
createChildNodePropsAsync: async (props) => {
|
|
144
|
-
if (!hasFilter) {
|
|
145
|
-
return undefined;
|
|
146
|
-
}
|
|
147
|
-
const reducer = new MatchingFilteringPathsReducer(filteringProps?.hasFilterTargetAncestor);
|
|
148
|
-
for (const filteredChildrenNodeIdentifierPath of filteringProps.filteredNodePaths) {
|
|
149
|
-
const normalizedPath = HierarchyFilteringPath.normalize(filteredChildrenNodeIdentifierPath);
|
|
150
|
-
/* c8 ignore next 3 */
|
|
151
|
-
if (normalizedPath.path.length === 0) {
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
const matchesPossiblyPromise = props.pathMatcher(normalizedPath.path[0]);
|
|
155
|
-
if (matchesPossiblyPromise instanceof Promise) {
|
|
156
|
-
if (!(await matchesPossiblyPromise)) {
|
|
157
|
-
continue;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
if (!matchesPossiblyPromise) {
|
|
161
|
-
continue;
|
|
162
|
-
}
|
|
163
|
-
reducer.accept(normalizedPath);
|
|
164
|
-
}
|
|
165
|
-
return reducer.getNodeProps();
|
|
166
|
-
},
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
class MatchingFilteringPathsReducer {
|
|
170
|
-
_hasFilterTargetAncestor;
|
|
171
|
-
_filteredChildrenIdentifierPaths = new Array();
|
|
172
|
-
_isFilterTarget = false;
|
|
173
|
-
_filterTargetOptions = undefined;
|
|
174
|
-
_needsAutoExpand = false;
|
|
175
|
-
constructor(_hasFilterTargetAncestor) {
|
|
176
|
-
this._hasFilterTargetAncestor = _hasFilterTargetAncestor;
|
|
177
|
-
}
|
|
178
|
-
accept({ path, options }) {
|
|
179
|
-
if (path.length === 1) {
|
|
180
|
-
this._isFilterTarget = true;
|
|
181
|
-
this._filterTargetOptions = HierarchyFilteringPath.mergeOptions(this._filterTargetOptions, options);
|
|
182
|
-
}
|
|
183
|
-
else if (path.length > 1) {
|
|
184
|
-
this._filteredChildrenIdentifierPaths.push({ path: path.slice(1), options });
|
|
185
|
-
if (options?.autoExpand) {
|
|
186
|
-
this._needsAutoExpand = true;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
getNodeProps() {
|
|
191
|
-
return {
|
|
192
|
-
...(this._hasFilterTargetAncestor || this._isFilterTarget || this._filteredChildrenIdentifierPaths.length > 0
|
|
193
|
-
? {
|
|
194
|
-
filtering: {
|
|
195
|
-
...(this._hasFilterTargetAncestor ? { hasFilterTargetAncestor: true } : undefined),
|
|
196
|
-
...(this._isFilterTarget ? { isFilterTarget: true, filterTargetOptions: this._filterTargetOptions } : undefined),
|
|
197
|
-
...(this._filteredChildrenIdentifierPaths.length > 0 ? { filteredChildrenIdentifierPaths: this._filteredChildrenIdentifierPaths } : undefined),
|
|
198
|
-
},
|
|
199
|
-
}
|
|
200
|
-
: undefined),
|
|
201
|
-
...(this._needsAutoExpand ? { autoExpand: true } : undefined),
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
//# sourceMappingURL=HierarchyFiltering.js.map
|