Skip to content

[Tree widget]: header buttons adjustments on next - #1751

Merged
JonasDov merged 8 commits into
tree-widget/nextfrom
JonasD/header-buttons
Jul 30, 2026
Merged

[Tree widget]: header buttons adjustments on next#1751
JonasDov merged 8 commits into
tree-widget/nextfrom
JonasD/header-buttons

Conversation

@JonasDov

Copy link
Copy Markdown
Contributor
  • Changed Models and Categories tree header buttons to be more consistent.
  • Those actions now use BufferingViewport.
  • PlanProjection models are now detected and corretly used in view2d/view3d buttons. This fixes the 2D toggle being always disabled.
  • Updated 2D/3D toggle state handling to react to viewport display changes.
  • Expanded visibility utility test coverage.

@JonasDov
JonasDov requested a review from a team as a code owner July 28, 2026 07:54
Copilot AI review requested due to automatic review settings July 28, 2026 07:54
@JonasDov
JonasDov requested a review from a team as a code owner July 28, 2026 07:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request updates the Models and Categories tree header button behavior to be more consistent and cancellable by running visibility changes through a buffered viewport workflow, while also improving plan projection model detection so the 2D/3D toggle state correctly reflects what’s displayed.

Changes:

  • Refactors Models/Categories header actions (show/hide/invert) to use buffered, cancellable visibility operations and updated visibility utilities.
  • Improves 2D/3D toggle logic by detecting plan projection models and reacting to displayed-model changes.
  • Expands VisibilityUtils unit test coverage for the new buffered visibility behaviors.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/tree-widget/src/tree-widget-react/components/trees/models-tree/ModelsTreeButtons.tsx Updates model header buttons to use buffered visibility operations and fixes 2D/3D toggle detection/state.
packages/tree-widget/src/tree-widget-react/components/trees/common/Utils.ts Removes old visibility helpers relocated to internal visibility utilities.
packages/tree-widget/src/tree-widget-react/components/trees/common/internal/VisibilityUtils.ts Introduces buffered/cancellable visibility operations (show/hide/invert) and category display modification utilities.
packages/tree-widget/src/tree-widget-react/components/trees/common/internal/Utils.ts Adds setIntersection helper used by plan projection model detection.
packages/tree-widget/src/tree-widget-react/components/trees/common/internal/caches/ElementModelCategoriesCache.ts Adds plan projection model query/caching and intersects results with cached model set.
packages/tree-widget/src/tree-widget-react/components/trees/common/internal/caches/BaseIdsCache.ts Exposes getPlanProjectionModels() through BaseIdsCache.
packages/tree-widget/src/tree-widget-react/components/trees/categories-tree/CategoriesTreeButtons.tsx Refactors category header buttons to use buffered/cancellable visibility operations and category info mapping.
packages/tree-widget/src/test/trees/common/internal/VisibilityUtils.test.ts Updates and expands tests for the new visibility utilities and cancellation behavior.
change/@itwin-tree-widget-react-c3197d23-0763-4d55-a452-0716c6140208.json Adds changelog entry for the behavior consistency update and 2D toggle fix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tree-Widget Next benchmark

Benchmark suite Current: 7c71de8 Previous: 9ab33ea Deviation Status
models tree 50k 3D elements search > get search paths 1413 ms 1326 ms 6.56% 〰️
models tree 50k 3D elements search > get search paths (P95 of main thread blocks) 60 ms 50 ms 20% 〰️
models tree 50k 3D elements search > load hierarchy from search paths 123619 ms 115619 ms 6.92% 〰️
models tree 50k 3D elements search > load hierarchy from search paths (P95 of main thread blocks) 44 ms 38 ms 15.79% 〰️
models tree 50k categories > collect nodes 2998 ms 2961 ms 1.25% 〰️
models tree 50k categories > collect nodes (P95 of main thread blocks) 101 ms 107 ms -5.61% 〰️
models tree 50k categories > validate initial visibility 2041 ms 1790 ms 14.02% 🚨
models tree 50k categories > validate initial visibility (P95 of main thread blocks) 39 ms 0 ms 3900% 〰️
models tree 50k categories > change visibility 211 ms 203 ms 3.94% 〰️
models tree 50k categories > change visibility (P95 of main thread blocks) 57 ms 57 ms 0% 🟰
models tree 50k categories > validate changed visibility 2408 ms 2280 ms 5.61% 〰️
models tree 50k categories > validate changed visibility (P95 of main thread blocks) 24 ms 25 ms -4% 〰️
models tree 50k 3D elements > collect nodes 51888 ms 47201 ms 9.93% 〰️
models tree 50k 3D elements > collect nodes (P95 of main thread blocks) 83 ms 50 ms 66% 〰️
models tree 50k 3D elements > validate initial visibility 1428 ms 1384 ms 3.18% 〰️
models tree 50k 3D elements > validate initial visibility (P95 of main thread blocks) 0 ms 0 ms 0% 🟰
models tree 50k 3D elements > change model visibility 116 ms 110 ms 5.45% 〰️
models tree 50k 3D elements > change model visibility (P95 of main thread blocks) 25 ms 0 ms 2500% 〰️
models tree 50k 3D elements > validate changed model visibility 2271 ms 2163 ms 4.99% 〰️
models tree 50k 3D elements > validate changed model visibility (P95 of main thread blocks) 0 ms 0 ms 0% 🟰
models tree 50k 3D elements > change category node visibility 484 ms 472 ms 2.54% 〰️
models tree 50k 3D elements > change category node visibility (P95 of main thread blocks) 68 ms 43 ms 58.14% 〰️
models tree 50k 3D elements > validate changed category visibility 1588 ms 1476 ms 7.59% 〰️
models tree 50k 3D elements > validate changed category visibility (P95 of main thread blocks) 0 ms 0 ms 0% 🟰
models tree 50k 3D elements > validate per-model category override 1636 ms 1449 ms 12.91% 🚨
models tree 50k 3D elements > validate per-model category override (P95 of main thread blocks) 112 ms 0 ms 11200% 🚨
models tree 50k 3D elements > change element visibility 46 ms 39 ms 17.95% 〰️
models tree 50k 3D elements > change element visibility (P95 of main thread blocks) 0 ms 0 ms 0% 🟰
models tree 50k 3D elements > validate changed element visibility 2321 ms 2228 ms 4.17% 〰️
models tree 50k 3D elements > validate changed element visibility (P95 of main thread blocks) 69 ms 70 ms -1.43% 〰️
models tree 50k 3D child elements with different categories and excluded classes > collect nodes 72097 ms 65769 ms 9.62% 〰️
models tree 50k 3D child elements with different categories and excluded classes > collect nodes (P95 of main thread blocks) 58 ms 55 ms 5.45% 〰️
models tree 50k 3D child elements with different categories and excluded classes > validate initial visibility 2029 ms 2137 ms -5.05% 〰️
models tree 50k 3D child elements with different categories and excluded classes > validate initial visibility (P95 of main thread blocks) 0 ms 49 ms -100% 〰️
models tree 50k 3D child elements with different categories and excluded classes > change visibility 52 ms 53 ms -1.89% 〰️
models tree 50k 3D child elements with different categories and excluded classes > change visibility (P95 of main thread blocks) 0 ms 0 ms 0% 🟰
models tree 50k 3D child elements with different categories and excluded classes > validate changed visibility 5793 ms 5533 ms 4.70% 〰️
models tree 50k 3D child elements with different categories and excluded classes > validate changed visibility (P95 of main thread blocks) 107 ms 88 ms 21.59% 〰️
models tree 50k 3D child elements with different categories and excluded classes > collect nodes 71092 ms 65769 ms 8.09% 〰️
models tree 50k 3D child elements with different categories and excluded classes > collect nodes (P95 of main thread blocks) 79 ms 55 ms 43.64% 〰️
models tree 50k 3D child elements with different categories and excluded classes > validate initial visibility 2186 ms 2137 ms 2.29% 〰️
models tree 50k 3D child elements with different categories and excluded classes > validate initial visibility (P95 of main thread blocks) 0 ms 49 ms -100% 〰️
models tree 50k 3D child elements with different categories and excluded classes > change visibility 52 ms 53 ms -1.89% 〰️
models tree 50k 3D child elements with different categories and excluded classes > change visibility (P95 of main thread blocks) 0 ms 0 ms 0% 🟰
models tree 50k 3D child elements with different categories and excluded classes > validate changed visibility 7667 ms 5533 ms 38.57% 🚨
models tree 50k 3D child elements with different categories and excluded classes > validate changed visibility (P95 of main thread blocks) 67 ms 88 ms -23.86% 〰️
categories tree 50k subCategories search > get search paths 1787 ms 1715 ms 4.20% 〰️
categories tree 50k subCategories search > get search paths (P95 of main thread blocks) 116 ms 110 ms 5.45% 〰️
categories tree 50k subCategories search > load hierarchy from search paths 6177 ms 5819 ms 6.15% 〰️
categories tree 50k subCategories search > load hierarchy from search paths (P95 of main thread blocks) 65 ms 58 ms 12.07% 〰️
categories tree 50k subCategories > collect nodes 6679 ms 6415 ms 4.12% 〰️
categories tree 50k subCategories > collect nodes (P95 of main thread blocks) 43 ms 43 ms 0% 🟰
categories tree 50k subCategories > validate initial visibility 1022 ms 986 ms 3.65% 〰️
categories tree 50k subCategories > validate initial visibility (P95 of main thread blocks) 0 ms 0 ms 0% 🟰
categories tree 50k subCategories > change visibility 372 ms 347 ms 7.20% 〰️
categories tree 50k subCategories > change visibility (P95 of main thread blocks) 28 ms 29 ms -3.45% 〰️
categories tree 50k subCategories > validate changed visibility 1091 ms 1063 ms 2.63% 〰️
categories tree 50k subCategories > validate changed visibility (P95 of main thread blocks) 32 ms 28 ms 14.29% 〰️
categories tree 50k categories and excluded classes > collect nodes 126828 ms 114664 ms 10.61% 🚨
categories tree 50k categories and excluded classes > collect nodes (P95 of main thread blocks) 113 ms 110 ms 2.73% 〰️
categories tree 50k categories and excluded classes > validate initial visibility 5507 ms 5218 ms 5.54% 〰️
categories tree 50k categories and excluded classes > validate initial visibility (P95 of main thread blocks) 65 ms 37 ms 75.68% 〰️
categories tree 50k categories and excluded classes > change visibility 899 ms 788 ms 14.09% 🚨
categories tree 50k categories and excluded classes > change visibility (P95 of main thread blocks) 84 ms 52 ms 61.54% 〰️
categories tree 50k categories and excluded classes > validate changed visibility 5982 ms 5496 ms 8.84% 〰️
categories tree 50k categories and excluded classes > validate changed visibility (P95 of main thread blocks) 50 ms 38 ms 31.58% 〰️
categories tree 50k categories and excluded classes > collect nodes 129130 ms 114664 ms 12.62% 🚨
categories tree 50k categories and excluded classes > collect nodes (P95 of main thread blocks) 206 ms 110 ms 87.27% 🚨
categories tree 50k categories and excluded classes > validate initial visibility 6184 ms 5218 ms 18.51% 🚨
categories tree 50k categories and excluded classes > validate initial visibility (P95 of main thread blocks) 53 ms 37 ms 43.24% 〰️
categories tree 50k categories and excluded classes > change visibility 856 ms 788 ms 8.63% 〰️
categories tree 50k categories and excluded classes > change visibility (P95 of main thread blocks) 64 ms 52 ms 23.08% 〰️
categories tree 50k categories and excluded classes > validate changed visibility 8849 ms 5496 ms 61.01% 🚨
categories tree 50k categories and excluded classes > validate changed visibility (P95 of main thread blocks) 53 ms 38 ms 39.47% 〰️
classifications tree 50k classifications search > get search paths 2744 ms 2521 ms 8.85% 〰️
classifications tree 50k classifications search > get search paths (P95 of main thread blocks) 226 ms 190 ms 18.95% 〰️
classifications tree 50k classifications search > load hierarchy from search paths 69114 ms 64162 ms 7.72% 〰️
classifications tree 50k classifications search > load hierarchy from search paths (P95 of main thread blocks) 27 ms 27 ms 0% 🟰
classifications tree 50k classifications and excluded classes > collect nodes 35573 ms 33874 ms 5.02% 〰️
classifications tree 50k classifications and excluded classes > collect nodes (P95 of main thread blocks) 66 ms 99 ms -33.33% 〰️
classifications tree 50k classifications and excluded classes > validate initial visibility 3075 ms 2846 ms 8.05% 〰️
classifications tree 50k classifications and excluded classes > validate initial visibility (P95 of main thread blocks) 0 ms 0 ms 0% 🟰
classifications tree 50k classifications and excluded classes > change visibility 184 ms 159 ms 15.72% 〰️
classifications tree 50k classifications and excluded classes > change visibility (P95 of main thread blocks) 24 ms 0 ms 2400% 〰️
classifications tree 50k classifications and excluded classes > validate changed visibility 3756 ms 3484 ms 7.81% 〰️
classifications tree 50k classifications and excluded classes > validate changed visibility (P95 of main thread blocks) 80 ms 98 ms -18.37% 〰️
classifications tree 50k classifications and excluded classes > collect nodes 36648 ms 33874 ms 8.19% 〰️
classifications tree 50k classifications and excluded classes > collect nodes (P95 of main thread blocks) 52 ms 99 ms -47.47% 〰️
classifications tree 50k classifications and excluded classes > validate initial visibility 3073 ms 2846 ms 7.98% 〰️
classifications tree 50k classifications and excluded classes > validate initial visibility (P95 of main thread blocks) 0 ms 0 ms 0% 🟰
classifications tree 50k classifications and excluded classes > change visibility 177 ms 159 ms 11.32% 〰️
classifications tree 50k classifications and excluded classes > change visibility (P95 of main thread blocks) 24 ms 0 ms 2400% 〰️
classifications tree 50k classifications and excluded classes > validate changed visibility 3647 ms 3484 ms 4.68% 〰️
classifications tree 50k classifications and excluded classes > validate changed visibility (P95 of main thread blocks) 51 ms 98 ms -47.96% 〰️

This comment was automatically generated by workflow using github-action-benchmark.

Comment thread packages/tree-widget/src/test/trees/common/internal/VisibilityUtils.test.ts Outdated
@JonasDov

Copy link
Copy Markdown
Contributor Author

@saskliutas I have made changes to when buttons are disabled and their tooltips. Previously we would allow clicking header buttons even when models/categories arrays were empty, now they are disabled. Tooltip of disabled buttons now shows Loading when data is not yet loaded. What do you think?

@saskliutas

Copy link
Copy Markdown
Member

@saskliutas I have made changes to when buttons are disabled and their tooltips. Previously we would allow clicking header buttons even when models/categories arrays were empty, now they are disabled. Tooltip of disabled buttons now shows Loading when data is not yet loaded. What do you think?

I don't like disabled buttons with loading tooltip. Can we leave it as is? It will be noop until data is loaded? Ideally we would show skeleton buttons while loading but I think active noop button should be fine because if I understand correctly in that case where buttons are loading data tree will be loading too?

@JonasDov

Copy link
Copy Markdown
Contributor Author

but I think active noop button should be fine because if I understand correctly in that case where buttons are loading data tree will be loading too?

Well, not exactly. Tree nodes can be loaded without loading that data in. Models/Categories trees don't use that data to load the root hierarchy level, they use it to validate visibility. So, there is a point (especially noticeable on larger imodels) where root nodes are loaded, but element-model-categories query has not yet finished. So I see root nodes, I can click header buttons, but nothing happens. That's why I wanted to add the disabled state for such scenarios.

@JonasDov

Copy link
Copy Markdown
Contributor Author

I don't like disabled buttons with loading tooltip. Can we leave it as is? It will be noop until data is loaded? Ideally we would show skeleton buttons while loading but I think active noop button should be fine because if I understand correctly in that case where buttons are loading data tree will be loading too?

Added skeleton buttons which are displayed when models/categories arrays are empty AND cache has not yet loaded items.
Buttons are now disabled if those arrays are empty. Here is how it looks:
image

@JonasDov
JonasDov merged commit f066a3d into tree-widget/next Jul 30, 2026
15 of 16 checks passed
@JonasDov
JonasDov deleted the JonasD/header-buttons branch July 30, 2026 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants