@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.
Files changed (153) hide show
  1. package/CHANGELOG.md +306 -7
  2. package/README.md +4 -22
  3. package/lib/cjs/hierarchies/HierarchyMerge.d.ts +19 -0
  4. package/lib/cjs/hierarchies/HierarchyMerge.d.ts.map +1 -0
  5. package/lib/cjs/hierarchies/HierarchyMerge.js +43 -0
  6. package/lib/cjs/hierarchies/HierarchyMerge.js.map +1 -0
  7. package/lib/cjs/hierarchies/HierarchyNode.d.ts +14 -24
  8. package/lib/cjs/hierarchies/HierarchyNode.d.ts.map +1 -1
  9. package/lib/cjs/hierarchies/HierarchyNode.js +1 -21
  10. package/lib/cjs/hierarchies/HierarchyNode.js.map +1 -1
  11. package/lib/cjs/hierarchies/HierarchyNodeKey.d.ts.map +1 -1
  12. package/lib/cjs/hierarchies/HierarchyNodeKey.js +8 -8
  13. package/lib/cjs/hierarchies/HierarchyNodeKey.js.map +1 -1
  14. package/lib/cjs/hierarchies/HierarchyProvider.d.ts +11 -29
  15. package/lib/cjs/hierarchies/HierarchyProvider.d.ts.map +1 -1
  16. package/lib/cjs/hierarchies/HierarchyProvider.js +0 -37
  17. package/lib/cjs/hierarchies/HierarchyProvider.js.map +1 -1
  18. package/lib/cjs/hierarchies/HierarchySearch.d.ts +167 -0
  19. package/lib/cjs/hierarchies/HierarchySearch.d.ts.map +1 -0
  20. package/lib/cjs/hierarchies/HierarchySearch.js +259 -0
  21. package/lib/cjs/hierarchies/HierarchySearch.js.map +1 -0
  22. package/lib/cjs/hierarchies/imodel/HierarchyCache.js +3 -3
  23. package/lib/cjs/hierarchies/imodel/HierarchyCache.js.map +1 -1
  24. package/lib/cjs/hierarchies/imodel/IModelHierarchyDefinition.d.ts +15 -4
  25. package/lib/cjs/hierarchies/imodel/IModelHierarchyDefinition.d.ts.map +1 -1
  26. package/lib/cjs/hierarchies/imodel/IModelHierarchyDefinition.js.map +1 -1
  27. package/lib/cjs/hierarchies/imodel/IModelHierarchyProvider.d.ts +46 -11
  28. package/lib/cjs/hierarchies/imodel/IModelHierarchyProvider.d.ts.map +1 -1
  29. package/lib/cjs/hierarchies/imodel/IModelHierarchyProvider.js +192 -72
  30. package/lib/cjs/hierarchies/imodel/IModelHierarchyProvider.js.map +1 -1
  31. package/lib/cjs/hierarchies/imodel/NodeSelectQueryFactory.d.ts +2 -2
  32. package/lib/cjs/hierarchies/imodel/NodeSelectQueryFactory.d.ts.map +1 -1
  33. package/lib/cjs/hierarchies/imodel/NodeSelectQueryFactory.js +99 -40
  34. package/lib/cjs/hierarchies/imodel/NodeSelectQueryFactory.js.map +1 -1
  35. package/lib/cjs/hierarchies/imodel/SearchHierarchyDefinition.d.ts +35 -0
  36. package/lib/cjs/hierarchies/imodel/SearchHierarchyDefinition.d.ts.map +1 -0
  37. package/lib/cjs/hierarchies/imodel/SearchHierarchyDefinition.js +285 -0
  38. package/lib/cjs/hierarchies/imodel/SearchHierarchyDefinition.js.map +1 -0
  39. package/lib/cjs/hierarchies/imodel/TreeNodesReader.d.ts +5 -7
  40. package/lib/cjs/hierarchies/imodel/TreeNodesReader.d.ts.map +1 -1
  41. package/lib/cjs/hierarchies/imodel/TreeNodesReader.js +15 -8
  42. package/lib/cjs/hierarchies/imodel/TreeNodesReader.js.map +1 -1
  43. package/lib/cjs/hierarchies/imodel/operators/HideIfNoChildren.d.ts.map +1 -1
  44. package/lib/cjs/hierarchies/imodel/operators/HideIfNoChildren.js +1 -0
  45. package/lib/cjs/hierarchies/imodel/operators/HideIfNoChildren.js.map +1 -1
  46. package/lib/cjs/hierarchies/imodel/operators/grouping/BaseClassGrouping.d.ts.map +1 -1
  47. package/lib/cjs/hierarchies/imodel/operators/grouping/BaseClassGrouping.js +6 -5
  48. package/lib/cjs/hierarchies/imodel/operators/grouping/BaseClassGrouping.js.map +1 -1
  49. package/lib/cjs/hierarchies/imodel/operators/grouping/ClassGrouping.d.ts.map +1 -1
  50. package/lib/cjs/hierarchies/imodel/operators/grouping/ClassGrouping.js +4 -3
  51. package/lib/cjs/hierarchies/imodel/operators/grouping/ClassGrouping.js.map +1 -1
  52. package/lib/cjs/hierarchies/imodel/operators/grouping/PropertiesGrouping.d.ts.map +1 -1
  53. package/lib/cjs/hierarchies/imodel/operators/grouping/PropertiesGrouping.js +21 -16
  54. package/lib/cjs/hierarchies/imodel/operators/grouping/PropertiesGrouping.js.map +1 -1
  55. package/lib/cjs/hierarchies/internal/Common.d.ts +3 -0
  56. package/lib/cjs/hierarchies/internal/Common.d.ts.map +1 -1
  57. package/lib/cjs/hierarchies/internal/Common.js +12 -1
  58. package/lib/cjs/hierarchies/internal/Common.js.map +1 -1
  59. package/lib/cjs/hierarchies/internal/EachValueFrom.d.ts.map +1 -1
  60. package/lib/cjs/hierarchies/internal/EachValueFrom.js +1 -0
  61. package/lib/cjs/hierarchies/internal/EachValueFrom.js.map +1 -1
  62. package/lib/cjs/hierarchies/internal/RxjsHierarchyDefinition.d.ts +68 -0
  63. package/lib/cjs/hierarchies/internal/RxjsHierarchyDefinition.d.ts.map +1 -0
  64. package/lib/cjs/hierarchies/internal/RxjsHierarchyDefinition.js +26 -0
  65. package/lib/cjs/hierarchies/internal/RxjsHierarchyDefinition.js.map +1 -0
  66. package/lib/cjs/presentation-hierarchies.d.ts +5 -4
  67. package/lib/cjs/presentation-hierarchies.d.ts.map +1 -1
  68. package/lib/cjs/presentation-hierarchies.js +7 -7
  69. package/lib/cjs/presentation-hierarchies.js.map +1 -1
  70. package/lib/esm/hierarchies/HierarchyMerge.d.ts +19 -0
  71. package/lib/esm/hierarchies/HierarchyMerge.d.ts.map +1 -0
  72. package/lib/esm/hierarchies/HierarchyMerge.js +40 -0
  73. package/lib/esm/hierarchies/HierarchyMerge.js.map +1 -0
  74. package/lib/esm/hierarchies/HierarchyNode.d.ts +14 -24
  75. package/lib/esm/hierarchies/HierarchyNode.d.ts.map +1 -1
  76. package/lib/esm/hierarchies/HierarchyNode.js +0 -20
  77. package/lib/esm/hierarchies/HierarchyNode.js.map +1 -1
  78. package/lib/esm/hierarchies/HierarchyNodeKey.d.ts.map +1 -1
  79. package/lib/esm/hierarchies/HierarchyNodeKey.js +9 -9
  80. package/lib/esm/hierarchies/HierarchyNodeKey.js.map +1 -1
  81. package/lib/esm/hierarchies/HierarchyProvider.d.ts +11 -29
  82. package/lib/esm/hierarchies/HierarchyProvider.d.ts.map +1 -1
  83. package/lib/esm/hierarchies/HierarchyProvider.js +1 -36
  84. package/lib/esm/hierarchies/HierarchyProvider.js.map +1 -1
  85. package/lib/esm/hierarchies/HierarchySearch.d.ts +167 -0
  86. package/lib/esm/hierarchies/HierarchySearch.d.ts.map +1 -0
  87. package/lib/esm/hierarchies/HierarchySearch.js +254 -0
  88. package/lib/esm/hierarchies/HierarchySearch.js.map +1 -0
  89. package/lib/esm/hierarchies/imodel/HierarchyCache.js +3 -3
  90. package/lib/esm/hierarchies/imodel/HierarchyCache.js.map +1 -1
  91. package/lib/esm/hierarchies/imodel/IModelHierarchyDefinition.d.ts +15 -4
  92. package/lib/esm/hierarchies/imodel/IModelHierarchyDefinition.d.ts.map +1 -1
  93. package/lib/esm/hierarchies/imodel/IModelHierarchyDefinition.js.map +1 -1
  94. package/lib/esm/hierarchies/imodel/IModelHierarchyProvider.d.ts +46 -11
  95. package/lib/esm/hierarchies/imodel/IModelHierarchyProvider.d.ts.map +1 -1
  96. package/lib/esm/hierarchies/imodel/IModelHierarchyProvider.js +194 -75
  97. package/lib/esm/hierarchies/imodel/IModelHierarchyProvider.js.map +1 -1
  98. package/lib/esm/hierarchies/imodel/NodeSelectQueryFactory.d.ts +2 -2
  99. package/lib/esm/hierarchies/imodel/NodeSelectQueryFactory.d.ts.map +1 -1
  100. package/lib/esm/hierarchies/imodel/NodeSelectQueryFactory.js +100 -41
  101. package/lib/esm/hierarchies/imodel/NodeSelectQueryFactory.js.map +1 -1
  102. package/lib/esm/hierarchies/imodel/SearchHierarchyDefinition.d.ts +35 -0
  103. package/lib/esm/hierarchies/imodel/SearchHierarchyDefinition.d.ts.map +1 -0
  104. package/lib/esm/hierarchies/imodel/SearchHierarchyDefinition.js +279 -0
  105. package/lib/esm/hierarchies/imodel/SearchHierarchyDefinition.js.map +1 -0
  106. package/lib/esm/hierarchies/imodel/TreeNodesReader.d.ts +5 -7
  107. package/lib/esm/hierarchies/imodel/TreeNodesReader.d.ts.map +1 -1
  108. package/lib/esm/hierarchies/imodel/TreeNodesReader.js +13 -7
  109. package/lib/esm/hierarchies/imodel/TreeNodesReader.js.map +1 -1
  110. package/lib/esm/hierarchies/imodel/operators/HideIfNoChildren.d.ts.map +1 -1
  111. package/lib/esm/hierarchies/imodel/operators/HideIfNoChildren.js +1 -0
  112. package/lib/esm/hierarchies/imodel/operators/HideIfNoChildren.js.map +1 -1
  113. package/lib/esm/hierarchies/imodel/operators/grouping/BaseClassGrouping.d.ts.map +1 -1
  114. package/lib/esm/hierarchies/imodel/operators/grouping/BaseClassGrouping.js +7 -6
  115. package/lib/esm/hierarchies/imodel/operators/grouping/BaseClassGrouping.js.map +1 -1
  116. package/lib/esm/hierarchies/imodel/operators/grouping/ClassGrouping.d.ts.map +1 -1
  117. package/lib/esm/hierarchies/imodel/operators/grouping/ClassGrouping.js +5 -4
  118. package/lib/esm/hierarchies/imodel/operators/grouping/ClassGrouping.js.map +1 -1
  119. package/lib/esm/hierarchies/imodel/operators/grouping/PropertiesGrouping.d.ts.map +1 -1
  120. package/lib/esm/hierarchies/imodel/operators/grouping/PropertiesGrouping.js +22 -17
  121. package/lib/esm/hierarchies/imodel/operators/grouping/PropertiesGrouping.js.map +1 -1
  122. package/lib/esm/hierarchies/internal/Common.d.ts +3 -0
  123. package/lib/esm/hierarchies/internal/Common.d.ts.map +1 -1
  124. package/lib/esm/hierarchies/internal/Common.js +11 -1
  125. package/lib/esm/hierarchies/internal/Common.js.map +1 -1
  126. package/lib/esm/hierarchies/internal/EachValueFrom.d.ts.map +1 -1
  127. package/lib/esm/hierarchies/internal/EachValueFrom.js +1 -0
  128. package/lib/esm/hierarchies/internal/EachValueFrom.js.map +1 -1
  129. package/lib/esm/hierarchies/internal/RxjsHierarchyDefinition.d.ts +68 -0
  130. package/lib/esm/hierarchies/internal/RxjsHierarchyDefinition.d.ts.map +1 -0
  131. package/lib/esm/hierarchies/internal/RxjsHierarchyDefinition.js +23 -0
  132. package/lib/esm/hierarchies/internal/RxjsHierarchyDefinition.js.map +1 -0
  133. package/lib/esm/presentation-hierarchies.d.ts +5 -4
  134. package/lib/esm/presentation-hierarchies.d.ts.map +1 -1
  135. package/lib/esm/presentation-hierarchies.js +3 -3
  136. package/lib/esm/presentation-hierarchies.js.map +1 -1
  137. package/package.json +19 -19
  138. package/lib/cjs/hierarchies/HierarchyFiltering.d.ts +0 -110
  139. package/lib/cjs/hierarchies/HierarchyFiltering.d.ts.map +0 -1
  140. package/lib/cjs/hierarchies/HierarchyFiltering.js +0 -210
  141. package/lib/cjs/hierarchies/HierarchyFiltering.js.map +0 -1
  142. package/lib/cjs/hierarchies/imodel/FilteringHierarchyDefinition.d.ts +0 -34
  143. package/lib/cjs/hierarchies/imodel/FilteringHierarchyDefinition.d.ts.map +0 -1
  144. package/lib/cjs/hierarchies/imodel/FilteringHierarchyDefinition.js +0 -270
  145. package/lib/cjs/hierarchies/imodel/FilteringHierarchyDefinition.js.map +0 -1
  146. package/lib/esm/hierarchies/HierarchyFiltering.d.ts +0 -110
  147. package/lib/esm/hierarchies/HierarchyFiltering.d.ts.map +0 -1
  148. package/lib/esm/hierarchies/HierarchyFiltering.js +0 -205
  149. package/lib/esm/hierarchies/HierarchyFiltering.js.map +0 -1
  150. package/lib/esm/hierarchies/imodel/FilteringHierarchyDefinition.d.ts +0 -34
  151. package/lib/esm/hierarchies/imodel/FilteringHierarchyDefinition.d.ts.map +0 -1
  152. package/lib/esm/hierarchies/imodel/FilteringHierarchyDefinition.js +0 -264
  153. 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