@itwin/tree-widget-react 3.4.0 → 3.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +18 -2
  2. package/lib/cjs/tree-widget-react/components/trees/common/components/Tree.js +4 -3
  3. package/lib/cjs/tree-widget-react/components/trees/common/components/Tree.js.map +1 -1
  4. package/lib/cjs/tree-widget-react/components/trees/common/components/TreeNodeCheckbox.js +1 -5
  5. package/lib/cjs/tree-widget-react/components/trees/common/components/TreeNodeCheckbox.js.map +1 -1
  6. package/lib/cjs/tree-widget-react/components/trees/common/components/TreeNodeRenderer.js +3 -5
  7. package/lib/cjs/tree-widget-react/components/trees/common/components/TreeNodeRenderer.js.map +1 -1
  8. package/lib/cjs/tree-widget-react/components/trees/common/components/TreeRenderer.d.ts +0 -1
  9. package/lib/cjs/tree-widget-react/components/trees/common/components/TreeRenderer.js +2 -3
  10. package/lib/cjs/tree-widget-react/components/trees/common/components/TreeRenderer.js.map +1 -1
  11. package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.d.ts +5 -0
  12. package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js +45 -0
  13. package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js.map +1 -1
  14. package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js +123 -36
  15. package/lib/cjs/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js.map +1 -1
  16. package/lib/esm/tree-widget-react/components/trees/common/components/Tree.js +5 -4
  17. package/lib/esm/tree-widget-react/components/trees/common/components/Tree.js.map +1 -1
  18. package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeCheckbox.js +1 -2
  19. package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeCheckbox.js.map +1 -1
  20. package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeRenderer.js +3 -2
  21. package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeRenderer.js.map +1 -1
  22. package/lib/esm/tree-widget-react/components/trees/common/components/TreeRenderer.d.ts +0 -1
  23. package/lib/esm/tree-widget-react/components/trees/common/components/TreeRenderer.js +2 -3
  24. package/lib/esm/tree-widget-react/components/trees/common/components/TreeRenderer.js.map +1 -1
  25. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.d.ts +5 -0
  26. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js +45 -0
  27. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js.map +1 -1
  28. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js +125 -38
  29. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js.map +1 -1
  30. package/lib/public/locales/en/TreeWidget.json +15 -4
  31. package/package.json +5 -5
  32. package/lib/cjs/tree-widget-react/components/trees/common/components/TreeRenderer.scss +0 -48
  33. package/lib/esm/tree-widget-react/components/trees/common/components/TreeRenderer.scss +0 -48
@@ -158,7 +158,12 @@ class ModelsTreeVisibilityHandlerImpl {
158
158
  return (0, rxjs_1.of)((0, Tooltip_js_1.createVisibilityStatus)("disabled", getTooltipOptions("modelsTree.model.nonSpatialView", ignoreTooltip)));
159
159
  }
160
160
  if (!viewport.view.viewsModel(modelId)) {
161
- return (0, rxjs_1.of)((0, Tooltip_js_1.createVisibilityStatus)("hidden", getTooltipOptions("modelsTree.model.hiddenThroughModelSelector", ignoreTooltip)));
161
+ return (0, rxjs_1.from)(this._idsCache.getModelCategories(modelId)).pipe((0, rxjs_1.mergeMap)((categoryIds) => (0, rxjs_1.from)(this._idsCache.getCategoriesModeledElements(modelId, categoryIds))), this.getSubModeledElementsVisibilityStatus({
162
+ ignoreTooltips: ignoreTooltip,
163
+ haveSubModel: "yes",
164
+ tooltips: { visible: undefined, hidden: "modelsTree.model.hiddenThroughModelSelector", partial: "modelsTree.model.someSubModelsVisible" },
165
+ parentNodeVisibilityStatus: (0, Tooltip_js_1.createVisibilityStatus)("hidden"),
166
+ }));
162
167
  }
163
168
  return (0, rxjs_1.from)(this._idsCache.getModelCategories(modelId)).pipe((0, rxjs_1.concatAll)(), (0, rxjs_1.mergeMap)((categoryId) => this.getCategoryDisplayStatus({ modelId, categoryId, ignoreTooltip: true })), (0, rxjs_1.map)((x) => x.state), getVisibilityFromTreeNodeChildren, (0, rxjs_1.map)((visibilityByCategories) => {
164
169
  const state = visibilityByCategories === "empty" ? "visible" : visibilityByCategories;
@@ -186,7 +191,16 @@ class ModelsTreeVisibilityHandlerImpl {
186
191
  getCategoryDisplayStatus({ ignoreTooltip, ...props }) {
187
192
  const result = (0, rxjs_1.defer)(() => {
188
193
  if (!this._props.viewport.view.viewsModel(props.modelId)) {
189
- return (0, rxjs_1.of)((0, Tooltip_js_1.createVisibilityStatus)("hidden", getTooltipOptions("modelsTree.category.hiddenThroughModel", ignoreTooltip)));
194
+ return (0, rxjs_1.from)(this._idsCache.getCategoriesModeledElements(props.modelId, [props.categoryId])).pipe(this.getSubModeledElementsVisibilityStatus({
195
+ ignoreTooltips: ignoreTooltip,
196
+ parentNodeVisibilityStatus: (0, Tooltip_js_1.createVisibilityStatus)("hidden"),
197
+ tooltips: {
198
+ visible: undefined,
199
+ hidden: "modelsTree.category.hiddenThroughModel",
200
+ partial: "modelsTree.category.someElementsOrSubModelsHidden",
201
+ },
202
+ haveSubModel: "yes",
203
+ }));
190
204
  }
191
205
  return this.getVisibilityFromAlwaysAndNeverDrawnElements({
192
206
  queryProps: props,
@@ -198,7 +212,18 @@ class ModelsTreeVisibilityHandlerImpl {
198
212
  },
199
213
  defaultStatus: () => this.getDefaultCategoryVisibilityStatus(props),
200
214
  ignoreTooltip,
201
- });
215
+ }).pipe((0, rxjs_1.mergeMap)((visibilityStatusAlwaysAndNeverDraw) => {
216
+ return (0, rxjs_1.from)(this._idsCache.getCategoriesModeledElements(props.modelId, [props.categoryId])).pipe(this.getSubModeledElementsVisibilityStatus({
217
+ tooltips: {
218
+ visible: undefined,
219
+ hidden: "modelsTree.category.allElementsAndSubModelsHidden",
220
+ partial: "modelsTree.category.someElementsOrSubModelsHidden",
221
+ },
222
+ haveSubModel: "yes",
223
+ parentNodeVisibilityStatus: visibilityStatusAlwaysAndNeverDraw,
224
+ ignoreTooltips: ignoreTooltip,
225
+ }));
226
+ }));
202
227
  });
203
228
  return (0, UseHierarchyVisibility_js_1.createVisibilityHandlerResult)(this, props, result, this._props.overrides?.getCategoryDisplayStatus);
204
229
  }
@@ -207,7 +232,15 @@ class ModelsTreeVisibilityHandlerImpl {
207
232
  const info = this.getGroupingNodeInfo(node);
208
233
  const { modelId, categoryId, elementIds } = info;
209
234
  if (!this._props.viewport.view.viewsModel(modelId)) {
210
- return (0, rxjs_1.of)((0, Tooltip_js_1.createVisibilityStatus)("hidden"));
235
+ return (0, rxjs_1.of)([...elementIds]).pipe(this.getSubModeledElementsVisibilityStatus({
236
+ tooltips: {
237
+ visible: undefined,
238
+ hidden: undefined,
239
+ partial: "modelsTree.groupingNode.someElementsOrSubModelsHidden",
240
+ },
241
+ parentNodeVisibilityStatus: (0, Tooltip_js_1.createVisibilityStatus)("hidden"),
242
+ haveSubModel: "unknown",
243
+ }));
211
244
  }
212
245
  return this.getVisibilityFromAlwaysAndNeverDrawnElements({
213
246
  elements: elementIds,
@@ -221,7 +254,17 @@ class ModelsTreeVisibilityHandlerImpl {
221
254
  elementsInBothAlwaysAndNeverDrawn: "modelsTree.groupingNode.someElementsAreHidden",
222
255
  noElementsInExclusiveAlwaysDrawnList: "modelsTree.groupingNode.allElementsHidden",
223
256
  },
224
- });
257
+ }).pipe((0, rxjs_1.mergeMap)((visibilityStatusAlwaysAndNeverDraw) => {
258
+ return (0, rxjs_1.of)([...elementIds]).pipe(this.getSubModeledElementsVisibilityStatus({
259
+ tooltips: {
260
+ visible: undefined,
261
+ hidden: "modelsTree.groupingNode.allElementsAndSubModelsHidden",
262
+ partial: "modelsTree.groupingNode.someElementsOrSubModelsHidden",
263
+ },
264
+ parentNodeVisibilityStatus: visibilityStatusAlwaysAndNeverDraw,
265
+ haveSubModel: "unknown",
266
+ }));
267
+ }));
225
268
  });
226
269
  return (0, UseHierarchyVisibility_js_1.createVisibilityHandlerResult)(this, { node }, result, this._props.overrides?.getElementGroupingNodeDisplayStatus);
227
270
  }
@@ -240,19 +283,46 @@ class ModelsTreeVisibilityHandlerImpl {
240
283
  }
241
284
  return undefined;
242
285
  }
286
+ getElementVisibility(ignoreTooltip, viewsModel, overridenVisibility, categoryVisibility, subModelVisibilityStatus) {
287
+ if (subModelVisibilityStatus === undefined) {
288
+ if (!viewsModel) {
289
+ return (0, Tooltip_js_1.createVisibilityStatus)("hidden", getTooltipOptions("modelsTree.element.hiddenThroughModel", ignoreTooltip));
290
+ }
291
+ if (overridenVisibility) {
292
+ return overridenVisibility;
293
+ }
294
+ return (0, Tooltip_js_1.createVisibilityStatus)(categoryVisibility.state, getTooltipOptions(categoryVisibility.state === "visible" ? undefined : "modelsTree.element.hiddenThroughCategory", ignoreTooltip));
295
+ }
296
+ if (subModelVisibilityStatus.state === "partial") {
297
+ return (0, Tooltip_js_1.createVisibilityStatus)("partial", getTooltipOptions("modelsTree.element.someElementsAreHidden", ignoreTooltip));
298
+ }
299
+ if (subModelVisibilityStatus.state === "visible") {
300
+ if (!viewsModel || overridenVisibility?.state === "hidden" || (categoryVisibility.state === "hidden" && !overridenVisibility)) {
301
+ return (0, Tooltip_js_1.createVisibilityStatus)("partial", getTooltipOptions("modelsTree.element.partialThroughSubModel", ignoreTooltip));
302
+ }
303
+ return (0, Tooltip_js_1.createVisibilityStatus)("visible", getTooltipOptions(undefined, ignoreTooltip));
304
+ }
305
+ if (!viewsModel) {
306
+ return (0, Tooltip_js_1.createVisibilityStatus)("hidden", getTooltipOptions("modelsTree.element.hiddenThroughModel", ignoreTooltip));
307
+ }
308
+ if (overridenVisibility) {
309
+ if (overridenVisibility.state === "hidden") {
310
+ return overridenVisibility;
311
+ }
312
+ return (0, Tooltip_js_1.createVisibilityStatus)("partial", getTooltipOptions("modelsTree.element.partialThroughElement", ignoreTooltip));
313
+ }
314
+ if (categoryVisibility.state === "visible") {
315
+ return (0, Tooltip_js_1.createVisibilityStatus)("partial", getTooltipOptions("modelsTree.element.partialThroughCategory", ignoreTooltip));
316
+ }
317
+ return (0, Tooltip_js_1.createVisibilityStatus)("hidden", getTooltipOptions("modelsTree.element.hiddenThroughCategory", ignoreTooltip));
318
+ }
243
319
  getElementDisplayStatus({ ignoreTooltip, ...props }) {
244
320
  const result = (0, rxjs_1.defer)(() => {
245
321
  const viewport = this._props.viewport;
246
322
  const { elementId, modelId, categoryId } = props;
247
- if (!viewport.view.viewsModel(modelId)) {
248
- return (0, rxjs_1.of)((0, Tooltip_js_1.createVisibilityStatus)("hidden", getTooltipOptions("modelsTree.element.hiddenThroughModel", ignoreTooltip)));
249
- }
250
- let status = this.getElementOverriddenVisibility(elementId, ignoreTooltip);
251
- if (status) {
252
- return (0, rxjs_1.of)(status);
253
- }
254
- status = this.getDefaultCategoryVisibilityStatus({ categoryId, modelId, ignoreTooltip: true });
255
- return (0, rxjs_1.of)((0, Tooltip_js_1.createVisibilityStatus)(status.state, getTooltipOptions(status.state === "visible" ? undefined : "modelsTree.element.hiddenThroughCategory", ignoreTooltip)));
323
+ const viewsModel = viewport.view.viewsModel(modelId);
324
+ const elementStatus = this.getElementOverriddenVisibility(elementId, ignoreTooltip);
325
+ return (0, rxjs_1.from)(this._idsCache.hasSubModel(elementId)).pipe((0, rxjs_1.mergeMap)((hasSubModel) => (hasSubModel ? this.getModelVisibilityStatus({ modelId: elementId }) : (0, rxjs_1.of)(undefined))), (0, rxjs_1.map)((subModelVisibilityStatus) => this.getElementVisibility(ignoreTooltip, viewsModel, elementStatus, this.getDefaultCategoryVisibilityStatus({ categoryId, modelId, ignoreTooltip: true }), subModelVisibilityStatus)));
256
326
  });
257
327
  return (0, UseHierarchyVisibility_js_1.createVisibilityHandlerResult)(this, props, result, this._props.overrides?.getElementDisplayStatus);
258
328
  }
@@ -333,20 +403,24 @@ class ModelsTreeVisibilityHandlerImpl {
333
403
  return (0, UseHierarchyVisibility_js_1.createVisibilityHandlerResult)(this, { ids, on }, result, this._props.overrides?.changeSubjectNodeState);
334
404
  }
335
405
  changeModelState(props) {
406
+ const { ids, on } = props;
407
+ if (core_bentley_1.Id64.sizeOf(ids) === 0) {
408
+ return rxjs_1.EMPTY;
409
+ }
336
410
  const result = (0, rxjs_1.defer)(() => {
337
411
  const viewport = this._props.viewport;
338
412
  if (!viewport.view.isSpatialView()) {
339
413
  return rxjs_1.EMPTY;
340
414
  }
341
- const { ids, on } = props;
415
+ const idsObs = (0, rxjs_1.from)(core_bentley_1.Id64.iterable(ids));
342
416
  if (!on) {
343
417
  viewport.changeModelDisplay(ids, false);
344
- return rxjs_1.EMPTY;
418
+ return idsObs.pipe((0, rxjs_1.mergeMap)(async (modelId) => ({ modelId, categoryIds: await this._idsCache.getModelCategories(modelId) })), (0, rxjs_1.mergeMap)(({ modelId, categoryIds }) => (0, rxjs_1.from)(this._idsCache.getCategoriesModeledElements(modelId, categoryIds))), (0, rxjs_1.mergeMap)((modeledElementIds) => this.changeModelState({ ids: modeledElementIds, on })));
345
419
  }
346
420
  return (0, rxjs_1.concat)((0, rxjs_1.defer)(() => {
347
421
  viewport.perModelCategoryVisibility.clearOverrides(ids);
348
422
  return (0, rxjs_1.from)(viewport.addViewedModels(ids));
349
- }), (typeof ids === "string" ? (0, rxjs_1.of)(ids) : (0, rxjs_1.from)(ids)).pipe((0, rxjs_1.mergeMap)((modelId) => {
423
+ }), idsObs.pipe((0, rxjs_1.mergeMap)((modelId) => {
350
424
  return (0, rxjs_1.from)(this._idsCache.getModelCategories(modelId)).pipe((0, rxjs_1.concatAll)(), (0, rxjs_1.mergeMap)((categoryId) => this.changeCategoryState({ categoryId, modelId, on: true })));
351
425
  })));
352
426
  });
@@ -390,25 +464,27 @@ class ModelsTreeVisibilityHandlerImpl {
390
464
  return (0, rxjs_1.concat)(props.on && !viewport.view.viewsModel(modelId) ? this.showModelWithoutAnyCategoriesOrElements(modelId) : rxjs_1.EMPTY, (0, rxjs_1.defer)(() => {
391
465
  this.changeCategoryStateInViewportAccordingToModelVisibility(modelId, categoryId, on);
392
466
  return this.clearAlwaysAndNeverDrawnElements(props);
393
- }));
467
+ }), (0, rxjs_1.from)(this._idsCache.getCategoriesModeledElements(modelId, [categoryId])).pipe((0, rxjs_1.mergeMap)((modeledElementIds) => this.changeModelState({ ids: modeledElementIds, on }))));
394
468
  });
395
469
  return (0, UseHierarchyVisibility_js_1.createVisibilityHandlerResult)(this, props, result, this._props.overrides?.changeCategoryState);
396
470
  }
397
- /**
398
- * Updates visibility of all grouping node's elements.
399
- * @see `changeElementState`
400
- */
401
- changeElementGroupingNodeState(node, on) {
402
- const result = (0, rxjs_1.defer)(() => {
403
- const info = this.getGroupingNodeInfo(node);
404
- const { modelId, categoryId, elementIds } = info;
471
+ doChangeElementsState(props) {
472
+ return (0, rxjs_1.defer)(() => {
473
+ const { modelId, categoryId, elementIds, on } = props;
405
474
  const viewport = this._props.viewport;
406
475
  return (0, rxjs_1.concat)(on && !viewport.view.viewsModel(modelId) ? this.showModelWithoutAnyCategoriesOrElements(modelId) : rxjs_1.EMPTY, (0, rxjs_1.defer)(() => {
407
476
  const categoryVisibility = this.getDefaultCategoryVisibilityStatus({ categoryId, modelId, ignoreTooltip: true });
408
477
  const isDisplayedByDefault = categoryVisibility.state === "visible";
409
478
  return this.queueElementsVisibilityChange(elementIds, on, isDisplayedByDefault);
410
- }));
479
+ }), (0, rxjs_1.from)(elementIds).pipe((0, rxjs_1.mergeMap)(async (elementId) => ({ elementId, isSubModel: await this._idsCache.hasSubModel(elementId) })), (0, rxjs_1.filter)(({ isSubModel }) => isSubModel), (0, rxjs_1.map)(({ elementId }) => elementId), (0, rxjs_1.toArray)(), (0, rxjs_1.mergeMap)((subModelIds) => this.changeModelState({ ids: subModelIds, on }))));
411
480
  });
481
+ }
482
+ /**
483
+ * Updates visibility of all grouping node's elements.
484
+ * @see `changeElementState`
485
+ */
486
+ changeElementGroupingNodeState(node, on) {
487
+ const result = this.doChangeElementsState({ ...this.getGroupingNodeInfo(node), on });
412
488
  return (0, UseHierarchyVisibility_js_1.createVisibilityHandlerResult)(this, { node, on }, result, this._props.overrides?.changeElementGroupingNodeState);
413
489
  }
414
490
  /**
@@ -416,15 +492,7 @@ class ModelsTreeVisibilityHandlerImpl {
416
492
  * @note If element is to be enabled and model is hidden, it will be enabled.
417
493
  */
418
494
  changeElementsState(props) {
419
- const result = (0, rxjs_1.defer)(() => {
420
- const { elementIds, on, modelId, categoryId } = props;
421
- const viewport = this._props.viewport;
422
- return (0, rxjs_1.concat)(props.on && !viewport.view.viewsModel(modelId) ? this.showModelWithoutAnyCategoriesOrElements(modelId) : rxjs_1.EMPTY, (0, rxjs_1.defer)(() => {
423
- const categoryVisibility = this.getDefaultCategoryVisibilityStatus({ categoryId, modelId, ignoreTooltip: true });
424
- const isDisplayedByDefault = categoryVisibility.state === "visible";
425
- return this.queueElementsVisibilityChange(elementIds, on, isDisplayedByDefault);
426
- }));
427
- });
495
+ const result = this.doChangeElementsState(props);
428
496
  return (0, UseHierarchyVisibility_js_1.createVisibilityHandlerResult)(this, props, result, this._props.overrides?.changeElementsState);
429
497
  }
430
498
  queueElementsVisibilityChange(elementIds, on, visibleByDefault) {
@@ -568,6 +636,25 @@ class ModelsTreeVisibilityHandlerImpl {
568
636
  const elementIds = new Set(node.groupedInstanceKeys.map((key) => key.id));
569
637
  return { modelId, categoryId, elementIds };
570
638
  }
639
+ getSubModeledElementsVisibilityStatus({ parentNodeVisibilityStatus, haveSubModel, tooltips, ignoreTooltips, }) {
640
+ return (obs) => {
641
+ return obs.pipe(
642
+ // ensure we're only looking at elements that have a sub-model
643
+ (0, rxjs_1.mergeMap)((modeledElementIds) => {
644
+ if (haveSubModel === "yes") {
645
+ return (0, rxjs_1.of)(modeledElementIds);
646
+ }
647
+ return (0, rxjs_1.from)(modeledElementIds).pipe((0, rxjs_1.mergeMap)(async (elementId) => ({ elementId, hasSubModel: await this._idsCache.hasSubModel(elementId) })), (0, rxjs_1.filter)(({ hasSubModel }) => hasSubModel), (0, rxjs_1.map)(({ elementId }) => elementId), (0, rxjs_1.toArray)());
648
+ }),
649
+ // combine visibility status of sub-models with visibility status of parent node
650
+ (0, rxjs_1.mergeMap)((modeledElementIds) => {
651
+ if (modeledElementIds.length === 0) {
652
+ return (0, rxjs_1.of)(parentNodeVisibilityStatus);
653
+ }
654
+ return (0, rxjs_1.from)(modeledElementIds).pipe((0, rxjs_1.mergeMap)((modeledElementId) => this.getModelVisibilityStatus({ modelId: modeledElementId })), (0, rxjs_1.startWith)(parentNodeVisibilityStatus), (0, rxjs_1.map)((visibilityStatus) => visibilityStatus.state), getVisibilityStatusFromTreeNodeChildren(tooltips, ignoreTooltips));
655
+ }));
656
+ };
657
+ }
571
658
  }
572
659
  function getVisibilityFromTreeNodeChildren(obs) {
573
660
  return obs.pipe((0, Rxjs_js_1.reduceWhile)((x) => x.allVisible || x.allHidden, (acc, val) => {