From c6dbc96cbf437ca149f2bc324da8f55e457b2862 Mon Sep 17 00:00:00 2001 From: Ayaan Zaidi Date: Fri, 14 Aug 2026 11:22:16 +0530 Subject: [PATCH] fix(ui): drop empty sidebar session lead columns (#123505) Reserved 16/20px indicator slots indented titles when there was no artwork. --- .../app-sidebar-session-catalog-render.ts | 1 - .../app-sidebar-session-row-render.ts | 22 ++++++++++++------- .../catalog-project-activity.ts | 8 ++----- .../app-sidebar-cases/session-indicators.ts | 18 +++++++-------- .../app-sidebar-cases/sessions.ts | 4 +--- .../app-sidebar-cases/sidebar-zone.ts | 5 ++--- 6 files changed, 27 insertions(+), 31 deletions(-) diff --git a/ui/src/components/app-sidebar-session-catalog-render.ts b/ui/src/components/app-sidebar-session-catalog-render.ts index 32bbfafe4e72..e71d503315e0 100644 --- a/ui/src/components/app-sidebar-session-catalog-render.ts +++ b/ui/src/components/app-sidebar-session-catalog-render.ts @@ -475,7 +475,6 @@ function renderCatalogSessionRow( } }} > - ${label} diff --git a/ui/src/components/app-sidebar-session-row-render.ts b/ui/src/components/app-sidebar-session-row-render.ts index 4cb743dc7abb..7ae0205b0b70 100644 --- a/ui/src/components/app-sidebar-session-row-render.ts +++ b/ui/src/components/app-sidebar-session-row-render.ts @@ -242,6 +242,8 @@ export function renderRecentSession(params: { requiredScope: "operator.write", }); const rowDraggable = !session.isChild && groupWriteAccess.allowed; + // Empty 16/20px lead columns indent titles past section labels and siblings. + const showLead = leadingIndicator !== nothing || session.visibility === "draft"; const row = html`
host.handleSessionRowClick(event, session)} > - ${leadingIndicator} - ${session.visibility === "draft" - ? html`👻` - : nothing} + ${showLead + ? html`${leadingIndicator} + ${session.visibility === "draft" + ? html`👻` + : nothing}` + : nothing} ${session.archived diff --git a/ui/src/test-helpers/app-sidebar-cases/catalog-project-activity.ts b/ui/src/test-helpers/app-sidebar-cases/catalog-project-activity.ts index 7c39d00469b4..ce119b7d2c96 100644 --- a/ui/src/test-helpers/app-sidebar-cases/catalog-project-activity.ts +++ b/ui/src/test-helpers/app-sidebar-cases/catalog-project-activity.ts @@ -81,12 +81,8 @@ describe("AppSidebar project session activity", () => { expect(active?.querySelector(".session-run-spinner")?.getAttribute("aria-label")).toBe( "Active run", ); - const activeLead = active?.querySelector(".sidebar-session-indicator"); - const idleLead = idle?.querySelector(".sidebar-session-indicator"); - expect(activeLead).not.toBeNull(); - expect(activeLead?.childElementCount).toBe(0); - expect(idleLead).not.toBeNull(); - expect(idleLead?.childElementCount).toBe(0); + expect(active?.querySelector(".sidebar-session-indicator")).toBeNull(); + expect(idle?.querySelector(".sidebar-session-indicator")).toBeNull(); expect(idle?.querySelector(".session-row-state")).toBeNull(); }); }); diff --git a/ui/src/test-helpers/app-sidebar-cases/session-indicators.ts b/ui/src/test-helpers/app-sidebar-cases/session-indicators.ts index c354d0b65564..5163c2e0cbba 100644 --- a/ui/src/test-helpers/app-sidebar-cases/session-indicators.ts +++ b/ui/src/test-helpers/app-sidebar-cases/session-indicators.ts @@ -6,10 +6,8 @@ import { SESSION_PULL_REQUESTS_SUBSCRIBE_METHOD } from "../../lib/session-pull-r import { createGatewayHarness, createSessionsHarness, mountSidebar } from "../app-sidebar.ts"; import { waitForFast } from "../wait-for.ts"; -function expectEmptyLead(row: Element | null) { - const lead = row?.querySelector(".sidebar-session-indicator"); - expect(lead).not.toBeNull(); - expect(lead?.childElementCount).toBe(0); +function expectNoLead(row: Element | null) { + expect(row?.querySelector(".sidebar-session-indicator")).toBeNull(); } describe("AppSidebar session indicators", () => { @@ -198,11 +196,11 @@ describe("AppSidebar session indicators", () => { expect(sidebar.querySelector('[data-session-pr-state="merged"]')).not.toBeNull(); }); const plain = sidebar.querySelector(`[data-session-key="${keys.plain}"]`); - expectEmptyLead(plain); + expectNoLead(plain); expect(plain?.querySelector(".session-row-state")).toBeNull(); const forked = sidebar.querySelector(`[data-session-key="${keys.forked}"]`); - expectEmptyLead(forked); + expectNoLead(forked); expect( forked?.querySelector(".session-row-aside > .session-row-state .session-row-fork-indicator"), ).not.toBeNull(); @@ -212,14 +210,14 @@ describe("AppSidebar session indicators", () => { expect(forked?.querySelector(".session-row-fork-indicator")?.hasAttribute("title")).toBe(false); const unread = sidebar.querySelector(`[data-session-key="${keys.unread}"]`); - expectEmptyLead(unread); + expectNoLead(unread); expect( unread?.querySelector(".session-row-aside > .session-row-state .session-unread-dot"), ).not.toBeNull(); const runningUnread = sidebar.querySelector(`[data-session-key="${keys.runningUnread}"]`); expect(runningUnread?.classList.contains("session-row-host--running")).toBe(true); - expectEmptyLead(runningUnread); + expectNoLead(runningUnread); expect( runningUnread?.querySelector(".session-row-aside > .session-row-state .session-run-spinner"), ).not.toBeNull(); @@ -243,7 +241,7 @@ describe("AppSidebar session indicators", () => { for (const key of [keys.openPullRequest, keys.mergedPullRequest]) { const row = sidebar.querySelector(`[data-session-key="${key}"]`); - expectEmptyLead(row); + expectNoLead(row); expect(row?.querySelector(".session-row-state [data-session-pr-state]")).not.toBeNull(); expect(row?.querySelector("a")?.getAttribute("title")).toContain( key === keys.openPullRequest ? "Open PR" : "Merged", @@ -259,7 +257,7 @@ describe("AppSidebar session indicators", () => { sessions.publishList({ result }); await waitForFast(() => { expect(sidebar.querySelector('[data-session-pr-state="open"]')).toBeNull(); - expectEmptyLead(sidebar.querySelector(`[data-session-key="${keys.openPullRequest}"]`)); + expectNoLead(sidebar.querySelector(`[data-session-key="${keys.openPullRequest}"]`)); }); }); }); diff --git a/ui/src/test-helpers/app-sidebar-cases/sessions.ts b/ui/src/test-helpers/app-sidebar-cases/sessions.ts index 2f09b5376e7a..e7b3e86c3634 100644 --- a/ui/src/test-helpers/app-sidebar-cases/sessions.ts +++ b/ui/src/test-helpers/app-sidebar-cases/sessions.ts @@ -298,9 +298,7 @@ describe("AppSidebar session accessibility", () => { expect(row?.hasAttribute("aria-label")).toBe(false); expect(link?.hasAttribute("aria-label")).toBe(false); expect(link?.getAttribute("aria-current")).toBe("page"); - const lead = link?.querySelector(".sidebar-session-indicator"); - expect(lead).not.toBeNull(); - expect(lead?.childElementCount).toBe(0); + expect(link?.querySelector(".sidebar-session-indicator")).toBeNull(); expect(link?.querySelector(".sidebar-recent-session__text")).not.toBeNull(); const rowState = row?.querySelector(".session-row-state"); expect(rowState?.getAttribute("role")).toBe("img"); diff --git a/ui/src/test-helpers/app-sidebar-cases/sidebar-zone.ts b/ui/src/test-helpers/app-sidebar-cases/sidebar-zone.ts index 53ff925fe88f..05b45292f0cb 100644 --- a/ui/src/test-helpers/app-sidebar-cases/sidebar-zone.ts +++ b/ui/src/test-helpers/app-sidebar-cases/sidebar-zone.ts @@ -149,9 +149,8 @@ describe("AppSidebar interleaved zone", () => { // Pinning is not a status, so it must not claim the row's one leading slot. const row = sidebar.querySelector('[data-session-key="agent:main:page"]'); const plain = sidebar.querySelector('[data-session-key="agent:main:plain"]'); - expect(row?.querySelector(".sidebar-session-indicator")?.innerHTML).toBe( - plain?.querySelector(".sidebar-session-indicator")?.innerHTML, - ); + expect(row?.querySelector(".sidebar-session-indicator")).toBeNull(); + expect(plain?.querySelector(".sidebar-session-indicator")).toBeNull(); expect(row?.querySelector(".nav-item__state")).toBeNull(); expect(row?.querySelector(".session-row-state .sidebar-recent-session__state")).not.toBeNull(); });