Add offline and ntfy alerts
Co-authored-by: Copilot <[email protected]>
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
const count = document.getElementById("alert-count");
|
||||
const notifications = document.getElementById("alert-notifications");
|
||||
|
||||
const titles = {
|
||||
mil: "Check-engine light",
|
||||
disk: "Pi storage nearly full",
|
||||
upload_backlog: "Upload backlog growing",
|
||||
temperature: "Pi temperature high",
|
||||
power: "Pi power or throttling warning",
|
||||
gps_loss: "GPS fix lost while moving",
|
||||
};
|
||||
|
||||
function renderAlerts(status) {
|
||||
const active = Object.entries(status.conditions)
|
||||
.filter(function (entry) {
|
||||
return entry[1].active;
|
||||
});
|
||||
const stale = status.last_run_at == null
|
||||
|| Date.now() / 1000 - status.last_run_at > 150;
|
||||
const monitorError = status.last_run_error
|
||||
|| (stale ? "Alert monitor data is stale." : null);
|
||||
const alertCount = active.length + (monitorError ? 1 : 0);
|
||||
count.hidden = alertCount === 0;
|
||||
count.textContent = alertCount;
|
||||
notifications.replaceChildren();
|
||||
|
||||
if (monitorError) {
|
||||
const item = document.createElement("div");
|
||||
item.className = "dropdown-item-text border-top py-2";
|
||||
const title = document.createElement("strong");
|
||||
title.className = "d-block text-danger small";
|
||||
title.textContent = "Alert monitor problem";
|
||||
const message = document.createElement("span");
|
||||
message.className = "d-block small text-wrap";
|
||||
message.textContent = monitorError;
|
||||
item.append(title, message);
|
||||
notifications.appendChild(item);
|
||||
}
|
||||
|
||||
if (!active.length && !monitorError) {
|
||||
const empty = document.createElement("div");
|
||||
empty.className = "dropdown-item-text text-muted small";
|
||||
empty.textContent = "No active alerts";
|
||||
notifications.appendChild(empty);
|
||||
return;
|
||||
}
|
||||
|
||||
active.forEach(function (entry) {
|
||||
const item = document.createElement("div");
|
||||
item.className = "dropdown-item-text border-top py-2";
|
||||
const title = document.createElement("strong");
|
||||
title.className = "d-block text-danger small";
|
||||
title.textContent = titles[entry[0]] || entry[0];
|
||||
const message = document.createElement("span");
|
||||
message.className = "d-block small text-wrap";
|
||||
message.textContent = entry[1].message;
|
||||
item.append(title, message);
|
||||
notifications.appendChild(item);
|
||||
});
|
||||
}
|
||||
|
||||
function showUnavailable(message) {
|
||||
count.hidden = true;
|
||||
notifications.replaceChildren();
|
||||
const error = document.createElement("div");
|
||||
error.className = "dropdown-item-text text-danger small";
|
||||
error.textContent = message;
|
||||
notifications.appendChild(error);
|
||||
}
|
||||
|
||||
async function refreshAlerts() {
|
||||
const response = await fetch("/api/alerts/status");
|
||||
const status = await response.json();
|
||||
if (!response.ok) {
|
||||
throw new Error(status.error || "Could not load alerts.");
|
||||
}
|
||||
renderAlerts(status);
|
||||
}
|
||||
|
||||
refreshAlerts().catch(function (error) {
|
||||
showUnavailable(error.message);
|
||||
});
|
||||
window.setInterval(function () {
|
||||
refreshAlerts().catch(function (error) {
|
||||
showUnavailable(error.message);
|
||||
});
|
||||
}, 30000);
|
||||
}());
|
||||
Reference in New Issue
Block a user