@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Utils.js","sourceRoot":"","sources":["../../../../../../src/tree-widget-react/components/trees/models-tree/Utils.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;
|
|
1
|
+
{"version":3,"file":"Utils.js","sourceRoot":"","sources":["../../../../../../src/tree-widget-react/components/trees/models-tree/Utils.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;AAQhG,wDAqBC;AAQD,gDA4BC;AAGD,kDAEC;AA/DD,gBAAgB;AAChB,SAAgB,sBAAsB,CAAwB,EAC5D,IAAI,EACJ,SAAS,GAIV;IACC,SAAS,cAAc,CAAC,EAAE,YAAY,EAAE,KAAK,EAAoD;QAC/F,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;QACjC,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;YACjC,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;gBACzD,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACjB,CAAC;YACD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACnB,MAAM,WAAW,GAAG,cAAc,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;gBACvF,WAAW,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,cAAc,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;GAKG;AACH,SAAgB,kBAAkB,CAAwB,EACxD,IAAI,EACJ,qBAAqB,EACrB,QAAQ,GAKT;IACC,IAAI,WAAW,GAAoB,IAAI,CAAC;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;QACzC,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACvB,IAAI,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChC,KAAK,GAAG;YACN,oEAAoE;YACpE,GAAG,qBAAqB,CAAC,EAAE,EAAE,KAAK,CAAC;YACnC,2CAA2C;YAC3C,6HAA6H;YAC7H,GAAG,CAAC,KAAK,EAAE,QAAQ,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClG,CAAC;QACF,4CAA4C;QAC5C,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC3B,kGAAkG;QAClG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;YACpB,MAAM;QACR,CAAC;QACD,WAAW,GAAG,KAAK,CAAC,QAAQ,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,gBAAgB;AAChB,SAAgB,mBAAmB,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAmD;IAClH,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,gBAAgB,CAAC,CAAC,CAAC;AACxE,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport type { Id64Array, Id64String } from \"@itwin/core-bentley\";\n\n/** @internal */\nexport type ChildrenTree<T extends object = {}> = Map<string, T & { children?: ChildrenTree<T> }>;\n\n/** @internal */\nexport function getIdsFromChildrenTree<T extends object = {}>({\n tree,\n predicate,\n}: {\n tree: ChildrenTree<T>;\n predicate?: (props: { depth: number; treeEntry: T }) => boolean;\n}): Set<string> {\n function getIdsInternal({ childrenTree, depth }: { childrenTree: ChildrenTree<T>; depth: number }): Set<string> {\n const result = new Set<string>();\n childrenTree.forEach((entry, id) => {\n if (!predicate || predicate({ depth, treeEntry: entry })) {\n result.add(id);\n }\n if (entry.children) {\n const childrenIds = getIdsInternal({ childrenTree: entry.children, depth: depth + 1 });\n childrenIds.forEach((childId) => result.add(childId));\n }\n });\n return result;\n }\n return getIdsInternal({ childrenTree: tree, depth: 0 });\n}\n\n/**\n * Updates children tree with provided `idsToAdd`:\n * - All Ids are added (if they are not yet added) to children tree in the same order they appear in `idsToAdd` array.\n * - `T` is assigned to each entry using the `additionalPropsGetter` function.\n * @internal\n */\nexport function updateChildrenTree<T extends object = {}>({\n tree,\n additionalPropsGetter,\n idsToAdd,\n}: {\n tree: ChildrenTree<T>;\n idsToAdd: Id64Array;\n additionalPropsGetter: (id: Id64String, additionalProps?: T) => T;\n}) {\n let currentTree: ChildrenTree<T> = tree;\n for (let i = 0; i < idsToAdd.length; ++i) {\n const id = idsToAdd[i];\n let entry = currentTree.get(id);\n entry = {\n // Whoever calls this function knows how to assign the `T` to entry.\n ...additionalPropsGetter(id, entry),\n // If children already exists, we reuse it.\n // If children do not exist and there are still ids left in the `idsToAdd` array, create a new Map, it will have the next id.\n ...(entry?.children || i + 1 < idsToAdd.length ? { children: entry?.children ?? new Map() } : {}),\n };\n // Always update the set with updated entry.\n currentTree.set(id, entry);\n // This will only happen if it's the last id in `idsToAdd` array. In such case loop can be exited.\n if (!entry.children) {\n break;\n }\n currentTree = entry.children;\n }\n}\n\n/** @internal */\nexport function getOptimalBatchSize({ totalSize, maximumBatchSize }: { totalSize: number; maximumBatchSize: number }): number {\n return Math.ceil(totalSize / Math.ceil(totalSize / maximumBatchSize));\n}\n"]}
|
|
@@ -8,7 +8,8 @@ exports.AlwaysAndNeverDrawnElementInfo = exports.SET_CHANGE_DEBOUNCE_TIME = void
|
|
|
8
8
|
const rxjs_1 = require("rxjs");
|
|
9
9
|
const core_bentley_1 = require("@itwin/core-bentley");
|
|
10
10
|
const presentation_core_interop_1 = require("@itwin/presentation-core-interop");
|
|
11
|
-
const Utils_js_1 = require("
|
|
11
|
+
const Utils_js_1 = require("../../common/internal/Utils.js");
|
|
12
|
+
const Utils_js_2 = require("../Utils.js");
|
|
12
13
|
/** @internal */
|
|
13
14
|
exports.SET_CHANGE_DEBOUNCE_TIME = 20;
|
|
14
15
|
class AlwaysAndNeverDrawnElementInfo {
|
|
@@ -109,9 +110,9 @@ class AlwaysAndNeverDrawnElementInfo {
|
|
|
109
110
|
}
|
|
110
111
|
queryAlwaysOrNeverDrawnElementInfo(set, requestId) {
|
|
111
112
|
const elementInfo = set?.size
|
|
112
|
-
? (0, rxjs_1.from)(set).pipe((0, rxjs_1.bufferCount)(
|
|
113
|
+
? (0, rxjs_1.from)(set).pipe((0, rxjs_1.bufferCount)((0, Utils_js_1.getOptimalBatchSize)({ totalSize: set.size, maximumBatchSize: 1000 })), (0, Utils_js_1.releaseMainThreadOnItemsCount)(2), (0, rxjs_1.mergeMap)((block, index) => this.queryElementInfo(block, `${requestId}-${index}`), 10))
|
|
113
114
|
: rxjs_1.EMPTY;
|
|
114
|
-
return elementInfo.pipe((0, Utils_js_1.releaseMainThreadOnItemsCount)(
|
|
115
|
+
return elementInfo.pipe((0, Utils_js_1.releaseMainThreadOnItemsCount)(500), (0, rxjs_1.reduce)((acc, { categoryId, rootCategoryId, modelId, elementsPath }) => {
|
|
115
116
|
const elementIdInList = elementsPath[elementsPath.length - 1];
|
|
116
117
|
const additionalPropsGetter = (id, additionalProps) => {
|
|
117
118
|
if (id === elementIdInList) {
|
|
@@ -121,7 +122,7 @@ class AlwaysAndNeverDrawnElementInfo {
|
|
|
121
122
|
// Existing entries can keep their value, if it's a new entry it's not in the list.
|
|
122
123
|
return additionalProps ?? { isInAlwaysOrNeverDrawnSet: false };
|
|
123
124
|
};
|
|
124
|
-
(0,
|
|
125
|
+
(0, Utils_js_2.updateChildrenTree)({ tree: acc, idsToAdd: [modelId, rootCategoryId, ...elementsPath], additionalPropsGetter });
|
|
125
126
|
return acc;
|
|
126
127
|
}, (() => new Map())()));
|
|
127
128
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AlwaysAndNeverDrawnElementInfo.js","sourceRoot":"","sources":["../../../../../../../src/tree-widget-react/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport {\n BehaviorSubject,\n bufferCount,\n debounceTime,\n defer,\n EMPTY,\n filter,\n first,\n from,\n fromEventPattern,\n map,\n mergeMap,\n of,\n reduce,\n scan,\n share,\n shareReplay,\n startWith,\n Subject,\n switchMap,\n take,\n takeUntil,\n tap,\n} from \"rxjs\";\nimport { Guid, Id64 } from \"@itwin/core-bentley\";\nimport { createECSqlQueryExecutor } from \"@itwin/presentation-core-interop\";\nimport { releaseMainThreadOnItemsCount, updateChildrenTree } from \"../Utils.js\";\n\nimport type { Observable, Subscription } from \"rxjs\";\nimport type { GuidString, Id64Arg, Id64Array, Id64Set, Id64String } from \"@itwin/core-bentley\";\nimport type { Viewport } from \"@itwin/core-frontend\";\nimport type { ChildrenTree } from \"../Utils.js\";\n\n/** @internal */\nexport const SET_CHANGE_DEBOUNCE_TIME = 20;\n\ntype SetType = \"always\" | \"never\";\n\ninterface GetElementsTreeByModelProps {\n /** Only always/never drawn elements that have the specified models will be returned. */\n modelIds: Id64Arg;\n /**\n * The type of set from which tree should be retrieved.\n * `always` - ChildrenTree will be created from `alwaysDrawn` set.\n * `never` - ChildrenTree will be created from `neverDrawn` set.\n */\n setType: SetType;\n}\ninterface GetElementsTreeByCategoryProps extends GetElementsTreeByModelProps {\n /**\n * Categories of root elements.\n *\n * Elements are filtered by given categories. Children of those elements are also included, no matter their category.\n */\n categoryIds: Id64Arg;\n}\ninterface GetElementsTreeByElementProps extends GetElementsTreeByCategoryProps {\n /** Path to element for which to get its' child always/never drawn elements. When undefined, models and categories will be used to get the always/never drawn elements. */\n parentElementIdsPath: Array<Id64Arg>;\n}\n\n/** @internal */\nexport type GetElementsTreeProps = GetElementsTreeByModelProps | GetElementsTreeByCategoryProps | GetElementsTreeByElementProps;\n\n/**\n * - `categoryId` is assigned only to the elements in always/never drawn set.\n * - `isInAlwaysOrNeverDrawnSet` flag determines if key (ECInstanceId) is in always/never set.\n * @internal\n */\nexport type MapEntry = { isInAlwaysOrNeverDrawnSet: true; categoryId: Id64String } | { isInAlwaysOrNeverDrawnSet: false };\n\ntype CachedNodesMap = ChildrenTree<MapEntry>;\n\nexport class AlwaysAndNeverDrawnElementInfo implements Disposable {\n #subscriptions: Subscription[];\n #alwaysDrawn: { cacheEntryObs: Observable<CachedNodesMap>; latestCacheEntryValue?: CachedNodesMap };\n #neverDrawn: { cacheEntryObs: Observable<CachedNodesMap>; latestCacheEntryValue?: CachedNodesMap };\n #disposeSubject = new Subject<void>();\n readonly #viewport: Viewport;\n #componentId: GuidString;\n #componentName: string;\n\n #suppressors: Observable<number>;\n #suppress = new Subject<boolean>();\n\n constructor(viewport: Viewport, componentId?: GuidString) {\n this.#viewport = viewport;\n this.#alwaysDrawn = { cacheEntryObs: this.createCacheEntryObservable(\"always\") };\n this.#neverDrawn = { cacheEntryObs: this.createCacheEntryObservable(\"never\") };\n this.#suppressors = this.#suppress.pipe(\n scan((acc, suppress) => acc + (suppress ? 1 : -1), 0),\n startWith(0),\n shareReplay(1),\n );\n this.#subscriptions = [this.#alwaysDrawn.cacheEntryObs.subscribe(), this.#neverDrawn.cacheEntryObs.subscribe()];\n this.#componentId = componentId ?? Guid.createValue();\n this.#componentName = \"AlwaysAndNeverDrawnElementInfo\";\n }\n\n public suppressChangeEvents() {\n this.#suppress.next(true);\n }\n\n public resumeChangeEvents() {\n this.#suppress.next(false);\n }\n\n public getElementsTree({ setType, modelIds, ...props }: GetElementsTreeProps): Observable<CachedNodesMap> {\n const cache = setType === \"always\" ? this.#alwaysDrawn : this.#neverDrawn;\n const getElements = (rootTreeNodes: CachedNodesMap | undefined): CachedNodesMap => {\n if (!rootTreeNodes) {\n return new Map();\n }\n const pathToElements = [modelIds];\n if (\"categoryIds\" in props && props.categoryIds) {\n pathToElements.push(props.categoryIds);\n if (\"parentElementIdsPath\" in props && props.parentElementIdsPath) {\n props.parentElementIdsPath.forEach((parentElementIds) => pathToElements.push(parentElementIds));\n }\n }\n return this.getChildrenTree({ currentChildrenTree: rootTreeNodes, pathToElements, currentIdsIndex: 0 });\n };\n\n return !cache.latestCacheEntryValue\n ? cache.cacheEntryObs.pipe(map(getElements))\n : this.#suppressors.pipe(\n take(1),\n mergeMap((suppressionCount) =>\n suppressionCount > 0 ? of(cache.latestCacheEntryValue).pipe(map(getElements)) : cache.cacheEntryObs.pipe(map(getElements)),\n ),\n );\n }\n\n private getChildrenTree<T extends object>({\n currentChildrenTree,\n pathToElements,\n currentIdsIndex,\n }: {\n currentChildrenTree: ChildrenTree<T>;\n pathToElements: Array<Id64Arg>;\n currentIdsIndex: number;\n }): ChildrenTree<T> {\n if (currentIdsIndex >= pathToElements.length) {\n return currentChildrenTree;\n }\n const result: ChildrenTree<T> = new Map();\n for (const parentId of Id64.iterable(pathToElements[currentIdsIndex])) {\n const entry = currentChildrenTree.get(parentId);\n if (entry?.children) {\n const childrenTreeOfChildren = this.getChildrenTree({\n currentChildrenTree: entry.children,\n pathToElements,\n currentIdsIndex: currentIdsIndex + 1,\n });\n childrenTreeOfChildren.forEach((val, childId) => result.set(childId, val));\n }\n }\n return result;\n }\n\n private createCacheEntryObservable(setType: SetType): Observable<CachedNodesMap> {\n const event = setType === \"always\" ? this.#viewport.onAlwaysDrawnChanged : this.#viewport.onNeverDrawnChanged;\n const getIds = setType === \"always\" ? () => this.#viewport.alwaysDrawn : () => this.#viewport.neverDrawn;\n\n const resultSubject = new BehaviorSubject<CachedNodesMap | undefined>(undefined);\n\n const obs: Observable<CachedNodesMap> = fromEventPattern(\n (handler) => event.addListener(handler),\n (handler) => event.removeListener(handler),\n ).pipe(\n // Fire the observable once at the beginning\n startWith(undefined),\n // Reset result subject as soon as a new event is emitted.\n // This will make newly subscribed observers wait for the debounce period to pass\n // instead of consuming the cached value which at this point becomes invalid.\n tap(() => resultSubject.next(undefined)),\n // Check if cache updates are not suppressed.\n switchMap(() =>\n this.#suppressors.pipe(\n filter((suppressors) => suppressors === 0),\n take(1),\n ),\n ),\n debounceTime(SET_CHANGE_DEBOUNCE_TIME),\n // Cancel pending request if dispose() is called.\n takeUntil(this.#disposeSubject),\n // If multiple requests are sent at once, preserve only the result of the newest.\n switchMap(() => this.queryAlwaysOrNeverDrawnElementInfo(getIds(), `${setType}Drawn`)),\n tap((cacheEntry) => {\n const value = setType === \"always\" ? this.#alwaysDrawn : this.#neverDrawn;\n value.latestCacheEntryValue = cacheEntry;\n }),\n // Share the result by using a subject which always emits the saved result.\n share({\n connector: () => resultSubject,\n resetOnRefCountZero: false,\n }),\n // Wait until the result is available.\n first((x): x is CachedNodesMap => !!x, new Map()),\n );\n return obs;\n }\n\n public [Symbol.dispose]() {\n this.#subscriptions.forEach((x) => x.unsubscribe());\n this.#subscriptions = [];\n this.#disposeSubject.next();\n }\n\n private queryAlwaysOrNeverDrawnElementInfo(set: Id64Set | undefined, requestId: string): Observable<CachedNodesMap> {\n const elementInfo = set?.size\n ? from(set).pipe(\n bufferCount(Math.ceil(set.size / Math.ceil(set.size / 5000))),\n mergeMap((block, index) => this.queryElementInfo(block, `${requestId}-${index}`), 10),\n )\n : EMPTY;\n return elementInfo.pipe(\n releaseMainThreadOnItemsCount(1000),\n reduce(\n (acc, { categoryId, rootCategoryId, modelId, elementsPath }) => {\n const elementIdInList = elementsPath[elementsPath.length - 1];\n const additionalPropsGetter = (id: Id64String, additionalProps?: MapEntry): MapEntry => {\n if (id === elementIdInList) {\n // Last element in elementsPath is in always/never drawn set. We want to mark, that it is in the set, and save it's categoryId.\n return { isInAlwaysOrNeverDrawnSet: true, categoryId };\n }\n // Existing entries can keep their value, if it's a new entry it's not in the list.\n return additionalProps ?? { isInAlwaysOrNeverDrawnSet: false };\n };\n updateChildrenTree({ tree: acc, idsToAdd: [modelId, rootCategoryId, ...elementsPath], additionalPropsGetter });\n return acc;\n },\n ((): CachedNodesMap => new Map())(),\n ),\n );\n }\n\n private queryElementInfo(\n elementIds: Id64Array,\n requestId: string,\n ): Observable<{\n rootCategoryId: Id64String;\n modelId: Id64String;\n categoryId: Id64String;\n elementsPath: Id64Array;\n }> {\n return defer(() => {\n const executor = createECSqlQueryExecutor(this.#viewport.iModel);\n return executor.createQueryReader(\n {\n ctes: [\n `\n ElementInfo(modelId, rootCategoryId, categoryId, parentId, elementsPath) AS (\n SELECT\n Model.Id modelId,\n Category.Id rootCategoryId,\n Category.Id categoryId,\n Parent.Id parentId,\n CAST(IdToHex(ECInstanceId) AS TEXT) elementsPath\n FROM bis.GeometricElement3d\n WHERE InVirtualSet(?, ECInstanceId)\n\n UNION ALL\n\n SELECT\n e.modelId modelId,\n p.Category.Id rootCategoryId,\n e.categoryId categoryId,\n p.Parent.Id parentId,\n CAST(IdToHex(p.ECInstanceId) AS TEXT) || ';' || e.elementsPath\n FROM bis.GeometricElement3d p\n JOIN ElementInfo e ON p.ECInstanceId = e.parentId\n )\n `,\n ],\n ecsql: `\n SELECT elementsPath elementsPath, modelId modelId, categoryId categoryId, rootCategoryId rootCategoryId\n FROM ElementInfo\n WHERE parentId IS NULL\n `,\n bindings: [{ type: \"idset\", value: elementIds }],\n },\n {\n rowFormat: \"ECSqlPropertyNames\",\n restartToken: `${this.#componentName}/${this.#componentId}/${requestId}`,\n },\n );\n }).pipe(\n map((row) => {\n return { elementsPath: row.elementsPath.split(\";\"), modelId: row.modelId, categoryId: row.categoryId, rootCategoryId: row.rootCategoryId };\n }),\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AlwaysAndNeverDrawnElementInfo.js","sourceRoot":"","sources":["../../../../../../../src/tree-widget-react/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport {\n BehaviorSubject,\n bufferCount,\n debounceTime,\n defer,\n EMPTY,\n filter,\n first,\n from,\n fromEventPattern,\n map,\n mergeMap,\n of,\n reduce,\n scan,\n share,\n shareReplay,\n startWith,\n Subject,\n switchMap,\n take,\n takeUntil,\n tap,\n} from \"rxjs\";\nimport { Guid, Id64 } from \"@itwin/core-bentley\";\nimport { createECSqlQueryExecutor } from \"@itwin/presentation-core-interop\";\nimport { getOptimalBatchSize, releaseMainThreadOnItemsCount } from \"../../common/internal/Utils.js\";\nimport { updateChildrenTree } from \"../Utils.js\";\n\nimport type { Observable, Subscription } from \"rxjs\";\nimport type { GuidString, Id64Arg, Id64Array, Id64Set, Id64String } from \"@itwin/core-bentley\";\nimport type { Viewport } from \"@itwin/core-frontend\";\nimport type { ChildrenTree } from \"../Utils.js\";\n\n/** @internal */\nexport const SET_CHANGE_DEBOUNCE_TIME = 20;\n\ntype SetType = \"always\" | \"never\";\n\ninterface GetElementsTreeByModelProps {\n /** Only always/never drawn elements that have the specified models will be returned. */\n modelIds: Id64Arg;\n /**\n * The type of set from which tree should be retrieved.\n * `always` - ChildrenTree will be created from `alwaysDrawn` set.\n * `never` - ChildrenTree will be created from `neverDrawn` set.\n */\n setType: SetType;\n}\ninterface GetElementsTreeByCategoryProps extends GetElementsTreeByModelProps {\n /**\n * Categories of root elements.\n *\n * Elements are filtered by given categories. Children of those elements are also included, no matter their category.\n */\n categoryIds: Id64Arg;\n}\ninterface GetElementsTreeByElementProps extends GetElementsTreeByCategoryProps {\n /** Path to element for which to get its' child always/never drawn elements. When undefined, models and categories will be used to get the always/never drawn elements. */\n parentElementIdsPath: Array<Id64Arg>;\n}\n\n/** @internal */\nexport type GetElementsTreeProps = GetElementsTreeByModelProps | GetElementsTreeByCategoryProps | GetElementsTreeByElementProps;\n\n/**\n * - `categoryId` is assigned only to the elements in always/never drawn set.\n * - `isInAlwaysOrNeverDrawnSet` flag determines if key (ECInstanceId) is in always/never set.\n * @internal\n */\nexport type MapEntry = { isInAlwaysOrNeverDrawnSet: true; categoryId: Id64String } | { isInAlwaysOrNeverDrawnSet: false };\n\ntype CachedNodesMap = ChildrenTree<MapEntry>;\n\nexport class AlwaysAndNeverDrawnElementInfo implements Disposable {\n #subscriptions: Subscription[];\n #alwaysDrawn: { cacheEntryObs: Observable<CachedNodesMap>; latestCacheEntryValue?: CachedNodesMap };\n #neverDrawn: { cacheEntryObs: Observable<CachedNodesMap>; latestCacheEntryValue?: CachedNodesMap };\n #disposeSubject = new Subject<void>();\n readonly #viewport: Viewport;\n #componentId: GuidString;\n #componentName: string;\n\n #suppressors: Observable<number>;\n #suppress = new Subject<boolean>();\n\n constructor(viewport: Viewport, componentId?: GuidString) {\n this.#viewport = viewport;\n this.#alwaysDrawn = { cacheEntryObs: this.createCacheEntryObservable(\"always\") };\n this.#neverDrawn = { cacheEntryObs: this.createCacheEntryObservable(\"never\") };\n this.#suppressors = this.#suppress.pipe(\n scan((acc, suppress) => acc + (suppress ? 1 : -1), 0),\n startWith(0),\n shareReplay(1),\n );\n this.#subscriptions = [this.#alwaysDrawn.cacheEntryObs.subscribe(), this.#neverDrawn.cacheEntryObs.subscribe()];\n this.#componentId = componentId ?? Guid.createValue();\n this.#componentName = \"AlwaysAndNeverDrawnElementInfo\";\n }\n\n public suppressChangeEvents() {\n this.#suppress.next(true);\n }\n\n public resumeChangeEvents() {\n this.#suppress.next(false);\n }\n\n public getElementsTree({ setType, modelIds, ...props }: GetElementsTreeProps): Observable<CachedNodesMap> {\n const cache = setType === \"always\" ? this.#alwaysDrawn : this.#neverDrawn;\n const getElements = (rootTreeNodes: CachedNodesMap | undefined): CachedNodesMap => {\n if (!rootTreeNodes) {\n return new Map();\n }\n const pathToElements = [modelIds];\n if (\"categoryIds\" in props && props.categoryIds) {\n pathToElements.push(props.categoryIds);\n if (\"parentElementIdsPath\" in props && props.parentElementIdsPath) {\n props.parentElementIdsPath.forEach((parentElementIds) => pathToElements.push(parentElementIds));\n }\n }\n return this.getChildrenTree({ currentChildrenTree: rootTreeNodes, pathToElements, currentIdsIndex: 0 });\n };\n\n return !cache.latestCacheEntryValue\n ? cache.cacheEntryObs.pipe(map(getElements))\n : this.#suppressors.pipe(\n take(1),\n mergeMap((suppressionCount) =>\n suppressionCount > 0 ? of(cache.latestCacheEntryValue).pipe(map(getElements)) : cache.cacheEntryObs.pipe(map(getElements)),\n ),\n );\n }\n\n private getChildrenTree<T extends object>({\n currentChildrenTree,\n pathToElements,\n currentIdsIndex,\n }: {\n currentChildrenTree: ChildrenTree<T>;\n pathToElements: Array<Id64Arg>;\n currentIdsIndex: number;\n }): ChildrenTree<T> {\n if (currentIdsIndex >= pathToElements.length) {\n return currentChildrenTree;\n }\n const result: ChildrenTree<T> = new Map();\n for (const parentId of Id64.iterable(pathToElements[currentIdsIndex])) {\n const entry = currentChildrenTree.get(parentId);\n if (entry?.children) {\n const childrenTreeOfChildren = this.getChildrenTree({\n currentChildrenTree: entry.children,\n pathToElements,\n currentIdsIndex: currentIdsIndex + 1,\n });\n childrenTreeOfChildren.forEach((val, childId) => result.set(childId, val));\n }\n }\n return result;\n }\n\n private createCacheEntryObservable(setType: SetType): Observable<CachedNodesMap> {\n const event = setType === \"always\" ? this.#viewport.onAlwaysDrawnChanged : this.#viewport.onNeverDrawnChanged;\n const getIds = setType === \"always\" ? () => this.#viewport.alwaysDrawn : () => this.#viewport.neverDrawn;\n\n const resultSubject = new BehaviorSubject<CachedNodesMap | undefined>(undefined);\n\n const obs: Observable<CachedNodesMap> = fromEventPattern(\n (handler) => event.addListener(handler),\n (handler) => event.removeListener(handler),\n ).pipe(\n // Fire the observable once at the beginning\n startWith(undefined),\n // Reset result subject as soon as a new event is emitted.\n // This will make newly subscribed observers wait for the debounce period to pass\n // instead of consuming the cached value which at this point becomes invalid.\n tap(() => resultSubject.next(undefined)),\n // Check if cache updates are not suppressed.\n switchMap(() =>\n this.#suppressors.pipe(\n filter((suppressors) => suppressors === 0),\n take(1),\n ),\n ),\n debounceTime(SET_CHANGE_DEBOUNCE_TIME),\n // Cancel pending request if dispose() is called.\n takeUntil(this.#disposeSubject),\n // If multiple requests are sent at once, preserve only the result of the newest.\n switchMap(() => this.queryAlwaysOrNeverDrawnElementInfo(getIds(), `${setType}Drawn`)),\n tap((cacheEntry) => {\n const value = setType === \"always\" ? this.#alwaysDrawn : this.#neverDrawn;\n value.latestCacheEntryValue = cacheEntry;\n }),\n // Share the result by using a subject which always emits the saved result.\n share({\n connector: () => resultSubject,\n resetOnRefCountZero: false,\n }),\n // Wait until the result is available.\n first((x): x is CachedNodesMap => !!x, new Map()),\n );\n return obs;\n }\n\n public [Symbol.dispose]() {\n this.#subscriptions.forEach((x) => x.unsubscribe());\n this.#subscriptions = [];\n this.#disposeSubject.next();\n }\n\n private queryAlwaysOrNeverDrawnElementInfo(set: Id64Set | undefined, requestId: string): Observable<CachedNodesMap> {\n const elementInfo = set?.size\n ? from(set).pipe(\n bufferCount(getOptimalBatchSize({ totalSize: set.size, maximumBatchSize: 1000 })),\n releaseMainThreadOnItemsCount(2),\n mergeMap((block, index) => this.queryElementInfo(block, `${requestId}-${index}`), 10),\n )\n : EMPTY;\n return elementInfo.pipe(\n releaseMainThreadOnItemsCount(500),\n reduce(\n (acc, { categoryId, rootCategoryId, modelId, elementsPath }) => {\n const elementIdInList = elementsPath[elementsPath.length - 1];\n const additionalPropsGetter = (id: Id64String, additionalProps?: MapEntry): MapEntry => {\n if (id === elementIdInList) {\n // Last element in elementsPath is in always/never drawn set. We want to mark, that it is in the set, and save it's categoryId.\n return { isInAlwaysOrNeverDrawnSet: true, categoryId };\n }\n // Existing entries can keep their value, if it's a new entry it's not in the list.\n return additionalProps ?? { isInAlwaysOrNeverDrawnSet: false };\n };\n updateChildrenTree({ tree: acc, idsToAdd: [modelId, rootCategoryId, ...elementsPath], additionalPropsGetter });\n return acc;\n },\n ((): CachedNodesMap => new Map())(),\n ),\n );\n }\n\n private queryElementInfo(\n elementIds: Id64Array,\n requestId: string,\n ): Observable<{\n rootCategoryId: Id64String;\n modelId: Id64String;\n categoryId: Id64String;\n elementsPath: Id64Array;\n }> {\n return defer(() => {\n const executor = createECSqlQueryExecutor(this.#viewport.iModel);\n return executor.createQueryReader(\n {\n ctes: [\n `\n ElementInfo(modelId, rootCategoryId, categoryId, parentId, elementsPath) AS (\n SELECT\n Model.Id modelId,\n Category.Id rootCategoryId,\n Category.Id categoryId,\n Parent.Id parentId,\n CAST(IdToHex(ECInstanceId) AS TEXT) elementsPath\n FROM bis.GeometricElement3d\n WHERE InVirtualSet(?, ECInstanceId)\n\n UNION ALL\n\n SELECT\n e.modelId modelId,\n p.Category.Id rootCategoryId,\n e.categoryId categoryId,\n p.Parent.Id parentId,\n CAST(IdToHex(p.ECInstanceId) AS TEXT) || ';' || e.elementsPath\n FROM bis.GeometricElement3d p\n JOIN ElementInfo e ON p.ECInstanceId = e.parentId\n )\n `,\n ],\n ecsql: `\n SELECT elementsPath elementsPath, modelId modelId, categoryId categoryId, rootCategoryId rootCategoryId\n FROM ElementInfo\n WHERE parentId IS NULL\n `,\n bindings: [{ type: \"idset\", value: elementIds }],\n },\n {\n rowFormat: \"ECSqlPropertyNames\",\n restartToken: `${this.#componentName}/${this.#componentId}/${requestId}`,\n },\n );\n }).pipe(\n map((row) => {\n return { elementsPath: row.elementsPath.split(\";\"), modelId: row.modelId, categoryId: row.categoryId, rootCategoryId: row.rootCategoryId };\n }),\n );\n }\n}\n"]}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { HierarchyFilteringPath, HierarchyNode } from "@itwin/presentation-hierarchies";
|
|
2
|
-
import type { Id64String } from "@itwin/core-bentley";
|
|
2
|
+
import type { Id64Arg, Id64Set, Id64String } from "@itwin/core-bentley";
|
|
3
3
|
import type { ClassGroupingNodeKey, InstancesNodeKey } from "@itwin/presentation-hierarchies";
|
|
4
4
|
import type { ECClassHierarchyInspector } from "@itwin/presentation-shared";
|
|
5
|
+
import type { ChildrenTree } from "../Utils.js";
|
|
6
|
+
interface GetElementsFromUnfilteredChildrenTreeProps {
|
|
7
|
+
childrenTree: ChildrenTree;
|
|
8
|
+
parentIdsPath: Array<Id64Arg>;
|
|
9
|
+
}
|
|
5
10
|
/** @internal */
|
|
6
11
|
export interface FilteredTree {
|
|
7
12
|
getVisibilityChangeTargets(node: HierarchyNode & {
|
|
8
13
|
key: ClassGroupingNodeKey | InstancesNodeKey;
|
|
9
14
|
}): VisibilityChangeTargets;
|
|
15
|
+
getElementsFromUnfilteredChildrenTree(props: GetElementsFromUnfilteredChildrenTreeProps): Id64Set | undefined;
|
|
10
16
|
}
|
|
11
17
|
export declare const SUBJECT_CLASS_NAME: "BisCore.Subject";
|
|
12
18
|
export declare const MODEL_CLASS_NAME: "BisCore.GeometricModel3d";
|
|
@@ -9,6 +9,7 @@ exports.parseCategoryKey = parseCategoryKey;
|
|
|
9
9
|
exports.createFilteredTree = createFilteredTree;
|
|
10
10
|
const core_bentley_1 = require("@itwin/core-bentley");
|
|
11
11
|
const presentation_hierarchies_1 = require("@itwin/presentation-hierarchies");
|
|
12
|
+
const Utils_js_1 = require("../Utils.js");
|
|
12
13
|
exports.SUBJECT_CLASS_NAME = "BisCore.Subject";
|
|
13
14
|
exports.MODEL_CLASS_NAME = "BisCore.GeometricModel3d";
|
|
14
15
|
exports.CATEGORY_CLASS_NAME = "BisCore.SpatialCategory";
|
|
@@ -55,8 +56,59 @@ async function createFilteredTree(imodelAccess, filteringPaths) {
|
|
|
55
56
|
}
|
|
56
57
|
return {
|
|
57
58
|
getVisibilityChangeTargets: (node) => getVisibilityChangeTargets(root, node),
|
|
59
|
+
getElementsFromUnfilteredChildrenTree: ({ childrenTree, parentIdsPath }) => getElementsFromUnfilteredChildrenTree({ parentIdsPath, root, childrenTree }),
|
|
58
60
|
};
|
|
59
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Unfiltered tree can contain ids of models/categories/elements which are not present in the filtered tree.
|
|
64
|
+
* This function retrieves only those ids which are either filter tree targets, or are their children (direct and indirect).
|
|
65
|
+
*/
|
|
66
|
+
function getElementsFromUnfilteredChildrenTree(props) {
|
|
67
|
+
if (props.childrenTree.size === 0 || props.parentIdsPath.length === 0) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
let lookupParents = [props.root];
|
|
71
|
+
for (const parentIds of props.parentIdsPath) {
|
|
72
|
+
// When filtered node does not have children, it is filter target and because of this, all elements in the childrenTree are in the filtered tree
|
|
73
|
+
if (lookupParents.every((parent) => !parent.children)) {
|
|
74
|
+
return (0, Utils_js_1.getIdsFromChildrenTree)({ tree: props.childrenTree });
|
|
75
|
+
}
|
|
76
|
+
const parentNodes = findMatchingFilteredNodes(lookupParents, parentIds);
|
|
77
|
+
if (parentNodes.length === 0) {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
lookupParents = parentNodes;
|
|
81
|
+
}
|
|
82
|
+
// We have unfiltered children tree and filtered nodes that are parents of first level nodes in unfiltered children tree.
|
|
83
|
+
// We can start filtering unfiltered children tree based on filtered nodes.
|
|
84
|
+
const result = getChildrenTreeIdsMatchingFilteredNodes({ tree: props.childrenTree, filteredNodes: lookupParents });
|
|
85
|
+
return result.size > 0 ? result : undefined;
|
|
86
|
+
}
|
|
87
|
+
function getChildrenTreeIdsMatchingFilteredNodes({ tree, filteredNodes, }) {
|
|
88
|
+
const getIdsRecursively = (childrenTree, parentFilteredNodes) => {
|
|
89
|
+
// If one of the parent filtered nodes does not have children, it is filter target and because of this, all elements in the childrenTree are in the filtered tree.
|
|
90
|
+
const hasParentFilterTarget = parentFilteredNodes.some((filteredNode) => "isFilterTarget" in filteredNode && filteredNode.isFilterTarget);
|
|
91
|
+
if (hasParentFilterTarget) {
|
|
92
|
+
return (0, Utils_js_1.getIdsFromChildrenTree)({ tree: childrenTree });
|
|
93
|
+
}
|
|
94
|
+
const result = new Set();
|
|
95
|
+
childrenTree.forEach((entry, id) => {
|
|
96
|
+
const nodes = findMatchingFilteredNodes(parentFilteredNodes, id);
|
|
97
|
+
// If no filtered nodes match this id, skip it since it's not in the filtered tree.
|
|
98
|
+
if (nodes.length === 0) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
// Id was found in filtered nodes children, add it to the result.
|
|
102
|
+
result.add(id);
|
|
103
|
+
if (entry.children) {
|
|
104
|
+
// Continue recursively for children
|
|
105
|
+
getIdsRecursively(entry.children, nodes).forEach((childId) => result.add(childId));
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
return result;
|
|
109
|
+
};
|
|
110
|
+
return getIdsRecursively(tree, filteredNodes);
|
|
111
|
+
}
|
|
60
112
|
function getVisibilityChangeTargets(root, node) {
|
|
61
113
|
let lookupParents = [root];
|
|
62
114
|
const changeTargets = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilteredTree.js","sourceRoot":"","sources":["../../../../../../../src/tree-widget-react/components/trees/models-tree/internal/FilteredTree.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { assert, Id64 } from \"@itwin/core-bentley\";\nimport { HierarchyFilteringPath, HierarchyNode, HierarchyNodeIdentifier, HierarchyNodeKey } from \"@itwin/presentation-hierarchies\";\n\nimport type { Id64Arg, Id64String } from \"@itwin/core-bentley\";\nimport type { ClassGroupingNodeKey, InstancesNodeKey } from \"@itwin/presentation-hierarchies\";\nimport type { ECClassHierarchyInspector } from \"@itwin/presentation-shared\";\n\ninterface FilteredTreeRootNode {\n children: Map<Id64String, FilteredTreeNode>;\n}\n\ninterface BaseFilteredTreeNode {\n id: string;\n children?: Map<Id64String, FilteredTreeNode>;\n isFilterTarget: boolean;\n}\n\ninterface GenericFilteredTreeNode extends BaseFilteredTreeNode {\n type: \"subject\" | \"model\";\n}\n\ninterface CategoryFilteredTreeNode extends BaseFilteredTreeNode {\n type: \"category\";\n modelId: Id64String;\n}\n\ninterface ElementFilteredTreeNode extends BaseFilteredTreeNode {\n type: \"element\";\n modelId: Id64String;\n categoryId: Id64String;\n}\n\ntype FilteredTreeNode = GenericFilteredTreeNode | CategoryFilteredTreeNode | ElementFilteredTreeNode;\n\n/** @internal */\nexport interface FilteredTree {\n getVisibilityChangeTargets(node: HierarchyNode & { key: ClassGroupingNodeKey | InstancesNodeKey }): VisibilityChangeTargets;\n}\n\nexport const SUBJECT_CLASS_NAME = \"BisCore.Subject\" as const;\nexport const MODEL_CLASS_NAME = \"BisCore.GeometricModel3d\" as const;\nexport const CATEGORY_CLASS_NAME = \"BisCore.SpatialCategory\" as const;\nexport const ELEMENT_CLASS_NAME = \"BisCore.GeometricElement3d\" as const;\n\ntype CategoryKey = `${Id64String}-${Id64String}`;\n\nfunction createCategoryKey(modelId: string, categoryId: string): CategoryKey {\n return `${modelId}-${categoryId}`;\n}\n\n/** @internal */\nexport function parseCategoryKey(key: CategoryKey) {\n const [modelId, categoryId] = key.split(\"-\");\n return { modelId, categoryId };\n}\n\n/** @internal */\nexport interface VisibilityChangeTargets {\n subjects?: Set<Id64String>;\n models?: Set<Id64String>;\n categories?: Set<CategoryKey>;\n elements?: Map<CategoryKey, Map<Id64String, { isFilterTarget: boolean }>>;\n}\n\n/** @internal */\nexport async function createFilteredTree(imodelAccess: ECClassHierarchyInspector, filteringPaths: HierarchyFilteringPath[]): Promise<FilteredTree> {\n const root: FilteredTreeRootNode = {\n children: new Map(),\n };\n\n for (const filteringPath of filteringPaths) {\n const normalizedPath = HierarchyFilteringPath.normalize(filteringPath).path;\n\n let parentNode: FilteredTreeRootNode | FilteredTreeNode = root;\n for (let i = 0; i < normalizedPath.length; i++) {\n if (\"type\" in parentNode && parentNode.isFilterTarget) {\n break;\n }\n\n const identifier = normalizedPath[i];\n if (!HierarchyNodeIdentifier.isInstanceNodeIdentifier(identifier)) {\n break;\n }\n\n const currentNode: FilteredTreeNode | undefined = parentNode.children?.get(identifier.id);\n if (currentNode !== undefined) {\n parentNode = currentNode;\n continue;\n }\n\n const type = await getType(imodelAccess, identifier.className);\n const newNode: FilteredTreeNode = createFilteredTreeNode({\n type,\n id: identifier.id,\n isFilterTarget: i === normalizedPath.length - 1,\n parent: parentNode as FilteredTreeNode,\n });\n (parentNode.children ??= new Map()).set(identifier.id, newNode);\n parentNode = newNode;\n }\n }\n\n return {\n getVisibilityChangeTargets: (node) => getVisibilityChangeTargets(root, node),\n };\n}\n\nfunction getVisibilityChangeTargets(root: FilteredTreeRootNode, node: HierarchyNode & { key: ClassGroupingNodeKey | InstancesNodeKey }) {\n let lookupParents: Array<FilteredTreeRootNode | FilteredTreeNode> = [root];\n const changeTargets: VisibilityChangeTargets = {};\n\n // find the filtered parent nodes of the `node`\n for (const parentKey of node.parentKeys) {\n if (!HierarchyNodeKey.isInstances(parentKey)) {\n continue;\n }\n\n // tree node might be merged from multiple instances. As filtered tree stores only one instance per node, we need to find all matching nodes\n // and use them when checking for matching node in one level deeper.\n const parentNodes = findMatchingFilteredNodes(\n lookupParents,\n parentKey.instanceKeys.map((key) => key.id),\n );\n if (parentNodes.length === 0) {\n return changeTargets;\n }\n lookupParents = parentNodes;\n }\n const ids = HierarchyNode.isInstancesNode(node) ? node.key.instanceKeys.map(({ id }) => id) : node.groupedInstanceKeys.map(({ id }) => id);\n // find filtered nodes that match the `node`\n const filteredNodes = findMatchingFilteredNodes(lookupParents, ids);\n if (filteredNodes.length === 0) {\n return changeTargets;\n }\n\n filteredNodes.forEach((filteredNode) => collectVisibilityChangeTargets(changeTargets, filteredNode));\n return changeTargets;\n}\n\nfunction findMatchingFilteredNodes(lookupParents: Array<FilteredTreeRootNode | FilteredTreeNode>, ids: Id64Arg): Array<FilteredTreeNode> {\n return lookupParents.flatMap((lookup) => {\n const childrenArray = Array<FilteredTreeNode>();\n for (const id of Id64.iterable(ids)) {\n const node = lookup.children?.get(id);\n if (node) {\n childrenArray.push(node);\n }\n }\n return childrenArray;\n });\n}\n\nfunction collectVisibilityChangeTargets(changeTargets: VisibilityChangeTargets, node: FilteredTreeNode) {\n if (node.isFilterTarget) {\n addTarget(changeTargets, node);\n return;\n }\n\n if (node.type === \"element\") {\n // need to add parent ids as filter target will be an element\n addTarget(changeTargets, node);\n }\n\n if (!node.children) {\n return;\n }\n\n for (const child of node.children.values()) {\n collectVisibilityChangeTargets(changeTargets, child);\n }\n}\n\nfunction addTarget(filterTargets: VisibilityChangeTargets, node: FilteredTreeNode) {\n switch (node.type) {\n case \"subject\":\n (filterTargets.subjects ??= new Set()).add(node.id);\n return;\n case \"model\":\n (filterTargets.models ??= new Set()).add(node.id);\n return;\n case \"category\":\n (filterTargets.categories ??= new Set()).add(createCategoryKey(node.modelId, node.id));\n return;\n case \"element\":\n const categoryKey = createCategoryKey(node.modelId, node.categoryId);\n const elements = (filterTargets.elements ??= new Map()).get(categoryKey);\n if (elements) {\n elements.set(node.id, { isFilterTarget: node.isFilterTarget });\n } else {\n filterTargets.elements.set(categoryKey, new Map([[node.id, { isFilterTarget: node.isFilterTarget }]]));\n }\n }\n}\n\nfunction createFilteredTreeNode({\n type,\n id,\n isFilterTarget,\n parent,\n}: {\n type: FilteredTreeNode[\"type\"];\n id: string;\n isFilterTarget: boolean;\n parent: FilteredTreeNode | FilteredTreeRootNode;\n}): FilteredTreeNode {\n if (type === \"subject\" || type === \"model\") {\n return {\n id,\n isFilterTarget,\n type,\n };\n }\n\n if (type === \"category\") {\n assert(\"type\" in parent && parent.type === \"model\");\n return {\n id,\n isFilterTarget,\n type,\n modelId: parent.id,\n };\n }\n\n if (\"type\" in parent && parent.type === \"category\") {\n return {\n id,\n isFilterTarget,\n type,\n modelId: parent.modelId,\n categoryId: parent.id,\n };\n }\n\n if (\"type\" in parent && parent.type === \"element\") {\n return {\n id,\n isFilterTarget,\n type,\n modelId: parent.modelId,\n categoryId: parent.categoryId,\n };\n }\n\n throw new Error(\"Invalid parent node type\");\n}\n\nasync function getType(hierarchyChecker: ECClassHierarchyInspector, className: string) {\n if (await hierarchyChecker.classDerivesFrom(className, SUBJECT_CLASS_NAME)) {\n return \"subject\";\n }\n if (await hierarchyChecker.classDerivesFrom(className, MODEL_CLASS_NAME)) {\n return \"model\";\n }\n if (await hierarchyChecker.classDerivesFrom(className, CATEGORY_CLASS_NAME)) {\n return \"category\";\n }\n return \"element\";\n}\n"]}
|
|
1
|
+
{"version":3,"file":"FilteredTree.js","sourceRoot":"","sources":["../../../../../../../src/tree-widget-react/components/trees/models-tree/internal/FilteredTree.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { assert, Id64 } from \"@itwin/core-bentley\";\nimport { HierarchyFilteringPath, HierarchyNode, HierarchyNodeIdentifier, HierarchyNodeKey } from \"@itwin/presentation-hierarchies\";\nimport { getIdsFromChildrenTree } from \"../Utils.js\";\n\nimport type { Id64Arg, Id64Set, Id64String } from \"@itwin/core-bentley\";\nimport type { ClassGroupingNodeKey, InstancesNodeKey } from \"@itwin/presentation-hierarchies\";\nimport type { ECClassHierarchyInspector } from \"@itwin/presentation-shared\";\nimport type { ChildrenTree } from \"../Utils.js\";\n\ninterface FilteredTreeRootNode {\n children: Map<Id64String, FilteredTreeNode>;\n}\n\ninterface BaseFilteredTreeNode {\n id: string;\n children?: Map<Id64String, FilteredTreeNode>;\n isFilterTarget: boolean;\n}\n\ninterface GenericFilteredTreeNode extends BaseFilteredTreeNode {\n type: \"subject\" | \"model\";\n}\n\ninterface CategoryFilteredTreeNode extends BaseFilteredTreeNode {\n type: \"category\";\n modelId: Id64String;\n}\n\ninterface ElementFilteredTreeNode extends BaseFilteredTreeNode {\n type: \"element\";\n modelId: Id64String;\n categoryId: Id64String;\n}\n\ntype FilteredTreeNode = GenericFilteredTreeNode | CategoryFilteredTreeNode | ElementFilteredTreeNode;\n\ninterface GetElementsFromUnfilteredChildrenTreeProps {\n childrenTree: ChildrenTree;\n parentIdsPath: Array<Id64Arg>;\n}\n\n/** @internal */\nexport interface FilteredTree {\n getVisibilityChangeTargets(node: HierarchyNode & { key: ClassGroupingNodeKey | InstancesNodeKey }): VisibilityChangeTargets;\n getElementsFromUnfilteredChildrenTree(props: GetElementsFromUnfilteredChildrenTreeProps): Id64Set | undefined;\n}\n\nexport const SUBJECT_CLASS_NAME = \"BisCore.Subject\" as const;\nexport const MODEL_CLASS_NAME = \"BisCore.GeometricModel3d\" as const;\nexport const CATEGORY_CLASS_NAME = \"BisCore.SpatialCategory\" as const;\nexport const ELEMENT_CLASS_NAME = \"BisCore.GeometricElement3d\" as const;\n\ntype CategoryKey = `${Id64String}-${Id64String}`;\n\nfunction createCategoryKey(modelId: string, categoryId: string): CategoryKey {\n return `${modelId}-${categoryId}`;\n}\n\n/** @internal */\nexport function parseCategoryKey(key: CategoryKey) {\n const [modelId, categoryId] = key.split(\"-\");\n return { modelId, categoryId };\n}\n\n/** @internal */\nexport interface VisibilityChangeTargets {\n subjects?: Set<Id64String>;\n models?: Set<Id64String>;\n categories?: Set<CategoryKey>;\n elements?: Map<CategoryKey, Map<Id64String, { isFilterTarget: boolean }>>;\n}\n\n/** @internal */\nexport async function createFilteredTree(imodelAccess: ECClassHierarchyInspector, filteringPaths: HierarchyFilteringPath[]): Promise<FilteredTree> {\n const root: FilteredTreeRootNode = {\n children: new Map(),\n };\n\n for (const filteringPath of filteringPaths) {\n const normalizedPath = HierarchyFilteringPath.normalize(filteringPath).path;\n\n let parentNode: FilteredTreeRootNode | FilteredTreeNode = root;\n for (let i = 0; i < normalizedPath.length; i++) {\n if (\"type\" in parentNode && parentNode.isFilterTarget) {\n break;\n }\n\n const identifier = normalizedPath[i];\n if (!HierarchyNodeIdentifier.isInstanceNodeIdentifier(identifier)) {\n break;\n }\n\n const currentNode: FilteredTreeNode | undefined = parentNode.children?.get(identifier.id);\n if (currentNode !== undefined) {\n parentNode = currentNode;\n continue;\n }\n\n const type = await getType(imodelAccess, identifier.className);\n const newNode: FilteredTreeNode = createFilteredTreeNode({\n type,\n id: identifier.id,\n isFilterTarget: i === normalizedPath.length - 1,\n parent: parentNode as FilteredTreeNode,\n });\n (parentNode.children ??= new Map()).set(identifier.id, newNode);\n parentNode = newNode;\n }\n }\n\n return {\n getVisibilityChangeTargets: (node) => getVisibilityChangeTargets(root, node),\n getElementsFromUnfilteredChildrenTree: ({ childrenTree, parentIdsPath }) => getElementsFromUnfilteredChildrenTree({ parentIdsPath, root, childrenTree }),\n };\n}\n\n/**\n * Unfiltered tree can contain ids of models/categories/elements which are not present in the filtered tree.\n * This function retrieves only those ids which are either filter tree targets, or are their children (direct and indirect).\n */\nfunction getElementsFromUnfilteredChildrenTree(props: GetElementsFromUnfilteredChildrenTreeProps & { root: FilteredTreeRootNode }): Id64Set | undefined {\n if (props.childrenTree.size === 0 || props.parentIdsPath.length === 0) {\n return undefined;\n }\n\n let lookupParents: Array<FilteredTreeRootNode | FilteredTreeNode> = [props.root];\n for (const parentIds of props.parentIdsPath) {\n // When filtered node does not have children, it is filter target and because of this, all elements in the childrenTree are in the filtered tree\n if (lookupParents.every((parent) => !parent.children)) {\n return getIdsFromChildrenTree({ tree: props.childrenTree });\n }\n\n const parentNodes = findMatchingFilteredNodes(lookupParents, parentIds);\n if (parentNodes.length === 0) {\n return undefined;\n }\n lookupParents = parentNodes;\n }\n\n // We have unfiltered children tree and filtered nodes that are parents of first level nodes in unfiltered children tree.\n // We can start filtering unfiltered children tree based on filtered nodes.\n const result = getChildrenTreeIdsMatchingFilteredNodes({ tree: props.childrenTree, filteredNodes: lookupParents });\n return result.size > 0 ? result : undefined;\n}\n\nfunction getChildrenTreeIdsMatchingFilteredNodes({\n tree,\n filteredNodes,\n}: {\n tree: ChildrenTree;\n filteredNodes: Array<FilteredTreeNode | FilteredTreeRootNode>;\n}): Id64Set {\n const getIdsRecursively = (childrenTree: ChildrenTree, parentFilteredNodes: Array<FilteredTreeNode | FilteredTreeRootNode>): Id64Set => {\n // If one of the parent filtered nodes does not have children, it is filter target and because of this, all elements in the childrenTree are in the filtered tree.\n const hasParentFilterTarget = parentFilteredNodes.some((filteredNode) => \"isFilterTarget\" in filteredNode && filteredNode.isFilterTarget);\n if (hasParentFilterTarget) {\n return getIdsFromChildrenTree({ tree: childrenTree });\n }\n const result = new Set<Id64String>();\n childrenTree.forEach((entry, id) => {\n const nodes = findMatchingFilteredNodes(parentFilteredNodes, id);\n // If no filtered nodes match this id, skip it since it's not in the filtered tree.\n if (nodes.length === 0) {\n return;\n }\n // Id was found in filtered nodes children, add it to the result.\n result.add(id);\n if (entry.children) {\n // Continue recursively for children\n getIdsRecursively(entry.children, nodes).forEach((childId) => result.add(childId));\n }\n });\n return result;\n };\n\n return getIdsRecursively(tree, filteredNodes);\n}\n\nfunction getVisibilityChangeTargets(root: FilteredTreeRootNode, node: HierarchyNode & { key: ClassGroupingNodeKey | InstancesNodeKey }) {\n let lookupParents: Array<FilteredTreeRootNode | FilteredTreeNode> = [root];\n const changeTargets: VisibilityChangeTargets = {};\n\n // find the filtered parent nodes of the `node`\n for (const parentKey of node.parentKeys) {\n if (!HierarchyNodeKey.isInstances(parentKey)) {\n continue;\n }\n\n // tree node might be merged from multiple instances. As filtered tree stores only one instance per node, we need to find all matching nodes\n // and use them when checking for matching node in one level deeper.\n const parentNodes = findMatchingFilteredNodes(\n lookupParents,\n parentKey.instanceKeys.map((key) => key.id),\n );\n if (parentNodes.length === 0) {\n return changeTargets;\n }\n lookupParents = parentNodes;\n }\n const ids = HierarchyNode.isInstancesNode(node) ? node.key.instanceKeys.map(({ id }) => id) : node.groupedInstanceKeys.map(({ id }) => id);\n // find filtered nodes that match the `node`\n const filteredNodes = findMatchingFilteredNodes(lookupParents, ids);\n if (filteredNodes.length === 0) {\n return changeTargets;\n }\n\n filteredNodes.forEach((filteredNode) => collectVisibilityChangeTargets(changeTargets, filteredNode));\n return changeTargets;\n}\n\nfunction findMatchingFilteredNodes(lookupParents: Array<FilteredTreeRootNode | FilteredTreeNode>, ids: Id64Arg): Array<FilteredTreeNode> {\n return lookupParents.flatMap((lookup) => {\n const childrenArray = Array<FilteredTreeNode>();\n for (const id of Id64.iterable(ids)) {\n const node = lookup.children?.get(id);\n if (node) {\n childrenArray.push(node);\n }\n }\n return childrenArray;\n });\n}\n\nfunction collectVisibilityChangeTargets(changeTargets: VisibilityChangeTargets, node: FilteredTreeNode) {\n if (node.isFilterTarget) {\n addTarget(changeTargets, node);\n return;\n }\n\n if (node.type === \"element\") {\n // need to add parent ids as filter target will be an element\n addTarget(changeTargets, node);\n }\n\n if (!node.children) {\n return;\n }\n\n for (const child of node.children.values()) {\n collectVisibilityChangeTargets(changeTargets, child);\n }\n}\n\nfunction addTarget(filterTargets: VisibilityChangeTargets, node: FilteredTreeNode) {\n switch (node.type) {\n case \"subject\":\n (filterTargets.subjects ??= new Set()).add(node.id);\n return;\n case \"model\":\n (filterTargets.models ??= new Set()).add(node.id);\n return;\n case \"category\":\n (filterTargets.categories ??= new Set()).add(createCategoryKey(node.modelId, node.id));\n return;\n case \"element\":\n const categoryKey = createCategoryKey(node.modelId, node.categoryId);\n const elements = (filterTargets.elements ??= new Map()).get(categoryKey);\n if (elements) {\n elements.set(node.id, { isFilterTarget: node.isFilterTarget });\n } else {\n filterTargets.elements.set(categoryKey, new Map([[node.id, { isFilterTarget: node.isFilterTarget }]]));\n }\n }\n}\n\nfunction createFilteredTreeNode({\n type,\n id,\n isFilterTarget,\n parent,\n}: {\n type: FilteredTreeNode[\"type\"];\n id: string;\n isFilterTarget: boolean;\n parent: FilteredTreeNode | FilteredTreeRootNode;\n}): FilteredTreeNode {\n if (type === \"subject\" || type === \"model\") {\n return {\n id,\n isFilterTarget,\n type,\n };\n }\n\n if (type === \"category\") {\n assert(\"type\" in parent && parent.type === \"model\");\n return {\n id,\n isFilterTarget,\n type,\n modelId: parent.id,\n };\n }\n\n if (\"type\" in parent && parent.type === \"category\") {\n return {\n id,\n isFilterTarget,\n type,\n modelId: parent.modelId,\n categoryId: parent.id,\n };\n }\n\n if (\"type\" in parent && parent.type === \"element\") {\n return {\n id,\n isFilterTarget,\n type,\n modelId: parent.modelId,\n categoryId: parent.categoryId,\n };\n }\n\n throw new Error(\"Invalid parent node type\");\n}\n\nasync function getType(hierarchyChecker: ECClassHierarchyInspector, className: string) {\n if (await hierarchyChecker.classDerivesFrom(className, SUBJECT_CLASS_NAME)) {\n return \"subject\";\n }\n if (await hierarchyChecker.classDerivesFrom(className, MODEL_CLASS_NAME)) {\n return \"model\";\n }\n if (await hierarchyChecker.classDerivesFrom(className, CATEGORY_CLASS_NAME)) {\n return \"category\";\n }\n return \"element\";\n}\n"]}
|
package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { Observable } from "rxjs";
|
|
1
2
|
import type { GuidString, Id64Arg, Id64Array, Id64Set, Id64String } from "@itwin/core-bentley";
|
|
2
3
|
import type { HierarchyNodeIdentifiersPath, LimitingECSqlQueryExecutor } from "@itwin/presentation-hierarchies";
|
|
3
4
|
import type { ModelsTreeDefinition } from "../ModelsTreeDefinition.js";
|
|
5
|
+
import type { ChildrenTree } from "../Utils.js";
|
|
4
6
|
type ModelsTreeHierarchyConfiguration = ConstructorParameters<typeof ModelsTreeDefinition>[0]["hierarchyConfig"];
|
|
5
7
|
/** @internal */
|
|
6
8
|
export declare class ModelsTreeIdsCache implements Disposable {
|
|
@@ -9,31 +11,45 @@ export declare class ModelsTreeIdsCache implements Disposable {
|
|
|
9
11
|
[Symbol.dispose](): void;
|
|
10
12
|
private querySubjects;
|
|
11
13
|
private queryModels;
|
|
14
|
+
private queryChildren;
|
|
15
|
+
private getChildrenTreeFromMap;
|
|
16
|
+
private getChildrenCountMap;
|
|
17
|
+
/**
|
|
18
|
+
* Populates #childrenLoadingMap with promises. When these promises resolve, they will populate #childrenMap with values and delete entries from #childrenLoadingMap.
|
|
19
|
+
*/
|
|
20
|
+
private createChildrenLoadingMapEntries;
|
|
21
|
+
private createChildrenMapEntries;
|
|
22
|
+
getChildrenTree({ elementIds }: {
|
|
23
|
+
elementIds: Id64Arg;
|
|
24
|
+
}): Observable<ChildrenTree>;
|
|
25
|
+
getAllChildrenCount({ elementIds }: {
|
|
26
|
+
elementIds: Id64Arg;
|
|
27
|
+
}): Observable<Map<Id64String, number>>;
|
|
12
28
|
private getSubjectInfos;
|
|
13
29
|
/** Returns ECInstanceIDs of Subjects that either have direct Model or at least one child Subject with a Model. */
|
|
14
|
-
getParentSubjectIds():
|
|
30
|
+
getParentSubjectIds(): Observable<Id64Array>;
|
|
15
31
|
/**
|
|
16
32
|
* Returns child subjects of the specified parent subjects as they're displayed in the hierarchy - taking into
|
|
17
33
|
* account `hideInHierarchy` flag.
|
|
18
34
|
*/
|
|
19
|
-
getChildSubjectIds(parentSubjectIds:
|
|
35
|
+
getChildSubjectIds(parentSubjectIds: Id64Array): Observable<Id64Array>;
|
|
20
36
|
/** Returns ECInstanceIDs of all Models under specific parent Subjects, including their child Subjects, etc. */
|
|
21
|
-
getSubjectModelIds(subjectIds: Id64Array):
|
|
37
|
+
getSubjectModelIds(subjectIds: Id64Array): Observable<Id64Array>;
|
|
22
38
|
/** Returns ECInstanceIDs of Models under specific parent Subjects as they are displayed in the hierarchy. */
|
|
23
|
-
getChildSubjectModelIds(parentSubjectIds:
|
|
24
|
-
createSubjectInstanceKeysPath(targetSubjectId: Id64String):
|
|
39
|
+
getChildSubjectModelIds(parentSubjectIds: Id64Array): Observable<Id64Array>;
|
|
40
|
+
createSubjectInstanceKeysPath(targetSubjectId: Id64String): Observable<HierarchyNodeIdentifiersPath>;
|
|
25
41
|
private queryModelCategories;
|
|
26
42
|
private queryModeledElements;
|
|
27
43
|
private getModelWithCategoryModeledElements;
|
|
28
44
|
private getModelInfos;
|
|
29
|
-
getAllCategories():
|
|
30
|
-
getModelCategories(modelId: Id64String):
|
|
31
|
-
hasSubModel(elementId: Id64String):
|
|
32
|
-
getCategoriesModeledElements(modelId: Id64String, categoryIds: Id64Arg):
|
|
33
|
-
createModelInstanceKeyPaths(modelId: Id64String):
|
|
45
|
+
getAllCategories(): Observable<Id64Set>;
|
|
46
|
+
getModelCategories(modelId: Id64String): Observable<Id64Array>;
|
|
47
|
+
hasSubModel(elementId: Id64String): Observable<boolean>;
|
|
48
|
+
getCategoriesModeledElements(modelId: Id64String, categoryIds: Id64Arg): Observable<Id64Array>;
|
|
49
|
+
createModelInstanceKeyPaths(modelId: Id64String): Observable<HierarchyNodeIdentifiersPath[]>;
|
|
34
50
|
private queryCategoryElementCounts;
|
|
35
|
-
getCategoryElementsCount(modelId: Id64String, categoryId: Id64String):
|
|
36
|
-
createCategoryInstanceKeyPaths(categoryId: Id64String):
|
|
51
|
+
getCategoryElementsCount(modelId: Id64String, categoryId: Id64String): Observable<number>;
|
|
52
|
+
createCategoryInstanceKeyPaths(categoryId: Id64String): Observable<HierarchyNodeIdentifiersPath[]>;
|
|
37
53
|
}
|
|
38
54
|
export {};
|
|
39
55
|
//# sourceMappingURL=ModelsTreeIdsCache.d.ts.map
|