@itwin/tree-widget-react 3.16.1 → 3.17.1
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 +24 -2
- package/lib/cjs/tree-widget-react/components/SelectableTree.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/TreeSelector.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/TreeWidgetUiItemsProvider.js +1 -1
- package/lib/cjs/tree-widget-react/components/TreeWidgetUiItemsProvider.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/tree-header/TreeHeader.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/tree-header/TreeWithHeader.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/CategoriesTree.d.ts +2 -2
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/CategoriesTree.js +2 -1
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/CategoriesTree.js.map +1 -1
- 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/CategoriesTreeComponent.d.ts +1 -1
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/CategoriesTreeComponent.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.d.ts +13 -0
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.js +92 -74
- 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.d.ts +3 -1
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/UseCategoriesTree.js +21 -8
- 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 +21 -9
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.js +300 -251
- 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 +2 -0
- package/lib/cjs/tree-widget-react/components/trees/categories-tree/internal/CategoriesVisibilityHandler.js +66 -107
- 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.js +22 -12
- package/lib/cjs/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/UseActiveViewport.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/UseHierarchyVisibility.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/components/ProgressOverlay.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/components/Tree.d.ts +2 -2
- package/lib/cjs/tree-widget-react/components/trees/common/components/Tree.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/components/TreeNodeCheckbox.d.ts +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/components/TreeNodeCheckbox.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/components/TreeRenderer.d.ts +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/components/TreeRenderer.js +2 -2
- package/lib/cjs/tree-widget-react/components/trees/common/components/TreeRenderer.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/components/VisibilityTree.d.ts +3 -3
- package/lib/cjs/tree-widget-react/components/trees/common/components/VisibilityTree.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/components/VisibilityTreeRenderer.d.ts +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/components/VisibilityTreeRenderer.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/common/internal/Utils.d.ts +25 -0
- package/lib/cjs/tree-widget-react/components/trees/common/internal/Utils.js +83 -0
- package/lib/cjs/tree-widget-react/components/trees/common/internal/Utils.js.map +1 -0
- package/lib/cjs/tree-widget-react/components/trees/models-tree/ModelsTree.d.ts +1 -1
- package/lib/cjs/tree-widget-react/components/trees/models-tree/ModelsTree.js.map +1 -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/ModelsTreeComponent.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.d.ts +1 -0
- package/lib/cjs/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.js +86 -28
- 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 +2 -1
- 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 +5 -6
- package/lib/cjs/tree-widget-react/components/trees/models-tree/Utils.js +5 -17
- 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.js +5 -4
- 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 +7 -1
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/FilteredTree.js +52 -0
- 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 +28 -12
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js +382 -278
- 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/ModelsTreeNode.d.ts +1 -1
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeNode.js.map +1 -1
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js +272 -139
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js.map +1 -1
- package/lib/cjs/tree-widget-react-internal.d.ts +2 -1
- package/lib/cjs/tree-widget-react-internal.js +4 -1
- package/lib/cjs/tree-widget-react-internal.js.map +1 -1
- package/lib/esm/tree-widget-react/components/SelectableTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/TreeSelector.js.map +1 -1
- package/lib/esm/tree-widget-react/components/TreeWidgetUiItemsProvider.js +1 -1
- package/lib/esm/tree-widget-react/components/TreeWidgetUiItemsProvider.js.map +1 -1
- package/lib/esm/tree-widget-react/components/tree-header/TreeHeader.js.map +1 -1
- package/lib/esm/tree-widget-react/components/tree-header/TreeWithHeader.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTree.d.ts +2 -2
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTree.js +2 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTree.js.map +1 -1
- 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/CategoriesTreeComponent.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeComponent.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.d.ts +13 -0
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.js +92 -74
- 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.d.ts +3 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/UseCategoriesTree.js +22 -9
- 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 +21 -9
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.js +301 -252
- 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 +2 -0
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesVisibilityHandler.js +67 -108
- 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.js +23 -13
- package/lib/esm/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/UseActiveViewport.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/UseHierarchyVisibility.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/ProgressOverlay.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/Tree.d.ts +2 -2
- package/lib/esm/tree-widget-react/components/trees/common/components/Tree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeCheckbox.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeCheckbox.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/TreeRenderer.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/TreeRenderer.js +2 -2
- package/lib/esm/tree-widget-react/components/trees/common/components/TreeRenderer.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTree.d.ts +3 -3
- package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTreeRenderer.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTreeRenderer.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/internal/Utils.d.ts +25 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/Utils.js +74 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/Utils.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTree.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTree.js.map +1 -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/ModelsTreeComponent.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.d.ts +1 -0
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.js +83 -25
- 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 +2 -1
- 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 +5 -6
- package/lib/esm/tree-widget-react/components/trees/models-tree/Utils.js +4 -16
- 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.js +4 -3
- 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 +7 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/FilteredTree.js +52 -0
- 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 +28 -12
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js +382 -278
- 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/ModelsTreeNode.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeNode.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js +257 -124
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js.map +1 -1
- package/lib/esm/tree-widget-react-internal.d.ts +2 -1
- package/lib/esm/tree-widget-react-internal.js +2 -1
- package/lib/esm/tree-widget-react-internal.js.map +1 -1
- package/package.json +1 -1
package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js
CHANGED
|
@@ -8,8 +8,9 @@ exports.ModelsTreeIdsCache = void 0;
|
|
|
8
8
|
const rxjs_1 = require("rxjs");
|
|
9
9
|
const core_bentley_1 = require("@itwin/core-bentley");
|
|
10
10
|
const core_common_1 = require("@itwin/core-common");
|
|
11
|
-
const
|
|
12
|
-
const
|
|
11
|
+
const Utils_js_1 = require("../../common/internal/Utils.js");
|
|
12
|
+
const Utils_js_2 = require("../../common/Utils.js");
|
|
13
|
+
const Utils_js_3 = require("../Utils.js");
|
|
13
14
|
/** @internal */
|
|
14
15
|
class ModelsTreeIdsCache {
|
|
15
16
|
#categoryElementCounts;
|
|
@@ -22,93 +23,221 @@ class ModelsTreeIdsCache {
|
|
|
22
23
|
#categoryKeyPaths;
|
|
23
24
|
#queryExecutor;
|
|
24
25
|
#hierarchyConfig;
|
|
26
|
+
#childrenMap;
|
|
27
|
+
/** Stores element ids which have children query scheduled to execute. */
|
|
28
|
+
#childrenLoadingMap;
|
|
25
29
|
#componentId;
|
|
26
30
|
#componentName;
|
|
27
31
|
constructor(queryExecutor, hierarchyConfig, componentId) {
|
|
28
32
|
this.#hierarchyConfig = hierarchyConfig;
|
|
29
33
|
this.#queryExecutor = queryExecutor;
|
|
30
|
-
this.#categoryElementCounts = new ModelCategoryElementsCountCache(
|
|
34
|
+
this.#categoryElementCounts = new ModelCategoryElementsCountCache((input) => this.queryCategoryElementCounts(input));
|
|
31
35
|
this.#modelKeyPaths = new Map();
|
|
32
36
|
this.#subjectKeyPaths = new Map();
|
|
33
37
|
this.#categoryKeyPaths = new Map();
|
|
38
|
+
this.#childrenMap = new Map();
|
|
39
|
+
this.#childrenLoadingMap = new Map();
|
|
34
40
|
this.#componentId = componentId ?? core_bentley_1.Guid.createValue();
|
|
35
41
|
this.#componentName = "ModelsTreeIdsCache";
|
|
36
42
|
}
|
|
37
43
|
[Symbol.dispose]() {
|
|
38
44
|
this.#categoryElementCounts[Symbol.dispose]();
|
|
39
45
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
46
|
+
querySubjects() {
|
|
47
|
+
return (0, rxjs_1.defer)(() => {
|
|
48
|
+
const subjectsQuery = `
|
|
49
|
+
SELECT
|
|
50
|
+
s.ECInstanceId id,
|
|
51
|
+
s.Parent.Id parentId,
|
|
52
|
+
(
|
|
53
|
+
SELECT m.ECInstanceId
|
|
54
|
+
FROM bis.GeometricModel3d m
|
|
55
|
+
WHERE m.ECInstanceId = HexToId(json_extract(s.JsonProperties, '$.Subject.Model.TargetPartition'))
|
|
56
|
+
AND NOT m.IsPrivate
|
|
57
|
+
AND EXISTS (SELECT 1 FROM ${this.#hierarchyConfig.elementClassSpecification} WHERE Model.Id = m.ECInstanceId)
|
|
58
|
+
) targetPartitionId,
|
|
59
|
+
CASE
|
|
60
|
+
WHEN (
|
|
61
|
+
json_extract(s.JsonProperties, '$.Subject.Job.Bridge') IS NOT NULL
|
|
62
|
+
OR json_extract(s.JsonProperties, '$.Subject.Model.Type') = 'Hierarchy'
|
|
63
|
+
) THEN 1
|
|
64
|
+
ELSE 0
|
|
65
|
+
END hideInHierarchy
|
|
66
|
+
FROM bis.Subject s
|
|
67
|
+
`;
|
|
68
|
+
return this.#queryExecutor.createQueryReader({ ecsql: subjectsQuery }, { rowFormat: "ECSqlPropertyNames", limit: "unbounded", restartToken: `${this.#componentName}/${this.#componentId}/subjects` });
|
|
69
|
+
}).pipe((0, rxjs_1.map)((row) => {
|
|
70
|
+
return { id: row.id, parentId: row.parentId, targetPartitionId: row.targetPartitionId, hideInHierarchy: !!row.hideInHierarchy };
|
|
71
|
+
}));
|
|
64
72
|
}
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
queryModels() {
|
|
74
|
+
return (0, rxjs_1.defer)(() => {
|
|
75
|
+
const modelsQuery = `
|
|
67
76
|
SELECT p.ECInstanceId id, p.Parent.Id parentId
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
77
|
+
FROM bis.InformationPartitionElement p
|
|
78
|
+
INNER JOIN bis.GeometricModel3d m ON m.ModeledElement.Id = p.ECInstanceId
|
|
79
|
+
WHERE
|
|
80
|
+
NOT m.IsPrivate
|
|
81
|
+
${this.#hierarchyConfig.showEmptyModels ? "" : `AND EXISTS (SELECT 1 FROM ${this.#hierarchyConfig.elementClassSpecification} WHERE Model.Id = m.ECInstanceId)`}
|
|
82
|
+
`;
|
|
83
|
+
return this.#queryExecutor.createQueryReader({ ecsql: modelsQuery }, { rowFormat: "ECSqlPropertyNames", limit: "unbounded", restartToken: `${this.#componentName}/${this.#componentId}/models` });
|
|
84
|
+
}).pipe((0, rxjs_1.map)((row) => {
|
|
85
|
+
return { id: row.id, parentId: row.parentId };
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
queryChildren({ elementIds }) {
|
|
89
|
+
if (elementIds.length === 0) {
|
|
90
|
+
return rxjs_1.EMPTY;
|
|
76
91
|
}
|
|
92
|
+
return (0, rxjs_1.defer)(() => {
|
|
93
|
+
const ctes = [
|
|
94
|
+
`
|
|
95
|
+
ElementChildren(id, parentId) AS (
|
|
96
|
+
SELECT ECInstanceId id, Parent.Id parentId
|
|
97
|
+
FROM ${this.#hierarchyConfig.elementClassSpecification}
|
|
98
|
+
WHERE Parent.Id IN (${elementIds.join(", ")})
|
|
99
|
+
|
|
100
|
+
UNION ALL
|
|
101
|
+
|
|
102
|
+
SELECT c.ECInstanceId id, c.Parent.Id
|
|
103
|
+
FROM ${this.#hierarchyConfig.elementClassSpecification} c
|
|
104
|
+
JOIN ElementChildren p ON c.Parent.Id = p.id
|
|
105
|
+
)
|
|
106
|
+
`,
|
|
107
|
+
];
|
|
108
|
+
const ecsql = `
|
|
109
|
+
SELECT id, parentId
|
|
110
|
+
FROM ElementChildren
|
|
111
|
+
`;
|
|
112
|
+
return this.#queryExecutor.createQueryReader({ ecsql, ctes }, { rowFormat: "ECSqlPropertyNames", limit: "unbounded", restartToken: `${this.#componentName}/${this.#componentId}/children/${core_bentley_1.Guid.createValue()}` });
|
|
113
|
+
}).pipe((0, rxjs_1.map)((row) => {
|
|
114
|
+
return { id: row.id, parentId: row.parentId };
|
|
115
|
+
}));
|
|
77
116
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
117
|
+
getChildrenTreeFromMap({ elementIds }) {
|
|
118
|
+
const result = new Map();
|
|
119
|
+
if (core_bentley_1.Id64.sizeOf(elementIds) === 0 || this.#childrenMap.size === 0) {
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
for (const elementId of core_bentley_1.Id64.iterable(elementIds)) {
|
|
123
|
+
const entry = this.#childrenMap.get(elementId);
|
|
124
|
+
if (!entry?.children) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
const elementChildrenTree = new Map();
|
|
128
|
+
result.set(elementId, { children: elementChildrenTree });
|
|
129
|
+
entry.children.forEach((childId) => {
|
|
130
|
+
const childrenTreeOfChild = this.getChildrenTreeFromMap({ elementIds: childId });
|
|
131
|
+
// Need to add children tree created from childId. This tree includes childId as root element
|
|
132
|
+
// If child does not have children, children tree won't be created. Need to add childId with undefined children
|
|
133
|
+
elementChildrenTree.set(childId, { children: childrenTreeOfChild.size > 0 ? childrenTreeOfChild : undefined });
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
getChildrenCountMap({ elementIds }) {
|
|
139
|
+
const result = new Map();
|
|
140
|
+
for (const elementId of core_bentley_1.Id64.iterable(elementIds)) {
|
|
141
|
+
const entry = this.#childrenMap.get(elementId);
|
|
142
|
+
if (entry?.children) {
|
|
143
|
+
let totalChildrenCount = entry.children.length;
|
|
144
|
+
this.getChildrenCountMap({ elementIds: entry.children }).forEach((childrenOfChildCount) => (totalChildrenCount += childrenOfChildCount));
|
|
145
|
+
result.set(elementId, totalChildrenCount);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Populates #childrenLoadingMap with promises. When these promises resolve, they will populate #childrenMap with values and delete entries from #childrenLoadingMap.
|
|
152
|
+
*/
|
|
153
|
+
createChildrenLoadingMapEntries({ elementsToQuery }) {
|
|
154
|
+
const getElementsToQueryPromise = async (batchedElementsToQuery) => (0, rxjs_1.firstValueFrom)(this.queryChildren({ elementIds: batchedElementsToQuery }).pipe(
|
|
155
|
+
// Want to have void at the end instead of void[], so using reduce
|
|
156
|
+
(0, rxjs_1.reduce)((acc, { parentId, id }) => {
|
|
157
|
+
let entry = this.#childrenMap.get(parentId);
|
|
158
|
+
if (!entry) {
|
|
159
|
+
entry = { children: [] };
|
|
160
|
+
this.#childrenMap.set(parentId, entry);
|
|
161
|
+
}
|
|
162
|
+
if (!entry.children) {
|
|
163
|
+
entry.children = [];
|
|
164
|
+
}
|
|
165
|
+
// Add child to parent's entry and add child to children map
|
|
166
|
+
entry.children.push(id);
|
|
167
|
+
if (!this.#childrenMap.has(id)) {
|
|
168
|
+
this.#childrenMap.set(id, { children: undefined });
|
|
169
|
+
}
|
|
170
|
+
return acc;
|
|
171
|
+
}, (() => { })()), (0, rxjs_1.tap)({ complete: () => batchedElementsToQuery.forEach((elementId) => this.#childrenLoadingMap.delete(elementId)) }), (0, rxjs_1.defaultIfEmpty)((() => { })())));
|
|
172
|
+
const maximumBatchSize = 1000;
|
|
173
|
+
const totalSize = elementsToQuery.length;
|
|
174
|
+
const optimalBatchSize = (0, Utils_js_3.getOptimalBatchSize)({ totalSize, maximumBatchSize });
|
|
175
|
+
const loadingMapEntries = new Array();
|
|
176
|
+
// Don't want to slice if its not necessary
|
|
177
|
+
if (totalSize <= maximumBatchSize) {
|
|
178
|
+
loadingMapEntries.push(getElementsToQueryPromise(elementsToQuery));
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
for (let i = 0; i < elementsToQuery.length; i += optimalBatchSize) {
|
|
182
|
+
loadingMapEntries.push(getElementsToQueryPromise(elementsToQuery.slice(i, i + optimalBatchSize)));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
elementsToQuery.forEach((elementId, index) => this.#childrenLoadingMap.set(elementId, loadingMapEntries[Math.floor(index / optimalBatchSize)]));
|
|
186
|
+
return { loadingMapEntries: Promise.all(loadingMapEntries).then(() => { }) };
|
|
187
|
+
}
|
|
188
|
+
createChildrenMapEntries({ elementIds }) {
|
|
189
|
+
return (0, rxjs_1.from)(core_bentley_1.Id64.iterable(elementIds)).pipe((0, rxjs_1.reduce)((acc, elementId) => {
|
|
190
|
+
if (this.#childrenMap.has(elementId)) {
|
|
191
|
+
return acc;
|
|
192
|
+
}
|
|
193
|
+
const loadingPromise = this.#childrenLoadingMap.get(elementId);
|
|
194
|
+
if (loadingPromise) {
|
|
195
|
+
acc.existingPromises.push(loadingPromise);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
acc.elementsToQuery.push(elementId);
|
|
199
|
+
}
|
|
200
|
+
return acc;
|
|
201
|
+
}, { existingPromises: new Array(), elementsToQuery: new Array() }), (0, rxjs_1.mergeMap)(async ({ elementsToQuery, existingPromises }) => {
|
|
202
|
+
existingPromises.push(this.createChildrenLoadingMapEntries({ elementsToQuery }).loadingMapEntries);
|
|
203
|
+
return Promise.all(existingPromises);
|
|
204
|
+
}));
|
|
205
|
+
}
|
|
206
|
+
getChildrenTree({ elementIds }) {
|
|
207
|
+
return this.createChildrenMapEntries({ elementIds }).pipe((0, rxjs_1.map)(() => this.getChildrenTreeFromMap({ elementIds })));
|
|
208
|
+
}
|
|
209
|
+
getAllChildrenCount({ elementIds }) {
|
|
210
|
+
return this.createChildrenMapEntries({ elementIds }).pipe((0, rxjs_1.map)(() => this.getChildrenCountMap({ elementIds })));
|
|
211
|
+
}
|
|
212
|
+
getSubjectInfos() {
|
|
213
|
+
this.#subjectInfos ??= (0, rxjs_1.forkJoin)({
|
|
214
|
+
subjectInfos: this.querySubjects().pipe((0, rxjs_1.reduce)((acc, subject) => {
|
|
215
|
+
const subjectInfo = {
|
|
216
|
+
parentSubject: subject.parentId,
|
|
217
|
+
hideInHierarchy: subject.hideInHierarchy,
|
|
218
|
+
childSubjects: new Set(),
|
|
219
|
+
childModels: new Set(),
|
|
220
|
+
};
|
|
221
|
+
if (subject.targetPartitionId) {
|
|
222
|
+
subjectInfo.childModels.add(subject.targetPartitionId);
|
|
223
|
+
}
|
|
224
|
+
acc.set(subject.id, subjectInfo);
|
|
225
|
+
return acc;
|
|
226
|
+
}, new Map()), (0, rxjs_1.map)((subjectInfos) => {
|
|
227
|
+
for (const [subjectId, { parentSubject: parentSubjectId }] of subjectInfos.entries()) {
|
|
228
|
+
if (parentSubjectId) {
|
|
229
|
+
const parentSubjectInfo = subjectInfos.get(parentSubjectId);
|
|
230
|
+
(0, core_bentley_1.assert)(!!parentSubjectInfo);
|
|
231
|
+
parentSubjectInfo.childSubjects.add(subjectId);
|
|
101
232
|
}
|
|
102
|
-
return result;
|
|
103
|
-
})(),
|
|
104
|
-
]);
|
|
105
|
-
for (const [subjectId, { parentSubject: parentSubjectId }] of subjectInfos.entries()) {
|
|
106
|
-
if (parentSubjectId) {
|
|
107
|
-
const parentSubjectInfo = subjectInfos.get(parentSubjectId);
|
|
108
|
-
(0, core_bentley_1.assert)(!!parentSubjectInfo);
|
|
109
|
-
parentSubjectInfo.childSubjects.add(subjectId);
|
|
110
233
|
}
|
|
111
|
-
|
|
234
|
+
return subjectInfos;
|
|
235
|
+
})),
|
|
236
|
+
targetPartitionSubjects: this.queryModels().pipe((0, rxjs_1.reduce)((acc, model) => {
|
|
237
|
+
(0, Utils_js_2.pushToMap)(acc, model.id, model.parentId);
|
|
238
|
+
return acc;
|
|
239
|
+
}, new Map())),
|
|
240
|
+
}).pipe((0, rxjs_1.map)(({ subjectInfos, targetPartitionSubjects }) => {
|
|
112
241
|
for (const [partitionId, subjectIds] of targetPartitionSubjects) {
|
|
113
242
|
subjectIds.forEach((subjectId) => {
|
|
114
243
|
const subjectInfo = subjectInfos.get(subjectId);
|
|
@@ -117,13 +246,12 @@ class ModelsTreeIdsCache {
|
|
|
117
246
|
});
|
|
118
247
|
}
|
|
119
248
|
return subjectInfos;
|
|
120
|
-
})();
|
|
249
|
+
}), (0, rxjs_1.shareReplay)());
|
|
121
250
|
return this.#subjectInfos;
|
|
122
251
|
}
|
|
123
252
|
/** Returns ECInstanceIDs of Subjects that either have direct Model or at least one child Subject with a Model. */
|
|
124
|
-
|
|
125
|
-
this.#parentSubjectIds ??= (
|
|
126
|
-
const subjectInfos = await this.getSubjectInfos();
|
|
253
|
+
getParentSubjectIds() {
|
|
254
|
+
this.#parentSubjectIds ??= this.getSubjectInfos().pipe((0, rxjs_1.map)((subjectInfos) => {
|
|
127
255
|
const parentSubjectIds = new Set();
|
|
128
256
|
subjectInfos.forEach((subjectInfo, subjectId) => {
|
|
129
257
|
if (subjectInfo.childModels.size > 0) {
|
|
@@ -136,71 +264,73 @@ class ModelsTreeIdsCache {
|
|
|
136
264
|
}
|
|
137
265
|
});
|
|
138
266
|
return [...parentSubjectIds];
|
|
139
|
-
})();
|
|
267
|
+
}), (0, rxjs_1.shareReplay)());
|
|
140
268
|
return this.#parentSubjectIds;
|
|
141
269
|
}
|
|
142
270
|
/**
|
|
143
271
|
* Returns child subjects of the specified parent subjects as they're displayed in the hierarchy - taking into
|
|
144
272
|
* account `hideInHierarchy` flag.
|
|
145
273
|
*/
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
274
|
+
getChildSubjectIds(parentSubjectIds) {
|
|
275
|
+
return this.getSubjectInfos().pipe((0, rxjs_1.map)((subjectInfos) => {
|
|
276
|
+
const childSubjectIds = new Array();
|
|
277
|
+
parentSubjectIds.forEach((subjectId) => {
|
|
278
|
+
forEachChildSubject(subjectInfos, subjectId, (childSubjectId, childSubjectInfo) => {
|
|
279
|
+
if (!childSubjectInfo.hideInHierarchy) {
|
|
280
|
+
childSubjectIds.push(childSubjectId);
|
|
281
|
+
return "break";
|
|
282
|
+
}
|
|
283
|
+
return "continue";
|
|
284
|
+
});
|
|
156
285
|
});
|
|
157
|
-
|
|
158
|
-
|
|
286
|
+
return childSubjectIds;
|
|
287
|
+
}));
|
|
159
288
|
}
|
|
160
289
|
/** Returns ECInstanceIDs of all Models under specific parent Subjects, including their child Subjects, etc. */
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
290
|
+
getSubjectModelIds(subjectIds) {
|
|
291
|
+
return this.getSubjectInfos().pipe((0, rxjs_1.map)((subjectInfos) => {
|
|
292
|
+
const subjectStack = [...subjectIds];
|
|
293
|
+
const result = new Array();
|
|
294
|
+
while (true) {
|
|
295
|
+
const subjectId = subjectStack.pop();
|
|
296
|
+
if (subjectId === undefined) {
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
const subjectInfo = subjectInfos.get(subjectId);
|
|
300
|
+
if (!subjectInfo) {
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
result.push(...subjectInfo.childModels);
|
|
304
|
+
subjectStack.push(...subjectInfo.childSubjects);
|
|
173
305
|
}
|
|
174
|
-
result
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
return result;
|
|
306
|
+
return result;
|
|
307
|
+
}));
|
|
178
308
|
}
|
|
179
309
|
/** Returns ECInstanceIDs of Models under specific parent Subjects as they are displayed in the hierarchy. */
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
310
|
+
getChildSubjectModelIds(parentSubjectIds) {
|
|
311
|
+
return this.getSubjectInfos().pipe((0, rxjs_1.map)((subjectInfos) => {
|
|
312
|
+
const hiddenSubjectIds = new Array();
|
|
313
|
+
parentSubjectIds.forEach((subjectId) => {
|
|
314
|
+
forEachChildSubject(subjectInfos, subjectId, (childSubjectId, childSubjectInfo) => {
|
|
315
|
+
if (childSubjectInfo.hideInHierarchy) {
|
|
316
|
+
hiddenSubjectIds.push(childSubjectId);
|
|
317
|
+
return "continue";
|
|
318
|
+
}
|
|
319
|
+
return "break";
|
|
320
|
+
});
|
|
190
321
|
});
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
322
|
+
const modelIds = new Array();
|
|
323
|
+
[...parentSubjectIds, ...hiddenSubjectIds].forEach((subjectId) => {
|
|
324
|
+
const subjectInfo = subjectInfos.get(subjectId);
|
|
325
|
+
subjectInfo && modelIds.push(...subjectInfo.childModels);
|
|
326
|
+
});
|
|
327
|
+
return modelIds;
|
|
328
|
+
}));
|
|
198
329
|
}
|
|
199
|
-
|
|
330
|
+
createSubjectInstanceKeysPath(targetSubjectId) {
|
|
200
331
|
let entry = this.#subjectKeyPaths.get(targetSubjectId);
|
|
201
332
|
if (!entry) {
|
|
202
|
-
entry = (
|
|
203
|
-
const subjectInfos = await this.getSubjectInfos();
|
|
333
|
+
entry = this.getSubjectInfos().pipe((0, rxjs_1.map)((subjectInfos) => {
|
|
204
334
|
const result = new Array();
|
|
205
335
|
let currParentId = targetSubjectId;
|
|
206
336
|
while (currParentId) {
|
|
@@ -214,128 +344,111 @@ class ModelsTreeIdsCache {
|
|
|
214
344
|
currParentId = parentInfo?.parentSubject;
|
|
215
345
|
}
|
|
216
346
|
return result.reverse();
|
|
217
|
-
})();
|
|
347
|
+
}), (0, rxjs_1.shareReplay)());
|
|
218
348
|
this.#subjectKeyPaths.set(targetSubjectId, entry);
|
|
219
349
|
}
|
|
220
350
|
return entry;
|
|
221
351
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
352
|
+
queryModelCategories() {
|
|
353
|
+
return (0, rxjs_1.defer)(() => {
|
|
354
|
+
const query = `
|
|
355
|
+
SELECT
|
|
356
|
+
this.Model.Id modelId,
|
|
357
|
+
this.Category.Id categoryId,
|
|
358
|
+
m.IsPrivate isModelPrivate,
|
|
359
|
+
MAX(IIF(this.Parent.Id IS NULL, 1, 0)) isRootElementCategory
|
|
360
|
+
FROM BisCore.Model m
|
|
361
|
+
JOIN ${this.#hierarchyConfig.elementClassSpecification} this ON m.ECInstanceId = this.Model.Id
|
|
362
|
+
GROUP BY modelId, categoryId, isModelPrivate
|
|
363
|
+
`;
|
|
364
|
+
return this.#queryExecutor.createQueryReader({ ecsql: query }, { rowFormat: "ECSqlPropertyNames", limit: "unbounded", restartToken: `${this.#componentName}/${this.#componentId}/model-categories` });
|
|
365
|
+
}).pipe((0, rxjs_1.map)((row) => {
|
|
366
|
+
return { modelId: row.modelId, categoryId: row.categoryId, isModelPrivate: !!row.isModelPrivate, isRootElementCategory: !!row.isRootElementCategory };
|
|
367
|
+
}));
|
|
236
368
|
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}
|
|
369
|
+
queryModeledElements() {
|
|
370
|
+
return (0, rxjs_1.defer)(() => {
|
|
371
|
+
const query = `
|
|
372
|
+
SELECT
|
|
373
|
+
pe.ECInstanceId modeledElementId,
|
|
374
|
+
pe.Category.Id categoryId,
|
|
375
|
+
pe.Model.Id modelId
|
|
376
|
+
FROM BisCore.Model m
|
|
377
|
+
JOIN ${this.#hierarchyConfig.elementClassSpecification} pe ON pe.ECInstanceId = m.ModeledElement.Id
|
|
378
|
+
WHERE
|
|
379
|
+
m.IsPrivate = false
|
|
380
|
+
AND m.ECInstanceId IN (SELECT Model.Id FROM ${this.#hierarchyConfig.elementClassSpecification})
|
|
381
|
+
`;
|
|
382
|
+
return this.#queryExecutor.createQueryReader({ ecsql: query }, { rowFormat: "ECSqlPropertyNames", limit: "unbounded", restartToken: `${this.#componentName}/${this.#componentId}/modeled-elements` });
|
|
383
|
+
}).pipe((0, rxjs_1.map)((row) => {
|
|
384
|
+
return { modelId: row.modelId, categoryId: row.categoryId, modeledElementId: row.modeledElementId };
|
|
385
|
+
}));
|
|
252
386
|
}
|
|
253
|
-
|
|
254
|
-
this.#modelWithCategoryModeledElements ??= (
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
if (entry === undefined) {
|
|
260
|
-
modelWithCategoryModeledElements.set(key, new Set([modeledElementId]));
|
|
261
|
-
}
|
|
262
|
-
else {
|
|
263
|
-
entry.add(modeledElementId);
|
|
264
|
-
}
|
|
387
|
+
getModelWithCategoryModeledElements() {
|
|
388
|
+
this.#modelWithCategoryModeledElements ??= this.queryModeledElements().pipe((0, rxjs_1.reduce)((acc, { modelId, categoryId, modeledElementId }) => {
|
|
389
|
+
const key = `${modelId}-${categoryId}`;
|
|
390
|
+
const entry = acc.get(key);
|
|
391
|
+
if (entry === undefined) {
|
|
392
|
+
acc.set(key, new Set([modeledElementId]));
|
|
265
393
|
}
|
|
266
|
-
|
|
267
|
-
|
|
394
|
+
else {
|
|
395
|
+
entry.add(modeledElementId);
|
|
396
|
+
}
|
|
397
|
+
return acc;
|
|
398
|
+
}, new Map()), (0, rxjs_1.shareReplay)());
|
|
268
399
|
return this.#modelWithCategoryModeledElements;
|
|
269
400
|
}
|
|
270
|
-
|
|
271
|
-
this.#modelInfos ??= (
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
}
|
|
279
|
-
else {
|
|
280
|
-
modelInfos.set(modelId, { categories: new Map([[categoryId, { isRootElementCategory }]]), isModelPrivate });
|
|
281
|
-
}
|
|
401
|
+
getModelInfos() {
|
|
402
|
+
this.#modelInfos ??= this.queryModelCategories().pipe((0, rxjs_1.reduce)((acc, { modelId, categoryId, isModelPrivate, isRootElementCategory }) => {
|
|
403
|
+
const entry = acc.get(modelId);
|
|
404
|
+
if (entry) {
|
|
405
|
+
entry.categories.set(categoryId, { isRootElementCategory });
|
|
406
|
+
entry.isModelPrivate = isModelPrivate;
|
|
407
|
+
}
|
|
408
|
+
else {
|
|
409
|
+
acc.set(modelId, { categories: new Map([[categoryId, { isRootElementCategory }]]), isModelPrivate });
|
|
282
410
|
}
|
|
283
|
-
return
|
|
284
|
-
})();
|
|
411
|
+
return acc;
|
|
412
|
+
}, new Map()), (0, rxjs_1.shareReplay)());
|
|
285
413
|
return this.#modelInfos;
|
|
286
414
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
});
|
|
293
|
-
return result;
|
|
415
|
+
getAllCategories() {
|
|
416
|
+
return this.getModelInfos().pipe((0, rxjs_1.mergeMap)((modelInfos) => modelInfos.values()), (0, rxjs_1.mergeMap)(({ categories }) => categories.keys()), (0, rxjs_1.reduce)((acc, categoryId) => {
|
|
417
|
+
acc.add(categoryId);
|
|
418
|
+
return acc;
|
|
419
|
+
}, new Set()));
|
|
294
420
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
const categories = modelInfos.get(modelId)?.categories.keys();
|
|
298
|
-
return categories ? [...categories] : [];
|
|
421
|
+
getModelCategories(modelId) {
|
|
422
|
+
return this.getModelInfos().pipe((0, rxjs_1.mergeMap)((modelInfos) => modelInfos.get(modelId)?.categories.keys() ?? []), (0, rxjs_1.toArray)());
|
|
299
423
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
424
|
+
hasSubModel(elementId) {
|
|
425
|
+
return this.getModelInfos().pipe((0, rxjs_1.map)((modelInfos) => {
|
|
426
|
+
const modeledElementInfo = modelInfos.get(elementId);
|
|
427
|
+
if (!modeledElementInfo) {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
return !modeledElementInfo.isModelPrivate;
|
|
431
|
+
}));
|
|
307
432
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
const result = new Array();
|
|
311
|
-
for (const categoryId of core_bentley_1.Id64.iterable(categoryIds)) {
|
|
433
|
+
getCategoriesModeledElements(modelId, categoryIds) {
|
|
434
|
+
return this.getModelWithCategoryModeledElements().pipe((0, rxjs_1.mergeMap)((modelWithCategoryModeledElements) => (0, rxjs_1.from)(core_bentley_1.Id64.iterable(categoryIds)).pipe((0, rxjs_1.reduce)((acc, categoryId) => {
|
|
312
435
|
const entry = modelWithCategoryModeledElements.get(`${modelId}-${categoryId}`);
|
|
313
436
|
if (entry !== undefined) {
|
|
314
|
-
|
|
437
|
+
acc.push(...entry);
|
|
315
438
|
}
|
|
316
|
-
|
|
317
|
-
|
|
439
|
+
return acc;
|
|
440
|
+
}, new Array()))));
|
|
318
441
|
}
|
|
319
|
-
|
|
442
|
+
createModelInstanceKeyPaths(modelId) {
|
|
320
443
|
let entry = this.#modelKeyPaths.get(modelId);
|
|
321
444
|
if (!entry) {
|
|
322
|
-
entry = (
|
|
323
|
-
const result = new Array();
|
|
324
|
-
const subjectInfos = (await this.getSubjectInfos()).entries();
|
|
325
|
-
for (const [modelSubjectId, subjectInfo] of subjectInfos) {
|
|
326
|
-
if (subjectInfo.childModels.has(modelId)) {
|
|
327
|
-
const subjectPath = await this.createSubjectInstanceKeysPath(modelSubjectId);
|
|
328
|
-
result.push([...subjectPath, { className: "BisCore.GeometricModel3d", id: modelId }]);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
return result;
|
|
332
|
-
})();
|
|
445
|
+
entry = this.getSubjectInfos().pipe((0, rxjs_1.mergeMap)((subjectInfos) => subjectInfos.entries()), (0, rxjs_1.filter)(([_, subjectInfo]) => subjectInfo.childModels.has(modelId)), (0, rxjs_1.mergeMap)(([modelSubjectId]) => this.createSubjectInstanceKeysPath(modelSubjectId).pipe((0, rxjs_1.map)((path) => [...path, { className: "BisCore.GeometricModel3d", id: modelId }]))), (0, rxjs_1.toArray)(), (0, rxjs_1.shareReplay)());
|
|
333
446
|
this.#modelKeyPaths.set(modelId, entry);
|
|
334
447
|
}
|
|
335
448
|
return entry;
|
|
336
449
|
}
|
|
337
|
-
|
|
338
|
-
return (0,
|
|
450
|
+
queryCategoryElementCounts(input) {
|
|
451
|
+
return (0, rxjs_1.from)(input).pipe((0, rxjs_1.reduce)((acc, { modelId, categoryId }) => {
|
|
339
452
|
const entry = acc.get(modelId);
|
|
340
453
|
if (!entry) {
|
|
341
454
|
acc.set(modelId, new Set([categoryId]));
|
|
@@ -347,73 +460,64 @@ class ModelsTreeIdsCache {
|
|
|
347
460
|
}, new Map()), (0, rxjs_1.mergeMap)((modelCategoryMap) => modelCategoryMap.entries()), (0, rxjs_1.map)(([modelId, categoryIds]) => `Model.Id = ${modelId} AND Category.Id IN (${[...categoryIds].join(", ")})`),
|
|
348
461
|
// we may have thousands of where clauses here, and sending a single query with all of them could take a
|
|
349
462
|
// long time - instead, split it into smaller chunks
|
|
350
|
-
(0, rxjs_1.bufferCount)(100), (0, rxjs_1.mergeMap)(
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
)
|
|
463
|
+
(0, rxjs_1.bufferCount)(100), (0, rxjs_1.mergeMap)((whereClauses) => (0, rxjs_1.defer)(() => this.#queryExecutor.createQueryReader({
|
|
464
|
+
ctes: [
|
|
465
|
+
`
|
|
466
|
+
CategoryElements(id, modelId, categoryId) AS (
|
|
467
|
+
SELECT ECInstanceId, Model.Id, Category.Id
|
|
468
|
+
FROM ${this.#hierarchyConfig.elementClassSpecification}
|
|
469
|
+
WHERE
|
|
470
|
+
Parent.Id IS NULL
|
|
471
|
+
AND (
|
|
472
|
+
${whereClauses.join(" OR ")}
|
|
473
|
+
)
|
|
362
474
|
|
|
363
|
-
|
|
475
|
+
UNION ALL
|
|
364
476
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
477
|
+
SELECT c.ECInstanceId, p.modelId, p.categoryId
|
|
478
|
+
FROM ${this.#hierarchyConfig.elementClassSpecification} c
|
|
479
|
+
JOIN CategoryElements p ON c.Parent.Id = p.id
|
|
480
|
+
)
|
|
481
|
+
`,
|
|
482
|
+
],
|
|
483
|
+
ecsql: `
|
|
484
|
+
SELECT modelId, categoryId, COUNT(id) elementsCount
|
|
485
|
+
FROM CategoryElements
|
|
486
|
+
GROUP BY modelId, categoryId
|
|
369
487
|
`,
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
restartToken: `${this.#componentName}/${this.#componentId}/category-element-counts/${core_bentley_1.Guid.createValue()}`,
|
|
488
|
+
}, {
|
|
489
|
+
rowFormat: "ECSqlPropertyNames",
|
|
490
|
+
limit: "unbounded",
|
|
491
|
+
restartToken: `${this.#componentName}/${this.#componentId}/category-element-counts/${core_bentley_1.Guid.createValue()}`,
|
|
492
|
+
}))), (0, Utils_js_1.releaseMainThreadOnItemsCount)(500), (0, rxjs_1.reduce)(({ acc, createKey }, row) => {
|
|
493
|
+
acc.set(createKey({ modelId: row.modelId, categoryId: row.categoryId }), {
|
|
494
|
+
modelId: row.modelId,
|
|
495
|
+
categoryId: row.categoryId,
|
|
496
|
+
elementsCount: row.elementsCount,
|
|
380
497
|
});
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
498
|
+
return { acc, createKey };
|
|
499
|
+
}, {
|
|
500
|
+
acc: new Map(),
|
|
501
|
+
createKey: (keyProps) => `${keyProps.modelId}-${keyProps.categoryId}`,
|
|
502
|
+
}), (0, rxjs_1.mergeMap)(({ acc: result, createKey }) => {
|
|
385
503
|
input.forEach(({ modelId, categoryId }) => {
|
|
386
|
-
if (!result.
|
|
387
|
-
result.
|
|
504
|
+
if (!result.has(createKey({ modelId, categoryId }))) {
|
|
505
|
+
result.set(createKey({ modelId, categoryId }), { categoryId, modelId, elementsCount: 0 });
|
|
388
506
|
}
|
|
389
507
|
});
|
|
390
|
-
return result;
|
|
391
|
-
}), (0, rxjs_1.
|
|
508
|
+
return (0, rxjs_1.from)(result.values());
|
|
509
|
+
}), (0, rxjs_1.toArray)());
|
|
392
510
|
}
|
|
393
|
-
|
|
511
|
+
getCategoryElementsCount(modelId, categoryId) {
|
|
394
512
|
return this.#categoryElementCounts.getCategoryElementsCount(modelId, categoryId);
|
|
395
513
|
}
|
|
396
|
-
|
|
514
|
+
createCategoryInstanceKeyPaths(categoryId) {
|
|
397
515
|
let entry = this.#categoryKeyPaths.get(categoryId);
|
|
398
516
|
if (!entry) {
|
|
399
|
-
entry = (
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
const categoryEntry = modelInfo.categories.get(categoryId);
|
|
404
|
-
if (categoryEntry?.isRootElementCategory) {
|
|
405
|
-
result.add(modelId);
|
|
406
|
-
}
|
|
407
|
-
});
|
|
408
|
-
const categoryPaths = new Array();
|
|
409
|
-
for (const categoryModelId of [...result]) {
|
|
410
|
-
const modelPaths = await this.createModelInstanceKeyPaths(categoryModelId);
|
|
411
|
-
for (const modelPath of modelPaths) {
|
|
412
|
-
categoryPaths.push([...modelPath, { className: "BisCore.SpatialCategory", id: categoryId }]);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
return categoryPaths;
|
|
416
|
-
})();
|
|
517
|
+
entry = this.getModelInfos().pipe((0, rxjs_1.mergeMap)((modelInfos) => modelInfos.entries()), (0, rxjs_1.filter)(([_, modelInfo]) => !!modelInfo.categories.get(categoryId)?.isRootElementCategory), (0, rxjs_1.mergeMap)(([categoryModelId]) => this.createModelInstanceKeyPaths(categoryModelId)), (0, rxjs_1.mergeMap)((modelPaths) => modelPaths), (0, rxjs_1.reduce)((acc, modelPath) => {
|
|
518
|
+
acc.push([...modelPath, { className: "BisCore.SpatialCategory", id: categoryId }]);
|
|
519
|
+
return acc;
|
|
520
|
+
}, new Array()), (0, rxjs_1.shareReplay)());
|
|
417
521
|
this.#categoryKeyPaths.set(categoryId, entry);
|
|
418
522
|
}
|
|
419
523
|
return entry;
|
|
@@ -437,7 +541,7 @@ class ModelCategoryElementsCountCache {
|
|
|
437
541
|
#subscription;
|
|
438
542
|
constructor(loader) {
|
|
439
543
|
this.#subscription = this.#requestsStream
|
|
440
|
-
.pipe((0, rxjs_1.bufferTime)(20), (0, rxjs_1.filter)((requests) => requests.length > 0), (0, rxjs_1.mergeMap)(
|
|
544
|
+
.pipe((0, rxjs_1.bufferTime)(20), (0, rxjs_1.filter)((requests) => requests.length > 0), (0, rxjs_1.mergeMap)((requests) => loader(requests)), (0, rxjs_1.mergeAll)())
|
|
441
545
|
.subscribe({
|
|
442
546
|
next: ({ modelId, categoryId, elementsCount }) => {
|
|
443
547
|
const subject = this.#cache.get(`${modelId}${categoryId}`);
|
|
@@ -449,16 +553,16 @@ class ModelCategoryElementsCountCache {
|
|
|
449
553
|
[Symbol.dispose]() {
|
|
450
554
|
this.#subscription.unsubscribe();
|
|
451
555
|
}
|
|
452
|
-
|
|
556
|
+
getCategoryElementsCount(modelId, categoryId) {
|
|
453
557
|
const cacheKey = `${modelId}${categoryId}`;
|
|
454
558
|
let result = this.#cache.get(cacheKey);
|
|
455
559
|
if (result !== undefined) {
|
|
456
|
-
return (0, rxjs_1.
|
|
560
|
+
return (0, rxjs_1.from)(result).pipe((0, rxjs_1.take)(1));
|
|
457
561
|
}
|
|
458
562
|
result = new rxjs_1.ReplaySubject(1);
|
|
459
563
|
this.#cache.set(cacheKey, result);
|
|
460
564
|
this.#requestsStream.next({ modelId, categoryId });
|
|
461
|
-
return (0, rxjs_1.
|
|
565
|
+
return (0, rxjs_1.from)(result).pipe((0, rxjs_1.take)(1));
|
|
462
566
|
}
|
|
463
567
|
}
|
|
464
568
|
//# sourceMappingURL=ModelsTreeIdsCache.js.map
|