Commit graph

6 commits

Author SHA1 Message Date
c2206ad5a7 dashboard: live cache-age indicator
The web server's dashboardStats now reports how stale its shared cache
snapshot is — data.cache = { enabled, ttlMs, ageMs }, using the age of the
oldest dataset feeding the view (OLT-STATE, plus ONU-STATE under detailed
scan). cache.js gains ageOf(key).

The dashboard renders a live-ticking badge from it (renderCacheBadge):
  - within TTL  -> "◷ cached Ns ago" (info)
  - past TTL    -> same, warn-coloured (next load will refetch)
  - no cache    -> "● live" (Electron app, or PFW_CACHE_TTL_SECONDS=0)
The Dashboard Refresh button now sends fresh:true to bypass the cache and
reset the age; the detailed-stats toggle and auto-loads use the cache.

Shared renderer change, so the Electron app shows "live" (it sends no cache
field). Verified offscreen over HTTP: cached / stale / live states render
with the right text + colour.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 14:25:46 +02:00
96b0264179 Add multi-user web server variant (browser UI behind a reverse proxy)
New web/ subfolder: a Node http server that serves the SAME tooling as the
Electron app to any browser, with per-session MCMS credentials so several
operators can use it at once behind a TLS reverse proxy. Mobile-responsive.

Not a fork — it reuses the core and the UI:
- serves renderer/app.js + app.css verbatim and rewrites index.html on the
  fly (mobile viewport + browser window.api shim + responsive overlay)
- web/public/api-web.js: a drop-in window.api over fetch + NDJSON streaming;
  Electron file dialogs -> <input type=file>, CSV-to-Downloads -> Blob
- web/server.js: per-session McmsClient (cookie pfw_sid), idle expiry,
  routes mirroring the IPC handlers, NDJSON for the 6 streaming ops
- pure Node http, no new deps (borrows ../node_modules tough-cookie)

Shared improvements (benefit both apps):
- src/dashboard.js: extracted, pure dashboard aggregation (main.js now uses
  it); adds abnormal-Tx detection alongside abnormal-Rx
- renderer: dashboard health stats are now clickable — abnormal Rx / Tx /
  lasers-off pop a list of the offending devices (like the iOS app), via a
  new showListModal

Docs: web/README.md (run + reverse-proxy + security), CLAUDE.md §16.

Verified: node --check all; started the server and confirmed transformed
index, shared-asset serving, 401 auth gate, login (per-session client), and
NDJSON wiring; rendered login + dashboard drilldown + mobile over HTTP.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 14:07:23 +02:00
9106e5a071 Add top tabs + telemetry Dashboard + animated edge glow
Restructure the UI behind top-level tabs (Dashboard / ONU / OLT) so more
features have room to land. showView() now drives the active tab via a
VIEW_TO_TAB map, so sub-views (campaign/verify) keep the ONU tab lit.
Tabs appear on login (landing on Dashboard) and hide on logout.

Dashboard: a read-only network telemetry view modeled on the PONGo iOS
app's DashboardViewModel. New api:dashboardStats aggregates, all in
main.js (renderer just formats):
- counts: ONUs, OLTs, controllers (controllers best-effort via
  /v3/controllers/configs/)
- aggregate traffic (OLT TX BW = downstream, RX BW = upstream)
- health: OLTs with laser off; abnormal-Rx count (rx < -28 || > -10)
- ONU registration-state breakdown (clicking a state deep-links to the
  ONU tab pre-filtered)
- opt-in detailed scan: per-ONU optical + FEC-health distribution
fmtBps is a port of the iOS Format.bps.

Edge glow: #edge-glow draws a neon conic-gradient beam masked to a 3px
border ring and spins an @property --beam-angle 0->360deg, so a glow
travels around the screen edge. Honors prefers-reduced-motion.

mcms-api: add listAllControllerConfigs.
Docs: CLAUDE.md section 15 + README + IPC table.

Verified: npm run check passes; rendered the Dashboard + tabs + edge beam
offscreen (beam frozen on the right edge to confirm it follows the border).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 13:45:24 +02:00
7cc9649f03 Fix unsupported prompt() confirm; bluer neon theme + themed modal
Bug: the OLT flooding-mode and ONU-delete flows gated on window.prompt()
for the typed APPLY/DELETE confirmation, but Electron does not support
prompt() — it returns null and shows nothing, so clicking OK on the first
dialog silently fell through to "Cancelled." and nothing happened.

Fix: replace window.confirm + window.prompt with an in-app confirmTyped()
modal (Promise<boolean>). It combines the summary and the typed-word gate
into one dialog: the confirm button stays disabled until the operator
types the exact word; Enter confirms, Escape/backdrop cancels. Wired into
all three confirmations (OLT flood change, ONU delete, firmware execute).

Theme: shift the palette electric-blue, turn up the glow (stronger
multi-layer box/text shadows, bluer ambient vignette), and style the new
modal to match (neon border, red glow for destructive variant).

Verified: npm run check passes; rendered the login + modal offscreen and
functionally confirmed the typed-word gate enables the button and resolves
true on confirm.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 13:13:42 +02:00
49a0e1cba1 Restyle UI with neon/terminal "hackertyper" theme
Darker phosphor-black background with ambient neon vignette, monospace
everywhere, glowing neon-green accents, and CRT scanline + brand-flicker
effects. Restyle only — every class name HTML/app.js depends on is
preserved (status pills, fec-cell, slot-arrow, table classes, etc.).

- Neon-green primary / cyan secondary / magenta-red danger, all with
  text-shadow + box-shadow glow
- Glowing focus rings on inputs, glowing buttons and selected rows
- CRT scanline overlay (body::after, non-interactive) + subtle flicker
- Neon scrollbars and selection highlight

Verified by rendering the login view offscreen via Electron.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 12:59:22 +02:00
0eb9b55717 initial commit 2026-05-26 11:16:18 +02:00