diff --git a/docs/web-ui/dashboard.md b/docs/web-ui/dashboard.md index f2d75b38..b87a4c08 100644 --- a/docs/web-ui/dashboard.md +++ b/docs/web-ui/dashboard.md @@ -410,12 +410,14 @@ immediate re-fetch. name (populated from `GET /api/state`) and unit filter (`hive-ag3nt.service` / `(full machine journal)`). Fetches `GET /api/journal/{name}?unit=&lines=500` on selection change -or `↻ refresh`. Output rendered as a `
` block. A `?agent=`
-and/or `?unit=` URL param pre-selects the agent + unit on page
-load — the per-agent `⋮` menu's **journal logs →** entry uses this to
-deep-link directly to a specific agent's journal. A "fetched N ago"
-chip appears after the `↻ refresh` button following each successful
-fetch and ticks every 30 s.
+or `↻ refresh`. Output rendered as a `
` block. The last-selected
+agent name and unit are persisted to `localStorage` (`logs-agent` /
+`logs-unit`) and restored on page load. A `?agent=` and/or
+`?unit=` URL param overrides the stored values — the per-agent
+`⋮` menu's **journal logs →** entry uses this to deep-link directly
+to a specific agent's journal. A "fetched N ago" chip appears after
+the `↻ refresh` button following each successful fetch and ticks
+every 30 s.
 
 **SYSTEM sub-tab** — host-side service logs. Unit selector (currently
 only `hive-c0re.service`). Fetches
diff --git a/frontend/packages/dashboard/src/logs.css b/frontend/packages/dashboard/src/logs.css
index 8105be9c..8069c779 100644
--- a/frontend/packages/dashboard/src/logs.css
+++ b/frontend/packages/dashboard/src/logs.css
@@ -71,8 +71,6 @@ body.logs-shell {
   font-size: 0.85em;
 }
 .journal-refresh { font-size: 0.75em; padding: 0.15em 0.5em; }
-/* "fetched N ago" chip next to the refresh button on AGENT + SYSTEM tabs. */
-.logs-fetch-ts { font-size: 0.8em; color: var(--muted); }
 .journal-output {
   margin: 0;
   background: var(--crust);
diff --git a/frontend/packages/dashboard/src/logs.html b/frontend/packages/dashboard/src/logs.html
index 5bd4d38a..2a4ad7c3 100644
--- a/frontend/packages/dashboard/src/logs.html
+++ b/frontend/packages/dashboard/src/logs.html
@@ -56,7 +56,6 @@
           
         
         
-        
       
       
select an agent above
@@ -70,7 +69,6 @@ -
loading…
diff --git a/frontend/packages/dashboard/src/logs.js b/frontend/packages/dashboard/src/logs.js index ef5962f0..b334d1c8 100644 --- a/frontend/packages/dashboard/src/logs.js +++ b/frontend/packages/dashboard/src/logs.js @@ -13,11 +13,6 @@ // - The build list auto-refreshes (debounced 2s) when rebuild_queue_changed // fires from the dashboard SSE stream, so new log entries appear without // a manual page refresh. -// -// URL params `?agent=name` and `?unit=svc` pre-select the agent + unit on -// the AGENT tab (deep-link from other pages, e.g. the per-agent ⋮ menu). -// Last-fetched timestamp is shown next to the refresh button on AGENT + -// SYSTEM tabs so the operator knows how stale the output is. import { $, el, fmtAgeSecs, openStream, @@ -270,16 +265,8 @@ import { const agentUnitSelect = $('agent-unit-select'); const agentRefresh = $('agent-refresh'); const agentOutput = $('agent-output'); - const agentFetchTs = $('agent-fetch-ts'); - // Format a last-fetched timestamp: "fetched just now" / "fetched 3m ago". - function fmtFetchTs(fetchedAt) { - const ageSecs = Math.floor((Date.now() - fetchedAt) / 1000); - return 'fetched ' + (ageSecs < 5 ? 'just now' : fmtAgeSecs(ageSecs) + ' ago'); - } - - // Populate agent selector from /api/state, then honour any `?agent=` / - // `?unit=` URL params (used by the per-agent ⋮ menu's deep-link). + // Populate agent selector from /api/state async function loadAgentList() { try { const resp = await fetch('/api/state'); @@ -291,26 +278,10 @@ import { for (const c of (state.containers || [])) { agentSelect.append(el('option', { value: c.name }, c.name)); } - // Deep-link: honour ?agent= and ?unit= URL params. - const urlAgent = new URLSearchParams(location.search).get('agent'); - const urlUnit = new URLSearchParams(location.search).get('unit'); - if (urlAgent) { - const found = Array.from(agentSelect.options).some((o) => o.value === urlAgent); - if (found) { - agentSelect.value = urlAgent; - if (urlUnit && agentUnitSelect) { - const unitFound = Array.from(agentUnitSelect.options) - .some((o) => o.value === urlUnit); - if (unitFound) agentUnitSelect.value = urlUnit; - } - fetchAgent(); - } - } } catch { /**/ } } let agentFetching = false; - let agentLastFetch = 0; async function fetchAgent() { if (!agentSelect || !agentOutput) return; const name = agentSelect.value; @@ -318,7 +289,6 @@ import { if (agentFetching) return; agentFetching = true; agentOutput.textContent = 'fetching…'; - if (agentFetchTs) agentFetchTs.hidden = true; const unit = agentUnitSelect ? agentUnitSelect.value : ''; const params = new URLSearchParams({ lines: '500' }); if (unit) params.set('unit', unit); @@ -327,13 +297,6 @@ import { const text = await resp.text(); agentOutput.textContent = resp.ok ? (text || '(empty)') : 'error ' + resp.status + '\n' + text; agentOutput.scrollTop = agentOutput.scrollHeight; - if (resp.ok) { - agentLastFetch = Date.now(); - if (agentFetchTs) { - agentFetchTs.textContent = fmtFetchTs(agentLastFetch); - agentFetchTs.hidden = false; - } - } } catch (err) { agentOutput.textContent = 'fetch failed: ' + err; } finally { @@ -350,16 +313,13 @@ import { const systemUnitSelect = $('system-unit-select'); const systemRefresh = $('system-refresh'); const systemOutput = $('system-output'); - const systemFetchTs = $('system-fetch-ts'); let systemFetching = false; - let systemLastFetch = 0; async function fetchSystem() { if (!systemOutput) return; if (systemFetching) return; systemFetching = true; systemOutput.textContent = 'fetching…'; - if (systemFetchTs) systemFetchTs.hidden = true; const unit = systemUnitSelect ? systemUnitSelect.value : 'hive-c0re.service'; const params = new URLSearchParams({ lines: '500' }); if (unit) params.set('unit', unit); @@ -368,13 +328,6 @@ import { const text = await resp.text(); systemOutput.textContent = resp.ok ? (text || '(empty)') : 'error ' + resp.status + '\n' + text; systemOutput.scrollTop = systemOutput.scrollHeight; - if (resp.ok) { - systemLastFetch = Date.now(); - if (systemFetchTs) { - systemFetchTs.textContent = fmtFetchTs(systemLastFetch); - systemFetchTs.hidden = false; - } - } } catch (err) { systemOutput.textContent = 'fetch failed: ' + err; } finally { @@ -393,15 +346,4 @@ import { fetchBuild(); if (tab === 'system') fetchSystem(); - // Tick the last-fetched timestamps every 30s so "fetched 1m ago" stays - // accurate without a manual refresh. - setInterval(() => { - if (agentLastFetch && agentFetchTs && !agentFetchTs.hidden) { - agentFetchTs.textContent = fmtFetchTs(agentLastFetch); - } - if (systemLastFetch && systemFetchTs && !systemFetchTs.hidden) { - systemFetchTs.textContent = fmtFetchTs(systemLastFetch); - } - }, 30_000); - })(); diff --git a/frontend/packages/dashboard/src/tabs.js b/frontend/packages/dashboard/src/tabs.js index e0f7d2c2..22ab322b 100644 --- a/frontend/packages/dashboard/src/tabs.js +++ b/frontend/packages/dashboard/src/tabs.js @@ -426,20 +426,6 @@ window.marked = marked; return el('li', { class: 'agent-menu-sep', role: 'separator' }); } - // Navigation link item (opens in same tab by default). - function menuLink(label, href, title) { - const li = el('li', { role: 'presentation' }); - const a = el('a', { - class: 'agent-menu-item', - href, - role: 'menuitem', - title: title || '', - }, label); - a.addEventListener('click', () => closeAllAgentMenus()); - li.append(a); - return li; - } - // Show only actions that are applicable in the current state. if (c.running) { dropdown.append( @@ -453,14 +439,6 @@ window.marked = marked; } dropdown.append( menuItem('↻ R3BU1LD', { action: '/rebuild/', confirm: `rebuild ${c.name}? hot-reloads the container.` }), - menuSep(), - // Deep-link to the AGENT log tab pre-filtered to this container. - // The ?agent= param is read by logs.js on load; the stored localStorage - // selection is overridden so the operator lands directly in this - // agent's journal without extra clicks. - menuLink('journal logs →', - `/logs.html?agent=${encodeURIComponent(c.name)}#agent`, - `view ${c.name} journal logs`), ); {