From 0575610f4cf6670e211e1087c4feb7f09ec06f41 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 8 Aug 2026 03:47:26 -0700 Subject: [PATCH] refactor(ui): align sidebar session list on a single lead-slot rail (#120473) * refactor(ui): align sidebar session list on a single lead-slot rail * fix(ui): keep sidebar group drag handle interactive * fix(ui): keep catalog chevron visible on touch devices Touch contexts have no hover, so branded catalog headers keep the chevron as their resting affordance (ClawSweeper P2 on #120473). --- .../app-sidebar-session-catalog-render.ts | 27 ++- .../app-sidebar-session-list-render.ts | 9 +- .../app-sidebar-session-row-render.ts | 16 +- .../components/session-leading-indicator.ts | 5 +- ui/src/e2e/claude-sessions.e2e.test.ts | 31 +++- ui/src/styles/layout.css | 155 ++++++++++++------ .../app-sidebar-cases/catalog-live.ts | 20 +-- .../catalog-project-activity.ts | 8 +- .../app-sidebar-cases/session-indicators.ts | 22 +-- .../session-list-sections.ts | 8 +- .../app-sidebar-cases/session-ownership.ts | 1 - .../app-sidebar-cases/sessions.ts | 6 +- 12 files changed, 202 insertions(+), 106 deletions(-) diff --git a/ui/src/components/app-sidebar-session-catalog-render.ts b/ui/src/components/app-sidebar-session-catalog-render.ts index 8216e6f60790..a5e8183da95e 100644 --- a/ui/src/components/app-sidebar-session-catalog-render.ts +++ b/ui/src/components/app-sidebar-session-catalog-render.ts @@ -138,6 +138,7 @@ export function renderSessionCatalogGroups(params: SessionCatalogGroupsParams) { }); const hasActiveRun = liveRows.some((row) => row.hasActiveRun === true); const hasUnread = liveRows.some((row) => row.unread === true); + const hasBrandIcon = hasProviderBrandIcon(catalog.id); const loadingMore = params.loadingMoreCatalogIds.has(catalog.id); const hasMore = hosts.some((host) => Boolean(host.nextCursor)); const canCreateSession = catalog.capabilities.createSession !== undefined; @@ -199,15 +200,22 @@ export function renderSessionCatalogGroups(params: SessionCatalogGroupsParams) { title=${hasError ? errorHelp : nothing} @click=${() => params.onToggleSection(sectionId)} > - ${hasProviderBrandIcon(catalog.id) - ? renderProviderBrandIcon(catalog.id, { - className: "sidebar-session-catalog-provider-icon", - }) - : nothing} - ${catalog.label} - + ${hasBrandIcon + ? renderProviderBrandIcon(catalog.id, { + className: "sidebar-session-catalog-provider-icon", + }) + : nothing} + ${collapsed ? icons.chevronRight : icons.chevronDown} + + ${catalog.label} ${renderCatalogHeaderStatus(hasActiveRun, hasUnread)} ${hasError || (collapsed && rows.length > 0) ? html` + ${label} diff --git a/ui/src/components/app-sidebar-session-list-render.ts b/ui/src/components/app-sidebar-session-list-render.ts index dbe73c2866e8..fd96c5962b4a 100644 --- a/ui/src/components/app-sidebar-session-list-render.ts +++ b/ui/src/components/app-sidebar-session-list-render.ts @@ -134,10 +134,12 @@ function renderSessionSection(params: { aria-label=${label} @click=${() => host.toggleSection(section.id)} > + ${label} - ${collapsed && totalRowCount > 0 ? html`${totalRowCount}` : nothing} @@ -248,6 +250,7 @@ function renderDraftSessionRow() { return html`