diff --git a/assets/static/base.css b/assets/static/base.css index 149871209..4bf9ff61c 100644 --- a/assets/static/base.css +++ b/assets/static/base.css @@ -246,7 +246,21 @@ blockquote.silence-comment { } .silence-block { margin-bottom: 2px; - padding: 0; + padding-left: 0; + padding-right: 2px; + padding-top: 2px; + padding-bottom: 0; +} + +/* button is an icon inside a well, it gets white color + make it dark gray by default, so it's visible but doesn't stand out + and black on hover */ +button.silence-delete { + color: inherit; +} +button.silence-delete:hover, +button.silence-delete:focus { + color: #2c3e50; } .incident .panel { diff --git a/assets/static/unsee.js b/assets/static/unsee.js index ab999f043..a8d2b79f4 100644 --- a/assets/static/unsee.js +++ b/assets/static/unsee.js @@ -1,7 +1,7 @@ /* globals Raven */ // raven.js /* globals moment */ // moment.js -/* globals Alerts, Autocomplete, Colors, Config, Counter, Grid, Filters, Progress, Silence, Summary, Templates, UI, Watchdog */ +/* globals Alerts, Autocomplete, Colors, Config, Counter, Grid, Filters, Progress, Silence, Summary, Templates, UI, Unsilence, Watchdog */ /* exported Unsee */ var Unsee = (function() { @@ -329,6 +329,7 @@ $(document).ready(function() { Templates.Init(); UI.Init(); Silence.Init(); + Unsilence.Init(); Unsee.Init(); // delay initial alert load to allow browser finish rendering diff --git a/assets/static/unsilence.js b/assets/static/unsilence.js new file mode 100644 index 000000000..66fccb0e1 --- /dev/null +++ b/assets/static/unsilence.js @@ -0,0 +1,92 @@ +/* globals Unsee */ + +/* exported Unsilence */ +var Unsilence = (function() { + + var selectors = { + button: "button.silence-delete" + }; + + var unsilenceButtonByID = function(alertmanagerURI, silenceID) { + var amSelector = "[data-alertmanager-uri='" + alertmanagerURI + "']"; + var silenceSelector = "[data-silence-id='" + silenceID + "']"; + return $(selectors.button + amSelector + silenceSelector); + }; + + var markInProgress = function(alertmanagerURI, silenceID) { + var elem = unsilenceButtonByID(alertmanagerURI, silenceID); + elem.attr("title", "Silence is being deleted from Alertmanager"); + elem.tooltip("fixTitle"); + elem.find(".fa").removeClass("fa-times").addClass("fa-refresh fa-spin"); + }; + + var markFailed = function(alertmanagerURI, silenceID, xhr) { + var err = Unsee.ParseAJAXError(xhr, "Failed to delete this silence from Alertmanager"); + var elem = unsilenceButtonByID(alertmanagerURI, silenceID); + elem.attr("title", err); + elem.tooltip("fixTitle"); + elem.find(".fa").removeClass("fa-times fa-refresh fa-spin").addClass("fa-exclamation-circle text-danger"); + + // Disable button, wait 5s and reset button to the original state + elem.data("disabled", "true"); + setTimeout(function() { + elem.find(".fa").removeClass("fa-exclamation-circle text-danger").addClass("fa-times"); + elem.removeData("disabled"); + elem.attr("title", "Delete this silence"); + elem.tooltip("fixTitle"); + }, 5000); + }; + + var markSuccess = function(alertmanagerURI, silenceID) { + var elem = unsilenceButtonByID(alertmanagerURI, silenceID); + elem.attr("title", "Silence deleted from Alertmanager"); + elem.tooltip("fixTitle"); + elem.find(".fa").removeClass("fa-times fa-refresh fa-spin").addClass("fa-check-circle text-success"); + // disable button so it's no longer clickable + elem.data("disabled", "true"); + }; + + var deleteSilence = function(alertmanagerURI, silenceID) { + $.ajax({ + type: "DELETE", + url: alertmanagerURI + "/api/v1/silence/" + silenceID, + error: function(xhr) { + markFailed(alertmanagerURI, silenceID, xhr); + }, + success: function() { + markSuccess(alertmanagerURI, silenceID); + }, + dataType: "json" + }); + }; + + var setupUnsilenceEvents = function() { + $("body").on("click", selectors.button, function(event) { + var elem = $(event.currentTarget); + + if (elem.data("disabled")) { + // if we marked button as disabled then skip all actions + // we use data attr to keep tooplips working on disabled buttons + // setting attr(disabled) via jquery disables bootstrap tooltips + return false; + } + + // hide tooltip for button that triggers this action + elem.tooltip("hide"); + + var amURI = elem.data("alertmanager-uri"); + var silenceID = elem.data("silence-id"); + + // change icon to indicate progress + markInProgress(amURI, silenceID); + + // send DELETE request to Alertmanager + deleteSilence(amURI, silenceID); + }); + }; + + return { + Init: setupUnsilenceEvents + }; + +})(); diff --git a/assets/templates/alertgroup.html b/assets/templates/alertgroup.html index b890ece86..03ba684ab 100644 --- a/assets/templates/alertgroup.html +++ b/assets/templates/alertgroup.html @@ -122,6 +122,15 @@ <% _.each(alert.alertmanager, function(am) { %> <% _.each(am.silences, function(silence) { %>