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

github-merge-queue[bot] pushed a commit to branch 
gh-readonly-queue/release/v1.3/pr-8620-fa0d7ee53079e8ae92c5168779156c513a341ad0
in repository https://gitbox.apache.org/repos/asf/texera.git

commit de57530e9e3ee2176600cdd42d6c85bf0bde4355
Author: Meng Wang <[email protected]>
AuthorDate: Mon Sep 21 20:07:41 2026 +0000

    fix(frontend, v1.3): refresh a dataset's paths after a rename, and block 
renaming mid-upload (#8620)
    
    ### What changes were proposed in this PR?
    
    Backport of #8347 to `release/v1.3`: a clean cherry-pick of its squash
    commit, no adaptations — the backport commit reuses the squash message
    and author, as the automated fast path would. See #8347 for the change
    itself (after a rename the detail page kept serving the old paths, so
    file preview and single-file download 404'd until a reload; renaming
    during an upload was also allowed).
    
    Opened manually by the v1.3 release manager: the automated fast path
    cherry-picked this cleanly and then pushed it straight to
    `release/v1.3`, where the Merge Queue ruleset rejected the push
    (`GH013`, [run
    33706287941](https://github.com/apache/texera/actions/runs/33706287941)).
    The Actions-app bypass meant to unblock that path (#8379) was never
    created — asfyaml rejects an `Integration` bypass actor — and the
    failing job's notification 403s for want of `pull-requests: write`, so
    the loss left neither a backport PR nor a comment on #8347. See #8377.
    
    Source: 4ff0b8b4ac415c4d60bfd73f37da5e3039ade2ec
    
    ### Any related issues, documentation, discussions?
    
    Backport of #8347. Originally linked #8345.
    
    ### How was this PR tested?
    
    The change is identical to #8347, which carries the specs
    (`dataset-detail.component.spec.ts`); the backport tree is verified
    byte-identical to cherry-picking the squash commit onto `release/v1.3`,
    and release-branch CI runs the full matrix on this PR. It touches the
    same three files as #8343's backport; the two apply cleanly onto this
    branch in either order.
    
    ### Was this PR authored or co-authored using generative AI tooling?
    
    Yes. Generated-by: Claude Code (claude-opus-5)
    
    Co-authored-by: Tanishq Gandhi 
<[email protected]>
---
 .../dataset-detail.component.html                  | 11 +++++-
 .../dataset-detail.component.spec.ts               | 43 ++++++++++++++++++++++
 .../dataset-detail.component.ts                    | 11 ++++++
 3 files changed, 64 insertions(+), 1 deletion(-)

diff --git 
a/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.html
 
b/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.html
index 5263213bbb..1053ea7c27 100644
--- 
a/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.html
+++ 
b/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.html
@@ -455,7 +455,8 @@
               [resourceName]="datasetName"
               [endpoint]="datasetEndpoint"
               [createVersion]="createDatasetVersion"
-              (versionCreated)="onVersionCreated()">
+              (versionCreated)="onVersionCreated()"
+              (uploadsInFlightChange)="uploadsInFlight = $event">
             </texera-version-uploader>
           </div>
         </nz-sider>
@@ -473,14 +474,22 @@
           <div class="settings-name-label">
             <label>Dataset name</label>
             <p class="settings-hint">Lowercase letters, numbers and 
hyphens.</p>
+            <p
+              *ngIf="uploadsInFlight"
+              class="settings-hint">
+              An upload is in progress — finish or cancel it in Versions &amp; 
Files first, or it will be left
+              incomplete.
+            </p>
           </div>
           <div class="settings-name-controls">
             <input
               nz-input
+              [disabled]="uploadsInFlight"
               [(ngModel)]="editedDatasetName" />
             <button
               nz-button
               nzType="primary"
+              [disabled]="uploadsInFlight"
               (click)="onSaveDatasetName()">
               Save
             </button>
diff --git 
a/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.spec.ts
 
b/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.spec.ts
index 617ae66559..11be93b137 100644
--- 
a/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.spec.ts
+++ 
b/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.spec.ts
@@ -1544,6 +1544,37 @@ describe("DatasetDetailComponent behavior", () => {
 
       expect(datasetServiceStub.updateDatasetName).not.toHaveBeenCalled();
     });
+
+    it("refetches the file tree and the latest-version facts, which both embed 
the old name", () => {
+      datasetServiceStub.updateDatasetName.mockReturnValue(of({}));
+      createComponent();
+      component.did = 5;
+      component.selectedVersion = makeVersion({ dvid: 12 });
+      component.editedDatasetName = "new-name";
+      datasetServiceStub.retrieveDatasetVersionFileTree.mockClear();
+      datasetServiceStub.retrieveDatasetLatestVersion.mockClear();
+
+      component.onSaveDatasetName();
+
+      
expect(datasetServiceStub.retrieveDatasetVersionFileTree).toHaveBeenCalledWith(5,
 12, component.isLogin);
+      
expect(datasetServiceStub.retrieveDatasetLatestVersion).toHaveBeenCalledWith(5);
+      // The browsed version stays put: a rename is not a reason to jump to 
the newest one.
+      expect(component.selectedVersion?.dvid).toBe(12);
+    });
+
+    it("refuses to rename while an upload is in flight, which would strand 
it", () => {
+      createComponent();
+      component.did = 5;
+      component.uploadsInFlight = true;
+      component.editedDatasetName = "new-name";
+
+      component.onSaveDatasetName();
+
+      expect(datasetServiceStub.updateDatasetName).not.toHaveBeenCalled();
+      expect(notificationServiceStub.error).toHaveBeenCalledWith(
+        "Finish or cancel the upload in progress before renaming this dataset"
+      );
+    });
   });
 
   describe("onDeleteDataset", () => {
@@ -2521,6 +2552,18 @@ describe("DatasetDetailComponent rendered template", () 
=> {
       expect(datasetService.updateDatasetDescription).toHaveBeenCalledWith(5, 
"brand new");
     });
 
+    it("locks the name field while an upload is in flight", () => {
+      const el = render({ did: 5, datasetName: "ds", userDatasetAccessLevel: 
"WRITE" });
+      openTab("Versions & Files");
+
+      
fixture.debugElement.query(By.css("texera-version-uploader")).triggerEventHandler("uploadsInFlightChange",
 true);
+      flush();
+      openTab("Settings");
+
+      expect(q<HTMLInputElement>(el, ".settings-name-controls 
input").disabled).toBe(true);
+      expect(q<HTMLButtonElement>(el, ".settings-name-controls 
button").disabled).toBe(true);
+    });
+
     it("deletes the dataset only once the confirmation is accepted", () => {
       const el = render({ did: 5, datasetName: "ds", userDatasetAccessLevel: 
"WRITE", isOwner: true });
       openTab("Settings");
diff --git 
a/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.ts
 
b/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.ts
index 72f89eb57b..9d38dab9ad 100644
--- 
a/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.ts
+++ 
b/frontend/src/app/dashboard/component/user/user-dataset/user-dataset-explorer/dataset-detail.component.ts
@@ -141,6 +141,7 @@ export class DatasetDetailComponent implements OnInit {
 
   public versions: ReadonlyArray<DatasetVersion> = [];
   public selectedVersion: DatasetVersion | undefined;
+  public uploadsInFlight = false;
   public fileTreeNodeList: DatasetFileNode[] = [];
   public selectedVersionCreationTime: string = "";
   // The following three fields describe the latest version for the Data Card, 
all
@@ -599,6 +600,10 @@ export class DatasetDetailComponent implements OnInit {
     if (!this.did) {
       return;
     }
+    if (this.uploadsInFlight) {
+      this.notificationService.error("Finish or cancel the upload in progress 
before renaming this dataset");
+      return;
+    }
     // Reject invalid names outright instead of silently rewriting them, 
matching
     // the shared validation used by the other rename entry points (PR #6426).
     const name = this.editedDatasetName;
@@ -615,6 +620,12 @@ export class DatasetDetailComponent implements OnInit {
         next: () => {
           this.datasetName = name;
           this.editedDatasetName = name;
+          // Every file path embeds the dataset name, and preview and 
single-file download resolve
+          // a dataset by (owner, name) — a stale tree 404s until reload.
+          if (this.selectedVersion) {
+            this.onVersionSelected(this.selectedVersion);
+          }
+          this.retrieveLatestVersionFile();
           this.notificationService.success(`Dataset name updated to 
'${name}'`);
         },
         error: (err: unknown) => {

Reply via email to