|
|
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>{{ site_name }}</title>
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <style>
- /* Colors, dark theme */
-
- .theme-dark {
- background: #000;
- color: #FFF;
- }
-
- .theme-dark #panel > div {
- background: #AAA;
- color: #000;
- }
-
- .theme-dark #panel > div.status-up {
- color: #FFF;
- background: #263026;
- }
-
- .theme-dark #panel > div.status-started {
- color: #FFF;
- background: #263026;
- }
-
-
- .theme-dark #panel > div.status-grace {
- color: #000;
- background: #FFB300;
- }
-
- .theme-dark #panel > div.status-down {
- color: #000;
- background: #ff3929;
- }
-
- .theme-dark .spinner:after {
- border-color: #4c604c transparent #4c604c transparent;
- }
-
- /* Colors, light theme */
-
- .theme-light {
- background: #FFF;
- color: #333;
- }
-
- .theme-light #panel > div {
- color: #000;
- background: #FFF;
- border: 2px solid #DDD;
- }
-
- .theme-light #panel > div.status-grace {
- color: #000;
- background: #FFAB00;
- border: none;
- }
-
- .theme-light #panel > div.status-down {
- color: #FFF;
- background: #D81818;
- border: none;
- }
-
- .theme-light .spinner:after {
- border-color: #DDD transparent #DDD transparent;
- }
-
-
- /* Spinner from https://loading.io/css/ */
- .spinner {
- display: none;
- }
-
- div.status-started .spinner {
- position: absolute;
- right: 8px;
- top: 50%;
- margin-top: -18px;
- display: inline-block;
- width: 36px;
- height: 36px;
- }
- .spinner:after {
- content: " ";
- display: block;
- width: 24px;
- height: 24px;
- margin: 1px;
- border-radius: 50%;
- border: 5px solid transparent;
- animation: lds-dual-ring 1.25s linear infinite;
- }
-
- @keyframes lds-dual-ring {
- 0% {
- transform: rotate(0deg);
- }
- 100% {
- transform: rotate(360deg);
- }
- }
-
- /* Layout and font */
-
- html, body {
- font-family: -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif;
- height: 100%;
- margin: 0;
- }
-
- #panel {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
- grid-gap: 8px;
- padding: 8px;
- }
-
- #panel > h1 {
- grid-column-start: 1;
- grid-column-end: -1;
- margin: 12px 0;
- font-size: 20px;
- }
-
- #panel > div {
- padding: 8px 8px 32px 8px;
- font-size: 18px;
- position: relative;
- }
-
- #panel > div .name {
- text-overflow: ellipsis;
- overflow: hidden;
- }
-
- #panel > div .lp {
- position: absolute;
- font-size: 13px;
- opacity: 0.8;
- }
-
- #panel > div .lp {
- bottom: 8px;
- left: 8px;
- }
-
- .check-template {
- display: none;
- }
- </style>
- </head>
- <body class="theme-light">
- <div id="panel"></div>
-
- <div class="check-template">
- <div class="name"></div>
- <div class="lp"></div>
- <div class="spinner"></div>
- </div>
-
- <script>
- function fetch(key, callback) {
- var httpRequest = new XMLHttpRequest();
- httpRequest.onreadystatechange = function() {
- if (httpRequest.readyState === 4) {
- if (httpRequest.status === 200) {
- callback(JSON.parse(httpRequest.responseText));
- }
- }
- };
- httpRequest.open("GET", "/api/v1/checks/");
- httpRequest.setRequestHeader("X-Api-Key", key);
- httpRequest.send();
- }
-
- function timeSince(date) {
- var v = Math.floor((new Date() - date) / 1000);
-
- if (v < 60) { // v is seconds
- return v + " second" + (v == 1 ? "" : "s");
- }
-
-
- v = Math.floor(v / 60); // v is now minutes
- if (v < 60) {
- return v + " minute" + (v == 1 ? "" : "s");
- }
-
- v = Math.floor(v / 60); // v is now hours
- if (v < 24) {
- return v + " hour" + (v == 1 ? "" : "s");
- }
-
-
- v = Math.floor(v / 24); // v is now days
- return v + " day" + (v == 1 ? "" : "s");
- };
-
- var template = document.querySelector(".check-template");
- function updatePanel(node) {
- fetch(node.dataset.readonlyKey, function(doc) {
- var tag = "TAG_" + node.dataset.readonlyKey.substr(0, 6);
-
- // Sort returned checks by name:
- var sorted = doc.checks.sort(function(a, b) {
- return a.name.localeCompare(b.name)
- });
-
- var fragment = document.createDocumentFragment();
- sorted.forEach(function(item) {
- var div = template.cloneNode(true);
- div.setAttribute("class", tag + " status-" + item.status);
- div.querySelector(".name").textContent = item.name || "unnamed";
- if (item.last_ping) {
- var s = timeSince(Date.parse(item.last_ping)) + " ago";
- div.querySelector(".lp").textContent = s;
- }
- fragment.appendChild(div);
- });
-
-
- document.querySelectorAll('.' + tag).forEach(function(element) {
- element.remove();
- });
-
- node.parentNode.insertBefore(fragment, node.nextSibling);
- });
- }
-
- if (window.location.hash) {
- var panel;
-
- var pairs = window.location.hash.substr(1).split("&");
- for (var i=0, pair; pair=pairs[i]; i++) {
- if (pair.indexOf("theme=") != -1) {
- document.body.setAttribute("class", pair.replace("=", "-"));
- continue;
- }
-
- var parts = pair.split("=");
- var h1 = document.createElement("H1");
- h1.dataset.readonlyKey = parts[0];
- if (parts[1]) {
- h1.innerText = decodeURIComponent(parts[1]);
- }
-
- if (!panel) {
- panel = document.getElementById("panel");
- panel.innerHTML = "";
- }
- panel.appendChild(h1);
- }
- }
- document.querySelectorAll("h1").forEach(updatePanel);
- setInterval(function() {
- document.querySelectorAll("h1").forEach(updatePanel);
- }, 5000);
-
- </script>
- </body>
- </html>
|