@itwin/tree-widget-react 4.0.0-alpha.10 → 4.0.0-alpha.12
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 +25 -1
- package/README.md +145 -84
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTree.d.ts +2 -2
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTree.js +2 -2
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeComponent.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeComponent.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.js +20 -20
- package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.js +11 -11
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/FilteredTree.js +2 -2
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/FilteredTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseFilteredPaths.js +3 -3
- package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseFilteredPaths.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTree.d.ts +12 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTree.js +14 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTree.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeComponent.d.ts +23 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeComponent.js +47 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeComponent.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeDefinition.d.ts +28 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeDefinition.js +275 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeDefinition.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeIcon.d.ts +6 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeIcon.js +33 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/ClassificationsTreeIcon.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/UseClassificationsTree.d.ts +23 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/UseClassificationsTree.js +52 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/UseClassificationsTree.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeIdsCache.d.ts +39 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeIdsCache.js +282 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeIdsCache.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeNode.d.ts +19 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeNode.js +32 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeNode.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeVisibilityHandler.d.ts +19 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeVisibilityHandler.js +488 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/ClassificationsTreeVisibilityHandler.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/UseIdsCache.d.ts +8 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/UseIdsCache.js +45 -0
- package/lib/esm/tree-widget-react/components/trees/classifications-tree/internal/UseIdsCache.js.map +1 -0
- package/lib/esm/tree-widget-react/components/trees/common/UseNodeHighlighting.d.ts +2 -2
- package/lib/esm/tree-widget-react/components/trees/common/UseNodeHighlighting.js +0 -4
- package/lib/esm/tree-widget-react/components/trees/common/UseNodeHighlighting.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/BaseTreeRenderer.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/BaseTreeRenderer.js +1 -2
- package/lib/esm/tree-widget-react/components/trees/common/components/BaseTreeRenderer.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/Tree.d.ts +3 -11
- package/lib/esm/tree-widget-react/components/trees/common/components/Tree.js +30 -28
- package/lib/esm/tree-widget-react/components/trees/common/components/Tree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeVisibilityButton.js +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeVisibilityButton.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/UseVisibilityButtonHandler.d.ts +2 -2
- package/lib/esm/tree-widget-react/components/trees/common/components/UseVisibilityButtonHandler.js +0 -4
- package/lib/esm/tree-widget-react/components/trees/common/components/UseVisibilityButtonHandler.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTree.js +3 -4
- package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTreeRenderer.js +0 -1
- package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTreeRenderer.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/internal/ClassNameDefinitions.d.ts +26 -16
- package/lib/esm/tree-widget-react/components/trees/common/internal/ClassNameDefinitions.js +26 -16
- package/lib/esm/tree-widget-react/components/trees/common/internal/ClassNameDefinitions.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/internal/ModelCategoryElementsCountCache.d.ts +2 -2
- package/lib/esm/tree-widget-react/components/trees/common/internal/ModelCategoryElementsCountCache.js +25 -21
- package/lib/esm/tree-widget-react/components/trees/common/internal/ModelCategoryElementsCountCache.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/internal/Tooltip.js +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/internal/Tooltip.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/internal/UseHierarchiesLocalization.d.ts +2 -2
- package/lib/esm/tree-widget-react/components/trees/common/internal/UseHierarchiesLocalization.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/internal/UseIModelAccess.d.ts +1 -3
- package/lib/esm/tree-widget-react/components/trees/common/internal/UseIModelAccess.js +5 -6
- package/lib/esm/tree-widget-react/components/trees/common/internal/UseIModelAccess.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/internal/Utils.js +3 -3
- package/lib/esm/tree-widget-react/components/trees/common/internal/Utils.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityUtils.js +1 -6
- package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityUtils.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTree.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeComponent.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeComponent.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTree.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeComponent.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeComponent.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.js +22 -22
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/internal/IModelContentTreeIdsCache.js +7 -7
- package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/internal/IModelContentTreeIdsCache.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/index.d.ts +7 -4
- package/lib/esm/tree-widget-react/components/trees/index.js +7 -4
- package/lib/esm/tree-widget-react/components/trees/index.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTree.d.ts +2 -2
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTree.js +2 -2
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeButtons.js +4 -4
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeButtons.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeComponent.d.ts +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeComponent.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.js +35 -35
- package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/UseModelsTree.d.ts +27 -0
- package/lib/esm/tree-widget-react/components/trees/models-tree/UseModelsTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/FilteredTree.js +4 -4
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/FilteredTree.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js +9 -9
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js +2 -2
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js.map +1 -1
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseFilteredPaths.d.ts +3 -0
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseFilteredPaths.js +4 -3
- package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseFilteredPaths.js.map +1 -1
- package/lib/esm/tree-widget-react-internal.d.ts +3 -1
- package/lib/esm/tree-widget-react-internal.js +3 -1
- package/lib/esm/tree-widget-react-internal.js.map +1 -1
- package/lib/public/locales/en/TreeWidget.json +3 -0
- package/package.json +30 -35
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
1
|
# Change Log - @itwin/tree-widget-react
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Fri, 20 Jun 2025 17:05:06 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## 3.10.1
|
|
8
|
+
|
|
9
|
+
Fri, 20 Jun 2025 17:05:06 GMT
|
|
10
|
+
|
|
11
|
+
### Patches
|
|
12
|
+
|
|
13
|
+
- Update itwinjs-core dependencies to v5.0.0 ([#1349](https://github.com/iTwin/viewer-components-react/pull/1349))
|
|
14
|
+
|
|
15
|
+
## 3.10.0
|
|
16
|
+
|
|
17
|
+
Mon, 02 Jun 2025 13:19:21 GMT
|
|
18
|
+
|
|
19
|
+
### Minor changes
|
|
20
|
+
|
|
21
|
+
- `useModelsTree`: The `getFilteredPaths` callback prop now has a `filter` prop, which matches the value of `filter` prop passed to `useModelsTree` hook. This make it more convenient for consumers to filter by instance keys and label at the same time. ([#1335](https://github.com/iTwin/viewer-components-react/pull/1335))
|
|
22
|
+
|
|
23
|
+
## 3.9.0
|
|
24
|
+
|
|
25
|
+
Mon, 19 May 2025 16:58:21 GMT
|
|
26
|
+
|
|
27
|
+
### Minor changes
|
|
28
|
+
|
|
29
|
+
- Add support for iTwin.js v5.0 ([#1326](https://github.com/iTwin/viewer-components-react/pull/1326))
|
|
30
|
+
|
|
7
31
|
## 3.8.0
|
|
8
32
|
|
|
9
33
|
Thu, 15 May 2025 05:33:32 GMT
|
package/README.md
CHANGED
|
@@ -69,8 +69,6 @@ UiItemsManager.register({
|
|
|
69
69
|
getLabel: () => ModelsTreeComponent.getLabel(),
|
|
70
70
|
render: (props) => (
|
|
71
71
|
<ModelsTreeComponent
|
|
72
|
-
// see "Creating schema context" section for example implementation
|
|
73
|
-
getSchemaContext={getSchemaContext}
|
|
74
72
|
// see "Creating unified selection storage" section for example implementation
|
|
75
73
|
selectionStorage={unifiedSelectionStorage}
|
|
76
74
|
/>
|
|
@@ -106,8 +104,6 @@ import { ModelsTreeComponent } from "@itwin/tree-widget-react";
|
|
|
106
104
|
function MyWidget() {
|
|
107
105
|
return (
|
|
108
106
|
<ModelsTreeComponent
|
|
109
|
-
// see "Creating schema context" section for example implementation
|
|
110
|
-
getSchemaContext={getSchemaContext}
|
|
111
107
|
// see "Creating unified selection storage" section for example implementation
|
|
112
108
|
selectionStorage={unifiedSelectionStorage}
|
|
113
109
|
headerButtons={[
|
|
@@ -148,7 +144,6 @@ import { useCallback } from "react";
|
|
|
148
144
|
import { TreeWithHeader, useModelsTree, useModelsTreeButtonProps, VisibilityTree, VisibilityTreeRenderer } from "@itwin/tree-widget-react";
|
|
149
145
|
import type { SelectionStorage } from "@itwin/unified-selection";
|
|
150
146
|
import type { IModelConnection, Viewport } from "@itwin/core-frontend";
|
|
151
|
-
import type { SchemaContext } from "@itwin/ecschema-metadata";
|
|
152
147
|
import type { ComponentPropsWithoutRef } from "react";
|
|
153
148
|
|
|
154
149
|
type VisibilityTreeRendererProps = ComponentPropsWithoutRef<typeof VisibilityTreeRenderer>;
|
|
@@ -169,11 +164,10 @@ function CustomModelsTreeRenderer(props: CustomModelsTreeRendererProps) {
|
|
|
169
164
|
interface CustomModelsTreeProps {
|
|
170
165
|
imodel: IModelConnection;
|
|
171
166
|
viewport: Viewport;
|
|
172
|
-
getSchemaContext: (imodel: IModelConnection) => SchemaContext;
|
|
173
167
|
selectionStorage: SelectionStorage;
|
|
174
168
|
}
|
|
175
169
|
|
|
176
|
-
function CustomModelsTreeComponent({ imodel, viewport,
|
|
170
|
+
function CustomModelsTreeComponent({ imodel, viewport, selectionStorage }: CustomModelsTreeProps) {
|
|
177
171
|
const { buttonProps } = useModelsTreeButtonProps({ imodel, viewport });
|
|
178
172
|
const { modelsTreeProps, rendererProps } = useModelsTree({ activeView: viewport });
|
|
179
173
|
|
|
@@ -186,7 +180,6 @@ function CustomModelsTreeComponent({ imodel, viewport, getSchemaContext, selecti
|
|
|
186
180
|
>
|
|
187
181
|
<VisibilityTree
|
|
188
182
|
{...modelsTreeProps}
|
|
189
|
-
getSchemaContext={getSchemaContext}
|
|
190
183
|
selectionStorage={selectionStorage}
|
|
191
184
|
imodel={imodel}
|
|
192
185
|
treeRenderer={(props) => <CustomModelsTreeRenderer {...props} {...rendererProps} />}
|
|
@@ -198,42 +191,149 @@ function CustomModelsTreeComponent({ imodel, viewport, getSchemaContext, selecti
|
|
|
198
191
|
|
|
199
192
|
#### Displaying a subset of the tree
|
|
200
193
|
|
|
201
|
-
Models tree allows displaying a subset of all nodes by providing a `getFilteredPaths` function
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
236
|
-
|
|
194
|
+
Models tree allows displaying a subset of all nodes by providing a `getFilteredPaths` function. This function receives a helper function called `createInstanceKeyPaths`, which can generate paths from either:
|
|
195
|
+
|
|
196
|
+
- a list of instance keys (`targetItems`)
|
|
197
|
+
- a label string
|
|
198
|
+
|
|
199
|
+
Based on the returned paths, the displayed hierarchy consists only of the targeted nodes, their ancestors, and their children.
|
|
200
|
+
|
|
201
|
+
Use `getFilteredPaths` when you need more control over which nodes are shown. Here are some example use cases:
|
|
202
|
+
|
|
203
|
+
- **Filter by known instance keys**: You already have a list of `InstanceKey` items that should remain in the tree. Pass them as `targetItems` to `createInstanceKeyPaths`.
|
|
204
|
+
<!-- [[include: [TreeWidget.GetFilteredPathsComponentWithTargetItemsExample], tsx]] -->
|
|
205
|
+
<!-- BEGIN EXTRACTION -->
|
|
206
|
+
|
|
207
|
+
```tsx
|
|
208
|
+
type UseModelsTreeProps = Parameters<typeof useModelsTree>[0];
|
|
209
|
+
type GetFilteredPathsType = Exclude<UseModelsTreeProps["getFilteredPaths"], undefined>;
|
|
210
|
+
|
|
211
|
+
function CustomModelsTreeComponentWithTargetItems({
|
|
212
|
+
viewport,
|
|
213
|
+
selectionStorage,
|
|
214
|
+
imodel,
|
|
215
|
+
targetItems,
|
|
216
|
+
}: {
|
|
217
|
+
viewport: Viewport;
|
|
218
|
+
selectionStorage: SelectionStorage;
|
|
219
|
+
imodel: IModelConnection;
|
|
220
|
+
targetItems: InstanceKey[];
|
|
221
|
+
}) {
|
|
222
|
+
const getFilteredPaths = useCallback<GetFilteredPathsType>(
|
|
223
|
+
async ({ createInstanceKeyPaths }) => {
|
|
224
|
+
return createInstanceKeyPaths({
|
|
225
|
+
// list of instance keys representing nodes that should be displayed in the hierarchy
|
|
226
|
+
targetItems,
|
|
227
|
+
});
|
|
228
|
+
},
|
|
229
|
+
[targetItems],
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
const { modelsTreeProps, rendererProps } = useModelsTree({ activeView: viewport, getFilteredPaths });
|
|
233
|
+
|
|
234
|
+
return (
|
|
235
|
+
<VisibilityTree
|
|
236
|
+
{...modelsTreeProps}
|
|
237
|
+
getSchemaContext={getSchemaContext}
|
|
238
|
+
selectionStorage={selectionStorage}
|
|
239
|
+
imodel={imodel}
|
|
240
|
+
treeRenderer={(props) => <VisibilityTreeRenderer {...props} {...rendererProps} />}
|
|
241
|
+
/>
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
<!-- END EXTRACTION -->
|
|
247
|
+
|
|
248
|
+
- **Post-process the paths created `createInstanceKeyPaths`**: Use `filter` string to generate the paths, then apply additional filtering - e.g., remove paths that are too long.
|
|
249
|
+
<!-- [[include: [TreeWidget.GetFilteredPathsComponentWithPostProcessingExample], tsx]] -->
|
|
250
|
+
<!-- BEGIN EXTRACTION -->
|
|
251
|
+
|
|
252
|
+
```tsx
|
|
253
|
+
function CustomModelsTreeComponentWithPostProcessing({
|
|
254
|
+
viewport,
|
|
255
|
+
selectionStorage,
|
|
256
|
+
imodel,
|
|
257
|
+
}: {
|
|
258
|
+
viewport: Viewport;
|
|
259
|
+
selectionStorage: SelectionStorage;
|
|
260
|
+
imodel: IModelConnection;
|
|
261
|
+
}) {
|
|
262
|
+
const getFilteredPaths = useCallback<GetFilteredPathsType>(async ({ createInstanceKeyPaths, filter }) => {
|
|
263
|
+
const defaultPaths = await createInstanceKeyPaths({ label: filter ?? "test" });
|
|
264
|
+
const result = new Array<HierarchyFilteringPath>();
|
|
265
|
+
for (const path of defaultPaths) {
|
|
266
|
+
const normalizedPath = HierarchyFilteringPath.normalize(path);
|
|
267
|
+
if (normalizedPath.path.length < 5) {
|
|
268
|
+
normalizedPath.options = { autoExpand: true };
|
|
269
|
+
result.push(normalizedPath);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return result;
|
|
273
|
+
}, []);
|
|
274
|
+
|
|
275
|
+
const { modelsTreeProps, rendererProps } = useModelsTree({ activeView: viewport, getFilteredPaths });
|
|
276
|
+
|
|
277
|
+
return (
|
|
278
|
+
<VisibilityTree
|
|
279
|
+
{...modelsTreeProps}
|
|
280
|
+
getSchemaContext={getSchemaContext}
|
|
281
|
+
selectionStorage={selectionStorage}
|
|
282
|
+
imodel={imodel}
|
|
283
|
+
treeRenderer={(props) => <VisibilityTreeRenderer {...props} {...rendererProps} />}
|
|
284
|
+
/>
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
<!-- END EXTRACTION -->
|
|
290
|
+
|
|
291
|
+
- **Apply custom logic to generate instance keys**: Generate instance keys using custom implementation. For example: query elements that have specified filter in their user label and provide them as targetItems.
|
|
292
|
+
<!-- [[include: [TreeWidget.GetFilteredPathsComponentWithFilterAndTargetItemsExample], tsx]] -->
|
|
293
|
+
<!-- BEGIN EXTRACTION -->
|
|
294
|
+
```tsx
|
|
295
|
+
function CustomModelsTreeComponentWithFilterAndTargetItems({
|
|
296
|
+
viewport,
|
|
297
|
+
selectionStorage,
|
|
298
|
+
imodel,
|
|
299
|
+
}: {
|
|
300
|
+
viewport: Viewport;
|
|
301
|
+
selectionStorage: SelectionStorage;
|
|
302
|
+
imodel: IModelConnection;
|
|
303
|
+
}) {
|
|
304
|
+
const getFilteredPaths = useCallback<GetFilteredPathsType>(
|
|
305
|
+
async ({ createInstanceKeyPaths, filter }) => {
|
|
306
|
+
const targetItems = new Array<InstanceKey>();
|
|
307
|
+
for await (const row of imodel.createQueryReader(
|
|
308
|
+
`
|
|
309
|
+
SELECT ec_classname(e.ECClassId, 's.c') className, e.ECInstanceId id
|
|
310
|
+
FROM BisCore.Element e
|
|
311
|
+
WHERE UserLabel LIKE '%${filter ?? ""}%'
|
|
312
|
+
`,
|
|
313
|
+
undefined,
|
|
314
|
+
{ rowFormat: QueryRowFormat.UseJsPropertyNames },
|
|
315
|
+
)) {
|
|
316
|
+
targetItems.push({ id: row.id, className: row.className });
|
|
317
|
+
}
|
|
318
|
+
return createInstanceKeyPaths({ targetItems });
|
|
319
|
+
},
|
|
320
|
+
[imodel],
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
const { modelsTreeProps, rendererProps } = useModelsTree({ activeView: viewport, getFilteredPaths, filter: "test" });
|
|
324
|
+
|
|
325
|
+
return (
|
|
326
|
+
<VisibilityTree
|
|
327
|
+
{...modelsTreeProps}
|
|
328
|
+
getSchemaContext={getSchemaContext}
|
|
329
|
+
selectionStorage={selectionStorage}
|
|
330
|
+
imodel={imodel}
|
|
331
|
+
treeRenderer={(props) => <VisibilityTreeRenderer {...props} {...rendererProps} />}
|
|
332
|
+
/>
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
<!-- END EXTRACTION -->
|
|
237
337
|
|
|
238
338
|
### Categories tree
|
|
239
339
|
|
|
@@ -249,8 +349,6 @@ import { CategoriesTreeComponent } from "@itwin/tree-widget-react";
|
|
|
249
349
|
function MyWidget() {
|
|
250
350
|
return (
|
|
251
351
|
<CategoriesTreeComponent
|
|
252
|
-
// see "Creating schema context" section for example implementation
|
|
253
|
-
getSchemaContext={getSchemaContext}
|
|
254
352
|
// see "Creating unified selection storage" section for example implementation
|
|
255
353
|
selectionStorage={unifiedSelectionStorage}
|
|
256
354
|
headerButtons={[(props) => <CategoriesTreeComponent.ShowAllButton {...props} />, (props) => <CategoriesTreeComponent.HideAllButton {...props} />]}
|
|
@@ -278,7 +376,6 @@ Example:
|
|
|
278
376
|
import { TreeWithHeader, useCategoriesTree, useCategoriesTreeButtonProps, VisibilityTree, VisibilityTreeRenderer } from "@itwin/tree-widget-react";
|
|
279
377
|
import type { IModelConnection, Viewport } from "@itwin/core-frontend";
|
|
280
378
|
import type { SelectionStorage } from "@itwin/unified-selection";
|
|
281
|
-
import type { SchemaContext } from "@itwin/ecschema-metadata";
|
|
282
379
|
import type { ComponentPropsWithoutRef } from "react";
|
|
283
380
|
|
|
284
381
|
type VisibilityTreeRendererProps = ComponentPropsWithoutRef<typeof VisibilityTreeRenderer>;
|
|
@@ -302,11 +399,10 @@ function CustomCategoriesTreeRenderer(props: CustomCategoriesTreeRendererProps)
|
|
|
302
399
|
interface CustomCategoriesTreeProps {
|
|
303
400
|
imodel: IModelConnection;
|
|
304
401
|
viewport: Viewport;
|
|
305
|
-
getSchemaContext: (imodel: IModelConnection) => SchemaContext;
|
|
306
402
|
selectionStorage: SelectionStorage;
|
|
307
403
|
}
|
|
308
404
|
|
|
309
|
-
function CustomCategoriesTreeComponent({ imodel, viewport,
|
|
405
|
+
function CustomCategoriesTreeComponent({ imodel, viewport, selectionStorage }: CustomCategoriesTreeProps) {
|
|
310
406
|
const { buttonProps } = useCategoriesTreeButtonProps({ viewport });
|
|
311
407
|
const { categoriesTreeProps, rendererProps } = useCategoriesTree({ activeView: viewport, filter: "" });
|
|
312
408
|
return (
|
|
@@ -318,7 +414,6 @@ function CustomCategoriesTreeComponent({ imodel, viewport, getSchemaContext, sel
|
|
|
318
414
|
>
|
|
319
415
|
<VisibilityTree
|
|
320
416
|
{...categoriesTreeProps}
|
|
321
|
-
getSchemaContext={getSchemaContext}
|
|
322
417
|
selectionStorage={selectionStorage}
|
|
323
418
|
imodel={imodel}
|
|
324
419
|
treeRenderer={(props) => <CustomCategoriesTreeRenderer {...props} {...rendererProps} />}
|
|
@@ -349,8 +444,6 @@ import { IModelContentTreeComponent } from "@itwin/tree-widget-react";
|
|
|
349
444
|
function MyWidget() {
|
|
350
445
|
return (
|
|
351
446
|
<IModelContentTreeComponent
|
|
352
|
-
// see "Creating schema context" section for example implementation
|
|
353
|
-
getSchemaContext={getSchemaContext}
|
|
354
447
|
// see "Creating unified selection storage" section for example implementation
|
|
355
448
|
selectionStorage={unifiedSelectionStorage}
|
|
356
449
|
/>
|
|
@@ -421,7 +514,6 @@ function MyTree({ imodel }: MyTreeProps) {
|
|
|
421
514
|
treeName="MyTree"
|
|
422
515
|
imodel={imodel}
|
|
423
516
|
selectionStorage={unifiedSelectionStorage}
|
|
424
|
-
getSchemaContext={getSchemaContext}
|
|
425
517
|
getHierarchyDefinition={getHierarchyDefinition}
|
|
426
518
|
treeRenderer={(props) => <TreeRenderer {...props} />}
|
|
427
519
|
/>
|
|
@@ -506,7 +598,6 @@ function MyVisibilityTree({ imodel }: MyVisibilityTreeProps) {
|
|
|
506
598
|
treeName="MyVisibilityTree"
|
|
507
599
|
imodel={imodel}
|
|
508
600
|
selectionStorage={unifiedSelectionStorage}
|
|
509
|
-
getSchemaContext={getSchemaContext}
|
|
510
601
|
getHierarchyDefinition={getHierarchyDefinition}
|
|
511
602
|
visibilityHandlerFactory={visibilityHandlerFactory}
|
|
512
603
|
treeRenderer={(props) => <VisibilityTreeRenderer {...props} />}
|
|
@@ -560,34 +651,6 @@ import { Presentation } from "@itwin/presentation-frontend";
|
|
|
560
651
|
await Presentation.initialize({ selection: { selectionStorage: getUnifiedSelectionStorage() } });
|
|
561
652
|
```
|
|
562
653
|
|
|
563
|
-
### Creating schema context
|
|
564
|
-
|
|
565
|
-
All tree components delivered with the package require a [`SchemaContext`](https://www.itwinjs.org/reference/ecschema-metadata/context/schemacontext/) to be able to access iModels metadata.
|
|
566
|
-
|
|
567
|
-
Typically, we want one schema context per iModel per application - this allows schema information to be shared across components, saving memory and time required to access the metadata. Below is an example implementation of `getSchemaContext` function, required by tree components:
|
|
568
|
-
|
|
569
|
-
```tsx
|
|
570
|
-
import { SchemaContext } from "@itwin/ecschema-metadata";
|
|
571
|
-
import { ECSchemaRpcLocater } from "@itwin/ecschema-rpcinterface-common";
|
|
572
|
-
import type { IModelConnection } from "@itwin/core-frontend";
|
|
573
|
-
|
|
574
|
-
const schemaContextCache = new Map<string, SchemaContext>();
|
|
575
|
-
function getSchemaContext(imodel: IModelConnection) {
|
|
576
|
-
const key = imodel.getRpcProps().key;
|
|
577
|
-
let schemaContext = schemaContextCache.get(key);
|
|
578
|
-
if (!schemaContext) {
|
|
579
|
-
const schemaLocater = new ECSchemaRpcLocater(imodel.getRpcProps());
|
|
580
|
-
schemaContext = new SchemaContext();
|
|
581
|
-
schemaContext.addLocater(schemaLocater);
|
|
582
|
-
schemaContextCache.set(key, schemaContext);
|
|
583
|
-
imodel.onClose.addOnce(() => schemaContextCache.delete(key));
|
|
584
|
-
}
|
|
585
|
-
return schemaContext;
|
|
586
|
-
}
|
|
587
|
-
```
|
|
588
|
-
|
|
589
|
-
Note: Using `ECSchemaRpcLocater` requires the application to support [ECSchemaRpcInterface](https://github.com/iTwin/itwinjs-core/blob/111ab9053f4718896de17bdaeb8de037bad281bd/core/ecschema-rpc/common/src/ECSchemaRpcInterface.ts#L14). This means [registering the interface](https://www.itwinjs.org/learning/rpcinterface/#configure-interfaces) and, on the backend, [registering the implementation](https://www.itwinjs.org/learning/rpcinterface/#server-side-configuration) by calling [ECSchemaRpcImpl.register()](https://github.com/iTwin/itwinjs-core/blob/111ab9053f4718896de17bdaeb8de037bad281bd/core/ecschema-rpc/impl/src/ECSchemaRpcImpl.ts#L29).
|
|
590
|
-
|
|
591
654
|
## Telemetry
|
|
592
655
|
|
|
593
656
|
### Performance tracking
|
|
@@ -645,7 +708,6 @@ function MyWidget() {
|
|
|
645
708
|
onFeatureUsed={(feature) => {
|
|
646
709
|
console.log(`TreeWidget [${feature}] used`);
|
|
647
710
|
}}
|
|
648
|
-
getSchemaContext={getSchemaContext}
|
|
649
711
|
selectionStorage={unifiedSelectionStorage}
|
|
650
712
|
/>
|
|
651
713
|
);
|
|
@@ -679,7 +741,6 @@ function MyTree() {
|
|
|
679
741
|
// VisibilityTree will use provided telemetry context to report used features and their performance
|
|
680
742
|
<VisibilityTree
|
|
681
743
|
{...categoriesTreeProps}
|
|
682
|
-
getSchemaContext={getSchemaContext}
|
|
683
744
|
selectionStorage={unifiedSelectionStorage}
|
|
684
745
|
imodel={imodel}
|
|
685
746
|
treeRenderer={(props) => <VisibilityTreeRenderer {...props} {...rendererProps} />}
|
|
@@ -2,11 +2,11 @@ import type { VisibilityTreeRendererProps } from "../common/components/Visibilit
|
|
|
2
2
|
import type { UseCategoriesTreeProps } from "./UseCategoriesTree.js";
|
|
3
3
|
import type { VisibilityTreeProps } from "../common/components/VisibilityTree.js";
|
|
4
4
|
/** @beta */
|
|
5
|
-
export type CategoriesTreeProps = Pick<VisibilityTreeProps, "imodel" | "
|
|
5
|
+
export type CategoriesTreeProps = Pick<VisibilityTreeProps, "imodel" | "selectionStorage" | "selectionMode" | "emptyTreeContent"> & Pick<VisibilityTreeRendererProps, "getActions" | "getDecorations"> & UseCategoriesTreeProps & {
|
|
6
6
|
hierarchyLevelConfig?: {
|
|
7
7
|
sizeLimit?: number;
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
10
|
/** @beta */
|
|
11
|
-
export declare function CategoriesTree({ imodel,
|
|
11
|
+
export declare function CategoriesTree({ imodel, selectionStorage, activeView, filter, hierarchyLevelConfig, selectionMode, onCategoriesFiltered, emptyTreeContent, getDecorations, getActions, hierarchyConfig, }: CategoriesTreeProps): import("react/jsx-runtime").JSX.Element;
|
|
12
12
|
//# sourceMappingURL=CategoriesTree.d.ts.map
|
|
@@ -7,7 +7,7 @@ import { VisibilityTree } from "../common/components/VisibilityTree.js";
|
|
|
7
7
|
import { VisibilityTreeRenderer } from "../common/components/VisibilityTreeRenderer.js";
|
|
8
8
|
import { useCategoriesTree } from "./UseCategoriesTree.js";
|
|
9
9
|
/** @beta */
|
|
10
|
-
export function CategoriesTree({ imodel,
|
|
10
|
+
export function CategoriesTree({ imodel, selectionStorage, activeView, filter, hierarchyLevelConfig, selectionMode, onCategoriesFiltered, emptyTreeContent, getDecorations, getActions, hierarchyConfig, }) {
|
|
11
11
|
const { categoriesTreeProps, rendererProps } = useCategoriesTree({
|
|
12
12
|
filter,
|
|
13
13
|
activeView,
|
|
@@ -15,6 +15,6 @@ export function CategoriesTree({ imodel, getSchemaContext, selectionStorage, act
|
|
|
15
15
|
emptyTreeContent,
|
|
16
16
|
hierarchyConfig,
|
|
17
17
|
});
|
|
18
|
-
return (_jsx(VisibilityTree, { ...categoriesTreeProps, imodel: imodel, selectionStorage: selectionStorage,
|
|
18
|
+
return (_jsx(VisibilityTree, { ...categoriesTreeProps, imodel: imodel, selectionStorage: selectionStorage, hierarchyLevelSizeLimit: hierarchyLevelConfig?.sizeLimit, selectionMode: selectionMode ?? "none", treeRenderer: (treeProps) => (_jsx(VisibilityTreeRenderer, { ...treeProps, ...rendererProps, getActions: getActions, getDecorations: getDecorations ?? rendererProps.getDecorations })) }));
|
|
19
19
|
}
|
|
20
20
|
//# sourceMappingURL=CategoriesTree.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CategoriesTree.js","sourceRoot":"","sources":["../../../../../../src/tree-widget-react/components/trees/categories-tree/CategoriesTree.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAe3D,YAAY;AACZ,MAAM,UAAU,cAAc,CAAC,EAC7B,MAAM,EACN,gBAAgB,EAChB,
|
|
1
|
+
{"version":3,"file":"CategoriesTree.js","sourceRoot":"","sources":["../../../../../../src/tree-widget-react/components/trees/categories-tree/CategoriesTree.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAe3D,YAAY;AACZ,MAAM,UAAU,cAAc,CAAC,EAC7B,MAAM,EACN,gBAAgB,EAChB,UAAU,EACV,MAAM,EACN,oBAAoB,EACpB,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,eAAe,GACK;IACpB,MAAM,EAAE,mBAAmB,EAAE,aAAa,EAAE,GAAG,iBAAiB,CAAC;QAC/D,MAAM;QACN,UAAU;QACV,oBAAoB;QACpB,gBAAgB;QAChB,eAAe;KAChB,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,cAAc,OACT,mBAAmB,EACvB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,gBAAgB,EAClC,uBAAuB,EAAE,oBAAoB,EAAE,SAAS,EACxD,aAAa,EAAE,aAAa,IAAI,MAAM,EACtC,YAAY,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,CAC3B,KAAC,sBAAsB,OAAK,SAAS,KAAM,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,IAAI,aAAa,CAAC,cAAc,GAAI,CACrJ,GACD,CACH,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { VisibilityTree } from \"../common/components/VisibilityTree.js\";\nimport { VisibilityTreeRenderer } from \"../common/components/VisibilityTreeRenderer.js\";\nimport { useCategoriesTree } from \"./UseCategoriesTree.js\";\n\nimport type { VisibilityTreeRendererProps } from \"../common/components/VisibilityTreeRenderer.js\";\nimport type { UseCategoriesTreeProps } from \"./UseCategoriesTree.js\";\nimport type { VisibilityTreeProps } from \"../common/components/VisibilityTree.js\";\n\n/** @beta */\nexport type CategoriesTreeProps = Pick<VisibilityTreeProps, \"imodel\" | \"selectionStorage\" | \"selectionMode\" | \"emptyTreeContent\"> &\n Pick<VisibilityTreeRendererProps, \"getActions\" | \"getDecorations\"> &\n UseCategoriesTreeProps & {\n hierarchyLevelConfig?: {\n sizeLimit?: number;\n };\n };\n\n/** @beta */\nexport function CategoriesTree({\n imodel,\n selectionStorage,\n activeView,\n filter,\n hierarchyLevelConfig,\n selectionMode,\n onCategoriesFiltered,\n emptyTreeContent,\n getDecorations,\n getActions,\n hierarchyConfig,\n}: CategoriesTreeProps) {\n const { categoriesTreeProps, rendererProps } = useCategoriesTree({\n filter,\n activeView,\n onCategoriesFiltered,\n emptyTreeContent,\n hierarchyConfig,\n });\n\n return (\n <VisibilityTree\n {...categoriesTreeProps}\n imodel={imodel}\n selectionStorage={selectionStorage}\n hierarchyLevelSizeLimit={hierarchyLevelConfig?.sizeLimit}\n selectionMode={selectionMode ?? \"none\"}\n treeRenderer={(treeProps) => (\n <VisibilityTreeRenderer {...treeProps} {...rendererProps} getActions={getActions} getDecorations={getDecorations ?? rendererProps.getDecorations} />\n )}\n />\n );\n}\n"]}
|
package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeComponent.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CategoriesTreeProps } from "./CategoriesTree.js";
|
|
2
2
|
import type { CategoriesTreeHeaderButtonProps, CategoriesTreeHeaderButtonType } from "./CategoriesTreeButtons.js";
|
|
3
3
|
/** @public */
|
|
4
|
-
interface CategoriesTreeComponentProps extends Pick<CategoriesTreeProps, "
|
|
4
|
+
interface CategoriesTreeComponentProps extends Pick<CategoriesTreeProps, "selectionStorage" | "hierarchyLevelConfig" | "selectionMode" | "filter" | "emptyTreeContent" | "getActions" | "getDecorations" | "hierarchyConfig"> {
|
|
5
5
|
/**
|
|
6
6
|
* Renderers of header buttons. Defaults to:
|
|
7
7
|
* ```ts
|
package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeComponent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CategoriesTreeComponent.js","sourceRoot":"","sources":["../../../../../../src/tree-widget-react/components/trees/categories-tree/CategoriesTreeComponent.tsx"],"names":[],"mappings":";;AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"CategoriesTreeComponent.js","sourceRoot":"","sources":["../../../../../../src/tree-widget-react/components/trees/categories-tree/CategoriesTreeComponent.tsx"],"names":[],"mappings":";;AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AA4BzH;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,KAAmC,EAAE,EAAE;IAC7E,MAAM,MAAM,GAAG,yBAAyB,EAAE,CAAC;IAC3C,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IAErC,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAC,2BAA2B,OAAK,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAI,CAAC;AACxF,CAAC,CAAC;AAEF;;;GAGG;AACH,uBAAuB,CAAC,aAAa,GAAG,aAA+C,CAAC;AAExF;;;GAGG;AACH,uBAAuB,CAAC,aAAa,GAAG,aAA+C,CAAC;AAExF;;;GAGG;AACH,uBAAuB,CAAC,eAAe,GAAG,eAAiD,CAAC;AAE5F;;;GAGG;AACH,uBAAuB,CAAC,EAAE,GAAG,oBAAoB,CAAC;AAElD;;;GAGG;AACH,uBAAuB,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;AAEtF,SAAS,2BAA2B,CAAC,EACnC,MAAM,EACN,QAAQ,EACR,aAAa,EACb,qBAAqB,EACrB,aAAa,EACb,MAAM,EACN,GAAG,SAAS,EAC0E;IACtF,MAAM,EAAE,WAAW,EAAE,oBAAoB,EAAE,GAAG,4BAA4B,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IAEzF,MAAM,OAAO,GAAc,aAAa;QACtC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,KAAC,QAAQ,cAAc,GAAG,CAAC,EAAE,GAAG,WAAW,EAAE,aAAa,EAAE,CAAC,IAA9C,KAAK,CAAqD,CAAC;QAC9G,CAAC,CAAC;YACE,eAAC,aAAa,OAAK,WAAW,EAAE,GAAG,EAAC,cAAc,EAAC,aAAa,EAAE,aAAa,GAAI;YACnF,eAAC,aAAa,OAAK,WAAW,EAAE,GAAG,EAAC,cAAc,EAAC,aAAa,EAAE,aAAa,GAAI;YACnF,eAAC,eAAe,OAAK,WAAW,EAAE,GAAG,EAAC,gBAAgB,EAAC,aAAa,EAAE,aAAa,GAAI;SACxF,CAAC;IAEN,OAAO,CACL,KAAC,wBAAwB,IAAC,mBAAmB,EAAE,uBAAuB,CAAC,EAAE,EAAE,aAAa,EAAE,aAAa,EAAE,qBAAqB,EAAE,qBAAqB,YACnJ,KAAC,cAAc,IAAC,OAAO,EAAE,OAAO,YAC9B,KAAC,cAAc,OAAK,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,oBAAoB,GAAI,GACpH,GACQ,CAC5B,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { Fragment } from \"react\";\nimport { useActiveIModelConnection } from \"@itwin/appui-react\";\nimport { TreeWidget } from \"../../../TreeWidget.js\";\nimport { SelectableTree } from \"../../tree-header/SelectableTree.js\";\nimport { useActiveViewport } from \"../common/internal/UseActiveViewport.js\";\nimport { TelemetryContextProvider } from \"../common/UseTelemetryContext.js\";\nimport { CategoriesTree } from \"./CategoriesTree.js\";\nimport { HideAllButton, InvertAllButton, ShowAllButton, useCategoriesTreeButtonProps } from \"./CategoriesTreeButtons.js\";\n\nimport type { CategoriesTreeProps } from \"./CategoriesTree.js\";\nimport type { ReactNode } from \"react\";\nimport type { IModelConnection, ScreenViewport } from \"@itwin/core-frontend\";\nimport type { CategoriesTreeHeaderButtonProps, CategoriesTreeHeaderButtonType } from \"./CategoriesTreeButtons.js\";\n\n/** @public */\ninterface CategoriesTreeComponentProps\n extends Pick<\n CategoriesTreeProps,\n \"selectionStorage\" | \"hierarchyLevelConfig\" | \"selectionMode\" | \"filter\" | \"emptyTreeContent\" | \"getActions\" | \"getDecorations\" | \"hierarchyConfig\"\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 onPerformanceMeasured?: (featureId: string, duration: number) => void;\n onFeatureUsed?: (feature: string) => void;\n}\n\n/**\n * A component that renders `CategoriesTree` and a header with filtering capabilities 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 as CategoriesTreeHeaderButtonType;\n\n/**\n * Renders a \"Hide all\" button that disables display of all categories.\n * @public\n */\nCategoriesTreeComponent.HideAllButton = HideAllButton as CategoriesTreeHeaderButtonType;\n\n/**\n * Renders an \"Invert all\" button that inverts display of all categories.\n * @public\n */\nCategoriesTreeComponent.InvertAllButton = InvertAllButton as CategoriesTreeHeaderButtonType;\n\n/**\n * Id of the component. May be used when a creating a `TreeDefinition` for `SelectableTree`.\n * @public\n */\nCategoriesTreeComponent.id = \"categories-tree-v2\";\n\n/**\n * Label of the component. May be used when a creating a `TreeDefinition` for `SelectableTree`.\n * @public\n */\nCategoriesTreeComponent.getLabel = () => TreeWidget.translate(\"categoriesTree.label\");\n\nfunction CategoriesTreeComponentImpl({\n iModel,\n viewport,\n headerButtons,\n onPerformanceMeasured,\n onFeatureUsed,\n filter,\n ...treeProps\n}: CategoriesTreeComponentProps & { iModel: IModelConnection; viewport: ScreenViewport }) {\n const { buttonProps, onCategoriesFiltered } = useCategoriesTreeButtonProps({ viewport });\n\n const buttons: ReactNode = headerButtons\n ? headerButtons.map((btn, index) => <Fragment key={index}>{btn({ ...buttonProps, onFeatureUsed })}</Fragment>)\n : [\n <ShowAllButton {...buttonProps} key=\"show-all-btn\" onFeatureUsed={onFeatureUsed} />,\n <HideAllButton {...buttonProps} key=\"hide-all-btn\" onFeatureUsed={onFeatureUsed} />,\n <InvertAllButton {...buttonProps} key=\"invert-all-btn\" onFeatureUsed={onFeatureUsed} />,\n ];\n\n return (\n <TelemetryContextProvider componentIdentifier={CategoriesTreeComponent.id} onFeatureUsed={onFeatureUsed} onPerformanceMeasured={onPerformanceMeasured}>\n <SelectableTree buttons={buttons}>\n <CategoriesTree {...treeProps} imodel={iModel} activeView={viewport} filter={filter} onCategoriesFiltered={onCategoriesFiltered} />\n </SelectableTree>\n </TelemetryContextProvider>\n );\n}\n"]}
|
package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.js
CHANGED
|
@@ -6,7 +6,7 @@ import { bufferCount, defer, firstValueFrom, from, lastValueFrom, map, merge, me
|
|
|
6
6
|
import { assert } from "@itwin/core-bentley";
|
|
7
7
|
import { createNodesQueryClauseFactory, createPredicateBasedHierarchyDefinition, ProcessedHierarchyNode } from "@itwin/presentation-hierarchies";
|
|
8
8
|
import { createBisInstanceLabelSelectClauseFactory, ECSql } from "@itwin/presentation-shared";
|
|
9
|
-
import {
|
|
9
|
+
import { CLASS_NAME_DefinitionContainer, CLASS_NAME_InformationPartitionElement, CLASS_NAME_ISubModeledElement, CLASS_NAME_Model, CLASS_NAME_SubCategory, } from "../common/internal/ClassNameDefinitions.js";
|
|
10
10
|
import { createIdsSelector, getClassesByView, getDistinctMapValues, parseIdsSelectorResult, releaseMainThreadOnItemsCount } from "../common/internal/Utils.js";
|
|
11
11
|
import { FilterLimitExceededError } from "../common/TreeErrors.js";
|
|
12
12
|
const MAX_FILTERING_INSTANCE_KEY_COUNT = 100;
|
|
@@ -85,7 +85,7 @@ export class CategoriesTreeDefinition {
|
|
|
85
85
|
definitions: async (requestProps) => this.createElementChildrenQuery(requestProps),
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
|
-
parentInstancesNodePredicate:
|
|
88
|
+
parentInstancesNodePredicate: CLASS_NAME_ISubModeledElement,
|
|
89
89
|
definitions: async (requestProps) => this.createISubModeledElementChildrenQuery(requestProps),
|
|
90
90
|
},
|
|
91
91
|
{
|
|
@@ -105,7 +105,7 @@ export class CategoriesTreeDefinition {
|
|
|
105
105
|
...(isDefinitionContainerSupported
|
|
106
106
|
? [
|
|
107
107
|
{
|
|
108
|
-
parentInstancesNodePredicate:
|
|
108
|
+
parentInstancesNodePredicate: CLASS_NAME_DefinitionContainer,
|
|
109
109
|
definitions: async (requestProps) => this.createDefinitionContainersAndCategoriesQuery(requestProps),
|
|
110
110
|
},
|
|
111
111
|
]
|
|
@@ -213,11 +213,11 @@ export class CategoriesTreeDefinition {
|
|
|
213
213
|
async createDefinitionContainersQuery({ definitionContainerIds, instanceFilter, }) {
|
|
214
214
|
const instanceFilterClauses = await this._selectQueryFactory.createFilterClauses({
|
|
215
215
|
filter: instanceFilter,
|
|
216
|
-
contentClass: { fullName:
|
|
216
|
+
contentClass: { fullName: CLASS_NAME_DefinitionContainer, alias: "this" },
|
|
217
217
|
});
|
|
218
218
|
return [
|
|
219
219
|
{
|
|
220
|
-
fullClassName:
|
|
220
|
+
fullClassName: CLASS_NAME_DefinitionContainer,
|
|
221
221
|
query: {
|
|
222
222
|
ecsql: `
|
|
223
223
|
SELECT
|
|
@@ -227,7 +227,7 @@ export class CategoriesTreeDefinition {
|
|
|
227
227
|
nodeLabel: {
|
|
228
228
|
selector: await this._nodeLabelSelectClauseFactory.createSelectClause({
|
|
229
229
|
classAlias: "this",
|
|
230
|
-
className:
|
|
230
|
+
className: CLASS_NAME_DefinitionContainer,
|
|
231
231
|
}),
|
|
232
232
|
},
|
|
233
233
|
extendedData: {
|
|
@@ -323,11 +323,11 @@ export class CategoriesTreeDefinition {
|
|
|
323
323
|
async createSubCategoriesQuery({ parentNodeInstanceIds: categoryIds, instanceFilter, }) {
|
|
324
324
|
const instanceFilterClauses = await this._selectQueryFactory.createFilterClauses({
|
|
325
325
|
filter: instanceFilter,
|
|
326
|
-
contentClass: { fullName:
|
|
326
|
+
contentClass: { fullName: CLASS_NAME_SubCategory, alias: "this" },
|
|
327
327
|
});
|
|
328
328
|
return [
|
|
329
329
|
{
|
|
330
|
-
fullClassName:
|
|
330
|
+
fullClassName: CLASS_NAME_SubCategory,
|
|
331
331
|
query: {
|
|
332
332
|
ecsql: `
|
|
333
333
|
SELECT
|
|
@@ -337,7 +337,7 @@ export class CategoriesTreeDefinition {
|
|
|
337
337
|
nodeLabel: {
|
|
338
338
|
selector: await this._nodeLabelSelectClauseFactory.createSelectClause({
|
|
339
339
|
classAlias: "this",
|
|
340
|
-
className:
|
|
340
|
+
className: CLASS_NAME_SubCategory,
|
|
341
341
|
}),
|
|
342
342
|
},
|
|
343
343
|
extendedData: {
|
|
@@ -412,7 +412,7 @@ export class CategoriesTreeDefinition {
|
|
|
412
412
|
supportsFiltering: true,
|
|
413
413
|
})}
|
|
414
414
|
FROM ${instanceFilterClauses.from} this
|
|
415
|
-
${parentNode.extendedData?.isCategoryOfSubModel ? "" : `JOIN ${
|
|
415
|
+
${parentNode.extendedData?.isCategoryOfSubModel ? "" : `JOIN ${CLASS_NAME_InformationPartitionElement} ipe ON ipe.ECInstanceId = this.Model.Id`}
|
|
416
416
|
${instanceFilterClauses.joins}
|
|
417
417
|
WHERE
|
|
418
418
|
this.Category.Id IN (${categoryIds.join(",")})
|
|
@@ -449,7 +449,7 @@ export class CategoriesTreeDefinition {
|
|
|
449
449
|
IFNULL((
|
|
450
450
|
SELECT 1
|
|
451
451
|
FROM ${this._categoryElementClass} ce
|
|
452
|
-
JOIN ${
|
|
452
|
+
JOIN ${CLASS_NAME_Model} m ON ce.Model.Id = m.ECInstanceId
|
|
453
453
|
WHERE ce.Parent.Id = this.ECInstanceId OR (ce.Model.Id = this.ECInstanceId AND m.IsPrivate = false)
|
|
454
454
|
LIMIT 1
|
|
455
455
|
), 0)
|
|
@@ -492,7 +492,7 @@ async function createInstanceKeyPathsFromInstanceLabel(props) {
|
|
|
492
492
|
const ELEMENTS_WITH_LABELS_CTE = "ElementsWithLabels";
|
|
493
493
|
const SUBCATEGORIES_WITH_LABELS_CTE = "SubCategoriesWithLabels";
|
|
494
494
|
const DEFINITION_CONTAINERS_WITH_LABELS_CTE = "DefinitionContainersWithLabels";
|
|
495
|
-
const [categoryLabelSelectClause, subCategoryLabelSelectClause, elementLabelSelectClause, definitionContainerLabelSelectClause] = await Promise.all([categoryClass,
|
|
495
|
+
const [categoryLabelSelectClause, subCategoryLabelSelectClause, elementLabelSelectClause, definitionContainerLabelSelectClause] = await Promise.all([categoryClass, CLASS_NAME_SubCategory, elementClass, ...(definitionContainers.length > 0 ? [CLASS_NAME_DefinitionContainer] : [])].map(async (className) => props.labelsFactory.createSelectClause({ classAlias: "this", className })));
|
|
496
496
|
return lastValueFrom(defer(() => {
|
|
497
497
|
const ctes = [
|
|
498
498
|
`${CATEGORIES_WITH_LABELS_CTE}(ClassName, ECInstanceId, ChildCount, DisplayLabel) AS (
|
|
@@ -503,7 +503,7 @@ async function createInstanceKeyPathsFromInstanceLabel(props) {
|
|
|
503
503
|
${categoryLabelSelectClause}
|
|
504
504
|
FROM
|
|
505
505
|
${categoryClass} this
|
|
506
|
-
JOIN ${
|
|
506
|
+
JOIN ${CLASS_NAME_SubCategory} sc ON sc.Parent.Id = this.ECInstanceId
|
|
507
507
|
WHERE
|
|
508
508
|
this.ECInstanceId IN (${categories.join(", ")})
|
|
509
509
|
GROUP BY this.ECInstanceId
|
|
@@ -518,7 +518,7 @@ async function createInstanceKeyPathsFromInstanceLabel(props) {
|
|
|
518
518
|
${elementLabelSelectClause}
|
|
519
519
|
FROM
|
|
520
520
|
${elementClass} this
|
|
521
|
-
JOIN ${
|
|
521
|
+
JOIN ${CLASS_NAME_Model} m ON this.Model.Id = m.ECInstanceId
|
|
522
522
|
WHERE
|
|
523
523
|
NOT m.IsPrivate
|
|
524
524
|
AND this.Category.Id IN (${categories.join(", ")})
|
|
@@ -535,7 +535,7 @@ async function createInstanceKeyPathsFromInstanceLabel(props) {
|
|
|
535
535
|
this.Parent.Id,
|
|
536
536
|
${subCategoryLabelSelectClause}
|
|
537
537
|
FROM
|
|
538
|
-
${
|
|
538
|
+
${CLASS_NAME_SubCategory} this
|
|
539
539
|
WHERE
|
|
540
540
|
NOT this.IsPrivate
|
|
541
541
|
AND this.Parent.Id IN (${categories.join(", ")})
|
|
@@ -549,7 +549,7 @@ async function createInstanceKeyPathsFromInstanceLabel(props) {
|
|
|
549
549
|
this.ECInstanceId,
|
|
550
550
|
${definitionContainerLabelSelectClause}
|
|
551
551
|
FROM
|
|
552
|
-
${
|
|
552
|
+
${CLASS_NAME_DefinitionContainer} this
|
|
553
553
|
WHERE
|
|
554
554
|
this.ECInstanceId IN (${definitionContainers.join(", ")})
|
|
555
555
|
)`,
|
|
@@ -620,13 +620,13 @@ async function createInstanceKeyPathsFromInstanceLabel(props) {
|
|
|
620
620
|
className = categoryClass;
|
|
621
621
|
break;
|
|
622
622
|
case "sc":
|
|
623
|
-
className =
|
|
623
|
+
className = CLASS_NAME_SubCategory;
|
|
624
624
|
break;
|
|
625
625
|
case "e":
|
|
626
626
|
className = elementClass;
|
|
627
627
|
break;
|
|
628
628
|
default:
|
|
629
|
-
className =
|
|
629
|
+
className = CLASS_NAME_DefinitionContainer;
|
|
630
630
|
break;
|
|
631
631
|
}
|
|
632
632
|
return {
|
|
@@ -645,11 +645,11 @@ function createInstanceKeyPathsFromTargetItems({ targetItems, imodelAccess, view
|
|
|
645
645
|
acc.categoryIds.push(id);
|
|
646
646
|
return acc;
|
|
647
647
|
}
|
|
648
|
-
if (className ===
|
|
648
|
+
if (className === CLASS_NAME_DefinitionContainer) {
|
|
649
649
|
acc.definitionContainerIds.push(id);
|
|
650
650
|
return acc;
|
|
651
651
|
}
|
|
652
|
-
if (className ===
|
|
652
|
+
if (className === CLASS_NAME_SubCategory) {
|
|
653
653
|
if (hierarchyConfig.hideSubCategories) {
|
|
654
654
|
return acc;
|
|
655
655
|
}
|