$(function () { $(".my-checks-name").click(function() { $("#update-name-form").attr("action", this.dataset.url); $("#update-name-input").val(this.dataset.name); $("#update-tags-input").val(this.dataset.tags); $('#update-name-modal').modal("show"); $("#update-name-input").focus(); return false; }); var MINUTE = {name: "minute", nsecs: 60}; var HOUR = {name: "hour", nsecs: MINUTE.nsecs * 60}; var DAY = {name: "day", nsecs: HOUR.nsecs * 24}; var WEEK = {name: "week", nsecs: DAY.nsecs * 7}; var UNITS = [WEEK, DAY, HOUR, MINUTE]; var secsToText = function(total) { var remainingSeconds = Math.floor(total); var result = ""; for (var i=0, unit; unit=UNITS[i]; i++) { if (unit === WEEK && remainingSeconds % unit.nsecs != 0) { // Say "8 days" instead of "1 week 1 day" continue } var count = Math.floor(remainingSeconds / unit.nsecs); remainingSeconds = remainingSeconds % unit.nsecs; if (count == 1) { result += "1 " + unit.name + " "; } if (count > 1) { result += count + " " + unit.name + "s "; } } return result; } var periodSlider = document.getElementById("period-slider"); noUiSlider.create(periodSlider, { start: [20], connect: "lower", range: { 'min': [60, 60], '33%': [3600, 3600], '66%': [86400, 86400], '83%': [604800, 604800], 'max': 2592000, }, pips: { mode: 'values', values: [60, 1800, 3600, 43200, 86400, 604800, 2592000], density: 4, format: { to: secsToText, from: function() {} } } }); periodSlider.noUiSlider.on("update", function(a, b, value) { var rounded = Math.round(value); $("#period-slider-value").text(secsToText(rounded)); $("#update-timeout-timeout").val(rounded); }); var graceSlider = document.getElementById("grace-slider"); noUiSlider.create(graceSlider, { start: [20], connect: "lower", range: { 'min': [60, 60], '33%': [3600, 3600], '66%': [86400, 86400], '83%': [604800, 604800], 'max': 2592000, }, pips: { mode: 'values', values: [60, 1800, 3600, 43200, 86400, 604800, 2592000], density: 4, format: { to: secsToText, from: function() {} } } }); graceSlider.noUiSlider.on("update", function(a, b, value) { var rounded = Math.round(value); $("#grace-slider-value").text(secsToText(rounded)); $("#update-timeout-grace").val(rounded); }); function showSimple() { $("#update-timeout-form").show(); $("#update-cron-form").hide(); } function showCron() { $("#update-timeout-form").hide(); $("#update-cron-form").show(); } var currentPreviewHash = ""; function updateCronPreview() { var schedule = $("#schedule").val(); var tz = $("#tz").val(); var hash = schedule + tz; // Don't try preview with empty values, or if values have not changed if (!schedule || !tz || hash == currentPreviewHash) return; // OK, we're good currentPreviewHash = hash; $("#cron-preview-title").text("Updating..."); var token = $('input[name=csrfmiddlewaretoken]').val(); $.ajax({ url: "/checks/cron_preview/", type: "post", headers: {"X-CSRFToken": token}, data: {schedule: schedule, tz: tz}, success: function(data) { if (hash != currentPreviewHash) { return; // ignore stale results } $("#cron-preview" ).html(data); var haveError = $("#invalid-arguments").size() > 0; $("#update-cron-submit").prop("disabled", haveError); } }); } $(".timeout-grace").click(function() { $("#update-timeout-form").attr("action", this.dataset.url); $("#update-cron-form").attr("action", this.dataset.url); // Simple periodSlider.noUiSlider.set(this.dataset.timeout); graceSlider.noUiSlider.set(this.dataset.grace); // Cron currentPreviewHash = ""; $("#cron-preview").html("
Updating...
"); $("#schedule").val(this.dataset.schedule); document.getElementById("tz").selectize.setValue(this.dataset.tz); var minutes = parseInt(this.dataset.grace / 60); $("#update-timeout-grace-cron").val(minutes); updateCronPreview(); this.dataset.kind == "simple" ? showSimple() : showCron(); $('#update-timeout-modal').modal({"show":true, "backdrop":"static"}); return false; }); // Wire up events for Timeout/Cron forms $(".kind-simple").click(showSimple); $(".kind-cron").click(showCron); $("#schedule").on("keyup", updateCronPreview); $("#tz").selectize({onChange: updateCronPreview}); $(".check-menu-remove").click(function() { $("#remove-check-form").attr("action", this.dataset.url); $(".remove-check-name").text(this.dataset.name); $('#remove-check-modal').modal("show"); return false; }); $(".last-ping-cell").on("click", ".last-ping", function() { $("#last-ping-body").text("Updating..."); $('#last-ping-modal').modal("show"); var token = $('input[name=csrfmiddlewaretoken]').val(); $.ajax({ url: this.dataset.url, type: "post", headers: {"X-CSRFToken": token}, success: function(data) { $("#last-ping-body" ).html(data); } }); return false; }); $("#my-checks-tags button").click(function() { // .active has not been updated yet by bootstrap code, // so cannot use it $(this).toggleClass('checked'); // Make a list of currently checked tags: var checked = []; $("#my-checks-tags button.checked").each(function(index, el) { checked.push(el.textContent); }); // No checked tags: show all if (checked.length == 0) { $("#checks-table tr.checks-row").show(); $("#checks-list > li").show(); return; } function applyFilters(index, element) { // use attr(), as data() tries converting strings to JS types: // (e.g., "123" -> 123) var tags = $(".my-checks-name", element).attr("data-tags").split(" "); for (var i=0, tag; tag=checked[i]; i++) { if (tags.indexOf(tag) == -1) { $(element).hide(); return; } } $(element).show(); } // Desktop: for each row, see if it needs to be shown or hidden $("#checks-table tr.checks-row").each(applyFilters); // Mobile: for each list item, see if it needs to be shown or hidden $("#checks-list > li").each(applyFilters); }); $(".pause-check").click(function(e) { var url = e.target.getAttribute("data-url"); $("#pause-form").attr("action", url).submit(); return false; }); $('[data-toggle="tooltip"]').tooltip({ title: function() { var cssClasses = this.getAttribute("class"); if (cssClasses.indexOf("icon-new") > -1) return "New. Has never received a ping."; if (cssClasses.indexOf("icon-paused") > -1) return "Monitoring paused. Ping to resume."; } }); $(".usage-examples").click(function(e) { var a = e.target; var url = a.getAttribute("data-url"); var email = a.getAttribute("data-email"); $(".ex", "#show-usage-modal").text(url); $(".em", "#show-usage-modal").text(email); $("#show-usage-modal").modal("show"); return false; }); // Auto-refresh var lastStatus = {}; var lastPing = {}; function refresh() { $.ajax({ url: "/checks/status/", dataType: "json", timeout: 2000, success: function(data) { for(var i=0, el; el=data.details[i]; i++) { if (lastStatus[el.code] != el.status) { lastStatus[el.code] = el.status; $("#si-" + el.code).attr("class", "status icon-" + el.status); $("#sl-" + el.code).attr("class", "label label-" + el.status).text(el.status); $("#pause-li-" + el.code).toggleClass("disabled", el.status == "paused"); } if (lastPing[el.code] != el.last_ping) { lastPing[el.code] = el.last_ping; $("#lpd-" + el.code).html(el.last_ping); $("#lpm-" + el.code).html(el.last_ping); } } $("#my-checks-tags button").each(function(a) { var status = data.tags[this.innerText]; if (status) { this.setAttribute("class", "btn btn-xs " + status); } }); } }); } // unconditionally refresh every minute setInterval(refresh, 60000); // scheduleRefresh() keeps calling refresh() and decreasing quota // every 3 seconds, until quota runs out. var quota = 0; var scheduledId = null; function scheduleRefresh() { if (quota > 0) { quota -= 1; clearTimeout(scheduledId); scheduledId = setTimeout(scheduleRefresh, 3000); refresh(); } } document.addEventListener("visibilitychange", function() { if (document.visibilityState == "visible") { // tab becomes visible: reset quota if (quota == 0) { quota = 20; scheduleRefresh(); } else { quota = 20; } } else { // lost visibility, clear quota quota = 0; } }); // user moves mouse: reset quota document.addEventListener("mousemove", function() { if (quota == 0) { quota = 20; scheduleRefresh(); } else { quota = 20; } }); // Copy to clipboard var clipboard = new Clipboard('button.copy-link'); $("button.copy-link").mouseout(function(e) { setTimeout(function() { e.target.textContent = "copy"; }, 300); }) clipboard.on('success', function(e) { e.trigger.textContent = "copied!"; e.clearSelection(); }); clipboard.on('error', function(e) { var text = e.trigger.getAttribute("data-clipboard-text"); prompt("Press Ctrl+C to select:", text) }); });