Page routes, Home link, documented-app filters, Overview colors and list fixes

- Every nav page has its own address (/tracked, /status, /devices, ...);
  the logo and name go to the Overview; back/forward work.
- List filters gain an "Only ticked" mode; software columns get a one-click
  "devices with only documented apps" pick and an easiest-first sort.
- Overview: the device list uses the dashboard's table header (sticky, with
  Excel filters); what opened it is clearly highlighted; locations colored by
  how much is done (red to green); stages read red / amber / green.
- Details: one-line title bar; presence and monitors only in Advanced View.
- Presence sweep pings only completed pairs (everything else is pinged by
  the sweep itself), hourly and at midnight.
- Custom View scrollbar smaller, in the table header blue.
- Docs: no sideways scroll in the article list; no blank lines around code.
This commit is contained in:
Johan Sandoval committed 2026-10-06 20:27:37 +00:00
1 parent e2125c760a
commit f72e39892c
13 files changed
+332 -117

No files matched your search

+11 -1
View File
@@ -96,6 +96,15 @@
return { online, last, lastIso: a.LastOnline, checked: a.LastChecked, ping: a.LastPing, first: a.FirstChecked, days, source: a.LastOnlineSource };
}
// Skip USMT tags are inventory only: the worker never pings them
function notPinged(name) {
try {
const rows = typeof apiData !== 'undefined' && Array.isArray(apiData) ? apiData : [];
return rows.some(r => r['Source Device'] === name && r.Pairing === 'Skipped');
} catch (e) { return false; }
}
const NOT_PINGED = 'Not pinged (Skip USMT tag)';
// Whole days offline (0 when online or offline less than a day), null if never seen
function daysOffline(name) {
const p = presence(name);
@@ -121,6 +130,7 @@
function computed(name, key) {
const a = entry(name);
if (!a) return { text: WAITING, state: 'waiting' };
if (['DaysOffline', 'LastOnline', 'LastChecked'].includes(key) && !a.LastChecked && notPinged(name)) return { text: NOT_PINGED, state: 'na' };
if (key === 'DaysOffline') {
const d = daysOffline(name);
if (d === undefined) return { text: WAITING, state: 'waiting' };
@@ -164,7 +174,7 @@
function presenceHtml(name) {
if (!isName(name)) return 'N/A';
const p = presence(name);
if (!p) return `<span class="di-waiting">${WAITING}</span>`;
if (!p) return notPinged(name) ? `<span class="di-sub">${NOT_PINGED}</span>` : `<span class="di-waiting">${WAITING}</span>`;
const txt = offlineText(name);
const cls = p.online ? 'di-online' : (p.days !== null && p.days >= 3 ? 'di-offline-long' : 'di-offline');
let sub = '';