@itwin/tree-widget-react 2.2.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -2
- package/README.md +26 -0
- package/lib/cjs/components/SelectableTree.d.ts +2 -0
- package/lib/cjs/components/SelectableTree.js +1 -0
- package/lib/cjs/components/SelectableTree.js.map +1 -1
- package/lib/cjs/components/TreeSelector.d.ts +1 -0
- package/lib/cjs/components/TreeSelector.js +1 -1
- package/lib/cjs/components/TreeSelector.js.map +1 -1
- package/lib/cjs/components/trees/models-tree/ModelsTree.js +2 -3
- package/lib/cjs/components/trees/models-tree/ModelsTree.js.map +1 -1
- package/lib/cjs/components/trees/models-tree/ModelsVisibilityHandler.d.ts +1 -0
- package/lib/cjs/components/trees/models-tree/ModelsVisibilityHandler.js +48 -15
- package/lib/cjs/components/trees/models-tree/ModelsVisibilityHandler.js.map +1 -1
- package/lib/cjs/components/trees/models-tree/Utils.js +0 -22
- package/lib/cjs/components/trees/models-tree/Utils.js.map +1 -1
- package/lib/esm/components/SelectableTree.d.ts +2 -0
- package/lib/esm/components/SelectableTree.js +1 -0
- package/lib/esm/components/SelectableTree.js.map +1 -1
- package/lib/esm/components/TreeSelector.d.ts +1 -0
- package/lib/esm/components/TreeSelector.js +1 -1
- package/lib/esm/components/TreeSelector.js.map +1 -1
- package/lib/esm/components/trees/models-tree/ModelsTree.js +2 -3
- package/lib/esm/components/trees/models-tree/ModelsTree.js.map +1 -1
- package/lib/esm/components/trees/models-tree/ModelsVisibilityHandler.d.ts +1 -0
- package/lib/esm/components/trees/models-tree/ModelsVisibilityHandler.js +48 -15
- package/lib/esm/components/trees/models-tree/ModelsVisibilityHandler.js.map +1 -1
- package/lib/esm/components/trees/models-tree/Utils.js +0 -22
- package/lib/esm/components/trees/models-tree/Utils.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,32 @@
|
|
|
1
1
|
# Change Log - @itwin/tree-widget-react
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Wed, 22 May 2024 16:03:32 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## 2.3.1
|
|
8
|
+
|
|
9
|
+
Wed, 22 May 2024 16:03:32 GMT
|
|
10
|
+
|
|
11
|
+
### Patches
|
|
12
|
+
|
|
13
|
+
- Fixed newly inserted subject node visibility not changing ([#838](https://github.com/iTwin/viewer-components-react/pull/838))
|
|
14
|
+
|
|
15
|
+
## 2.3.0
|
|
16
|
+
|
|
17
|
+
Tue, 21 May 2024 13:26:36 GMT
|
|
18
|
+
|
|
19
|
+
### Minor changes
|
|
20
|
+
|
|
21
|
+
- Added support for custom start icons in `TreeSelector`. ([#830](https://github.com/iTwin/viewer-components-react/pull/830))
|
|
22
|
+
|
|
23
|
+
### Patches
|
|
24
|
+
|
|
25
|
+
- Fixed `ModelsTree` not changing visibility for child elements. ([#828](https://github.com/iTwin/viewer-components-react/pull/828))
|
|
26
|
+
|
|
7
27
|
## 2.2.0
|
|
8
28
|
|
|
9
|
-
Mon, 29 Apr 2024 14:
|
|
29
|
+
Mon, 29 Apr 2024 14:59:26 GMT
|
|
10
30
|
|
|
11
31
|
### Minor changes
|
|
12
32
|
|
package/README.md
CHANGED
|
@@ -282,3 +282,29 @@ return (
|
|
|
282
282
|
/>
|
|
283
283
|
);
|
|
284
284
|
```
|
|
285
|
+
|
|
286
|
+
## Tree selector icons
|
|
287
|
+
|
|
288
|
+
Provided trees to `TreeWidgetUiItemsProvider` can define a `startIcon` property that will be shown next to the tree label in tree selector.
|
|
289
|
+
|
|
290
|
+
Example:
|
|
291
|
+
|
|
292
|
+
```ts
|
|
293
|
+
import { UiItemsManager } from "@itwin/appui-react";
|
|
294
|
+
import { TreeWidgetUiItemsProvider, ModelsTreeComponent } from "@itwin/tree-widget-react";
|
|
295
|
+
import { SvgTechnicalPreviewMiniBw } from "@itwin/itwinui-icons-react";
|
|
296
|
+
...
|
|
297
|
+
UiItemsManager.register(
|
|
298
|
+
new TreeWidgetUiItemsProvider({
|
|
299
|
+
defaultPanelLocation: StagePanelLocation.Left,
|
|
300
|
+
defaultPanelSection: StagePanelSection.End,
|
|
301
|
+
defaultTreeWidgetPriority: 1000,
|
|
302
|
+
trees: [{
|
|
303
|
+
id: ModelsTreeComponent.id,
|
|
304
|
+
getLabel: ModelsTreeComponent.getLabel,
|
|
305
|
+
render: (props) => <ModelsTreeComponent { ...props } />,
|
|
306
|
+
startIcon: <SvgTechnicalPreviewMiniBw />,
|
|
307
|
+
}];
|
|
308
|
+
})
|
|
309
|
+
);
|
|
310
|
+
```
|
|
@@ -26,6 +26,8 @@ export interface TreeDefinition {
|
|
|
26
26
|
* If callback is `undefined` tree is shown for all iModel connections.
|
|
27
27
|
*/
|
|
28
28
|
shouldShow?: (imodel: IModelConnection) => Promise<boolean>;
|
|
29
|
+
/** Icon to render before tree label in tree selector */
|
|
30
|
+
startIcon?: React.ReactNode;
|
|
29
31
|
}
|
|
30
32
|
/**
|
|
31
33
|
* Props for [[SelectableTree]]
|
|
@@ -56,6 +56,7 @@ async function getActiveTrees(treeDefinitions, imodel) {
|
|
|
56
56
|
id: treeDef.id,
|
|
57
57
|
label: treeDef.getLabel(),
|
|
58
58
|
render: treeDef.render,
|
|
59
|
+
startIcon: treeDef.startIcon,
|
|
59
60
|
};
|
|
60
61
|
};
|
|
61
62
|
return (await Promise.all(treeDefinitions.map(handleDefinition))).filter((tree) => tree !== undefined);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectableTree.js","sourceRoot":"","sources":["../../../src/components/SelectableTree.tsx"],"names":[],"mappings":";;;;AAAA;;;gGAGgG;AAEhG,iCAA+B;AAC/B,iCAA4C;AAC5C,oDAA+D;AAC/D,kDAAiD;AACjD,wDAAsD;AACtD,8CAA2C;AAC3C,iDAA8C;
|
|
1
|
+
{"version":3,"file":"SelectableTree.js","sourceRoot":"","sources":["../../../src/components/SelectableTree.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 \"./SelectableTree.scss\";\nimport { useEffect, useState } from \"react\";\nimport { useActiveIModelConnection } from \"@itwin/appui-react\";\nimport { FillCentered } from \"@itwin/core-react\";\nimport { ProgressLinear } from \"@itwin/itwinui-react\";\nimport { TreeWidget } from \"../TreeWidget\";\nimport { TreeSelector } from \"./TreeSelector\";\n\nimport type { PropsWithChildren } from \"react\";\nimport type { IModelConnection } from \"@itwin/core-frontend\";\nimport type { TreeContentDefinition, TreeSelectorProps } from \"./TreeSelector\";\n/**\n * Props for rendering trees\n * @public\n */\nexport interface TreeRenderProps {\n density?: \"enlarged\" | \"default\";\n onPerformanceMeasured?: (featureId: string, elapsedTime: number) => void;\n onFeatureUsed?: (feature: string) => void;\n}\n\n/**\n * Definition of a tree component displayed in [[SelectableTree]]\n * @public\n */\nexport interface TreeDefinition {\n /** Id of the tree */\n id: string;\n /** Callback that is used to get tree label */\n getLabel: () => string;\n /** Callback that is used to render tree component */\n render: (props: TreeRenderProps) => React.ReactNode;\n /**\n * Callback that is used to determine if tree should be shown for current active iModel connection.\n * If callback is `undefined` tree is shown for all iModel connections.\n */\n shouldShow?: (imodel: IModelConnection) => Promise<boolean>;\n /** Icon to render before tree label in tree selector */\n startIcon?: React.ReactNode;\n}\n\n/**\n * Props for [[SelectableTree]]\n * @public\n */\nexport interface SelectableTreeProps {\n trees: TreeDefinition[];\n density?: \"enlarged\" | \"default\";\n onPerformanceMeasured?: (feature: string, elapsedTime: number) => void;\n onFeatureUsed?: (feature: string) => void;\n}\n\n/**\n * A component that renders a tree (combo box) selector and the selected tree component.\n * @public\n */\nexport function SelectableTree(props: SelectableTreeProps) {\n const imodel = useActiveIModelConnection();\n\n if (!imodel) {\n return null;\n }\n\n return <SelectableTreeContent {...props} imodel={imodel} />;\n}\n\nfunction SelectableTreeContent(props: SelectableTreeProps & { imodel: IModelConnection }) {\n const { trees: treeDefinitions, imodel } = props;\n const trees = useActiveTrees(treeDefinitions, imodel);\n\n return (\n <div className=\"tree-widget-selectable-tree\">\n <TreeSelector\n {...getTreeSelectorProps(trees)}\n density={props.density}\n onPerformanceMeasured={props.onPerformanceMeasured}\n onFeatureUsed={props.onFeatureUsed}\n />\n </div>\n );\n}\n\nfunction useActiveTrees(treeDefinitions: TreeDefinition[], imodel: IModelConnection) {\n const [trees, setTrees] = useState<TreeContentDefinition[]>();\n\n useEffect(() => {\n let disposed = false;\n void (async () => {\n const visibleTrees = await getActiveTrees(treeDefinitions, imodel);\n // istanbul ignore else\n if (!disposed) {\n setTrees(visibleTrees);\n }\n })();\n\n return () => {\n disposed = true;\n };\n }, [treeDefinitions, imodel]);\n\n return trees;\n}\n\nasync function getActiveTrees(treeDefinitions: TreeDefinition[], imodel: IModelConnection): Promise<TreeContentDefinition[]> {\n const handleDefinition = async (treeDef: TreeDefinition) => {\n if (treeDef.shouldShow !== undefined && !(await treeDef.shouldShow(imodel))) {\n return undefined;\n }\n return {\n id: treeDef.id,\n label: treeDef.getLabel(),\n render: treeDef.render,\n startIcon: treeDef.startIcon,\n };\n };\n\n return (await Promise.all(treeDefinitions.map(handleDefinition))).filter((tree) => tree !== undefined) as TreeContentDefinition[];\n}\n\nfunction getTreeSelectorProps(trees?: TreeContentDefinition[]): TreeSelectorProps {\n if (trees === undefined) {\n return {\n defaultSelectedContentId: \"loading\",\n trees: [\n {\n id: \"loading\",\n label: \"\",\n render: () => (\n <Delayed>\n <ProgressLinear indeterminate={true} />\n </Delayed>\n ),\n },\n ],\n };\n }\n\n if (trees.length === 0) {\n return {\n defaultSelectedContentId: \"no-trees\",\n trees: [\n {\n id: \"no-trees\",\n label: \"\",\n render: () => <FillCentered>{TreeWidget.translate(\"noTrees\")}</FillCentered>,\n },\n ],\n };\n }\n\n return {\n defaultSelectedContentId: trees[0].id,\n trees,\n };\n}\n\nfunction Delayed({ delay = 200, children }: PropsWithChildren<{ delay?: number }>) {\n const [show, setShow] = useState(false);\n\n useEffect(() => {\n const id = setTimeout(() => {\n setShow(true);\n }, delay);\n return () => {\n clearTimeout(id);\n };\n }, [delay]);\n\n if (!show) {\n return null;\n }\n\n return <>{children}</>;\n}\n"]}
|
|
@@ -19,7 +19,7 @@ function TreeSelector(props) {
|
|
|
19
19
|
const selectedContent = props.trees.find((c) => c.id === selectedContentId) ?? props.trees[0];
|
|
20
20
|
const isEnlarged = props.density === "enlarged";
|
|
21
21
|
const options = (0, react_1.useMemo)(() => {
|
|
22
|
-
return props.trees.map((c) => ({ label: c.label, value: c.id }));
|
|
22
|
+
return props.trees.map((c) => ({ label: c.label, value: c.id, startIcon: c.startIcon }));
|
|
23
23
|
}, [props.trees]);
|
|
24
24
|
return ((0, jsx_runtime_1.jsxs)("div", { className: "presentation-components-tree-selector-content", children: [(0, jsx_runtime_1.jsx)("div", { className: "presentation-components-tree-selector-content-header", children: options.length > 0 && ((0, jsx_runtime_1.jsx)(itwinui_react_1.Select, { options: options, value: selectedContent.id, size: isEnlarged ? "large" : "small", onChange: (treeId) => {
|
|
25
25
|
props.onFeatureUsed?.(`choose-${treeId}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeSelector.js","sourceRoot":"","sources":["../../../src/components/TreeSelector.tsx"],"names":[],"mappings":";;;;AAAA;;;gGAGgG;AAEhG,+BAA6B;AAC7B,iCAA0C;AAC1C,wDAAwD;
|
|
1
|
+
{"version":3,"file":"TreeSelector.js","sourceRoot":"","sources":["../../../src/components/TreeSelector.tsx"],"names":[],"mappings":";;;;AAAA;;;gGAGgG;AAEhG,+BAA6B;AAC7B,iCAA0C;AAC1C,wDAAwD;AA4BxD;;;;GAIG;AACH,SAAgB,YAAY,CAAC,KAAwB;IACnD,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC3F,MAAM,eAAe,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,iBAAiB,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9F,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,KAAK,UAAU,CAAC;IAEhD,MAAM,OAAO,GAAG,IAAA,eAAO,EAAC,GAAG,EAAE;QAC3B,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAA2B,CAAC;IACrH,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAElB,OAAO,CACL,iCAAK,SAAS,EAAC,+CAA+C,aAC5D,gCAAK,SAAS,EAAC,sDAAsD,YAClE,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CACrB,uBAAC,sBAAM,IACL,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,eAAe,CAAC,EAAE,EACzB,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EACpC,QAAQ,EAAE,CAAC,MAAc,EAAE,EAAE;wBAC3B,KAAK,CAAC,aAAa,EAAE,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC;wBAC1C,oBAAoB,CAAC,MAAM,CAAC,CAAC;oBAC/B,CAAC,EACD,YAAY,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CACnC,uBAAC,wBAAQ,OAAK,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,YAC3F,MAAM,CAAC,KAAK,GACJ,CACZ,GACD,CACH,GACG,EACN,gCAAK,SAAS,EAAC,uDAAuD,YACnE,eAAe,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,qBAAqB,EAAE,KAAK,CAAC,qBAAqB,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,GACxI,IACF,CACP,CAAC;AACJ,CAAC;AAlCD,oCAkCC","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 \"./TreeSelector.scss\";\nimport { useMemo, useState } from \"react\";\nimport { MenuItem, Select } from \"@itwin/itwinui-react\";\n\nimport type { SelectOption } from \"@itwin/itwinui-react\";\nimport type { TreeRenderProps } from \"./SelectableTree\";\n\n/**\n * A definition for trees displayed in [[TreeSelector]]\n * @internal\n */\nexport interface TreeContentDefinition {\n id: string;\n label: string;\n render: (props: TreeRenderProps) => React.ReactNode;\n startIcon?: React.ReactNode;\n}\n\n/**\n * Props for [[TreeSelector]]\n * @internal\n */\nexport interface TreeSelectorProps {\n defaultSelectedContentId: string;\n trees: TreeContentDefinition[];\n density?: \"enlarged\" | \"default\";\n onPerformanceMeasured?: (feature: string, elapsedTime: number) => void;\n onFeatureUsed?: (feature: string) => void;\n}\n\n/**\n * A component that accepts a list of trees and renders a select box at the top,\n * allowing to choose which of the provided tree components should be rendered at the bottom.\n * @internal\n */\nexport function TreeSelector(props: TreeSelectorProps) {\n const [selectedContentId, setSelectedContentId] = useState(props.defaultSelectedContentId);\n const selectedContent = props.trees.find((c) => c.id === selectedContentId) ?? props.trees[0];\n const isEnlarged = props.density === \"enlarged\";\n\n const options = useMemo(() => {\n return props.trees.map((c) => ({ label: c.label, value: c.id, startIcon: c.startIcon })) as SelectOption<string>[];\n }, [props.trees]);\n\n return (\n <div className=\"presentation-components-tree-selector-content\">\n <div className=\"presentation-components-tree-selector-content-header\">\n {options.length > 0 && (\n <Select\n options={options}\n value={selectedContent.id}\n size={isEnlarged ? \"large\" : \"small\"}\n onChange={(treeId: string) => {\n props.onFeatureUsed?.(`choose-${treeId}`);\n setSelectedContentId(treeId);\n }}\n itemRenderer={(option, itemProps) => (\n <MenuItem {...option} isSelected={itemProps.isSelected} size={isEnlarged ? \"large\" : \"default\"}>\n {option.label}\n </MenuItem>\n )}\n />\n )}\n </div>\n <div className=\"presentation-components-tree-selector-content-wrapper\">\n {selectedContent?.render({ density: props.density, onPerformanceMeasured: props.onPerformanceMeasured, onFeatureUsed: props.onFeatureUsed })}\n </div>\n </div>\n );\n}\n"]}
|
|
@@ -133,7 +133,7 @@ function useTreeState({ modelsVisibilityHandler, activeView, selectionPredicate,
|
|
|
133
133
|
onHierarchyLimitExceeded: () => reportUsage({ featureId: "hierarchy-level-size-limit-hit", reportInteraction: false }),
|
|
134
134
|
});
|
|
135
135
|
}
|
|
136
|
-
function useVisibilityHandler(rulesetId, iModel, activeView, visibilityHandler
|
|
136
|
+
function useVisibilityHandler(rulesetId, iModel, activeView, visibilityHandler) {
|
|
137
137
|
const subjectModelIdsCache = (0, react_1.useMemo)(() => new ModelsVisibilityHandler_1.SubjectModelIdsCache(iModel), [iModel]);
|
|
138
138
|
const [state, setState] = (0, react_1.useState)();
|
|
139
139
|
(0, react_1.useEffect)(() => {
|
|
@@ -143,7 +143,6 @@ function useVisibilityHandler(rulesetId, iModel, activeView, visibilityHandler,
|
|
|
143
143
|
const visibilityHandlerProps = {
|
|
144
144
|
rulesetId,
|
|
145
145
|
viewport: activeView,
|
|
146
|
-
hierarchyAutoUpdateEnabled,
|
|
147
146
|
subjectModelIdsCache,
|
|
148
147
|
};
|
|
149
148
|
const handler = visibilityHandler ? visibilityHandler(visibilityHandlerProps) : new ModelsVisibilityHandler_1.ModelsVisibilityHandler(visibilityHandlerProps);
|
|
@@ -151,7 +150,7 @@ function useVisibilityHandler(rulesetId, iModel, activeView, visibilityHandler,
|
|
|
151
150
|
return () => {
|
|
152
151
|
handler.dispose();
|
|
153
152
|
};
|
|
154
|
-
}, [rulesetId, activeView,
|
|
153
|
+
}, [rulesetId, activeView, subjectModelIdsCache, visibilityHandler]);
|
|
155
154
|
return visibilityHandler && typeof visibilityHandler !== "function" ? visibilityHandler : state;
|
|
156
155
|
}
|
|
157
156
|
const customizeTreeNodeItem = (0, Utils_1.combineTreeNodeItemCustomizations)([Utils_1.addCustomTreeNodeItemLabelRenderer, Utils_1.addTreeNodeItemCheckbox, Utils_2.addModelsTreeNodeItemIcons]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ModelsTree.js","sourceRoot":"","sources":["../../../../../src/components/trees/models-tree/ModelsTree.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, useMemo, useRef, useState } from \"react\";\nimport { SelectionMode } from \"@itwin/components-react\";\nimport { isPresentationTreeNodeItem, PresentationTree } from \"@itwin/presentation-components\";\nimport { TreeWidget } from \"../../../TreeWidget\";\nimport { FilterableTreeRenderer } from \"../common/TreeRenderer\";\nimport { ClassGroupingOption } from \"../common/Types\";\nimport { useFeatureReporting } from \"../common/UseFeatureReporting\";\nimport { usePerformanceReporting } from \"../common/UsePerformanceReporting\";\nimport { useVisibilityTreeState } from \"../common/UseVisibilityTreeState\";\nimport { addCustomTreeNodeItemLabelRenderer, addTreeNodeItemCheckbox, combineTreeNodeItemCustomizations } from \"../common/Utils\";\nimport { createVisibilityTreeRenderer, FilterableVisibilityTreeNodeRenderer, VisibilityTreeNoFilteredData } from \"../VisibilityTreeRenderer\";\nimport { ModelsTreeComponent } from \"./ModelsTreeComponent\";\nimport { ModelsTreeEventHandler } from \"./ModelsTreeEventHandler\";\nimport { ModelsVisibilityHandler, SubjectModelIdsCache } from \"./ModelsVisibilityHandler\";\nimport { addModelsTreeNodeItemIcons, createRuleset, createSearchRuleset } from \"./Utils\";\n\nimport type { FilterableTreeNodeRendererProps } from \"../common/TreeRenderer\";\nimport type { UsageTrackedFeatures } from \"../common/UseFeatureReporting\";\nimport type { VisibilityTreeEventHandlerParams } from \"../VisibilityTreeEventHandler\";\nimport type { Ruleset, SingleSchemaClassSpecification } from \"@itwin/presentation-common\";\nimport type { IModelConnection, Viewport } from \"@itwin/core-frontend\";\nimport type { TreeNodeItem } from \"@itwin/components-react\";\nimport type { IFilteredPresentationTreeDataProvider } from \"@itwin/presentation-components\";\nimport type { BaseFilterableTreeProps, HierarchyLevelConfig } from \"../common/Types\";\nimport type { ModelsTreeSelectionPredicate, ModelsVisibilityHandlerProps } from \"./ModelsVisibilityHandler\";\nconst PAGING_SIZE = 20;\n\n/**\n * Props for configuring the hierarchy in [[ModelsTree]].\n * @public\n */\nexport interface ModelsTreeHierarchyConfiguration {\n /** Should the tree group displayed element nodes by class. Defaults to `ClassGroupingOption.No`. */\n enableElementsClassGrouping?: ClassGroupingOption;\n /**\n * Defines the `bis.GeometricElement3d` sub-class that should be used to load element nodes.\n * Defaults to `bis.GeometricElement3d`. It's expected for the given class to derive from it.\n */\n elementClassSpecification?: SingleSchemaClassSpecification;\n /** Should the tree show models without elements. */\n showEmptyModels?: boolean;\n}\n\n/**\n * Props for [[ModelsTree]] component.\n * @public\n */\nexport interface ModelsTreeProps extends BaseFilterableTreeProps {\n /**\n * Predicate which indicates whether node can be selected or no\n */\n selectionPredicate?: ModelsTreeSelectionPredicate;\n /**\n * Active view used to determine and control visibility\n */\n activeView: Viewport;\n /**\n * Configuration options for the hierarchy loaded in the component.\n */\n hierarchyConfig?: ModelsTreeHierarchyConfiguration;\n /**\n * Auto-update the hierarchy when data in the iModel changes.\n * @alpha\n * @deprecated in 2.0.1. It does not have any effect, auto update is always on.\n */\n enableHierarchyAutoUpdate?: boolean;\n /**\n * Custom visibility handler.\n */\n modelsVisibilityHandler?: ModelsVisibilityHandler | ((props: ModelsVisibilityHandlerProps) => ModelsVisibilityHandler);\n /**\n * Props for configuring hierarchy level.\n * @beta\n */\n hierarchyLevelConfig?: HierarchyLevelConfig;\n /**\n * Reports performance of a feature.\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 * A tree component that shows a subject - model - category - element\n * hierarchy along with checkboxes that represent and allow changing\n * the display of those instances.\n * @public\n */\nexport function ModelsTree(props: ModelsTreeProps) {\n const { hierarchyLevelConfig, density, height, width, selectionMode, onFeatureUsed } = props;\n const { reportUsage } = useFeatureReporting({ treeIdentifier: ModelsTreeComponent.id, onFeatureUsed });\n const state = useModelsTreeState({ ...props, reportUsage });\n\n const baseRendererProps = {\n reportUsage,\n contextMenuItems: props.contextMenuItems,\n nodeLabelRenderer: props.nodeLabelRenderer,\n density: props.density,\n nodeRendererProps: {\n iconsEnabled: true,\n descriptionEnabled: false,\n levelOffset: 10,\n disableRootNodeCollapse: true,\n onVisibilityToggled: () => reportUsage({ featureId: \"visibility-change\", reportInteraction: true }),\n },\n };\n\n // istanbul ignore next\n const noFilteredDataRenderer = useCallback(() => {\n return (\n <VisibilityTreeNoFilteredData title={TreeWidget.translate(\"modelTree.noModelFound\")} message={TreeWidget.translate(\"modelTree.noMatchingModelNames\")} />\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 state={state}\n selectionMode={selectionMode || SelectionMode.None}\n treeRenderer={\n hierarchyLevelConfig?.isFilteringEnabled\n ? (rendererProps) => (\n <FilterableTreeRenderer\n {...rendererProps}\n {...baseRendererProps}\n nodeLoader={state.nodeLoader}\n nodeRenderer={(nodeProps) => <ModelsTreeNodeRenderer {...nodeProps} density={density} />}\n />\n )\n : createVisibilityTreeRenderer(baseRendererProps)\n }\n noDataRenderer={isFilterApplied ? noFilteredDataRenderer : undefined}\n width={width}\n height={height}\n />\n {overlay}\n </div>\n );\n}\n\ninterface ModelsTreeNodeRendererProps extends FilterableTreeNodeRendererProps {\n density?: \"default\" | \"enlarged\";\n}\n\nfunction ModelsTreeNodeRenderer(props: ModelsTreeNodeRendererProps) {\n return (\n <FilterableVisibilityTreeNodeRenderer\n {...props}\n iconsEnabled={true}\n descriptionEnabled={false}\n levelOffset={10}\n disableRootNodeCollapse={true}\n isEnlarged={props.density === \"enlarged\"}\n onVisibilityToggled={() => props.reportUsage?.({ featureId: \"visibility-change\", reportInteraction: true })}\n />\n );\n}\n\ninterface UseModelsTreeStateProps extends Omit<ModelsTreeProps, \"onFeatureUsed\"> {\n reportUsage: (props: { featureId?: UsageTrackedFeatures; reportInteraction: boolean }) => void;\n}\n\nfunction useModelsTreeState({ filterInfo, onFilterApplied, ...props }: UseModelsTreeStateProps) {\n const rulesets = {\n general: useMemo(\n () =>\n createRuleset({\n enableElementsClassGrouping: !!props.hierarchyConfig?.enableElementsClassGrouping,\n elementClassSpecification: props.hierarchyConfig?.elementClassSpecification,\n showEmptyModels: props.hierarchyConfig?.showEmptyModels,\n }),\n [props.hierarchyConfig?.enableElementsClassGrouping, props.hierarchyConfig?.elementClassSpecification, props.hierarchyConfig?.showEmptyModels],\n ),\n search: useMemo(\n () =>\n createSearchRuleset({\n elementClassSpecification: props.hierarchyConfig?.elementClassSpecification,\n showEmptyModels: props.hierarchyConfig?.showEmptyModels,\n }),\n [props.hierarchyConfig?.elementClassSpecification, props.hierarchyConfig?.showEmptyModels],\n ),\n };\n\n const treeState = useTreeState({\n ...props,\n ruleset: rulesets.general,\n });\n\n const filteredTreeState = useTreeState({\n ...props,\n ruleset: rulesets.search,\n filterInfo,\n onFilterApplied,\n });\n\n return filterInfo?.filter ? filteredTreeState : treeState;\n}\n\ninterface UseTreeProps extends Omit<ModelsTreeProps, \"onFeatureUsed\"> {\n ruleset: Ruleset;\n reportUsage: (props: { featureId?: UsageTrackedFeatures; reportInteraction: boolean }) => void;\n}\n\nfunction useTreeState({\n modelsVisibilityHandler,\n activeView,\n selectionPredicate,\n hierarchyConfig,\n iModel,\n ruleset,\n filterInfo,\n onFilterApplied,\n hierarchyLevelConfig,\n onPerformanceMeasured,\n reportUsage,\n}: UseTreeProps) {\n const visibilityHandler = useVisibilityHandler(ruleset.id, iModel, activeView, modelsVisibilityHandler);\n const selectionPredicateRef = useRef(selectionPredicate);\n useEffect(() => {\n selectionPredicateRef.current = selectionPredicate;\n }, [selectionPredicate]);\n\n const onFilterChange = useCallback(\n (dataProvider?: IFilteredPresentationTreeDataProvider, matchesCount?: number) => {\n if (dataProvider && matchesCount !== undefined) {\n reportUsage({ featureId: \"filtering\", reportInteraction: false });\n onFilterApplied?.(dataProvider, matchesCount);\n }\n\n if (visibilityHandler) {\n visibilityHandler.setFilteredDataProvider(dataProvider);\n }\n },\n [onFilterApplied, reportUsage, visibilityHandler],\n );\n\n const { onNodeLoaded } = usePerformanceReporting({\n treeIdentifier: ModelsTreeComponent.id,\n onPerformanceMeasured,\n });\n\n const eventHandlerFactory = useCallback(\n (handlerProps: VisibilityTreeEventHandlerParams) => {\n return new ModelsTreeEventHandler({ ...handlerProps, reportUsage });\n },\n [reportUsage],\n );\n\n return useVisibilityTreeState({\n imodel: iModel,\n ruleset,\n pagingSize: PAGING_SIZE,\n appendChildrenCountForGroupingNodes: hierarchyConfig?.enableElementsClassGrouping === ClassGroupingOption.YesWithCounts,\n enableHierarchyAutoUpdate: true,\n customizeTreeNodeItem,\n visibilityHandler,\n filterInfo,\n onFilterChange,\n selectionPredicate: useCallback(\n (node: TreeNodeItem) =>\n !selectionPredicateRef.current || !isPresentationTreeNodeItem(node)\n ? true\n : selectionPredicateRef.current(node.key, ModelsVisibilityHandler.getNodeType(node)),\n [],\n ),\n eventHandler: eventHandlerFactory,\n hierarchyLevelSizeLimit: hierarchyLevelConfig?.sizeLimit,\n onNodeLoaded: filterInfo ? undefined : onNodeLoaded,\n reportUsage: filterInfo ? undefined : reportUsage,\n onHierarchyLimitExceeded: () => reportUsage({ featureId: \"hierarchy-level-size-limit-hit\", reportInteraction: false }),\n });\n}\n\nfunction useVisibilityHandler(\n rulesetId: string,\n iModel: IModelConnection,\n activeView: Viewport,\n visibilityHandler?: ModelsVisibilityHandler | ((props: ModelsVisibilityHandlerProps) => ModelsVisibilityHandler),\n hierarchyAutoUpdateEnabled?: boolean,\n) {\n const subjectModelIdsCache = useMemo(() => new SubjectModelIdsCache(iModel), [iModel]);\n const [state, setState] = useState<ModelsVisibilityHandler>();\n\n useEffect(() => {\n if (visibilityHandler && typeof visibilityHandler !== \"function\") {\n return;\n }\n\n const visibilityHandlerProps: ModelsVisibilityHandlerProps = {\n rulesetId,\n viewport: activeView,\n hierarchyAutoUpdateEnabled,\n subjectModelIdsCache,\n };\n\n const handler = visibilityHandler ? visibilityHandler(visibilityHandlerProps) : new ModelsVisibilityHandler(visibilityHandlerProps);\n setState(handler);\n return () => {\n handler.dispose();\n };\n }, [rulesetId, activeView, hierarchyAutoUpdateEnabled, subjectModelIdsCache, visibilityHandler]);\n\n return visibilityHandler && typeof visibilityHandler !== \"function\" ? visibilityHandler : state;\n}\n\nconst customizeTreeNodeItem = combineTreeNodeItemCustomizations([addCustomTreeNodeItemLabelRenderer, addTreeNodeItemCheckbox, addModelsTreeNodeItemIcons]);\n"]}
|
|
1
|
+
{"version":3,"file":"ModelsTree.js","sourceRoot":"","sources":["../../../../../src/components/trees/models-tree/ModelsTree.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, useMemo, useRef, useState } from \"react\";\nimport { SelectionMode } from \"@itwin/components-react\";\nimport { isPresentationTreeNodeItem, PresentationTree } from \"@itwin/presentation-components\";\nimport { TreeWidget } from \"../../../TreeWidget\";\nimport { FilterableTreeRenderer } from \"../common/TreeRenderer\";\nimport { ClassGroupingOption } from \"../common/Types\";\nimport { useFeatureReporting } from \"../common/UseFeatureReporting\";\nimport { usePerformanceReporting } from \"../common/UsePerformanceReporting\";\nimport { useVisibilityTreeState } from \"../common/UseVisibilityTreeState\";\nimport { addCustomTreeNodeItemLabelRenderer, addTreeNodeItemCheckbox, combineTreeNodeItemCustomizations } from \"../common/Utils\";\nimport { createVisibilityTreeRenderer, FilterableVisibilityTreeNodeRenderer, VisibilityTreeNoFilteredData } from \"../VisibilityTreeRenderer\";\nimport { ModelsTreeComponent } from \"./ModelsTreeComponent\";\nimport { ModelsTreeEventHandler } from \"./ModelsTreeEventHandler\";\nimport { ModelsVisibilityHandler, SubjectModelIdsCache } from \"./ModelsVisibilityHandler\";\nimport { addModelsTreeNodeItemIcons, createRuleset, createSearchRuleset } from \"./Utils\";\n\nimport type { FilterableTreeNodeRendererProps } from \"../common/TreeRenderer\";\nimport type { UsageTrackedFeatures } from \"../common/UseFeatureReporting\";\nimport type { VisibilityTreeEventHandlerParams } from \"../VisibilityTreeEventHandler\";\nimport type { Ruleset, SingleSchemaClassSpecification } from \"@itwin/presentation-common\";\nimport type { IModelConnection, Viewport } from \"@itwin/core-frontend\";\nimport type { TreeNodeItem } from \"@itwin/components-react\";\nimport type { IFilteredPresentationTreeDataProvider } from \"@itwin/presentation-components\";\nimport type { BaseFilterableTreeProps, HierarchyLevelConfig } from \"../common/Types\";\nimport type { ModelsTreeSelectionPredicate, ModelsVisibilityHandlerProps } from \"./ModelsVisibilityHandler\";\nconst PAGING_SIZE = 20;\n\n/**\n * Props for configuring the hierarchy in [[ModelsTree]].\n * @public\n */\nexport interface ModelsTreeHierarchyConfiguration {\n /** Should the tree group displayed element nodes by class. Defaults to `ClassGroupingOption.No`. */\n enableElementsClassGrouping?: ClassGroupingOption;\n /**\n * Defines the `bis.GeometricElement3d` sub-class that should be used to load element nodes.\n * Defaults to `bis.GeometricElement3d`. It's expected for the given class to derive from it.\n */\n elementClassSpecification?: SingleSchemaClassSpecification;\n /** Should the tree show models without elements. */\n showEmptyModels?: boolean;\n}\n\n/**\n * Props for [[ModelsTree]] component.\n * @public\n */\nexport interface ModelsTreeProps extends BaseFilterableTreeProps {\n /**\n * Predicate which indicates whether node can be selected or no\n */\n selectionPredicate?: ModelsTreeSelectionPredicate;\n /**\n * Active view used to determine and control visibility\n */\n activeView: Viewport;\n /**\n * Configuration options for the hierarchy loaded in the component.\n */\n hierarchyConfig?: ModelsTreeHierarchyConfiguration;\n /**\n * Auto-update the hierarchy when data in the iModel changes.\n * @alpha\n * @deprecated in 2.0.1. It does not have any effect, auto update is always on.\n */\n enableHierarchyAutoUpdate?: boolean;\n /**\n * Custom visibility handler.\n */\n modelsVisibilityHandler?: ModelsVisibilityHandler | ((props: ModelsVisibilityHandlerProps) => ModelsVisibilityHandler);\n /**\n * Props for configuring hierarchy level.\n * @beta\n */\n hierarchyLevelConfig?: HierarchyLevelConfig;\n /**\n * Reports performance of a feature.\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 * A tree component that shows a subject - model - category - element\n * hierarchy along with checkboxes that represent and allow changing\n * the display of those instances.\n * @public\n */\nexport function ModelsTree(props: ModelsTreeProps) {\n const { hierarchyLevelConfig, density, height, width, selectionMode, onFeatureUsed } = props;\n const { reportUsage } = useFeatureReporting({ treeIdentifier: ModelsTreeComponent.id, onFeatureUsed });\n const state = useModelsTreeState({ ...props, reportUsage });\n\n const baseRendererProps = {\n reportUsage,\n contextMenuItems: props.contextMenuItems,\n nodeLabelRenderer: props.nodeLabelRenderer,\n density: props.density,\n nodeRendererProps: {\n iconsEnabled: true,\n descriptionEnabled: false,\n levelOffset: 10,\n disableRootNodeCollapse: true,\n onVisibilityToggled: () => reportUsage({ featureId: \"visibility-change\", reportInteraction: true }),\n },\n };\n\n // istanbul ignore next\n const noFilteredDataRenderer = useCallback(() => {\n return (\n <VisibilityTreeNoFilteredData title={TreeWidget.translate(\"modelTree.noModelFound\")} message={TreeWidget.translate(\"modelTree.noMatchingModelNames\")} />\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 state={state}\n selectionMode={selectionMode || SelectionMode.None}\n treeRenderer={\n hierarchyLevelConfig?.isFilteringEnabled\n ? (rendererProps) => (\n <FilterableTreeRenderer\n {...rendererProps}\n {...baseRendererProps}\n nodeLoader={state.nodeLoader}\n nodeRenderer={(nodeProps) => <ModelsTreeNodeRenderer {...nodeProps} density={density} />}\n />\n )\n : createVisibilityTreeRenderer(baseRendererProps)\n }\n noDataRenderer={isFilterApplied ? noFilteredDataRenderer : undefined}\n width={width}\n height={height}\n />\n {overlay}\n </div>\n );\n}\n\ninterface ModelsTreeNodeRendererProps extends FilterableTreeNodeRendererProps {\n density?: \"default\" | \"enlarged\";\n}\n\nfunction ModelsTreeNodeRenderer(props: ModelsTreeNodeRendererProps) {\n return (\n <FilterableVisibilityTreeNodeRenderer\n {...props}\n iconsEnabled={true}\n descriptionEnabled={false}\n levelOffset={10}\n disableRootNodeCollapse={true}\n isEnlarged={props.density === \"enlarged\"}\n onVisibilityToggled={() => props.reportUsage?.({ featureId: \"visibility-change\", reportInteraction: true })}\n />\n );\n}\n\ninterface UseModelsTreeStateProps extends Omit<ModelsTreeProps, \"onFeatureUsed\"> {\n reportUsage: (props: { featureId?: UsageTrackedFeatures; reportInteraction: boolean }) => void;\n}\n\nfunction useModelsTreeState({ filterInfo, onFilterApplied, ...props }: UseModelsTreeStateProps) {\n const rulesets = {\n general: useMemo(\n () =>\n createRuleset({\n enableElementsClassGrouping: !!props.hierarchyConfig?.enableElementsClassGrouping,\n elementClassSpecification: props.hierarchyConfig?.elementClassSpecification,\n showEmptyModels: props.hierarchyConfig?.showEmptyModels,\n }),\n [props.hierarchyConfig?.enableElementsClassGrouping, props.hierarchyConfig?.elementClassSpecification, props.hierarchyConfig?.showEmptyModels],\n ),\n search: useMemo(\n () =>\n createSearchRuleset({\n elementClassSpecification: props.hierarchyConfig?.elementClassSpecification,\n showEmptyModels: props.hierarchyConfig?.showEmptyModels,\n }),\n [props.hierarchyConfig?.elementClassSpecification, props.hierarchyConfig?.showEmptyModels],\n ),\n };\n\n const treeState = useTreeState({\n ...props,\n ruleset: rulesets.general,\n });\n\n const filteredTreeState = useTreeState({\n ...props,\n ruleset: rulesets.search,\n filterInfo,\n onFilterApplied,\n });\n\n return filterInfo?.filter ? filteredTreeState : treeState;\n}\n\ninterface UseTreeProps extends Omit<ModelsTreeProps, \"onFeatureUsed\"> {\n ruleset: Ruleset;\n reportUsage: (props: { featureId?: UsageTrackedFeatures; reportInteraction: boolean }) => void;\n}\n\nfunction useTreeState({\n modelsVisibilityHandler,\n activeView,\n selectionPredicate,\n hierarchyConfig,\n iModel,\n ruleset,\n filterInfo,\n onFilterApplied,\n hierarchyLevelConfig,\n onPerformanceMeasured,\n reportUsage,\n}: UseTreeProps) {\n const visibilityHandler = useVisibilityHandler(ruleset.id, iModel, activeView, modelsVisibilityHandler);\n const selectionPredicateRef = useRef(selectionPredicate);\n useEffect(() => {\n selectionPredicateRef.current = selectionPredicate;\n }, [selectionPredicate]);\n\n const onFilterChange = useCallback(\n (dataProvider?: IFilteredPresentationTreeDataProvider, matchesCount?: number) => {\n if (dataProvider && matchesCount !== undefined) {\n reportUsage({ featureId: \"filtering\", reportInteraction: false });\n onFilterApplied?.(dataProvider, matchesCount);\n }\n\n if (visibilityHandler) {\n visibilityHandler.setFilteredDataProvider(dataProvider);\n }\n },\n [onFilterApplied, reportUsage, visibilityHandler],\n );\n\n const { onNodeLoaded } = usePerformanceReporting({\n treeIdentifier: ModelsTreeComponent.id,\n onPerformanceMeasured,\n });\n\n const eventHandlerFactory = useCallback(\n (handlerProps: VisibilityTreeEventHandlerParams) => {\n return new ModelsTreeEventHandler({ ...handlerProps, reportUsage });\n },\n [reportUsage],\n );\n\n return useVisibilityTreeState({\n imodel: iModel,\n ruleset,\n pagingSize: PAGING_SIZE,\n appendChildrenCountForGroupingNodes: hierarchyConfig?.enableElementsClassGrouping === ClassGroupingOption.YesWithCounts,\n enableHierarchyAutoUpdate: true,\n customizeTreeNodeItem,\n visibilityHandler,\n filterInfo,\n onFilterChange,\n selectionPredicate: useCallback(\n (node: TreeNodeItem) =>\n !selectionPredicateRef.current || !isPresentationTreeNodeItem(node)\n ? true\n : selectionPredicateRef.current(node.key, ModelsVisibilityHandler.getNodeType(node)),\n [],\n ),\n eventHandler: eventHandlerFactory,\n hierarchyLevelSizeLimit: hierarchyLevelConfig?.sizeLimit,\n onNodeLoaded: filterInfo ? undefined : onNodeLoaded,\n reportUsage: filterInfo ? undefined : reportUsage,\n onHierarchyLimitExceeded: () => reportUsage({ featureId: \"hierarchy-level-size-limit-hit\", reportInteraction: false }),\n });\n}\n\nfunction useVisibilityHandler(\n rulesetId: string,\n iModel: IModelConnection,\n activeView: Viewport,\n visibilityHandler?: ModelsVisibilityHandler | ((props: ModelsVisibilityHandlerProps) => ModelsVisibilityHandler),\n) {\n const subjectModelIdsCache = useMemo(() => new SubjectModelIdsCache(iModel), [iModel]);\n const [state, setState] = useState<ModelsVisibilityHandler>();\n\n useEffect(() => {\n if (visibilityHandler && typeof visibilityHandler !== \"function\") {\n return;\n }\n\n const visibilityHandlerProps: ModelsVisibilityHandlerProps = {\n rulesetId,\n viewport: activeView,\n subjectModelIdsCache,\n };\n\n const handler = visibilityHandler ? visibilityHandler(visibilityHandlerProps) : new ModelsVisibilityHandler(visibilityHandlerProps);\n setState(handler);\n return () => {\n handler.dispose();\n };\n }, [rulesetId, activeView, subjectModelIdsCache, visibilityHandler]);\n\n return visibilityHandler && typeof visibilityHandler !== \"function\" ? visibilityHandler : state;\n}\n\nconst customizeTreeNodeItem = combineTreeNodeItemCustomizations([addCustomTreeNodeItemLabelRenderer, addTreeNodeItemCheckbox, addModelsTreeNodeItemIcons]);\n"]}
|
|
@@ -49,15 +49,19 @@ class ModelsVisibilityHandler {
|
|
|
49
49
|
};
|
|
50
50
|
this._props = props;
|
|
51
51
|
this._subjectModelIdsCache = props.subjectModelIdsCache ?? new SubjectModelIdsCache(this._props.viewport.iModel);
|
|
52
|
-
this._elementIdsCache = new ElementIdsCache(this._props.viewport.iModel
|
|
52
|
+
this._elementIdsCache = new ElementIdsCache(this._props.viewport.iModel);
|
|
53
53
|
this._listeners.push(this._props.viewport.onViewedCategoriesPerModelChanged.addListener(this.onViewChanged));
|
|
54
54
|
this._listeners.push(this._props.viewport.onViewedCategoriesChanged.addListener(this.onViewChanged));
|
|
55
55
|
this._listeners.push(this._props.viewport.onViewedModelsChanged.addListener(this.onViewChanged));
|
|
56
56
|
this._listeners.push(this._props.viewport.onAlwaysDrawnChanged.addListener(this.onElementAlwaysDrawnChanged));
|
|
57
57
|
this._listeners.push(this._props.viewport.onNeverDrawnChanged.addListener(this.onElementNeverDrawnChanged));
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
this._listeners.push(
|
|
59
|
+
// eslint-disable-next-line @itwin/no-internal
|
|
60
|
+
presentation_frontend_1.Presentation.presentation.onIModelHierarchyChanged.addListener(
|
|
61
|
+
/* istanbul ignore next */ () => {
|
|
62
|
+
this._elementIdsCache.clear();
|
|
63
|
+
this._subjectModelIdsCache.clear();
|
|
64
|
+
}));
|
|
61
65
|
}
|
|
62
66
|
dispose() {
|
|
63
67
|
this._listeners.forEach((remove) => remove());
|
|
@@ -469,6 +473,12 @@ class SubjectModelIdsCache {
|
|
|
469
473
|
childSubjectIds.forEach((cs) => this.appendSubjectModelsRecursively(modelIds, cs));
|
|
470
474
|
}
|
|
471
475
|
}
|
|
476
|
+
// istanbul ignore next
|
|
477
|
+
clear() {
|
|
478
|
+
this._subjectsHierarchy?.clear();
|
|
479
|
+
this._subjectModels?.clear();
|
|
480
|
+
this._init = undefined;
|
|
481
|
+
}
|
|
472
482
|
async getSubjectModelIds(subjectId) {
|
|
473
483
|
await this.initCache();
|
|
474
484
|
const modelIds = new Array();
|
|
@@ -479,9 +489,8 @@ class SubjectModelIdsCache {
|
|
|
479
489
|
exports.SubjectModelIdsCache = SubjectModelIdsCache;
|
|
480
490
|
// istanbul ignore next
|
|
481
491
|
class ElementIdsCache {
|
|
482
|
-
constructor(_imodel
|
|
492
|
+
constructor(_imodel) {
|
|
483
493
|
this._imodel = _imodel;
|
|
484
|
-
this._rulesetId = _rulesetId;
|
|
485
494
|
this._assemblyElementIdsCache = new Map();
|
|
486
495
|
this._groupedElementIdsCache = new Map();
|
|
487
496
|
}
|
|
@@ -494,7 +503,7 @@ class ElementIdsCache {
|
|
|
494
503
|
if (ids) {
|
|
495
504
|
return ids;
|
|
496
505
|
}
|
|
497
|
-
const container = createAssemblyElementIdsContainer(this._imodel,
|
|
506
|
+
const container = createAssemblyElementIdsContainer(this._imodel, assemblyId);
|
|
498
507
|
this._assemblyElementIdsCache.set(assemblyId, container);
|
|
499
508
|
return container;
|
|
500
509
|
}
|
|
@@ -504,17 +513,41 @@ class ElementIdsCache {
|
|
|
504
513
|
if (ids) {
|
|
505
514
|
return ids;
|
|
506
515
|
}
|
|
507
|
-
const info = await createGroupedElementsInfo(this._imodel,
|
|
516
|
+
const info = await createGroupedElementsInfo(this._imodel, groupingNodeKey);
|
|
508
517
|
this._groupedElementIdsCache.set(keyString, info);
|
|
509
518
|
return info;
|
|
510
519
|
}
|
|
511
520
|
}
|
|
512
521
|
// istanbul ignore next
|
|
513
|
-
async function* createInstanceIdsGenerator(imodel,
|
|
522
|
+
async function* createInstanceIdsGenerator(imodel, inputKeys) {
|
|
514
523
|
const res = await presentation_frontend_1.Presentation.presentation.getContentInstanceKeys({
|
|
515
524
|
imodel,
|
|
516
|
-
rulesetOrId:
|
|
517
|
-
|
|
525
|
+
rulesetOrId: {
|
|
526
|
+
id: "ModelsTree/AssemblyElements",
|
|
527
|
+
rules: [
|
|
528
|
+
{
|
|
529
|
+
ruleType: "Content",
|
|
530
|
+
specifications: [
|
|
531
|
+
{
|
|
532
|
+
specType: "SelectedNodeInstances",
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
specType: "ContentRelatedInstances",
|
|
536
|
+
relationshipPaths: [
|
|
537
|
+
{
|
|
538
|
+
relationship: {
|
|
539
|
+
schemaName: "BisCore",
|
|
540
|
+
className: "ElementOwnsChildElements",
|
|
541
|
+
},
|
|
542
|
+
direction: "Forward",
|
|
543
|
+
count: "*",
|
|
544
|
+
},
|
|
545
|
+
],
|
|
546
|
+
},
|
|
547
|
+
],
|
|
548
|
+
},
|
|
549
|
+
],
|
|
550
|
+
},
|
|
518
551
|
keys: new presentation_common_1.KeySet(inputKeys),
|
|
519
552
|
});
|
|
520
553
|
for await (const key of res.items()) {
|
|
@@ -522,12 +555,12 @@ async function* createInstanceIdsGenerator(imodel, rulesetId, displayType, input
|
|
|
522
555
|
}
|
|
523
556
|
}
|
|
524
557
|
// istanbul ignore next
|
|
525
|
-
function createAssemblyElementIdsContainer(imodel,
|
|
526
|
-
return new Utils_1.CachingElementIdsContainer(createInstanceIdsGenerator(imodel,
|
|
558
|
+
function createAssemblyElementIdsContainer(imodel, assemblyId) {
|
|
559
|
+
return new Utils_1.CachingElementIdsContainer(createInstanceIdsGenerator(imodel, [{ className: "BisCore:Element", id: assemblyId }]));
|
|
527
560
|
}
|
|
528
561
|
// istanbul ignore next
|
|
529
|
-
async function createGroupedElementsInfo(imodel,
|
|
530
|
-
const groupedElementIdsContainer = new Utils_1.CachingElementIdsContainer(createInstanceIdsGenerator(imodel,
|
|
562
|
+
async function createGroupedElementsInfo(imodel, groupingNodeKey) {
|
|
563
|
+
const groupedElementIdsContainer = new Utils_1.CachingElementIdsContainer(createInstanceIdsGenerator(imodel, [groupingNodeKey]));
|
|
531
564
|
const elementId = await groupedElementIdsContainer.getElementIds().next();
|
|
532
565
|
if (elementId.done) {
|
|
533
566
|
throw new Error("Invalid grouping node key");
|