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-8771-3ba45ee5a5f641388d1a9eda90afa26a62d70d30
in repository https://gitbox.apache.org/repos/asf/texera.git

commit 7ddf661aaa35e1d161ddfb9b6e02193f64636b33
Author: Suryaa Charan <[email protected]>
AuthorDate: Wed Oct 21 21:24:05 2026 +0000

    feat(frontend): explain the Kill button and where to find results and 
errors (#8771)
    
    ### What changes were proposed in this PR?
    
    Two small hints in the workspace:
    
    - **Kill button tooltip:** "Stop this run. A stopped run can't be
    resumed." It was an icon-only button with no explanation.
    - **Empty Result panel:** the heading now says why it is empty: "No
    operator is selected." or "This operator has no results yet." With
    nothing selected it also says "Click an operator to see its results. If
    a run fails, its errors show here." It always adds "Errors an operator
    hits while running show in that operator's Console." A failed run's
    errors only appear in the Static Error tab when nothing is selected, and
    errors during a run pause it and go to the operator's Console. Neither
    hint shows while previewing a workflow version.
    
    Before and after, with nothing selected (top) and an operator selected
    (middle). The bottom row (a failed UDF showing its Static Error tab when
    clicked) is no longer part of this PR: on main that error still arrives
    as "unknown operator", because `ControlError` drops the worker that
    #8668 attaches. That will be fixed in the backend in a separate PR.
    
    
    <img width="1648" height="854" alt="texera-8771-before-after-v2"
    
src="https://github.com/user-attachments/assets/b1034c28-ce7d-4baf-b2f2-cfd935bc503e";
    />
    
    
    The tooltip is a native `title`, which browsers don't draw in
    screenshots. I checked it in the running app: hovering the red button
    shows "Stop this run. A stopped run can't be resumed."
    
    ### Any related issues, documentation, discussions?
    
    Part of #8736. Split out of #8737.
    
    ### How was this PR tested?
    
    New specs in `result-panel.component.spec.ts` (nothing selected, an
    operator selected, version preview) and `menu.component.spec.ts` (the
    tooltip).
    
    ```
    cd frontend
    yarn test --include 
src/app/workspace/component/result-panel/result-panel.component.spec.ts 
--include src/app/workspace/component/menu/menu.component.spec.ts
    yarn test
    yarn format:ci
    ```
    
    ### Was this PR authored or co-authored using generative AI tooling?
    
    Generated-by: Claude Code (Claude Opus 5.5)
    
    ---------
    
    Co-authored-by: suryaacharan <[email protected]>
    Co-authored-by: Claude Opus 5.5 <[email protected]>
---
 .../workspace/component/menu/menu.component.html   |  1 +
 .../component/menu/menu.component.spec.ts          |  8 +++++
 .../result-panel/result-panel.component.html       | 10 +++++-
 .../result-panel/result-panel.component.spec.ts    | 41 +++++++++++++++++++++-
 4 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/frontend/src/app/workspace/component/menu/menu.component.html 
b/frontend/src/app/workspace/component/menu/menu.component.html
index c5bde9d41d..32ecd7707d 100644
--- a/frontend/src/app/workspace/component/menu/menu.component.html
+++ b/frontend/src/app/workspace/component/menu/menu.component.html
@@ -438,6 +438,7 @@
         </button>
         <button
           (click)="handleKill()"
+          title="Stop this run. A stopped run can't be resumed."
           [disabled]="
         executionState === ExecutionState.Uninitialized ||
         executionState === ExecutionState.Completed ||
diff --git a/frontend/src/app/workspace/component/menu/menu.component.spec.ts 
b/frontend/src/app/workspace/component/menu/menu.component.spec.ts
index 3a5f8440b8..736f3602b0 100644
--- a/frontend/src/app/workspace/component/menu/menu.component.spec.ts
+++ b/frontend/src/app/workspace/component/menu/menu.component.spec.ts
@@ -1891,6 +1891,14 @@ describe("MenuComponent", () => {
         expect(run).toHaveBeenCalled();
         expect(kill).toHaveBeenCalled();
       });
+
+      it("explains the kill button with a tooltip", () => {
+        fixture.detectChanges();
+
+        expect(q("button[nzdanger]").nativeElement.getAttribute("title")).toBe(
+          "Stop this run. A stopped run can't be resumed."
+        );
+      });
     });
 
     describe("toolbar", () => {
diff --git 
a/frontend/src/app/workspace/component/result-panel/result-panel.component.html 
b/frontend/src/app/workspace/component/result-panel/result-panel.component.html
index d2c6a53549..f46c02358f 100644
--- 
a/frontend/src/app/workspace/component/result-panel/result-panel.component.html
+++ 
b/frontend/src/app/workspace/component/result-panel/result-panel.component.html
@@ -98,8 +98,16 @@
       <div *ngIf="frameComponentConfigs.size === 0">
         <nz-tab nzTitle="Result">
           <div style="text-align: center">
-            <h4>No results available to display.</h4>
+            <h4 *ngIf="previewWorkflowVersion">No results available to 
display.</h4>
+            <h4 *ngIf="!previewWorkflowVersion && !currentOperatorId">No 
operator is selected.</h4>
+            <h4 *ngIf="!previewWorkflowVersion && currentOperatorId">This 
operator has no results yet.</h4>
             <p>Tip: enable the eye icon on the operator and execute the 
workflow to view its results.</p>
+            <ng-container *ngIf="!previewWorkflowVersion">
+              <p *ngIf="!currentOperatorId">
+                Click an operator to see its results. If a run fails, its 
errors show here.
+              </p>
+              <p>Errors an operator hits while running show in that operator's 
Console.</p>
+            </ng-container>
           </div>
         </nz-tab>
       </div>
diff --git 
a/frontend/src/app/workspace/component/result-panel/result-panel.component.spec.ts
 
b/frontend/src/app/workspace/component/result-panel/result-panel.component.spec.ts
index abe5fe1eb2..58c880c73a 100644
--- 
a/frontend/src/app/workspace/component/result-panel/result-panel.component.spec.ts
+++ 
b/frontend/src/app/workspace/component/result-panel/result-panel.component.spec.ts
@@ -750,7 +750,46 @@ describe("ResultPanelComponent", () => {
       component.frameComponentConfigs.clear();
       fixture.detectChanges();
 
-      expect((fixture.nativeElement as HTMLElement).textContent).toContain("No 
results available to display.");
+      expect((fixture.nativeElement as HTMLElement).textContent).toContain("No 
operator is selected.");
+    });
+
+    it("with nothing selected, says to click an operator and where errors 
show", () => {
+      component.width = DEFAULT_WIDTH;
+      component.currentOperatorId = undefined;
+      component.frameComponentConfigs.clear();
+      fixture.detectChanges();
+
+      const text = (fixture.nativeElement as HTMLElement).textContent ?? "";
+      expect(text).toContain("No operator is selected.");
+      expect(text).toContain("Click an operator to see its results. If a run 
fails, its errors show here.");
+      expect(text).toContain("Errors an operator hits while running show in 
that operator's Console.");
+      expect(text).not.toContain("Click an empty spot");
+    });
+
+    it("with an operator already selected, does not say to click an operator", 
() => {
+      component.width = DEFAULT_WIDTH;
+      component.currentOperatorId = "op-1";
+      component.frameComponentConfigs.clear();
+      fixture.detectChanges();
+
+      const text = (fixture.nativeElement as HTMLElement).textContent ?? "";
+      expect(text).toContain("This operator has no results yet.");
+      expect(text).not.toContain("No operator is selected.");
+      expect(text).not.toContain("Click an operator");
+      expect(text).toContain("Errors an operator hits while running show in 
that operator's Console.");
+    });
+
+    it("while previewing a workflow version, shows no click hints", () => {
+      component.width = DEFAULT_WIDTH;
+      component.currentOperatorId = undefined;
+      component.previewWorkflowVersion = true;
+      component.frameComponentConfigs.clear();
+      fixture.detectChanges();
+
+      const text = (fixture.nativeElement as HTMLElement).textContent ?? "";
+      expect(text).toContain("No results available to display.");
+      expect(text).not.toContain("Click an operator");
+      expect(text).not.toContain("Errors an operator hits");
     });
 
     it("renders a tab per frame when frames are present", () => {

Reply via email to