feat(tabs): no label on the idle row (#426)

Idle is the default state of a tab, so naming it only adds noise. The
idle group is now quiet: its heading element stays (it anchors the row's
order band and, as the first row, holds its place beside the brand) but
draws no label or count. Needs you, Waiting and Working are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer
2026-10-06 06:29:40 +02:00
parent bb5fd5ee97
commit 55cafc282f
6 changed files with 28 additions and 12 deletions
+5 -2
View File
@@ -4880,7 +4880,10 @@ class CodemanApp {
};
for (const group of wanted.values()) {
const head = ensure('tab-triage-head', group.key);
if (!head.firstElementChild) {
// A quiet group (idle) keeps its heading as the row's anchor but draws
// no label or count.
head.classList.toggle('tab-triage-head--quiet', !!group.quiet);
if (!group.quiet && !head.firstElementChild) {
const label = document.createElement('span');
label.className = 'tab-triage-label';
label.textContent = group.label;
@@ -4889,7 +4892,7 @@ class CodemanApp {
head.append(label, count);
}
const count = String(group.count);
if (head.lastElementChild.textContent !== count) head.lastElementChild.textContent = count;
if (!group.quiet && head.lastElementChild.textContent !== count) head.lastElementChild.textContent = count;
// The first row's heading is the one that starts beside the brand in the
// header strip (styles.css); every later row starts under it.
head.classList.toggle('tab-triage-head--lead', group === triage.groups[0]);
+6 -2
View File
@@ -684,11 +684,14 @@ function sortSessionsByActivity(rows) {
// after those and the line break that ends the header row at the very end.
//
// Pure: no DOM, no `this`. Unit-tested in test/tab-triage.test.ts.
// `quiet` groups keep their heading element (it anchors the row and holds the
// row's place beside the brand) but draw no text: everything quiet is the
// default state of a tab, so naming it only adds noise.
const TAB_TRIAGE_GROUPS = [
{ key: 'needs', label: 'Needs you' },
{ key: 'waiting', label: 'Waiting' },
{ key: 'working', label: 'Working' },
{ key: 'idle', label: 'Idle' },
{ key: 'idle', label: 'Idle', quiet: true },
];
const TAB_TRIAGE_GROUP_OF_STATE = {
@@ -729,7 +732,7 @@ function tabTriageGroupFor(state, exited) {
* @returns {{
* order: Map<string, number>,
* webOrder: Map<string, number>,
* groups: Array<{key: string, label: string, count: number, headOrder: number, breakOrder: number}>
* groups: Array<{key: string, label: string, quiet: boolean, count: number, headOrder: number, breakOrder: number}>
* }} `groups` lists only the non-empty groups, in display order (most urgent
* first, or last with `reverse`).
*/
@@ -772,6 +775,7 @@ function computeTabTriageLayout(rows, webviewIds, options) {
const groups = sequence.filter((group) => counts[group.key] > 0).map((group) => ({
key: group.key,
label: group.label,
quiet: !!group.quiet,
count: counts[group.key],
headOrder: baseOf[group.key],
breakOrder: baseOf[group.key] + TAB_TRIAGE_STRIDE - 1,