feat: add auto metric refresh
This commit is contained in:
+14
-1
@@ -162,6 +162,7 @@
|
|||||||
<script src="https://cdn.datatables.net/2.3.8/js/dataTables.min.js"></script>
|
<script src="https://cdn.datatables.net/2.3.8/js/dataTables.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
let logTable = null;
|
let logTable = null;
|
||||||
|
let _lastDataKey = '';
|
||||||
|
|
||||||
function esc(str) {
|
function esc(str) {
|
||||||
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||||
@@ -190,7 +191,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadLog() {
|
async function loadLog(isRefresh = false) {
|
||||||
const tbody = document.getElementById('logBody');
|
const tbody = document.getElementById('logBody');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -202,6 +203,14 @@
|
|||||||
document.getElementById('stat-failed').textContent = stats.total_failed ?? '—';
|
document.getElementById('stat-failed').textContent = stats.total_failed ?? '—';
|
||||||
document.getElementById('stat-rate').textContent = stats.success_rate != null ? stats.success_rate + '%' : '—';
|
document.getElementById('stat-rate').textContent = stats.success_rate != null ? stats.success_rate + '%' : '—';
|
||||||
|
|
||||||
|
// Skip expensive DOM rebuild if nothing has changed
|
||||||
|
const dataKey = `${entries.length}:${stats.total_sent}:${stats.total_failed}`;
|
||||||
|
if (isRefresh && dataKey === _lastDataKey) return;
|
||||||
|
_lastDataKey = dataKey;
|
||||||
|
|
||||||
|
// Preserve current page position before destroying the table
|
||||||
|
const prevPage = logTable ? logTable.page() : 0;
|
||||||
|
|
||||||
// Destroy existing DataTable before rewriting DOM
|
// Destroy existing DataTable before rewriting DOM
|
||||||
if (logTable) { logTable.destroy(); logTable = null; }
|
if (logTable) { logTable.destroy(); logTable = null; }
|
||||||
|
|
||||||
@@ -237,12 +246,16 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
if (isRefresh && prevPage > 0 && prevPage < logTable.page.info().pages) {
|
||||||
|
logTable.page(prevPage).draw(false);
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
tbody.innerHTML = `<tr><td colspan="5" class="text-danger text-center py-4">Could not load delivery log.</td></tr>`;
|
tbody.innerHTML = `<tr><td colspan="5" class="text-danger text-center py-4">Could not load delivery log.</td></tr>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadLog();
|
loadLog();
|
||||||
|
setInterval(() => loadLog(true), 10_000);
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
async function checkAuth() {
|
async function checkAuth() {
|
||||||
|
|||||||
@@ -334,6 +334,7 @@
|
|||||||
} catch { /* DB unavailable — stats stay as dashes */ }
|
} catch { /* DB unavailable — stats stay as dashes */ }
|
||||||
}
|
}
|
||||||
loadStats();
|
loadStats();
|
||||||
|
setInterval(() => loadStats(), 10_000);
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
async function checkAuth() {
|
async function checkAuth() {
|
||||||
|
|||||||
Reference in New Issue
Block a user