From f099ccc0ead05c899efc190396a73f66810806a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Tue, 5 Mar 2019 11:02:08 +0000 Subject: [PATCH] feat(ui): render an indicator icon when alert is inhibited Right now we don't mark inhibted alerts in any way, so they look like silenced alerts with no silence details. Add an icon with tooltip so inhibited alerts can be easily distinguished from silenced onces --- .../Alert/__snapshots__/index.test.js.snap | 144 ++++++++++++++++++ .../Grid/AlertGrid/AlertGroup/Alert/index.js | 13 ++ .../AlertGrid/AlertGroup/Alert/index.test.js | 22 ++- .../AlertGroup/Silence/index.test.js | 3 +- ui/src/Models/API.js | 3 +- ui/src/__mocks__/Alerts.js | 3 +- 6 files changed, 183 insertions(+), 5 deletions(-) diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/__snapshots__/index.test.js.snap b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/__snapshots__/index.test.js.snap index 23529f82a..464c2d83b 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/__snapshots__/index.test.js.snap +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/__snapshots__/index.test.js.snap @@ -1,5 +1,149 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[` matches snapshot when inhibited 1`] = ` +" +
  • +
    +
    + + + + + + help: + + + some long text + +
    +
    + + + + + hidden +
    +
    + + + + + + + +
    + + + + + + +
    +
    + + + job: + + + node_exporter + + +
    +
    + + + cluster: + + + dev + + +
    + + + + + + link + +
  • +" +`; + exports[` matches snapshot with showAlertmanagers=false showReceiver=false 1`] = ` "
  • diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.js index 650582ea7..941365145 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.js @@ -3,11 +3,15 @@ import PropTypes from "prop-types"; import { observer } from "mobx-react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faVolumeMute } from "@fortawesome/free-solid-svg-icons/faVolumeMute"; + import { APIAlert, APIGroup } from "Models/API"; import { SilenceFormStore } from "Stores/SilenceFormStore"; import { BorderClassMap } from "Common/Colors"; import { StaticLabels } from "Common/Query"; import { FilteringLabel } from "Components/Labels/FilteringLabel"; +import { TooltipWrapper } from "Components/TooltipWrapper"; import { RenderNonLinkAnnotation, RenderLinkAnnotation } from "../Annotation"; import { Silence } from "../Silence"; import { AlertMenu } from "./AlertMenu"; @@ -80,6 +84,15 @@ const Alert = observer( alert={alert} silenceFormStore={silenceFormStore} /> + {alert.alertmanager + .map(am => am.inhibitedBy.length) + .reduce((sum, x) => sum + x) > 0 ? ( + + + + + + ) : null} {Object.entries(alert.labels).map(([name, value]) => ( ))} diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.test.js index f5efc1a1b..29490ee35 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.test.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Alert/index.test.js @@ -66,6 +66,22 @@ describe("", () => { expect(toDiffableHtml(tree.html())).toMatchSnapshot(); }); + it("matches snapshot when inhibited", () => { + const alert = MockedAlert(); + alert.alertmanager[0].inhibitedBy = ["123456"]; + const group = MockAlertGroup({}, [alert], [], {}); + const tree = MountedAlert(alert, group, false, false); + expect(toDiffableHtml(tree.html())).toMatchSnapshot(); + }); + + it("renders inhibition icon when inhibited", () => { + const alert = MockedAlert(); + alert.alertmanager[0].inhibitedBy = ["123456"]; + const group = MockAlertGroup({}, [alert], [], {}); + const tree = MountedAlert(alert, group, false, false); + expect(tree.find(".fa-volume-mute")).toHaveLength(1); + }); + it("renders @alertmanager label with showAlertmanagers=true", () => { const alert = MockedAlert(); const group = MockAlertGroup({}, [alert], [], {}); @@ -106,7 +122,8 @@ describe("", () => { startsAt: "2018-08-14T17:36:40.017867056Z", endsAt: "0001-01-01T00:00:00Z", source: "localhost/am1", - silencedBy: ["silence123456789"] + silencedBy: ["silence123456789"], + inhibitedBy: [] }, { name: "am2", @@ -115,7 +132,8 @@ describe("", () => { startsAt: "2018-08-14T17:36:40.017867056Z", endsAt: "0001-01-01T00:00:00Z", source: "localhost/am2", - silencedBy: ["silence123456789"] + silencedBy: ["silence123456789"], + inhibitedBy: [] } ]; const group = MockAlertGroup({}, [alert], [], {}); diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.test.js index e78c633e9..18dae9633 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.test.js +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.test.js @@ -23,7 +23,8 @@ const alertmanager = { startsAt: "2000-01-01T10:00:00Z", endsAt: "0001-01-01T00:00:00Z", source: "localhost/prometheus", - silencedBy: ["4cf5fd82-1edd-4169-99d1-ff8415e72179"] + silencedBy: ["4cf5fd82-1edd-4169-99d1-ff8415e72179"], + inhibitedBy: [] }; const silence = { diff --git a/ui/src/Models/API.js b/ui/src/Models/API.js index 3c295d48b..f0294b602 100644 --- a/ui/src/Models/API.js +++ b/ui/src/Models/API.js @@ -16,7 +16,8 @@ const APIAlertAlertmanagerState = PropTypes.exact({ startsAt: PropTypes.string.isRequired, endsAt: PropTypes.string.isRequired, source: PropTypes.string.isRequired, - silencedBy: PropTypes.arrayOf(PropTypes.string).isRequired + silencedBy: PropTypes.arrayOf(PropTypes.string).isRequired, + inhibitedBy: PropTypes.arrayOf(PropTypes.string).isRequired }); const APIAlert = PropTypes.exact({ diff --git a/ui/src/__mocks__/Alerts.js b/ui/src/__mocks__/Alerts.js index 3bc685d0e..2d88a36ae 100644 --- a/ui/src/__mocks__/Alerts.js +++ b/ui/src/__mocks__/Alerts.js @@ -19,7 +19,8 @@ const MockAlert = (annotations, labels, state) => ({ startsAt: "2018-08-14T17:36:40.017867056Z", endsAt: "0001-01-01T00:00:00Z", source: "localhost/prometheus", - silencedBy: [] + silencedBy: [], + inhibitedBy: [] } ], receiver: "by-name"