Improve sidebar workspace readability and host identity (#2790)

* fix(app): align turn footer actions

Keep running-turn actions in the same position as completed-turn actions and use the shared small icon size for both copy and fork controls.

* feat(app): improve sidebar workspace identity

Make dense sidebar workspace rows easier to scan and let each device control how connected hosts are identified.

* fix(app): keep host badges readable

Use a compact display menu and keep identity color on the host icon so translated controls fit and badge text retains standard contrast.

* fix(app): announce selected sidebar badge mode

* fix(app): retain icon-only host names for screen readers

* fix(app): name hoisted workspace rows

* fix(app): retain host identity in workspace labels

* fix(app): retain workspace status in row labels

* fix(app): defer host appearance until identity resolves

* fix(app): serialize host appearance writes

* fix(app): serialize host registry writes

* fix(app): bound sidebar host badge labels

* test(app): match workspace status labels

* fix(app): consolidate sidebar identity behavior

* test(app): assert status grouping behavior

* fix(app): keep sidebar row actions accessible

* fix(app): stabilize optimistic message layout
This commit is contained in:
Mohamed Boudra
2026-08-02 16:58:20 +02:00
committed by GitHub
parent 553ac53643
commit ccb668b3b4
57 changed files with 3251 additions and 809 deletions
@@ -116,7 +116,13 @@ async function startTrackingSidebarStatusGroups(page: import("@playwright/test")
capture();
const observer = new MutationObserver(capture);
observer.observe(document.body, { childList: true, subtree: true, characterData: true });
observer.observe(document.body, {
childList: true,
subtree: true,
characterData: true,
attributes: true,
attributeFilter: ["data-testid"],
});
win.__workspaceStatusGroupObserver = observer;
});
}
@@ -159,7 +165,6 @@ async function expectWorkspaceStatusGroupEvents(input: {
rowTestId: string;
includes: string;
excludes: string;
includesIndicator?: string;
excludesIndicator?: string;
}) {
await waitForWorkspaceStatusGroupEvent({
@@ -172,11 +177,6 @@ async function expectWorkspaceStatusGroupEvents(input: {
);
expect(createdWorkspaceEvents.map((event) => event.bucket)).toContain(input.includes);
expect(createdWorkspaceEvents.filter((event) => event.bucket === input.excludes)).toEqual([]);
if (input.includesIndicator) {
expect(createdWorkspaceEvents.map((event) => event.indicatorTestId)).toContain(
input.includesIndicator,
);
}
if (input.excludesIndicator) {
expect(
createdWorkspaceEvents.filter((event) => event.indicatorTestId === input.excludesIndicator),
@@ -612,7 +612,6 @@ test.describe("New workspace flow", () => {
rowTestId,
includes: "running",
excludes: "done",
includesIndicator: "workspace-status-indicator-running",
});
} finally {
await tempRepo.cleanup();