sync for dev 033026
This commit is contained in:
@ -15,25 +15,20 @@
|
||||
pingTimeout: 5000,
|
||||
pingInterval: 25000,
|
||||
});
|
||||
|
||||
/* ==========================================================
|
||||
Color constants
|
||||
========================================================== */
|
||||
const GREEN = [ 39, 174, 96]; // #27ae60
|
||||
const YELLOW = [243, 156, 18]; // #f39c12
|
||||
const RED = [192, 57, 43]; // #c0392b
|
||||
|
||||
/* ==========================================================
|
||||
Helpers
|
||||
========================================================== */
|
||||
const hostTimestamps = {}; // keyed by short_id
|
||||
|
||||
const toRgb = (r, g, b) => `rgb(${r},${g},${b})`;
|
||||
|
||||
const T20 = 20 * 1000;
|
||||
const T40 = 40 * 1000;
|
||||
const T60 = 60 * 1000;
|
||||
|
||||
function getFreshnessColor(ageMs) {
|
||||
if (ageMs <= T20) {
|
||||
return toRgb(...GREEN);
|
||||
@ -54,19 +49,16 @@
|
||||
}
|
||||
return toRgb(...RED);
|
||||
}
|
||||
|
||||
function safeSetText(id, txt) {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.textContent = txt;
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
Get the short_id from the query string
|
||||
========================================================== */
|
||||
function getSelectedId() {
|
||||
return new URLSearchParams(window.location.search).get('host') || '';
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
Sidebar building - uses short_id for status key
|
||||
========================================================== */
|
||||
@ -75,30 +67,24 @@
|
||||
const current = Array.from(ul.children).map(li => li.dataset.id);
|
||||
const newIds = systemList.map(s => s.short_id);
|
||||
if (arraysEqual(current, newIds)) return;
|
||||
|
||||
const selected = getSelectedId().toLowerCase();
|
||||
ul.innerHTML = ''; // reset list
|
||||
|
||||
systemList.forEach(item => {
|
||||
const li = document.createElement('li');
|
||||
|
||||
// status dot - keyed by short_id
|
||||
const status = document.createElement('span');
|
||||
status.className = 'host-status';
|
||||
status.dataset.id = item.short_id;
|
||||
|
||||
// link - display hostname, encode short_id in URL
|
||||
const a = document.createElement('a');
|
||||
a.href = '?host=' + encodeURIComponent(item.short_id);
|
||||
a.textContent = item.hostname;
|
||||
if (item.short_id.toLowerCase() === selected) a.classList.add('active');
|
||||
|
||||
li.appendChild(status);
|
||||
li.appendChild(a);
|
||||
ul.appendChild(li);
|
||||
});
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
Update status colors every second
|
||||
========================================================== */
|
||||
@ -113,9 +99,7 @@
|
||||
if (span) span.style.backgroundColor = color;
|
||||
});
|
||||
}
|
||||
|
||||
setInterval(updateStatusColors, 1000);
|
||||
|
||||
/* ==========================================================
|
||||
Utility helpers
|
||||
========================================================== */
|
||||
@ -124,7 +108,6 @@
|
||||
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function renderGenericTable(containerId, data, emptyMsg) {
|
||||
const container = document.getElementById(containerId);
|
||||
if (!Array.isArray(data) || !data.length) {
|
||||
@ -138,7 +121,6 @@
|
||||
container.innerHTML = '';
|
||||
container.appendChild(table);
|
||||
}
|
||||
|
||||
function mergeRowsByName(rows) {
|
||||
const groups = {}; // { Source: { Metric: [], Data: [] } }
|
||||
rows.forEach(r => {
|
||||
@ -156,7 +138,6 @@
|
||||
Data: g.Data,
|
||||
}));
|
||||
}
|
||||
|
||||
function orderRows(rows) {
|
||||
const priority = ['System', 'CPU', 'RAM'];
|
||||
const map = {};
|
||||
@ -167,7 +148,6 @@
|
||||
return ai - bi;
|
||||
});
|
||||
}
|
||||
|
||||
function buildTable(rows) {
|
||||
const cols = ['Source', 'Metric', 'Data'];
|
||||
const table = document.createElement('table');
|
||||
@ -200,12 +180,10 @@
|
||||
});
|
||||
return table;
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
Handle incoming data
|
||||
========================================================== */
|
||||
let lastUpdate = Date.now();
|
||||
|
||||
function handleSummary(raw) {
|
||||
lastUpdate = Date.now(); // reset watchdog
|
||||
let payload;
|
||||
@ -215,25 +193,20 @@
|
||||
return;
|
||||
}
|
||||
} else payload = raw;
|
||||
|
||||
if (!Array.isArray(payload) || !payload.length) {
|
||||
safeSetText('client_summary', 'No data available');
|
||||
return;
|
||||
}
|
||||
|
||||
// Build the list first (so <span> elements exist)
|
||||
buildList(payload);
|
||||
|
||||
// Store the timestamp for every short_id
|
||||
payload.forEach(hostObj => {
|
||||
if (hostObj.short_id && hostObj.data_timestamp) {
|
||||
hostTimestamps[hostObj.short_id] = hostObj.data_timestamp; // seconds
|
||||
}
|
||||
});
|
||||
|
||||
// Immediately update colors for the current view
|
||||
updateStatusColors();
|
||||
|
||||
// Metric table for selected host
|
||||
const selectedId = getSelectedId();
|
||||
const hostObj = payload.find(h => h.short_id === selectedId) || payload[0];
|
||||
@ -242,7 +215,6 @@
|
||||
: [];
|
||||
renderGenericTable('host_metrics', hostData, 'No Stats available');
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
Socket event wiring
|
||||
========================================================== */
|
||||
@ -258,7 +230,6 @@
|
||||
safeSetText('client_summary', `Re-connected (attempt ${attempt})`);
|
||||
requestSummary();
|
||||
});
|
||||
|
||||
/* ==========================================================
|
||||
Request logic
|
||||
========================================================== */
|
||||
@ -266,7 +237,6 @@
|
||||
if (!socket.connected) return; // guard against stale emits
|
||||
socket.emit('get_client_summary'); // server will reply via client_summary
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
Recursive polling
|
||||
========================================================== */
|
||||
@ -279,7 +249,6 @@
|
||||
socket.on('connect', () => {
|
||||
if (!pollTimer) pollLoop();
|
||||
});
|
||||
|
||||
/* ==========================================================
|
||||
Watchdog - force reconnect if no data for 15 s
|
||||
========================================================== */
|
||||
@ -291,7 +260,6 @@
|
||||
setTimeout(watchdog, 5000);
|
||||
}
|
||||
watchdog();
|
||||
|
||||
/* ==========================================================
|
||||
Keep the 'active' link in sync when the URL changes
|
||||
========================================================== */
|
||||
|
||||
Reference in New Issue
Block a user