@itwin/tree-widget-react 3.15.0 → 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 +22 -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 +5 -13
- package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js +70 -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 +189 -197
- 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 +5 -13
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js +71 -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 +192 -200
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js.map +1 -1
- package/package.json +8 -8
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
3
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
import { concat, concatAll, defer, distinct, EMPTY, filter, firstValueFrom, forkJoin, from, fromEventPattern, map, merge, mergeMap, of, reduce, shareReplay, startWith, Subject, take, takeUntil, tap, toArray, } from "rxjs";
|
|
5
|
+
import { concat, concatAll, defaultIfEmpty, defer, distinct, EMPTY, filter, firstValueFrom, forkJoin, from, fromEventPattern, map, merge, mergeMap, of, reduce, shareReplay, startWith, Subject, take, takeUntil, tap, toArray, } from "rxjs";
|
|
6
6
|
import { assert, Id64 } from "@itwin/core-bentley";
|
|
7
7
|
import { PerModelCategoryVisibility } from "@itwin/core-frontend";
|
|
8
8
|
import { HierarchyNode, HierarchyNodeKey } from "@itwin/presentation-hierarchies";
|
|
9
|
-
import {
|
|
9
|
+
import { enableCategoryDisplay, loadCategoriesFromViewport } from "../../common/CategoriesVisibilityUtils.js";
|
|
10
10
|
import { reduceWhile, toVoidPromise } from "../../common/Rxjs.js";
|
|
11
11
|
import { createVisibilityStatus } from "../../common/Tooltip.js";
|
|
12
12
|
import { createVisibilityHandlerResult } from "../../common/UseHierarchyVisibility.js";
|
|
13
|
-
import { releaseMainThreadOnItemsCount } from "../Utils.js";
|
|
13
|
+
import { getIdsFromChildrenTree, releaseMainThreadOnItemsCount } from "../Utils.js";
|
|
14
14
|
import { AlwaysAndNeverDrawnElementInfo } from "./AlwaysAndNeverDrawnElementInfo.js";
|
|
15
15
|
import { createFilteredTree, parseCategoryKey } from "./FilteredTree.js";
|
|
16
16
|
import { ModelsTreeNode } from "./ModelsTreeNode.js";
|
|
@@ -23,49 +23,49 @@ export function createModelsTreeVisibilityHandler(props) {
|
|
|
23
23
|
return new ModelsTreeVisibilityHandlerImpl(props);
|
|
24
24
|
}
|
|
25
25
|
class ModelsTreeVisibilityHandlerImpl {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
constructor(
|
|
35
|
-
this
|
|
36
|
-
this
|
|
37
|
-
this
|
|
38
|
-
this
|
|
39
|
-
this
|
|
40
|
-
this.
|
|
26
|
+
#eventListener;
|
|
27
|
+
#alwaysAndNeverDrawnElements;
|
|
28
|
+
#idsCache;
|
|
29
|
+
#filteredTree;
|
|
30
|
+
#elementChangeQueue = new Subject();
|
|
31
|
+
#subscriptions = [];
|
|
32
|
+
#changeRequest = new Subject();
|
|
33
|
+
#props;
|
|
34
|
+
constructor(props) {
|
|
35
|
+
this.#props = props;
|
|
36
|
+
this.#eventListener = createVisibilityChangeEventListener(this.#props.viewport);
|
|
37
|
+
this.#alwaysAndNeverDrawnElements = new AlwaysAndNeverDrawnElementInfo(this.#props.viewport, this.#props.componentId);
|
|
38
|
+
this.#idsCache = this.#props.idsCache;
|
|
39
|
+
this.#filteredTree = this.#props.filteredPaths ? createFilteredTree(this.#props.imodelAccess, this.#props.filteredPaths) : undefined;
|
|
40
|
+
this.#subscriptions.push(this.#elementChangeQueue.pipe(concatAll()).subscribe());
|
|
41
41
|
}
|
|
42
42
|
get onVisibilityChange() {
|
|
43
|
-
return this.
|
|
43
|
+
return this.#eventListener.onVisibilityChange;
|
|
44
44
|
}
|
|
45
45
|
async getVisibilityStatus(node) {
|
|
46
46
|
return firstValueFrom(this.getVisibilityStatusObs(node).pipe(
|
|
47
47
|
// unsubscribe from the observable if the change request for this node is received
|
|
48
|
-
takeUntil(this.
|
|
48
|
+
takeUntil(this.#changeRequest.pipe(filter(({ key, depth }) => depth === node.parentKeys.length && HierarchyNodeKey.equals(node.key, key)))),
|
|
49
49
|
// unsubscribe if visibility changes
|
|
50
50
|
takeUntil(fromEventPattern((handler) => {
|
|
51
|
-
this.
|
|
51
|
+
this.#eventListener.onVisibilityChange.addListener(handler);
|
|
52
52
|
}, (handler) => {
|
|
53
|
-
this.
|
|
54
|
-
}))));
|
|
53
|
+
this.#eventListener.onVisibilityChange.removeListener(handler);
|
|
54
|
+
})), defaultIfEmpty(createVisibilityStatus("hidden"))));
|
|
55
55
|
}
|
|
56
56
|
async changeVisibility(node, shouldDisplay) {
|
|
57
57
|
// notify about new change request
|
|
58
|
-
this.
|
|
58
|
+
this.#changeRequest.next({ key: node.key, depth: node.parentKeys.length });
|
|
59
59
|
const changeObservable = this.changeVisibilityObs(node, shouldDisplay).pipe(
|
|
60
60
|
// unsubscribe from the observable if the change request for this node is received
|
|
61
|
-
takeUntil(this.
|
|
61
|
+
takeUntil(this.#changeRequest.pipe(filter(({ key, depth }) => depth === node.parentKeys.length && HierarchyNodeKey.equals(node.key, key)))), tap({
|
|
62
62
|
subscribe: () => {
|
|
63
|
-
this.
|
|
64
|
-
this.
|
|
63
|
+
this.#eventListener.suppressChangeEvents();
|
|
64
|
+
this.#alwaysAndNeverDrawnElements.suppressChangeEvents();
|
|
65
65
|
},
|
|
66
66
|
finalize: () => {
|
|
67
|
-
this.
|
|
68
|
-
this.
|
|
67
|
+
this.#eventListener.resumeChangeEvents();
|
|
68
|
+
this.#alwaysAndNeverDrawnElements.resumeChangeEvents();
|
|
69
69
|
},
|
|
70
70
|
}));
|
|
71
71
|
return toVoidPromise(changeObservable);
|
|
@@ -74,20 +74,23 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
74
74
|
this[Symbol.dispose]();
|
|
75
75
|
}
|
|
76
76
|
[Symbol.dispose]() {
|
|
77
|
-
this
|
|
78
|
-
this
|
|
79
|
-
this.
|
|
77
|
+
this.#eventListener[Symbol.dispose]();
|
|
78
|
+
this.#alwaysAndNeverDrawnElements[Symbol.dispose]();
|
|
79
|
+
this.#subscriptions.forEach((x) => x.unsubscribe());
|
|
80
80
|
}
|
|
81
81
|
getVisibilityStatusObs(node) {
|
|
82
|
-
if (node.filtering?.filteredChildrenIdentifierPaths?.length && !node.filtering.isFilterTarget) {
|
|
83
|
-
return this.getFilteredNodeVisibility({ node });
|
|
84
|
-
}
|
|
85
82
|
if (HierarchyNode.isClassGroupingNode(node)) {
|
|
83
|
+
if (node.extendedData?.hasDirectNonFilteredTargets && !node.filtering?.hasFilterTargetAncestor) {
|
|
84
|
+
return this.getFilteredNodeVisibility({ node });
|
|
85
|
+
}
|
|
86
86
|
return this.getClassGroupingNodeDisplayStatus(node);
|
|
87
87
|
}
|
|
88
88
|
if (!HierarchyNode.isInstancesNode(node)) {
|
|
89
89
|
return of(createVisibilityStatus("disabled"));
|
|
90
90
|
}
|
|
91
|
+
if (node.filtering?.filteredChildrenIdentifierPaths?.length && !node.filtering.isFilterTarget) {
|
|
92
|
+
return this.getFilteredNodeVisibility({ node });
|
|
93
|
+
}
|
|
91
94
|
if (ModelsTreeNode.isSubjectNode(node)) {
|
|
92
95
|
// note: subject nodes may be merged to represent multiple subject instances
|
|
93
96
|
return this.getSubjectNodeVisibilityStatus({ subjectIds: node.key.instanceKeys.map((key) => key.id) });
|
|
@@ -110,13 +113,14 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
110
113
|
return of(createVisibilityStatus("disabled"));
|
|
111
114
|
}
|
|
112
115
|
return this.getElementDisplayStatus({
|
|
113
|
-
|
|
116
|
+
elementIds: node.key.instanceKeys.map(({ id }) => id),
|
|
114
117
|
modelId,
|
|
115
118
|
categoryId,
|
|
116
119
|
});
|
|
117
120
|
}
|
|
118
121
|
getFilteredNodeVisibility(props) {
|
|
119
|
-
|
|
122
|
+
assert(this.#filteredTree !== undefined);
|
|
123
|
+
return from(this.#filteredTree).pipe(map((filteredTree) => filteredTree.getVisibilityChangeTargets(props.node)), mergeMap(({ subjects, models, categories, elements }) => {
|
|
120
124
|
const observables = new Array();
|
|
121
125
|
if (subjects?.size) {
|
|
122
126
|
observables.push(this.getSubjectNodeVisibilityStatus({ subjectIds: [...subjects], ignoreTooltip: true }));
|
|
@@ -131,9 +135,13 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
131
135
|
})));
|
|
132
136
|
}
|
|
133
137
|
if (elements?.size) {
|
|
134
|
-
observables.push(from(elements).pipe(releaseMainThreadOnItemsCount(50), mergeMap(([categoryKey,
|
|
138
|
+
observables.push(from(elements).pipe(releaseMainThreadOnItemsCount(50), mergeMap(([categoryKey, elementsMap]) => {
|
|
135
139
|
const { modelId, categoryId } = parseCategoryKey(categoryKey);
|
|
136
|
-
return
|
|
140
|
+
return this.getElementsDisplayStatus({
|
|
141
|
+
elementIds: [...elementsMap.keys()],
|
|
142
|
+
modelId,
|
|
143
|
+
categoryId,
|
|
144
|
+
});
|
|
137
145
|
})));
|
|
138
146
|
}
|
|
139
147
|
return merge(...observables);
|
|
@@ -141,49 +149,49 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
141
149
|
}
|
|
142
150
|
getSubjectNodeVisibilityStatus({ subjectIds, ignoreTooltip }) {
|
|
143
151
|
const result = defer(() => {
|
|
144
|
-
if (!this.
|
|
152
|
+
if (!this.#props.viewport.view.isSpatialView()) {
|
|
145
153
|
return of(createVisibilityStatus("disabled", getTooltipOptions("modelsTree.subject.nonSpatialView", ignoreTooltip)));
|
|
146
154
|
}
|
|
147
|
-
return from(this.
|
|
155
|
+
return from(this.#idsCache.getSubjectModelIds(subjectIds)).pipe(mergeMap((modelIds) => this.getModelVisibilityStatus({ modelIds, ignoreTooltip: true })), mergeVisibilityStatuses({
|
|
148
156
|
visible: "modelsTree.subject.allModelsVisible",
|
|
149
157
|
hidden: "modelsTree.subject.allModelsHidden",
|
|
150
158
|
partial: "modelsTree.subject.someModelsHidden",
|
|
151
159
|
}, ignoreTooltip));
|
|
152
160
|
});
|
|
153
|
-
return createVisibilityHandlerResult(this, { ids: subjectIds }, result, this.
|
|
161
|
+
return createVisibilityHandlerResult(this, { ids: subjectIds }, result, this.#props.overrides?.getSubjectNodeVisibility);
|
|
154
162
|
}
|
|
155
163
|
getModelVisibilityStatus({ modelIds, ignoreTooltip }) {
|
|
156
164
|
const result = defer(() => {
|
|
157
|
-
const viewport = this.
|
|
165
|
+
const viewport = this.#props.viewport;
|
|
158
166
|
if (!viewport.view.isSpatialView()) {
|
|
159
167
|
return of(createVisibilityStatus("disabled", getTooltipOptions("modelsTree.model.nonSpatialView", ignoreTooltip)));
|
|
160
168
|
}
|
|
161
|
-
return from(modelIds).pipe(distinct(), mergeMap((modelId) => {
|
|
169
|
+
return from(Id64.iterable(modelIds)).pipe(distinct(), mergeMap((modelId) => {
|
|
162
170
|
if (!viewport.view.viewsModel(modelId)) {
|
|
163
|
-
return from(this.
|
|
171
|
+
return from(this.#idsCache.getModelCategories(modelId)).pipe(mergeMap((categoryIds) => from(this.#idsCache.getCategoriesModeledElements(modelId, categoryIds))), this.getSubModeledElementsVisibilityStatus({
|
|
164
172
|
ignoreTooltips: ignoreTooltip,
|
|
165
173
|
haveSubModel: "yes",
|
|
166
174
|
tooltips: { visible: undefined, hidden: "modelsTree.model.hiddenThroughModelSelector", partial: "modelsTree.model.someSubModelsVisible" },
|
|
167
175
|
parentNodeVisibilityStatus: createVisibilityStatus("hidden"),
|
|
168
176
|
}));
|
|
169
177
|
}
|
|
170
|
-
return from(this.
|
|
178
|
+
return from(this.#idsCache.getModelCategories(modelId)).pipe(mergeMap((categoryIds) => categoryIds.length === 0 ? of(createVisibilityStatus("visible")) : this.getCategoryDisplayStatus({ modelId, categoryIds, ignoreTooltip: true })), mergeVisibilityStatuses({
|
|
171
179
|
visible: "modelsTree.model.allCategoriesVisible",
|
|
172
180
|
partial: "modelsTree.model.someCategoriesHidden",
|
|
173
181
|
hidden: "modelsTree.model.allCategoriesHidden",
|
|
174
182
|
}));
|
|
175
183
|
}), mergeVisibilityStatuses());
|
|
176
184
|
});
|
|
177
|
-
return createVisibilityHandlerResult(this, { ids: modelIds }, result, this.
|
|
185
|
+
return createVisibilityHandlerResult(this, { ids: modelIds }, result, this.#props.overrides?.getModelDisplayStatus);
|
|
178
186
|
}
|
|
179
187
|
getDefaultCategoryVisibilityStatus({ modelId, categoryIds, ignoreTooltip, }) {
|
|
180
|
-
const viewport = this.
|
|
188
|
+
const viewport = this.#props.viewport;
|
|
181
189
|
if (!viewport.view.viewsModel(modelId) || Id64.sizeOf(categoryIds) === 0) {
|
|
182
190
|
return createVisibilityStatus("hidden", getTooltipOptions("modelsTree.category.hiddenThroughModel", ignoreTooltip));
|
|
183
191
|
}
|
|
184
192
|
let visibility = "unknown";
|
|
185
193
|
for (const categoryId of Id64.iterable(categoryIds)) {
|
|
186
|
-
const override = this.
|
|
194
|
+
const override = this.#props.viewport.perModelCategoryVisibility.getOverride(modelId, categoryId);
|
|
187
195
|
if (override === PerModelCategoryVisibility.Override.Show) {
|
|
188
196
|
if (visibility === "hidden") {
|
|
189
197
|
return createVisibilityStatus("partial");
|
|
@@ -212,8 +220,8 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
212
220
|
}
|
|
213
221
|
getCategoryDisplayStatus({ ignoreTooltip, ...props }) {
|
|
214
222
|
const result = defer(() => {
|
|
215
|
-
if (!this.
|
|
216
|
-
return from(this.
|
|
223
|
+
if (!this.#props.viewport.view.viewsModel(props.modelId)) {
|
|
224
|
+
return from(this.#idsCache.getCategoriesModeledElements(props.modelId, props.categoryIds)).pipe(this.getSubModeledElementsVisibilityStatus({
|
|
217
225
|
ignoreTooltips: ignoreTooltip,
|
|
218
226
|
parentNodeVisibilityStatus: createVisibilityStatus("hidden"),
|
|
219
227
|
tooltips: {
|
|
@@ -237,7 +245,7 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
237
245
|
: this.getDefaultCategoryVisibilityStatus({ modelId: props.modelId, categoryIds: props.categoryIds }),
|
|
238
246
|
ignoreTooltip,
|
|
239
247
|
}).pipe(mergeMap((visibilityStatusAlwaysAndNeverDraw) => {
|
|
240
|
-
return from(this.
|
|
248
|
+
return from(this.#idsCache.getCategoriesModeledElements(props.modelId, props.categoryIds)).pipe(this.getSubModeledElementsVisibilityStatus({
|
|
241
249
|
tooltips: {
|
|
242
250
|
visible: undefined,
|
|
243
251
|
hidden: "modelsTree.category.allElementsAndSubModelsHidden",
|
|
@@ -249,14 +257,30 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
249
257
|
}));
|
|
250
258
|
}));
|
|
251
259
|
});
|
|
252
|
-
return createVisibilityHandlerResult(this, props, result, this.
|
|
260
|
+
return createVisibilityHandlerResult(this, props, result, this.#props.overrides?.getCategoryDisplayStatus);
|
|
253
261
|
}
|
|
254
262
|
getClassGroupingNodeDisplayStatus(node) {
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
263
|
+
const { elementIds, modelId, categoryId } = this.getGroupingNodeInfo(node);
|
|
264
|
+
const result = this.getElementsDisplayStatus({
|
|
265
|
+
elementIds,
|
|
266
|
+
modelId,
|
|
267
|
+
categoryId,
|
|
268
|
+
});
|
|
269
|
+
return createVisibilityHandlerResult(this, { node }, result, this.#props.overrides?.getElementGroupingNodeDisplayStatus);
|
|
270
|
+
}
|
|
271
|
+
getElementDisplayStatus({ elementIds, modelId, categoryId, }) {
|
|
272
|
+
const result = this.getElementsDisplayStatus({
|
|
273
|
+
elementIds,
|
|
274
|
+
modelId,
|
|
275
|
+
categoryId,
|
|
276
|
+
});
|
|
277
|
+
return createVisibilityHandlerResult(this, { elementId: elementIds[0], modelId, categoryId }, result, this.#props.overrides?.getElementDisplayStatus);
|
|
278
|
+
}
|
|
279
|
+
getElementsDisplayStatus(props) {
|
|
280
|
+
return defer(() => {
|
|
281
|
+
const { modelId, categoryId, elementIds } = props;
|
|
282
|
+
if (!this.#props.viewport.view.viewsModel(modelId)) {
|
|
283
|
+
return of(elementIds).pipe(this.getSubModeledElementsVisibilityStatus({
|
|
260
284
|
tooltips: {
|
|
261
285
|
visible: undefined,
|
|
262
286
|
hidden: undefined,
|
|
@@ -279,7 +303,7 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
279
303
|
noElementsInExclusiveAlwaysDrawnList: "modelsTree.groupingNode.allElementsHidden",
|
|
280
304
|
},
|
|
281
305
|
}).pipe(mergeMap((visibilityStatusAlwaysAndNeverDraw) => {
|
|
282
|
-
return of(
|
|
306
|
+
return of(elementIds).pipe(this.getSubModeledElementsVisibilityStatus({
|
|
283
307
|
tooltips: {
|
|
284
308
|
visible: undefined,
|
|
285
309
|
hidden: "modelsTree.groupingNode.allElementsAndSubModelsHidden",
|
|
@@ -290,113 +314,58 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
290
314
|
}));
|
|
291
315
|
}));
|
|
292
316
|
});
|
|
293
|
-
return createVisibilityHandlerResult(this, { node }, result, this._props.overrides?.getElementGroupingNodeDisplayStatus);
|
|
294
317
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
return
|
|
318
|
+
/** Changes visibility of the items represented by the tree node. */
|
|
319
|
+
changeVisibilityObs(node, on) {
|
|
320
|
+
const changeObs = defer(() => {
|
|
321
|
+
if (HierarchyNode.isClassGroupingNode(node)) {
|
|
322
|
+
if (node.extendedData?.hasDirectNonFilteredTargets && !node.filtering?.hasFilterTargetAncestor) {
|
|
323
|
+
return this.changeFilteredNodeVisibility({ node, on });
|
|
324
|
+
}
|
|
325
|
+
return this.changeElementGroupingNodeState(node, on);
|
|
303
326
|
}
|
|
304
|
-
if (
|
|
305
|
-
return
|
|
327
|
+
if (!HierarchyNode.isInstancesNode(node)) {
|
|
328
|
+
return EMPTY;
|
|
306
329
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
}
|
|
310
|
-
getElementVisibility(ignoreTooltip, viewsModel, overriddenVisibility, categoryVisibility, subModelVisibilityStatus) {
|
|
311
|
-
if (subModelVisibilityStatus === undefined) {
|
|
312
|
-
if (!viewsModel) {
|
|
313
|
-
return createVisibilityStatus("hidden", getTooltipOptions("modelsTree.element.hiddenThroughModel", ignoreTooltip));
|
|
330
|
+
if (node.filtering?.filteredChildrenIdentifierPaths?.length && !node.filtering.isFilterTarget) {
|
|
331
|
+
return this.changeFilteredNodeVisibility({ node, on });
|
|
314
332
|
}
|
|
315
|
-
if (
|
|
316
|
-
return
|
|
333
|
+
if (ModelsTreeNode.isSubjectNode(node)) {
|
|
334
|
+
return this.changeSubjectNodeState(node.key.instanceKeys.map((key) => key.id), on);
|
|
317
335
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
if (subModelVisibilityStatus.state === "partial") {
|
|
321
|
-
return createVisibilityStatus("partial", getTooltipOptions("modelsTree.element.someElementsAreHidden", ignoreTooltip));
|
|
322
|
-
}
|
|
323
|
-
if (subModelVisibilityStatus.state === "visible") {
|
|
324
|
-
if (!viewsModel || overriddenVisibility?.state === "hidden" || (categoryVisibility.state === "hidden" && !overriddenVisibility)) {
|
|
325
|
-
return createVisibilityStatus("partial", getTooltipOptions("modelsTree.element.partialThroughSubModel", ignoreTooltip));
|
|
336
|
+
if (ModelsTreeNode.isModelNode(node)) {
|
|
337
|
+
return this.changeModelState({ ids: node.key.instanceKeys.map(({ id }) => id), on });
|
|
326
338
|
}
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
return createVisibilityStatus("hidden", getTooltipOptions("modelsTree.element.hiddenThroughModel", ignoreTooltip));
|
|
331
|
-
}
|
|
332
|
-
if (overriddenVisibility) {
|
|
333
|
-
if (overriddenVisibility.state === "hidden") {
|
|
334
|
-
return overriddenVisibility;
|
|
339
|
+
const modelId = ModelsTreeNode.getModelId(node);
|
|
340
|
+
if (!modelId) {
|
|
341
|
+
return EMPTY;
|
|
335
342
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
return from(this._idsCache.hasSubModel(elementId)).pipe(mergeMap((hasSubModel) => (hasSubModel ? this.getModelVisibilityStatus({ modelIds: [elementId] }) : of(undefined))), map((subModelVisibilityStatus) => this.getElementVisibility(ignoreTooltip, viewsModel, elementStatus,
|
|
350
|
-
// Single category will always return "visible" or "hidden"
|
|
351
|
-
this.getDefaultCategoryVisibilityStatus({ categoryIds: categoryId, modelId, ignoreTooltip: true }), subModelVisibilityStatus)));
|
|
352
|
-
});
|
|
353
|
-
return createVisibilityHandlerResult(this, props, result, this._props.overrides?.getElementDisplayStatus);
|
|
354
|
-
}
|
|
355
|
-
/** Changes visibility of the items represented by the tree node. */
|
|
356
|
-
changeVisibilityObs(node, on) {
|
|
357
|
-
if (node.filtering?.filteredChildrenIdentifierPaths?.length && !node.filtering.isFilterTarget) {
|
|
358
|
-
return this.changeFilteredNodeVisibility({ node, on });
|
|
359
|
-
}
|
|
360
|
-
if (HierarchyNode.isClassGroupingNode(node)) {
|
|
361
|
-
return this.changeElementGroupingNodeState(node, on);
|
|
362
|
-
}
|
|
363
|
-
if (!HierarchyNode.isInstancesNode(node)) {
|
|
364
|
-
return EMPTY;
|
|
365
|
-
}
|
|
366
|
-
if (ModelsTreeNode.isSubjectNode(node)) {
|
|
367
|
-
return this.changeSubjectNodeState(node.key.instanceKeys.map((key) => key.id), on);
|
|
368
|
-
}
|
|
369
|
-
if (ModelsTreeNode.isModelNode(node)) {
|
|
370
|
-
return this.changeModelState({ ids: node.key.instanceKeys.map(({ id }) => id), on });
|
|
371
|
-
}
|
|
372
|
-
const modelId = ModelsTreeNode.getModelId(node);
|
|
373
|
-
if (!modelId) {
|
|
374
|
-
return EMPTY;
|
|
375
|
-
}
|
|
376
|
-
if (ModelsTreeNode.isCategoryNode(node)) {
|
|
377
|
-
return this.changeCategoryState({
|
|
378
|
-
categoryIds: node.key.instanceKeys.map(({ id }) => id),
|
|
343
|
+
if (ModelsTreeNode.isCategoryNode(node)) {
|
|
344
|
+
return this.changeCategoryState({
|
|
345
|
+
categoryIds: node.key.instanceKeys.map(({ id }) => id),
|
|
346
|
+
modelId,
|
|
347
|
+
on,
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
const categoryId = ModelsTreeNode.getCategoryId(node);
|
|
351
|
+
if (!categoryId) {
|
|
352
|
+
return EMPTY;
|
|
353
|
+
}
|
|
354
|
+
return this.changeElementsState({
|
|
355
|
+
elementIds: new Set([...node.key.instanceKeys.map(({ id }) => id)]),
|
|
379
356
|
modelId,
|
|
357
|
+
categoryId,
|
|
380
358
|
on,
|
|
381
359
|
});
|
|
382
|
-
}
|
|
383
|
-
const categoryId = ModelsTreeNode.getCategoryId(node);
|
|
384
|
-
if (!categoryId) {
|
|
385
|
-
return EMPTY;
|
|
386
|
-
}
|
|
387
|
-
return this.changeElementsState({
|
|
388
|
-
elementIds: new Set([...node.key.instanceKeys.map(({ id }) => id)]),
|
|
389
|
-
modelId,
|
|
390
|
-
categoryId,
|
|
391
|
-
on,
|
|
392
360
|
});
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
return
|
|
361
|
+
if (this.#props.viewport.isAlwaysDrawnExclusive) {
|
|
362
|
+
return concat(this.removeAlwaysDrawnExclusive(), changeObs);
|
|
363
|
+
}
|
|
364
|
+
return changeObs;
|
|
397
365
|
}
|
|
398
366
|
changeFilteredNodeVisibility({ on, ...props }) {
|
|
399
|
-
|
|
367
|
+
assert(this.#filteredTree !== undefined);
|
|
368
|
+
return from(this.#filteredTree).pipe(map((filteredTree) => filteredTree.getVisibilityChangeTargets(props.node)), mergeMap(({ subjects, models, categories, elements }) => {
|
|
400
369
|
const observables = new Array();
|
|
401
370
|
if (subjects?.size) {
|
|
402
371
|
observables.push(this.changeSubjectNodeState([...subjects], on));
|
|
@@ -411,22 +380,30 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
411
380
|
})));
|
|
412
381
|
}
|
|
413
382
|
if (elements?.size) {
|
|
414
|
-
observables.push(from(elements).pipe(mergeMap(([categoryKey,
|
|
383
|
+
observables.push(from(elements).pipe(mergeMap(([categoryKey, elementsMap]) => {
|
|
415
384
|
const { modelId, categoryId } = parseCategoryKey(categoryKey);
|
|
416
|
-
return this.changeElementsState({ modelId, categoryId, elementIds, on });
|
|
385
|
+
return this.changeElementsState({ modelId, categoryId, elementIds: new Set([...elementsMap.keys()]), on });
|
|
417
386
|
})));
|
|
418
387
|
}
|
|
419
388
|
return merge(...observables);
|
|
420
389
|
}));
|
|
421
390
|
}
|
|
391
|
+
removeAlwaysDrawnExclusive() {
|
|
392
|
+
return from(this.#idsCache.getAllCategories()).pipe(map((categoryIds) => {
|
|
393
|
+
this.#props.viewport.changeCategoryDisplay(categoryIds, false, false);
|
|
394
|
+
this.#props.viewport.clearNeverDrawn();
|
|
395
|
+
this.#props.viewport.perModelCategoryVisibility.clearOverrides();
|
|
396
|
+
this.#props.viewport.setAlwaysDrawn(this.#props.viewport.alwaysDrawn ?? new Set());
|
|
397
|
+
}));
|
|
398
|
+
}
|
|
422
399
|
changeSubjectNodeState(ids, on) {
|
|
423
400
|
const result = defer(() => {
|
|
424
|
-
if (!this.
|
|
401
|
+
if (!this.#props.viewport.view.isSpatialView()) {
|
|
425
402
|
return EMPTY;
|
|
426
403
|
}
|
|
427
|
-
return from(this.
|
|
404
|
+
return from(this.#idsCache.getSubjectModelIds(ids)).pipe(mergeMap((modelIds) => this.changeModelState({ ids: modelIds, on })));
|
|
428
405
|
});
|
|
429
|
-
return createVisibilityHandlerResult(this, { ids, on }, result, this.
|
|
406
|
+
return createVisibilityHandlerResult(this, { ids, on }, result, this.#props.overrides?.changeSubjectNodeState);
|
|
430
407
|
}
|
|
431
408
|
changeModelState(props) {
|
|
432
409
|
const { ids, on } = props;
|
|
@@ -434,31 +411,31 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
434
411
|
return EMPTY;
|
|
435
412
|
}
|
|
436
413
|
const result = defer(() => {
|
|
437
|
-
const viewport = this.
|
|
414
|
+
const viewport = this.#props.viewport;
|
|
438
415
|
if (!viewport.view.isSpatialView()) {
|
|
439
416
|
return EMPTY;
|
|
440
417
|
}
|
|
441
418
|
const idsObs = from(Id64.iterable(ids));
|
|
442
419
|
if (!on) {
|
|
443
420
|
viewport.changeModelDisplay(ids, false);
|
|
444
|
-
return idsObs.pipe(mergeMap(async (modelId) => ({ modelId, categoryIds: await this.
|
|
421
|
+
return idsObs.pipe(mergeMap(async (modelId) => ({ modelId, categoryIds: await this.#idsCache.getModelCategories(modelId) })), mergeMap(({ modelId, categoryIds }) => from(this.#idsCache.getCategoriesModeledElements(modelId, categoryIds))), mergeMap((modeledElementIds) => this.changeModelState({ ids: modeledElementIds, on })));
|
|
445
422
|
}
|
|
446
423
|
return concat(defer(() => {
|
|
447
424
|
viewport.perModelCategoryVisibility.clearOverrides(ids);
|
|
448
425
|
return from(viewport.addViewedModels(ids));
|
|
449
426
|
}), idsObs.pipe(mergeMap((modelId) => {
|
|
450
|
-
return from(this.
|
|
427
|
+
return from(this.#idsCache.getModelCategories(modelId)).pipe(mergeMap((categoryIds) => this.changeCategoryState({ categoryIds, modelId, on: true })));
|
|
451
428
|
})));
|
|
452
429
|
});
|
|
453
|
-
return createVisibilityHandlerResult(this, props, result, this.
|
|
430
|
+
return createVisibilityHandlerResult(this, props, result, this.#props.overrides?.changeModelState);
|
|
454
431
|
}
|
|
455
432
|
showModelWithoutAnyCategoriesOrElements(modelId) {
|
|
456
|
-
const viewport = this.
|
|
433
|
+
const viewport = this.#props.viewport;
|
|
457
434
|
return forkJoin({
|
|
458
|
-
categories: this.
|
|
459
|
-
alwaysDrawnElements: this.
|
|
435
|
+
categories: this.#idsCache.getModelCategories(modelId),
|
|
436
|
+
alwaysDrawnElements: this.getAlwaysOrNeverDrawnElements({ modelIds: modelId, setType: "always" }),
|
|
460
437
|
}).pipe(mergeMap(async ({ categories, alwaysDrawnElements }) => {
|
|
461
|
-
const alwaysDrawn = this.
|
|
438
|
+
const alwaysDrawn = this.#props.viewport.alwaysDrawn;
|
|
462
439
|
if (alwaysDrawn && alwaysDrawnElements) {
|
|
463
440
|
viewport.setAlwaysDrawn(setDifference(alwaysDrawn, alwaysDrawnElements));
|
|
464
441
|
}
|
|
@@ -469,7 +446,7 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
469
446
|
}));
|
|
470
447
|
}
|
|
471
448
|
changeCategoryStateInViewportAccordingToModelVisibility(modelId, categoryId, on) {
|
|
472
|
-
const viewport = this.
|
|
449
|
+
const viewport = this.#props.viewport;
|
|
473
450
|
const isDisplayedInSelector = viewport.view.viewsCategory(categoryId);
|
|
474
451
|
const override = on === isDisplayedInSelector
|
|
475
452
|
? PerModelCategoryVisibility.Override.None
|
|
@@ -485,26 +462,26 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
485
462
|
}
|
|
486
463
|
changeCategoryState(props) {
|
|
487
464
|
const result = defer(() => {
|
|
488
|
-
const viewport = this.
|
|
465
|
+
const viewport = this.#props.viewport;
|
|
489
466
|
const { modelId, categoryIds, on } = props;
|
|
490
467
|
return concat(props.on && !viewport.view.viewsModel(modelId) ? this.showModelWithoutAnyCategoriesOrElements(modelId) : EMPTY, defer(() => {
|
|
491
468
|
for (const categoryId of Id64.iterable(categoryIds)) {
|
|
492
469
|
this.changeCategoryStateInViewportAccordingToModelVisibility(modelId, categoryId, on);
|
|
493
470
|
}
|
|
494
471
|
return this.clearAlwaysAndNeverDrawnElements(props);
|
|
495
|
-
}), from(this.
|
|
472
|
+
}), from(this.#idsCache.getCategoriesModeledElements(modelId, categoryIds)).pipe(mergeMap((modeledElementIds) => this.changeModelState({ ids: modeledElementIds, on }))));
|
|
496
473
|
});
|
|
497
|
-
return createVisibilityHandlerResult(this, props, result, this.
|
|
474
|
+
return createVisibilityHandlerResult(this, props, result, this.#props.overrides?.changeCategoryState);
|
|
498
475
|
}
|
|
499
476
|
doChangeElementsState(props) {
|
|
500
477
|
return defer(() => {
|
|
501
478
|
const { modelId, categoryId, elementIds, on } = props;
|
|
502
|
-
const viewport = this.
|
|
479
|
+
const viewport = this.#props.viewport;
|
|
503
480
|
return concat(on && !viewport.view.viewsModel(modelId) ? this.showModelWithoutAnyCategoriesOrElements(modelId) : EMPTY, defer(() => {
|
|
504
481
|
const categoryVisibility = this.getDefaultCategoryVisibilityStatus({ categoryIds: categoryId, modelId, ignoreTooltip: true });
|
|
505
482
|
const isDisplayedByDefault = categoryVisibility.state === "visible";
|
|
506
483
|
return this.queueElementsVisibilityChange(elementIds, on, isDisplayedByDefault);
|
|
507
|
-
}), from(elementIds).pipe(mergeMap(async (elementId) => ({ elementId, isSubModel: await this.
|
|
484
|
+
}), from(elementIds).pipe(mergeMap(async (elementId) => ({ elementId, isSubModel: await this.#idsCache.hasSubModel(elementId) })), filter(({ isSubModel }) => isSubModel), map(({ elementId }) => elementId), toArray(), mergeMap((subModelIds) => this.changeModelState({ ids: subModelIds, on }))));
|
|
508
485
|
});
|
|
509
486
|
}
|
|
510
487
|
/**
|
|
@@ -513,7 +490,7 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
513
490
|
*/
|
|
514
491
|
changeElementGroupingNodeState(node, on) {
|
|
515
492
|
const result = this.doChangeElementsState({ ...this.getGroupingNodeInfo(node), on });
|
|
516
|
-
return createVisibilityHandlerResult(this, { node, on }, result, this.
|
|
493
|
+
return createVisibilityHandlerResult(this, { node, on }, result, this.#props.overrides?.changeElementGroupingNodeState);
|
|
517
494
|
}
|
|
518
495
|
/**
|
|
519
496
|
* Updates visibility of an element and all its child elements by adding them to the always/never drawn list.
|
|
@@ -521,7 +498,7 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
521
498
|
*/
|
|
522
499
|
changeElementsState(props) {
|
|
523
500
|
const result = this.doChangeElementsState(props);
|
|
524
|
-
return createVisibilityHandlerResult(this, props, result, this.
|
|
501
|
+
return createVisibilityHandlerResult(this, props, result, this.#props.overrides?.changeElementsState);
|
|
525
502
|
}
|
|
526
503
|
queueElementsVisibilityChange(elementIds, on, visibleByDefault) {
|
|
527
504
|
const finishedSubject = new Subject();
|
|
@@ -536,7 +513,7 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
536
513
|
},
|
|
537
514
|
}));
|
|
538
515
|
// queue visibility change. `changeObservable` will be subscribed to when other queue changes are finished
|
|
539
|
-
this.
|
|
516
|
+
this.#elementChangeQueue.next(changeObservable);
|
|
540
517
|
// return observable that will emit when visibility change is finished
|
|
541
518
|
return changeFinished.pipe(take(1), tap({
|
|
542
519
|
unsubscribe: () => {
|
|
@@ -548,11 +525,11 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
548
525
|
changeElementStateNoChildrenOperator(props) {
|
|
549
526
|
return (elementIds) => {
|
|
550
527
|
const { on, isDisplayedByDefault } = props;
|
|
551
|
-
const isAlwaysDrawnExclusive = this.
|
|
528
|
+
const isAlwaysDrawnExclusive = this.#props.viewport.isAlwaysDrawnExclusive;
|
|
552
529
|
return elementIds.pipe(releaseMainThreadOnItemsCount(500), reduce((acc, elementId) => {
|
|
553
530
|
if (acc.alwaysDrawn === undefined || acc.neverDrawn === undefined) {
|
|
554
|
-
acc.alwaysDrawn = new Set(this.
|
|
555
|
-
acc.neverDrawn = new Set(this.
|
|
531
|
+
acc.alwaysDrawn = new Set(this.#props.viewport.alwaysDrawn || []);
|
|
532
|
+
acc.neverDrawn = new Set(this.#props.viewport.neverDrawn || []);
|
|
556
533
|
}
|
|
557
534
|
if (on) {
|
|
558
535
|
const wasRemoved = acc.neverDrawn.delete(elementId);
|
|
@@ -579,8 +556,8 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
579
556
|
neverDrawn: undefined,
|
|
580
557
|
alwaysDrawn: undefined,
|
|
581
558
|
}), map((state) => {
|
|
582
|
-
state.changedNeverDrawn && state.neverDrawn && this.
|
|
583
|
-
state.changedAlwaysDrawn && state.alwaysDrawn && this.
|
|
559
|
+
state.changedNeverDrawn && state.neverDrawn && this.#props.viewport.setNeverDrawn(state.neverDrawn);
|
|
560
|
+
state.changedAlwaysDrawn && state.alwaysDrawn && this.#props.viewport.setAlwaysDrawn(state.alwaysDrawn, this.#props.viewport.isAlwaysDrawnExclusive);
|
|
584
561
|
}));
|
|
585
562
|
};
|
|
586
563
|
}
|
|
@@ -595,7 +572,7 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
595
572
|
if (alwaysDrawn?.size === totalCount) {
|
|
596
573
|
return createVisibilityStatus("visible", getTooltipOptions(props.tooltips.allElementsInAlwaysDrawnList, ignoreTooltip));
|
|
597
574
|
}
|
|
598
|
-
const viewport = this.
|
|
575
|
+
const viewport = this.#props.viewport;
|
|
599
576
|
if (viewport.isAlwaysDrawnExclusive && viewport.alwaysDrawn?.size) {
|
|
600
577
|
return alwaysDrawn?.size
|
|
601
578
|
? createVisibilityStatus("partial", getTooltipOptions(props.tooltips.elementsInBothAlwaysAndNeverDrawn, ignoreTooltip))
|
|
@@ -608,7 +585,7 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
608
585
|
return status;
|
|
609
586
|
}
|
|
610
587
|
getVisibilityFromAlwaysAndNeverDrawnElements({ ignoreTooltip, ...props }) {
|
|
611
|
-
const viewport = this.
|
|
588
|
+
const viewport = this.#props.viewport;
|
|
612
589
|
if (viewport.isAlwaysDrawnExclusive) {
|
|
613
590
|
if (!viewport?.alwaysDrawn?.size) {
|
|
614
591
|
return of(createVisibilityStatus("hidden", getTooltipOptions(props.tooltips.noElementsInExclusiveAlwaysDrawnList, ignoreTooltip)));
|
|
@@ -622,17 +599,17 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
622
599
|
...props,
|
|
623
600
|
alwaysDrawn: viewport.alwaysDrawn?.size ? setIntersection(props.elements, viewport.alwaysDrawn) : undefined,
|
|
624
601
|
neverDrawn: viewport.neverDrawn?.size ? setIntersection(props.elements, viewport.neverDrawn) : undefined,
|
|
625
|
-
totalCount: props.elements
|
|
602
|
+
totalCount: Id64.sizeOf(props.elements),
|
|
626
603
|
ignoreTooltip,
|
|
627
604
|
}));
|
|
628
605
|
}
|
|
629
606
|
const { modelId, categoryIds } = props.categoryProps;
|
|
630
607
|
return from(Id64.iterable(categoryIds)).pipe(mergeMap((categoryId) => {
|
|
631
|
-
const totalCount = this.
|
|
608
|
+
const totalCount = this.#idsCache.getCategoryElementsCount(modelId, categoryId);
|
|
632
609
|
return forkJoin({
|
|
633
610
|
totalCount,
|
|
634
|
-
alwaysDrawn: this.
|
|
635
|
-
neverDrawn: this.
|
|
611
|
+
alwaysDrawn: this.getAlwaysOrNeverDrawnElements({ modelIds: modelId, categoryIds: categoryId, setType: "always" }),
|
|
612
|
+
neverDrawn: this.getAlwaysOrNeverDrawnElements({ modelIds: modelId, categoryIds: categoryId, setType: "never" }),
|
|
636
613
|
}).pipe(
|
|
637
614
|
// There is a known bug:
|
|
638
615
|
// Categories that don't have root elements will make visibility result incorrect
|
|
@@ -652,18 +629,17 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
652
629
|
}));
|
|
653
630
|
}), mergeVisibilityStatuses());
|
|
654
631
|
}
|
|
655
|
-
|
|
656
|
-
return this
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
return this._alwaysAndNeverDrawnElements.getElements({ modelId: props.modelId, categoryIds: props.categoryIds, setType: "never" });
|
|
632
|
+
getAlwaysOrNeverDrawnElements(props) {
|
|
633
|
+
return this.#alwaysAndNeverDrawnElements
|
|
634
|
+
.getElementsTree(props)
|
|
635
|
+
.pipe(map((childrenTree) => getIdsFromChildrenTree({ tree: childrenTree, predicate: ({ treeEntry }) => treeEntry.isInAlwaysOrNeverDrawnSet })));
|
|
660
636
|
}
|
|
661
637
|
clearAlwaysAndNeverDrawnElements(props) {
|
|
662
638
|
return forkJoin({
|
|
663
|
-
alwaysDrawn: this.
|
|
664
|
-
neverDrawn: this.
|
|
639
|
+
alwaysDrawn: this.getAlwaysOrNeverDrawnElements({ modelIds: props.modelId, categoryIds: props.categoryIds, setType: "always" }),
|
|
640
|
+
neverDrawn: this.getAlwaysOrNeverDrawnElements({ modelIds: props.modelId, categoryIds: props.categoryIds, setType: "never" }),
|
|
665
641
|
}).pipe(map(({ alwaysDrawn, neverDrawn }) => {
|
|
666
|
-
const viewport = this.
|
|
642
|
+
const viewport = this.#props.viewport;
|
|
667
643
|
if (viewport.alwaysDrawn?.size && alwaysDrawn.size) {
|
|
668
644
|
viewport.setAlwaysDrawn(setDifference(viewport.alwaysDrawn, alwaysDrawn));
|
|
669
645
|
}
|
|
@@ -687,11 +663,11 @@ class ModelsTreeVisibilityHandlerImpl {
|
|
|
687
663
|
if (haveSubModel === "yes") {
|
|
688
664
|
return of(modeledElementIds);
|
|
689
665
|
}
|
|
690
|
-
return from(modeledElementIds).pipe(mergeMap(async (elementId) => ({ elementId, hasSubModel: await this.
|
|
666
|
+
return from(Id64.iterable(modeledElementIds)).pipe(mergeMap(async (elementId) => ({ elementId, hasSubModel: await this.#idsCache.hasSubModel(elementId) })), filter(({ hasSubModel }) => hasSubModel), map(({ elementId }) => elementId), toArray());
|
|
691
667
|
}),
|
|
692
668
|
// combine visibility status of sub-models with visibility status of parent node
|
|
693
669
|
mergeMap((modeledElementIds) => {
|
|
694
|
-
if (modeledElementIds
|
|
670
|
+
if (Id64.sizeOf(modeledElementIds) === 0) {
|
|
695
671
|
return of(parentNodeVisibilityStatus);
|
|
696
672
|
}
|
|
697
673
|
return this.getModelVisibilityStatus({ modelIds: modeledElementIds }).pipe(startWith(parentNodeVisibilityStatus), mergeVisibilityStatuses(tooltips, ignoreTooltips));
|
|
@@ -723,24 +699,40 @@ function mergeVisibilityStatuses(tooltipMap, ignoreTooltip) {
|
|
|
723
699
|
}
|
|
724
700
|
function setDifference(lhs, rhs) {
|
|
725
701
|
const result = new Set();
|
|
726
|
-
|
|
702
|
+
for (const x of lhs) {
|
|
703
|
+
if (!rhs.has(x)) {
|
|
704
|
+
result.add(x);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
727
707
|
return result;
|
|
728
708
|
}
|
|
729
709
|
function setIntersection(lhs, rhs) {
|
|
730
710
|
const result = new Set();
|
|
731
|
-
|
|
711
|
+
for (const x of lhs) {
|
|
712
|
+
if (rhs.has(x)) {
|
|
713
|
+
result.add(x);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
732
716
|
return result;
|
|
733
717
|
}
|
|
734
718
|
/**
|
|
735
719
|
* Enables display of all given models. Also enables display of all categories and clears always and
|
|
736
720
|
* never drawn lists in the viewport.
|
|
721
|
+
*
|
|
722
|
+
* @param componentId Optional unique id of the component that consumes this function.
|
|
723
|
+
* It can be any string, as long as it is not shared across different components.
|
|
737
724
|
* @public
|
|
738
725
|
*/
|
|
739
|
-
export async function showAllModels(models, viewport) {
|
|
726
|
+
export async function showAllModels(models, viewport, componentId) {
|
|
740
727
|
await viewport.addViewedModels(models);
|
|
741
728
|
viewport.clearNeverDrawn();
|
|
742
729
|
viewport.clearAlwaysDrawn();
|
|
743
|
-
await
|
|
730
|
+
const categories = await loadCategoriesFromViewport(viewport, componentId);
|
|
731
|
+
if (categories.length === 0) {
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
const ids = categories.map((category) => category.categoryId);
|
|
735
|
+
await enableCategoryDisplay(viewport, ids, true);
|
|
744
736
|
}
|
|
745
737
|
/**
|
|
746
738
|
* Disables display of all given models.
|