From e3dfbf6591da8b2e1ee15530ad6b250422886e8e Mon Sep 17 00:00:00 2001 From: Codeman maintainer Date: Tue, 6 Oct 2026 03:53:47 +0200 Subject: [PATCH] feat(tabs): Tab Layout setting with by case (A) and ledger (B), reversible state order, cleaner tiles (#426) Tab Grouping becomes Tab Layout (tabArrangement: 'state' | 'case' | 'ledger' | 'classic', default 'state'), the first row of App Settings, Appearance, Tabs, so the old and the new strip are one choice apart. - By case (option A): each case's tabs sit in one .tab-cluster box in first-appearance order, labelled with the case and its count, coloured by a stable hash into the session palette. Membership is _mobileOverviewCaseFor(), the home screens' own match. Inside a box with company a generated w75-api-gateway reads w75; the - stays in the DOM in a .tab-name-case span only .tabs-clusters hides. The incremental render path rebuilds only when the cluster structure key changes. The rail and the sidebar get a labelled section per case; phones dissolve the boxes into the chip row. Drag stays inside one box. - Ledger (option B): CSS only on .tabs-ledger, desktop header strip: an auto-fill column grid of equal cells in mono type with a 3px status bar. Its markup is identical to classic's. - State Order (tabStateOrder: 'urgent-first' | 'urgent-last'): flips the by-state groups so needs you can be the bottom row. - By state: the label column is measured to the widest label on screen and the labels are right-aligned in it, instead of a fixed 92px gutter that left short labels far from their tabs. - Tiles: a three-row grid (label, value, bar) with pixel line-heights in the bundled JetBrains Mono, 36px like the header. The bar used to lie over a fixed 28px tile, and a taller system mono (SF Mono) pushed the value into it. The WS tile's grid moved onto an inner .connection-tile span because JS writes the indicator's display inline. Compact uses the same font and a matched WS size. Tests: test/tab-clusters.test.ts (new), plus the rename and the reversed order in test/tab-triage.test.ts. Co-Authored-By: Claude Opus 5.5 (1M context) --- CLAUDE.md | 4 +- docs/architecture-invariants.md | 18 +- docs/wiki/Settings-Reference.md | 5 +- docs/wiki/The-Dashboard.md | 36 ++-- src/web/public/app.js | 233 ++++++++++++++++++++++--- src/web/public/constants.js | 83 ++++++++- src/web/public/index.html | 39 +++-- src/web/public/mobile.css | 13 +- src/web/public/settings-ui.js | 50 ++++-- src/web/public/styles.css | 278 ++++++++++++++++++++++++++---- src/web/schemas.ts | 23 ++- test/header-stats-style.test.ts | 2 +- test/tab-clusters.test.ts | 296 ++++++++++++++++++++++++++++++++ test/tab-rail-order.test.ts | 4 +- test/tab-triage.test.ts | 83 +++++++-- 15 files changed, 1025 insertions(+), 142 deletions(-) create mode 100644 test/tab-clusters.test.ts diff --git a/CLAUDE.md b/CLAUDE.md index f9f56697..9f8f5d01 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -333,9 +333,9 @@ Frontend JS modules have `@fileoverview` with `@dependency`/`@loadorder` tags. L **Session list layout: header strip or left sidebar** (`sessionListLayout`, default `header`; per-device via `displayKeys`, also in `SettingsUpdateSchema`): the list can move into a collapsible `