// SvxPortal — web front-end for SvxReflector // Copyright (C) 2026 SA7AUX (Björn) // SPDX-License-Identifier: AGPL-3.0-or-later // // This program is free software: you can redistribute it and/or modify it under // the terms of the GNU Affero General Public License as published by the Free // Software Foundation, either version 3 of the License, or (at your option) any // later version. See the LICENSE file for details. 'use strict'; // Monitor → Trunks: ONLY the trunks THIS reflector is configured to trunk against, // read from the local svxreflector.conf (nodelist /api/local-trunks). The whole // network is on Monitor → Topology instead. No host/IP is ever shown. Footer // pager (first/prev/next/last, rows/page fit the screen) + regex search. (function () { let data = { trunks: [] }; let started = false, timer = null, _page = 1; const EXPANDED = new Set(); // trunk names whose TG list is expanded (persists across polls) function trunkDot(ok){ return ok ? '●' : '●'; } // Rows/page fit the space under the table so it never scrolls (same as the // node / TG pages). // Search matcher: the term is a case-insensitive regex (^se|us$, sm[0-9]). // Invalid regex falls back to a plain substring match. Empty → null. function trunkMatcher(term){ term = String(term == null ? '' : term).trim(); if(!term) return null; try { const re = new RegExp(term, 'i'); return (v) => re.test(String(v == null ? '' : v)); } catch(_) { const lc = term.toLowerCase(); return (v) => String(v == null ? '' : v).toLowerCase().indexOf(lc) !== -1; } } async function fetchData(){ try { const r = await fetch('/svxportal/api/local-trunks', { cache: 'no-store' }); if(r.ok){ data = await r.json(); render(); } } catch(_){} } function render(){ const body = document.getElementById('trunksBody'); if(!body) return; let trunks = Array.isArray(data.trunks) ? data.trunks : []; const m = trunkMatcher((document.getElementById('trunksSearch') || {}).value); if(m) trunks = trunks.filter(t => t && m(t.name)); trunks = trunks.slice().sort((a,b)=> String(a && a.name).localeCompare(String(b && b.name))); if(!trunks.length){ body.innerHTML = '
| Name | Status | Nodes |
|---|---|---|
| ${chev}${escHtml(t.name)}${hasTgs ? ` (${tgs.length} TG)` : ''} | ${trunkDot(ok)} ${ok ? 'online' : 'offline'} | ${Number(t.nodes || 0)} |
| ` + escHtml(g.name || ('TG ' + (g.tg || ''))) + (g.tg ? ' · TG ' + escHtml(g.tg) : '') + ` |