@itwin/presentation-hierarchies 2.0.0-alpha.1 → 2.0.0-alpha.3
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 +69 -0
- package/lib/cjs/hierarchies/HierarchyFiltering.d.ts +42 -16
- package/lib/cjs/hierarchies/HierarchyFiltering.d.ts.map +1 -1
- package/lib/cjs/hierarchies/HierarchyFiltering.js +59 -25
- package/lib/cjs/hierarchies/HierarchyFiltering.js.map +1 -1
- package/lib/cjs/hierarchies/imodel/FilteringHierarchyDefinition.d.ts +0 -1
- package/lib/cjs/hierarchies/imodel/FilteringHierarchyDefinition.d.ts.map +1 -1
- package/lib/cjs/hierarchies/imodel/FilteringHierarchyDefinition.js +37 -37
- package/lib/cjs/hierarchies/imodel/FilteringHierarchyDefinition.js.map +1 -1
- package/lib/esm/hierarchies/HierarchyFiltering.d.ts +42 -16
- package/lib/esm/hierarchies/HierarchyFiltering.d.ts.map +1 -1
- package/lib/esm/hierarchies/HierarchyFiltering.js +59 -25
- package/lib/esm/hierarchies/HierarchyFiltering.js.map +1 -1
- package/lib/esm/hierarchies/imodel/FilteringHierarchyDefinition.d.ts +0 -1
- package/lib/esm/hierarchies/imodel/FilteringHierarchyDefinition.d.ts.map +1 -1
- package/lib/esm/hierarchies/imodel/FilteringHierarchyDefinition.js +37 -37
- package/lib/esm/hierarchies/imodel/FilteringHierarchyDefinition.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @itwin/presentation-hierarchies
|
|
2
2
|
|
|
3
|
+
## 2.0.0-alpha.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1031](https://github.com/iTwin/presentation/pull/1031): Version bump
|
|
8
|
+
|
|
9
|
+
## 2.0.0-alpha.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#1005](https://github.com/iTwin/presentation/pull/1005): Removed deprecated `FilterTargetGroupingNodeInfo` interface.
|
|
14
|
+
|
|
3
15
|
## 2.0.0-alpha.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -32,6 +44,63 @@
|
|
|
32
44
|
- Updated dependencies:
|
|
33
45
|
- @itwin/presentation-shared@2.0.0-alpha.0
|
|
34
46
|
|
|
47
|
+
## 1.7.1
|
|
48
|
+
|
|
49
|
+
### Patch Changes
|
|
50
|
+
|
|
51
|
+
- [#1024](https://github.com/iTwin/presentation/pull/1024): Update `depthInPath` documentation. Clarified that it does not set auto-expand for node that is at `depthInPath` position.
|
|
52
|
+
|
|
53
|
+
## 1.7.0
|
|
54
|
+
|
|
55
|
+
### Minor Changes
|
|
56
|
+
|
|
57
|
+
- 8f7d200926b93e862276e1f978f6c891691e0dae: Refactored specifying the depth / level to which filtering path should be auto-expanded.
|
|
58
|
+
|
|
59
|
+
- Deprecated `FilteringPathAutoExpandOption` and `FilterTargetGroupingNodeInfo`.
|
|
60
|
+
- Added `FilteringPathAutoExpandDepthInPath` and `FilteringPathAutoExpandDepthInHierarchy` which should be used instead.
|
|
61
|
+
|
|
62
|
+
Migration:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
const pathExpandedToInstanceInPath: HierarchyFilteringPath = {
|
|
66
|
+
path: [instanceKey1, instanceKey2, instanceKey3],
|
|
67
|
+
options: {
|
|
68
|
+
// deprecated:
|
|
69
|
+
autoExpand: { depth: 1 },
|
|
70
|
+
// do this instead:
|
|
71
|
+
autoExpand: { depthInPath: 1 },
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const pathExpandedToGroupingNode: HierarchyFilteringPath = {
|
|
76
|
+
path: [instanceKey1, instanceKey2, instanceKey3],
|
|
77
|
+
options: {
|
|
78
|
+
// deprecated:
|
|
79
|
+
autoExpand: { depth: 1, key: groupingNodeKey },
|
|
80
|
+
// also deprecated:
|
|
81
|
+
autoExpand: { depth: 1, includeGroupingNodes: true },
|
|
82
|
+
// do this instead:
|
|
83
|
+
autoExpand: { depthInHierarchy: 1 },
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## 1.6.1
|
|
89
|
+
|
|
90
|
+
### Patch Changes
|
|
91
|
+
|
|
92
|
+
- [#1010](https://github.com/iTwin/presentation/pull/1010): Fixed `HierarchyFilteringPathOptions.autoExpand` depth option not working properly with grouping nodes. Added `includeGroupingNodes` attribute to `FilteringPathAutoExpandOption`, which allows auto-expanding only desired gouping nodes, when set together with `depth` value.
|
|
93
|
+
|
|
94
|
+
## 1.6.0
|
|
95
|
+
|
|
96
|
+
### Minor Changes
|
|
97
|
+
|
|
98
|
+
- 69a2db67917f84e99d532e8e9aabbc02ec262d91: `HierarchyFilteringPathOptions.autoExpand` is now of type:
|
|
99
|
+
```ts
|
|
100
|
+
autoExpand?: { depth: number } | boolean;
|
|
101
|
+
```
|
|
102
|
+
When `depth` is set, only nodes up to specified `depth` in `HierarchyFilteringPath` will have `autoExpand` option set.
|
|
103
|
+
|
|
35
104
|
## 1.5.1
|
|
36
105
|
|
|
37
106
|
### Patch Changes
|
|
@@ -1,15 +1,39 @@
|
|
|
1
1
|
import { HierarchyNode, NonGroupingHierarchyNode } from "./HierarchyNode.js";
|
|
2
2
|
import { HierarchyNodeIdentifier, HierarchyNodeIdentifiersPath } from "./HierarchyNodeIdentifier.js";
|
|
3
|
-
import { GenericNodeKey,
|
|
3
|
+
import { GenericNodeKey, InstancesNodeKey } from "./HierarchyNodeKey.js";
|
|
4
4
|
/** @public */
|
|
5
|
-
export interface
|
|
6
|
-
/** Key of the grouping node. */
|
|
7
|
-
key: GroupingNodeKey;
|
|
5
|
+
export interface FilteringPathAutoExpandDepthInPath {
|
|
8
6
|
/**
|
|
9
|
-
* Depth
|
|
10
|
-
*
|
|
7
|
+
* Depth that tells which nodes in the filtering path should be expanded.
|
|
8
|
+
*
|
|
9
|
+
* Use when you want to expand up to specific instance node and don't care about grouping nodes.
|
|
10
|
+
*
|
|
11
|
+
* **NOTE**: All nodes that are up to `depthInPath` will be expanded. Node at the `depthInPath` position won't be expanded.
|
|
12
|
+
*/
|
|
13
|
+
depthInPath: number;
|
|
14
|
+
}
|
|
15
|
+
/** @public */
|
|
16
|
+
export interface FilteringPathAutoExpandDepthInHierarchy {
|
|
17
|
+
/**
|
|
18
|
+
* Depth that tells which nodes in the hierarchy should be expanded.
|
|
19
|
+
*
|
|
20
|
+
* This should take into account the number of grouping nodes in hierarchy.
|
|
21
|
+
*
|
|
22
|
+
* * **Use case example:**
|
|
23
|
+
*
|
|
24
|
+
* You want to `autoExpand` only `Node1` and `GroupingNode1` in the following hierarchy:
|
|
25
|
+
* - Node1
|
|
26
|
+
* - GroupingNode1
|
|
27
|
+
* - GroupingNode2
|
|
28
|
+
* - Element1
|
|
29
|
+
* - Element2
|
|
30
|
+
* Then you provide `autoExpand: { depthInHierarchy: 2 }`
|
|
31
|
+
*
|
|
32
|
+
* To get the correct depth use `HierarchyNode.parentKeys.length`.
|
|
33
|
+
*
|
|
34
|
+
* **NOTE**: All nodes that are up to and including `depthInHierarchy` will be expanded.
|
|
11
35
|
*/
|
|
12
|
-
|
|
36
|
+
depthInHierarchy: number;
|
|
13
37
|
}
|
|
14
38
|
/** @public */
|
|
15
39
|
export interface HierarchyFilteringPathOptions {
|
|
@@ -17,10 +41,10 @@ export interface HierarchyFilteringPathOptions {
|
|
|
17
41
|
* This option specifies the way `autoExpand` flag should be assigned to nodes in the filtered hierarchy.
|
|
18
42
|
* - If it's `false` or `undefined`, nodes have no 'autoExpand' flag.
|
|
19
43
|
* - If it's `true`, then all nodes up to the filter target will have `autoExpand` flag.
|
|
20
|
-
* - If it's an instance of `
|
|
21
|
-
* will have `autoExpand` flag.
|
|
44
|
+
* - If it's an instance of `FilteringPathAutoExpandDepthInPath`, then all nodes up to `depthInPath` will have `autoExpand` flag.
|
|
45
|
+
* - If it's an instance of `FilteringPathAutoExpandDepthInHierarchy`, then all nodes up to and including `depthInHierarchy` will have `autoExpand` flag.
|
|
22
46
|
*/
|
|
23
|
-
autoExpand?: boolean |
|
|
47
|
+
autoExpand?: boolean | FilteringPathAutoExpandDepthInHierarchy | FilteringPathAutoExpandDepthInPath;
|
|
24
48
|
}
|
|
25
49
|
/**
|
|
26
50
|
* A path of hierarchy node identifiers for filtering the hierarchy with additional options.
|
|
@@ -45,9 +69,11 @@ export declare namespace HierarchyFilteringPath {
|
|
|
45
69
|
*
|
|
46
70
|
* For the `autoExpand` attribute, the merge chooses to auto-expand as deep as the deepest input:
|
|
47
71
|
* - if any one of the inputs is `true`, return `true`,
|
|
48
|
-
* - else if
|
|
49
|
-
* - else if
|
|
50
|
-
* - else
|
|
72
|
+
* - else if only one of the inputs is an object, return it,
|
|
73
|
+
* - else if both inputs are falsy, return `false` or `undefined`,
|
|
74
|
+
* - else:
|
|
75
|
+
* - if only one of the inputs has `includeGroupingNodes` set to `true` or `key` defined or `depthInHierarchy` set, return the other one,
|
|
76
|
+
* - else return the one with greater `depth`, `depthInPath` or `depthInHierarchy`.
|
|
51
77
|
*
|
|
52
78
|
* @public
|
|
53
79
|
*/
|
|
@@ -69,7 +95,7 @@ export declare function extractFilteringProps(rootLevelFilteringProps: Hierarchy
|
|
|
69
95
|
*
|
|
70
96
|
* @public
|
|
71
97
|
*/
|
|
72
|
-
export declare function createHierarchyFilteringHelper(rootLevelFilteringProps: HierarchyFilteringPath[] | undefined, parentNode: Pick<NonGroupingHierarchyNode, "filtering"> | undefined): {
|
|
98
|
+
export declare function createHierarchyFilteringHelper(rootLevelFilteringProps: HierarchyFilteringPath[] | undefined, parentNode: Pick<NonGroupingHierarchyNode, "filtering" | "parentKeys"> | undefined): {
|
|
73
99
|
/**
|
|
74
100
|
* Returns a flag indicating if the hierarchy level is filtered.
|
|
75
101
|
*/
|
|
@@ -99,12 +125,12 @@ export declare function createHierarchyFilteringHelper(rootLevelFilteringProps:
|
|
|
99
125
|
nodeKey: InstancesNodeKey | GenericNodeKey;
|
|
100
126
|
} | {
|
|
101
127
|
pathMatcher: (identifier: HierarchyNodeIdentifier) => boolean;
|
|
102
|
-
}) => Pick<HierarchyNode, "
|
|
128
|
+
}) => Pick<HierarchyNode, "autoExpand" | "filtering"> | undefined;
|
|
103
129
|
/**
|
|
104
130
|
* Similar to `createChildNodeProps`, but takes an async `pathMatcher` prop.
|
|
105
131
|
*/
|
|
106
132
|
createChildNodePropsAsync: (props: {
|
|
107
133
|
pathMatcher: (identifier: HierarchyNodeIdentifier) => boolean | Promise<boolean>;
|
|
108
|
-
}) => Promise<Pick<HierarchyNode, "
|
|
134
|
+
}) => Promise<Pick<HierarchyNode, "autoExpand" | "filtering"> | undefined> | Pick<HierarchyNode, "autoExpand" | "filtering"> | undefined;
|
|
109
135
|
};
|
|
110
136
|
//# sourceMappingURL=HierarchyFiltering.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,EAAoB,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE3F,cAAc;AACd,MAAM,WAAW,kCAAkC;IACjD;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,cAAc;AACd,MAAM,WAAW,uCAAuC;IACtD;;;;;;;;;;;;;;;;;;OAkBG;IACH,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,cAAc;AACd,MAAM,WAAW,6BAA6B;IAC5C;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG,uCAAuC,GAAG,kCAAkC,CAAC;CACrG;AAgCD;;;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;;;;;;;;;;;;;;;OAeG;IACH,SAAgB,YAAY,CAC1B,GAAG,EAAE,6BAA6B,GAAG,SAAS,EAC9C,GAAG,EAAE,6BAA6B,GAAG,SAAS,GAC7C,6BAA6B,GAAG,SAAS,CAQ3C;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,GAAG,YAAY,CAAC,GAAG,SAAS;IAKhF;;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,YAAY,GAAG,WAAW,CAAC,GAAG,SAAS;IAoB9D;;OAEG;uCACgC;QACjC,WAAW,EAAE,CAAC,UAAU,EAAE,uBAAuB,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KAClF,KAAG,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,GAAG,WAAW,CAAC,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,aAAa,EAAE,YAAY,GAAG,WAAW,CAAC,GAAG,SAAS;EAgCzI"}
|
|
@@ -9,6 +9,32 @@ exports.extractFilteringProps = extractFilteringProps;
|
|
|
9
9
|
exports.createHierarchyFilteringHelper = createHierarchyFilteringHelper;
|
|
10
10
|
const HierarchyNodeIdentifier_js_1 = require("./HierarchyNodeIdentifier.js");
|
|
11
11
|
const HierarchyNodeKey_js_1 = require("./HierarchyNodeKey.js");
|
|
12
|
+
var HierarchyFilteringPathOptions;
|
|
13
|
+
(function (HierarchyFilteringPathOptions) {
|
|
14
|
+
function mergeAutoExpandOptions(lhs, rhs) {
|
|
15
|
+
if (rhs === true || lhs === true) {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
if (!rhs || !lhs) {
|
|
19
|
+
return !!rhs ? rhs : lhs;
|
|
20
|
+
}
|
|
21
|
+
const lhsDepth = "depthInPath" in lhs ? lhs.depthInPath : lhs.depthInHierarchy;
|
|
22
|
+
const rhsDepth = "depthInPath" in rhs ? rhs.depthInPath : rhs.depthInHierarchy;
|
|
23
|
+
const isLhsDepthBasedOnPath = "depthInPath" in lhs;
|
|
24
|
+
const isRhsDepthBasedOnPath = "depthInPath" in rhs;
|
|
25
|
+
if (isLhsDepthBasedOnPath) {
|
|
26
|
+
if (isRhsDepthBasedOnPath) {
|
|
27
|
+
return lhsDepth > rhsDepth ? lhs : rhs;
|
|
28
|
+
}
|
|
29
|
+
return lhs;
|
|
30
|
+
}
|
|
31
|
+
if (isRhsDepthBasedOnPath) {
|
|
32
|
+
return rhs;
|
|
33
|
+
}
|
|
34
|
+
return lhsDepth > rhsDepth ? lhs : rhs;
|
|
35
|
+
}
|
|
36
|
+
HierarchyFilteringPathOptions.mergeAutoExpandOptions = mergeAutoExpandOptions;
|
|
37
|
+
})(HierarchyFilteringPathOptions || (HierarchyFilteringPathOptions = {}));
|
|
12
38
|
/** @public */
|
|
13
39
|
// eslint-disable-next-line @typescript-eslint/no-redeclare
|
|
14
40
|
var HierarchyFilteringPath;
|
|
@@ -32,9 +58,11 @@ var HierarchyFilteringPath;
|
|
|
32
58
|
*
|
|
33
59
|
* For the `autoExpand` attribute, the merge chooses to auto-expand as deep as the deepest input:
|
|
34
60
|
* - if any one of the inputs is `true`, return `true`,
|
|
35
|
-
* - else if
|
|
36
|
-
* - else if
|
|
37
|
-
* - else
|
|
61
|
+
* - else if only one of the inputs is an object, return it,
|
|
62
|
+
* - else if both inputs are falsy, return `false` or `undefined`,
|
|
63
|
+
* - else:
|
|
64
|
+
* - if only one of the inputs has `includeGroupingNodes` set to `true` or `key` defined or `depthInHierarchy` set, return the other one,
|
|
65
|
+
* - else return the one with greater `depth`, `depthInPath` or `depthInHierarchy`.
|
|
38
66
|
*
|
|
39
67
|
* @public
|
|
40
68
|
*/
|
|
@@ -43,18 +71,7 @@ var HierarchyFilteringPath;
|
|
|
43
71
|
return lhs ?? rhs;
|
|
44
72
|
}
|
|
45
73
|
return {
|
|
46
|
-
autoExpand: (
|
|
47
|
-
if (rhs.autoExpand === true || lhs.autoExpand === true) {
|
|
48
|
-
return true;
|
|
49
|
-
}
|
|
50
|
-
if (typeof lhs.autoExpand === "object") {
|
|
51
|
-
if (typeof rhs.autoExpand === "object" && rhs.autoExpand.depth > lhs.autoExpand.depth) {
|
|
52
|
-
return rhs.autoExpand;
|
|
53
|
-
}
|
|
54
|
-
return lhs.autoExpand;
|
|
55
|
-
}
|
|
56
|
-
return rhs.autoExpand;
|
|
57
|
-
})(),
|
|
74
|
+
autoExpand: HierarchyFilteringPathOptions.mergeAutoExpandOptions(lhs.autoExpand, rhs.autoExpand),
|
|
58
75
|
};
|
|
59
76
|
}
|
|
60
77
|
HierarchyFilteringPath.mergeOptions = mergeOptions;
|
|
@@ -140,7 +157,7 @@ function createHierarchyFilteringHelper(rootLevelFilteringProps, parentNode) {
|
|
|
140
157
|
reducer.accept(normalizedPath);
|
|
141
158
|
}
|
|
142
159
|
});
|
|
143
|
-
return reducer.getNodeProps();
|
|
160
|
+
return reducer.getNodeProps(parentNode);
|
|
144
161
|
},
|
|
145
162
|
/**
|
|
146
163
|
* Similar to `createChildNodeProps`, but takes an async `pathMatcher` prop.
|
|
@@ -168,11 +185,11 @@ function createHierarchyFilteringHelper(rootLevelFilteringProps, parentNode) {
|
|
|
168
185
|
reducer.accept(normalizedPath);
|
|
169
186
|
}
|
|
170
187
|
if (matchedPathPromises.length === 0) {
|
|
171
|
-
return reducer.getNodeProps();
|
|
188
|
+
return reducer.getNodeProps(parentNode);
|
|
172
189
|
}
|
|
173
190
|
return Promise.all(matchedPathPromises)
|
|
174
191
|
.then((matchedPath) => matchedPath.forEach((normalizedPath) => normalizedPath && reducer.accept(normalizedPath)))
|
|
175
|
-
.then(() => reducer.getNodeProps());
|
|
192
|
+
.then(() => reducer.getNodeProps(parentNode));
|
|
176
193
|
},
|
|
177
194
|
};
|
|
178
195
|
}
|
|
@@ -181,23 +198,40 @@ class MatchingFilteringPathsReducer {
|
|
|
181
198
|
_filteredChildrenIdentifierPaths = new Array();
|
|
182
199
|
_isFilterTarget = false;
|
|
183
200
|
_filterTargetOptions = undefined;
|
|
184
|
-
|
|
201
|
+
_autoExpandOption = false;
|
|
185
202
|
constructor(_hasFilterTargetAncestor) {
|
|
186
203
|
this._hasFilterTargetAncestor = _hasFilterTargetAncestor;
|
|
187
204
|
}
|
|
188
|
-
accept(
|
|
205
|
+
accept(normalizedPath) {
|
|
206
|
+
const { path, options } = normalizedPath;
|
|
189
207
|
if (path.length === 1) {
|
|
190
208
|
this._isFilterTarget = true;
|
|
191
209
|
this._filterTargetOptions = HierarchyFilteringPath.mergeOptions(this._filterTargetOptions, options);
|
|
192
210
|
}
|
|
193
211
|
else if (path.length > 1) {
|
|
194
212
|
this._filteredChildrenIdentifierPaths.push({ path: path.slice(1), options });
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
213
|
+
this._autoExpandOption = HierarchyFilteringPathOptions.mergeAutoExpandOptions(options?.autoExpand, this._autoExpandOption);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
getNeedsAutoExpand(parentNode) {
|
|
217
|
+
if (this._autoExpandOption === true) {
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
if (typeof this._autoExpandOption === "object") {
|
|
221
|
+
const parentLength = !parentNode
|
|
222
|
+
? 0
|
|
223
|
+
: "depthInHierarchy" in this._autoExpandOption
|
|
224
|
+
? 1 + parentNode.parentKeys.length
|
|
225
|
+
: 1 + parentNode.parentKeys.filter((key) => !HierarchyNodeKey_js_1.HierarchyNodeKey.isGrouping(key)).length;
|
|
226
|
+
const depth = "depthInHierarchy" in this._autoExpandOption
|
|
227
|
+
? this._autoExpandOption.depthInHierarchy
|
|
228
|
+
: // With `depthInPath` option we don't want to expand node that is at the `depthInPath` position
|
|
229
|
+
this._autoExpandOption.depthInPath - 1;
|
|
230
|
+
return parentLength < depth;
|
|
198
231
|
}
|
|
232
|
+
return false;
|
|
199
233
|
}
|
|
200
|
-
getNodeProps() {
|
|
234
|
+
getNodeProps(parentNode) {
|
|
201
235
|
return {
|
|
202
236
|
...(this._hasFilterTargetAncestor || this._isFilterTarget || this._filteredChildrenIdentifierPaths.length > 0
|
|
203
237
|
? {
|
|
@@ -208,7 +242,7 @@ class MatchingFilteringPathsReducer {
|
|
|
208
242
|
},
|
|
209
243
|
}
|
|
210
244
|
: undefined),
|
|
211
|
-
...(this.
|
|
245
|
+
...(this.getNeedsAutoExpand(parentNode) ? { autoExpand: true } : undefined),
|
|
212
246
|
};
|
|
213
247
|
}
|
|
214
248
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HierarchyFiltering.js","sourceRoot":"","sources":["../../../src/hierarchies/HierarchyFiltering.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 { HierarchyNode, NonGroupingHierarchyNode } from \"./HierarchyNode.js\";\nimport { HierarchyNodeIdentifier, HierarchyNodeIdentifiersPath } from \"./HierarchyNodeIdentifier.js\";\nimport { GenericNodeKey, GroupingNodeKey, HierarchyNodeKey, InstancesNodeKey } from \"./HierarchyNodeKey.js\";\n\n/** @public */\nexport interface FilterTargetGroupingNodeInfo {\n /** Key of the grouping node. */\n key: GroupingNodeKey;\n\n /**\n * Depth of the grouping node in the hierarchy.\n * Generally, it can be retrieved from `parentKeys.length`.\n */\n depth: number;\n}\n\n/** @public */\nexport interface HierarchyFilteringPathOptions {\n /**\n * This option specifies the way `autoExpand` flag should be assigned to nodes in the filtered hierarchy.\n * - If it's `false` or `undefined`, nodes have no 'autoExpand' flag.\n * - If it's `true`, then all nodes up to the filter target will have `autoExpand` flag.\n * - If it's an instance of `FilterTargetGroupingNodeInfo`, then all nodes up to the grouping node that matches this property,\n * will have `autoExpand` flag.\n */\n autoExpand?: boolean | FilterTargetGroupingNodeInfo;\n}\n\n/**\n * A path of hierarchy node identifiers for filtering the hierarchy with additional options.\n * @public\n */\nexport type HierarchyFilteringPath = HierarchyNodeIdentifiersPath | { path: HierarchyNodeIdentifiersPath; options?: HierarchyFilteringPathOptions };\n/** @public */\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace HierarchyFilteringPath {\n /**\n * Normalizes the hierarchy filtering path to the object form.\n * @public\n */\n export function normalize(source: HierarchyFilteringPath): Exclude<HierarchyFilteringPath, HierarchyNodeIdentifiersPath> {\n if (Array.isArray(source)) {\n return { path: source };\n }\n return source;\n }\n\n /**\n * Merges two given `HierarchyFilteringPathOptions` objects.\n * - if both inputs are `undefined`, `undefined` is returned,\n * - else if one of the inputs is `undefined`, the other one is returned.\n * - else, merge each option individually.\n *\n * For the `autoExpand` attribute, the merge chooses to auto-expand as deep as the deepest input:\n * - if any one of the inputs is `true`, return `true`,\n * - else if both inputs are objects, return the one with the greater `depth` attribute.\n * - else if one input is an object, return it.\n * - else, return `false` or `undefined`.\n *\n * @public\n */\n export function mergeOptions(\n lhs: HierarchyFilteringPathOptions | undefined,\n rhs: HierarchyFilteringPathOptions | undefined,\n ): HierarchyFilteringPathOptions | undefined {\n if (!lhs || !rhs) {\n return lhs ?? rhs;\n }\n\n return {\n autoExpand: ((): HierarchyFilteringPathOptions[\"autoExpand\"] => {\n if (rhs.autoExpand === true || lhs.autoExpand === true) {\n return true;\n }\n if (typeof lhs.autoExpand === \"object\") {\n if (typeof rhs.autoExpand === \"object\" && rhs.autoExpand.depth > lhs.autoExpand.depth) {\n return rhs.autoExpand;\n }\n return lhs.autoExpand;\n }\n return rhs.autoExpand;\n })(),\n };\n }\n}\n\n/**\n * An utility that extracts filtering properties from given root level filtering props or\n * the parent node. Returns `undefined` if filtering props are not present.\n * @public\n * @deprecated in 1.3. Use `createHierarchyFilteringHelper` instead.\n */\n/* c8 ignore start */\nexport function extractFilteringProps(\n rootLevelFilteringProps: HierarchyFilteringPath[],\n parentNode: Pick<NonGroupingHierarchyNode, \"filtering\"> | undefined,\n):\n | {\n filteredNodePaths: HierarchyFilteringPath[];\n hasFilterTargetAncestor: boolean;\n }\n | undefined {\n return extractFilteringPropsInternal(rootLevelFilteringProps, parentNode);\n}\n/* c8 ignore end */\n\nfunction extractFilteringPropsInternal(\n rootLevelFilteringProps: HierarchyFilteringPath[] | undefined,\n parentNode: Pick<NonGroupingHierarchyNode, \"filtering\"> | undefined,\n):\n | {\n filteredNodePaths: HierarchyFilteringPath[];\n hasFilterTargetAncestor: boolean;\n }\n | undefined {\n if (!parentNode) {\n return rootLevelFilteringProps ? { filteredNodePaths: rootLevelFilteringProps, hasFilterTargetAncestor: false } : undefined;\n }\n return parentNode.filtering?.filteredChildrenIdentifierPaths\n ? {\n filteredNodePaths: parentNode.filtering.filteredChildrenIdentifierPaths,\n hasFilterTargetAncestor: !!parentNode.filtering.hasFilterTargetAncestor || !!parentNode.filtering.isFilterTarget,\n }\n : undefined;\n}\n\n/**\n * Creates a set of utilities for making it easier to filter the given hierarchy\n * level.\n *\n * @public\n */\nexport function createHierarchyFilteringHelper(\n rootLevelFilteringProps: HierarchyFilteringPath[] | undefined,\n parentNode: Pick<NonGroupingHierarchyNode, \"filtering\"> | undefined,\n) {\n const filteringProps = extractFilteringPropsInternal(rootLevelFilteringProps, parentNode);\n const hasFilter = !!filteringProps;\n return {\n /**\n * Returns a flag indicating if the hierarchy level is filtered.\n */\n hasFilter,\n\n /**\n * Returns a flag indicating whether this hierarchy level has an ancestor node\n * that is a filter target. That generally means that this and all downstream hierarchy\n * levels should be displayed without filter being applied to them, even if filter paths\n * say otherwise.\n */\n hasFilterTargetAncestor: filteringProps?.hasFilterTargetAncestor ?? false,\n\n /**\n * Returns a list of hierarchy node identifiers that apply specifically for this\n * hierarchy level. Returns `undefined` if filtering is not applied to this level.\n */\n getChildNodeFilteringIdentifiers: () => {\n if (!hasFilter) {\n return undefined;\n }\n return filteringProps.filteredNodePaths\n .map(HierarchyFilteringPath.normalize)\n .filter(({ path }) => path.length > 0)\n .map(({ path }) => path[0]);\n },\n\n /**\n * When a hierarchy node is created for a filtered hierarchy level, it needs some attributes (e.g. `filtering`\n * and `autoExpand`) to be set based on the filter paths and filtering options. This function calculates\n * these props for a child node based on its key or path matcher.\n *\n * When using `pathMatcher` prop, callers have more flexibility to decide whether the given `HierarchyNodeIdentifier` applies\n * to their node. For example, only some parts of the identifier can be checked for improved performance. Otherwise, the\n * `nodeKey` prop can be used to check the whole identifier.\n */\n createChildNodeProps: (\n props:\n | {\n nodeKey: InstancesNodeKey | GenericNodeKey;\n }\n | {\n pathMatcher: (identifier: HierarchyNodeIdentifier) => boolean;\n },\n ): Pick<HierarchyNode, \"filtering\" | \"autoExpand\"> | undefined => {\n if (!hasFilter) {\n return undefined;\n }\n const reducer = new MatchingFilteringPathsReducer(filteringProps?.hasFilterTargetAncestor);\n filteringProps.filteredNodePaths.forEach((filteredPath) => {\n const normalizedPath = HierarchyFilteringPath.normalize(filteredPath);\n if (\n \"nodeKey\" in props &&\n ((HierarchyNodeKey.isGeneric(props.nodeKey) && HierarchyNodeIdentifier.equal(normalizedPath.path[0], props.nodeKey)) ||\n (HierarchyNodeKey.isInstances(props.nodeKey) && props.nodeKey.instanceKeys.some((ik) => HierarchyNodeIdentifier.equal(normalizedPath.path[0], ik))))\n ) {\n reducer.accept(normalizedPath);\n } else if (\"pathMatcher\" in props && props.pathMatcher(normalizedPath.path[0])) {\n reducer.accept(normalizedPath);\n }\n });\n return reducer.getNodeProps();\n },\n\n /**\n * Similar to `createChildNodeProps`, but takes an async `pathMatcher` prop.\n */\n createChildNodePropsAsync: (props: {\n pathMatcher: (identifier: HierarchyNodeIdentifier) => boolean | Promise<boolean>;\n }): Promise<Pick<HierarchyNode, \"filtering\" | \"autoExpand\"> | undefined> | Pick<HierarchyNode, \"filtering\" | \"autoExpand\"> | undefined => {\n if (!hasFilter) {\n return undefined;\n }\n const reducer = new MatchingFilteringPathsReducer(filteringProps?.hasFilterTargetAncestor);\n const matchedPathPromises = new Array<Promise<NormalizedFilteringPath | undefined>>();\n for (const filteredChildrenNodeIdentifierPath of filteringProps.filteredNodePaths) {\n const normalizedPath = HierarchyFilteringPath.normalize(filteredChildrenNodeIdentifierPath);\n /* c8 ignore next 3 */\n if (normalizedPath.path.length === 0) {\n continue;\n }\n\n const matchesPossiblyPromise = props.pathMatcher(normalizedPath.path[0]);\n if (matchesPossiblyPromise instanceof Promise) {\n matchedPathPromises.push(matchesPossiblyPromise.then((matches) => (matches ? normalizedPath : undefined)));\n continue;\n }\n if (!matchesPossiblyPromise) {\n continue;\n }\n\n reducer.accept(normalizedPath);\n }\n if (matchedPathPromises.length === 0) {\n return reducer.getNodeProps();\n }\n return Promise.all(matchedPathPromises)\n .then((matchedPath) => matchedPath.forEach((normalizedPath) => normalizedPath && reducer.accept(normalizedPath)))\n .then(() => reducer.getNodeProps());\n },\n };\n}\n\ntype NormalizedFilteringPath = ReturnType<(typeof HierarchyFilteringPath)[\"normalize\"]>;\n\nclass MatchingFilteringPathsReducer {\n private _filteredChildrenIdentifierPaths = new Array<NormalizedFilteringPath>();\n private _isFilterTarget = false;\n private _filterTargetOptions = undefined as HierarchyFilteringPathOptions | undefined;\n private _needsAutoExpand = false;\n\n public constructor(private _hasFilterTargetAncestor: boolean) {}\n\n public accept({ path, options }: NormalizedFilteringPath) {\n if (path.length === 1) {\n this._isFilterTarget = true;\n this._filterTargetOptions = HierarchyFilteringPath.mergeOptions(this._filterTargetOptions, options);\n } else if (path.length > 1) {\n this._filteredChildrenIdentifierPaths.push({ path: path.slice(1), options });\n if (options?.autoExpand) {\n this._needsAutoExpand = true;\n }\n }\n }\n public getNodeProps(): Pick<HierarchyNode, \"filtering\" | \"autoExpand\"> {\n return {\n ...(this._hasFilterTargetAncestor || this._isFilterTarget || this._filteredChildrenIdentifierPaths.length > 0\n ? {\n filtering: {\n ...(this._hasFilterTargetAncestor ? { hasFilterTargetAncestor: true } : undefined),\n ...(this._isFilterTarget ? { isFilterTarget: true, filterTargetOptions: this._filterTargetOptions } : undefined),\n ...(this._filteredChildrenIdentifierPaths.length > 0 ? { filteredChildrenIdentifierPaths: this._filteredChildrenIdentifierPaths } : undefined),\n },\n }\n : undefined),\n ...(this._needsAutoExpand ? { autoExpand: true } : undefined),\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"HierarchyFiltering.js","sourceRoot":"","sources":["../../../src/hierarchies/HierarchyFiltering.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 { HierarchyNode, NonGroupingHierarchyNode } from \"./HierarchyNode.js\";\nimport { HierarchyNodeIdentifier, HierarchyNodeIdentifiersPath } from \"./HierarchyNodeIdentifier.js\";\nimport { GenericNodeKey, HierarchyNodeKey, InstancesNodeKey } from \"./HierarchyNodeKey.js\";\n\n/** @public */\nexport interface FilteringPathAutoExpandDepthInPath {\n /**\n * Depth that tells which nodes in the filtering path should be expanded.\n *\n * Use when you want to expand up to specific instance node and don't care about grouping nodes.\n *\n * **NOTE**: All nodes that are up to `depthInPath` will be expanded. Node at the `depthInPath` position won't be expanded.\n */\n depthInPath: number;\n}\n\n/** @public */\nexport interface FilteringPathAutoExpandDepthInHierarchy {\n /**\n * Depth that tells which nodes in the hierarchy should be expanded.\n *\n * This should take into account the number of grouping nodes in hierarchy.\n *\n * * **Use case example:**\n *\n * You want to `autoExpand` only `Node1` and `GroupingNode1` in the following hierarchy:\n * - Node1\n * - GroupingNode1\n * - GroupingNode2\n * - Element1\n * - Element2\n * Then you provide `autoExpand: { depthInHierarchy: 2 }`\n *\n * To get the correct depth use `HierarchyNode.parentKeys.length`.\n *\n * **NOTE**: All nodes that are up to and including `depthInHierarchy` will be expanded.\n */\n depthInHierarchy: number;\n}\n\n/** @public */\nexport interface HierarchyFilteringPathOptions {\n /**\n * This option specifies the way `autoExpand` flag should be assigned to nodes in the filtered hierarchy.\n * - If it's `false` or `undefined`, nodes have no 'autoExpand' flag.\n * - If it's `true`, then all nodes up to the filter target will have `autoExpand` flag.\n * - If it's an instance of `FilteringPathAutoExpandDepthInPath`, then all nodes up to `depthInPath` will have `autoExpand` flag.\n * - If it's an instance of `FilteringPathAutoExpandDepthInHierarchy`, then all nodes up to and including `depthInHierarchy` will have `autoExpand` flag.\n */\n autoExpand?: boolean | FilteringPathAutoExpandDepthInHierarchy | FilteringPathAutoExpandDepthInPath;\n}\n\nnamespace HierarchyFilteringPathOptions {\n export function mergeAutoExpandOptions(\n lhs: HierarchyFilteringPathOptions[\"autoExpand\"],\n rhs: HierarchyFilteringPathOptions[\"autoExpand\"],\n ): HierarchyFilteringPathOptions[\"autoExpand\"] {\n if (rhs === true || lhs === true) {\n return true;\n }\n if (!rhs || !lhs) {\n return !!rhs ? rhs : lhs;\n }\n\n const lhsDepth = \"depthInPath\" in lhs ? lhs.depthInPath : lhs.depthInHierarchy;\n const rhsDepth = \"depthInPath\" in rhs ? rhs.depthInPath : rhs.depthInHierarchy;\n const isLhsDepthBasedOnPath = \"depthInPath\" in lhs;\n const isRhsDepthBasedOnPath = \"depthInPath\" in rhs;\n\n if (isLhsDepthBasedOnPath) {\n if (isRhsDepthBasedOnPath) {\n return lhsDepth > rhsDepth ? lhs : rhs;\n }\n return lhs;\n }\n if (isRhsDepthBasedOnPath) {\n return rhs;\n }\n return lhsDepth > rhsDepth ? lhs : rhs;\n }\n}\n\n/**\n * A path of hierarchy node identifiers for filtering the hierarchy with additional options.\n * @public\n */\nexport type HierarchyFilteringPath = HierarchyNodeIdentifiersPath | { path: HierarchyNodeIdentifiersPath; options?: HierarchyFilteringPathOptions };\n/** @public */\n// eslint-disable-next-line @typescript-eslint/no-redeclare\nexport namespace HierarchyFilteringPath {\n /**\n * Normalizes the hierarchy filtering path to the object form.\n * @public\n */\n export function normalize(source: HierarchyFilteringPath): Exclude<HierarchyFilteringPath, HierarchyNodeIdentifiersPath> {\n if (Array.isArray(source)) {\n return { path: source };\n }\n return source;\n }\n\n /**\n * Merges two given `HierarchyFilteringPathOptions` objects.\n * - if both inputs are `undefined`, `undefined` is returned,\n * - else if one of the inputs is `undefined`, the other one is returned.\n * - else, merge each option individually.\n *\n * For the `autoExpand` attribute, the merge chooses to auto-expand as deep as the deepest input:\n * - if any one of the inputs is `true`, return `true`,\n * - else if only one of the inputs is an object, return it,\n * - else if both inputs are falsy, return `false` or `undefined`,\n * - else:\n * - if only one of the inputs has `includeGroupingNodes` set to `true` or `key` defined or `depthInHierarchy` set, return the other one,\n * - else return the one with greater `depth`, `depthInPath` or `depthInHierarchy`.\n *\n * @public\n */\n export function mergeOptions(\n lhs: HierarchyFilteringPathOptions | undefined,\n rhs: HierarchyFilteringPathOptions | undefined,\n ): HierarchyFilteringPathOptions | undefined {\n if (!lhs || !rhs) {\n return lhs ?? rhs;\n }\n\n return {\n autoExpand: HierarchyFilteringPathOptions.mergeAutoExpandOptions(lhs.autoExpand, rhs.autoExpand),\n };\n }\n}\n\n/**\n * An utility that extracts filtering properties from given root level filtering props or\n * the parent node. Returns `undefined` if filtering props are not present.\n * @public\n * @deprecated in 1.3. Use `createHierarchyFilteringHelper` instead.\n */\n/* c8 ignore start */\nexport function extractFilteringProps(\n rootLevelFilteringProps: HierarchyFilteringPath[],\n parentNode: Pick<NonGroupingHierarchyNode, \"filtering\"> | undefined,\n):\n | {\n filteredNodePaths: HierarchyFilteringPath[];\n hasFilterTargetAncestor: boolean;\n }\n | undefined {\n return extractFilteringPropsInternal(rootLevelFilteringProps, parentNode);\n}\n/* c8 ignore end */\n\nfunction extractFilteringPropsInternal(\n rootLevelFilteringProps: HierarchyFilteringPath[] | undefined,\n parentNode: Pick<NonGroupingHierarchyNode, \"filtering\"> | undefined,\n):\n | {\n filteredNodePaths: HierarchyFilteringPath[];\n hasFilterTargetAncestor: boolean;\n }\n | undefined {\n if (!parentNode) {\n return rootLevelFilteringProps ? { filteredNodePaths: rootLevelFilteringProps, hasFilterTargetAncestor: false } : undefined;\n }\n return parentNode.filtering?.filteredChildrenIdentifierPaths\n ? {\n filteredNodePaths: parentNode.filtering.filteredChildrenIdentifierPaths,\n hasFilterTargetAncestor: !!parentNode.filtering.hasFilterTargetAncestor || !!parentNode.filtering.isFilterTarget,\n }\n : undefined;\n}\n\n/**\n * Creates a set of utilities for making it easier to filter the given hierarchy\n * level.\n *\n * @public\n */\nexport function createHierarchyFilteringHelper(\n rootLevelFilteringProps: HierarchyFilteringPath[] | undefined,\n parentNode: Pick<NonGroupingHierarchyNode, \"filtering\" | \"parentKeys\"> | undefined,\n) {\n const filteringProps = extractFilteringPropsInternal(rootLevelFilteringProps, parentNode);\n const hasFilter = !!filteringProps;\n return {\n /**\n * Returns a flag indicating if the hierarchy level is filtered.\n */\n hasFilter,\n\n /**\n * Returns a flag indicating whether this hierarchy level has an ancestor node\n * that is a filter target. That generally means that this and all downstream hierarchy\n * levels should be displayed without filter being applied to them, even if filter paths\n * say otherwise.\n */\n hasFilterTargetAncestor: filteringProps?.hasFilterTargetAncestor ?? false,\n\n /**\n * Returns a list of hierarchy node identifiers that apply specifically for this\n * hierarchy level. Returns `undefined` if filtering is not applied to this level.\n */\n getChildNodeFilteringIdentifiers: () => {\n if (!hasFilter) {\n return undefined;\n }\n return filteringProps.filteredNodePaths\n .map(HierarchyFilteringPath.normalize)\n .filter(({ path }) => path.length > 0)\n .map(({ path }) => path[0]);\n },\n\n /**\n * When a hierarchy node is created for a filtered hierarchy level, it needs some attributes (e.g. `filtering`\n * and `autoExpand`) to be set based on the filter paths and filtering options. This function calculates\n * these props for a child node based on its key or path matcher.\n *\n * When using `pathMatcher` prop, callers have more flexibility to decide whether the given `HierarchyNodeIdentifier` applies\n * to their node. For example, only some parts of the identifier can be checked for improved performance. Otherwise, the\n * `nodeKey` prop can be used to check the whole identifier.\n */\n createChildNodeProps: (\n props:\n | {\n nodeKey: InstancesNodeKey | GenericNodeKey;\n }\n | {\n pathMatcher: (identifier: HierarchyNodeIdentifier) => boolean;\n },\n ): Pick<HierarchyNode, \"autoExpand\" | \"filtering\"> | undefined => {\n if (!hasFilter) {\n return undefined;\n }\n const reducer = new MatchingFilteringPathsReducer(filteringProps?.hasFilterTargetAncestor);\n filteringProps.filteredNodePaths.forEach((filteredPath) => {\n const normalizedPath = HierarchyFilteringPath.normalize(filteredPath);\n if (\n \"nodeKey\" in props &&\n ((HierarchyNodeKey.isGeneric(props.nodeKey) && HierarchyNodeIdentifier.equal(normalizedPath.path[0], props.nodeKey)) ||\n (HierarchyNodeKey.isInstances(props.nodeKey) && props.nodeKey.instanceKeys.some((ik) => HierarchyNodeIdentifier.equal(normalizedPath.path[0], ik))))\n ) {\n reducer.accept(normalizedPath);\n } else if (\"pathMatcher\" in props && props.pathMatcher(normalizedPath.path[0])) {\n reducer.accept(normalizedPath);\n }\n });\n return reducer.getNodeProps(parentNode);\n },\n\n /**\n * Similar to `createChildNodeProps`, but takes an async `pathMatcher` prop.\n */\n createChildNodePropsAsync: (props: {\n pathMatcher: (identifier: HierarchyNodeIdentifier) => boolean | Promise<boolean>;\n }): Promise<Pick<HierarchyNode, \"autoExpand\" | \"filtering\"> | undefined> | Pick<HierarchyNode, \"autoExpand\" | \"filtering\"> | undefined => {\n if (!hasFilter) {\n return undefined;\n }\n const reducer = new MatchingFilteringPathsReducer(filteringProps?.hasFilterTargetAncestor);\n const matchedPathPromises = new Array<Promise<NormalizedFilteringPath | undefined>>();\n for (const filteredChildrenNodeIdentifierPath of filteringProps.filteredNodePaths) {\n const normalizedPath = HierarchyFilteringPath.normalize(filteredChildrenNodeIdentifierPath);\n /* c8 ignore next 3 */\n if (normalizedPath.path.length === 0) {\n continue;\n }\n\n const matchesPossiblyPromise = props.pathMatcher(normalizedPath.path[0]);\n if (matchesPossiblyPromise instanceof Promise) {\n matchedPathPromises.push(matchesPossiblyPromise.then((matches) => (matches ? normalizedPath : undefined)));\n continue;\n }\n if (!matchesPossiblyPromise) {\n continue;\n }\n\n reducer.accept(normalizedPath);\n }\n if (matchedPathPromises.length === 0) {\n return reducer.getNodeProps(parentNode);\n }\n return Promise.all(matchedPathPromises)\n .then((matchedPath) => matchedPath.forEach((normalizedPath) => normalizedPath && reducer.accept(normalizedPath)))\n .then(() => reducer.getNodeProps(parentNode));\n },\n };\n}\n\ntype NormalizedFilteringPath = ReturnType<(typeof HierarchyFilteringPath)[\"normalize\"]>;\n\nclass MatchingFilteringPathsReducer {\n private _filteredChildrenIdentifierPaths = new Array<NormalizedFilteringPath>();\n private _isFilterTarget = false;\n private _filterTargetOptions = undefined as HierarchyFilteringPathOptions | undefined;\n private _autoExpandOption: HierarchyFilteringPathOptions[\"autoExpand\"] = false;\n\n public constructor(private _hasFilterTargetAncestor: boolean) {}\n\n public accept(normalizedPath: NormalizedFilteringPath): void {\n const { path, options } = normalizedPath;\n if (path.length === 1) {\n this._isFilterTarget = true;\n this._filterTargetOptions = HierarchyFilteringPath.mergeOptions(this._filterTargetOptions, options);\n } else if (path.length > 1) {\n this._filteredChildrenIdentifierPaths.push({ path: path.slice(1), options });\n this._autoExpandOption = HierarchyFilteringPathOptions.mergeAutoExpandOptions(options?.autoExpand, this._autoExpandOption);\n }\n }\n\n private getNeedsAutoExpand(parentNode: Pick<NonGroupingHierarchyNode, \"parentKeys\"> | undefined): boolean {\n if (this._autoExpandOption === true) {\n return true;\n }\n if (typeof this._autoExpandOption === \"object\") {\n const parentLength = !parentNode\n ? 0\n : \"depthInHierarchy\" in this._autoExpandOption\n ? 1 + parentNode.parentKeys.length\n : 1 + parentNode.parentKeys.filter((key) => !HierarchyNodeKey.isGrouping(key)).length;\n const depth =\n \"depthInHierarchy\" in this._autoExpandOption\n ? this._autoExpandOption.depthInHierarchy\n : // With `depthInPath` option we don't want to expand node that is at the `depthInPath` position\n this._autoExpandOption.depthInPath - 1;\n\n return parentLength < depth;\n }\n return false;\n }\n\n public getNodeProps(parentNode: Pick<NonGroupingHierarchyNode, \"parentKeys\"> | undefined): Pick<HierarchyNode, \"autoExpand\" | \"filtering\"> {\n return {\n ...(this._hasFilterTargetAncestor || this._isFilterTarget || this._filteredChildrenIdentifierPaths.length > 0\n ? {\n filtering: {\n ...(this._hasFilterTargetAncestor ? { hasFilterTargetAncestor: true } : undefined),\n ...(this._isFilterTarget ? { isFilterTarget: true, filterTargetOptions: this._filterTargetOptions } : undefined),\n ...(this._filteredChildrenIdentifierPaths.length > 0 ? { filteredChildrenIdentifierPaths: this._filteredChildrenIdentifierPaths } : undefined),\n },\n }\n : undefined),\n ...(this.getNeedsAutoExpand(parentNode) ? { autoExpand: true } : undefined),\n };\n }\n}\n"]}
|
|
@@ -19,7 +19,6 @@ export declare class FilteringHierarchyDefinition implements RxjsHierarchyDefini
|
|
|
19
19
|
private _nodesParser;
|
|
20
20
|
constructor(props: FilteringHierarchyDefinitionProps);
|
|
21
21
|
get preProcessNode(): RxjsNodePreProcessor;
|
|
22
|
-
private shouldExpandGroupingNode;
|
|
23
22
|
get postProcessNode(): RxjsNodePostProcessor;
|
|
24
23
|
get parseNode(): RxjsNodeParser;
|
|
25
24
|
defineHierarchyLevel(props: DefineHierarchyLevelProps): Observable<HierarchyLevelDefinition>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilteringHierarchyDefinition.d.ts","sourceRoot":"","sources":["../../../../src/hierarchies/imodel/FilteringHierarchyDefinition.ts"],"names":[],"mappings":"AAKA,OAAO,EAAuD,UAAU,EAAe,MAAM,MAAM,CAAC;AAEpG,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAkC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"FilteringHierarchyDefinition.d.ts","sourceRoot":"","sources":["../../../../src/hierarchies/imodel/FilteringHierarchyDefinition.ts"],"names":[],"mappings":"AAKA,OAAO,EAAuD,UAAU,EAAe,MAAM,MAAM,CAAC;AAEpG,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACpF,OAAO,EAAkC,sBAAsB,EAAiC,MAAM,0BAA0B,CAAC;AAGjI,OAAO,EACL,yBAAyB,EAEzB,wBAAwB,EAExB,4BAA4B,EAC7B,MAAM,wCAAwC,CAAC;AAKhD,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAE9I,UAAU,iCAAiC;IACzC,YAAY,EAAE,yBAAyB,GAAG;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAChE,MAAM,EAAE,uBAAuB,CAAC;IAChC,mBAAmB,EAAE,sBAAsB,EAAE,CAAC;IAC9C,WAAW,CAAC,EAAE,cAAc,CAAC;CAC9B;AAED,gBAAgB;AAChB,qBAAa,4BAA6B,YAAW,uBAAuB;IAC1E,OAAO,CAAC,aAAa,CAAoD;IACzE,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,oBAAoB,CAA2B;IACvD,OAAO,CAAC,YAAY,CAAiB;gBAElB,KAAK,EAAE,iCAAiC;IAO3D,IAAW,cAAc,IAAI,oBAAoB,CAYhD;IAED,IAAW,eAAe,IAAI,qBAAqB,CAYlD;IAED,IAAW,SAAS,IAAI,cAAc,CA2CrC;IAEM,oBAAoB,CAAC,KAAK,EAAE,yBAAyB,GAAG,UAAU,CAAC,wBAAwB,CAAC;CAoGpG;AAED,gBAAgB;AAEhB,eAAO,MAAM,oCAAoC,uBAAuB,CAAC;AAEzE,gBAAgB;AAEhB,eAAO,MAAM,iCAAiC,oBAAoB,CAAC;AAenE,gBAAgB;AAChB,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,WAAW,EAAE,GAAG,4BAA4B,CAgC7I;AAED,gBAAgB;AAChB,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,4BAA4B,GAAG,4BAA4B,CAc1G"}
|
|
@@ -10,6 +10,7 @@ exports.applyECInstanceIdsSelector = applyECInstanceIdsSelector;
|
|
|
10
10
|
const rxjs_1 = require("rxjs");
|
|
11
11
|
const HierarchyFiltering_js_1 = require("../HierarchyFiltering.js");
|
|
12
12
|
const HierarchyNodeIdentifier_js_1 = require("../HierarchyNodeIdentifier.js");
|
|
13
|
+
const HierarchyNodeKey_js_1 = require("../HierarchyNodeKey.js");
|
|
13
14
|
const IModelHierarchyDefinition_js_1 = require("../imodel/IModelHierarchyDefinition.js");
|
|
14
15
|
const IModelHierarchyNode_js_1 = require("../imodel/IModelHierarchyNode.js");
|
|
15
16
|
const NodeSelectQueryFactory_js_1 = require("../imodel/NodeSelectQueryFactory.js");
|
|
@@ -38,47 +39,11 @@ class FilteringHierarchyDefinition {
|
|
|
38
39
|
}));
|
|
39
40
|
};
|
|
40
41
|
}
|
|
41
|
-
shouldExpandGroupingNode(node) {
|
|
42
|
-
for (const child of node.children) {
|
|
43
|
-
/* c8 ignore next 3 */
|
|
44
|
-
if (!child.filtering) {
|
|
45
|
-
continue;
|
|
46
|
-
}
|
|
47
|
-
if (child.filtering.isFilterTarget) {
|
|
48
|
-
const childAutoExpand = child.filtering.filterTargetOptions?.autoExpand;
|
|
49
|
-
// If child is a filter target and is has no `autoExpand` flag, then it's always to be expanded.
|
|
50
|
-
if (childAutoExpand === true) {
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
// If it's not an object and not `true`, then it's falsy - continue looking
|
|
54
|
-
if (typeof childAutoExpand !== "object") {
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
// If grouping node's child has `autoExpandUntil` flag,
|
|
58
|
-
// auto-expand the grouping node only if it's depth is lower than that of the grouping node in associated with the target.
|
|
59
|
-
const nodeDepth = node.parentKeys.length;
|
|
60
|
-
const filterTargetDepth = childAutoExpand.depth;
|
|
61
|
-
if (nodeDepth < filterTargetDepth) {
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (!child.filtering.filteredChildrenIdentifierPaths) {
|
|
66
|
-
/* c8 ignore next */
|
|
67
|
-
continue;
|
|
68
|
-
}
|
|
69
|
-
for (const path of child.filtering.filteredChildrenIdentifierPaths) {
|
|
70
|
-
if ("path" in path && path.options?.autoExpand) {
|
|
71
|
-
return true;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
42
|
get postProcessNode() {
|
|
78
43
|
return (node) => {
|
|
79
44
|
return (this._source.postProcessNode ? this._source.postProcessNode(node) : (0, rxjs_1.of)(node)).pipe((0, rxjs_1.map)((processedNode) => {
|
|
80
45
|
// instance nodes get the auto-expand flag in `parseNode`, but grouping ones need to be handled during post-processing
|
|
81
|
-
if (IModelHierarchyNode_js_1.ProcessedHierarchyNode.isGroupingNode(node) &&
|
|
46
|
+
if (IModelHierarchyNode_js_1.ProcessedHierarchyNode.isGroupingNode(node) && shouldExpandGroupingNode(node)) {
|
|
82
47
|
Object.assign(processedNode, { autoExpand: true });
|
|
83
48
|
}
|
|
84
49
|
return processedNode;
|
|
@@ -271,4 +236,39 @@ function applyECInstanceIdsSelector(def) {
|
|
|
271
236
|
},
|
|
272
237
|
};
|
|
273
238
|
}
|
|
239
|
+
function shouldExpandGroupingNode(node) {
|
|
240
|
+
const numberOfNonGroupingParentNodes = node.parentKeys.filter((key) => !HierarchyNodeKey_js_1.HierarchyNodeKey.isGrouping(key)).length;
|
|
241
|
+
for (const child of node.children) {
|
|
242
|
+
/* c8 ignore next 3 */
|
|
243
|
+
if (!child.filtering) {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
if (child.filtering.isFilterTarget &&
|
|
247
|
+
getAutoExpandAsTrueFalse(child.filtering.filterTargetOptions?.autoExpand, numberOfNonGroupingParentNodes, node.parentKeys.length)) {
|
|
248
|
+
return true;
|
|
249
|
+
}
|
|
250
|
+
if (!child.filtering.filteredChildrenIdentifierPaths) {
|
|
251
|
+
/* c8 ignore next */
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
for (const path of child.filtering.filteredChildrenIdentifierPaths) {
|
|
255
|
+
if ("path" in path && getAutoExpandAsTrueFalse(path.options?.autoExpand, numberOfNonGroupingParentNodes, node.parentKeys.length)) {
|
|
256
|
+
return true;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
function getAutoExpandAsTrueFalse(autoExpand, numberOfNonGroupingParentNodes, numberOfParentNodes) {
|
|
263
|
+
if (!autoExpand) {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
if (autoExpand === true) {
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
// auto-expand should be set to true only if parentKeys length is smaller than depth.
|
|
270
|
+
const nodeDepth = "depthInHierarchy" in autoExpand ? numberOfParentNodes : numberOfNonGroupingParentNodes;
|
|
271
|
+
const filterTargetDepth = "depthInPath" in autoExpand ? autoExpand.depthInPath : autoExpand.depthInHierarchy;
|
|
272
|
+
return nodeDepth < filterTargetDepth;
|
|
273
|
+
}
|
|
274
274
|
//# sourceMappingURL=FilteringHierarchyDefinition.js.map
|