You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

299 lines
9.5 KiB

10 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
  1. $(function () {
  2. var base = document.getElementById("base-url").getAttribute("href").slice(0, -1);
  3. $(".rw .my-checks-name").click(function() {
  4. var code = $(this).closest("tr.checks-row").attr("id");
  5. var url = base + "/checks/" + code + "/name/";
  6. $("#update-name-form").attr("action", url);
  7. $("#update-name-input").val(this.dataset.name);
  8. var tagsSelectize = document.getElementById("update-tags-input").selectize;
  9. tagsSelectize.setValue(this.dataset.tags.split(" "));
  10. $("#update-desc-input").val(this.dataset.desc);
  11. $('#update-name-modal').modal("show");
  12. $("#update-name-input").focus();
  13. return false;
  14. });
  15. $(".integrations").tooltip({
  16. container: "body",
  17. selector: "span",
  18. title: function() {
  19. var idx = $(this).index();
  20. return $("#ch-" + idx).data("title");
  21. }
  22. });
  23. $(".rw .integrations").on("click", "span", function() {
  24. var isOff = $(this).toggleClass("off").hasClass("off");
  25. var token = $('input[name=csrfmiddlewaretoken]').val();
  26. var idx = $(this).index();
  27. var checkCode = $(this).closest("tr.checks-row").attr("id");
  28. var channelCode = $("#ch-" + idx).data("code");
  29. var url = base + "/checks/" + checkCode + "/channels/" + channelCode + "/enabled";
  30. $.ajax({
  31. url: url,
  32. type: "post",
  33. headers: {"X-CSRFToken": token},
  34. data: {"state": isOff ? "off" : "on"}
  35. });
  36. return false;
  37. });
  38. $(".last-ping").on("click", function() {
  39. if (this.innerText == "Never") {
  40. return false;
  41. }
  42. $("#ping-details-body").text("Updating...");
  43. $('#ping-details-modal').modal("show");
  44. var code = $(this).closest("tr.checks-row").attr("id");
  45. var lastPingUrl = base + "/checks/" + code + "/last_ping/";
  46. $.get(lastPingUrl, function(data) {
  47. $("#ping-details-body" ).html(data);
  48. var htmlPre = $("#email-body-html pre");
  49. if (htmlPre.length) {
  50. var opts = {USE_PROFILES: {html: true}};
  51. var clean = DOMPurify.sanitize(htmlPre.text(), opts);
  52. var blob = new Blob([clean], {type: "text/html; charset=utf-8"});
  53. var iframe = document.createElement("iframe");
  54. iframe.sandbox = "";
  55. iframe.src = URL.createObjectURL(blob);
  56. htmlPre.replaceWith(iframe);
  57. }
  58. });
  59. var logUrl = base + "/checks/" + code + "/log/";
  60. $("#ping-details-log").attr("href", logUrl);
  61. return false;
  62. });
  63. $(".last-ping").tooltip({
  64. selector: ".label-confirmation",
  65. title: 'The word "confirm" was found in request body'
  66. });
  67. function applyFilters() {
  68. // Make a list of currently checked tags:
  69. var checked = [];
  70. var qs = [];
  71. $("#my-checks-tags .checked").each(function(index, el) {
  72. checked.push(el.textContent);
  73. qs.push({"name": "tag", "value": el.textContent});
  74. });
  75. var search = $("#search").val().toLowerCase();
  76. if (search) {
  77. qs.push({"name": "search", "value": search});
  78. }
  79. // Update hash
  80. if (window.history && window.history.replaceState) {
  81. var url = $("#checks-table").data("list-url");
  82. if (qs.length) {
  83. url += "?" + $.param(qs);
  84. }
  85. window.history.replaceState({}, "", url);
  86. }
  87. // No checked tags and no search string: show all
  88. if (checked.length == 0 && !search) {
  89. $("#checks-table tr.checks-row").show();
  90. return;
  91. }
  92. function applySingle(index, element) {
  93. if (search) {
  94. var code = element.getAttribute("id");
  95. var name = $(".my-checks-name", element).attr("data-name").toLowerCase();
  96. if (name.indexOf(search) == -1 && code.indexOf(search) == -1) {
  97. $(element).hide();
  98. return;
  99. }
  100. }
  101. if (checked.length) {
  102. // use attr(), as data() tries converting strings to JS types:
  103. // (e.g., "123" -> 123)
  104. var tags = $(".my-checks-name", element).attr("data-tags").split(" ");
  105. for (var i=0, tag; tag=checked[i]; i++) {
  106. if (tags.indexOf(tag) == -1) {
  107. $(element).hide();
  108. return;
  109. }
  110. }
  111. }
  112. $(element).show();
  113. }
  114. // For each row, see if it needs to be shown or hidden
  115. $("#checks-table tr.checks-row").each(applySingle);
  116. }
  117. // User clicks on tags: apply filters
  118. $("#my-checks-tags div").click(function() {
  119. $(this).toggleClass('checked');
  120. applyFilters();
  121. });
  122. // User changes the search string: apply filters
  123. $("#search").keyup(applyFilters);
  124. $(".show-log").click(function(e) {
  125. var code = $(this).closest("tr.checks-row").attr("id");
  126. var url = base + "/checks/" + code + "/details/";
  127. window.location = url;
  128. return false;
  129. });
  130. $(".pause").tooltip({
  131. title: "Pause this check?<br />Click again to confirm.",
  132. trigger: "manual",
  133. html: true
  134. });
  135. $(".pause").click(function() {
  136. var btn = $(this);
  137. // First click: show a confirmation tooltip
  138. if (!btn.hasClass("confirm")) {
  139. btn.addClass("confirm").tooltip("show");
  140. return false;
  141. }
  142. // Second click: update UI and pause the check
  143. btn.removeClass("confirm").tooltip("hide");
  144. var code = btn.closest("tr.checks-row").attr("id");
  145. $("#" + code + " span.status").attr("class", "status ic-paused");
  146. var url = base + "/checks/" + code + "/pause/";
  147. var token = $('input[name=csrfmiddlewaretoken]').val();
  148. $.ajax({
  149. url: url,
  150. type: "post",
  151. headers: {"X-CSRFToken": token}
  152. });
  153. return false;
  154. });
  155. $(".pause").mouseleave(function() {
  156. $(this).removeClass("confirm").tooltip("hide");
  157. });
  158. $('[data-toggle="tooltip"]').tooltip({
  159. html: true,
  160. container: "body",
  161. title: function() {
  162. var cssClasses = this.getAttribute("class");
  163. if (cssClasses.indexOf("ic-new") > -1)
  164. return "New. Has never received a ping.";
  165. if (cssClasses.indexOf("ic-paused") > -1)
  166. return "Monitoring paused. Ping to resume.";
  167. if (cssClasses.indexOf("sort-name") > -1)
  168. return "Sort by name<br />(but failed always first)";
  169. if (cssClasses.indexOf("sort-last-ping") > -1)
  170. return "Sort by last ping<br />(but failed always first)";
  171. }
  172. });
  173. // Schedule refresh to run every 3s when tab is visible and user
  174. // is active, every 60s otherwise
  175. var lastStatus = {};
  176. var lastStarted = {};
  177. var lastPing = {};
  178. var statusUrl = $("#checks-table").data("status-url");
  179. function refreshStatus() {
  180. $.ajax({
  181. url: statusUrl,
  182. dataType: "json",
  183. timeout: 2000,
  184. success: function(data) {
  185. for(var i=0, el; el=data.details[i]; i++) {
  186. if (lastStatus[el.code] != el.status) {
  187. lastStatus[el.code] = el.status;
  188. $("#" + el.code + " span.status").attr("class", "status ic-" + el.status);
  189. }
  190. if (lastStarted[el.code] != el.started) {
  191. lastStarted[el.code] = el.started;
  192. $("#" + el.code + " .spinner").toggleClass("started", el.started);
  193. }
  194. if (lastPing[el.code] != el.last_ping) {
  195. lastPing[el.code] = el.last_ping;
  196. $("#lpd-" + el.code).html(el.last_ping);
  197. }
  198. }
  199. $("#my-checks-tags div").each(function(a) {
  200. var status = data.tags[this.innerText];
  201. if (lastStatus[this.innerText] == status)
  202. return;
  203. $(this).removeClass("up grace down").addClass(status);
  204. lastStatus[this.innerText] = status;
  205. });
  206. if (document.title != data.title) {
  207. document.title = data.title;
  208. }
  209. }
  210. });
  211. }
  212. // Schedule regular status updates:
  213. if (statusUrl) {
  214. adaptiveSetInterval(refreshStatus);
  215. }
  216. // Copy to clipboard
  217. var clipboard = new Clipboard('button.copy-link');
  218. $("button.copy-link").mouseout(function(e) {
  219. setTimeout(function() {
  220. e.target.textContent = "copy";
  221. }, 300);
  222. });
  223. clipboard.on('success', function(e) {
  224. e.trigger.textContent = "copied!";
  225. e.clearSelection();
  226. });
  227. clipboard.on('error', function(e) {
  228. var text = e.trigger.getAttribute("data-clipboard-text");
  229. prompt("Press Ctrl+C to select:", text)
  230. });
  231. // Configure Selectize for entering tags
  232. function divToOption() {
  233. return {value: this.textContent};
  234. }
  235. $("#update-tags-input").selectize({
  236. create: true,
  237. createOnBlur: true,
  238. delimiter: " ",
  239. labelField: "value",
  240. searchField: ["value"],
  241. hideSelected: true,
  242. highlight: false,
  243. options: $("#my-checks-tags div").map(divToOption).get()
  244. });
  245. });