[object Object]

← back to Desktop Dotbar

dotbar: each ticket state (blocked/open/idle/doing/parked) is individually clickable → loads that filtered Fleet board section

fa6b41eb5afcd15246a2de1350936f8988723fcc · 2026-09-23 10:19:37 -0700 · Steve Abrams

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017VyZZwbLBMfoBmdLGuxBuD

Files touched

Diff

commit fa6b41eb5afcd15246a2de1350936f8988723fcc
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Sep 23 10:19:37 2026 -0700

    dotbar: each ticket state (blocked/open/idle/doing/parked) is individually clickable → loads that filtered Fleet board section
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_017VyZZwbLBMfoBmdLGuxBuD
---
 public/index.html | 28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/public/index.html b/public/index.html
index 147cee7..c2ce886 100644
--- a/public/index.html
+++ b/public/index.html
@@ -68,6 +68,9 @@
   .nm { color:var(--dim); font-size:11px; }
   /* the flexible gap that pushes #meta to the far end (right on top; bottom on side) */
   #spacer, #spacer2 { flex:1; -webkit-app-region:drag; }
+  /* Individually-clickable ticket-state segments (Steve 2026-09-23): hover highlights the one under the cursor. */
+  .tkseg { -webkit-app-region:no-drag; transition:background .1s; }
+  .tkseg:hover { background:var(--bg2); box-shadow:inset 0 0 0 1px var(--line); }
   #meta { -webkit-app-region:no-drag; color:var(--dim); font-size:11px; display:flex; gap:10px; align-items:center; }
   body.orient-left #meta, body.orient-right #meta { flex-direction:column; align-items:stretch; gap:6px; }
   #meta b { color:var(--fg); font-variant-numeric:tabular-nums; }
@@ -130,6 +133,8 @@ const ORIENT_LABEL = { top: '▲ Top', left: '◀ Left', right: '▶ Right' };
 
 async function fetchDots(){ try { const r = await fetch('/api/dots'); return await r.json(); } catch { return null; } }
 async function fetchTickets(){ try { const r = await fetch('/api/tickets'); return await r.json(); } catch { return null; } }
+// Open the Fleet board filtered to one section (blocked/open/stopped/doing/parked/all).
+function openBoard(section){ try { window.open(`http://127.0.0.1:9794/?section=${section}&layout=grid`, 'fleet'); } catch(e){} }
 
 function resize(open){
   // Electron shell owns the window bounds via IPC; fall back to resizeTo in a plain browser.
@@ -186,16 +191,21 @@ function renderBar(){
   if (tickets.updated) {
     const tchip = document.createElement('div');
     tchip.className = 'chip tickets';
-    tchip.title = `Board — ${tickets.blocked} blocked · ${tickets.open} open · ${tickets.idle} idle · ${tickets.doing} doing · ${tickets.parked} parked${tickets.latest ? '\n↳ latest: ' + tickets.latest : ''}\nclick → open Fleet board`;
-    const seg = (emoji, n, color) => `<span style="color:${color};font-weight:700">${emoji}${n}</span>`;
-    tchip.innerHTML = `<span class="cnt" style="font-size:12px;display:flex;gap:9px;align-items:center">`
-      + seg('🔴', tickets.blocked, '#f87171')
-      + seg('⚪', tickets.open, '#e5e7eb')
-      + seg('⚫', tickets.idle, '#9ca3af')
-      + seg('🔵', tickets.doing, '#60a5fa')
-      + seg('🩷', tickets.parked, '#f9a8d4')
+    tchip.title = `Board — ${tickets.blocked} blocked · ${tickets.open} open · ${tickets.idle} idle · ${tickets.doing} doing · ${tickets.parked} parked${tickets.latest ? '\n↳ latest: ' + tickets.latest : ''}`;
+    // Each state is INDIVIDUALLY clickable (Steve 2026-09-23): a segment loads the Fleet board
+    // filtered to that section. idle maps to the board's `stopped` section. stopPropagation keeps
+    // a segment click from also firing the whole-chip (all-tickets) fallback.
+    const seg = (emoji, n, section, label, color) =>
+      `<span class="tkseg" title="load ${label} tickets (${n})" onclick="event.stopPropagation();openBoard('${section}')" `
+      + `style="color:${color};font-weight:700;cursor:pointer;padding:2px 4px;border-radius:5px">${emoji}${n}</span>`;
+    tchip.innerHTML = `<span class="cnt" style="font-size:12px;display:flex;gap:6px;align-items:center">`
+      + seg('🔴', tickets.blocked, 'blocked', 'blocked', '#f87171')
+      + seg('⚪', tickets.open, 'open', 'open', '#e5e7eb')
+      + seg('⚫', tickets.idle, 'stopped', 'idle', '#9ca3af')
+      + seg('🔵', tickets.doing, 'doing', 'doing', '#60a5fa')
+      + seg('🩷', tickets.parked, 'parked', 'parked', '#f9a8d4')
       + `</span>`;
-    tchip.onclick = () => { window.open('http://127.0.0.1:9794/?section=all&layout=grid', 'fleet'); };
+    tchip.onclick = () => openBoard('all');   // clicking the gaps opens the whole board
     bar.appendChild(tchip);
   }
   const sp2 = document.createElement('div'); sp2.id='spacer2'; sp2.className='spacer-grow'; bar.appendChild(sp2);

← 0347444 dotbar: ticket summary centered in the middle band, 5 live s  ·  back to Desktop Dotbar  ·  dotbar: fix ticket-segment clicks — Electron can't window.op 36f503b →