@itwin/tree-widget-react 4.0.0-alpha.6 → 4.0.0-alpha.8
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 -1
- package/README.md +2 -1
- package/lib/esm/tree-widget-react/TreeWidget.d.ts +6 -1
- package/lib/esm/tree-widget-react/TreeWidget.js +19 -2
- package/lib/esm/tree-widget-react/TreeWidget.js.map +1 -1
- package/lib/esm/tree-widget-react/components/TreeWidgetComponentImpl.d.ts +6 -0
- package/lib/esm/tree-widget-react/components/TreeWidgetComponentImpl.js +22 -23
- package/lib/esm/tree-widget-react/components/TreeWidgetComponentImpl.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/ErrorState.js +1 -1
- package/lib/esm/tree-widget-react/components/tree-header/ErrorState.js.map +1 -1
- package/lib/esm/tree-widget-react/components/tree-header/SearchBox.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/tree-header/SearchBox.js +4 -4
- package/lib/esm/tree-widget-react/components/tree-header/SearchBox.js.map +1 -1
- package/lib/esm/tree-widget-react/components/tree-header/SelectableTree.css +2 -0
- package/lib/esm/tree-widget-react/components/tree-header/WidgetHeader.css +1 -0
- package/lib/esm/tree-widget-react/components/tree-header/WidgetHeader.d.ts +12 -4
- package/lib/esm/tree-widget-react/components/tree-header/WidgetHeader.js +13 -9
- package/lib/esm/tree-widget-react/components/tree-header/WidgetHeader.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 -2
- 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.d.ts +9 -2
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeButtons.js +53 -7
- 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 +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 +17 -3
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.js +561 -161
- 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 +6 -2
- package/lib/esm/tree-widget-react/components/trees/categories-tree/UseCategoriesTree.js +46 -117
- 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 +30 -15
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.js +188 -38
- 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/CategoriesTreeNode.d.ts +18 -3
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeNode.js +30 -3
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeNode.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeVisibilityHandler.d.ts +24 -0
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeVisibilityHandler.js +701 -0
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeVisibilityHandler.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/FilteredTree.d.ts +39 -0
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/FilteredTree.js +221 -0
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/FilteredTree.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseFilteredPaths.d.ts +25 -0
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseFilteredPaths.js +133 -0
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseFilteredPaths.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseIdsCache.d.ts +8 -0
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseIdsCache.js +48 -0
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseIdsCache.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.d.ts +5 -17
- package/lib/esm/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.js +5 -62
- package/lib/esm/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/UseHierarchyVisibility.d.ts +2 -2
- package/lib/esm/tree-widget-react/components/trees/common/UseHierarchyVisibility.js +11 -5
- package/lib/esm/tree-widget-react/components/trees/common/UseHierarchyVisibility.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/UseNodeHighlighting.d.ts +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/UseNodeHighlighting.js +13 -11
- package/lib/esm/tree-widget-react/components/trees/common/UseNodeHighlighting.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/UseTelemetryContext.d.ts +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/UseTelemetryContext.js +2 -1
- package/lib/esm/tree-widget-react/components/trees/common/UseTelemetryContext.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/Utils.d.ts +38 -23
- package/lib/esm/tree-widget-react/components/trees/common/Utils.js +65 -47
- package/lib/esm/tree-widget-react/components/trees/common/Utils.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/BaseTreeRenderer.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/BaseTreeRenderer.js +4 -4
- package/lib/esm/tree-widget-react/components/trees/common/components/BaseTreeRenderer.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/Delayed.d.ts +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/components/Delayed.js +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/components/Delayed.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/ProgressOverlay.d.ts +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/components/ProgressOverlay.js +1 -0
- 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.css +2 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/Tree.d.ts +3 -3
- package/lib/esm/tree-widget-react/components/trees/common/components/Tree.js +15 -6
- 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/TreeNodeVisibilityButton.d.ts +6 -4
- package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeVisibilityButton.js +20 -25
- package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeVisibilityButton.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 +10 -4
- 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/UseVisibilityButtonHandler.d.ts +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/components/UseVisibilityButtonHandler.js +7 -3
- package/lib/esm/tree-widget-react/components/trees/common/components/UseVisibilityButtonHandler.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTree.js +1 -1
- 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 +12 -11
- 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/AlwaysAndNeverDrawnElementInfo.d.ts +44 -0
- package/lib/esm/tree-widget-react/components/trees/{models-tree → common}/internal/AlwaysAndNeverDrawnElementInfo.js +81 -31
- package/lib/esm/tree-widget-react/components/trees/common/internal/AlwaysAndNeverDrawnElementInfo.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/ClassNameDefinitions.d.ts +33 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/ClassNameDefinitions.js +37 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/ClassNameDefinitions.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/ModelCategoryElementsCountCache.d.ts +16 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/ModelCategoryElementsCountCache.js +72 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/ModelCategoryElementsCountCache.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/{Rxjs.d.ts → internal/Rxjs.d.ts} +9 -2
- package/lib/esm/tree-widget-react/components/trees/common/{Rxjs.js → internal/Rxjs.js} +9 -2
- package/lib/esm/tree-widget-react/components/trees/common/internal/Rxjs.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/{Tooltip.d.ts → internal/Tooltip.d.ts} +4 -8
- package/lib/esm/tree-widget-react/components/trees/common/{Tooltip.js → internal/Tooltip.js} +4 -10
- package/lib/esm/tree-widget-react/components/trees/common/internal/Tooltip.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/Types.d.ts +14 -0
- package/lib/esm/tree-widget-react/components/{tree-header/SearchBox.css → trees/common/internal/Types.js} +2 -4
- package/lib/esm/tree-widget-react/components/trees/common/internal/Types.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/UseActiveViewport.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/{UseHierarchiesLocalization.d.ts → internal/UseHierarchiesLocalization.d.ts} +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/{UseHierarchiesLocalization.js → internal/UseHierarchiesLocalization.js} +6 -2
- package/lib/esm/tree-widget-react/components/trees/common/internal/UseHierarchiesLocalization.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/{UseHierarchyFiltering.d.ts → internal/UseHierarchyFiltering.d.ts} +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/{UseHierarchyFiltering.js → internal/UseHierarchyFiltering.js} +4 -3
- package/lib/esm/tree-widget-react/components/trees/common/internal/UseHierarchyFiltering.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/{UseIModelChangeListener.d.ts → internal/UseIModelChangeListener.d.ts} +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/{UseIModelChangeListener.js → internal/UseIModelChangeListener.js} +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/UseIModelChangeListener.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/Utils.d.ts +47 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/Utils.js +101 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/Utils.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityChangeEventListener.d.ts +20 -0
- package/lib/esm/tree-widget-react/components/trees/{models-tree → common}/internal/VisibilityChangeEventListener.js +17 -9
- package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityChangeEventListener.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityUtils.d.ts +63 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityUtils.js +210 -0
- package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityUtils.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTree.d.ts +2 -2
- package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTree.js +8 -8
- 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/ExternalSourcesTreeComponent.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeComponent.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeDefinition.d.ts +1 -0
- package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeDefinition.js +1 -0
- 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 +4 -2
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTree.js +22 -18
- 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/IModelContentTreeComponent.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeComponent.js +1 -1
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeComponent.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.d.ts +13 -0
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.js +39 -38
- 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 +5 -5
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/internal/IModelContentTreeIdsCache.js +25 -24
- 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/ModelsTree.d.ts +2 -2
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTree.js +2 -2
- 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 +15 -11
- 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.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeComponent.js +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 +7 -2
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.js +73 -70
- 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 +36 -202
- 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/internal/FilteredTree.d.ts +7 -9
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/FilteredTree.js +4 -6
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/FilteredTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.d.ts +4 -5
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js +54 -104
- 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 +0 -26
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js +80 -359
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseFilteredPaths.d.ts +27 -0
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseFilteredPaths.js +170 -0
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseFilteredPaths.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseIdsCache.d.ts +8 -0
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseIdsCache.js +47 -0
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseIdsCache.js.map +1 -0
- package/lib/public/locales/en/TreeWidget.json +13 -59
- package/package.json +19 -20
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesVisibilityHandler.d.ts +0 -37
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesVisibilityHandler.js +0 -214
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesVisibilityHandler.js.map +0 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/ClassNameDefinitions.d.ts +0 -7
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/ClassNameDefinitions.js +0 -11
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/ClassNameDefinitions.js.map +0 -1
- package/lib/esm/tree-widget-react/components/trees/common/Rxjs.js.map +0 -1
- package/lib/esm/tree-widget-react/components/trees/common/Tooltip.js.map +0 -1
- package/lib/esm/tree-widget-react/components/trees/common/UseActiveViewport.js.map +0 -1
- package/lib/esm/tree-widget-react/components/trees/common/UseFiltering.d.ts +0 -11
- package/lib/esm/tree-widget-react/components/trees/common/UseFiltering.js +0 -24
- package/lib/esm/tree-widget-react/components/trees/common/UseFiltering.js.map +0 -1
- package/lib/esm/tree-widget-react/components/trees/common/UseHierarchiesLocalization.js.map +0 -1
- package/lib/esm/tree-widget-react/components/trees/common/UseHierarchyFiltering.js.map +0 -1
- package/lib/esm/tree-widget-react/components/trees/common/UseIModelChangeListener.js.map +0 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/Utils.d.ts +0 -7
- package/lib/esm/tree-widget-react/components/trees/models-tree/Utils.js +0 -21
- package/lib/esm/tree-widget-react/components/trees/models-tree/Utils.js.map +0 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.d.ts +0 -29
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.js.map +0 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/VisibilityChangeEventListener.d.ts +0 -12
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/VisibilityChangeEventListener.js.map +0 -1
- /package/lib/esm/tree-widget-react/components/trees/common/{UseActiveViewport.d.ts → internal/UseActiveViewport.d.ts} +0 -0
- /package/lib/esm/tree-widget-react/components/trees/common/{UseActiveViewport.js → internal/UseActiveViewport.js} +0 -0
package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseFilteredPaths.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { useEffect, useMemo, useState } from "react";
|
|
6
|
+
import { assert } from "@itwin/core-bentley";
|
|
7
|
+
import { HierarchyFilteringPath, HierarchyNodeIdentifier } from "@itwin/presentation-hierarchies";
|
|
8
|
+
import { DEFINITION_CONTAINER_CLASS_NAME, SUB_CATEGORY_CLASS_NAME } from "../../common/internal/ClassNameDefinitions.js";
|
|
9
|
+
import { getClassesByView } from "../../common/internal/Utils.js";
|
|
10
|
+
import { FilterLimitExceededError } from "../../common/TreeErrors.js";
|
|
11
|
+
import { useTelemetryContext } from "../../common/UseTelemetryContext.js";
|
|
12
|
+
import { CategoriesTreeDefinition } from "../CategoriesTreeDefinition.js";
|
|
13
|
+
/** @internal */
|
|
14
|
+
export function useFilteredPaths({ filter, viewType, hierarchyConfiguration, getCategoriesTreeIdsCache, onCategoriesFiltered, onFilteredPathsChanged, }) {
|
|
15
|
+
const [filteringError, setFilteringError] = useState();
|
|
16
|
+
const { onFeatureUsed } = useTelemetryContext();
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
setFilteringError(undefined);
|
|
19
|
+
onCategoriesFiltered?.({ categories: undefined, models: undefined });
|
|
20
|
+
if (!filter) {
|
|
21
|
+
onFilteredPathsChanged(undefined);
|
|
22
|
+
}
|
|
23
|
+
}, [filter, onCategoriesFiltered, onFilteredPathsChanged]);
|
|
24
|
+
const getFilteredPaths = useMemo(() => {
|
|
25
|
+
if (!filter) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
return async ({ imodelAccess }) => {
|
|
29
|
+
onFeatureUsed({ featureId: "filtering", reportInteraction: true });
|
|
30
|
+
try {
|
|
31
|
+
const paths = await CategoriesTreeDefinition.createInstanceKeyPaths({
|
|
32
|
+
imodelAccess,
|
|
33
|
+
label: filter,
|
|
34
|
+
viewType,
|
|
35
|
+
idsCache: getCategoriesTreeIdsCache(),
|
|
36
|
+
hierarchyConfig: hierarchyConfiguration,
|
|
37
|
+
});
|
|
38
|
+
onFilteredPathsChanged(paths);
|
|
39
|
+
const { elementClass, modelClass } = getClassesByView(viewType);
|
|
40
|
+
onCategoriesFiltered?.(await getCategoriesFromPaths(paths, getCategoriesTreeIdsCache(), elementClass, modelClass));
|
|
41
|
+
return paths;
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
const newError = e instanceof FilterLimitExceededError ? "tooManyFilterMatches" : "unknownFilterError";
|
|
45
|
+
if (newError !== "tooManyFilterMatches") {
|
|
46
|
+
const feature = e instanceof Error && e.message.includes("query too long to execute or server is too busy") ? "error-timeout" : "error-unknown";
|
|
47
|
+
onFeatureUsed({ featureId: feature, reportInteraction: false });
|
|
48
|
+
}
|
|
49
|
+
setFilteringError(newError);
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}, [onCategoriesFiltered, filter, onFilteredPathsChanged, onFeatureUsed, viewType, getCategoriesTreeIdsCache, hierarchyConfiguration]);
|
|
54
|
+
return {
|
|
55
|
+
getPaths: getFilteredPaths,
|
|
56
|
+
filteringError,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
async function getCategoriesFromPaths(paths, idsCache, elementClassName, modelsClassName) {
|
|
60
|
+
if (!paths) {
|
|
61
|
+
return { categories: undefined };
|
|
62
|
+
}
|
|
63
|
+
const rootFilteredElementIds = new Set();
|
|
64
|
+
const subModelIds = new Set();
|
|
65
|
+
const categories = new Map();
|
|
66
|
+
for (const path of paths) {
|
|
67
|
+
const currPath = HierarchyFilteringPath.normalize(path).path;
|
|
68
|
+
if (currPath.length === 0) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
let category;
|
|
72
|
+
let subCategory;
|
|
73
|
+
let lastNodeInfo;
|
|
74
|
+
for (let i = 0; i < currPath.length; ++i) {
|
|
75
|
+
const currentNode = currPath[i];
|
|
76
|
+
if (!HierarchyNodeIdentifier.isInstanceNodeIdentifier(currentNode)) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (currentNode.className === elementClassName) {
|
|
80
|
+
rootFilteredElementIds.add(currentNode.id);
|
|
81
|
+
for (let j = i + 1; j < currPath.length; ++j) {
|
|
82
|
+
const childNode = currPath[j];
|
|
83
|
+
if (!HierarchyNodeIdentifier.isInstanceNodeIdentifier(childNode)) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (childNode.className === modelsClassName) {
|
|
87
|
+
subModelIds.add(childNode.id);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
lastNodeInfo = { lastNode: currentNode, nodeIndex: i };
|
|
93
|
+
}
|
|
94
|
+
assert(lastNodeInfo !== undefined && HierarchyNodeIdentifier.isInstanceNodeIdentifier(lastNodeInfo.lastNode));
|
|
95
|
+
if (lastNodeInfo.lastNode.className === DEFINITION_CONTAINER_CLASS_NAME) {
|
|
96
|
+
const definitionContainerCategories = await idsCache.getAllContainedCategories([lastNodeInfo.lastNode.id]);
|
|
97
|
+
for (const categoryId of definitionContainerCategories) {
|
|
98
|
+
const value = categories.get(categoryId);
|
|
99
|
+
if (value === undefined) {
|
|
100
|
+
categories.set(categoryId, []);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (lastNodeInfo.lastNode.className === SUB_CATEGORY_CLASS_NAME) {
|
|
106
|
+
const secondToLastNode = lastNodeInfo.nodeIndex > 0 ? currPath[lastNodeInfo.nodeIndex - 1] : undefined;
|
|
107
|
+
assert(secondToLastNode !== undefined && HierarchyNodeIdentifier.isInstanceNodeIdentifier(secondToLastNode));
|
|
108
|
+
subCategory = lastNodeInfo.lastNode;
|
|
109
|
+
category = secondToLastNode;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
category = lastNodeInfo.lastNode;
|
|
113
|
+
}
|
|
114
|
+
let entry = categories.get(category.id);
|
|
115
|
+
if (entry === undefined) {
|
|
116
|
+
entry = [];
|
|
117
|
+
categories.set(category.id, entry);
|
|
118
|
+
}
|
|
119
|
+
if (subCategory) {
|
|
120
|
+
entry.push(subCategory.id);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const rootElementModelMap = await idsCache.getFilteredElementsModels([...rootFilteredElementIds]);
|
|
124
|
+
const models = [...subModelIds, ...new Set(rootElementModelMap.values())];
|
|
125
|
+
return {
|
|
126
|
+
categories: [...categories.entries()].map(([categoryId, subCategoryIds]) => ({
|
|
127
|
+
categoryId,
|
|
128
|
+
subCategoryIds: subCategoryIds.length === 0 ? undefined : subCategoryIds,
|
|
129
|
+
})),
|
|
130
|
+
models,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=UseFilteredPaths.js.map
|
package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseFilteredPaths.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UseFilteredPaths.js","sourceRoot":"","sources":["../../../../../../../src/tree-widget-react/components/trees/categories-tree/internal/UseFilteredPaths.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 { useEffect, useMemo, useState } from \"react\";\nimport { assert } from \"@itwin/core-bentley\";\nimport { HierarchyFilteringPath, HierarchyNodeIdentifier } from \"@itwin/presentation-hierarchies\";\nimport { DEFINITION_CONTAINER_CLASS_NAME, SUB_CATEGORY_CLASS_NAME } from \"../../common/internal/ClassNameDefinitions.js\";\nimport { getClassesByView } from \"../../common/internal/Utils.js\";\nimport { FilterLimitExceededError } from \"../../common/TreeErrors.js\";\nimport { useTelemetryContext } from \"../../common/UseTelemetryContext.js\";\nimport { CategoriesTreeDefinition } from \"../CategoriesTreeDefinition.js\";\n\nimport type { VisibilityTreeProps } from \"../../common/components/VisibilityTree.js\";\nimport type { CategoriesTreeHierarchyConfiguration } from \"../CategoriesTreeDefinition.js\";\nimport type { CategoriesTreeIdsCache } from \"./CategoriesTreeIdsCache.js\";\nimport type { CategoryId, ElementId, ModelId, SubCategoryId } from \"../../common/internal/Types.js\";\nimport type { CategoryInfo } from \"../../common/CategoriesVisibilityUtils.js\";\n\n/** @internal */\nexport type CategoriesTreeFilteringError = \"tooManyFilterMatches\" | \"unknownFilterError\";\n\ntype HierarchyFilteringPaths = Awaited<ReturnType<Required<VisibilityTreeProps>[\"getFilteredPaths\"]>>;\n\n/** @internal */\nexport function useFilteredPaths({\n filter,\n viewType,\n hierarchyConfiguration,\n getCategoriesTreeIdsCache,\n onCategoriesFiltered,\n onFilteredPathsChanged,\n}: {\n viewType: \"2d\" | \"3d\";\n filter?: string;\n hierarchyConfiguration: CategoriesTreeHierarchyConfiguration;\n getCategoriesTreeIdsCache: () => CategoriesTreeIdsCache;\n onCategoriesFiltered?: (categories: { categories: CategoryInfo[] | undefined; models?: Array<ModelId> }) => void;\n onFilteredPathsChanged: (paths: HierarchyFilteringPaths | undefined) => void;\n}): {\n getPaths: VisibilityTreeProps[\"getFilteredPaths\"] | undefined;\n filteringError: CategoriesTreeFilteringError | undefined;\n} {\n const [filteringError, setFilteringError] = useState<CategoriesTreeFilteringError | undefined>();\n const { onFeatureUsed } = useTelemetryContext();\n\n useEffect(() => {\n setFilteringError(undefined);\n onCategoriesFiltered?.({ categories: undefined, models: undefined });\n if (!filter) {\n onFilteredPathsChanged(undefined);\n }\n }, [filter, onCategoriesFiltered, onFilteredPathsChanged]);\n\n const getFilteredPaths = useMemo<VisibilityTreeProps[\"getFilteredPaths\"] | undefined>(() => {\n if (!filter) {\n return undefined;\n }\n\n return async ({ imodelAccess }) => {\n onFeatureUsed({ featureId: \"filtering\", reportInteraction: true });\n try {\n const paths = await CategoriesTreeDefinition.createInstanceKeyPaths({\n imodelAccess,\n label: filter,\n viewType,\n idsCache: getCategoriesTreeIdsCache(),\n hierarchyConfig: hierarchyConfiguration,\n });\n onFilteredPathsChanged(paths);\n const { elementClass, modelClass } = getClassesByView(viewType);\n onCategoriesFiltered?.(await getCategoriesFromPaths(paths, getCategoriesTreeIdsCache(), elementClass, modelClass));\n return paths;\n } catch (e) {\n const newError = e instanceof FilterLimitExceededError ? \"tooManyFilterMatches\" : \"unknownFilterError\";\n if (newError !== \"tooManyFilterMatches\") {\n const feature = e instanceof Error && e.message.includes(\"query too long to execute or server is too busy\") ? \"error-timeout\" : \"error-unknown\";\n onFeatureUsed({ featureId: feature, reportInteraction: false });\n }\n setFilteringError(newError);\n return [];\n }\n };\n }, [onCategoriesFiltered, filter, onFilteredPathsChanged, onFeatureUsed, viewType, getCategoriesTreeIdsCache, hierarchyConfiguration]);\n\n return {\n getPaths: getFilteredPaths,\n filteringError,\n };\n}\n\nasync function getCategoriesFromPaths(\n paths: HierarchyFilteringPaths,\n idsCache: CategoriesTreeIdsCache,\n elementClassName: string,\n modelsClassName: string,\n): Promise<{ categories: CategoryInfo[] | undefined; models?: Array<ModelId> }> {\n if (!paths) {\n return { categories: undefined };\n }\n\n const rootFilteredElementIds = new Set<ElementId>();\n const subModelIds = new Set<ModelId>();\n\n const categories = new Map<CategoryId, Array<SubCategoryId>>();\n for (const path of paths) {\n const currPath = HierarchyFilteringPath.normalize(path).path;\n if (currPath.length === 0) {\n continue;\n }\n\n let category: HierarchyNodeIdentifier;\n let subCategory: HierarchyNodeIdentifier | undefined;\n\n let lastNodeInfo: { lastNode: HierarchyNodeIdentifier; nodeIndex: number } | undefined;\n\n for (let i = 0; i < currPath.length; ++i) {\n const currentNode = currPath[i];\n if (!HierarchyNodeIdentifier.isInstanceNodeIdentifier(currentNode)) {\n continue;\n }\n if (currentNode.className === elementClassName) {\n rootFilteredElementIds.add(currentNode.id);\n for (let j = i + 1; j < currPath.length; ++j) {\n const childNode = currPath[j];\n if (!HierarchyNodeIdentifier.isInstanceNodeIdentifier(childNode)) {\n continue;\n }\n if (childNode.className === modelsClassName) {\n subModelIds.add(childNode.id);\n }\n }\n break;\n }\n lastNodeInfo = { lastNode: currentNode, nodeIndex: i };\n }\n\n assert(lastNodeInfo !== undefined && HierarchyNodeIdentifier.isInstanceNodeIdentifier(lastNodeInfo.lastNode));\n\n if (lastNodeInfo.lastNode.className === DEFINITION_CONTAINER_CLASS_NAME) {\n const definitionContainerCategories = await idsCache.getAllContainedCategories([lastNodeInfo.lastNode.id]);\n for (const categoryId of definitionContainerCategories) {\n const value = categories.get(categoryId);\n if (value === undefined) {\n categories.set(categoryId, []);\n }\n }\n continue;\n }\n\n if (lastNodeInfo.lastNode.className === SUB_CATEGORY_CLASS_NAME) {\n const secondToLastNode = lastNodeInfo.nodeIndex > 0 ? currPath[lastNodeInfo.nodeIndex - 1] : undefined;\n assert(secondToLastNode !== undefined && HierarchyNodeIdentifier.isInstanceNodeIdentifier(secondToLastNode));\n\n subCategory = lastNodeInfo.lastNode;\n category = secondToLastNode;\n } else {\n category = lastNodeInfo.lastNode;\n }\n\n let entry = categories.get(category.id);\n if (entry === undefined) {\n entry = [];\n categories.set(category.id, entry);\n }\n\n if (subCategory) {\n entry.push(subCategory.id);\n }\n }\n const rootElementModelMap = await idsCache.getFilteredElementsModels([...rootFilteredElementIds]);\n const models = [...subModelIds, ...new Set(rootElementModelMap.values())];\n return {\n categories: [...categories.entries()].map(([categoryId, subCategoryIds]) => ({\n categoryId,\n subCategoryIds: subCategoryIds.length === 0 ? undefined : subCategoryIds,\n })),\n models,\n };\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CategoriesTreeIdsCache } from "./CategoriesTreeIdsCache.js";
|
|
2
|
+
import type { IModelConnection } from "@itwin/core-frontend";
|
|
3
|
+
import type { HierarchyFilteringPath } from "@itwin/presentation-hierarchies";
|
|
4
|
+
/** @internal */
|
|
5
|
+
export declare function useIdsCache(imodel: IModelConnection, viewType: "2d" | "3d", filteredPaths?: HierarchyFilteringPath[]): {
|
|
6
|
+
getCache: () => CategoriesTreeIdsCache;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=UseIdsCache.d.ts.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
6
|
+
import { createECSqlQueryExecutor } from "@itwin/presentation-core-interop";
|
|
7
|
+
import { useIModelChangeListener } from "../../common/internal/UseIModelChangeListener.js";
|
|
8
|
+
import { CategoriesTreeIdsCache } from "./CategoriesTreeIdsCache.js";
|
|
9
|
+
/** @internal */
|
|
10
|
+
export function useIdsCache(imodel, viewType, filteredPaths) {
|
|
11
|
+
const cacheRef = useRef(undefined);
|
|
12
|
+
const clearCacheRef = useRef(() => () => {
|
|
13
|
+
cacheRef.current?.[Symbol.dispose]?.();
|
|
14
|
+
cacheRef.current = undefined;
|
|
15
|
+
});
|
|
16
|
+
const createCacheGetterRef = useRef((currImodel, currViewType) => () => {
|
|
17
|
+
if (cacheRef.current === undefined) {
|
|
18
|
+
cacheRef.current = new CategoriesTreeIdsCache(createECSqlQueryExecutor(currImodel), currViewType);
|
|
19
|
+
}
|
|
20
|
+
return cacheRef.current;
|
|
21
|
+
});
|
|
22
|
+
const [getCache, setCacheGetter] = useState(() => createCacheGetterRef.current(imodel, viewType));
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
// clear cache in case it was created before `useEffect` was run first time
|
|
25
|
+
clearCacheRef.current();
|
|
26
|
+
// make sure all cache users rerender
|
|
27
|
+
setCacheGetter(() => createCacheGetterRef.current(imodel, viewType));
|
|
28
|
+
return () => {
|
|
29
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
30
|
+
clearCacheRef.current();
|
|
31
|
+
};
|
|
32
|
+
}, [imodel, viewType]);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
cacheRef.current?.clearFilteredElementsModels();
|
|
35
|
+
}, [filteredPaths]);
|
|
36
|
+
useIModelChangeListener({
|
|
37
|
+
imodel,
|
|
38
|
+
action: useCallback(() => {
|
|
39
|
+
clearCacheRef.current();
|
|
40
|
+
// make sure all cache users rerender
|
|
41
|
+
setCacheGetter(() => createCacheGetterRef.current(imodel, viewType));
|
|
42
|
+
}, [imodel, viewType]),
|
|
43
|
+
});
|
|
44
|
+
return {
|
|
45
|
+
getCache,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=UseIdsCache.js.map
|
package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseIdsCache.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UseIdsCache.js","sourceRoot":"","sources":["../../../../../../../src/tree-widget-react/components/trees/categories-tree/internal/UseIdsCache.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,uBAAuB,EAAE,MAAM,kDAAkD,CAAC;AAC3F,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAKrE,gBAAgB;AAChB,MAAM,UAAU,WAAW,CAAC,MAAwB,EAAE,QAAqB,EAAE,aAAwC;IACnH,MAAM,QAAQ,GAAG,MAAM,CAAqC,SAAS,CAAC,CAAC;IACvE,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE;QACtC,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QACvC,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC;IAC/B,CAAC,CAAC,CAAC;IACH,MAAM,oBAAoB,GAAG,MAAM,CAAC,CAAC,UAA4B,EAAE,YAAyB,EAAE,EAAE,CAAC,GAAG,EAAE;QACpG,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE;YAClC,QAAQ,CAAC,OAAO,GAAG,IAAI,sBAAsB,CAAC,wBAAwB,CAAC,UAAU,CAAC,EAAE,YAAY,CAAC,CAAC;SACnG;QACD,OAAO,QAAQ,CAAC,OAAO,CAAC;IAC1B,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,QAAQ,EAAE,cAAc,CAAC,GAAG,QAAQ,CAA+B,GAAG,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEhI,SAAS,CAAC,GAAG,EAAE;QACb,2EAA2E;QAC3E,aAAa,CAAC,OAAO,EAAE,CAAC;QAExB,qCAAqC;QACrC,cAAc,CAAC,GAAG,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QACrE,OAAO,GAAG,EAAE;YACV,uDAAuD;YACvD,aAAa,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEvB,SAAS,CAAC,GAAG,EAAE;QACb,QAAQ,CAAC,OAAO,EAAE,2BAA2B,EAAE,CAAC;IAClD,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,uBAAuB,CAAC;QACtB,MAAM;QACN,MAAM,EAAE,WAAW,CAAC,GAAG,EAAE;YACvB,aAAa,CAAC,OAAO,EAAE,CAAC;YACxB,qCAAqC;YACrC,cAAc,CAAC,GAAG,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;KACvB,CAAC,CAAC;IAEH,OAAO;QACL,QAAQ;KACT,CAAC;AACJ,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 { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createECSqlQueryExecutor } from \"@itwin/presentation-core-interop\";\nimport { useIModelChangeListener } from \"../../common/internal/UseIModelChangeListener.js\";\nimport { CategoriesTreeIdsCache } from \"./CategoriesTreeIdsCache.js\";\n\nimport type { IModelConnection } from \"@itwin/core-frontend\";\nimport type { HierarchyFilteringPath } from \"@itwin/presentation-hierarchies\";\n\n/** @internal */\nexport function useIdsCache(imodel: IModelConnection, viewType: \"2d\" | \"3d\", filteredPaths?: HierarchyFilteringPath[]) {\n const cacheRef = useRef<CategoriesTreeIdsCache | undefined>(undefined);\n const clearCacheRef = useRef(() => () => {\n cacheRef.current?.[Symbol.dispose]?.();\n cacheRef.current = undefined;\n });\n const createCacheGetterRef = useRef((currImodel: IModelConnection, currViewType: \"2d\" | \"3d\") => () => {\n if (cacheRef.current === undefined) {\n cacheRef.current = new CategoriesTreeIdsCache(createECSqlQueryExecutor(currImodel), currViewType);\n }\n return cacheRef.current;\n });\n const [getCache, setCacheGetter] = useState<() => CategoriesTreeIdsCache>(() => createCacheGetterRef.current(imodel, viewType));\n\n useEffect(() => {\n // clear cache in case it was created before `useEffect` was run first time\n clearCacheRef.current();\n\n // make sure all cache users rerender\n setCacheGetter(() => createCacheGetterRef.current(imodel, viewType));\n return () => {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n clearCacheRef.current();\n };\n }, [imodel, viewType]);\n\n useEffect(() => {\n cacheRef.current?.clearFilteredElementsModels();\n }, [filteredPaths]);\n\n useIModelChangeListener({\n imodel,\n action: useCallback(() => {\n clearCacheRef.current();\n // make sure all cache users rerender\n setCacheGetter(() => createCacheGetterRef.current(imodel, viewType));\n }, [imodel, viewType]),\n });\n\n return {\n getCache,\n };\n}\n"]}
|
|
@@ -1,35 +1,23 @@
|
|
|
1
|
+
import type { Id64Array, Id64String } from "@itwin/core-bentley";
|
|
1
2
|
import type { Viewport } from "@itwin/core-frontend";
|
|
2
3
|
/**
|
|
3
4
|
* Data structure that describes category.
|
|
4
5
|
* @beta
|
|
5
6
|
*/
|
|
6
7
|
export interface CategoryInfo {
|
|
7
|
-
categoryId:
|
|
8
|
-
subCategoryIds?:
|
|
8
|
+
categoryId: Id64String;
|
|
9
|
+
subCategoryIds?: Id64Array;
|
|
9
10
|
}
|
|
10
|
-
/**
|
|
11
|
-
* Toggles visibility of categories to show or hide.
|
|
12
|
-
*/
|
|
13
|
-
export declare function toggleAllCategories(viewport: Viewport, display: boolean): Promise<void>;
|
|
14
|
-
/**
|
|
15
|
-
* Changes category display in the viewport.
|
|
16
|
-
*/
|
|
17
|
-
export declare function enableCategoryDisplay(viewport: Viewport, ids: string[], enabled: boolean, enableAllSubCategories?: boolean): Promise<void>;
|
|
18
|
-
/**
|
|
19
|
-
* Changes subcategory display in the viewport
|
|
20
|
-
*/
|
|
21
|
-
export declare function enableSubCategoryDisplay(viewport: Viewport, key: string, enabled: boolean): void;
|
|
22
|
-
export declare function loadCategoriesFromViewport(vp: Viewport): Promise<CategoryInfo[]>;
|
|
23
11
|
/**
|
|
24
12
|
* Enable display of all given categories.
|
|
25
13
|
* @public
|
|
26
14
|
*/
|
|
27
|
-
export declare function showAllCategories(categories:
|
|
15
|
+
export declare function showAllCategories(categories: Id64Array, viewport: Viewport): Promise<void>;
|
|
28
16
|
/**
|
|
29
17
|
* Disable display of all given categories.
|
|
30
18
|
* @public
|
|
31
19
|
*/
|
|
32
|
-
export declare function hideAllCategories(categories:
|
|
20
|
+
export declare function hideAllCategories(categories: Id64Array, viewport: Viewport): Promise<void>;
|
|
33
21
|
/**
|
|
34
22
|
* Invert display of all given categories.
|
|
35
23
|
* @public
|
|
@@ -2,64 +2,7 @@
|
|
|
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 {
|
|
6
|
-
import { PerModelCategoryVisibility } from "@itwin/core-frontend";
|
|
7
|
-
/**
|
|
8
|
-
* Toggles visibility of categories to show or hide.
|
|
9
|
-
*/
|
|
10
|
-
export async function toggleAllCategories(viewport, display) {
|
|
11
|
-
const ids = await getCategories(viewport);
|
|
12
|
-
if (ids.length === 0) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
await enableCategoryDisplay(viewport, ids, display);
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Gets ids of all categories from specified imodel and viewport.
|
|
19
|
-
*/
|
|
20
|
-
async function getCategories(viewport) {
|
|
21
|
-
const categories = await loadCategoriesFromViewport(viewport);
|
|
22
|
-
return categories.map((category) => category.categoryId);
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Changes category display in the viewport.
|
|
26
|
-
*/
|
|
27
|
-
export async function enableCategoryDisplay(viewport, ids, enabled, enableAllSubCategories = true) {
|
|
28
|
-
viewport.changeCategoryDisplay(ids, enabled, enableAllSubCategories);
|
|
29
|
-
// remove category overrides per model
|
|
30
|
-
const modelsContainingOverrides = [];
|
|
31
|
-
for (const ovr of viewport.perModelCategoryVisibility) {
|
|
32
|
-
if (ids.findIndex((id) => id === ovr.categoryId) !== -1) {
|
|
33
|
-
modelsContainingOverrides.push(ovr.modelId);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
viewport.perModelCategoryVisibility.setOverride(modelsContainingOverrides, ids, PerModelCategoryVisibility.Override.None);
|
|
37
|
-
// changeCategoryDisplay only enables subcategories, it does not disabled them. So we must do that ourselves.
|
|
38
|
-
if (false === enabled) {
|
|
39
|
-
(await viewport.iModel.categories.getCategoryInfo(ids)).forEach((categoryInfo) => {
|
|
40
|
-
categoryInfo.subCategories.forEach((value) => enableSubCategoryDisplay(viewport, value.id, false));
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Changes subcategory display in the viewport
|
|
46
|
-
*/
|
|
47
|
-
export function enableSubCategoryDisplay(viewport, key, enabled) {
|
|
48
|
-
viewport.changeSubCategoryDisplay(key, enabled);
|
|
49
|
-
}
|
|
50
|
-
export async function loadCategoriesFromViewport(vp) {
|
|
51
|
-
// Query categories and add them to state
|
|
52
|
-
const selectUsedSpatialCategoryIds = "SELECT DISTINCT Category.Id as id from BisCore.GeometricElement3d WHERE Category.Id IN (SELECT ECInstanceId from BisCore.SpatialCategory)";
|
|
53
|
-
const selectUsedDrawingCategoryIds = "SELECT DISTINCT Category.Id as id from BisCore.GeometricElement2d WHERE Model.Id=? AND Category.Id IN (SELECT ECInstanceId from BisCore.DrawingCategory)";
|
|
54
|
-
const ecsql = vp.view.is3d() ? selectUsedSpatialCategoryIds : selectUsedDrawingCategoryIds;
|
|
55
|
-
const ecsql2 = `SELECT ECInstanceId as id FROM ${vp.view.is3d() ? "BisCore.SpatialCategory" : "BisCore.DrawingCategory"} WHERE ECInstanceId IN (${ecsql})`;
|
|
56
|
-
const categories = [];
|
|
57
|
-
const rows = await vp.iModel.createQueryReader(ecsql2, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames }).toArray();
|
|
58
|
-
(await vp.iModel.categories.getCategoryInfo(rows.map((row) => row.id))).forEach((val) => {
|
|
59
|
-
categories.push({ categoryId: val.id, subCategoryIds: val.subCategories.size ? [...val.subCategories.keys()] : undefined });
|
|
60
|
-
});
|
|
61
|
-
return categories;
|
|
62
|
-
}
|
|
5
|
+
import { enableCategoryDisplay, enableSubCategoryDisplay } from "./internal/VisibilityUtils.js";
|
|
63
6
|
/**
|
|
64
7
|
* Enable display of all given categories.
|
|
65
8
|
* @public
|
|
@@ -79,10 +22,10 @@ export async function hideAllCategories(categories, viewport) {
|
|
|
79
22
|
* @public
|
|
80
23
|
*/
|
|
81
24
|
export async function invertAllCategories(categories, viewport) {
|
|
82
|
-
const enabled =
|
|
83
|
-
const disabled =
|
|
84
|
-
const enabledSubCategories =
|
|
85
|
-
const disabledSubCategories =
|
|
25
|
+
const enabled = new Array();
|
|
26
|
+
const disabled = new Array();
|
|
27
|
+
const enabledSubCategories = new Array();
|
|
28
|
+
const disabledSubCategories = new Array();
|
|
86
29
|
for (const category of categories) {
|
|
87
30
|
if (!viewport.view.viewsCategory(category.categoryId)) {
|
|
88
31
|
disabled.push(category.categoryId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CategoriesVisibilityUtils.js","sourceRoot":"","sources":["../../../../../../src/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"CategoriesVisibilityUtils.js","sourceRoot":"","sources":["../../../../../../src/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAchG;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,UAAqB,EAAE,QAAkB;IAC/E,MAAM,qBAAqB,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,UAAqB,EAAE,QAAkB;IAC/E,MAAM,qBAAqB,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;AACjE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,UAA0B,EAAE,QAAkB;IACtF,MAAM,OAAO,GAAG,IAAI,KAAK,EAAc,CAAC;IACxC,MAAM,QAAQ,GAAG,IAAI,KAAK,EAAc,CAAC;IACzC,MAAM,oBAAoB,GAAG,IAAI,KAAK,EAAc,CAAC;IACrD,MAAM,qBAAqB,GAAG,IAAI,KAAK,EAAc,CAAC;IAEtD,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE;QACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE;YACrD,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACnC,SAAS;SACV;QACD,iJAAiJ;QACjJ,IAAI,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,EAAE;YAC/F,KAAK,MAAM,WAAW,IAAI,QAAQ,CAAC,cAAc,EAAE;gBACjD,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;aAC/H;SACF;aAAM;YACL,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;SACnC;KACF;IAED,kBAAkB;IAClB,oBAAoB,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,wBAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;IAEtG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAE5D,kBAAkB;IAClB,qBAAqB,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,wBAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;IAEtG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC9D,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 { enableCategoryDisplay, enableSubCategoryDisplay } from \"./internal/VisibilityUtils.js\";\n\nimport type { Id64Array, Id64String } from \"@itwin/core-bentley\";\nimport type { Viewport } from \"@itwin/core-frontend\";\n\n/**\n * Data structure that describes category.\n * @beta\n */\nexport interface CategoryInfo {\n categoryId: Id64String;\n subCategoryIds?: Id64Array;\n}\n\n/**\n * Enable display of all given categories.\n * @public\n */\nexport async function showAllCategories(categories: Id64Array, viewport: Viewport) {\n await enableCategoryDisplay(viewport, categories, true, true);\n}\n\n/**\n * Disable display of all given categories.\n * @public\n */\nexport async function hideAllCategories(categories: Id64Array, viewport: Viewport) {\n await enableCategoryDisplay(viewport, categories, false, true);\n}\n\n/**\n * Invert display of all given categories.\n * @public\n */\nexport async function invertAllCategories(categories: CategoryInfo[], viewport: Viewport) {\n const enabled = new Array<Id64String>();\n const disabled = new Array<Id64String>();\n const enabledSubCategories = new Array<Id64String>();\n const disabledSubCategories = new Array<Id64String>();\n\n for (const category of categories) {\n if (!viewport.view.viewsCategory(category.categoryId)) {\n disabled.push(category.categoryId);\n continue;\n }\n // First, we need to check if at least one subcategory is disabled. If it is true, then only subcategories should change display, not categories.\n if (category.subCategoryIds?.some((subCategory) => !viewport.isSubCategoryVisible(subCategory))) {\n for (const subCategory of category.subCategoryIds) {\n viewport.isSubCategoryVisible(subCategory) ? enabledSubCategories.push(subCategory) : disabledSubCategories.push(subCategory);\n }\n } else {\n enabled.push(category.categoryId);\n }\n }\n\n // Disable enabled\n enabledSubCategories.forEach((subCategory) => enableSubCategoryDisplay(viewport, subCategory, false));\n\n await enableCategoryDisplay(viewport, enabled, false, true);\n\n // Enable disabled\n disabledSubCategories.forEach((subCategory) => enableSubCategoryDisplay(viewport, subCategory, true));\n\n await enableCategoryDisplay(viewport, disabled, true, true);\n}\n"]}
|
|
@@ -11,8 +11,6 @@ export interface VisibilityStatus {
|
|
|
11
11
|
state: "visible" | "partial" | "hidden";
|
|
12
12
|
/** Specifies whether visibility changing is disabled or not. */
|
|
13
13
|
isDisabled?: boolean;
|
|
14
|
-
/** Tooltip that should be displayed when hovering over the visibility checkbox. */
|
|
15
|
-
tooltip?: string;
|
|
16
14
|
}
|
|
17
15
|
/**
|
|
18
16
|
* Handler that can be used to determine and change visibility of instances represented by tree nodes.
|
|
@@ -29,6 +27,7 @@ export interface HierarchyVisibilityHandler extends IDisposable {
|
|
|
29
27
|
interface UseHierarchyVisibilityProps {
|
|
30
28
|
visibilityHandlerFactory: () => HierarchyVisibilityHandler;
|
|
31
29
|
}
|
|
30
|
+
/** @internal */
|
|
32
31
|
export declare function useHierarchyVisibility({ visibilityHandlerFactory, }: UseHierarchyVisibilityProps): TreeItemVisibilityButtonProps & {
|
|
33
32
|
triggerRefresh: () => void;
|
|
34
33
|
};
|
|
@@ -50,6 +49,7 @@ export type HierarchyVisibilityHandlerOverridableMethodProps<TFunc> = TFunc exte
|
|
|
50
49
|
* @beta
|
|
51
50
|
*/
|
|
52
51
|
export type HierarchyVisibilityHandlerOverridableMethod<TFunc> = TFunc extends (...args: any[]) => infer TResult ? (props: HierarchyVisibilityHandlerOverridableMethodProps<TFunc>) => TResult : never;
|
|
52
|
+
/** @internal */
|
|
53
53
|
export declare function createVisibilityHandlerResult<TResult, TOverrideProps>(handler: HierarchyVisibilityHandler, props: TOverrideProps, obs: Observable<TResult>, override: HierarchyVisibilityHandlerOverridableMethod<(props: TOverrideProps) => Promise<TResult>> | undefined): Observable<TResult>;
|
|
54
54
|
export {};
|
|
55
55
|
//# sourceMappingURL=UseHierarchyVisibility.d.ts.map
|
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import { useEffect, useRef, useState } from "react";
|
|
6
6
|
import { asyncScheduler, defer, distinct, EMPTY, from, lastValueFrom, mergeMap, observeOn, onErrorResumeNextWith, Subject, takeUntil, tap, throttleTime, } from "rxjs";
|
|
7
|
+
import { createTooltip } from "./internal/Tooltip.js";
|
|
7
8
|
import { useTelemetryContext } from "./UseTelemetryContext.js";
|
|
9
|
+
/** @internal */
|
|
8
10
|
export function useHierarchyVisibility({ visibilityHandlerFactory, }) {
|
|
9
11
|
const visibilityStatusMap = useRef(new Map());
|
|
10
12
|
const [state, setState] = useState({
|
|
11
|
-
getVisibilityButtonState: () => ({ state: "
|
|
13
|
+
getVisibilityButtonState: () => ({ state: "visible", isDisabled: true }),
|
|
12
14
|
onVisibilityButtonClick: () => { },
|
|
13
15
|
triggerRefresh: () => { },
|
|
14
16
|
});
|
|
@@ -30,7 +32,7 @@ export function useHierarchyVisibility({ visibilityHandlerFactory, }) {
|
|
|
30
32
|
const triggerCheckboxUpdate = () => {
|
|
31
33
|
setState((prev) => ({
|
|
32
34
|
...prev,
|
|
33
|
-
|
|
35
|
+
getVisibilityButtonState: createStateGetter(visibilityStatusMap, calculateNodeStatus),
|
|
34
36
|
}));
|
|
35
37
|
};
|
|
36
38
|
const subscription = calculate
|
|
@@ -38,7 +40,10 @@ export function useHierarchyVisibility({ visibilityHandlerFactory, }) {
|
|
|
38
40
|
next: (status) => {
|
|
39
41
|
visibilityStatusMap.current.set(node.id, {
|
|
40
42
|
node,
|
|
41
|
-
status
|
|
43
|
+
status: {
|
|
44
|
+
...status,
|
|
45
|
+
tooltip: createTooltip(status.state),
|
|
46
|
+
},
|
|
42
47
|
needsRefresh: false,
|
|
43
48
|
});
|
|
44
49
|
},
|
|
@@ -58,7 +63,7 @@ export function useHierarchyVisibility({ visibilityHandlerFactory, }) {
|
|
|
58
63
|
return;
|
|
59
64
|
}
|
|
60
65
|
entry.status.state = visibilityState;
|
|
61
|
-
entry.status.tooltip =
|
|
66
|
+
entry.status.tooltip = createTooltip("determining");
|
|
62
67
|
triggerCheckboxUpdate();
|
|
63
68
|
};
|
|
64
69
|
setState({
|
|
@@ -86,7 +91,7 @@ function createStateGetter(map, calculateVisibility) {
|
|
|
86
91
|
const entry = map.current.get(node.id);
|
|
87
92
|
if (entry === undefined) {
|
|
88
93
|
calculateVisibility(node);
|
|
89
|
-
return { state: "
|
|
94
|
+
return { state: "visible", isDisabled: true, tooltip: createTooltip("determining") };
|
|
90
95
|
}
|
|
91
96
|
if (entry.needsRefresh) {
|
|
92
97
|
calculateVisibility(node);
|
|
@@ -99,6 +104,7 @@ function createStateGetter(map, calculateVisibility) {
|
|
|
99
104
|
};
|
|
100
105
|
};
|
|
101
106
|
}
|
|
107
|
+
/** @internal */
|
|
102
108
|
export function createVisibilityHandlerResult(handler, props, obs, override) {
|
|
103
109
|
return override
|
|
104
110
|
? from(override({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UseHierarchyVisibility.js","sourceRoot":"","sources":["../../../../../../src/tree-widget-react/components/trees/common/UseHierarchyVisibility.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 { useEffect, useRef, useState } from \"react\";\nimport {\n asyncScheduler,\n defer,\n distinct,\n EMPTY,\n from,\n lastValueFrom,\n mergeMap,\n observeOn,\n onErrorResumeNextWith,\n Subject,\n takeUntil,\n tap,\n throttleTime,\n} from \"rxjs\";\nimport { useTelemetryContext } from \"./UseTelemetryContext.js\";\n\nimport type { Observable } from \"rxjs\";\nimport type { MutableRefObject } from \"react\";\nimport type { BeEvent, IDisposable } from \"@itwin/core-bentley\";\nimport type { HierarchyNode, PresentationHierarchyNode } from \"@itwin/presentation-hierarchies-react\";\nimport type { TreeItemVisibilityButtonProps } from \"./components/TreeNodeVisibilityButton.js\";\n\n/**\n * Data structure that describes instance visibility status.\n * @beta\n */\nexport interface VisibilityStatus {\n /** Instance visibility state. */\n state: \"visible\" | \"partial\" | \"hidden\";\n /** Specifies whether visibility changing is disabled or not. */\n isDisabled?: boolean;\n /** Tooltip that should be displayed when hovering over the visibility checkbox. */\n tooltip?: string;\n}\n\n/**\n * Handler that can be used to determine and change visibility of instances represented by tree nodes.\n * @beta\n */\nexport interface HierarchyVisibilityHandler extends IDisposable {\n /** Event used to notify tree about visibility changes from outside. */\n readonly onVisibilityChange: BeEvent<() => void>;\n /** Returns current visibility status for tree node. */\n getVisibilityStatus(node: HierarchyNode): Promise<VisibilityStatus> | VisibilityStatus;\n /** Changes visibility of the instance represented by tree node. */\n changeVisibility(node: HierarchyNode, on: boolean): Promise<void>;\n}\n\ninterface UseHierarchyVisibilityProps {\n visibilityHandlerFactory: () => HierarchyVisibilityHandler;\n}\n\nexport function useHierarchyVisibility({\n visibilityHandlerFactory,\n}: UseHierarchyVisibilityProps): TreeItemVisibilityButtonProps & { triggerRefresh: () => void } {\n const visibilityStatusMap = useRef(new Map<string, { node: PresentationHierarchyNode; status: VisibilityStatus; needsRefresh: boolean }>());\n const [state, setState] = useState<TreeItemVisibilityButtonProps & { triggerRefresh: () => void }>({\n getVisibilityButtonState: () => ({ state: \"hidden\", isDisabled: true }),\n onVisibilityButtonClick: () => {},\n triggerRefresh: () => {},\n });\n const { onFeatureUsed } = useTelemetryContext();\n\n useEffect(() => {\n visibilityStatusMap.current.clear();\n const handler = visibilityHandlerFactory();\n\n const visibilityChanged = new Subject<void>();\n const calculate = new Subject<PresentationHierarchyNode>();\n const calculateNodeStatus = (node: PresentationHierarchyNode) => {\n calculate.next(node);\n };\n\n const resetCache = () => {\n visibilityStatusMap.current.forEach((value) => {\n value.needsRefresh = true;\n });\n visibilityChanged.next();\n };\n\n const triggerCheckboxUpdate = () => {\n setState((prev) => ({\n ...prev,\n getCheckboxState: createStateGetter(visibilityStatusMap, calculateNodeStatus),\n }));\n };\n\n const subscription = calculate\n .pipe(\n distinct(undefined, visibilityChanged),\n observeOn(asyncScheduler),\n mergeMap((node) =>\n defer(async () => handler.getVisibilityStatus(node.nodeData)).pipe(\n tap({\n next: (status) => {\n visibilityStatusMap.current.set(node.id, {\n node,\n status,\n needsRefresh: false,\n });\n },\n }),\n takeUntil(visibilityChanged),\n onErrorResumeNextWith(EMPTY),\n ),\n ),\n throttleTime(100, undefined, { leading: false, trailing: true }),\n )\n .subscribe({\n next: () => {\n triggerCheckboxUpdate();\n },\n });\n\n const changeVisibility: TreeItemVisibilityButtonProps[\"onVisibilityButtonClick\"] = (node, visibilityState) => {\n onFeatureUsed({ featureId: \"visibility-change\", reportInteraction: true });\n // visible should become hidden, partial and hidden should become visible TODO: redo for clarity\n const on = visibilityState === \"visible\" ? false : true;\n void handler.changeVisibility(node.nodeData, on);\n const entry = visibilityStatusMap.current.get(node.id);\n if (!entry) {\n return;\n }\n entry.status.state = visibilityState;\n entry.status.tooltip = undefined;\n triggerCheckboxUpdate();\n };\n\n setState({\n onVisibilityButtonClick: changeVisibility,\n getVisibilityButtonState: createStateGetter(visibilityStatusMap, calculateNodeStatus),\n triggerRefresh: () => {\n resetCache();\n triggerCheckboxUpdate();\n },\n });\n\n const removeListener = handler.onVisibilityChange.addListener(() => {\n resetCache();\n triggerCheckboxUpdate();\n });\n\n return () => {\n subscription.unsubscribe();\n removeListener();\n handler.dispose();\n };\n }, [visibilityHandlerFactory, onFeatureUsed]);\n\n return state;\n}\n\nfunction createStateGetter(\n map: MutableRefObject<Map<string, { node: PresentationHierarchyNode; status: VisibilityStatus; needsRefresh: boolean }>>,\n calculateVisibility: (node: PresentationHierarchyNode) => void,\n): TreeItemVisibilityButtonProps[\"getVisibilityButtonState\"] {\n return (node) => {\n const entry = map.current.get(node.id);\n if (entry === undefined) {\n calculateVisibility(node);\n return { state: \"hidden\", isDisabled: true };\n }\n if (entry.needsRefresh) {\n calculateVisibility(node);\n }\n\n const status = entry.status;\n return {\n state: status.state,\n tooltip: status.tooltip,\n isDisabled: status.isDisabled,\n };\n };\n}\n\n/**\n * Properties for an overridden method of a `HierarchyVisibilityHandler` implementation.\n * @beta\n */\nexport type HierarchyVisibilityHandlerOverridableMethodProps<TFunc> = TFunc extends (props: infer TProps) => infer TResult\n ? TProps & {\n /** A callback that produces the value from the original implementation. */\n readonly originalImplementation: () => TResult;\n /**\n * Reference to the hierarchy based handler.\n * @note Calling `getVisibility` or `changeVisibility` of this object invokes the overridden implementation as well.\n */\n readonly handler: HierarchyVisibilityHandler;\n }\n : never;\n\n/**\n * Function type for an overridden method of `HierarchyVisibilityHandler`.\n * @beta\n */\nexport type HierarchyVisibilityHandlerOverridableMethod<TFunc> = TFunc extends (...args: any[]) => infer TResult\n ? (props: HierarchyVisibilityHandlerOverridableMethodProps<TFunc>) => TResult\n : never;\n\nexport function createVisibilityHandlerResult<TResult, TOverrideProps>(\n handler: HierarchyVisibilityHandler,\n props: TOverrideProps,\n obs: Observable<TResult>,\n override: HierarchyVisibilityHandlerOverridableMethod<(props: TOverrideProps) => Promise<TResult>> | undefined,\n): Observable<TResult> {\n return override\n ? from(\n override({\n ...props,\n originalImplementation: async () => lastValueFrom(obs, { defaultValue: undefined as TResult }),\n handler,\n }),\n )\n : obs;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"UseHierarchyVisibility.js","sourceRoot":"","sources":["../../../../../../src/tree-widget-react/components/trees/common/UseHierarchyVisibility.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 { useEffect, useRef, useState } from \"react\";\nimport {\n asyncScheduler,\n defer,\n distinct,\n EMPTY,\n from,\n lastValueFrom,\n mergeMap,\n observeOn,\n onErrorResumeNextWith,\n Subject,\n takeUntil,\n tap,\n throttleTime,\n} from \"rxjs\";\nimport { createTooltip } from \"./internal/Tooltip.js\";\nimport { useTelemetryContext } from \"./UseTelemetryContext.js\";\n\nimport type { Observable } from \"rxjs\";\nimport type { MutableRefObject } from \"react\";\nimport type { BeEvent, IDisposable } from \"@itwin/core-bentley\";\nimport type { HierarchyNode, PresentationHierarchyNode } from \"@itwin/presentation-hierarchies-react\";\nimport type { TreeItemVisibilityButtonProps, TreeItemVisibilityButtonState } from \"./components/TreeNodeVisibilityButton.js\";\n\n/**\n * Data structure that describes instance visibility status.\n * @beta\n */\nexport interface VisibilityStatus {\n /** Instance visibility state. */\n state: \"visible\" | \"partial\" | \"hidden\";\n /** Specifies whether visibility changing is disabled or not. */\n isDisabled?: boolean;\n}\n\n/**\n * Handler that can be used to determine and change visibility of instances represented by tree nodes.\n * @beta\n */\nexport interface HierarchyVisibilityHandler extends IDisposable {\n /** Event used to notify tree about visibility changes from outside. */\n readonly onVisibilityChange: BeEvent<() => void>;\n /** Returns current visibility status for tree node. */\n getVisibilityStatus(node: HierarchyNode): Promise<VisibilityStatus> | VisibilityStatus;\n /** Changes visibility of the instance represented by tree node. */\n changeVisibility(node: HierarchyNode, on: boolean): Promise<void>;\n}\n\ninterface UseHierarchyVisibilityProps {\n visibilityHandlerFactory: () => HierarchyVisibilityHandler;\n}\n\n/** @internal */\nexport function useHierarchyVisibility({\n visibilityHandlerFactory,\n}: UseHierarchyVisibilityProps): TreeItemVisibilityButtonProps & { triggerRefresh: () => void } {\n const visibilityStatusMap = useRef(new Map<string, { node: PresentationHierarchyNode; status: TreeItemVisibilityButtonState; needsRefresh: boolean }>());\n const [state, setState] = useState<TreeItemVisibilityButtonProps & { triggerRefresh: () => void }>({\n getVisibilityButtonState: () => ({ state: \"visible\", isDisabled: true }),\n onVisibilityButtonClick: () => {},\n triggerRefresh: () => {},\n });\n const { onFeatureUsed } = useTelemetryContext();\n\n useEffect(() => {\n visibilityStatusMap.current.clear();\n const handler = visibilityHandlerFactory();\n\n const visibilityChanged = new Subject<void>();\n const calculate = new Subject<PresentationHierarchyNode>();\n const calculateNodeStatus = (node: PresentationHierarchyNode) => {\n calculate.next(node);\n };\n\n const resetCache = () => {\n visibilityStatusMap.current.forEach((value) => {\n value.needsRefresh = true;\n });\n visibilityChanged.next();\n };\n\n const triggerCheckboxUpdate = () => {\n setState((prev) => ({\n ...prev,\n getVisibilityButtonState: createStateGetter(visibilityStatusMap, calculateNodeStatus),\n }));\n };\n\n const subscription = calculate\n .pipe(\n distinct(undefined, visibilityChanged),\n observeOn(asyncScheduler),\n mergeMap((node) =>\n defer(async () => handler.getVisibilityStatus(node.nodeData)).pipe(\n tap({\n next: (status) => {\n visibilityStatusMap.current.set(node.id, {\n node,\n status: {\n ...status,\n tooltip: createTooltip(status.state),\n },\n needsRefresh: false,\n });\n },\n }),\n takeUntil(visibilityChanged),\n onErrorResumeNextWith(EMPTY),\n ),\n ),\n throttleTime(100, undefined, { leading: false, trailing: true }),\n )\n .subscribe({\n next: () => {\n triggerCheckboxUpdate();\n },\n });\n\n const changeVisibility: TreeItemVisibilityButtonProps[\"onVisibilityButtonClick\"] = (node, visibilityState) => {\n onFeatureUsed({ featureId: \"visibility-change\", reportInteraction: true });\n // visible should become hidden, partial and hidden should become visible TODO: redo for clarity\n const on = visibilityState === \"visible\" ? false : true;\n void handler.changeVisibility(node.nodeData, on);\n const entry = visibilityStatusMap.current.get(node.id);\n if (!entry) {\n return;\n }\n entry.status.state = visibilityState;\n entry.status.tooltip = createTooltip(\"determining\");\n triggerCheckboxUpdate();\n };\n\n setState({\n onVisibilityButtonClick: changeVisibility,\n getVisibilityButtonState: createStateGetter(visibilityStatusMap, calculateNodeStatus),\n triggerRefresh: () => {\n resetCache();\n triggerCheckboxUpdate();\n },\n });\n\n const removeListener = handler.onVisibilityChange.addListener(() => {\n resetCache();\n triggerCheckboxUpdate();\n });\n\n return () => {\n subscription.unsubscribe();\n removeListener();\n handler.dispose();\n };\n }, [visibilityHandlerFactory, onFeatureUsed]);\n\n return state;\n}\n\nfunction createStateGetter(\n map: MutableRefObject<Map<string, { node: PresentationHierarchyNode; status: TreeItemVisibilityButtonState; needsRefresh: boolean }>>,\n calculateVisibility: (node: PresentationHierarchyNode) => void,\n): TreeItemVisibilityButtonProps[\"getVisibilityButtonState\"] {\n return (node) => {\n const entry = map.current.get(node.id);\n if (entry === undefined) {\n calculateVisibility(node);\n return { state: \"visible\", isDisabled: true, tooltip: createTooltip(\"determining\") };\n }\n if (entry.needsRefresh) {\n calculateVisibility(node);\n }\n\n const status = entry.status;\n return {\n state: status.state,\n tooltip: status.tooltip,\n isDisabled: status.isDisabled,\n };\n };\n}\n\n/**\n * Properties for an overridden method of a `HierarchyVisibilityHandler` implementation.\n * @beta\n */\nexport type HierarchyVisibilityHandlerOverridableMethodProps<TFunc> = TFunc extends (props: infer TProps) => infer TResult\n ? TProps & {\n /** A callback that produces the value from the original implementation. */\n readonly originalImplementation: () => TResult;\n /**\n * Reference to the hierarchy based handler.\n * @note Calling `getVisibility` or `changeVisibility` of this object invokes the overridden implementation as well.\n */\n readonly handler: HierarchyVisibilityHandler;\n }\n : never;\n\n/**\n * Function type for an overridden method of `HierarchyVisibilityHandler`.\n * @beta\n */\nexport type HierarchyVisibilityHandlerOverridableMethod<TFunc> = TFunc extends (...args: any[]) => infer TResult\n ? (props: HierarchyVisibilityHandlerOverridableMethodProps<TFunc>) => TResult\n : never;\n\n/** @internal */\nexport function createVisibilityHandlerResult<TResult, TOverrideProps>(\n handler: HierarchyVisibilityHandler,\n props: TOverrideProps,\n obs: Observable<TResult>,\n override: HierarchyVisibilityHandlerOverridableMethod<(props: TOverrideProps) => Promise<TResult>> | undefined,\n): Observable<TResult> {\n return override\n ? from(\n override({\n ...props,\n originalImplementation: async () => lastValueFrom(obs, { defaultValue: undefined as TResult }),\n handler,\n }),\n )\n : obs;\n}\n"]}
|
|
@@ -15,6 +15,7 @@ interface UseNodeHighlightingResult {
|
|
|
15
15
|
activeNodeId?: string;
|
|
16
16
|
getLabel: (node: PresentationHierarchyNode) => React.ReactElement;
|
|
17
17
|
}
|
|
18
|
+
/** @internal */
|
|
18
19
|
export declare function useNodeHighlighting({ rootNodes, highlight }: UseNodeHighlightingProps): UseNodeHighlightingResult;
|
|
19
20
|
export {};
|
|
20
21
|
//# sourceMappingURL=UseNodeHighlighting.d.ts.map
|
|
@@ -3,40 +3,42 @@ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
4
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
5
|
*--------------------------------------------------------------------------------------------*/
|
|
6
|
-
import { useCallback, useEffect,
|
|
6
|
+
import { useCallback, useEffect, useState } from "react";
|
|
7
7
|
import { isPresentationHierarchyNode } from "@itwin/presentation-hierarchies-react";
|
|
8
|
-
import { useLatest } from "./Utils.js";
|
|
8
|
+
import { useLatest } from "./internal/Utils.js";
|
|
9
|
+
/** @internal */
|
|
9
10
|
export function useNodeHighlighting({ rootNodes, highlight }) {
|
|
10
|
-
const state =
|
|
11
|
+
const [state, setState] = useState({ nodeInfoMap: new Map(), totalMatches: 0 });
|
|
11
12
|
const [activeNodeId, setActiveNodeId] = useState();
|
|
12
13
|
const activeMatchIndexRef = useLatest(highlight?.activeMatchIndex);
|
|
13
14
|
const activeNodeIdRef = useLatest(activeNodeId);
|
|
14
15
|
const onHighlightChangedRef = useLatest(highlight?.onHighlightChanged);
|
|
16
|
+
const prevStateRef = useLatest(state);
|
|
15
17
|
const searchText = highlight?.text;
|
|
16
18
|
useEffect(() => {
|
|
17
19
|
const { state: newState, activeIndex } = rootNodes && searchText
|
|
18
|
-
? computeHighlightState(rootNodes, searchText,
|
|
20
|
+
? computeHighlightState(rootNodes, searchText, prevStateRef.current, activeNodeIdRef.current, activeMatchIndexRef.current)
|
|
19
21
|
: { state: { nodeInfoMap: new Map(), totalMatches: 0 }, activeIndex: 0 };
|
|
20
|
-
|
|
22
|
+
setState(newState);
|
|
21
23
|
if (newState.totalMatches === 0) {
|
|
22
24
|
setActiveNodeId(undefined);
|
|
23
25
|
}
|
|
24
26
|
onHighlightChangedRef.current?.(newState.totalMatches === 0 ? 0 : activeIndex, newState.totalMatches);
|
|
25
|
-
}, [rootNodes, searchText, activeNodeIdRef, activeMatchIndexRef, onHighlightChangedRef]);
|
|
27
|
+
}, [rootNodes, searchText, activeNodeIdRef, activeMatchIndexRef, onHighlightChangedRef, prevStateRef]);
|
|
26
28
|
useEffect(() => {
|
|
27
|
-
for (const nodeId of state.
|
|
28
|
-
if (getNodeChunkInfo(state
|
|
29
|
+
for (const nodeId of state.nodeInfoMap.keys()) {
|
|
30
|
+
if (getNodeChunkInfo(state, nodeId, highlight?.activeMatchIndex)?.activeChunkIndex !== undefined) {
|
|
29
31
|
setActiveNodeId(nodeId);
|
|
30
32
|
}
|
|
31
33
|
}
|
|
32
|
-
}, [highlight?.activeMatchIndex]);
|
|
34
|
+
}, [state, highlight?.activeMatchIndex]);
|
|
33
35
|
const getLabel = useCallback((node) => {
|
|
34
|
-
const chunkInfo = getNodeChunkInfo(state
|
|
36
|
+
const chunkInfo = getNodeChunkInfo(state, node.id, highlight?.activeMatchIndex);
|
|
35
37
|
if (searchText && chunkInfo) {
|
|
36
38
|
return _jsx(_Fragment, { children: markChunks(node.label, chunkInfo.chunks, chunkInfo.activeChunkIndex) });
|
|
37
39
|
}
|
|
38
40
|
return _jsx("span", { children: node.label });
|
|
39
|
-
}, [searchText, highlight?.activeMatchIndex]);
|
|
41
|
+
}, [state, searchText, highlight?.activeMatchIndex]);
|
|
40
42
|
return { activeNodeId, getLabel };
|
|
41
43
|
}
|
|
42
44
|
function getNodeChunkInfo(state, nodeId, activeIndex) {
|