ponfw/preload.js
Jon Vanvik 2046fad0f8 onu detail polish + clickable OLT detail modal
- Fix alarm card overflow: alarm rows stack (severity+text on one line that
  wraps, meta below) instead of squeezing the text to ~0 width next to the
  nowrap meta — which had made long alarm text render one char per line in
  narrow columns. Also min-width:0 on cards/kv so long IPv6/descr strings
  don't blow out the grid track.
- Combine Parent OLT + Upstream switch into one "Parent OLT & uplink" card.
- ONU list/search de-compacted: add equipment/version + PON-mode filters;
  two-line rows (serial+status, then equipment · version · last-seen).
- UNI card labels the speed as configured ("cfg Auto/Auto"); negotiated
  speed isn't in the payloads — link up/down still comes from LAN-LOS.

Clickable parent OLT -> OLT detail modal (showOltModal):
- new src/oltdetail.js (pure, shared; reuses summarizeAlarms) + getOltState
  / getOltAlarms client methods + api:getOltDetail (main + web + bridges).
- shows identity, traffic + util, ASIC temperature, ONU counts, laser,
  alarms, upstream switch; plus a connected-ONU list with per-ONU
  FEC/optical built from the loaded fleet (filtered by _status.oltMac),
  each row clickable back into that ONU's detail.

Docs: CLAUDE.md §17 + IPC table.

Verified: node --check; oltdetail.js unit-tested 9/9 (fw active-bank,
traffic down=TX/up=RX, util, ASIC temp, ONU counts, laser, LLDP, alarms);
rendered the OLT modal + richer list offscreen and confirmed the alarm-text
wrap fix (alarm head ~1-2 lines, not vertical).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 16:10:34 +02:00

83 lines
3.2 KiB
JavaScript

// Preload: the only bridge between renderer and main. Everything the UI
// can do is enumerated here — the renderer has no direct node access.
const { contextBridge, ipcRenderer } = require('electron');
function call(channel, args) {
return ipcRenderer.invoke(channel, args);
}
contextBridge.exposeInMainWorld('api', {
login: (opts) => call('api:login', opts),
logout: () => call('api:logout'),
listOnuConfigs: (opts) => call('api:listOnuConfigs', opts),
listFleet: (opts) => call('api:listFleet', opts),
fetchStates: (opts) => call('api:fetchStates', opts),
getOnuConfig: (opts) => call('api:getOnuConfig', opts),
getOnuCpe: (opts) => call('api:getOnuCpe', opts),
getOnuDetail: (opts) => call('api:getOnuDetail', opts),
getOltDetail: (opts) => call('api:getOltDetail', opts),
listOnuFirmware: () => call('api:listOnuFirmware'),
uploadFirmware: () => call('api:uploadFirmware'),
planUpgrade: (opts) => call('api:planUpgrade', opts),
executePerOnu: (opts) => call('api:executePerOnu', opts),
executeBulkTask: (opts) => call('api:executeBulkTask', opts),
getTaskConfig: (opts) => call('api:getTaskConfig', opts),
getUpgradeStatus: (opts) => call('api:getUpgradeStatus', opts),
deleteOnus: (opts) => call('api:deleteOnus', opts),
dashboardStats: (opts) => call('api:dashboardStats', opts),
listOlts: (opts) => call('api:listOlts', opts),
executeFloodChange: (opts) => call('api:executeFloodChange', opts),
onFloodProgress: (handler) => {
const fn = (_ev, payload) => handler(payload);
ipcRenderer.on('olt-flood:progress', fn);
return () => ipcRenderer.removeListener('olt-flood:progress', fn);
},
fetchFecHealth: (opts) => call('api:fetchFecHealth', opts),
fetchOnuSnapshot: (opts) => call('api:fetchOnuSnapshot', opts),
savePlanCsv: (opts) => call('api:savePlanCsv', opts),
saveCsvFile: (opts) => call('api:saveCsvFile', opts),
openCsvFile: () => call('api:openCsvFile'),
// Streaming FEC pre-flight progress (one event per ONU resolved).
onFecProgress: (handler) => {
const fn = (_ev, payload) => handler(payload);
ipcRenderer.on('fec:progress', fn);
return () => ipcRenderer.removeListener('fec:progress', fn);
},
// Streaming verify-snapshot progress.
onVerifyProgress: (handler) => {
const fn = (_ev, payload) => handler(payload);
ipcRenderer.on('verify:progress', fn);
return () => ipcRenderer.removeListener('verify:progress', fn);
},
// Live progress events from the main process while executePerOnu runs.
onUpgradeProgress: (handler) => {
const fn = (_ev, payload) => handler(payload);
ipcRenderer.on('upgrade:progress', fn);
return () => ipcRenderer.removeListener('upgrade:progress', fn);
},
// Streaming state-fetch progress (Equipment ID population).
onStatesProgress: (handler) => {
const fn = (_ev, payload) => handler(payload);
ipcRenderer.on('states:progress', fn);
return () => ipcRenderer.removeListener('states:progress', fn);
},
// Streaming delete progress.
onDeleteProgress: (handler) => {
const fn = (_ev, payload) => handler(payload);
ipcRenderer.on('delete:progress', fn);
return () => ipcRenderer.removeListener('delete:progress', fn);
},
});