@itwin/tree-widget-react 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/CHANGELOG.md +12 -4
  2. package/README.md +59 -0
  3. package/lib/cjs/components/SelectableTree.d.ts +2 -0
  4. package/lib/cjs/components/SelectableTree.js +1 -1
  5. package/lib/cjs/components/SelectableTree.js.map +1 -1
  6. package/lib/cjs/components/TreeSelector.d.ts +1 -0
  7. package/lib/cjs/components/TreeSelector.js +4 -1
  8. package/lib/cjs/components/TreeSelector.js.map +1 -1
  9. package/lib/cjs/components/TreeWidgetUiItemsProvider.d.ts +2 -0
  10. package/lib/cjs/components/TreeWidgetUiItemsProvider.js +1 -1
  11. package/lib/cjs/components/TreeWidgetUiItemsProvider.js.map +1 -1
  12. package/lib/cjs/components/tree-header/TreeHeader.d.ts +1 -0
  13. package/lib/cjs/components/tree-header/TreeHeader.js.map +1 -1
  14. package/lib/cjs/components/trees/VisibilityTreeRenderer.d.ts +11 -3
  15. package/lib/cjs/components/trees/VisibilityTreeRenderer.js +8 -5
  16. package/lib/cjs/components/trees/VisibilityTreeRenderer.js.map +1 -1
  17. package/lib/cjs/components/trees/category-tree/CategoriesTree.d.ts +6 -0
  18. package/lib/cjs/components/trees/category-tree/CategoriesTree.js +10 -5
  19. package/lib/cjs/components/trees/category-tree/CategoriesTree.js.map +1 -1
  20. package/lib/cjs/components/trees/category-tree/CategoriesTreeComponent.js +17 -8
  21. package/lib/cjs/components/trees/category-tree/CategoriesTreeComponent.js.map +1 -1
  22. package/lib/cjs/components/trees/common/ReportingTreeEventHandler.d.ts +27 -0
  23. package/lib/cjs/components/trees/common/ReportingTreeEventHandler.js +51 -0
  24. package/lib/cjs/components/trees/common/ReportingTreeEventHandler.js.map +1 -0
  25. package/lib/cjs/components/trees/common/TreeRenderer.d.ts +17 -2
  26. package/lib/cjs/components/trees/common/TreeRenderer.js +19 -3
  27. package/lib/cjs/components/trees/common/TreeRenderer.js.map +1 -1
  28. package/lib/cjs/components/trees/common/TreeRenderer.scss +1 -1
  29. package/lib/cjs/components/trees/common/UseFeatureReporting.d.ts +23 -0
  30. package/lib/cjs/components/trees/common/UseFeatureReporting.js +30 -0
  31. package/lib/cjs/components/trees/common/UseFeatureReporting.js.map +1 -0
  32. package/lib/cjs/components/trees/common/UseVisibilityTreeState.d.ts +8 -1
  33. package/lib/cjs/components/trees/common/UseVisibilityTreeState.js +5 -3
  34. package/lib/cjs/components/trees/common/UseVisibilityTreeState.js.map +1 -1
  35. package/lib/cjs/components/trees/external-sources-tree/ExternalSourcesTree.d.ts +6 -0
  36. package/lib/cjs/components/trees/external-sources-tree/ExternalSourcesTree.js +16 -7
  37. package/lib/cjs/components/trees/external-sources-tree/ExternalSourcesTree.js.map +1 -1
  38. package/lib/cjs/components/trees/imodel-content-tree/IModelContentTree.d.ts +6 -0
  39. package/lib/cjs/components/trees/imodel-content-tree/IModelContentTree.js +17 -3
  40. package/lib/cjs/components/trees/imodel-content-tree/IModelContentTree.js.map +1 -1
  41. package/lib/cjs/components/trees/models-tree/ModelsTree.d.ts +6 -0
  42. package/lib/cjs/components/trees/models-tree/ModelsTree.js +19 -12
  43. package/lib/cjs/components/trees/models-tree/ModelsTree.js.map +1 -1
  44. package/lib/cjs/components/trees/models-tree/ModelsTreeComponent.js +26 -11
  45. package/lib/cjs/components/trees/models-tree/ModelsTreeComponent.js.map +1 -1
  46. package/lib/cjs/components/trees/models-tree/ModelsTreeEventHandler.d.ts +10 -0
  47. package/lib/cjs/components/trees/models-tree/ModelsTreeEventHandler.js +5 -0
  48. package/lib/cjs/components/trees/models-tree/ModelsTreeEventHandler.js.map +1 -1
  49. package/lib/esm/components/SelectableTree.d.ts +2 -0
  50. package/lib/esm/components/SelectableTree.js +1 -1
  51. package/lib/esm/components/SelectableTree.js.map +1 -1
  52. package/lib/esm/components/TreeSelector.d.ts +1 -0
  53. package/lib/esm/components/TreeSelector.js +4 -1
  54. package/lib/esm/components/TreeSelector.js.map +1 -1
  55. package/lib/esm/components/TreeWidgetUiItemsProvider.d.ts +2 -0
  56. package/lib/esm/components/TreeWidgetUiItemsProvider.js +1 -1
  57. package/lib/esm/components/TreeWidgetUiItemsProvider.js.map +1 -1
  58. package/lib/esm/components/tree-header/TreeHeader.d.ts +1 -0
  59. package/lib/esm/components/tree-header/TreeHeader.js.map +1 -1
  60. package/lib/esm/components/trees/VisibilityTreeRenderer.d.ts +11 -3
  61. package/lib/esm/components/trees/VisibilityTreeRenderer.js +8 -5
  62. package/lib/esm/components/trees/VisibilityTreeRenderer.js.map +1 -1
  63. package/lib/esm/components/trees/category-tree/CategoriesTree.d.ts +6 -0
  64. package/lib/esm/components/trees/category-tree/CategoriesTree.js +10 -5
  65. package/lib/esm/components/trees/category-tree/CategoriesTree.js.map +1 -1
  66. package/lib/esm/components/trees/category-tree/CategoriesTreeComponent.js +17 -8
  67. package/lib/esm/components/trees/category-tree/CategoriesTreeComponent.js.map +1 -1
  68. package/lib/esm/components/trees/common/ReportingTreeEventHandler.d.ts +27 -0
  69. package/lib/esm/components/trees/common/ReportingTreeEventHandler.js +47 -0
  70. package/lib/esm/components/trees/common/ReportingTreeEventHandler.js.map +1 -0
  71. package/lib/esm/components/trees/common/TreeRenderer.d.ts +17 -2
  72. package/lib/esm/components/trees/common/TreeRenderer.js +19 -3
  73. package/lib/esm/components/trees/common/TreeRenderer.js.map +1 -1
  74. package/lib/esm/components/trees/common/TreeRenderer.scss +1 -1
  75. package/lib/esm/components/trees/common/UseFeatureReporting.d.ts +23 -0
  76. package/lib/esm/components/trees/common/UseFeatureReporting.js +26 -0
  77. package/lib/esm/components/trees/common/UseFeatureReporting.js.map +1 -0
  78. package/lib/esm/components/trees/common/UseVisibilityTreeState.d.ts +8 -1
  79. package/lib/esm/components/trees/common/UseVisibilityTreeState.js +5 -3
  80. package/lib/esm/components/trees/common/UseVisibilityTreeState.js.map +1 -1
  81. package/lib/esm/components/trees/external-sources-tree/ExternalSourcesTree.d.ts +6 -0
  82. package/lib/esm/components/trees/external-sources-tree/ExternalSourcesTree.js +17 -8
  83. package/lib/esm/components/trees/external-sources-tree/ExternalSourcesTree.js.map +1 -1
  84. package/lib/esm/components/trees/imodel-content-tree/IModelContentTree.d.ts +6 -0
  85. package/lib/esm/components/trees/imodel-content-tree/IModelContentTree.js +18 -4
  86. package/lib/esm/components/trees/imodel-content-tree/IModelContentTree.js.map +1 -1
  87. package/lib/esm/components/trees/models-tree/ModelsTree.d.ts +6 -0
  88. package/lib/esm/components/trees/models-tree/ModelsTree.js +19 -12
  89. package/lib/esm/components/trees/models-tree/ModelsTree.js.map +1 -1
  90. package/lib/esm/components/trees/models-tree/ModelsTreeComponent.js +26 -11
  91. package/lib/esm/components/trees/models-tree/ModelsTreeComponent.js.map +1 -1
  92. package/lib/esm/components/trees/models-tree/ModelsTreeEventHandler.d.ts +10 -0
  93. package/lib/esm/components/trees/models-tree/ModelsTreeEventHandler.js +5 -0
  94. package/lib/esm/components/trees/models-tree/ModelsTreeEventHandler.js.map +1 -1
  95. package/package.json +20 -20
@@ -1 +1 @@
1
- {"version":3,"file":"CategoriesTree.js","sourceRoot":"","sources":["../../../../../src/components/trees/category-tree/CategoriesTree.tsx"],"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 \"../VisibilityTreeBase.scss\";\nimport classNames from \"classnames\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { SelectionMode } from \"@itwin/components-react\";\nimport { IModelApp } from \"@itwin/core-frontend\";\nimport { PresentationTree } from \"@itwin/presentation-components\";\nimport { Presentation } from \"@itwin/presentation-frontend\";\nimport { TreeWidget } from \"../../../TreeWidget\";\nimport { FilterableTreeRenderer } from \"../common/TreeRenderer\";\nimport { usePerformanceReporting } from \"../common/UsePerformanceReporting\";\nimport { useVisibilityTreeState } from \"../common/UseVisibilityTreeState\";\nimport { addCustomTreeNodeItemLabelRenderer, combineTreeNodeItemCustomizations } from \"../common/Utils\";\nimport { createVisibilityTreeRenderer, FilterableVisibilityTreeNodeRenderer, VisibilityTreeNoFilteredData } from \"../VisibilityTreeRenderer\";\nimport { CategoriesTreeComponent } from \"./CategoriesTreeComponent\";\nimport { CategoryVisibilityHandler } from \"./CategoryVisibilityHandler\";\n\nimport type { IModelConnection, SpatialViewState, ViewManager, Viewport } from \"@itwin/core-frontend\";\nimport type { Ruleset } from \"@itwin/presentation-common\";\nimport type { IFilteredPresentationTreeDataProvider, PresentationTreeNodeRendererProps } from \"@itwin/presentation-components\";\nimport type { BaseFilterableTreeProps, HierarchyLevelConfig } from \"../common/Types\";\nimport type { CategoryInfo } from \"./CategoryVisibilityHandler\";\nconst PAGING_SIZE = 20;\n\n/**\n * Presentation rules used by ControlledCategoriesTree\n * @internal\n */\nexport const RULESET_CATEGORIES: Ruleset = require(\"./Categories.json\"); // eslint-disable-line @typescript-eslint/no-var-requires\n\n/**\n * Properties for the [[CategoryTree]] component\n * @public\n */\nexport interface CategoryTreeProps extends BaseFilterableTreeProps {\n /** Flag for accommodating all viewports */\n allViewports?: boolean;\n /** Active viewport */\n activeView: Viewport;\n /**\n * Available iModel categories\n */\n categories: CategoryInfo[];\n /**\n * Custom category visibility handler to use for testing\n * @internal\n */\n categoryVisibilityHandler?: CategoryVisibilityHandler;\n /**\n * Custom view manager to use for testing\n * @internal\n */\n viewManager?: ViewManager;\n /**\n * Props for configuring hierarchy level.\n * @beta\n */\n hierarchyLevelConfig?: HierarchyLevelConfig;\n /**\n * Callback that is invoked when performance of tracked feature is measured.\n * @param featureId ID of the feature.\n * @param elapsedTime Elapsed time of the feature.\n * @beta\n */\n onPerformanceMeasured?: (featureId: string, elapsedTime: number) => void;\n}\n\n/**\n * Tree which displays and manages display of categories contained in an iModel.\n * @public\n */\nexport function CategoryTree(props: CategoryTreeProps) {\n // istanbul ignore next\n const viewManager = props.viewManager ?? IModelApp.viewManager;\n const { activeView, allViewports, categoryVisibilityHandler, onFilterApplied, density, hierarchyLevelConfig } = props;\n\n const visibilityHandler = useCategoryVisibilityHandler(viewManager, props.iModel, props.categories, activeView, allViewports, categoryVisibilityHandler);\n const onFilterChange = useCallback(\n (dataProvider?: IFilteredPresentationTreeDataProvider, matchesCount?: number) => {\n if (onFilterApplied && dataProvider && matchesCount !== undefined) {\n onFilterApplied(dataProvider, matchesCount);\n }\n },\n [onFilterApplied],\n );\n const reporting = usePerformanceReporting({\n treeIdentifier: CategoriesTreeComponent.id,\n onPerformanceMeasured: props.onPerformanceMeasured,\n });\n const state = useVisibilityTreeState({\n imodel: props.iModel,\n ruleset: RULESET_CATEGORIES,\n pagingSize: PAGING_SIZE,\n visibilityHandler,\n customizeTreeNodeItem,\n filterInfo: props.filterInfo,\n onFilterChange,\n hierarchyLevelSizeLimit: hierarchyLevelConfig?.sizeLimit,\n enableHierarchyAutoUpdate: true,\n onNodeLoaded: reporting.onNodeLoaded,\n });\n\n useEffect(() => {\n setViewType(activeView); // eslint-disable-line @typescript-eslint/no-floating-promises\n }, [activeView]);\n\n const baseRendererProps = {\n contextMenuItems: props.contextMenuItems,\n nodeLabelRenderer: props.nodeLabelRenderer,\n density: props.density,\n nodeRendererProps: {\n iconsEnabled: false,\n descriptionEnabled: true,\n levelOffset: 10,\n },\n };\n\n const noFilteredDataRenderer = useCallback(() => {\n return (\n <VisibilityTreeNoFilteredData\n title={TreeWidget.translate(\"categoriesTree.noCategoryFound\")}\n message={TreeWidget.translate(\"categoriesTree.noMatchingCategoryNames\")}\n />\n );\n }, []);\n\n if (!state) {\n return null;\n }\n\n const isFilterApplied = state.filteringResult?.filteredProvider !== undefined;\n const overlay = state.filteringResult?.isFiltering ? <div className=\"filteredTreeOverlay\" /> : undefined;\n return (\n <div className={classNames(\"tree-widget-visibility-tree-base\", \"tree-widget-tree-container\")}>\n <PresentationTree\n width={props.width}\n height={props.height}\n state={state}\n selectionMode={props.selectionMode ?? SelectionMode.None}\n treeRenderer={\n hierarchyLevelConfig?.isFilteringEnabled\n ? (rendererProps) => (\n <FilterableTreeRenderer\n {...rendererProps}\n {...baseRendererProps}\n nodeLoader={state.nodeLoader}\n nodeRenderer={(nodeProps) => <CategoriesTreeNodeRenderer {...nodeProps} density={density} />}\n />\n )\n : createVisibilityTreeRenderer(baseRendererProps)\n }\n descriptionsEnabled={true}\n noDataRenderer={isFilterApplied ? noFilteredDataRenderer : undefined}\n />\n {overlay}\n </div>\n );\n}\n\nfunction CategoriesTreeNodeRenderer(props: PresentationTreeNodeRendererProps & { density?: \"default\" | \"enlarged\" }) {\n return (\n <FilterableVisibilityTreeNodeRenderer\n {...props}\n iconsEnabled={false}\n descriptionEnabled={true}\n levelOffset={10}\n isEnlarged={props.density === \"enlarged\"}\n />\n );\n\n}\n\nfunction useCategoryVisibilityHandler(\n viewManager: ViewManager,\n imodel: IModelConnection,\n categories: CategoryInfo[],\n activeView: Viewport,\n allViewports?: boolean,\n visibilityHandler?: CategoryVisibilityHandler,\n) {\n const [state, setState] = useState<CategoryVisibilityHandler>();\n\n useEffect(() => {\n if (visibilityHandler) {\n return;\n }\n\n const defaultHandler = new CategoryVisibilityHandler({ viewManager, imodel, categories, activeView, allViewports });\n setState(defaultHandler);\n return () => {\n defaultHandler.dispose();\n };\n }, [viewManager, imodel, categories, activeView, allViewports, visibilityHandler]);\n\n return visibilityHandler ?? state;\n}\n\nasync function setViewType(activeView: Viewport) {\n const view = activeView.view as SpatialViewState;\n const viewType = view.is3d() ? \"3d\" : \"2d\";\n await Presentation.presentation.vars(RULESET_CATEGORIES.id).setString(\"ViewType\", viewType);\n}\n\nconst customizeTreeNodeItem = combineTreeNodeItemCustomizations([addCustomTreeNodeItemLabelRenderer]);\n"]}
1
+ {"version":3,"file":"CategoriesTree.js","sourceRoot":"","sources":["../../../../../src/components/trees/category-tree/CategoriesTree.tsx"],"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 \"../VisibilityTreeBase.scss\";\nimport classNames from \"classnames\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { SelectionMode } from \"@itwin/components-react\";\nimport { IModelApp } from \"@itwin/core-frontend\";\nimport { PresentationTree } from \"@itwin/presentation-components\";\nimport { Presentation } from \"@itwin/presentation-frontend\";\nimport { TreeWidget } from \"../../../TreeWidget\";\nimport { FilterableTreeRenderer } from \"../common/TreeRenderer\";\nimport { useFeatureReporting } from \"../common/UseFeatureReporting\";\nimport { usePerformanceReporting } from \"../common/UsePerformanceReporting\";\nimport { useVisibilityTreeState } from \"../common/UseVisibilityTreeState\";\nimport { addCustomTreeNodeItemLabelRenderer, combineTreeNodeItemCustomizations } from \"../common/Utils\";\nimport { createVisibilityTreeRenderer, FilterableVisibilityTreeNodeRenderer, VisibilityTreeNoFilteredData } from \"../VisibilityTreeRenderer\";\nimport { CategoriesTreeComponent } from \"./CategoriesTreeComponent\";\nimport { CategoryVisibilityHandler } from \"./CategoryVisibilityHandler\";\n\nimport type { FilterableTreeNodeRendererProps } from \"../common/TreeRenderer\";\nimport type { IModelConnection, SpatialViewState, ViewManager, Viewport } from \"@itwin/core-frontend\";\nimport type { Ruleset } from \"@itwin/presentation-common\";\nimport type { IFilteredPresentationTreeDataProvider } from \"@itwin/presentation-components\";\nimport type { BaseFilterableTreeProps, HierarchyLevelConfig } from \"../common/Types\";\nimport type { CategoryInfo } from \"./CategoryVisibilityHandler\";\nconst PAGING_SIZE = 20;\n\n/**\n * Presentation rules used by ControlledCategoriesTree\n * @internal\n */\nexport const RULESET_CATEGORIES: Ruleset = require(\"./Categories.json\"); // eslint-disable-line @typescript-eslint/no-var-requires\n\n/**\n * Properties for the [[CategoryTree]] component\n * @public\n */\nexport interface CategoryTreeProps extends BaseFilterableTreeProps {\n /** Flag for accommodating all viewports */\n allViewports?: boolean;\n /** Active viewport */\n activeView: Viewport;\n /**\n * Available iModel categories\n */\n categories: CategoryInfo[];\n /**\n * Custom category visibility handler to use for testing\n * @internal\n */\n categoryVisibilityHandler?: CategoryVisibilityHandler;\n /**\n * Custom view manager to use for testing\n * @internal\n */\n viewManager?: ViewManager;\n /**\n * Props for configuring hierarchy level.\n * @beta\n */\n hierarchyLevelConfig?: HierarchyLevelConfig;\n /**\n * Callback that is invoked when performance of tracked feature is measured.\n * @param featureId ID of the feature.\n * @param elapsedTime Elapsed time of the feature.\n * @beta\n */\n onPerformanceMeasured?: (featureId: string, elapsedTime: number) => void;\n /**\n * Callback that is invoked when a tracked feature is used.\n * @param featureId ID of the feature.\n * @beta\n */\n onFeatureUsed?: (feature: string) => void;\n}\n\n/**\n * Tree which displays and manages display of categories contained in an iModel.\n * @public\n */\nexport function CategoryTree(props: CategoryTreeProps) {\n // istanbul ignore next\n const viewManager = props.viewManager ?? IModelApp.viewManager;\n const { activeView, allViewports, categoryVisibilityHandler, onFilterApplied, density, hierarchyLevelConfig, onPerformanceMeasured, onFeatureUsed } = props;\n\n const visibilityHandler = useCategoryVisibilityHandler(viewManager, props.iModel, props.categories, activeView, allViewports, categoryVisibilityHandler);\n const onFilterChange = useCallback(\n (dataProvider?: IFilteredPresentationTreeDataProvider, matchesCount?: number) => {\n if (onFilterApplied && dataProvider && matchesCount !== undefined) {\n onFilterApplied(dataProvider, matchesCount);\n }\n },\n [onFilterApplied],\n );\n\n const { reportUsage } = useFeatureReporting({ treeIdentifier: CategoriesTreeComponent.id, onFeatureUsed });\n const { onNodeLoaded } = usePerformanceReporting({\n treeIdentifier: CategoriesTreeComponent.id,\n onPerformanceMeasured,\n });\n\n const state = useVisibilityTreeState({\n imodel: props.iModel,\n ruleset: RULESET_CATEGORIES,\n pagingSize: PAGING_SIZE,\n visibilityHandler,\n customizeTreeNodeItem,\n filterInfo: props.filterInfo,\n onFilterChange,\n hierarchyLevelSizeLimit: hierarchyLevelConfig?.sizeLimit,\n enableHierarchyAutoUpdate: true,\n onNodeLoaded,\n reportUsage,\n });\n\n useEffect(() => {\n setViewType(activeView); // eslint-disable-line @typescript-eslint/no-floating-promises\n }, [activeView]);\n\n const baseRendererProps = {\n reportUsage,\n contextMenuItems: props.contextMenuItems,\n nodeLabelRenderer: props.nodeLabelRenderer,\n density: props.density,\n nodeRendererProps: {\n iconsEnabled: false,\n descriptionEnabled: true,\n levelOffset: 10,\n onVisibilityToggled: () => reportUsage({ featureId: \"visibility-change\", reportInteraction: true }),\n },\n };\n\n const noFilteredDataRenderer = useCallback(() => {\n return (\n <VisibilityTreeNoFilteredData\n title={TreeWidget.translate(\"categoriesTree.noCategoryFound\")}\n message={TreeWidget.translate(\"categoriesTree.noMatchingCategoryNames\")}\n />\n );\n }, []);\n\n if (!state) {\n return null;\n }\n\n const isFilterApplied = state.filteringResult?.filteredProvider !== undefined;\n const overlay = state.filteringResult?.isFiltering ? <div className=\"filteredTreeOverlay\" /> : undefined;\n return (\n <div className={classNames(\"tree-widget-visibility-tree-base\", \"tree-widget-tree-container\")}>\n <PresentationTree\n width={props.width}\n height={props.height}\n state={state}\n selectionMode={props.selectionMode ?? SelectionMode.None}\n treeRenderer={\n hierarchyLevelConfig?.isFilteringEnabled\n ? (rendererProps) => (\n <FilterableTreeRenderer\n {...rendererProps}\n {...baseRendererProps}\n nodeLoader={state.nodeLoader}\n nodeRenderer={(nodeProps) => <CategoriesTreeNodeRenderer {...nodeProps} density={density} />}\n />\n )\n : createVisibilityTreeRenderer(baseRendererProps)\n }\n descriptionsEnabled={true}\n noDataRenderer={isFilterApplied ? noFilteredDataRenderer : undefined}\n />\n {overlay}\n </div>\n );\n}\n\ninterface CategoriesTreeNodeRendererProps extends FilterableTreeNodeRendererProps {\n density?: \"default\" | \"enlarged\";\n}\n\nfunction CategoriesTreeNodeRenderer(props: CategoriesTreeNodeRendererProps) {\n return (\n <FilterableVisibilityTreeNodeRenderer\n {...props}\n iconsEnabled={false}\n descriptionEnabled={true}\n levelOffset={10}\n isEnlarged={props.density === \"enlarged\"}\n onVisibilityToggled={() => props.reportUsage?.({ featureId: \"visibility-change\", reportInteraction: true })}\n />\n );\n}\n\nfunction useCategoryVisibilityHandler(\n viewManager: ViewManager,\n imodel: IModelConnection,\n categories: CategoryInfo[],\n activeView: Viewport,\n allViewports?: boolean,\n visibilityHandler?: CategoryVisibilityHandler,\n) {\n const [state, setState] = useState<CategoryVisibilityHandler>();\n\n useEffect(() => {\n if (visibilityHandler) {\n return;\n }\n\n const defaultHandler = new CategoryVisibilityHandler({ viewManager, imodel, categories, activeView, allViewports });\n setState(defaultHandler);\n return () => {\n defaultHandler.dispose();\n };\n }, [viewManager, imodel, categories, activeView, allViewports, visibilityHandler]);\n\n return visibilityHandler ?? state;\n}\n\nasync function setViewType(activeView: Viewport) {\n const view = activeView.view as SpatialViewState;\n const viewType = view.is3d() ? \"3d\" : \"2d\";\n await Presentation.presentation.vars(RULESET_CATEGORIES.id).setString(\"ViewType\", viewType);\n}\n\nconst customizeTreeNodeItem = combineTreeNodeItemCustomizations([addCustomTreeNodeItemLabelRenderer]);\n"]}
@@ -10,6 +10,7 @@ const jsx_runtime_1 = require("react/jsx-runtime");
10
10
  * See LICENSE.md in the project root for license terms and full copyright notice.
11
11
  *--------------------------------------------------------------------------------------------*/
12
12
  require("../VisibilityTreeBase.scss");
13
+ const classnames_1 = __importDefault(require("classnames"));
13
14
  const react_1 = require("react");
14
15
  const appui_react_1 = require("@itwin/appui-react");
15
16
  const core_frontend_1 = require("@itwin/core-frontend");
@@ -22,7 +23,6 @@ const TreeFilteringState_1 = require("../../TreeFilteringState");
22
23
  const AutoSizer_1 = require("../../utils/AutoSizer");
23
24
  const CategoriesTree_1 = require("./CategoriesTree");
24
25
  const CategoryVisibilityHandler_1 = require("./CategoryVisibilityHandler");
25
- const classnames_1 = __importDefault(require("classnames"));
26
26
  /**
27
27
  * A component that renders [[CategoriesTree]] and a header with filtering capabilities
28
28
  * and header buttons.
@@ -78,11 +78,11 @@ function CategoriesTreeComponentImpl(props) {
78
78
  })();
79
79
  }, [filteredProvider]);
80
80
  return ((0, jsx_runtime_1.jsxs)("div", { className: "tree-widget-tree-with-header", children: [(0, jsx_runtime_1.jsx)(TreeHeader_1.TreeHeader, { onFilterClear: searchOptions.onFilterCancel, onFilterStart: searchOptions.onFilterStart, onSelectedChanged: searchOptions.onResultSelectedChanged, resultCount: searchOptions.matchedResultCount, selectedIndex: searchOptions.activeMatchIndex, density: props.density, children: props.headerButtons
81
- ? props.headerButtons.map((btn, index) => (0, jsx_runtime_1.jsx)(react_1.Fragment, { children: btn({ viewport: props.viewport, categories, filteredCategories }) }, index))
81
+ ? props.headerButtons.map((btn, index) => ((0, jsx_runtime_1.jsx)(react_1.Fragment, { children: btn({ viewport: props.viewport, categories, filteredCategories, density: props.density, onFeatureUsed: props.onFeatureUsed }) }, index)))
82
82
  : [
83
- (0, jsx_runtime_1.jsx)(ShowAllButton, { viewport: props.viewport, categories: categories, filteredCategories: filteredCategories, density: props.density }, "show-all-btn"),
84
- (0, jsx_runtime_1.jsx)(HideAllButton, { viewport: props.viewport, categories: categories, filteredCategories: filteredCategories, density: props.density }, "hide-all-btn"),
85
- (0, jsx_runtime_1.jsx)(InvertAllButton, { viewport: props.viewport, categories: categories, filteredCategories: filteredCategories, density: props.density }, "invert-all-btn"),
83
+ (0, jsx_runtime_1.jsx)(ShowAllButton, { viewport: props.viewport, categories: categories, filteredCategories: filteredCategories, density: props.density, onFeatureUsed: props.onFeatureUsed }, "show-all-btn"),
84
+ (0, jsx_runtime_1.jsx)(HideAllButton, { viewport: props.viewport, categories: categories, filteredCategories: filteredCategories, density: props.density, onFeatureUsed: props.onFeatureUsed }, "hide-all-btn"),
85
+ (0, jsx_runtime_1.jsx)(InvertAllButton, { viewport: props.viewport, categories: categories, filteredCategories: filteredCategories, density: props.density, onFeatureUsed: props.onFeatureUsed }, "invert-all-btn"),
86
86
  ] }), (0, jsx_runtime_1.jsx)("div", { className: contentClassName, children: (0, jsx_runtime_1.jsx)(AutoSizer_1.AutoSizer, { children: ({ width, height }) => ((0, jsx_runtime_1.jsx)(CategoriesTree_1.CategoryTree, { ...props, categories: categories, width: width, height: height, filterInfo: { filter: filterString, activeMatchIndex: searchOptions.activeMatchIndex }, onFilterApplied: onFilterApplied, activeView: props.viewport })) }) })] }));
87
87
  }
88
88
  async function getFilteredCategories(filteredProvider) {
@@ -103,12 +103,21 @@ async function getFilteredCategories(filteredProvider) {
103
103
  return filteredCategories;
104
104
  }
105
105
  function ShowAllButton(props) {
106
- return ((0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { size: props.density === "enlarged" ? "large" : "small", styleType: "borderless", title: TreeWidget_1.TreeWidget.translate("showAll"), onClick: () => void (0, CategoryVisibilityHandler_1.showAllCategories)((props.filteredCategories ?? props.categories).map((category) => category.categoryId), props.viewport), children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgVisibilityShow, {}) }));
106
+ return ((0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { size: props.density === "enlarged" ? "large" : "small", styleType: "borderless", title: TreeWidget_1.TreeWidget.translate("showAll"), onClick: () => {
107
+ props.onFeatureUsed?.(`${exports.CategoriesTreeComponent.id}-showall`);
108
+ void (0, CategoryVisibilityHandler_1.showAllCategories)((props.filteredCategories ?? props.categories).map((category) => category.categoryId), props.viewport);
109
+ }, children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgVisibilityShow, {}) }));
107
110
  }
108
111
  function HideAllButton(props) {
109
- return ((0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { size: props.density === "enlarged" ? "large" : "small", styleType: "borderless", title: TreeWidget_1.TreeWidget.translate("hideAll"), onClick: () => void (0, CategoryVisibilityHandler_1.hideAllCategories)((props.filteredCategories ?? props.categories).map((category) => category.categoryId), props.viewport), children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgVisibilityHide, {}) }));
112
+ return ((0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { size: props.density === "enlarged" ? "large" : "small", styleType: "borderless", title: TreeWidget_1.TreeWidget.translate("hideAll"), onClick: () => {
113
+ props.onFeatureUsed?.(`${exports.CategoriesTreeComponent.id}-hideall`);
114
+ void (0, CategoryVisibilityHandler_1.hideAllCategories)((props.filteredCategories ?? props.categories).map((category) => category.categoryId), props.viewport);
115
+ }, children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgVisibilityHide, {}) }));
110
116
  }
111
117
  function InvertAllButton(props) {
112
- return ((0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { title: TreeWidget_1.TreeWidget.translate("invert"), size: props.density === "enlarged" ? "large" : "small", styleType: "borderless", onClick: () => void (0, CategoryVisibilityHandler_1.invertAllCategories)(props.filteredCategories ?? props.categories, props.viewport), children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgVisibilityHalf, {}) }));
118
+ return ((0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { title: TreeWidget_1.TreeWidget.translate("invert"), size: props.density === "enlarged" ? "large" : "small", styleType: "borderless", onClick: () => {
119
+ props.onFeatureUsed?.(`${exports.CategoriesTreeComponent.id}-invert`);
120
+ void (0, CategoryVisibilityHandler_1.invertAllCategories)(props.filteredCategories ?? props.categories, props.viewport);
121
+ }, children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgVisibilityHalf, {}) }));
113
122
  }
114
123
  //# sourceMappingURL=CategoriesTreeComponent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CategoriesTreeComponent.js","sourceRoot":"","sources":["../../../../../src/components/trees/category-tree/CategoriesTreeComponent.tsx"],"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 \"../VisibilityTreeBase.scss\";\nimport { Fragment, useEffect, useState } from \"react\";\nimport { useActiveIModelConnection, useActiveViewport } from \"@itwin/appui-react\";\nimport { IModelApp } from \"@itwin/core-frontend\";\nimport { SvgVisibilityHalf, SvgVisibilityHide, SvgVisibilityShow } from \"@itwin/itwinui-icons-react\";\nimport { IconButton } from \"@itwin/itwinui-react\";\nimport { isPresentationTreeNodeItem } from \"@itwin/presentation-components\";\nimport { TreeWidget } from \"../../../TreeWidget\";\nimport { TreeHeader } from \"../../tree-header/TreeHeader\";\nimport { useTreeFilteringState } from \"../../TreeFilteringState\";\nimport { AutoSizer } from \"../../utils/AutoSizer\";\nimport { CategoryTree } from \"./CategoriesTree\";\nimport { CategoryVisibilityHandler, hideAllCategories, invertAllCategories, showAllCategories, useCategories } from \"./CategoryVisibilityHandler\";\n\nimport type { IModelConnection, ScreenViewport } from \"@itwin/core-frontend\";\nimport type { IPresentationTreeDataProvider } from \"@itwin/presentation-components\";\nimport type { TreeHeaderButtonProps } from \"../../tree-header/TreeHeader\";\nimport type { CategoryTreeProps } from \"./CategoriesTree\";\nimport type { CategoryInfo } from \"./CategoryVisibilityHandler\";\nimport classNames from \"classnames\";\n\n/**\n * Props that get passed to [[CategoriesTreeComponent]] header button renderer.\n * @see CategoriesTreeComponentProps.headerButtons\n * @public\n */\nexport interface CategoriesTreeHeaderButtonProps extends TreeHeaderButtonProps {\n /** A list of categories available in the iModel */\n categories: CategoryInfo[];\n /** In case the tree is filtered, a list of filtered categories. */\n filteredCategories?: CategoryInfo[];\n}\n\n/**\n * Props for [[CategoriesTreeComponent]].\n * @public\n */\nexport interface CategoriesTreeComponentProps\n extends Omit<\n CategoryTreeProps,\n \"iModel\" | \"activeView\" | \"width\" | \"height\" | \"filterInfo\" | \"onFilterApplied\" | \"categories\" | \"categoryVisibilityHandler\" | \"viewManager\"\n > {\n /**\n * Renderers of header buttons. Defaults to:\n * ```ts\n * [\n * CategoriesTreeComponent.ShowAllButton,\n * CategoriesTreeComponent.HideAllButton,\n * CategoriesTreeComponent.InvertAllButton,\n * ]\n * ```\n */\n headerButtons?: Array<(props: CategoriesTreeHeaderButtonProps) => React.ReactNode>;\n}\n\n/**\n * A component that renders [[CategoriesTree]] and a header with filtering capabilities\n * and header buttons.\n * @public\n */\nexport const CategoriesTreeComponent = (props: CategoriesTreeComponentProps) => {\n const iModel = useActiveIModelConnection();\n const viewport = useActiveViewport();\n\n if (!iModel || !viewport) {\n return null;\n }\n\n return <CategoriesTreeComponentImpl {...props} iModel={iModel} viewport={viewport} />;\n};\n\n/**\n * Renders a \"Show all\" button that enables display of all categories and their subcategories.\n * @public\n */\nCategoriesTreeComponent.ShowAllButton = ShowAllButton;\n\n/**\n * Renders a \"Hide all\" button that disables display of all categories.\n * @public\n */\nCategoriesTreeComponent.HideAllButton = HideAllButton;\n\n/**\n * Renders an \"Invert all\" button that inverts display of all categories.\n * @public\n */\nCategoriesTreeComponent.InvertAllButton = InvertAllButton;\n\n/**\n * Id of the component. May be used when a creating a [[TreeDefinition]] for [[SelectableTree]].\n * @public\n */\nCategoriesTreeComponent.id = \"categories-tree\";\n\n/**\n * Label of the component. May be used when a creating a [[TreeDefinition]] for [[SelectableTree]].\n * @public\n */\nCategoriesTreeComponent.getLabel = () => TreeWidget.translate(\"categories\");\n\nfunction CategoriesTreeComponentImpl(props: CategoriesTreeComponentProps & { iModel: IModelConnection; viewport: ScreenViewport }) {\n const categories = useCategories(IModelApp.viewManager, props.iModel, props.viewport);\n const [filteredCategories, setFilteredCategories] = useState<CategoryInfo[]>();\n const { searchOptions, filterString, onFilterApplied, filteredProvider } = useTreeFilteringState();\n const contentClassName = classNames(\"tree-widget-tree-content\", props.density === \"enlarged\" && \"enlarge\");\n\n useEffect(() => {\n void (async () => {\n if (filteredProvider) {\n setFilteredCategories(await getFilteredCategories(filteredProvider));\n } else {\n setFilteredCategories(undefined);\n }\n })();\n }, [filteredProvider]);\n\n return (\n <div className=\"tree-widget-tree-with-header\">\n <TreeHeader\n onFilterClear={searchOptions.onFilterCancel}\n onFilterStart={searchOptions.onFilterStart}\n onSelectedChanged={searchOptions.onResultSelectedChanged}\n resultCount={searchOptions.matchedResultCount}\n selectedIndex={searchOptions.activeMatchIndex}\n density={props.density}\n >\n {props.headerButtons\n ? props.headerButtons.map((btn, index) => <Fragment key={index}>{btn({ viewport: props.viewport, categories, filteredCategories })}</Fragment>)\n : [\n <ShowAllButton\n viewport={props.viewport}\n categories={categories}\n filteredCategories={filteredCategories}\n key=\"show-all-btn\"\n density={props.density}\n />,\n <HideAllButton\n viewport={props.viewport}\n categories={categories}\n filteredCategories={filteredCategories}\n key=\"hide-all-btn\"\n density={props.density}\n />,\n <InvertAllButton\n viewport={props.viewport}\n categories={categories}\n filteredCategories={filteredCategories}\n key=\"invert-all-btn\"\n density={props.density}\n />,\n ]}\n </TreeHeader>\n <div className={contentClassName}>\n <AutoSizer>\n {({ width, height }) => (\n <CategoryTree\n {...props}\n categories={categories}\n width={width}\n height={height}\n filterInfo={{ filter: filterString, activeMatchIndex: searchOptions.activeMatchIndex }}\n onFilterApplied={onFilterApplied}\n activeView={props.viewport}\n />\n )}\n </AutoSizer>\n </div>\n </div>\n );\n}\n\nasync function getFilteredCategories(filteredProvider: IPresentationTreeDataProvider) {\n const filteredCategories: CategoryInfo[] = [];\n const nodes = await filteredProvider.getNodes();\n for (const node of nodes) {\n if (!isPresentationTreeNodeItem(node)) {\n continue;\n }\n const filteredCategoryId = CategoryVisibilityHandler.getInstanceIdFromTreeNodeKey(node.key);\n const filteredSubCategoriesIds = node.hasChildren\n ? (await filteredProvider.getNodes(node))\n .filter(isPresentationTreeNodeItem)\n .map((child) => CategoryVisibilityHandler.getInstanceIdFromTreeNodeKey(child.key))\n : [];\n filteredCategories.push({ categoryId: filteredCategoryId, subCategoryIds: filteredSubCategoriesIds });\n }\n return filteredCategories;\n}\n\nfunction ShowAllButton(props: CategoriesTreeHeaderButtonProps) {\n return (\n <IconButton\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n title={TreeWidget.translate(\"showAll\")}\n onClick={() =>\n void showAllCategories(\n (props.filteredCategories ?? props.categories).map((category) => category.categoryId),\n props.viewport,\n )\n }\n >\n <SvgVisibilityShow />\n </IconButton>\n );\n}\n\nfunction HideAllButton(props: CategoriesTreeHeaderButtonProps) {\n return (\n <IconButton\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n title={TreeWidget.translate(\"hideAll\")}\n onClick={() =>\n void hideAllCategories(\n (props.filteredCategories ?? props.categories).map((category) => category.categoryId),\n props.viewport,\n )\n }\n >\n <SvgVisibilityHide />\n </IconButton>\n );\n}\n\nfunction InvertAllButton(props: CategoriesTreeHeaderButtonProps) {\n return (\n <IconButton\n title={TreeWidget.translate(\"invert\")}\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n onClick={() => void invertAllCategories(props.filteredCategories ?? props.categories, props.viewport)}\n >\n <SvgVisibilityHalf />\n </IconButton>\n );\n}\n"]}
1
+ {"version":3,"file":"CategoriesTreeComponent.js","sourceRoot":"","sources":["../../../../../src/components/trees/category-tree/CategoriesTreeComponent.tsx"],"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 \"../VisibilityTreeBase.scss\";\nimport classNames from \"classnames\";\nimport { Fragment, useEffect, useState } from \"react\";\nimport { useActiveIModelConnection, useActiveViewport } from \"@itwin/appui-react\";\nimport { IModelApp } from \"@itwin/core-frontend\";\nimport { SvgVisibilityHalf, SvgVisibilityHide, SvgVisibilityShow } from \"@itwin/itwinui-icons-react\";\nimport { IconButton } from \"@itwin/itwinui-react\";\nimport { isPresentationTreeNodeItem } from \"@itwin/presentation-components\";\nimport { TreeWidget } from \"../../../TreeWidget\";\nimport { TreeHeader } from \"../../tree-header/TreeHeader\";\nimport { useTreeFilteringState } from \"../../TreeFilteringState\";\nimport { AutoSizer } from \"../../utils/AutoSizer\";\nimport { CategoryTree } from \"./CategoriesTree\";\nimport { CategoryVisibilityHandler, hideAllCategories, invertAllCategories, showAllCategories, useCategories } from \"./CategoryVisibilityHandler\";\n\nimport type { IModelConnection, ScreenViewport } from \"@itwin/core-frontend\";\nimport type { IPresentationTreeDataProvider } from \"@itwin/presentation-components\";\nimport type { TreeHeaderButtonProps } from \"../../tree-header/TreeHeader\";\nimport type { CategoryTreeProps } from \"./CategoriesTree\";\nimport type { CategoryInfo } from \"./CategoryVisibilityHandler\";\n/**\n * Props that get passed to [[CategoriesTreeComponent]] header button renderer.\n * @see CategoriesTreeComponentProps.headerButtons\n * @public\n */\nexport interface CategoriesTreeHeaderButtonProps extends TreeHeaderButtonProps {\n /** A list of categories available in the iModel */\n categories: CategoryInfo[];\n /** In case the tree is filtered, a list of filtered categories. */\n filteredCategories?: CategoryInfo[];\n}\n\n/**\n * Props for [[CategoriesTreeComponent]].\n * @public\n */\nexport interface CategoriesTreeComponentProps\n extends Omit<\n CategoryTreeProps,\n \"iModel\" | \"activeView\" | \"width\" | \"height\" | \"filterInfo\" | \"onFilterApplied\" | \"categories\" | \"categoryVisibilityHandler\" | \"viewManager\"\n > {\n /**\n * Renderers of header buttons. Defaults to:\n * ```ts\n * [\n * CategoriesTreeComponent.ShowAllButton,\n * CategoriesTreeComponent.HideAllButton,\n * CategoriesTreeComponent.InvertAllButton,\n * ]\n * ```\n */\n headerButtons?: Array<(props: CategoriesTreeHeaderButtonProps) => React.ReactNode>;\n}\n\n/**\n * A component that renders [[CategoriesTree]] and a header with filtering capabilities\n * and header buttons.\n * @public\n */\nexport const CategoriesTreeComponent = (props: CategoriesTreeComponentProps) => {\n const iModel = useActiveIModelConnection();\n const viewport = useActiveViewport();\n\n if (!iModel || !viewport) {\n return null;\n }\n\n return <CategoriesTreeComponentImpl {...props} iModel={iModel} viewport={viewport} />;\n};\n\n/**\n * Renders a \"Show all\" button that enables display of all categories and their subcategories.\n * @public\n */\nCategoriesTreeComponent.ShowAllButton = ShowAllButton;\n\n/**\n * Renders a \"Hide all\" button that disables display of all categories.\n * @public\n */\nCategoriesTreeComponent.HideAllButton = HideAllButton;\n\n/**\n * Renders an \"Invert all\" button that inverts display of all categories.\n * @public\n */\nCategoriesTreeComponent.InvertAllButton = InvertAllButton;\n\n/**\n * Id of the component. May be used when a creating a [[TreeDefinition]] for [[SelectableTree]].\n * @public\n */\nCategoriesTreeComponent.id = \"categories-tree\";\n\n/**\n * Label of the component. May be used when a creating a [[TreeDefinition]] for [[SelectableTree]].\n * @public\n */\nCategoriesTreeComponent.getLabel = () => TreeWidget.translate(\"categories\");\n\nfunction CategoriesTreeComponentImpl(props: CategoriesTreeComponentProps & { iModel: IModelConnection; viewport: ScreenViewport }) {\n const categories = useCategories(IModelApp.viewManager, props.iModel, props.viewport);\n const [filteredCategories, setFilteredCategories] = useState<CategoryInfo[]>();\n const { searchOptions, filterString, onFilterApplied, filteredProvider } = useTreeFilteringState();\n const contentClassName = classNames(\"tree-widget-tree-content\", props.density === \"enlarged\" && \"enlarge\");\n\n useEffect(() => {\n void (async () => {\n if (filteredProvider) {\n setFilteredCategories(await getFilteredCategories(filteredProvider));\n } else {\n setFilteredCategories(undefined);\n }\n })();\n }, [filteredProvider]);\n\n return (\n <div className=\"tree-widget-tree-with-header\">\n <TreeHeader\n onFilterClear={searchOptions.onFilterCancel}\n onFilterStart={searchOptions.onFilterStart}\n onSelectedChanged={searchOptions.onResultSelectedChanged}\n resultCount={searchOptions.matchedResultCount}\n selectedIndex={searchOptions.activeMatchIndex}\n density={props.density}\n >\n {props.headerButtons\n ? props.headerButtons.map((btn, index) => (\n <Fragment key={index}>\n {btn({ viewport: props.viewport, categories, filteredCategories, density: props.density, onFeatureUsed: props.onFeatureUsed })}\n </Fragment>\n ))\n : [\n <ShowAllButton\n viewport={props.viewport}\n categories={categories}\n filteredCategories={filteredCategories}\n key=\"show-all-btn\"\n density={props.density}\n onFeatureUsed={props.onFeatureUsed}\n />,\n <HideAllButton\n viewport={props.viewport}\n categories={categories}\n filteredCategories={filteredCategories}\n key=\"hide-all-btn\"\n density={props.density}\n onFeatureUsed={props.onFeatureUsed}\n />,\n <InvertAllButton\n viewport={props.viewport}\n categories={categories}\n filteredCategories={filteredCategories}\n key=\"invert-all-btn\"\n density={props.density}\n onFeatureUsed={props.onFeatureUsed}\n />,\n ]}\n </TreeHeader>\n <div className={contentClassName}>\n <AutoSizer>\n {({ width, height }) => (\n <CategoryTree\n {...props}\n categories={categories}\n width={width}\n height={height}\n filterInfo={{ filter: filterString, activeMatchIndex: searchOptions.activeMatchIndex }}\n onFilterApplied={onFilterApplied}\n activeView={props.viewport}\n />\n )}\n </AutoSizer>\n </div>\n </div>\n );\n}\n\nasync function getFilteredCategories(filteredProvider: IPresentationTreeDataProvider) {\n const filteredCategories: CategoryInfo[] = [];\n const nodes = await filteredProvider.getNodes();\n for (const node of nodes) {\n if (!isPresentationTreeNodeItem(node)) {\n continue;\n }\n const filteredCategoryId = CategoryVisibilityHandler.getInstanceIdFromTreeNodeKey(node.key);\n const filteredSubCategoriesIds = node.hasChildren\n ? (await filteredProvider.getNodes(node))\n .filter(isPresentationTreeNodeItem)\n .map((child) => CategoryVisibilityHandler.getInstanceIdFromTreeNodeKey(child.key))\n : [];\n filteredCategories.push({ categoryId: filteredCategoryId, subCategoryIds: filteredSubCategoriesIds });\n }\n return filteredCategories;\n}\n\nfunction ShowAllButton(props: CategoriesTreeHeaderButtonProps) {\n return (\n <IconButton\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n title={TreeWidget.translate(\"showAll\")}\n onClick={() => {\n props.onFeatureUsed?.(`${CategoriesTreeComponent.id}-showall`);\n void showAllCategories(\n (props.filteredCategories ?? props.categories).map((category) => category.categoryId),\n props.viewport,\n );\n }}\n >\n <SvgVisibilityShow />\n </IconButton>\n );\n}\n\nfunction HideAllButton(props: CategoriesTreeHeaderButtonProps) {\n return (\n <IconButton\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n title={TreeWidget.translate(\"hideAll\")}\n onClick={() => {\n props.onFeatureUsed?.(`${CategoriesTreeComponent.id}-hideall`);\n void hideAllCategories(\n (props.filteredCategories ?? props.categories).map((category) => category.categoryId),\n props.viewport,\n );\n }}\n >\n <SvgVisibilityHide />\n </IconButton>\n );\n}\n\nfunction InvertAllButton(props: CategoriesTreeHeaderButtonProps) {\n return (\n <IconButton\n title={TreeWidget.translate(\"invert\")}\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n onClick={() => {\n props.onFeatureUsed?.(`${CategoriesTreeComponent.id}-invert`);\n void invertAllCategories(props.filteredCategories ?? props.categories, props.viewport);\n }}\n >\n <SvgVisibilityHalf />\n </IconButton>\n );\n}\n"]}
@@ -0,0 +1,27 @@
1
+ import { TreeEventHandler } from "@itwin/components-react";
2
+ import type { AbstractTreeNodeLoaderWithProvider, TreeCheckboxStateChangeEventArgs, TreeNodeEventArgs, TreeSelectionModificationEventArgs, TreeSelectionReplacementEventArgs } from "@itwin/components-react";
3
+ import type { IPresentationTreeDataProvider } from "@itwin/presentation-components";
4
+ export interface ReportingTreeEventHandlerProps {
5
+ nodeLoader: AbstractTreeNodeLoaderWithProvider<IPresentationTreeDataProvider>;
6
+ eventHandler: TreeEventHandler;
7
+ reportUsage: (props: {
8
+ reportInteraction: boolean;
9
+ }) => void;
10
+ }
11
+ export declare class ReportingTreeEventHandler extends TreeEventHandler {
12
+ protected _eventHandler: TreeEventHandler;
13
+ protected _reportUsage: (props: {
14
+ reportInteraction: boolean;
15
+ }) => void;
16
+ constructor(props: ReportingTreeEventHandlerProps);
17
+ dispose(): void;
18
+ onNodeExpanded(props: TreeNodeEventArgs): void;
19
+ onNodeCollapsed(props: TreeNodeEventArgs): void;
20
+ onSelectionModified(props: TreeSelectionModificationEventArgs): import("@itwin/components-react").Subscription | undefined;
21
+ onSelectionReplaced(props: TreeSelectionReplacementEventArgs): import("@itwin/components-react").Subscription | undefined;
22
+ onCheckboxStateChanged(props: TreeCheckboxStateChangeEventArgs): import("@itwin/components-react").Subscription | undefined;
23
+ onDelayedNodeClick(props: TreeNodeEventArgs): void;
24
+ onNodeDoubleClick(props: TreeNodeEventArgs): void;
25
+ onNodeEditorActivated(props: TreeNodeEventArgs): void;
26
+ }
27
+ //# sourceMappingURL=ReportingTreeEventHandler.d.ts.map
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.ReportingTreeEventHandler = void 0;
8
+ const components_react_1 = require("@itwin/components-react");
9
+ class ReportingTreeEventHandler extends components_react_1.TreeEventHandler {
10
+ constructor(props) {
11
+ super({ modelSource: props.nodeLoader.modelSource, nodeLoader: props.nodeLoader });
12
+ this._eventHandler = props.eventHandler;
13
+ this._reportUsage = props.reportUsage;
14
+ }
15
+ dispose() {
16
+ this._eventHandler.dispose();
17
+ super.dispose();
18
+ }
19
+ onNodeExpanded(props) {
20
+ this._reportUsage({ reportInteraction: true });
21
+ this._eventHandler.onNodeExpanded(props);
22
+ }
23
+ onNodeCollapsed(props) {
24
+ this._reportUsage({ reportInteraction: true });
25
+ this._eventHandler.onNodeCollapsed(props);
26
+ }
27
+ onSelectionModified(props) {
28
+ this._reportUsage({ reportInteraction: true });
29
+ return this._eventHandler.onSelectionModified(props);
30
+ }
31
+ onSelectionReplaced(props) {
32
+ this._reportUsage({ reportInteraction: true });
33
+ return this._eventHandler.onSelectionReplaced(props);
34
+ }
35
+ onCheckboxStateChanged(props) {
36
+ return this._eventHandler.onCheckboxStateChanged(props);
37
+ }
38
+ onDelayedNodeClick(props) {
39
+ this._eventHandler.onDelayedNodeClick(props);
40
+ }
41
+ onNodeDoubleClick(props) {
42
+ this._reportUsage({ reportInteraction: true });
43
+ this._eventHandler.onNodeDoubleClick(props);
44
+ }
45
+ onNodeEditorActivated(props) {
46
+ this._reportUsage({ reportInteraction: true });
47
+ this._eventHandler.onNodeEditorActivated(props);
48
+ }
49
+ }
50
+ exports.ReportingTreeEventHandler = ReportingTreeEventHandler;
51
+ //# sourceMappingURL=ReportingTreeEventHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReportingTreeEventHandler.js","sourceRoot":"","sources":["../../../../../src/components/trees/common/ReportingTreeEventHandler.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAEhG,8DAA2D;AAgB3D,MAAa,yBAA0B,SAAQ,mCAAgB;IAI7D,YAAY,KAAqC;QAC/C,KAAK,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,YAAY,CAAC;QACxC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC;IACxC,CAAC;IAEM,OAAO;QACZ,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;QAC7B,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;IAEe,cAAc,CAAC,KAAwB;QACrD,IAAI,CAAC,YAAY,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IAEe,eAAe,CAAC,KAAwB;QACtD,IAAI,CAAC,YAAY,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IAEe,mBAAmB,CAAC,KAAyC;QAC3E,IAAI,CAAC,YAAY,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACvD,CAAC;IAEe,mBAAmB,CAAC,KAAwC;QAC1E,IAAI,CAAC,YAAY,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACvD,CAAC;IAEe,sBAAsB,CAAC,KAAuC;QAC5E,OAAO,IAAI,CAAC,aAAa,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC;IAEe,kBAAkB,CAAC,KAAwB;QACzD,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC;IAEe,iBAAiB,CAAC,KAAwB;QACxD,IAAI,CAAC,YAAY,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IAEe,qBAAqB,CAAC,KAAwB;QAC5D,IAAI,CAAC,YAAY,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;CACF;AApDD,8DAoDC","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 { TreeEventHandler } from \"@itwin/components-react\";\n\nimport type {\n AbstractTreeNodeLoaderWithProvider,\n TreeCheckboxStateChangeEventArgs,\n TreeNodeEventArgs,\n TreeSelectionModificationEventArgs,\n TreeSelectionReplacementEventArgs,\n} from \"@itwin/components-react\";\nimport type { IPresentationTreeDataProvider } from \"@itwin/presentation-components\";\nexport interface ReportingTreeEventHandlerProps {\n nodeLoader: AbstractTreeNodeLoaderWithProvider<IPresentationTreeDataProvider>;\n eventHandler: TreeEventHandler;\n reportUsage: (props: { reportInteraction: boolean }) => void;\n}\n\nexport class ReportingTreeEventHandler extends TreeEventHandler {\n protected _eventHandler: TreeEventHandler;\n protected _reportUsage: (props: { reportInteraction: boolean }) => void;\n\n constructor(props: ReportingTreeEventHandlerProps) {\n super({ modelSource: props.nodeLoader.modelSource, nodeLoader: props.nodeLoader });\n this._eventHandler = props.eventHandler;\n this._reportUsage = props.reportUsage;\n }\n\n public dispose() {\n this._eventHandler.dispose();\n super.dispose();\n }\n\n public override onNodeExpanded(props: TreeNodeEventArgs) {\n this._reportUsage({ reportInteraction: true });\n this._eventHandler.onNodeExpanded(props);\n }\n\n public override onNodeCollapsed(props: TreeNodeEventArgs) {\n this._reportUsage({ reportInteraction: true });\n this._eventHandler.onNodeCollapsed(props);\n }\n\n public override onSelectionModified(props: TreeSelectionModificationEventArgs) {\n this._reportUsage({ reportInteraction: true });\n return this._eventHandler.onSelectionModified(props);\n }\n\n public override onSelectionReplaced(props: TreeSelectionReplacementEventArgs) {\n this._reportUsage({ reportInteraction: true });\n return this._eventHandler.onSelectionReplaced(props);\n }\n\n public override onCheckboxStateChanged(props: TreeCheckboxStateChangeEventArgs) {\n return this._eventHandler.onCheckboxStateChanged(props);\n }\n\n public override onDelayedNodeClick(props: TreeNodeEventArgs) {\n this._eventHandler.onDelayedNodeClick(props);\n }\n\n public override onNodeDoubleClick(props: TreeNodeEventArgs) {\n this._reportUsage({ reportInteraction: true });\n this._eventHandler.onNodeDoubleClick(props);\n }\n\n public override onNodeEditorActivated(props: TreeNodeEventArgs) {\n this._reportUsage({ reportInteraction: true });\n this._eventHandler.onNodeEditorActivated(props);\n }\n}\n"]}
@@ -4,6 +4,7 @@ import type { IPresentationTreeDataProvider, PresentationTreeNodeRendererProps }
4
4
  import type { AbstractTreeNodeLoaderWithProvider, TreeRendererProps as ComponentsTreeRendererProps } from "@itwin/components-react";
5
5
  import type { TreeNodeRendererProps } from "./TreeNodeRenderer";
6
6
  import type { TreeContextMenuProps } from "./ContextMenu";
7
+ import type { UsageTrackedFeatures } from "./UseFeatureReporting";
7
8
  /**
8
9
  * Base props for [[TreeRenderer]] component.
9
10
  * @public
@@ -24,17 +25,31 @@ export type TreeRendererProps = ComponentsTreeRendererProps & TreeRendererBasePr
24
25
  * @public
25
26
  */
26
27
  export declare function TreeRenderer({ contextMenuItems, nodeRenderer, nodeLabelRenderer, density, ...restProps }: TreeRendererProps): JSX.Element;
28
+ /**
29
+ * Props for [[FilterableTreeRenderer]] node renderer.
30
+ * @beta
31
+ */
32
+ export interface FilterableTreeNodeRendererProps extends PresentationTreeNodeRendererProps {
33
+ reportUsage?: (props: {
34
+ featureId?: UsageTrackedFeatures;
35
+ reportInteraction: boolean;
36
+ }) => void;
37
+ }
27
38
  /**
28
39
  * Props for [[FilterableTreeRenderer]] component.
29
40
  * @beta
30
41
  */
31
42
  export interface FilterableTreeRendererProps extends Omit<TreeRendererProps, "nodeLoader" | "nodeRenderer"> {
32
43
  nodeLoader: AbstractTreeNodeLoaderWithProvider<IPresentationTreeDataProvider>;
33
- nodeRenderer: (props: PresentationTreeNodeRendererProps) => React.ReactNode;
44
+ nodeRenderer: (props: FilterableTreeNodeRendererProps) => React.ReactNode;
45
+ reportUsage?: (props: {
46
+ featureId?: UsageTrackedFeatures;
47
+ reportInteraction: boolean;
48
+ }) => void;
34
49
  }
35
50
  /**
36
51
  * Base tree renderer for trees with enabled hierarchy level filtering.
37
52
  * @beta
38
53
  */
39
- export declare function FilterableTreeRenderer({ nodeRenderer, nodeLoader, ...restProps }: FilterableTreeRendererProps): JSX.Element;
54
+ export declare function FilterableTreeRenderer({ nodeRenderer, nodeLoader, reportUsage, ...restProps }: FilterableTreeRendererProps): JSX.Element;
40
55
  //# sourceMappingURL=TreeRenderer.d.ts.map
@@ -33,10 +33,26 @@ exports.TreeRenderer = TreeRenderer;
33
33
  * Base tree renderer for trees with enabled hierarchy level filtering.
34
34
  * @beta
35
35
  */
36
- function FilterableTreeRenderer({ nodeRenderer, nodeLoader, ...restProps }) {
37
- const { onClearFilterClick, onFilterClick, filterDialog } = (0, presentation_components_1.useFilterablePresentationTree)({ nodeLoader });
36
+ function FilterableTreeRenderer({ nodeRenderer, nodeLoader, reportUsage, ...restProps }) {
37
+ const { onClearFilterClick, onFilterClick, filterDialog } = (0, presentation_components_1.useFilterablePresentationTree)({
38
+ nodeLoader,
39
+ onFilterApplied: () => {
40
+ reportUsage?.({ featureId: "hierarchy-level-filtering", reportInteraction: true });
41
+ },
42
+ });
38
43
  return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(TreeRenderer, { ...restProps, nodeLoader: nodeLoader, nodeRenderer: (props) => {
39
- return nodeRenderer({ ...props, onClearFilterClick, onFilterClick });
44
+ return nodeRenderer({
45
+ ...props,
46
+ reportUsage,
47
+ onFilterClick: (nodeId) => {
48
+ reportUsage?.({ reportInteraction: true });
49
+ onFilterClick(nodeId);
50
+ },
51
+ onClearFilterClick: (nodeId) => {
52
+ reportUsage?.({ reportInteraction: true });
53
+ onClearFilterClick(nodeId);
54
+ },
55
+ });
40
56
  } }), filterDialog] }));
41
57
  }
42
58
  exports.FilterableTreeRenderer = FilterableTreeRenderer;
@@ -1 +1 @@
1
- {"version":3,"file":"TreeRenderer.js","sourceRoot":"","sources":["../../../../../src/components/trees/common/TreeRenderer.tsx"],"names":[],"mappings":";;;;;;;AAAA;;;gGAGgG;AAEhG,+BAA6B;AAC7B,4DAAoC;AACpC,8DAAmG;AACnG,4EAA+E;AAC/E,+CAA+C;AAC/C,yDAAqE;AAuBrE;;;GAGG;AACH,SAAgB,YAAY,CAAC,EAAE,gBAAgB,EAAE,YAAY,EAAE,iBAAiB,EAAE,OAAO,EAAE,GAAG,SAAS,EAAqB;IAC1H,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,GAAG,IAAA,4BAAc,EAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAElF,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,IAAI,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;IAC7E,MAAM,SAAS,GAAG,IAAA,oBAAU,EAAC,6BAA6B,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,UAAU,EAAE,CAAC,CAAC;IAErG,OAAO,CACL,iCAAK,SAAS,EAAE,SAAS,aACvB,uBAAC,+BAAsB,OACjB,SAAS,EACb,YAAY,EAAE,CAAC,SAAS,EAAE,EAAE;oBAC1B,MAAM,aAAa,GAAG,SAAS,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,SAAS,CAAC;oBACxF,OAAO,CACL,uBAAC,kDAA+B,IAAC,IAAI,EAAE,SAAS,CAAC,IAAI,EAAE,iBAAiB,EAAE,iBAAiB,YACxF,YAAY,CAAC,CAAC,CAAC,CACd,YAAY,CAAC,EAAE,GAAG,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CACxE,CAAC,CAAC,CAAC,CACF,uBAAC,mCAAgB,OAAK,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,GAAI,CAC5F,GAC+B,CACnC,CAAC;gBACJ,CAAC,EACD,UAAU,EAAE,UAAU,GACtB,EACD,iBAAiB,EAAE,IAChB,CACP,CAAC;AACJ,CAAC;AA3BD,oCA2BC;AAUD;;;GAGG;AACH,SAAgB,sBAAsB,CAAC,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,SAAS,EAA+B;IAC5G,MAAM,EAAE,kBAAkB,EAAE,aAAa,EAAE,YAAY,EAAE,GAAG,IAAA,uDAA6B,EAAC,EAAE,UAAU,EAAE,CAAC,CAAC;IAE1G,OAAO,CACL,4CACE,uBAAC,YAAY,OACP,SAAS,EACb,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE;oBACtB,OAAO,YAAY,CAAC,EAAE,GAAG,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAC,CAAC;gBACvE,CAAC,GACD,EACD,YAAY,IACT,CACP,CAAC;AACJ,CAAC;AAfD,wDAeC;AAED,SAAS,aAAa,CAAC,OAA+B,EAAE,aAAwD;IAC9G,QAAQ,OAAO,EAAE;QACf,KAAK,SAAS;YACZ,OAAO,aAAa,CAAC;QACvB,KAAK,UAAU;YACb,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC;KACnB;AACH,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 \"./TreeRenderer.scss\";\nimport classNames from \"classnames\";\nimport { TreeRenderer as ComponentsTreeRenderer, TreeNodeRenderer } from \"@itwin/components-react\";\nimport { useFilterablePresentationTree } from \"@itwin/presentation-components\";\nimport { useContextMenu } from \"./ContextMenu\";\nimport { TreeNodeRendererContextProvider } from \"./TreeNodeRenderer\";\n\nimport type { IPresentationTreeDataProvider, PresentationTreeNodeRendererProps } from \"@itwin/presentation-components\";\nimport type { AbstractTreeNodeLoaderWithProvider, TreeRendererProps as ComponentsTreeRendererProps } from \"@itwin/components-react\";\nimport type { TreeNodeRendererProps } from \"./TreeNodeRenderer\";\nimport type { TreeContextMenuProps } from \"./ContextMenu\";\n/**\n * Base props for [[TreeRenderer]] component.\n * @public\n */\nexport interface TreeRendererBaseProps extends TreeContextMenuProps, TreeNodeRendererProps {\n /**\n * Modifies the density of tree nodes. `enlarged` tree nodes have bigger height and bigger button hit boxes.\n */\n density?: \"default\" | \"enlarged\";\n}\n\n/**\n * Props for [[TreeRenderer]] component.\n * @public\n */\nexport type TreeRendererProps = ComponentsTreeRendererProps & TreeRendererBaseProps;\n\n/**\n * Base tree renderer for visibility trees.\n * @public\n */\nexport function TreeRenderer({ contextMenuItems, nodeRenderer, nodeLabelRenderer, density, ...restProps }: TreeRendererProps) {\n const { onContextMenu, renderContextMenu } = useContextMenu({ contextMenuItems });\n\n const nodeHeight = getNodeHeight(density ?? \"default\", restProps.nodeHeight);\n const className = classNames(\"tree-widget-tree-nodes-list\", { [\"enlarge\"]: density === \"enlarged\" });\n\n return (\n <div className={className}>\n <ComponentsTreeRenderer\n {...restProps}\n nodeRenderer={(nodeProps) => {\n const nodeClassName = nodeProps.node.numChildren === 0 ? \"without-expander\" : undefined;\n return (\n <TreeNodeRendererContextProvider node={nodeProps.node} nodeLabelRenderer={nodeLabelRenderer}>\n {nodeRenderer ? (\n nodeRenderer({ ...nodeProps, onContextMenu, className: nodeClassName })\n ) : (\n <TreeNodeRenderer {...nodeProps} onContextMenu={onContextMenu} className={nodeClassName} />\n )}\n </TreeNodeRendererContextProvider>\n );\n }}\n nodeHeight={nodeHeight}\n />\n {renderContextMenu()}\n </div>\n );\n}\n\n/**\n * Props for [[FilterableTreeRenderer]] component.\n * @beta\n */\nexport interface FilterableTreeRendererProps extends Omit<TreeRendererProps, \"nodeLoader\" | \"nodeRenderer\"> {\n nodeLoader: AbstractTreeNodeLoaderWithProvider<IPresentationTreeDataProvider>;\n nodeRenderer: (props: PresentationTreeNodeRendererProps) => React.ReactNode;\n}\n/**\n * Base tree renderer for trees with enabled hierarchy level filtering.\n * @beta\n */\nexport function FilterableTreeRenderer({ nodeRenderer, nodeLoader, ...restProps }: FilterableTreeRendererProps) {\n const { onClearFilterClick, onFilterClick, filterDialog } = useFilterablePresentationTree({ nodeLoader });\n\n return (\n <div>\n <TreeRenderer\n {...restProps}\n nodeLoader={nodeLoader}\n nodeRenderer={(props) => {\n return nodeRenderer({ ...props, onClearFilterClick, onFilterClick });\n }}\n />\n {filterDialog}\n </div>\n );\n}\n\nfunction getNodeHeight(density: \"default\" | \"enlarged\", defaultHeight: ComponentsTreeRendererProps[\"nodeHeight\"]) {\n switch (density) {\n case \"default\":\n return defaultHeight;\n case \"enlarged\":\n return () => 43;\n }\n}\n"]}
1
+ {"version":3,"file":"TreeRenderer.js","sourceRoot":"","sources":["../../../../../src/components/trees/common/TreeRenderer.tsx"],"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 \"./TreeRenderer.scss\";\nimport classNames from \"classnames\";\nimport { TreeRenderer as ComponentsTreeRenderer, TreeNodeRenderer } from \"@itwin/components-react\";\nimport { useFilterablePresentationTree } from \"@itwin/presentation-components\";\nimport { useContextMenu } from \"./ContextMenu\";\nimport { TreeNodeRendererContextProvider } from \"./TreeNodeRenderer\";\n\nimport type { IPresentationTreeDataProvider, PresentationTreeNodeRendererProps } from \"@itwin/presentation-components\";\nimport type { AbstractTreeNodeLoaderWithProvider, TreeRendererProps as ComponentsTreeRendererProps } from \"@itwin/components-react\";\nimport type { TreeNodeRendererProps } from \"./TreeNodeRenderer\";\nimport type { TreeContextMenuProps } from \"./ContextMenu\";\nimport type { UsageTrackedFeatures } from \"./UseFeatureReporting\";\n/**\n * Base props for [[TreeRenderer]] component.\n * @public\n */\nexport interface TreeRendererBaseProps extends TreeContextMenuProps, TreeNodeRendererProps {\n /**\n * Modifies the density of tree nodes. `enlarged` tree nodes have bigger height and bigger button hit boxes.\n */\n density?: \"default\" | \"enlarged\";\n}\n\n/**\n * Props for [[TreeRenderer]] component.\n * @public\n */\nexport type TreeRendererProps = ComponentsTreeRendererProps & TreeRendererBaseProps;\n\n/**\n * Base tree renderer for visibility trees.\n * @public\n */\nexport function TreeRenderer({ contextMenuItems, nodeRenderer, nodeLabelRenderer, density, ...restProps }: TreeRendererProps) {\n const { onContextMenu, renderContextMenu } = useContextMenu({ contextMenuItems });\n\n const nodeHeight = getNodeHeight(density ?? \"default\", restProps.nodeHeight);\n const className = classNames(\"tree-widget-tree-nodes-list\", { [\"enlarge\"]: density === \"enlarged\" });\n\n return (\n <div className={className}>\n <ComponentsTreeRenderer\n {...restProps}\n nodeRenderer={(nodeProps) => {\n const nodeClassName = nodeProps.node.numChildren === 0 ? \"without-expander\" : undefined;\n return (\n <TreeNodeRendererContextProvider node={nodeProps.node} nodeLabelRenderer={nodeLabelRenderer}>\n {nodeRenderer ? (\n nodeRenderer({ ...nodeProps, onContextMenu, className: nodeClassName })\n ) : (\n <TreeNodeRenderer {...nodeProps} onContextMenu={onContextMenu} className={nodeClassName} />\n )}\n </TreeNodeRendererContextProvider>\n );\n }}\n nodeHeight={nodeHeight}\n />\n {renderContextMenu()}\n </div>\n );\n}\n\n/**\n * Props for [[FilterableTreeRenderer]] node renderer.\n * @beta\n */\nexport interface FilterableTreeNodeRendererProps extends PresentationTreeNodeRendererProps {\n reportUsage?: (props: { featureId?: UsageTrackedFeatures; reportInteraction: boolean }) => void;\n}\n\n/**\n * Props for [[FilterableTreeRenderer]] component.\n * @beta\n */\nexport interface FilterableTreeRendererProps extends Omit<TreeRendererProps, \"nodeLoader\" | \"nodeRenderer\"> {\n nodeLoader: AbstractTreeNodeLoaderWithProvider<IPresentationTreeDataProvider>;\n nodeRenderer: (props: FilterableTreeNodeRendererProps) => React.ReactNode;\n reportUsage?: (props: { featureId?: UsageTrackedFeatures; reportInteraction: boolean }) => void;\n}\n/**\n * Base tree renderer for trees with enabled hierarchy level filtering.\n * @beta\n */\nexport function FilterableTreeRenderer({ nodeRenderer, nodeLoader, reportUsage, ...restProps }: FilterableTreeRendererProps) {\n const { onClearFilterClick, onFilterClick, filterDialog } = useFilterablePresentationTree({\n nodeLoader,\n onFilterApplied: () => {\n reportUsage?.({ featureId: \"hierarchy-level-filtering\", reportInteraction: true });\n },\n });\n\n return (\n <div>\n <TreeRenderer\n {...restProps}\n nodeLoader={nodeLoader}\n nodeRenderer={(props) => {\n return nodeRenderer({\n ...props,\n reportUsage,\n onFilterClick: (nodeId: string) => {\n reportUsage?.({ reportInteraction: true });\n onFilterClick(nodeId);\n },\n onClearFilterClick: (nodeId: string) => {\n reportUsage?.({ reportInteraction: true });\n onClearFilterClick(nodeId);\n },\n });\n }}\n />\n {filterDialog}\n </div>\n );\n}\n\nfunction getNodeHeight(density: \"default\" | \"enlarged\", defaultHeight: ComponentsTreeRendererProps[\"nodeHeight\"]) {\n switch (density) {\n case \"default\":\n return defaultHeight;\n case \"enlarged\":\n return () => 43;\n }\n}\n"]}
@@ -58,7 +58,7 @@
58
58
 
59
59
  .core-tree-node {
60
60
  &.without-expander {
61
- margin-left: var(--enlarged-node-without-expander-margin);
61
+ margin-left: var(--enlarged-node-without-expander-margin);
62
62
  }
63
63
 
64
64
  > .presentation-components-node-action-buttons {
@@ -0,0 +1,23 @@
1
+ /** @internal */
2
+ export interface UseFeatureReportingProps {
3
+ treeIdentifier: string;
4
+ onFeatureUsed?: (featureId: string) => void;
5
+ }
6
+ /** @internal */
7
+ export interface UseFeatureReportingResult {
8
+ reportUsage: (props: {
9
+ featureId?: UsageTrackedFeatures;
10
+ reportInteraction: boolean;
11
+ }) => void;
12
+ }
13
+ /**
14
+ * Features that are tracked for usage.
15
+ * @internal
16
+ */
17
+ export type UsageTrackedFeatures = "visibility-change" | "hierarchy-level-filtering" | "filtering" | "hierarchy-level-size-limit-hit" | "zoom-to-node";
18
+ /**
19
+ * Enables feature reporting for a tree component.
20
+ * @internal
21
+ */
22
+ export declare function useFeatureReporting(props: UseFeatureReportingProps): UseFeatureReportingResult;
23
+ //# sourceMappingURL=UseFeatureReporting.d.ts.map
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ /*---------------------------------------------------------------------------------------------
3
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
+ * See LICENSE.md in the project root for license terms and full copyright notice.
5
+ *--------------------------------------------------------------------------------------------*/
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.useFeatureReporting = void 0;
8
+ const react_1 = require("react");
9
+ /**
10
+ * Enables feature reporting for a tree component.
11
+ * @internal
12
+ */
13
+ function useFeatureReporting(props) {
14
+ const { treeIdentifier, onFeatureUsed } = props;
15
+ const onFeatureUsedRef = (0, react_1.useRef)(onFeatureUsed);
16
+ (0, react_1.useEffect)(() => {
17
+ onFeatureUsedRef.current = onFeatureUsed;
18
+ }, [onFeatureUsed]);
19
+ const reportUsage = (0, react_1.useCallback)(({ featureId, reportInteraction }) => {
20
+ if (reportInteraction !== false) {
21
+ onFeatureUsedRef.current?.(`use-${treeIdentifier}`);
22
+ }
23
+ if (featureId) {
24
+ onFeatureUsedRef.current?.(`${treeIdentifier}-${featureId}`);
25
+ }
26
+ }, [treeIdentifier]);
27
+ return { reportUsage };
28
+ }
29
+ exports.useFeatureReporting = useFeatureReporting;
30
+ //# sourceMappingURL=UseFeatureReporting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UseFeatureReporting.js","sourceRoot":"","sources":["../../../../../src/components/trees/common/UseFeatureReporting.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAEhG,iCAAuD;AAmBvD;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,KAA+B;IACjE,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,GAAG,KAAK,CAAC;IAChD,MAAM,gBAAgB,GAAG,IAAA,cAAM,EAAC,aAAa,CAAC,CAAC;IAE/C,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,gBAAgB,CAAC,OAAO,GAAG,aAAa,CAAC;IAC3C,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,MAAM,WAAW,GAAG,IAAA,mBAAW,EAC7B,CAAC,EAAE,SAAS,EAAE,iBAAiB,EAAoE,EAAE,EAAE;QACrG,IAAI,iBAAiB,KAAK,KAAK,EAAE;YAC/B,gBAAgB,CAAC,OAAO,EAAE,CAAC,OAAO,cAAc,EAAE,CAAC,CAAC;SACrD;QACD,IAAI,SAAS,EAAE;YACb,gBAAgB,CAAC,OAAO,EAAE,CAAC,GAAG,cAAc,IAAI,SAAS,EAAE,CAAC,CAAC;SAC9D;IACH,CAAC,EACD,CAAC,cAAc,CAAC,CACjB,CAAC;IAEF,OAAO,EAAE,WAAW,EAAE,CAAC;AACzB,CAAC;AArBD,kDAqBC","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 } from \"react\";\n\n/** @internal */\nexport interface UseFeatureReportingProps {\n treeIdentifier: string;\n onFeatureUsed?: (featureId: string) => void;\n}\n\n/** @internal */\nexport interface UseFeatureReportingResult {\n reportUsage: (props: { featureId?: UsageTrackedFeatures; reportInteraction: boolean }) => void;\n}\n\n/**\n * Features that are tracked for usage.\n * @internal\n */\nexport type UsageTrackedFeatures = \"visibility-change\" | \"hierarchy-level-filtering\" | \"filtering\" | \"hierarchy-level-size-limit-hit\" | \"zoom-to-node\";\n\n/**\n * Enables feature reporting for a tree component.\n * @internal\n */\nexport function useFeatureReporting(props: UseFeatureReportingProps): UseFeatureReportingResult {\n const { treeIdentifier, onFeatureUsed } = props;\n const onFeatureUsedRef = useRef(onFeatureUsed);\n\n useEffect(() => {\n onFeatureUsedRef.current = onFeatureUsed;\n }, [onFeatureUsed]);\n\n const reportUsage = useCallback(\n ({ featureId, reportInteraction }: { featureId?: UsageTrackedFeatures; reportInteraction: boolean }) => {\n if (reportInteraction !== false) {\n onFeatureUsedRef.current?.(`use-${treeIdentifier}`);\n }\n if (featureId) {\n onFeatureUsedRef.current?.(`${treeIdentifier}-${featureId}`);\n }\n },\n [treeIdentifier],\n );\n\n return { reportUsage };\n}\n"]}
@@ -1,9 +1,11 @@
1
1
  import { VisibilityTreeEventHandler } from "../VisibilityTreeEventHandler";
2
+ import { ReportingTreeEventHandler } from "./ReportingTreeEventHandler";
2
3
  import type { IModelConnection } from "@itwin/core-frontend";
3
4
  import type { Ruleset } from "@itwin/presentation-common";
4
5
  import type { IFilteredPresentationTreeDataProvider, UsePresentationTreeStateProps } from "@itwin/presentation-components";
5
6
  import type { IVisibilityHandler, VisibilityTreeEventHandlerParams, VisibilityTreeSelectionPredicate } from "../VisibilityTreeEventHandler";
6
7
  import type { VisibilityTreeFilterInfo } from "./Types";
8
+ import type { UsageTrackedFeatures } from "./UseFeatureReporting";
7
9
  /**
8
10
  * Props for [[useVisibilityTreeState]] hook.
9
11
  * @beta
@@ -25,6 +27,11 @@ export interface UseVisibilityTreeStateProps extends Omit<UsePresentationTreeSta
25
27
  eventHandler?: (props: VisibilityTreeEventHandlerParams) => VisibilityTreeEventHandler;
26
28
  /** The limit for how many items should be loaded for a single hierarchy level. */
27
29
  hierarchyLevelSizeLimit?: number;
30
+ /** Callback called when a feature is used. */
31
+ reportUsage?: (props: {
32
+ featureId?: UsageTrackedFeatures;
33
+ reportInteraction: boolean;
34
+ }) => void;
28
35
  }
29
36
  /**
30
37
  * Custom hook for creating visibility tree component state.
@@ -32,5 +39,5 @@ export interface UseVisibilityTreeStateProps extends Omit<UsePresentationTreeSta
32
39
  * @returns `undefined` on first render cycle. On all other render cycles state is initialized and valid object is returned.
33
40
  * @beta
34
41
  */
35
- export declare function useVisibilityTreeState({ imodel, ruleset, filterInfo, onFilterChange, visibilityHandler, selectionPredicate, eventHandler, ...props }: UseVisibilityTreeStateProps): import("@itwin/presentation-components").UsePresentationTreeStateResult<VisibilityTreeEventHandler> | undefined;
42
+ export declare function useVisibilityTreeState({ imodel, ruleset, filterInfo, onFilterChange, visibilityHandler, selectionPredicate, eventHandler, reportUsage, ...props }: UseVisibilityTreeStateProps): import("@itwin/presentation-components").UsePresentationTreeStateResult<VisibilityTreeEventHandler | ReportingTreeEventHandler> | undefined;
36
43
  //# sourceMappingURL=UseVisibilityTreeState.d.ts.map
@@ -8,13 +8,14 @@ exports.useVisibilityTreeState = void 0;
8
8
  const react_1 = require("react");
9
9
  const presentation_components_1 = require("@itwin/presentation-components");
10
10
  const VisibilityTreeEventHandler_1 = require("../VisibilityTreeEventHandler");
11
+ const ReportingTreeEventHandler_1 = require("./ReportingTreeEventHandler");
11
12
  /**
12
13
  * Custom hook for creating visibility tree component state.
13
14
  *
14
15
  * @returns `undefined` on first render cycle. On all other render cycles state is initialized and valid object is returned.
15
16
  * @beta
16
17
  */
17
- function useVisibilityTreeState({ imodel, ruleset, filterInfo, onFilterChange, visibilityHandler, selectionPredicate, eventHandler, ...props }) {
18
+ function useVisibilityTreeState({ imodel, ruleset, filterInfo, onFilterChange, visibilityHandler, selectionPredicate, eventHandler, reportUsage, ...props }) {
18
19
  const eventHandlerFactory = (0, react_1.useCallback)((params) => {
19
20
  if (!visibilityHandler) {
20
21
  return undefined;
@@ -24,8 +25,9 @@ function useVisibilityTreeState({ imodel, ruleset, filterInfo, onFilterChange, v
24
25
  visibilityHandler,
25
26
  selectionPredicate,
26
27
  };
27
- return eventHandler ? eventHandler(eventHandlerProps) : new VisibilityTreeEventHandler_1.VisibilityTreeEventHandler(eventHandlerProps);
28
- }, [visibilityHandler, selectionPredicate, eventHandler]);
28
+ const handler = eventHandler ? eventHandler(eventHandlerProps) : new VisibilityTreeEventHandler_1.VisibilityTreeEventHandler(eventHandlerProps);
29
+ return reportUsage ? new ReportingTreeEventHandler_1.ReportingTreeEventHandler({ eventHandler: handler, reportUsage, nodeLoader: eventHandlerProps.nodeLoader }) : handler;
30
+ }, [visibilityHandler, selectionPredicate, eventHandler, reportUsage]);
29
31
  const treeState = (0, presentation_components_1.usePresentationTreeState)({
30
32
  ...props,
31
33
  imodel,
@@ -1 +1 @@
1
- {"version":3,"file":"UseVisibilityTreeState.js","sourceRoot":"","sources":["../../../../../src/components/trees/common/UseVisibilityTreeState.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAEhG,iCAA+C;AAC/C,4EAA0E;AAC1E,8EAA2E;AA+B3E;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,EACrC,MAAM,EACN,OAAO,EACP,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,GAAG,KAAK,EACoB;IAC5B,MAAM,mBAAmB,GAAG,IAAA,mBAAW,EACrC,CAAC,MAAyC,EAAE,EAAE;QAC5C,IAAI,CAAC,iBAAiB,EAAE;YACtB,OAAO,SAAS,CAAC;SAClB;QAED,MAAM,iBAAiB,GAAqC;YAC1D,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,iBAAiB;YACjB,kBAAkB;SACnB,CAAC;QAEF,OAAO,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,uDAA0B,CAAC,iBAAiB,CAAC,CAAC;IAC5G,CAAC,EACD,CAAC,iBAAiB,EAAE,kBAAkB,EAAE,YAAY,CAAC,CACtD,CAAC;IAEF,MAAM,SAAS,GAAG,IAAA,kDAAwB,EAAC;QACzC,GAAG,KAAK;QACR,MAAM;QACN,OAAO;QACP,mBAAmB;QACnB,eAAe,EAAE,UAAU,EAAE,MAAM;YACjC,CAAC,CAAC;gBACE,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,gBAAgB,EAAE,UAAU,EAAE,gBAAgB;aAC/C;YACH,CAAC,CAAC,SAAS;KACd,CAAC,CAAC;IAEH,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,cAAc,IAAI,cAAc,CAAC,SAAS,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC;IAC3H,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,CAAC,CAAC,CAAC;IAE7G,OAAO,SAAS,CAAC;AACnB,CAAC;AA7CD,wDA6CC","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 } from \"react\";\nimport { usePresentationTreeState } from \"@itwin/presentation-components\";\nimport { VisibilityTreeEventHandler } from \"../VisibilityTreeEventHandler\";\n\nimport type { IModelConnection } from \"@itwin/core-frontend\";\nimport type { Ruleset } from \"@itwin/presentation-common\";\nimport type { IFilteredPresentationTreeDataProvider, PresentationTreeEventHandlerProps, UsePresentationTreeStateProps } from \"@itwin/presentation-components\";\nimport type { IVisibilityHandler, VisibilityTreeEventHandlerParams, VisibilityTreeSelectionPredicate } from \"../VisibilityTreeEventHandler\";\nimport type { VisibilityTreeFilterInfo } from \"./Types\";\n\n/**\n * Props for [[useVisibilityTreeState]] hook.\n * @beta\n */\nexport interface UseVisibilityTreeStateProps extends Omit<UsePresentationTreeStateProps<VisibilityTreeEventHandler>, \"rulesetOrId\"> {\n /** iModel to pull data from. */\n imodel: IModelConnection;\n /** Presentation rules to use when pulling data from iModel. */\n ruleset: Ruleset;\n /** Visibility handler that will be used to determine tree node visibility or change it. */\n visibilityHandler?: IVisibilityHandler;\n /** Info about filter that should be applied on tree. */\n filterInfo?: VisibilityTreeFilterInfo;\n /** Callback that is invoked when filter is applied, changed or removed. */\n onFilterChange?: (filteredDataProvider?: IFilteredPresentationTreeDataProvider, matchesCount?: number) => void;\n /** Callback that is used to determine if node can be selected. If not provided all nodes are selectable. */\n selectionPredicate?: VisibilityTreeSelectionPredicate;\n /** Factory for custom `VisibilityTreeEventHandler`. Defaults to `VisibilityTreeEventHandler`. */\n eventHandler?: (props: VisibilityTreeEventHandlerParams) => VisibilityTreeEventHandler;\n /** The limit for how many items should be loaded for a single hierarchy level. */\n hierarchyLevelSizeLimit?: number;\n}\n\n/**\n * Custom hook for creating visibility tree component state.\n *\n * @returns `undefined` on first render cycle. On all other render cycles state is initialized and valid object is returned.\n * @beta\n */\nexport function useVisibilityTreeState({\n imodel,\n ruleset,\n filterInfo,\n onFilterChange,\n visibilityHandler,\n selectionPredicate,\n eventHandler,\n ...props\n}: UseVisibilityTreeStateProps) {\n const eventHandlerFactory = useCallback(\n (params: PresentationTreeEventHandlerProps) => {\n if (!visibilityHandler) {\n return undefined;\n }\n\n const eventHandlerProps: VisibilityTreeEventHandlerParams = {\n nodeLoader: params.nodeLoader,\n visibilityHandler,\n selectionPredicate,\n };\n\n return eventHandler ? eventHandler(eventHandlerProps) : new VisibilityTreeEventHandler(eventHandlerProps);\n },\n [visibilityHandler, selectionPredicate, eventHandler],\n );\n\n const treeState = usePresentationTreeState({\n ...props,\n imodel,\n ruleset,\n eventHandlerFactory,\n filteringParams: filterInfo?.filter\n ? {\n filter: filterInfo.filter,\n activeMatchIndex: filterInfo?.activeMatchIndex,\n }\n : undefined,\n });\n\n useEffect(() => {\n onFilterChange && onFilterChange(treeState?.filteringResult?.filteredProvider, treeState?.filteringResult?.matchesCount);\n }, [treeState?.filteringResult?.matchesCount, treeState?.filteringResult?.filteredProvider, onFilterChange]);\n\n return treeState;\n}\n"]}
1
+ {"version":3,"file":"UseVisibilityTreeState.js","sourceRoot":"","sources":["../../../../../src/components/trees/common/UseVisibilityTreeState.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAEhG,iCAA+C;AAC/C,4EAA0E;AAC1E,8EAA2E;AAC3E,2EAAwE;AAiCxE;;;;;GAKG;AACH,SAAgB,sBAAsB,CAAC,EACrC,MAAM,EACN,OAAO,EACP,UAAU,EACV,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,GAAG,KAAK,EACoB;IAC5B,MAAM,mBAAmB,GAAG,IAAA,mBAAW,EACrC,CAAC,MAAyC,EAAE,EAAE;QAC5C,IAAI,CAAC,iBAAiB,EAAE;YACtB,OAAO,SAAS,CAAC;SAClB;QAED,MAAM,iBAAiB,GAAqC;YAC1D,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,iBAAiB;YACjB,kBAAkB;SACnB,CAAC;QAEF,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,uDAA0B,CAAC,iBAAiB,CAAC,CAAC;QACnH,OAAO,WAAW,CAAC,CAAC,CAAC,IAAI,qDAAyB,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IACjJ,CAAC,EACD,CAAC,iBAAiB,EAAE,kBAAkB,EAAE,YAAY,EAAE,WAAW,CAAC,CACnE,CAAC;IAEF,MAAM,SAAS,GAAG,IAAA,kDAAwB,EAAC;QACzC,GAAG,KAAK;QACR,MAAM;QACN,OAAO;QACP,mBAAmB;QACnB,eAAe,EAAE,UAAU,EAAE,MAAM;YACjC,CAAC,CAAC;gBACE,MAAM,EAAE,UAAU,CAAC,MAAM;gBACzB,gBAAgB,EAAE,UAAU,EAAE,gBAAgB;aAC/C;YACH,CAAC,CAAC,SAAS;KACd,CAAC,CAAC;IAEH,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,cAAc,IAAI,cAAc,CAAC,SAAS,EAAE,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC;IAC3H,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,CAAC,CAAC,CAAC;IAE7G,OAAO,SAAS,CAAC;AACnB,CAAC;AA/CD,wDA+CC","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 } from \"react\";\nimport { usePresentationTreeState } from \"@itwin/presentation-components\";\nimport { VisibilityTreeEventHandler } from \"../VisibilityTreeEventHandler\";\nimport { ReportingTreeEventHandler } from \"./ReportingTreeEventHandler\";\n\nimport type { IModelConnection } from \"@itwin/core-frontend\";\nimport type { Ruleset } from \"@itwin/presentation-common\";\nimport type { IFilteredPresentationTreeDataProvider, PresentationTreeEventHandlerProps, UsePresentationTreeStateProps } from \"@itwin/presentation-components\";\nimport type { IVisibilityHandler, VisibilityTreeEventHandlerParams, VisibilityTreeSelectionPredicate } from \"../VisibilityTreeEventHandler\";\nimport type { VisibilityTreeFilterInfo } from \"./Types\";\nimport type { UsageTrackedFeatures } from \"./UseFeatureReporting\";\n/**\n * Props for [[useVisibilityTreeState]] hook.\n * @beta\n */\nexport interface UseVisibilityTreeStateProps extends Omit<UsePresentationTreeStateProps<VisibilityTreeEventHandler>, \"rulesetOrId\"> {\n /** iModel to pull data from. */\n imodel: IModelConnection;\n /** Presentation rules to use when pulling data from iModel. */\n ruleset: Ruleset;\n /** Visibility handler that will be used to determine tree node visibility or change it. */\n visibilityHandler?: IVisibilityHandler;\n /** Info about filter that should be applied on tree. */\n filterInfo?: VisibilityTreeFilterInfo;\n /** Callback that is invoked when filter is applied, changed or removed. */\n onFilterChange?: (filteredDataProvider?: IFilteredPresentationTreeDataProvider, matchesCount?: number) => void;\n /** Callback that is used to determine if node can be selected. If not provided all nodes are selectable. */\n selectionPredicate?: VisibilityTreeSelectionPredicate;\n /** Factory for custom `VisibilityTreeEventHandler`. Defaults to `VisibilityTreeEventHandler`. */\n eventHandler?: (props: VisibilityTreeEventHandlerParams) => VisibilityTreeEventHandler;\n /** The limit for how many items should be loaded for a single hierarchy level. */\n hierarchyLevelSizeLimit?: number;\n /** Callback called when a feature is used. */\n reportUsage?: (props: { featureId?: UsageTrackedFeatures; reportInteraction: boolean }) => void;\n}\n\n/**\n * Custom hook for creating visibility tree component state.\n *\n * @returns `undefined` on first render cycle. On all other render cycles state is initialized and valid object is returned.\n * @beta\n */\nexport function useVisibilityTreeState({\n imodel,\n ruleset,\n filterInfo,\n onFilterChange,\n visibilityHandler,\n selectionPredicate,\n eventHandler,\n reportUsage,\n ...props\n}: UseVisibilityTreeStateProps) {\n const eventHandlerFactory = useCallback(\n (params: PresentationTreeEventHandlerProps) => {\n if (!visibilityHandler) {\n return undefined;\n }\n\n const eventHandlerProps: VisibilityTreeEventHandlerParams = {\n nodeLoader: params.nodeLoader,\n visibilityHandler,\n selectionPredicate,\n };\n\n const handler = eventHandler ? eventHandler(eventHandlerProps) : new VisibilityTreeEventHandler(eventHandlerProps);\n return reportUsage ? new ReportingTreeEventHandler({ eventHandler: handler, reportUsage, nodeLoader: eventHandlerProps.nodeLoader }) : handler;\n },\n [visibilityHandler, selectionPredicate, eventHandler, reportUsage],\n );\n\n const treeState = usePresentationTreeState({\n ...props,\n imodel,\n ruleset,\n eventHandlerFactory,\n filteringParams: filterInfo?.filter\n ? {\n filter: filterInfo.filter,\n activeMatchIndex: filterInfo?.activeMatchIndex,\n }\n : undefined,\n });\n\n useEffect(() => {\n onFilterChange && onFilterChange(treeState?.filteringResult?.filteredProvider, treeState?.filteringResult?.matchesCount);\n }, [treeState?.filteringResult?.matchesCount, treeState?.filteringResult?.filteredProvider, onFilterChange]);\n\n return treeState;\n}\n"]}
@@ -24,6 +24,12 @@ export interface ExternalSourcesTreeProps extends BaseTreeProps {
24
24
  * @beta
25
25
  */
26
26
  onPerformanceMeasured?: (featureId: string, elapsedTime: number) => void;
27
+ /**
28
+ * Callback that is invoked when a tracked feature is used.
29
+ * @param featureId ID of the feature.
30
+ * @beta
31
+ */
32
+ onFeatureUsed?: (feature: string) => void;
27
33
  }
28
34
  /**
29
35
  * Tree which displays a hierarchy of ExternalSources and their elements.