fix(ui): drop empty sidebar session lead columns (#123505)

Reserved 16/20px indicator slots indented titles when there was no artwork.
This commit is contained in:
Ayaan Zaidi
2026-08-14 11:22:16 +05:30
committed by GitHub
parent 65fca84d7c
commit c6dbc96cbf
6 changed files with 27 additions and 31 deletions
@@ -475,7 +475,6 @@ function renderCatalogSessionRow(
}
}}
>
<span class="sidebar-session-indicator"></span>
<span class="sidebar-recent-session__text">
<span class="sidebar-recent-session__name hover-marquee">${label}</span>
</span>
@@ -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`
<div
class=${rowClass}
@@ -276,14 +278,18 @@ export function renderRecentSession(params: {
aria-describedby=${[stateId, metaId].filter(Boolean).join(" ") || nothing}
@click=${(event: MouseEvent) => host.handleSessionRowClick(event, session)}
>
<span class="sidebar-session-indicator"
>${leadingIndicator}
${session.visibility === "draft"
? html`<span class="session-row-draft-indicator" title=${t("chat.sessionSharing.draft")}
>👻</span
>`
: nothing}</span
>
${showLead
? html`<span class="sidebar-session-indicator"
>${leadingIndicator}
${session.visibility === "draft"
? html`<span
class="session-row-draft-indicator"
title=${t("chat.sessionSharing.draft")}
>👻</span
>`
: nothing}</span
>`
: nothing}
<span class="sidebar-recent-session__text">
<span class="sidebar-recent-session__name hover-marquee"
>${session.archived
@@ -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();
});
});
@@ -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}"]`));
});
});
});
@@ -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");
@@ -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();
});