// Public status page client JS: // Bar tooltips - hover any heartbeat bar to see the bucket time range and uptime breakdown. // Expand/collapse is pure CSS (hidden checkbox + :checked sibling selector), no JS needed. // Reads its config from window.PINGQL_PAGE. (function () { var cfg = window.PINGQL_PAGE || {}; var barFrequency = cfg.bar_frequency || "daily"; // ── Bar tooltips ────────────────────────────────────────────────────── var tooltip = document.getElementById("bar-tooltip"); if (!tooltip) return; var bucketSpanMs = (barFrequency === "hourly") ? 3600 * 1000 : 86400 * 1000; function fmtBucketRange(startIso) { var start = new Date(startIso); var end = new Date(start.getTime() + bucketSpanMs); var dateOpts = { month: "short", day: "numeric" }; var timeOpts = { hour: "2-digit", minute: "2-digit" }; if (barFrequency === "hourly") { return start.toLocaleDateString(undefined, dateOpts) + ", " + start.toLocaleTimeString(undefined, timeOpts) + " - " + end.toLocaleTimeString(undefined, timeOpts); } return start.toLocaleDateString(undefined, { weekday: "short", month: "short", day: "numeric" }); } function uptimeBand(p) { if (p == null) return ""; if (p >= 99.9) return "good"; if (p >= 99.0) return "warn"; return "bad"; } function showTooltipForBar(bar) { var total = parseInt(bar.getAttribute("data-total") || "0", 10); var up = parseInt(bar.getAttribute("data-up") || "0", 10); var start = bar.getAttribute("data-start"); var latRaw = bar.getAttribute("data-latency"); var lat = latRaw == null ? null : parseInt(latRaw, 10); if (!start) return; // Full precision pct so the formatter can decide. Anything below 100% gets // 2 truncated (not rounded) decimals - same rule as the page-level uptime // numbers, so a bucket with one failed check never displays as "100%". var pct = total > 0 ? (100 * up / total) : null; var pctText; if (pct == null) pctText = "-"; else if (pct >= 100) pctText = "100%"; else pctText = (Math.floor(pct * 100) / 100).toFixed(2) + "%"; var html = '