@itwin/tree-widget-react 3.15.1 → 3.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -2
- package/lib/cjs/tree-widget-react/TreeWidget.d.ts +1 -2
- package/lib/cjs/tree-widget-react/TreeWidget.js +12 -12
- package/lib/cjs/tree-widget-react/TreeWidget.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/CategoriesTreeButtons.d.ts +2 -3
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/CategoriesTreeButtons.js +5 -4
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/CategoriesTreeButtons.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.d.ts +4 -7
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.js +39 -31
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/UseCategoriesTree.js +6 -2
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/UseCategoriesTree.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.d.ts +3 -11
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.js +45 -36
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/internal/CategoriesVisibilityHandler.d.ts +1 -3
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/internal/CategoriesVisibilityHandler.js +30 -30
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/internal/CategoriesVisibilityHandler.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.d.ts +2 -7
- package/lib/cjs/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.js +8 -21
- package/lib/cjs/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/internal/useTreeHooks/UseIdsCache.d.ts +3 -0
- package/lib/cjs/tree-widget-react/components/trees/common/internal/useTreeHooks/UseIdsCache.js +7 -7
- package/lib/cjs/tree-widget-react/components/trees/common/internal/useTreeHooks/UseIdsCache.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/useGuid.d.ts +2 -0
- package/lib/cjs/tree-widget-react/components/trees/common/useGuid.js +14 -0
- package/lib/cjs/tree-widget-react/components/trees/common/useGuid.js.map +1 -0
- package/lib/cjs/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTree.js +4 -1
- package/lib/cjs/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTree.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeDefinition.d.ts +4 -6
- package/lib/cjs/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeDefinition.js +31 -26
- package/lib/cjs/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeDefinition.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/imodel-content-tree/IModelContentTree.d.ts +1 -1
- package/lib/cjs/tree-widget-react/components/trees/imodel-content-tree/IModelContentTree.js +4 -2
- package/lib/cjs/tree-widget-react/components/trees/imodel-content-tree/IModelContentTree.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.d.ts +1 -5
- package/lib/cjs/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.js +44 -44
- package/lib/cjs/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/imodel-content-tree/internal/IModelContentTreeIdsCache.d.ts +3 -6
- package/lib/cjs/tree-widget-react/components/trees/imodel-content-tree/internal/IModelContentTreeIdsCache.js +20 -16
- package/lib/cjs/tree-widget-react/components/trees/imodel-content-tree/internal/IModelContentTreeIdsCache.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/models-tree/ModelsTreeButtons.js +3 -1
- package/lib/cjs/tree-widget-react/components/trees/models-tree/ModelsTreeButtons.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.d.ts +6 -10
- package/lib/cjs/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.js +107 -64
- package/lib/cjs/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/models-tree/UseModelsTree.js +18 -8
- package/lib/cjs/tree-widget-react/components/trees/models-tree/UseModelsTree.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/models-tree/Utils.d.ts +24 -0
- package/lib/cjs/tree-widget-react/components/trees/models-tree/Utils.js +46 -0
- package/lib/cjs/tree-widget-react/components/trees/models-tree/Utils.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.d.ts +40 -9
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.js +68 -39
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/FilteredTree.d.ts +13 -5
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/FilteredTree.js +20 -14
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/FilteredTree.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.d.ts +4 -13
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js +62 -60
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.d.ts +6 -2
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js +155 -177
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js.map +1 -1
- package/lib/esm/tree-widget-react/TreeWidget.d.ts +1 -2
- package/lib/esm/tree-widget-react/TreeWidget.js +12 -12
- package/lib/esm/tree-widget-react/TreeWidget.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeButtons.d.ts +2 -3
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeButtons.js +5 -3
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeButtons.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.d.ts +4 -7
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.js +39 -31
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/UseCategoriesTree.js +6 -2
- package/lib/esm/tree-widget-react/components/trees/categories-tree/UseCategoriesTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.d.ts +3 -11
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.js +45 -36
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesVisibilityHandler.d.ts +1 -3
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesVisibilityHandler.js +30 -30
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesVisibilityHandler.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.d.ts +2 -7
- package/lib/esm/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.js +8 -20
- package/lib/esm/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/internal/useTreeHooks/UseIdsCache.d.ts +3 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/useTreeHooks/UseIdsCache.js +7 -7
- package/lib/esm/tree-widget-react/components/trees/common/internal/useTreeHooks/UseIdsCache.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/useGuid.d.ts +2 -0
- package/lib/esm/tree-widget-react/components/trees/common/useGuid.js +11 -0
- package/lib/esm/tree-widget-react/components/trees/common/useGuid.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTree.js +4 -1
- package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeDefinition.d.ts +4 -6
- package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeDefinition.js +31 -26
- package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeDefinition.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTree.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTree.js +4 -2
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.d.ts +1 -5
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.js +44 -44
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/internal/IModelContentTreeIdsCache.d.ts +3 -6
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/internal/IModelContentTreeIdsCache.js +21 -17
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/internal/IModelContentTreeIdsCache.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeButtons.js +3 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeButtons.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.d.ts +6 -10
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.js +107 -64
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/UseModelsTree.js +18 -8
- package/lib/esm/tree-widget-react/components/trees/models-tree/UseModelsTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/Utils.d.ts +24 -0
- package/lib/esm/tree-widget-react/components/trees/models-tree/Utils.js +44 -0
- package/lib/esm/tree-widget-react/components/trees/models-tree/Utils.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.d.ts +40 -9
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.js +70 -41
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/FilteredTree.d.ts +13 -5
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/FilteredTree.js +22 -16
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/FilteredTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.d.ts +4 -13
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js +63 -61
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.d.ts +6 -2
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js +157 -179
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js.map +1 -1
- package/package.json +8 -8
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import { bufferCount, defaultIfEmpty, defer, firstValueFrom, from, fromEvent, identity, lastValueFrom, map, merge, mergeAll, mergeMap, reduce, switchMap, takeUntil, toArray, } from "rxjs";
|
|
6
|
+
import { Guid } from "@itwin/core-bentley";
|
|
6
7
|
import { IModel } from "@itwin/core-common";
|
|
7
8
|
import { createNodesQueryClauseFactory, createPredicateBasedHierarchyDefinition, HierarchyFilteringPath, NodeSelectClauseColumnNames, ProcessedHierarchyNode, } from "@itwin/presentation-hierarchies";
|
|
8
9
|
import { createBisInstanceLabelSelectClauseFactory, ECSql } from "@itwin/presentation-shared";
|
|
@@ -28,18 +29,20 @@ export var ModelsTreeInstanceKeyPathsProps;
|
|
|
28
29
|
ModelsTreeInstanceKeyPathsProps.isLabelProps = isLabelProps;
|
|
29
30
|
})(ModelsTreeInstanceKeyPathsProps || (ModelsTreeInstanceKeyPathsProps = {}));
|
|
30
31
|
export class ModelsTreeDefinition {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
#impl;
|
|
33
|
+
#idsCache;
|
|
34
|
+
#hierarchyConfig;
|
|
35
|
+
#selectQueryFactory;
|
|
36
|
+
#nodeLabelSelectClauseFactory;
|
|
37
|
+
#queryExecutor;
|
|
38
|
+
#isSupported;
|
|
39
|
+
static #componentName = "ModelsTreeDefinition";
|
|
40
|
+
#componentId;
|
|
38
41
|
constructor(props) {
|
|
39
|
-
this
|
|
42
|
+
this.#impl = createPredicateBasedHierarchyDefinition({
|
|
40
43
|
classHierarchyInspector: props.imodelAccess,
|
|
41
44
|
hierarchy: {
|
|
42
|
-
rootNodes: async (requestProps) => this.createSubjectChildrenQuery({ ...requestProps, parentNodeInstanceIds: this.
|
|
45
|
+
rootNodes: async (requestProps) => this.createSubjectChildrenQuery({ ...requestProps, parentNodeInstanceIds: this.#hierarchyConfig.hideRootSubject ? [IModel.rootSubjectId] : [] }),
|
|
43
46
|
childNodes: [
|
|
44
47
|
{
|
|
45
48
|
parentInstancesNodePredicate: "BisCore.Subject",
|
|
@@ -64,24 +67,48 @@ export class ModelsTreeDefinition {
|
|
|
64
67
|
],
|
|
65
68
|
},
|
|
66
69
|
});
|
|
67
|
-
this
|
|
68
|
-
this
|
|
69
|
-
this
|
|
70
|
-
this
|
|
71
|
-
this
|
|
70
|
+
this.#componentId = props.componentId ?? Guid.createValue();
|
|
71
|
+
this.#idsCache = props.idsCache;
|
|
72
|
+
this.#queryExecutor = props.imodelAccess;
|
|
73
|
+
this.#hierarchyConfig = props.hierarchyConfig;
|
|
74
|
+
this.#nodeLabelSelectClauseFactory = createBisInstanceLabelSelectClauseFactory({ classHierarchyInspector: props.imodelAccess });
|
|
75
|
+
this.#selectQueryFactory = createNodesQueryClauseFactory({
|
|
72
76
|
imodelAccess: props.imodelAccess,
|
|
73
|
-
instanceLabelSelectClauseFactory: this
|
|
77
|
+
instanceLabelSelectClauseFactory: this.#nodeLabelSelectClauseFactory,
|
|
74
78
|
});
|
|
75
79
|
}
|
|
76
80
|
async postProcessNode(node) {
|
|
77
81
|
if (ProcessedHierarchyNode.isGroupingNode(node)) {
|
|
82
|
+
let hasDirectNonFilteredTargets = false;
|
|
83
|
+
let hasFilterTargetAncestor = false;
|
|
84
|
+
for (const child of node.children) {
|
|
85
|
+
if (child.filtering) {
|
|
86
|
+
if (child.filtering.hasFilterTargetAncestor) {
|
|
87
|
+
hasFilterTargetAncestor = true;
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
if (!child.filtering.isFilterTarget) {
|
|
91
|
+
hasDirectNonFilteredTargets = true;
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
78
96
|
return {
|
|
79
97
|
...node,
|
|
80
|
-
|
|
98
|
+
...(hasFilterTargetAncestor
|
|
99
|
+
? {
|
|
100
|
+
filtering: {
|
|
101
|
+
...(node.filtering ?? {}),
|
|
102
|
+
hasFilterTargetAncestor,
|
|
103
|
+
},
|
|
104
|
+
}
|
|
105
|
+
: {}),
|
|
106
|
+
label: this.#hierarchyConfig.elementClassGrouping === "enableWithCounts" ? `${node.label} (${node.children.length})` : node.label,
|
|
81
107
|
extendedData: {
|
|
82
108
|
...node.extendedData,
|
|
83
109
|
// add `modelId` and `categoryId` from the first grouped element
|
|
84
110
|
...node.children[0].extendedData,
|
|
111
|
+
...(hasDirectNonFilteredTargets ? { hasDirectNonFilteredTargets } : {}),
|
|
85
112
|
// `imageId` is assigned to instance nodes at query time, but grouping ones need to
|
|
86
113
|
// be handled during post-processing
|
|
87
114
|
imageId: "icon-ec-class",
|
|
@@ -91,27 +118,27 @@ export class ModelsTreeDefinition {
|
|
|
91
118
|
return node;
|
|
92
119
|
}
|
|
93
120
|
async defineHierarchyLevel(props) {
|
|
94
|
-
if (this
|
|
95
|
-
this
|
|
121
|
+
if (this.#isSupported === undefined) {
|
|
122
|
+
this.#isSupported = this.isSupported();
|
|
96
123
|
}
|
|
97
|
-
if ((await this
|
|
124
|
+
if ((await this.#isSupported) === false) {
|
|
98
125
|
return [];
|
|
99
126
|
}
|
|
100
|
-
return this.
|
|
127
|
+
return this.#impl.defineHierarchyLevel(props);
|
|
101
128
|
}
|
|
102
129
|
async createSubjectChildrenQuery({ parentNodeInstanceIds: parentSubjectIds, instanceFilter, }) {
|
|
103
130
|
const [subjectFilterClauses, modelFilterClauses] = await Promise.all([
|
|
104
|
-
this.
|
|
131
|
+
this.#selectQueryFactory.createFilterClauses({
|
|
105
132
|
filter: instanceFilter,
|
|
106
133
|
contentClass: { fullName: "BisCore.Subject", alias: "this" },
|
|
107
134
|
}),
|
|
108
|
-
this.
|
|
135
|
+
this.#selectQueryFactory.createFilterClauses({
|
|
109
136
|
filter: instanceFilter,
|
|
110
137
|
contentClass: { fullName: "BisCore.GeometricModel3d", alias: "this" },
|
|
111
138
|
}),
|
|
112
139
|
]);
|
|
113
140
|
const [childSubjectIds, childModelIds] = parentSubjectIds.length
|
|
114
|
-
? await Promise.all([this.
|
|
141
|
+
? await Promise.all([this.#idsCache.getChildSubjectIds(parentSubjectIds), this.#idsCache.getChildSubjectModelIds(parentSubjectIds)])
|
|
115
142
|
: [[IModel.rootSubjectId], []];
|
|
116
143
|
const defs = new Array();
|
|
117
144
|
childSubjectIds.length &&
|
|
@@ -120,11 +147,11 @@ export class ModelsTreeDefinition {
|
|
|
120
147
|
query: {
|
|
121
148
|
ecsql: `
|
|
122
149
|
SELECT
|
|
123
|
-
${await this.
|
|
150
|
+
${await this.#selectQueryFactory.createSelectClause({
|
|
124
151
|
ecClassId: { selector: "this.ECClassId" },
|
|
125
152
|
ecInstanceId: { selector: "this.ECInstanceId" },
|
|
126
153
|
nodeLabel: {
|
|
127
|
-
selector: await this.
|
|
154
|
+
selector: await this.#nodeLabelSelectClauseFactory.createSelectClause({
|
|
128
155
|
classAlias: "this",
|
|
129
156
|
className: "BisCore.Subject",
|
|
130
157
|
}),
|
|
@@ -146,7 +173,7 @@ export class ModelsTreeDefinition {
|
|
|
146
173
|
${subjectFilterClauses.where ? `AND ${subjectFilterClauses.where}` : ""}
|
|
147
174
|
`,
|
|
148
175
|
bindings: [
|
|
149
|
-
{ type: "idset", value: await this.
|
|
176
|
+
{ type: "idset", value: await this.#idsCache.getParentSubjectIds() },
|
|
150
177
|
...childSubjectIds.map((id) => ({ type: "id", value: id })),
|
|
151
178
|
],
|
|
152
179
|
},
|
|
@@ -159,11 +186,11 @@ export class ModelsTreeDefinition {
|
|
|
159
186
|
SELECT model.ECInstanceId AS ECInstanceId, model.*
|
|
160
187
|
FROM (
|
|
161
188
|
SELECT
|
|
162
|
-
${await this.
|
|
189
|
+
${await this.#selectQueryFactory.createSelectClause({
|
|
163
190
|
ecClassId: { selector: "m.ECClassId" },
|
|
164
191
|
ecInstanceId: { selector: "m.ECInstanceId" },
|
|
165
192
|
nodeLabel: {
|
|
166
|
-
selector: await this.
|
|
193
|
+
selector: await this.#nodeLabelSelectClauseFactory.createSelectClause({
|
|
167
194
|
classAlias: "partition",
|
|
168
195
|
className: "BisCore.InformationPartitionElement",
|
|
169
196
|
}),
|
|
@@ -179,12 +206,12 @@ export class ModelsTreeDefinition {
|
|
|
179
206
|
END
|
|
180
207
|
`,
|
|
181
208
|
},
|
|
182
|
-
hasChildren: this.
|
|
209
|
+
hasChildren: this.#hierarchyConfig.showEmptyModels
|
|
183
210
|
? {
|
|
184
211
|
selector: `
|
|
185
212
|
IFNULL((
|
|
186
213
|
SELECT 1
|
|
187
|
-
FROM ${this.
|
|
214
|
+
FROM ${this.#hierarchyConfig.elementClassSpecification} e
|
|
188
215
|
WHERE e.Model.Id = m.ECInstanceId
|
|
189
216
|
LIMIT 1
|
|
190
217
|
), 0)
|
|
@@ -220,7 +247,7 @@ export class ModelsTreeDefinition {
|
|
|
220
247
|
query: {
|
|
221
248
|
ecsql: `
|
|
222
249
|
SELECT
|
|
223
|
-
${await this.
|
|
250
|
+
${await this.#selectQueryFactory.createSelectClause({
|
|
224
251
|
ecClassId: { selector: "this.ECClassId" },
|
|
225
252
|
ecInstanceId: { selector: "this.ECInstanceId" },
|
|
226
253
|
nodeLabel: "", // doesn't matter - the node is always hidden
|
|
@@ -230,7 +257,7 @@ export class ModelsTreeDefinition {
|
|
|
230
257
|
WHERE
|
|
231
258
|
this.ModeledElement.Id IN (${elementIds.map(() => "?").join(",")})
|
|
232
259
|
AND NOT this.IsPrivate
|
|
233
|
-
AND this.ECInstanceId IN (SELECT Model.Id FROM ${this.
|
|
260
|
+
AND this.ECInstanceId IN (SELECT Model.Id FROM ${this.#hierarchyConfig.elementClassSpecification})
|
|
234
261
|
`,
|
|
235
262
|
bindings: [...elementIds.map((id) => ({ type: "id", value: id }))],
|
|
236
263
|
},
|
|
@@ -238,7 +265,7 @@ export class ModelsTreeDefinition {
|
|
|
238
265
|
];
|
|
239
266
|
}
|
|
240
267
|
async createGeometricModel3dChildrenQuery({ parentNodeInstanceIds: modelIds, instanceFilter, }) {
|
|
241
|
-
const instanceFilterClauses = await this.
|
|
268
|
+
const instanceFilterClauses = await this.#selectQueryFactory.createFilterClauses({
|
|
242
269
|
filter: instanceFilter,
|
|
243
270
|
contentClass: { fullName: "BisCore.SpatialCategory", alias: "this" },
|
|
244
271
|
});
|
|
@@ -248,11 +275,11 @@ export class ModelsTreeDefinition {
|
|
|
248
275
|
query: {
|
|
249
276
|
ecsql: `
|
|
250
277
|
SELECT
|
|
251
|
-
${await this.
|
|
278
|
+
${await this.#selectQueryFactory.createSelectClause({
|
|
252
279
|
ecClassId: { selector: "this.ECClassId" },
|
|
253
280
|
ecInstanceId: { selector: "this.ECInstanceId" },
|
|
254
281
|
nodeLabel: {
|
|
255
|
-
selector: await this.
|
|
282
|
+
selector: await this.#nodeLabelSelectClauseFactory.createSelectClause({
|
|
256
283
|
classAlias: "this",
|
|
257
284
|
className: "BisCore.SpatialCategory",
|
|
258
285
|
}),
|
|
@@ -271,7 +298,7 @@ export class ModelsTreeDefinition {
|
|
|
271
298
|
WHERE
|
|
272
299
|
EXISTS (
|
|
273
300
|
SELECT 1
|
|
274
|
-
FROM ${this.
|
|
301
|
+
FROM ${this.#hierarchyConfig.elementClassSpecification} element
|
|
275
302
|
WHERE
|
|
276
303
|
element.Model.Id IN (${modelIds.map(() => "?").join(",")})
|
|
277
304
|
AND element.Category.Id = +this.ECInstanceId
|
|
@@ -289,30 +316,30 @@ export class ModelsTreeDefinition {
|
|
|
289
316
|
if (modelIds.length === 0) {
|
|
290
317
|
throw new Error(`Invalid category node "${parentNode.label}" - missing model information.`);
|
|
291
318
|
}
|
|
292
|
-
const instanceFilterClauses = await this.
|
|
319
|
+
const instanceFilterClauses = await this.#selectQueryFactory.createFilterClauses({
|
|
293
320
|
filter: instanceFilter,
|
|
294
|
-
contentClass: { fullName: this.
|
|
321
|
+
contentClass: { fullName: this.#hierarchyConfig.elementClassSpecification, alias: "this" },
|
|
295
322
|
});
|
|
296
|
-
const modeledElements = await firstValueFrom(from(modelIds).pipe(mergeMap(async (modelId) => this.
|
|
323
|
+
const modeledElements = await firstValueFrom(from(modelIds).pipe(mergeMap(async (modelId) => this.#idsCache.getCategoriesModeledElements(modelId, categoryIds)), reduce((acc, foundModeledElements) => {
|
|
297
324
|
return acc.concat(foundModeledElements);
|
|
298
325
|
}, new Array())));
|
|
299
326
|
return [
|
|
300
327
|
{
|
|
301
|
-
fullClassName: this.
|
|
328
|
+
fullClassName: this.#hierarchyConfig.elementClassSpecification,
|
|
302
329
|
query: {
|
|
303
330
|
ecsql: `
|
|
304
331
|
SELECT
|
|
305
|
-
${await this.
|
|
332
|
+
${await this.#selectQueryFactory.createSelectClause({
|
|
306
333
|
ecClassId: { selector: "this.ECClassId" },
|
|
307
334
|
ecInstanceId: { selector: "this.ECInstanceId" },
|
|
308
335
|
nodeLabel: {
|
|
309
|
-
selector: await this.
|
|
336
|
+
selector: await this.#nodeLabelSelectClauseFactory.createSelectClause({
|
|
310
337
|
classAlias: "this",
|
|
311
|
-
className: this.
|
|
338
|
+
className: this.#hierarchyConfig.elementClassSpecification,
|
|
312
339
|
}),
|
|
313
340
|
},
|
|
314
341
|
grouping: {
|
|
315
|
-
byClass: this.
|
|
342
|
+
byClass: this.#hierarchyConfig.elementClassGrouping !== "disable",
|
|
316
343
|
},
|
|
317
344
|
hasChildren: {
|
|
318
345
|
selector: `
|
|
@@ -321,7 +348,7 @@ export class ModelsTreeDefinition {
|
|
|
321
348
|
1,
|
|
322
349
|
IFNULL((
|
|
323
350
|
SELECT 1
|
|
324
|
-
FROM ${this.
|
|
351
|
+
FROM ${this.#hierarchyConfig.elementClassSpecification} ce
|
|
325
352
|
WHERE ce.Parent.Id = this.ECInstanceId
|
|
326
353
|
LIMIT 1
|
|
327
354
|
), 0)
|
|
@@ -349,33 +376,33 @@ export class ModelsTreeDefinition {
|
|
|
349
376
|
];
|
|
350
377
|
}
|
|
351
378
|
async createGeometricElement3dChildrenQuery({ parentNodeInstanceIds: elementIds, instanceFilter, }) {
|
|
352
|
-
const instanceFilterClauses = await this.
|
|
379
|
+
const instanceFilterClauses = await this.#selectQueryFactory.createFilterClauses({
|
|
353
380
|
filter: instanceFilter,
|
|
354
|
-
contentClass: { fullName: this.
|
|
381
|
+
contentClass: { fullName: this.#hierarchyConfig.elementClassSpecification, alias: "this" },
|
|
355
382
|
});
|
|
356
383
|
return [
|
|
357
384
|
{
|
|
358
|
-
fullClassName: this.
|
|
385
|
+
fullClassName: this.#hierarchyConfig.elementClassSpecification,
|
|
359
386
|
query: {
|
|
360
387
|
ecsql: `
|
|
361
388
|
SELECT
|
|
362
|
-
${await this.
|
|
389
|
+
${await this.#selectQueryFactory.createSelectClause({
|
|
363
390
|
ecClassId: { selector: "this.ECClassId" },
|
|
364
391
|
ecInstanceId: { selector: "this.ECInstanceId" },
|
|
365
392
|
nodeLabel: {
|
|
366
|
-
selector: await this.
|
|
393
|
+
selector: await this.#nodeLabelSelectClauseFactory.createSelectClause({
|
|
367
394
|
classAlias: "this",
|
|
368
|
-
className: this.
|
|
395
|
+
className: this.#hierarchyConfig.elementClassSpecification,
|
|
369
396
|
}),
|
|
370
397
|
},
|
|
371
398
|
grouping: {
|
|
372
|
-
byClass: this.
|
|
399
|
+
byClass: this.#hierarchyConfig.elementClassGrouping !== "disable",
|
|
373
400
|
},
|
|
374
401
|
hasChildren: {
|
|
375
402
|
selector: `
|
|
376
403
|
IFNULL((
|
|
377
404
|
SELECT 1
|
|
378
|
-
FROM ${this.
|
|
405
|
+
FROM ${this.#hierarchyConfig.elementClassSpecification} ce
|
|
379
406
|
JOIN BisCore.Model m ON ce.Model.Id = m.ECInstanceId
|
|
380
407
|
WHERE ce.Parent.Id = this.ECInstanceId OR (ce.Model.Id = this.ECInstanceId AND m.IsPrivate = false)
|
|
381
408
|
LIMIT 1
|
|
@@ -402,20 +429,25 @@ export class ModelsTreeDefinition {
|
|
|
402
429
|
}
|
|
403
430
|
static async createInstanceKeyPaths(props) {
|
|
404
431
|
return lastValueFrom(defer(() => {
|
|
432
|
+
const componentInfo = { componentId: props.componentId ?? Guid.createValue(), componentName: this.#componentName };
|
|
405
433
|
if (ModelsTreeInstanceKeyPathsProps.isLabelProps(props)) {
|
|
406
434
|
const labelsFactory = createBisInstanceLabelSelectClauseFactory({ classHierarchyInspector: props.imodelAccess });
|
|
407
|
-
return createInstanceKeyPathsFromInstanceLabelObs({
|
|
435
|
+
return createInstanceKeyPathsFromInstanceLabelObs({
|
|
436
|
+
...props,
|
|
437
|
+
...componentInfo,
|
|
438
|
+
labelsFactory,
|
|
439
|
+
});
|
|
408
440
|
}
|
|
409
|
-
return createInstanceKeyPathsFromTargetItemsObs(props);
|
|
441
|
+
return createInstanceKeyPathsFromTargetItemsObs({ ...props, ...componentInfo });
|
|
410
442
|
}).pipe(props.abortSignal ? takeUntil(fromEvent(props.abortSignal, "abort")) : identity, defaultIfEmpty([])));
|
|
411
443
|
}
|
|
412
444
|
supportsFiltering() {
|
|
413
|
-
return this.
|
|
445
|
+
return this.#hierarchyConfig.hierarchyLevelFiltering === "enable";
|
|
414
446
|
}
|
|
415
447
|
async isSupported() {
|
|
416
|
-
const [schemaName, className] = this.
|
|
448
|
+
const [schemaName, className] = this.#hierarchyConfig.elementClassSpecification.split(/[\.:]/);
|
|
417
449
|
if (!schemaName || !className) {
|
|
418
|
-
throw new Error(`Provided class specification ${this.
|
|
450
|
+
throw new Error(`Provided class specification ${this.#hierarchyConfig.elementClassSpecification} should be in format {SchemaName}:{ClassName} or {SchemaName}.{ClassName}`);
|
|
419
451
|
}
|
|
420
452
|
const query = {
|
|
421
453
|
ecsql: `
|
|
@@ -429,13 +461,16 @@ export class ModelsTreeDefinition {
|
|
|
429
461
|
{ type: "string", value: className },
|
|
430
462
|
],
|
|
431
463
|
};
|
|
432
|
-
for await (const _row of this.
|
|
464
|
+
for await (const _row of this.#queryExecutor.createQueryReader(query, {
|
|
465
|
+
restartToken: `${ModelsTreeDefinition.#componentName}/${this.#componentId}/is-class-supported`,
|
|
466
|
+
})) {
|
|
433
467
|
return true;
|
|
434
468
|
}
|
|
435
469
|
return false;
|
|
436
470
|
}
|
|
437
471
|
}
|
|
438
|
-
function createGeometricElementInstanceKeyPaths(
|
|
472
|
+
function createGeometricElementInstanceKeyPaths(props) {
|
|
473
|
+
const { targetItems, chunkIndex, componentId, componentName, hierarchyConfig, idsCache, imodelAccess } = props;
|
|
439
474
|
const elementIds = targetItems.filter((info) => typeof info === "string");
|
|
440
475
|
const groupInfos = targetItems.filter((info) => typeof info !== "string");
|
|
441
476
|
const separator = ";";
|
|
@@ -495,7 +530,7 @@ function createGeometricElementInstanceKeyPaths(imodelAccess, idsCache, hierarch
|
|
|
495
530
|
FROM ModelsCategoriesElementsHierarchy mce
|
|
496
531
|
WHERE mce.ParentId IS NULL
|
|
497
532
|
`;
|
|
498
|
-
return imodelAccess.createQueryReader({ ctes, ecsql }, { rowFormat: "Indexes", limit: "unbounded" });
|
|
533
|
+
return imodelAccess.createQueryReader({ ctes, ecsql }, { rowFormat: "Indexes", limit: "unbounded", restartToken: `${componentName}/${componentId}/geometric-element-paths/${chunkIndex}` });
|
|
499
534
|
}).pipe(releaseMainThreadOnItemsCount(300), map((row) => parseQueryRow(row, groupInfos, separator, hierarchyConfig.elementClassSpecification)), mergeMap(({ modelId, elementHierarchyPath, groupingNode }) => from(idsCache.createModelInstanceKeyPaths(modelId)).pipe(mergeAll(), map((modelPath) => {
|
|
500
535
|
// We don't want to modify the original path, we create a copy that we can modify
|
|
501
536
|
const newModelPath = [...modelPath];
|
|
@@ -537,7 +572,7 @@ function parseQueryRow(row, groupInfos, separator, elementClassName) {
|
|
|
537
572
|
groupingNode: row[2] === -1 ? undefined : groupInfos[row[2]].groupingNode,
|
|
538
573
|
};
|
|
539
574
|
}
|
|
540
|
-
function createInstanceKeyPathsFromTargetItemsObs({ targetItems, imodelAccess, hierarchyConfig, idsCache, limit, }) {
|
|
575
|
+
function createInstanceKeyPathsFromTargetItemsObs({ targetItems, imodelAccess, hierarchyConfig, idsCache, limit, componentId, componentName, }) {
|
|
541
576
|
if (limit !== "unbounded" && targetItems.length > (limit ?? MAX_FILTERING_INSTANCE_KEY_COUNT)) {
|
|
542
577
|
throw new FilterLimitExceededError(limit ?? MAX_FILTERING_INSTANCE_KEY_COUNT);
|
|
543
578
|
}
|
|
@@ -577,7 +612,15 @@ function createInstanceKeyPathsFromTargetItemsObs({ targetItems, imodelAccess, h
|
|
|
577
612
|
elements: new Array(),
|
|
578
613
|
}), switchMap(async (ids) => {
|
|
579
614
|
const elementsLength = ids.elements.length;
|
|
580
|
-
return collect(merge(from(ids.subjects).pipe(mergeMap((id) => from(idsCache.createSubjectInstanceKeysPath(id)).pipe(map(HierarchyFilteringPath.normalize)))), from(ids.models).pipe(mergeMap((id) => from(idsCache.createModelInstanceKeyPaths(id)).pipe(mergeAll(), map(HierarchyFilteringPath.normalize)))), from(ids.categories).pipe(mergeMap((id) => from(idsCache.createCategoryInstanceKeyPaths(id)).pipe(mergeAll(), map(HierarchyFilteringPath.normalize)))), from(ids.elements).pipe(bufferCount(Math.ceil(elementsLength / Math.ceil(elementsLength / 5000))), releaseMainThreadOnItemsCount(1), mergeMap((block) => createGeometricElementInstanceKeyPaths(
|
|
615
|
+
return collect(merge(from(ids.subjects).pipe(mergeMap((id) => from(idsCache.createSubjectInstanceKeysPath(id)).pipe(map(HierarchyFilteringPath.normalize)))), from(ids.models).pipe(mergeMap((id) => from(idsCache.createModelInstanceKeyPaths(id)).pipe(mergeAll(), map(HierarchyFilteringPath.normalize)))), from(ids.categories).pipe(mergeMap((id) => from(idsCache.createCategoryInstanceKeyPaths(id)).pipe(mergeAll(), map(HierarchyFilteringPath.normalize)))), from(ids.elements).pipe(bufferCount(Math.ceil(elementsLength / Math.ceil(elementsLength / 5000))), releaseMainThreadOnItemsCount(1), mergeMap((block, chunkIndex) => createGeometricElementInstanceKeyPaths({
|
|
616
|
+
imodelAccess,
|
|
617
|
+
idsCache,
|
|
618
|
+
hierarchyConfig,
|
|
619
|
+
targetItems: block,
|
|
620
|
+
componentId,
|
|
621
|
+
componentName,
|
|
622
|
+
chunkIndex,
|
|
623
|
+
}), 10))));
|
|
581
624
|
}));
|
|
582
625
|
}
|
|
583
626
|
function createInstanceKeyPathsFromInstanceLabelObs(props) {
|
|
@@ -620,7 +663,7 @@ function createInstanceKeyPathsFromInstanceLabelObs(props) {
|
|
|
620
663
|
}).pipe(mergeMap((queryProps) => {
|
|
621
664
|
return imodelAccess.createQueryReader(queryProps, {
|
|
622
665
|
rowFormat: "Indexes",
|
|
623
|
-
restartToken:
|
|
666
|
+
restartToken: `${props.componentName}/${props.componentId}/filter-by-label`,
|
|
624
667
|
limit,
|
|
625
668
|
});
|
|
626
669
|
}), map((row) => ({ className: row[0], id: row[1] })), toArray(), mergeMap((targetKeys) => createInstanceKeyPathsFromTargetItemsObs({ ...props, targetItems: targetKeys })));
|