mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-10 01:09:43 +02:00
feat(tabs,header): group tabs by state and add header stats styles (#426)
Two directions from Discussion #426, each a per-device setting and the new default. Tab Grouping (tabGrouping: 'state' | 'none', default 'state', option C): tabs are grouped needs you (red, plus failed sessions), waiting (yellow), working and idle (also ended, exited panes and web tabs), most urgent on top. The desktop header strip draws a row per group with its label and count in a left gutter; the flat vertical rail and the sidebar draw a section per group; tablets keep their scrolling row with inline dividers; phones keep the chip row in group order without headings. Classification is the home screens' own (_mobileOverviewState/_mobileOverviewExit), the fold into four groups is pure in CodemanTabTriage (constants.js). It is flex `order` plus aria-hidden heading/break elements reconciled in place after both render paths, never a DOM reorder, so Alt+N, the keyboard walk and drag keep reading tab order; a drop is refused across groups. Named groups in the vertical rail take precedence. Header Stats Style (headerStatsStyle: 'classic' | 'compact' | 'tiles', default 'tiles', option G): tiles give WS, CPU, MEM and each plan window a label-over-value tile with a bar underneath; compact is one WS/CPU/MEM pill with sparklines plus a plan-ring pill; classic is the header as before. Desktop only (classic below 768px and in solo windows). The clustered styles move #connectionIndicator into #headerSystemStats and WS stays out of a hidden System Stats pill. The extra parts are always rendered and hidden by default in CSS, so classic is unchanged. Tests: test/tab-triage.test.ts, test/header-stats-style.test.ts; three source pins in test/tab-rail-order.test.ts follow renamed lines. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6028,6 +6028,11 @@ Object.assign(CodemanApp.prototype, {
|
||||
}
|
||||
}
|
||||
|
||||
// Sparklines for the Compact header style. Always recorded (four numbers a
|
||||
// poll), so switching styles shows history at once instead of empty bars.
|
||||
this._pushStatSpark('cpu', stats.cpu);
|
||||
this._pushStatSpark('mem', stats.memory?.percent);
|
||||
|
||||
if (memEl && memBar) {
|
||||
const memGB = (stats.memory.usedMB / 1024).toFixed(1);
|
||||
memEl.textContent = `${memGB}G`;
|
||||
@@ -6045,6 +6050,27 @@ Object.assign(CodemanApp.prototype, {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Record one percentage sample and redraw that stat's sparkline: one bar per
|
||||
* sample, newest on the right, as many samples as the template has bars.
|
||||
* Bars stay 10% tall at minimum so an idle machine still draws a baseline.
|
||||
*/
|
||||
_pushStatSpark(key, percent) {
|
||||
const history = (this._statSparkHistory ||= { cpu: [], mem: [] })[key];
|
||||
if (!history) return;
|
||||
const el = this.$(key === 'cpu' ? 'statCpuSpark' : 'statMemSpark');
|
||||
const size = el?.children.length || 4;
|
||||
const value = Number(percent);
|
||||
history.push(Number.isFinite(value) ? Math.min(100, Math.max(0, value)) : 0);
|
||||
while (history.length > size) history.shift();
|
||||
if (!el) return;
|
||||
const offset = size - history.length;
|
||||
for (let i = 0; i < el.children.length; i++) {
|
||||
const sample = history[i - offset];
|
||||
el.children[i].style.height = sample === undefined ? '' : `${Math.max(10, Math.round(sample))}%`;
|
||||
}
|
||||
},
|
||||
|
||||
// ─── Clipboard ──────────────────────────────────────────────────────────────
|
||||
|
||||
async _onClipboardWrite(data) {
|
||||
|
||||
Reference in New Issue
Block a user