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-8589-9264975c2d05d2520593f84060b39db23ab8eae0 in repository https://gitbox.apache.org/repos/asf/texera.git
commit d11878426b59967e5466ef6a927ef1a97d63b606 Author: Meng Wang <[email protected]> AuthorDate: Fri Sep 18 07:12:01 2026 +0000 fix(frontend): keep the warehouse run-button label inside the button, and name the picker in its tooltip (#8589) ### What changes were proposed in this PR? A follow-up to the warehouse picker (#8551). - **The run button's label overflowed.** `#run-button` is a fixed 140px, which fits `Empty Workflow` with about a pixel to spare; `Create Warehouse` ran roughly 13px past it and spilled over the execution timer. The label is now `Warehouse` — the same word the picker's own empty state already shows, mirroring how the computing-unit flow repeats `Connect` in both places — and the button keeps its fixed width, so nothing else on the toolbar moves. - **The trigger's tooltip now reads `Warehouse: <name>`.** Two pickers sit side by side showing nothing but a name, and the trigger ellipsises that name at 220px; one tooltip says which picker this is and carries the name in full, in the same shape every time — short names included, so there is nothing to learn about when it appears. It replaces "Warehouse this execution writes to", which named the picker but not the warehouse. Flag off (the default): the picker never renders and the run button is untouched. ### before: <img width="715" height="208" alt="Screenshot 2026-09-17 at 11 28 13 PM" src="https://github.com/user-attachments/assets/59f58e27-259d-413d-aca2-ce2bbf2aec24" /> <img width="761" height="191" alt="Screenshot 2026-09-17 at 11 29 10 PM" src="https://github.com/user-attachments/assets/c0cd7e1e-ea60-4f0f-b5c0-48b445c42d12" /> ### after: <img width="657" height="165" alt="Screenshot 2026-09-17 at 11 30 12 PM" src="https://github.com/user-attachments/assets/e007fcaf-7771-4030-a961-49e361cf14aa" /> <img width="758" height="278" alt="Screenshot 2026-09-17 at 11 30 45 PM" src="https://github.com/user-attachments/assets/2771ae7d-0713-40a1-af96-7f0324996089" /> ### Any related issues, documentation, discussions? Follow-up to #8551. Part of #6870. The remaining divergences are on the computing-unit side and are tracked separately in #8587; a warehouse status badge needs a backend signal first (#8588). ### How was this PR tested? - Label widths measured in a browser against the button's real clipping width (140px minus padding, border and icon leaves ~106px for text) across the font stack's macOS, Windows and Linux faces: `Warehouse` 72px, `Create Warehouse` 119px, and main's own `Empty Workflow`/`Invalid Workflow` 105px. - Vitest: the run-button label test updated, a tooltip test added covering both a long and a short name and pinning one tooltip per control; the workspace suite passes in full (3323 tests). - Failure paths verified rather than assumed: the label and the tooltip's name were each reverted on purpose and the suite confirmed to fail for the expected reason before being restored. ### Was this PR authored or co-authored using generative AI tooling? Generated-by: Claude Code (claude-opus-5, claude-fable-5) --- .../component/menu/menu.component.spec.ts | 6 ++++-- .../app/workspace/component/menu/menu.component.ts | 5 +++-- .../computing-unit-selection.component.html | 2 +- .../computing-unit-selection.component.scss | 2 ++ .../computing-unit-selection.component.spec.ts | 25 ++++++++++++++++++++++ .../computing-unit-selection.component.ts | 11 ++++++++++ 6 files changed, 46 insertions(+), 5 deletions(-) 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 5996762420..e23d4b9890 100644 --- a/frontend/src/app/workspace/component/menu/menu.component.spec.ts +++ b/frontend/src/app/workspace/component/menu/menu.component.spec.ts @@ -414,7 +414,7 @@ describe("MenuComponent", () => { it("keeps Pause in control of a running execution even when the warehouse disappears", () => { // Deleting the last warehouse mid-run flips warehouseRequiredButMissing; - // the primary button must stay Pause/Kill, not become "Create Warehouse". + // the primary button must stay Pause/Kill, not become the warehouse prompt. component.isWorkflowValid = true; component.isWorkflowEmpty = false; component.computingUnitStatus = ComputingUnitState.Running; @@ -441,7 +441,9 @@ describe("MenuComponent", () => { const behavior = component.getRunButtonBehavior(); - expect(behavior.text).toBe("Create Warehouse"); + // Same word the picker's own empty state shows, as CU repeats "Connect"; + // it also has to fit the run button's fixed width. + expect(behavior.text).toBe("Warehouse"); expect(behavior.icon).toBe("plus-circle"); expect(behavior.disable).toBe(false); }); diff --git a/frontend/src/app/workspace/component/menu/menu.component.ts b/frontend/src/app/workspace/component/menu/menu.component.ts index 04da8e2b08..fe8d2de53a 100644 --- a/frontend/src/app/workspace/component/menu/menu.component.ts +++ b/frontend/src/app/workspace/component/menu/menu.component.ts @@ -422,7 +422,8 @@ export class MenuComponent implements OnInit, OnDestroy { } // Per-user warehouses enabled but none to write to (#7817): mirror the - // Connect state above — name the fixing action, and runWorkflow() routes + // Connect state above — same word as the picker's own empty state, and + // runWorkflow() routes // the click into the create-warehouse modal. Only in the states whose // button would start a run: mid-execution the button is Pause/Resume/Kill, // and losing the last warehouse must not take that control away. @@ -437,7 +438,7 @@ export class MenuComponent implements OnInit, OnDestroy { ].includes(this.executionState) ) { return { - text: "Create Warehouse", + text: "Warehouse", icon: "plus-circle", disable: false, onClick: () => this.runWorkflow(), diff --git a/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.html b/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.html index ddbd2249a4..17224ec394 100644 --- a/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.html +++ b/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.html @@ -68,7 +68,7 @@ (nzVisibleChange)="onWarehouseDropdownVisibilityChange($event)" class="warehouse-dropdown-button" nz-tooltip - nzTooltipTitle="Warehouse this execution writes to"> + [nzTooltipTitle]="warehouseButtonTooltip"> <div class="button-content"> <texera-user-avatar *ngIf="selectedWarehouse as selected" diff --git a/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.scss b/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.scss index ce27d35674..ba5d4bad29 100644 --- a/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.scss +++ b/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.scss @@ -207,6 +207,8 @@ align-items: center; min-width: 220px; max-width: 280px; + // The gap between this picker and the computing-unit one that follows it; + // the computing-unit trigger has none because nothing follows it. margin-right: 4px; padding: 0 8px; overflow: hidden; diff --git a/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.spec.ts b/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.spec.ts index 9f861e0d37..1cdf2052e0 100644 --- a/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.spec.ts +++ b/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.spec.ts @@ -56,6 +56,7 @@ import { ComputingUnitActionsService } from "../../../common/service/computing-u import { ComputingUnitMetadataComponent } from "../../../common/util/computing-unit.util"; import { GuiConfigService } from "../../../common/service/gui-config.service"; import { NzPopoverDirective } from "ng-zorro-antd/popover"; +import { NzTooltipDirective } from "ng-zorro-antd/tooltip"; import { WarehouseService } from "../../../common/service/warehouse/warehouse.service"; import { WarehouseActionsService } from "../../../common/service/warehouse/warehouse-actions.service"; import { DashboardWarehouse } from "../../../common/type/warehouse"; @@ -2840,5 +2841,29 @@ describe("PowerButtonComponent", () => { expect(TestBed.inject(WarehouseService).getSelectedWarehouseIdValue()).toBe(9); expect(statusSpy).not.toHaveBeenCalled(); }); + + it("the trigger's tooltip names the picker and the warehouse, whatever the name's length", () => { + // Two pickers sit side by side showing nothing but a name, and the + // trigger ellipsises at 220px: one tooltip carries both facts, in the + // same shape every time, rather than a second one nested on the name. + const { comp, pickerFixture } = bootPicker({ + enabled: true, + warehouses: [makeWarehouse(1, "wh"), makeWarehouse(2, "a-very-long-warehouse-name-that-truncates")], + latest: "error", + }); + pickerFixture.detectChanges(); + const trigger = pickerFixture.debugElement.query(By.css(".warehouse-dropdown-button")); + const tooltip = trigger.injector.get(NzTooltipDirective) as NzTooltipDirective; + + comp.onWarehouseSelected(2); + pickerFixture.detectChanges(); + expect(tooltip.title).toBe("Warehouse: a-very-long-warehouse-name-that-truncates"); + + comp.onWarehouseSelected(1); + pickerFixture.detectChanges(); + expect(tooltip.title).toBe("Warehouse: wh"); + + expect(pickerFixture.debugElement.query(By.css(".warehouse-name-text[nz-tooltip]"))).toBeNull(); + }); }); }); diff --git a/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.ts b/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.ts index 566e1d9bed..7ee2a14e42 100644 --- a/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.ts +++ b/frontend/src/app/workspace/component/power-button/computing-unit-selection.component.ts @@ -558,6 +558,17 @@ export class ComputingUnitSelectionComponent implements OnInit { return this.warehouseEnabled && this.selectedWarehouseId === undefined; } + /** + * `Warehouse: <name>` — one tooltip that says which picker this is (two of + * them sit side by side showing nothing but a name) and carries the name in + * full, which the trigger ellipsises at 220px. Always the same shape, short + * names included, so there is nothing to learn about when it appears. + */ + get warehouseButtonTooltip(): string { + const selected = this.selectedWarehouse; + return selected ? `Warehouse: ${selected.name}` : "Warehouse"; + } + getWarehouseButtonText(): string { return this.selectedWarehouse?.name ?? "Warehouse"; }
