From 01c108fd416fdabcbb9cb492292d5a7c08f81e80 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Mon, 8 Oct 2018 19:06:10 +0100
Subject: [PATCH] refactor(ui): move label list preview to a dedicated
component
This will be reused in delete confirmation modal
---
ui/src/Components/LabelSetList/index.js | 53 +++++++++++++++++++
.../SilenceModal/SilencePreview/index.js | 45 +++-------------
.../SilenceModal/SilencePreview/index.test.js | 6 +--
3 files changed, 62 insertions(+), 42 deletions(-)
create mode 100644 ui/src/Components/LabelSetList/index.js
diff --git a/ui/src/Components/LabelSetList/index.js b/ui/src/Components/LabelSetList/index.js
new file mode 100644
index 000000000..758ece060
--- /dev/null
+++ b/ui/src/Components/LabelSetList/index.js
@@ -0,0 +1,53 @@
+import React from "react";
+import PropTypes from "prop-types";
+
+import hash from "object-hash";
+
+import { AlertStore } from "Stores/AlertStore";
+import { StaticLabel } from "Components/Labels/StaticLabel";
+
+// take a list of groups and outputs a list of label sets, this ignores
+// the receiver, so we'll end up with only unique alerts
+const GroupListToUniqueLabelsList = groups => {
+ const alerts = {};
+ for (const group of groups) {
+ for (const alert of group.alerts) {
+ const alertLabels = Object.assign(
+ {},
+ group.labels,
+ group.shared.labels,
+ alert.labels
+ );
+ const alertHash = hash(alertLabels);
+ alerts[alertHash] = alertLabels;
+ }
+ }
+ return Object.values(alerts);
+};
+
+// used in new silence form preview stage and when deleting silences
+const LabelSetList = ({ alertStore, labelsList }) =>
+ labelsList.length > 0 ? (
+
+ {labelsList.map(labels => (
+ -
+ {Object.entries(labels).map(([name, value]) => (
+
+ ))}
+
+ ))}
+
+ ) : (
+ No alerts matched
+ );
+LabelSetList.propTypes = {
+ alertStore: PropTypes.instanceOf(AlertStore).isRequired,
+ labelsList: PropTypes.arrayOf(PropTypes.object).isRequired
+};
+
+export { LabelSetList, GroupListToUniqueLabelsList };
diff --git a/ui/src/Components/SilenceModal/SilencePreview/index.js b/ui/src/Components/SilenceModal/SilencePreview/index.js
index 6f3144736..46fff071d 100644
--- a/ui/src/Components/SilenceModal/SilencePreview/index.js
+++ b/ui/src/Components/SilenceModal/SilencePreview/index.js
@@ -4,8 +4,6 @@ import PropTypes from "prop-types";
import { observable, action } from "mobx";
import { observer } from "mobx-react";
-import hash from "object-hash";
-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faArrowLeft } from "@fortawesome/free-solid-svg-icons/faArrowLeft";
import { faCheckCircle } from "@fortawesome/free-solid-svg-icons/faCheckCircle";
@@ -13,7 +11,10 @@ import { faExclamationCircle } from "@fortawesome/free-solid-svg-icons/faExclama
import { AlertStore, FormatBackendURI, FormatAlertsQ } from "Stores/AlertStore";
import { SilenceFormStore } from "Stores/SilenceFormStore";
-import { StaticLabel } from "Components/Labels/StaticLabel";
+import {
+ LabelSetList,
+ GroupListToUniqueLabelsList
+} from "Components/LabelSetList";
import { MatcherToFilter, AlertManagersToFilter } from "../Matchers";
const FetchError = ({ message }) => (
@@ -28,27 +29,6 @@ FetchError.propTypes = {
message: PropTypes.node.isRequired
};
-const Preview = ({ alertStore, labelsList }) => (
-
- {labelsList.map(labels => (
- -
- {Object.entries(labels).map(([name, value]) => (
-
- ))}
-
- ))}
-
-);
-Preview.propTypes = {
- alertStore: PropTypes.instanceOf(AlertStore).isRequired,
- labelsList: PropTypes.arrayOf(PropTypes.object).isRequired
-};
-
const SilencePreview = observer(
class SilencePreview extends Component {
static propTypes = {
@@ -64,20 +44,7 @@ const SilencePreview = observer(
// take a list of groups and outputs a list of label sets, this ignores
// the receiver, so we'll end up with only unique alerts
groupsToUniqueLabels(groups) {
- const alerts = {};
- for (const group of groups) {
- for (const alert of group.alerts) {
- const alertLabels = Object.assign(
- {},
- group.labels,
- group.shared.labels,
- alert.labels
- );
- const alertHash = hash(alertLabels);
- alerts[alertHash] = alertLabels;
- }
- }
- this.alertLabels = Object.values(alerts);
+ this.alertLabels = GroupListToUniqueLabelsList(groups);
},
setError(value) {
this.error = value;
@@ -135,7 +102,7 @@ const SilencePreview = observer(
silence.
-
diff --git a/ui/src/Components/SilenceModal/SilencePreview/index.test.js b/ui/src/Components/SilenceModal/SilencePreview/index.test.js
index 91b10d70a..9288082bc 100644
--- a/ui/src/Components/SilenceModal/SilencePreview/index.test.js
+++ b/ui/src/Components/SilenceModal/SilencePreview/index.test.js
@@ -95,10 +95,10 @@ describe("
", () => {
tree.update();
expect(tree.find("FetchError")).toHaveLength(1);
expect(consoleSpy).toHaveBeenCalled();
- expect(tree.find("Preview")).toHaveLength(0);
+ expect(tree.find("LabelSetList")).toHaveLength(0);
});
- it("renders Preview on successful fetch", async () => {
+ it("renders LabelSetList on successful fetch", async () => {
fetch.mockResponse(JSON.stringify(MockAPIResponse()));
const tree = MountedSilencePreview();
@@ -106,7 +106,7 @@ describe("
", () => {
tree.update();
expect(tree.find("FetchError")).toHaveLength(0);
- expect(tree.find("Preview")).toHaveLength(1);
+ expect(tree.find("LabelSetList")).toHaveLength(1);
});
it("clicking on the submit button moves form to the 'Submit' stage", () => {