
When user double-clicks on text, browser selects a single word. When user triple-clicks, browser selects a line or a paragraph of text. We have JS code that enables user to click on ping URL to copy it to the clipboard. After copying it shows a small non-native tooltip saying "Copied!" above the ping URL. This was interfering with triple-click selection, the word "Copied!" would get selected as well. The fix is to use document body as the container of the tooltip, not the ping URL span (which is the default).
295 lines
No EOL
9.6 KiB
JavaScript
295 lines
No EOL
9.6 KiB
JavaScript
$(function () {
|
|
var base = document.getElementById("base-url").getAttribute("href").slice(0, -1);
|
|
var favicon = document.querySelector('link[rel="icon"]');
|
|
|
|
$(".rw .my-checks-name").click(function() {
|
|
var code = $(this).closest("tr.checks-row").attr("id");
|
|
var url = base + "/checks/" + code + "/name/";
|
|
|
|
$("#update-name-form").attr("action", url);
|
|
$("#update-name-input").val(this.dataset.name);
|
|
$("#update-slug-input").val(this.dataset.slug);
|
|
|
|
var tagsSelectize = document.getElementById("update-tags-input").selectize;
|
|
tagsSelectize.setValue(this.dataset.tags.split(" "));
|
|
|
|
$("#update-desc-input").val(this.dataset.desc);
|
|
$('#update-name-modal').modal("show");
|
|
$("#update-name-input").focus();
|
|
|
|
return false;
|
|
});
|
|
|
|
$(".integrations").tooltip({
|
|
container: "body",
|
|
selector: "span",
|
|
title: function() {
|
|
var idx = $(this).index();
|
|
return $("#ch-" + idx).data("title");
|
|
}
|
|
});
|
|
|
|
$(".rw .integrations").on("click", "span", function() {
|
|
var isOff = $(this).toggleClass("off").hasClass("off");
|
|
var token = $('input[name=csrfmiddlewaretoken]').val();
|
|
|
|
var idx = $(this).index();
|
|
var checkCode = $(this).closest("tr.checks-row").attr("id");
|
|
var channelCode = $("#ch-" + idx).data("code");
|
|
|
|
var url = base + "/checks/" + checkCode + "/channels/" + channelCode + "/enabled";
|
|
|
|
$.ajax({
|
|
url: url,
|
|
type: "post",
|
|
headers: {"X-CSRFToken": token},
|
|
data: {"state": isOff ? "off" : "on"}
|
|
});
|
|
|
|
return false;
|
|
});
|
|
|
|
$(".last-ping").on("click", function() {
|
|
if (this.innerText == "Never") {
|
|
return false;
|
|
}
|
|
var code = $(this).closest("tr.checks-row").attr("id");
|
|
var lastPingUrl = base + "/checks/" + code + "/last_ping/";
|
|
loadPingDetails(lastPingUrl);
|
|
|
|
var logUrl = base + "/checks/" + code + "/log/";
|
|
$("#ping-details-log").attr("href", logUrl);
|
|
|
|
return false;
|
|
});
|
|
|
|
$(".last-ping").tooltip({
|
|
selector: ".label-confirmation",
|
|
title: 'The word "confirm" was found in request body'
|
|
});
|
|
|
|
$("#my-checks-tags .btn").tooltip({
|
|
title: function() {return this.getAttribute("data-tooltip");}
|
|
});
|
|
|
|
function applyFilters() {
|
|
// Make a list of currently checked tags:
|
|
var checked = [];
|
|
var url = new URL(window.location.href);
|
|
url.search = "";
|
|
$("#my-checks-tags .checked").each(function(index, el) {
|
|
checked.push(el.textContent);
|
|
url.searchParams.append("tag", el.textContent);
|
|
});
|
|
|
|
var search = $("#search").val().toLowerCase();
|
|
if (search) {
|
|
url.searchParams.append("search", search);
|
|
}
|
|
|
|
// Update hash
|
|
if (window.history && window.history.replaceState) {
|
|
window.history.replaceState({}, "", url.toString());
|
|
}
|
|
|
|
// Update sort links
|
|
document.querySelectorAll("a[data-sort-value]").forEach((a) => {
|
|
url.searchParams.set("sort", a.dataset.sortValue);
|
|
a.setAttribute("href", url.toString());
|
|
});
|
|
|
|
// No checked tags and no search string: show all
|
|
if (checked.length == 0 && !search) {
|
|
$("#checks-table tr.checks-row").show();
|
|
return;
|
|
}
|
|
|
|
function applySingle(index, element) {
|
|
var nameDiv = element.querySelector(".my-checks-name");
|
|
if (search) {
|
|
var haystack = [nameDiv.dataset.name, nameDiv.dataset.slug, element.id].join("\n");
|
|
if (haystack.toLowerCase().indexOf(search) == -1) {
|
|
$(element).hide();
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (checked.length) {
|
|
var tags = nameDiv.dataset.tags.split(" ");
|
|
for (var i=0, checkedTag; checkedTag=checked[i]; i++) {
|
|
if (tags.indexOf(checkedTag) == -1) {
|
|
$(element).hide();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
$(element).show();
|
|
}
|
|
|
|
// For each row, see if it needs to be shown or hidden
|
|
$("#checks-table tr.checks-row").each(applySingle);
|
|
}
|
|
|
|
// User clicks on tags: apply filters
|
|
$("#my-checks-tags div").click(function() {
|
|
$(this).toggleClass('checked');
|
|
applyFilters();
|
|
});
|
|
|
|
// User changes the search string: apply filters
|
|
$("#search").keyup(applyFilters);
|
|
|
|
function switchUrlFormat(format) {
|
|
var url = new URL(window.location.href);
|
|
url.searchParams.delete("urls");
|
|
url.searchParams.append("urls", format);
|
|
window.location.href = url.toString();
|
|
return false;
|
|
}
|
|
|
|
$("#to-uuid").click(e => switchUrlFormat("uuid"));
|
|
$("#to-slug").click(e => switchUrlFormat("slug"));
|
|
|
|
$(".show-log").click(function(e) {
|
|
var code = $(this).closest("tr.checks-row").attr("id");
|
|
var url = base + "/checks/" + code + "/details/";
|
|
window.location = url;
|
|
return false;
|
|
});
|
|
|
|
$(".pause").tooltip({
|
|
title: "Pause this check?<br />Click again to confirm.",
|
|
trigger: "manual",
|
|
html: true
|
|
});
|
|
|
|
$(".pause").click(function() {
|
|
var btn = $(this);
|
|
|
|
// First click: show a confirmation tooltip
|
|
if (!btn.hasClass("confirm")) {
|
|
btn.addClass("confirm").tooltip("show");
|
|
return false;
|
|
}
|
|
|
|
// Second click: update UI and pause the check
|
|
btn.removeClass("confirm").tooltip("hide");
|
|
var code = btn.closest("tr.checks-row").attr("id");
|
|
$("#" + code + " span.status").attr("class", "status ic-paused");
|
|
|
|
var url = base + "/checks/" + code + "/pause/";
|
|
var token = $('input[name=csrfmiddlewaretoken]').val();
|
|
$.ajax({
|
|
url: url,
|
|
type: "post",
|
|
headers: {"X-CSRFToken": token}
|
|
});
|
|
|
|
return false;
|
|
});
|
|
|
|
$(".pause").mouseleave(function() {
|
|
$(this).removeClass("confirm").tooltip("hide");
|
|
});
|
|
|
|
$('[data-toggle="tooltip"]').tooltip({
|
|
html: true,
|
|
container: "body",
|
|
title: function() {
|
|
var cssClasses = this.getAttribute("class");
|
|
if (cssClasses.indexOf("ic-new") > -1)
|
|
return "New. Has never received a ping.";
|
|
if (cssClasses.indexOf("ic-paused") > -1)
|
|
return "Monitoring paused. Ping to resume.";
|
|
|
|
if (cssClasses.indexOf("sort-name") > -1)
|
|
return "Sort by name<br />(but failed always first)";
|
|
|
|
if (cssClasses.indexOf("sort-last-ping") > -1)
|
|
return "Sort by last ping<br />(but failed always first)";
|
|
}
|
|
});
|
|
|
|
// Schedule refresh to run every 3s when tab is visible and user
|
|
// is active, every 60s otherwise
|
|
var lastStatus = {};
|
|
var lastStarted = {};
|
|
var lastPing = {};
|
|
var statusUrl = $("#checks-table").data("status-url");
|
|
function refreshStatus() {
|
|
$.ajax({
|
|
url: statusUrl,
|
|
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;
|
|
$("#" + el.code + " span.status").attr("class", "status ic-" + el.status);
|
|
}
|
|
|
|
if (lastStarted[el.code] != el.started) {
|
|
lastStarted[el.code] = el.started;
|
|
$("#" + el.code + " .spinner").toggleClass("started", el.started);
|
|
}
|
|
|
|
if (lastPing[el.code] != el.last_ping) {
|
|
lastPing[el.code] = el.last_ping;
|
|
$("#" + el.code + " .last-ping").html(el.last_ping);
|
|
}
|
|
}
|
|
|
|
$("#my-checks-tags > div.btn").each(function(a) {
|
|
tag = this.innerText;
|
|
this.setAttribute("data-tooltip", data.tags[tag][1]);
|
|
var status = data.tags[tag][0];
|
|
if (lastStatus[tag] != status) {
|
|
$(this).removeClass("up grace down").addClass(status);
|
|
lastStatus[tag] = status;
|
|
}
|
|
});
|
|
|
|
if (document.title != data.title) {
|
|
document.title = data.title;
|
|
var downPostfix = data.title.includes("down") ? "_down" : "";
|
|
favicon.href = `${base}/static/img/favicon${downPostfix}.svg`;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
// Schedule regular status updates:
|
|
if (statusUrl) {
|
|
adaptiveSetInterval(refreshStatus);
|
|
}
|
|
|
|
// Configure Selectize for entering tags
|
|
function divToOption() {
|
|
return {value: this.textContent};
|
|
}
|
|
|
|
$("#update-tags-input").selectize({
|
|
create: true,
|
|
createOnBlur: true,
|
|
selectOnTab: false,
|
|
delimiter: " ",
|
|
labelField: "value",
|
|
searchField: ["value"],
|
|
hideSelected: true,
|
|
highlight: false,
|
|
options: $("#my-checks-tags div").map(divToOption).get()
|
|
});
|
|
|
|
$('.my-checks-url').tooltip({container: "body", title: "Click to copy"});
|
|
$('.my-checks-url').click(function(e) {
|
|
if (window.getSelection().toString()) {
|
|
// do nothing, selection not empty
|
|
return;
|
|
}
|
|
|
|
navigator.clipboard.writeText(this.textContent);
|
|
$(".tooltip-inner").text("Copied!");
|
|
});
|
|
|
|
}); |