This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch 
gh-readonly-queue/main/pr-8838-b43d46520365a42e8a5df892520bead6b2fb6cfe
in repository https://gitbox.apache.org/repos/asf/texera.git

commit 9a427ccfc8f2821a5ecd4a6a502baacc45c6d1cb
Author: Tanishq Gandhi <[email protected]>
AuthorDate: Tue Oct 6 21:48:31 2026 +0000

    fix(frontend): list a version's files when the Versions & Files tab opens 
(#8838)
    
    ### What changes were proposed in this PR?
    
    The version file tree uses virtual scroll, which measures its viewport
    once and then only on scroll. On the dataset and model detail pages the
    tree sits in the "Versions & Files" tab, which is hidden when the page
    loads. So the files arrived while the tree measured a 0px viewport, and
    it drew no rows until switching versions changed its height and forced a
    re-measure.
    
    The tree now re-measures itself whenever its container is shown or
    resized, using a `ResizeObserver`. The fix is inside the tree component,
    so the dataset page, the model page and the two version pickers that
    reuse it are all covered. No change to the host pages.
    
    - `user-dataset-version-filetree.component.ts`: observe the container
    and call `tree.sizeChanged()` (past the library's throttle) on resize;
    disconnect on destroy. The existing re-measure on a height change goes
    through the same helper.
    - `user-dataset-version-filetree.component.html`: `#container` ref on
    the tree's container.
    
    Before: dataset and model right after opening the tab:
    
    <img width="1440" height="900" alt="annotated-before-dataset"
    
src="https://github.com/user-attachments/assets/01d99d8c-179b-455f-ab03-68357b3164f3";
    />
    
    <img width="1440" height="900" alt="annotated-before-model"
    
src="https://github.com/user-attachments/assets/01631a0b-0d66-428a-8161-17ba0568efe3";
    />
    
    
    After: the same pages right after opening the tab:
    
    <img width="1440" height="900" alt="annotated-after-dataset"
    
src="https://github.com/user-attachments/assets/7c754657-b172-4b9f-a6a4-5c7fa53e54f7";
    />
    
    <img width="1440" height="900" alt="annotated-after-model"
    
src="https://github.com/user-attachments/assets/747b0135-923d-4735-b0d8-62c2fed0b348";
    />
    
    ### Any related issues, documentation, discussions?
    
    Closes #8833
    
    ### How was this PR tested?
    
    One case added to
    `user-dataset-version-filetree.component.browser.spec.ts`: a tree filled
    while hidden renders its rows once shown. It fails without the fix (0
    rows) and passes with it.
    
    ```
    cd frontend
    yarn ng run gui:test-browser 
--include='**/user-dataset-version-filetree.component.browser.spec.ts'
    # Tests  6 passed (6)
    yarn ng test --watch=false 
--include='**/user-dataset-version-filetree.component.spec.ts' 
--include='**/dataset-detail.component.spec.ts' 
--include='**/model-detail.component.spec.ts'
    # Tests  249 passed (249)
    ```
    
    Also checked against a local stack: on a dataset and a model with two
    versions, the latest version's files are listed as soon as the "Versions
    & Files" tab opens, and switching versions still updates the list.
    
    ### Was this PR authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Claude Opus 5.5)
    
    Co-authored-by: Meng Wang <[email protected]>
---
 ...aset-version-filetree.component.browser.spec.ts | 12 +++++++
 .../user-dataset-version-filetree.component.html   |  1 +
 .../user-dataset-version-filetree.component.ts     | 40 +++++++++++++++++-----
 3 files changed, 45 insertions(+), 8 deletions(-)

diff --git 
a/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-version-filetree/user-dataset-version-filetree.component.browser.spec.ts
 
b/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-version-filetree/user-dataset-version-filetree.component.browser.spec.ts
index 8124417c1f..ae5429b244 100644
--- 
a/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-version-filetree/user-dataset-version-filetree.component.browser.spec.ts
+++ 
b/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-version-filetree/user-dataset-version-filetree.component.browser.spec.ts
@@ -96,6 +96,18 @@ describe("UserDatasetVersionFiletreeComponent (browser)", () 
=> {
     expect(renderedRows).toBeGreaterThan(0);
   });
 
+  it("renders rows once a tree filled while hidden is shown", async () => {
+    fixture.nativeElement.style.display = "none";
+    await renderTree(makeFlatFileNodes(3));
+    expect(fixture.nativeElement.querySelectorAll("tree-node").length).toBe(0);
+
+    fixture.nativeElement.style.display = "";
+    await vi.waitFor(() => {
+      fixture.detectChanges();
+      
expect(fixture.nativeElement.querySelectorAll("tree-node").length).toBe(3);
+    });
+  });
+
   it("lays out the container at content height for small trees", async () => {
     await renderTree(makeFlatFileNodes(3));
 
diff --git 
a/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-version-filetree/user-dataset-version-filetree.component.html
 
b/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-version-filetree/user-dataset-version-filetree.component.html
index 1b64346316..d564c5edbd 100644
--- 
a/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-version-filetree/user-dataset-version-filetree.component.html
+++ 
b/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-version-filetree/user-dataset-version-filetree.component.html
@@ -18,6 +18,7 @@
 -->
 
 <div
+  #container
   class="file-tree-container"
   [style.height.px]="fileTreeContainerHeightPx"
   [style.--tree-node-height.px]="TREE_NODE_HEIGHT_PX">
diff --git 
a/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-version-filetree/user-dataset-version-filetree.component.ts
 
b/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-version-filetree/user-dataset-version-filetree.component.ts
index a365864333..2e53d5dffa 100644
--- 
a/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-version-filetree/user-dataset-version-filetree.component.ts
+++ 
b/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/user-dataset-version-filetree/user-dataset-version-filetree.component.ts
@@ -18,7 +18,18 @@
  */
 
 import { UntilDestroy } from "@ngneat/until-destroy";
-import { AfterViewInit, Component, EventEmitter, Input, Output, ViewChild } 
from "@angular/core";
+import {
+  AfterViewInit,
+  Component,
+  ElementRef,
+  EventEmitter,
+  inject,
+  Input,
+  NgZone,
+  OnDestroy,
+  Output,
+  ViewChild,
+} from "@angular/core";
 import {
   DatasetFileNode,
   getRelativePathFromDatasetFileNode,
@@ -65,7 +76,10 @@ function countNodes(nodes: DatasetFileNode[]): number {
     NzTooltipDirective,
   ],
 })
-export class UserDatasetVersionFiletreeComponent implements AfterViewInit {
+export class UserDatasetVersionFiletreeComponent implements AfterViewInit, 
OnDestroy {
+  private ngZone = inject(NgZone);
+  private resizeObserver?: ResizeObserver;
+
   @Input()
   public isTreeNodeDeletable: boolean = false;
 
@@ -78,12 +92,8 @@ export class UserDatasetVersionFiletreeComponent implements 
AfterViewInit {
     const newHeight = this.computeContainerHeightPx();
     if (newHeight !== this.fileTreeContainerHeightPx) {
       this.fileTreeContainerHeightPx = newHeight;
-      // The tree measures its viewport once after init and again only on
-      // scroll, so a height change must trigger a re-measure (delayed past
-      // the throttle) — otherwise a tree that starts empty stays blank. For
-      // the same reason, a host that creates this component hidden must call
-      // tree.sizeChanged() on reveal.
-      setTimeout(() => this.tree?.sizeChanged(), 
TREE_VIEWPORT_REMEASURE_DELAY_MS);
+      // The tree re-measures its viewport only on scroll.
+      this.remeasureViewport();
     }
   }
   public get fileTreeNodes(): DatasetFileNode[] {
@@ -95,6 +105,7 @@ export class UserDatasetVersionFiletreeComponent implements 
AfterViewInit {
   public isExpandAllAfterViewInit = false;
 
   @ViewChild("tree") tree: any;
+  @ViewChild("container") container?: ElementRef<HTMLElement>;
 
   @Output()
   setCoverImage = new EventEmitter<string>();
@@ -143,6 +154,19 @@ export class UserDatasetVersionFiletreeComponent 
implements AfterViewInit {
     if (this.isExpandAllAfterViewInit) {
       this.tree.treeModel.expandAll();
     }
+    // Re-measure once a tree created hidden, e.g. in an inactive tab, is 
shown.
+    if (this.container) {
+      this.resizeObserver = new ResizeObserver(() => this.ngZone.run(() => 
this.remeasureViewport()));
+      this.resizeObserver.observe(this.container.nativeElement);
+    }
+  }
+
+  ngOnDestroy(): void {
+    this.resizeObserver?.disconnect();
+  }
+
+  private remeasureViewport(): void {
+    setTimeout(() => this.tree?.sizeChanged(), 
TREE_VIEWPORT_REMEASURE_DELAY_MS);
   }
 
   isImageFile(fileName: string): boolean {

Reply via email to