feat(storybook): add more stories to storybook

This commit is contained in:
Łukasz Mierzwa
2019-11-26 23:36:07 +00:00
parent 361f50cfd9
commit f3e2ed2b00
20 changed files with 713 additions and 394 deletions
+2 -172
View File
@@ -2,9 +2,7 @@ import React from "react";
import { storiesOf } from "@storybook/react";
import moment from "moment";
import { MockAlert, MockAlertGroup, MockSilence } from "__mocks__/Alerts.js";
import { MockGrid } from "__mocks__/Stories.js";
import { AlertStore } from "Stores/AlertStore";
import { Settings } from "Stores/Settings";
import { SilenceFormStore } from "Stores/SilenceFormStore";
@@ -14,61 +12,6 @@ import { Grid } from ".";
import "Percy.scss";
const MockGroup = (groupName, alertCount, active, suppressed, unprocessed) => {
let alerts = [];
for (let i = 1; i <= alertCount; i++) {
let state;
switch (true) {
case i > active && i <= active + suppressed:
state = "suppressed";
break;
case i > active + suppressed:
state = "unprocessed";
break;
default:
state = "active";
}
const alert = MockAlert(
alertCount < 4
? [
{
name: "dashboard",
value: "http://localhost",
visible: true,
isLink: true
},
{
name: "help",
value: "this is a summary text",
visible: true,
isLink: false
},
{
name: "hidden",
value: "this is hidden by default",
visible: false,
isLink: false
}
]
: [],
{ instance: `instance${i}` },
state
);
alert.startsAt = moment()
.subtract(alertCount, "minutes")
.toISOString();
alerts.push(alert);
}
const group = MockAlertGroup(
{ alertname: "Fake Alert", group: groupName },
alerts,
[],
{},
{}
);
return group;
};
storiesOf("Grid", module)
.add("FatalError", () => {
return (
@@ -83,120 +26,7 @@ storiesOf("Grid", module)
const settingsStore = new Settings();
const silenceFormStore = new SilenceFormStore();
alertStore.settings.values.alertAcknowledgement.enabled = true;
const silence = MockSilence();
silence.startsAt = "2018-08-14T12:00:00Z";
silence.endsAt = "2018-08-14T18:00:00Z";
alertStore.data.silences = { am: {} };
alertStore.data.silences["am"][silence.id] = silence;
alertStore.data.colors = {
group: {
group1: {
brightness: 50,
background: { red: 178, green: 55, blue: 247, alpha: 255 }
},
group2: {
brightness: 50,
background: { red: 200, green: 100, blue: 66, alpha: 255 }
},
group3: {
brightness: 205,
background: { red: 246, green: 176, blue: 247, alpha: 255 }
},
group4: {
brightness: 111,
background: { red: 115, green: 101, blue: 152, alpha: 255 }
}
},
instance: {
instance1: {
brightness: 50,
background: { red: 111, green: 65, blue: 40, alpha: 255 }
},
instance2: {
brightness: 50,
background: { red: 66, green: 99, blue: 66, alpha: 255 }
},
instance3: {
brightness: 150,
background: { red: 66, green: 250, blue: 123, alpha: 255 }
}
}
};
let groups = [];
for (let i = 1; i <= 10; i++) {
const active = Math.max(1, Math.ceil(i / 3));
const suppressed = Math.max(0, i - 2 * Math.ceil(i / 3));
const unprocessed = Math.max(0, i - active - suppressed);
const id = `id${i}`;
const hash = `hash${i}`;
const group = MockGroup(`group${i}`, i, active, suppressed, unprocessed);
for (let j = 0; j < group.alerts.length; j++) {
if (group.alerts[j].state === "suppressed") {
group.alerts[j].silencedBy = [silence.id];
group.alerts[j].alertmanager = [
{
name: "am1",
cluster: "am",
state: "suppressed",
startsAt: "2018-08-14T17:36:40.017867056Z",
source: "localhost/prometheus",
silencedBy: [
j < 2 ? "'Fake Silence ID / Should be fallback'" : silence.id
],
inhibitedBy: []
}
];
}
}
group.id = id;
group.hash = hash;
group.stateCount.active = active;
group.stateCount.suppressed = suppressed;
group.stateCount.unprocessed = unprocessed;
if (i < 3) {
group.shared.labels = {
cluster: `prod${i}`,
job: "textfile_exporter"
};
}
if (i < 5) {
group.shared.annotations = [
{
name: "summary",
value: "Only 5% free space left on /disk",
visible: true,
isLink: false
}
];
}
groups.push(group);
}
alertStore.data.upstreams = {
counters: { total: 3, healthy: 1, failed: 2 },
instances: [
{ name: "am1", uri: "http://localhost:9093", error: "" },
{
name: "am2",
uri: "http://localhost:9094",
error: "Failed to connect to http://localhost:9094"
},
{
name: "failed",
uri: "https://am.example.com",
error:
"Failed to connect to https://am.example.com veryLongStringToTestTextWrappingveryLongStringToTestTextWrappingveryLongStringToTestTextWrappingveryLongStringToTestTextWrappingveryLongStringToTestTextWrappingveryLongStringToTestTextWrapping"
}
],
clusters: { am: ["am1", "am2"], failed: ["failed"] }
};
alertStore.data.groups = groups;
MockGrid(alertStore);
return (
<Grid
@@ -75,7 +75,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible card\\">
<div class=\\"Collapsible__trigger is-closed card-header cursor-pointer border-bottom-0\\">
<div class=\\"Collapsible__trigger is-open card-header cursor-pointer bg-light\\">
<div class=\\"d-flex flex-row justify-content-between\\">
<div>
Filter bar configuration
@@ -84,14 +84,14 @@ exports[`<Configuration /> matches snapshot 1`] = `
<svg aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 text-muted\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 text-muted\\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
@@ -99,7 +99,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible__contentOuter collapse show\\"
style=\\"height:0;-webkit-transition:height 50ms linear;-ms-transition:height 50ms linear;transition:height 50ms linear;overflow:hidden\\"
style=\\"height:auto;-webkit-transition:none;-ms-transition:none;transition:none;overflow:visible\\"
>
<div class=\\"Collapsible__contentInner card-body my-2\\">
<div class=\\"form-group mb-0\\">
@@ -123,7 +123,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible card\\">
<div class=\\"Collapsible__trigger is-closed card-header cursor-pointer border-bottom-0\\">
<div class=\\"Collapsible__trigger is-open card-header cursor-pointer bg-light\\">
<div class=\\"d-flex flex-row justify-content-between\\">
<div>
Theme
@@ -132,14 +132,14 @@ exports[`<Configuration /> matches snapshot 1`] = `
<svg aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 text-muted\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 text-muted\\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
@@ -147,7 +147,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible__contentOuter collapse show\\"
style=\\"height:0;-webkit-transition:height 50ms linear;-ms-transition:height 50ms linear;transition:height 50ms linear;overflow:hidden\\"
style=\\"height:auto;-webkit-transition:none;-ms-transition:none;transition:none;overflow:visible\\"
>
<div class=\\"Collapsible__contentInner card-body my-2\\">
<div class=\\"form-group mb-2\\">
@@ -189,7 +189,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible card\\">
<div class=\\"Collapsible__trigger is-closed card-header cursor-pointer border-bottom-0\\">
<div class=\\"Collapsible__trigger is-open card-header cursor-pointer bg-light\\">
<div class=\\"d-flex flex-row justify-content-between\\">
<div>
Minimal alert group width
@@ -198,14 +198,14 @@ exports[`<Configuration /> matches snapshot 1`] = `
<svg aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 text-muted\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 text-muted\\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
@@ -213,7 +213,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible__contentOuter collapse show\\"
style=\\"height:0;-webkit-transition:height 50ms linear;-ms-transition:height 50ms linear;transition:height 50ms linear;overflow:hidden\\"
style=\\"height:auto;-webkit-transition:none;-ms-transition:none;transition:none;overflow:visible\\"
>
<div class=\\"Collapsible__contentInner card-body my-2\\">
<div class=\\"form-group mb-0 text-center\\">
@@ -260,7 +260,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible card\\">
<div class=\\"Collapsible__trigger is-closed card-header cursor-pointer border-bottom-0\\">
<div class=\\"Collapsible__trigger is-open card-header cursor-pointer bg-light\\">
<div class=\\"d-flex flex-row justify-content-between\\">
<div>
Default number of alerts to show per group
@@ -269,14 +269,14 @@ exports[`<Configuration /> matches snapshot 1`] = `
<svg aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 text-muted\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 text-muted\\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
@@ -284,7 +284,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible__contentOuter collapse show\\"
style=\\"height:0;-webkit-transition:height 50ms linear;-ms-transition:height 50ms linear;transition:height 50ms linear;overflow:hidden\\"
style=\\"height:auto;-webkit-transition:none;-ms-transition:none;transition:none;overflow:visible\\"
>
<div class=\\"Collapsible__contentInner card-body my-2\\">
<div class=\\"form-group mb-0 text-center\\">
@@ -331,7 +331,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible card\\">
<div class=\\"Collapsible__trigger is-closed card-header cursor-pointer border-bottom-0\\">
<div class=\\"Collapsible__trigger is-open card-header cursor-pointer bg-light\\">
<div class=\\"d-flex flex-row justify-content-between\\">
<div>
Default alert group display
@@ -340,14 +340,14 @@ exports[`<Configuration /> matches snapshot 1`] = `
<svg aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 text-muted\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 text-muted\\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
@@ -355,7 +355,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible__contentOuter collapse show\\"
style=\\"height:0;-webkit-transition:height 50ms linear;-ms-transition:height 50ms linear;transition:height 50ms linear;overflow:hidden\\"
style=\\"height:auto;-webkit-transition:none;-ms-transition:none;transition:none;overflow:visible\\"
>
<div class=\\"Collapsible__contentInner card-body my-2\\">
<div class=\\"form-group mb-0\\">
@@ -410,7 +410,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible card\\">
<div class=\\"Collapsible__trigger is-closed card-header cursor-pointer border-bottom-0\\">
<div class=\\"Collapsible__trigger is-open card-header cursor-pointer bg-light\\">
<div class=\\"d-flex flex-row justify-content-between\\">
<div>
Grid sort order
@@ -419,14 +419,14 @@ exports[`<Configuration /> matches snapshot 1`] = `
<svg aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 text-muted\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 text-muted\\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
@@ -434,7 +434,7 @@ exports[`<Configuration /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible__contentOuter collapse show\\"
style=\\"height:0;-webkit-transition:height 50ms linear;-ms-transition:height 50ms linear;transition:height 50ms linear;overflow:hidden\\"
style=\\"height:auto;-webkit-transition:none;-ms-transition:none;transition:none;overflow:visible\\"
>
<div class=\\"Collapsible__contentInner card-body my-2\\">
<div class=\\"form-group mb-0\\">
@@ -12,7 +12,7 @@ import { AlertGroupCollapseConfiguration } from "./AlertGroupCollapseConfigurati
import { AlertGroupTitleBarColor } from "./AlertGroupTitleBarColor";
import { ThemeConfiguration } from "./ThemeConfiguration";
const Configuration = ({ settingsStore }) => (
const Configuration = ({ settingsStore, defaultIsOpen }) => (
<form className="px-3 accordion">
<Accordion
text="Refresh interval"
@@ -22,6 +22,7 @@ const Configuration = ({ settingsStore }) => (
<Accordion
text="Filter bar configuration"
content={<FilterBarConfiguration settingsStore={settingsStore} />}
extraProps={{ open: defaultIsOpen }}
/>
<Accordion
text="Theme"
@@ -31,29 +32,35 @@ const Configuration = ({ settingsStore }) => (
<ThemeConfiguration settingsStore={settingsStore} />
</React.Fragment>
}
extraProps={{ open: defaultIsOpen }}
/>
<Accordion
text="Minimal alert group width"
content={<AlertGroupWidthConfiguration settingsStore={settingsStore} />}
extraProps={{ open: defaultIsOpen }}
/>
<Accordion
text="Default number of alerts to show per group"
content={<AlertGroupConfiguration settingsStore={settingsStore} />}
extraProps={{ open: defaultIsOpen }}
/>
<Accordion
text="Default alert group display"
content={
<AlertGroupCollapseConfiguration settingsStore={settingsStore} />
}
extraProps={{ open: defaultIsOpen }}
/>
<Accordion
text="Grid sort order"
content={<AlertGroupSortConfiguration settingsStore={settingsStore} />}
extraProps={{ open: defaultIsOpen }}
/>
</form>
);
Configuration.propTypes = {
settingsStore: PropTypes.instanceOf(Settings).isRequired
settingsStore: PropTypes.instanceOf(Settings).isRequired,
defaultIsOpen: PropTypes.bool.isRequired
};
export { Configuration };
@@ -10,7 +10,9 @@ import { Configuration } from ".";
describe("<Configuration />", () => {
it("matches snapshot", () => {
const settingsStore = new Settings();
const tree = shallow(<Configuration settingsStore={settingsStore} />);
const tree = shallow(
<Configuration settingsStore={settingsStore} defaultIsOpen={true} />
);
expect(toDiffableHtml(tree.html())).toMatchSnapshot();
});
});
+6 -1
View File
@@ -71,7 +71,7 @@ FilterExample.propTypes = {
children: PropTypes.node
};
const Help = () => (
const Help = ({ defaultIsOpen }) => (
<div className="accordion">
<Accordion
text="Fiter operators"
@@ -147,6 +147,7 @@ const Help = () => (
</QueryHelp>
</dl>
}
extraProps={{ open: defaultIsOpen }}
/>
<Accordion
text="Filtering alerts using special filters"
@@ -282,8 +283,12 @@ const Help = () => (
</QueryHelp>
</dl>
}
extraProps={{ open: defaultIsOpen }}
/>
</div>
);
Help.propTypes = {
defaultIsOpen: PropTypes.bool.isRequired
};
export { Help };
+1 -1
View File
@@ -8,7 +8,7 @@ import { Help } from "./Help";
describe("<Help />", () => {
it("matches snapshot", () => {
const tree = shallow(<Help />);
const tree = shallow(<Help defaultIsOpen={true} />);
expect(toDiffableHtml(tree.html())).toMatchSnapshot();
});
});
@@ -21,7 +21,8 @@ const MainModalContent = observer(
alertStore: PropTypes.instanceOf(AlertStore).isRequired,
settingsStore: PropTypes.instanceOf(Settings).isRequired,
onHide: PropTypes.func.isRequired,
openTab: PropTypes.oneOf(Object.values(TabNames))
openTab: PropTypes.oneOf(Object.values(TabNames)),
expandAllOptions: PropTypes.bool.isRequired
};
static defaultProps = {
openTab: TabNames.Configuration
@@ -42,7 +43,12 @@ const MainModalContent = observer(
}
render() {
const { alertStore, settingsStore, onHide } = this.props;
const {
alertStore,
settingsStore,
onHide,
expandAllOptions
} = this.props;
return (
<React.Fragment>
@@ -64,9 +70,14 @@ const MainModalContent = observer(
</nav>
</div>
<div className="modal-body">
{this.tab.current === TabNames.Help ? <Help /> : null}
{this.tab.current === TabNames.Help ? (
<Help defaultIsOpen={expandAllOptions} />
) : null}
{this.tab.current === TabNames.Configuration ? (
<Configuration settingsStore={settingsStore} />
<Configuration
settingsStore={settingsStore}
defaultIsOpen={expandAllOptions}
/>
) : null}
</div>
<div className="modal-footer">
@@ -28,6 +28,7 @@ const FakeModal = () => {
alertStore={alertStore}
settingsStore={settingsStore}
onHide={onHide}
expandAllOptions={true}
/>
);
};
@@ -54,6 +55,7 @@ describe("<MainModalContent />", () => {
alertStore={alertStore}
settingsStore={settingsStore}
onHide={onHide}
expandAllOptions={true}
/>
</span>
);
@@ -163,7 +163,7 @@ exports[`<Help /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible card\\">
<div class=\\"Collapsible__trigger is-closed card-header cursor-pointer border-bottom-0\\">
<div class=\\"Collapsible__trigger is-open card-header cursor-pointer bg-light\\">
<div class=\\"d-flex flex-row justify-content-between\\">
<div>
Filtering using alert labels
@@ -172,14 +172,14 @@ exports[`<Help /> matches snapshot 1`] = `
<svg aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 text-muted\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 text-muted\\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
@@ -187,7 +187,7 @@ exports[`<Help /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible__contentOuter collapse show\\"
style=\\"height:0;-webkit-transition:height 50ms linear;-ms-transition:height 50ms linear;transition:height 50ms linear;overflow:hidden\\"
style=\\"height:auto;-webkit-transition:none;-ms-transition:none;transition:none;overflow:visible\\"
>
<div class=\\"Collapsible__contentInner card-body my-2\\">
<dl>
@@ -339,7 +339,7 @@ exports[`<Help /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible card\\">
<div class=\\"Collapsible__trigger is-closed card-header cursor-pointer border-bottom-0\\">
<div class=\\"Collapsible__trigger is-open card-header cursor-pointer bg-light\\">
<div class=\\"d-flex flex-row justify-content-between\\">
<div>
Filtering alerts using special filters
@@ -348,14 +348,14 @@ exports[`<Help /> matches snapshot 1`] = `
<svg aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 text-muted\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 text-muted\\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
@@ -363,7 +363,7 @@ exports[`<Help /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible__contentOuter collapse show\\"
style=\\"height:0;-webkit-transition:height 50ms linear;-ms-transition:height 50ms linear;transition:height 50ms linear;overflow:hidden\\"
style=\\"height:auto;-webkit-transition:none;-ms-transition:none;transition:none;overflow:visible\\"
>
<div class=\\"Collapsible__contentInner card-body my-2\\">
<dl>
@@ -94,7 +94,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible card\\">
<div class=\\"Collapsible__trigger is-closed card-header cursor-pointer border-bottom-0\\">
<div class=\\"Collapsible__trigger is-open card-header cursor-pointer bg-light\\">
<div class=\\"d-flex flex-row justify-content-between\\">
<div>
Filter bar configuration
@@ -103,14 +103,14 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
<svg aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 text-muted\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 text-muted\\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
@@ -118,7 +118,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible__contentOuter collapse show\\"
style=\\"height: 0px; transition: height 50ms linear; overflow: hidden;\\"
style=\\"height: auto; transition: none; overflow: visible;\\"
>
<div class=\\"Collapsible__contentInner card-body my-2\\">
<div class=\\"form-group mb-0\\">
@@ -142,7 +142,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible card\\">
<div class=\\"Collapsible__trigger is-closed card-header cursor-pointer border-bottom-0\\">
<div class=\\"Collapsible__trigger is-open card-header cursor-pointer bg-light\\">
<div class=\\"d-flex flex-row justify-content-between\\">
<div>
Theme
@@ -151,14 +151,14 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
<svg aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 text-muted\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 text-muted\\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
@@ -166,7 +166,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible__contentOuter collapse show\\"
style=\\"height: 0px; transition: height 50ms linear; overflow: hidden;\\"
style=\\"height: auto; transition: none; overflow: visible;\\"
>
<div class=\\"Collapsible__contentInner card-body my-2\\">
<div class=\\"form-group mb-2\\">
@@ -208,7 +208,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible card\\">
<div class=\\"Collapsible__trigger is-closed card-header cursor-pointer border-bottom-0\\">
<div class=\\"Collapsible__trigger is-open card-header cursor-pointer bg-light\\">
<div class=\\"d-flex flex-row justify-content-between\\">
<div>
Minimal alert group width
@@ -217,14 +217,14 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
<svg aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 text-muted\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 text-muted\\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
@@ -232,7 +232,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible__contentOuter collapse show\\"
style=\\"height: 0px; transition: height 50ms linear; overflow: hidden;\\"
style=\\"height: auto; transition: none; overflow: visible;\\"
>
<div class=\\"Collapsible__contentInner card-body my-2\\">
<div class=\\"form-group mb-0 text-center\\">
@@ -279,7 +279,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible card\\">
<div class=\\"Collapsible__trigger is-closed card-header cursor-pointer border-bottom-0\\">
<div class=\\"Collapsible__trigger is-open card-header cursor-pointer bg-light\\">
<div class=\\"d-flex flex-row justify-content-between\\">
<div>
Default number of alerts to show per group
@@ -288,14 +288,14 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
<svg aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 text-muted\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 text-muted\\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
@@ -303,7 +303,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible__contentOuter collapse show\\"
style=\\"height: 0px; transition: height 50ms linear; overflow: hidden;\\"
style=\\"height: auto; transition: none; overflow: visible;\\"
>
<div class=\\"Collapsible__contentInner card-body my-2\\">
<div class=\\"form-group mb-0 text-center\\">
@@ -350,7 +350,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible card\\">
<div class=\\"Collapsible__trigger is-closed card-header cursor-pointer border-bottom-0\\">
<div class=\\"Collapsible__trigger is-open card-header cursor-pointer bg-light\\">
<div class=\\"d-flex flex-row justify-content-between\\">
<div>
Default alert group display
@@ -359,14 +359,14 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
<svg aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 text-muted\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 text-muted\\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
@@ -374,7 +374,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible__contentOuter collapse show\\"
style=\\"height: 0px; transition: height 50ms linear; overflow: hidden;\\"
style=\\"height: auto; transition: none; overflow: visible;\\"
>
<div class=\\"Collapsible__contentInner card-body my-2\\">
<div class=\\"form-group mb-0\\">
@@ -429,7 +429,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible card\\">
<div class=\\"Collapsible__trigger is-closed card-header cursor-pointer border-bottom-0\\">
<div class=\\"Collapsible__trigger is-open card-header cursor-pointer bg-light\\">
<div class=\\"d-flex flex-row justify-content-between\\">
<div>
Grid sort order
@@ -438,14 +438,14 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
<svg aria-hidden=\\"true\\"
focusable=\\"false\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 text-muted\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 text-muted\\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
@@ -453,7 +453,7 @@ exports[`<MainModalContent /> matches snapshot 1`] = `
</div>
</div>
<div class=\\"Collapsible__contentOuter collapse show\\"
style=\\"height: 0px; transition: height 50ms linear; overflow: hidden;\\"
style=\\"height: auto; transition: none; overflow: visible;\\"
>
<div class=\\"Collapsible__contentInner card-body my-2\\">
<div class=\\"form-group mb-0\\">
+1
View File
@@ -72,6 +72,7 @@ const MainModal = observer(
settingsStore={settingsStore}
onHide={this.toggle.hide}
isVisible={this.toggle.show}
expandAllOptions={false}
/>
</React.Suspense>
</Modal>
@@ -25,6 +25,7 @@ storiesOf("MainModal", module)
settingsStore={settingsStore}
onHide={() => {}}
isVisible={true}
expandAllOptions={true}
/>
);
})
@@ -38,6 +39,7 @@ storiesOf("MainModal", module)
onHide={() => {}}
isVisible={true}
openTab={TabNames.Help}
expandAllOptions={true}
/>
);
});
+20 -12
View File
@@ -23,20 +23,28 @@ const ManagedSilence = observer(
alertStore: PropTypes.instanceOf(AlertStore).isRequired,
silenceFormStore: PropTypes.instanceOf(SilenceFormStore).isRequired,
onDidUpdate: PropTypes.func,
onDeleteModalClose: PropTypes.func
onDeleteModalClose: PropTypes.func,
isOpen: PropTypes.bool
};
static defaultProps = {
isOpen: false
};
// store collapse state, by default only silence comment is visible
// the rest of the silence is hidden until expanded by a click
collapse = observable(
{
value: true,
toggle() {
this.value = !this.value;
}
},
{ toggle: action.bound }
);
constructor(props) {
super(props);
// store collapse state, by default only silence comment is visible
// the rest of the silence is hidden until expanded by a click
this.collapse = observable(
{
value: !props.isOpen,
toggle() {
this.value = !this.value;
}
},
{ toggle: action.bound }
);
}
getAlertmanager = () =>
this.props.alertStore.data.upstreams.instances
@@ -0,0 +1,91 @@
import React from "react";
import { storiesOf } from "@storybook/react";
import { MockSilence } from "__mocks__/Alerts";
import { AlertStore } from "Stores/AlertStore";
import { SilenceFormStore } from "Stores/SilenceFormStore";
import { ManagedSilence } from ".";
import "Percy.scss";
storiesOf("ManagedSilence", module)
.addDecorator(storyFn => (
<div>
<div className="modal-dialog modal-lg" role="document">
<div className="modal-content p-2">{storyFn()}</div>
</div>
</div>
))
.add("Silence", () => {
const alertStore = new AlertStore([]);
const silenceFormStore = new SilenceFormStore();
const cluster = "am";
alertStore.data.upstreams = {
instances: [
{
name: "am1",
cluster: cluster,
clusterMembers: ["am1"],
uri: "http://localhost:9093",
publicURI: "http://example.com",
error: "",
version: "0.15.3",
headers: {}
}
],
clusters: { am: ["am1"] }
};
const silence = MockSilence();
silence.startsAt = "2018-08-14T16:00:00Z";
silence.endsAt = "2018-08-14T18:00:00Z";
const expiredSilence = MockSilence();
expiredSilence.startsAt = "2018-08-14T10:00:00Z";
expiredSilence.endsAt = "2018-08-14T11:00:00Z";
return (
<React.Fragment>
<ManagedSilence
cluster={cluster}
alertCount={123}
alertCountAlwaysVisible={true}
silence={silence}
alertStore={alertStore}
silenceFormStore={silenceFormStore}
onDidUpdate={() => {}}
/>
<ManagedSilence
cluster={cluster}
alertCount={123}
alertCountAlwaysVisible={true}
silence={silence}
alertStore={alertStore}
silenceFormStore={silenceFormStore}
onDidUpdate={() => {}}
isOpen={true}
/>
<ManagedSilence
cluster={cluster}
alertCount={123}
alertCountAlwaysVisible={true}
silence={expiredSilence}
alertStore={alertStore}
silenceFormStore={silenceFormStore}
onDidUpdate={() => {}}
/>
<ManagedSilence
cluster={cluster}
alertCount={123}
alertCountAlwaysVisible={true}
silence={expiredSilence}
alertStore={alertStore}
silenceFormStore={silenceFormStore}
onDidUpdate={() => {}}
isOpen={true}
/>
</React.Fragment>
);
});
+80 -80
View File
@@ -59,87 +59,85 @@ ActionButton.propTypes = {
afterClick: PropTypes.func.isRequired
};
const HistoryMenu = onClickOutside(
({
popperPlacement,
popperRef,
popperStyle,
filters,
alertStore,
settingsStore,
afterClick,
onClear
}) => {
return (
<div
className="dropdown-menu d-block shadow components-navbar-historymenu"
ref={popperRef}
style={popperStyle}
data-placement={popperPlacement}
>
<h6 className="dropdown-header text-center">
<FontAwesomeIcon icon={faHistory} className="mr-1" />
Last used filters
</h6>
{filters.length === 0 ? (
<h6 className="dropdown-header text-muted text-center">Empty</h6>
) : (
filters.map(historyFilters => (
<button
className="dropdown-item cursor-pointer px-3"
key={hash(historyFilters)}
onClick={() => {
alertStore.filters.setFilters(historyFilters.map(f => f.raw));
afterClick();
}}
>
<div className="components-navbar-historymenu-labels pl-2">
{historyFilters.map(f => (
<HistoryLabel
key={f.raw}
alertStore={alertStore}
name={f.name}
matcher={f.matcher}
value={f.value}
/>
))}
</div>
</button>
))
)}
<div className="dropdown-divider" />
<div className="container text-center">
<ActionButton
color="success"
icon={faSave}
title="Save filters"
action={() => {
settingsStore.savedFilters.save(
alertStore.filters.values.map(f => f.raw)
);
const HistoryMenuContent = ({
popperPlacement,
popperRef,
popperStyle,
filters,
alertStore,
settingsStore,
afterClick,
onClear
}) => {
return (
<div
className="dropdown-menu d-block shadow components-navbar-historymenu"
ref={popperRef}
style={popperStyle}
data-placement={popperPlacement}
>
<h6 className="dropdown-header text-center">
<FontAwesomeIcon icon={faHistory} className="mr-1" />
Last used filters
</h6>
{filters.length === 0 ? (
<h6 className="dropdown-header text-muted text-center">Empty</h6>
) : (
filters.map(historyFilters => (
<button
className="dropdown-item cursor-pointer px-3"
key={hash(historyFilters)}
onClick={() => {
alertStore.filters.setFilters(historyFilters.map(f => f.raw));
afterClick();
}}
afterClick={afterClick}
/>
<ActionButton
color="danger"
icon={faUndoAlt}
title="Reset filters"
action={settingsStore.savedFilters.clear}
afterClick={afterClick}
/>
<ActionButton
color="dark"
icon={faTrash}
title="Clear history"
action={onClear}
afterClick={afterClick}
/>
</div>
>
<div className="components-navbar-historymenu-labels pl-2">
{historyFilters.map(f => (
<HistoryLabel
key={f.raw}
alertStore={alertStore}
name={f.name}
matcher={f.matcher}
value={f.value}
/>
))}
</div>
</button>
))
)}
<div className="dropdown-divider" />
<div className="container text-center">
<ActionButton
color="success"
icon={faSave}
title="Save filters"
action={() => {
settingsStore.savedFilters.save(
alertStore.filters.values.map(f => f.raw)
);
}}
afterClick={afterClick}
/>
<ActionButton
color="danger"
icon={faUndoAlt}
title="Reset filters"
action={settingsStore.savedFilters.clear}
afterClick={afterClick}
/>
<ActionButton
color="dark"
icon={faTrash}
title="Clear history"
action={onClear}
afterClick={afterClick}
/>
</div>
);
}
);
HistoryMenu.propTypes = {
</div>
);
};
HistoryMenuContent.propTypes = {
popperPlacement: PropTypes.string,
popperRef: PropTypes.func,
popperStyle: PropTypes.object,
@@ -150,6 +148,8 @@ HistoryMenu.propTypes = {
onClear: PropTypes.func.isRequired
};
const HistoryMenu = onClickOutside(HistoryMenuContent);
const History = observer(
class History extends Component {
static propTypes = {
@@ -278,4 +278,4 @@ const History = observer(
}
);
export { History, HistoryMenu, ReduceFilter };
export { History, HistoryMenu, HistoryMenuContent, ReduceFilter };
+55 -5
View File
@@ -5,6 +5,7 @@ import { storiesOf } from "@storybook/react";
import { AlertStore, NewUnappliedFilter } from "Stores/AlertStore";
import { Settings } from "Stores/Settings";
import { SilenceFormStore } from "Stores/SilenceFormStore";
import { HistoryMenuContent } from "./FilterInput/History";
import { NavBar } from ".";
import "Percy.scss";
@@ -49,11 +50,60 @@ storiesOf("NavBar", module).add("NavBar", () => {
NewFilter("foo", "", "", "", true, true, 2)
];
const history = [
[NewFilter("alertname=Foo", "alertname", "=", "foo", true, true, 15)],
[NewFilter("cluster=staging", "cluster", "=", "staging", true, true, 15)],
[
NewFilter("cluster=staging", "cluster", "=", "staging", true, true, 15),
NewFilter("region=AF", "region", "=", "AF", true, true, 180)
],
[
NewFilter("cluster=staging", "cluster", "=", "staging", true, true, 15),
NewFilter("region=AF", "region", "=", "AF", true, true, 180),
NewFilter(
"instance!=server1",
"instance",
"!=",
"server1",
false,
true,
0
)
],
[
NewFilter(
"alertname=VeryVeryVeryVeryVeryLoooooooooooooooongAlertnameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"alertname",
"=",
"VeryVeryVeryVeryVeryLoooooooooooooooongAlertnameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
true,
true,
15
)
]
];
return (
<NavBar
alertStore={alertStore}
settingsStore={settingsStore}
silenceFormStore={silenceFormStore}
/>
<React.Fragment>
<NavBar
alertStore={alertStore}
settingsStore={settingsStore}
silenceFormStore={silenceFormStore}
/>
<div style={{ position: "absolute", top: "150px", left: "5%" }}>
<HistoryMenuContent
popperPlacement="top"
popperRef={() => {}}
popperStyle={{}}
filters={history}
onClear={() => {}}
alertStore={alertStore}
settingsStore={settingsStore}
afterClick={() => {}}
handleClickOutside={() => {}}
outsideClickIgnoreClass="components-navbar-history"
/>
</div>
</React.Fragment>
);
});
@@ -0,0 +1,25 @@
import React from "react";
import { storiesOf } from "@storybook/react";
import { MockGrid } from "__mocks__/Stories.js";
import { AlertStore } from "Stores/AlertStore";
import { OverviewModalContent } from "./OverviewModalContent";
import "Percy.scss";
storiesOf("OverviewModal", module)
.addDecorator(storyFn => (
<div>
<div className="modal-dialog modal-lg" role="document">
<div className="modal-content">{storyFn()}</div>
</div>
</div>
))
.add("OverviewModal", () => {
const alertStore = new AlertStore([]);
MockGrid(alertStore);
return <OverviewModalContent alertStore={alertStore} onHide={() => {}} />;
});
@@ -171,33 +171,41 @@ TabContentDuration.propTypes = {
const DateTimeSelect = observer(
class DateTimeSelect extends Component {
static propTypes = {
silenceFormStore: PropTypes.instanceOf(SilenceFormStore).isRequired
silenceFormStore: PropTypes.instanceOf(SilenceFormStore).isRequired,
openTab: PropTypes.oneOf(Object.values(TabNames))
};
static defaultProps = {
openTab: TabNames.Duration
};
tab = observable(
{
current: TabNames.Duration,
setStart() {
this.current = TabNames.Start;
constructor(props) {
super(props);
this.tab = observable(
{
current: props.openTab,
setStart() {
this.current = TabNames.Start;
},
setEnd() {
this.current = TabNames.End;
},
setDuration() {
this.current = TabNames.Duration;
},
timeNow: moment().seconds(0),
updateTimeNow() {
this.timeNow = moment().seconds(0);
}
},
setEnd() {
this.current = TabNames.End;
},
setDuration() {
this.current = TabNames.Duration;
},
timeNow: moment().seconds(0),
updateTimeNow() {
this.timeNow = moment().seconds(0);
{
setStart: action.bound,
setEnd: action.bound,
setDuration: action.bound,
updateTimeNow: action.bound
}
},
{
setStart: action.bound,
setEnd: action.bound,
setDuration: action.bound,
updateTimeNow: action.bound
}
);
);
}
componentDidMount() {
this.tab.updateTimeNow();
@@ -274,4 +282,10 @@ const DateTimeSelect = observer(
}
);
export { DateTimeSelect, TabContentStart, TabContentEnd, TabContentDuration };
export {
DateTimeSelect,
TabContentStart,
TabContentEnd,
TabContentDuration,
TabNames
};
+46 -22
View File
@@ -13,6 +13,7 @@ import {
MatcherValueToObject,
SilenceTabNames
} from "Stores/SilenceFormStore";
import { DateTimeSelect, TabNames } from "./DateTimeSelect";
import { SilenceModalContent } from "./SilenceModalContent";
import "Percy.scss";
@@ -25,14 +26,15 @@ const MockMatcher = (name, values, isRegex) => {
return matcher;
};
storiesOf("SilenceModal", module)
.addDecorator(storyFn => (
<div>
<div className="modal-dialog modal-lg" role="document">
<div className="modal-content">{storyFn()}</div>
</div>
const Modal = ({ children }) => (
<div>
<div className="modal-dialog modal-lg" role="document">
<div className="modal-content">{children}</div>
</div>
))
</div>
);
storiesOf("SilenceModal", module)
.add("Editor", () => {
const alertStore = new AlertStore([]);
const settingsStore = new Settings();
@@ -74,14 +76,34 @@ storiesOf("SilenceModal", module)
);
return (
<SilenceModalContent
alertStore={alertStore}
silenceFormStore={silenceFormStore}
settingsStore={settingsStore}
onHide={() => {}}
previewOpen={true}
onDeleteModalClose={() => {}}
/>
<React.Fragment>
<Modal>
<SilenceModalContent
alertStore={alertStore}
silenceFormStore={silenceFormStore}
settingsStore={settingsStore}
onHide={() => {}}
previewOpen={true}
onDeleteModalClose={() => {}}
/>
</Modal>
<Modal>
<div className="pt-2">
<DateTimeSelect
silenceFormStore={silenceFormStore}
openTab={TabNames.Start}
/>
</div>
</Modal>
<Modal>
<div className="pt-2">
<DateTimeSelect
silenceFormStore={silenceFormStore}
openTab={TabNames.End}
/>
</div>
</Modal>
</React.Fragment>
);
})
.add("Browser", () => {
@@ -135,12 +157,14 @@ storiesOf("SilenceModal", module)
});
return (
<SilenceModalContent
alertStore={alertStore}
silenceFormStore={silenceFormStore}
settingsStore={settingsStore}
onHide={() => {}}
onDeleteModalClose={() => {}}
/>
<Modal>
<SilenceModalContent
alertStore={alertStore}
silenceFormStore={silenceFormStore}
settingsStore={settingsStore}
onHide={() => {}}
onDeleteModalClose={() => {}}
/>
</Modal>
);
});
+247
View File
@@ -0,0 +1,247 @@
import moment from "moment";
import { MockAlert, MockAlertGroup, MockSilence } from "./Alerts.js";
const MockGroup = (groupName, alertCount, active, suppressed, unprocessed) => {
let alerts = [];
for (let i = 1; i <= alertCount; i++) {
let state;
switch (true) {
case i > active && i <= active + suppressed:
state = "suppressed";
break;
case i > active + suppressed:
state = "unprocessed";
break;
default:
state = "active";
}
const alert = MockAlert(
alertCount < 4
? [
{
name: "dashboard",
value: "http://localhost",
visible: true,
isLink: true
},
{
name: "help",
value: "this is a summary text",
visible: true,
isLink: false
},
{
name: "hidden",
value: "this is hidden by default",
visible: false,
isLink: false
}
]
: [],
{ instance: `instance${i}` },
state
);
alert.startsAt = moment()
.subtract(alertCount, "minutes")
.toISOString();
alerts.push(alert);
}
const group = MockAlertGroup(
{ alertname: "Fake Alert", group: groupName },
alerts,
[],
{},
{}
);
return group;
};
const MockGrid = alertStore => {
alertStore.settings.values.alertAcknowledgement.enabled = true;
const silence = MockSilence();
silence.startsAt = "2018-08-14T12:00:00Z";
silence.endsAt = "2018-08-14T18:00:00Z";
alertStore.data.silences = { am: {} };
alertStore.data.silences["am"][silence.id] = silence;
alertStore.data.colors = {
group: {
group1: {
brightness: 50,
background: { red: 178, green: 55, blue: 247, alpha: 255 }
},
group2: {
brightness: 50,
background: { red: 200, green: 100, blue: 66, alpha: 255 }
},
group3: {
brightness: 205,
background: { red: 246, green: 176, blue: 247, alpha: 255 }
},
group4: {
brightness: 111,
background: { red: 115, green: 101, blue: 152, alpha: 255 }
}
},
instance: {
instance1: {
brightness: 50,
background: { red: 111, green: 65, blue: 40, alpha: 255 }
},
instance2: {
brightness: 50,
background: { red: 66, green: 99, blue: 66, alpha: 255 }
},
instance3: {
brightness: 150,
background: { red: 66, green: 250, blue: 123, alpha: 255 }
}
}
};
alertStore.data.counters = [
{
name: "@receiver",
hits: 2,
values: [
{
value: "by-cluster-service",
raw: "@receiver=by-cluster-service",
hits: 2,
percent: 100,
offset: 0
}
]
},
{
name: "alertname",
hits: 90,
values: [
{
value: "Fake Alert",
raw: "alertname=Fake Alert",
hits: 45,
percent: 50,
offset: 0
},
{
value: "Second Fake Alert",
raw: "alertname=Second Fake Alert",
hits: 45,
percent: 50,
offset: 50
}
]
},
{
name: "group",
hits: 100,
values: [
{
value: "group1",
raw: "group=group1",
hits: 25,
percent: 25,
offset: 0
},
{
value: "group2",
raw: "group=group2",
hits: 70,
percent: 70,
offset: 25
},
{
value: "group3",
raw: "group=group3",
hits: 4,
percent: 4,
offset: 95
},
{
value: "group4",
raw: "group=group4",
hits: 1,
percent: 1,
offset: 99
}
]
}
];
let groups = [];
for (let i = 1; i <= 10; i++) {
const active = Math.max(1, Math.ceil(i / 3));
const suppressed = Math.max(0, i - 2 * Math.ceil(i / 3));
const unprocessed = Math.max(0, i - active - suppressed);
const id = `id${i}`;
const hash = `hash${i}`;
const group = MockGroup(`group${i}`, i, active, suppressed, unprocessed);
for (let j = 0; j < group.alerts.length; j++) {
if (group.alerts[j].state === "suppressed") {
group.alerts[j].silencedBy = [silence.id];
group.alerts[j].alertmanager = [
{
name: "am1",
cluster: "am",
state: "suppressed",
startsAt: "2018-08-14T17:36:40.017867056Z",
source: "localhost/prometheus",
silencedBy: [
j < 2 ? "'Fake Silence ID / Should be fallback'" : silence.id
],
inhibitedBy: []
}
];
}
}
group.id = id;
group.hash = hash;
group.stateCount.active = active;
group.stateCount.suppressed = suppressed;
group.stateCount.unprocessed = unprocessed;
if (i < 3) {
group.shared.labels = {
cluster: `prod${i}`,
job: "textfile_exporter"
};
}
if (i < 5) {
group.shared.annotations = [
{
name: "summary",
value: "Only 5% free space left on /disk",
visible: true,
isLink: false
}
];
}
groups.push(group);
}
alertStore.data.upstreams = {
counters: { total: 3, healthy: 1, failed: 2 },
instances: [
{ name: "am1", uri: "http://localhost:9093", error: "" },
{
name: "am2",
uri: "http://localhost:9094",
error: "Failed to connect to http://localhost:9094"
},
{
name: "failed",
uri: "https://am.example.com",
error:
"Failed to connect to https://am.example.com veryLongStringToTestTextWrappingveryLongStringToTestTextWrappingveryLongStringToTestTextWrappingveryLongStringToTestTextWrappingveryLongStringToTestTextWrappingveryLongStringToTestTextWrapping"
}
],
clusters: { am: ["am1", "am2"], failed: ["failed"] }
};
alertStore.data.groups = groups;
};
export { MockGrid };