Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui): always use current filters as default silence matchers #1902

Merged
merged 1 commit into from
Jun 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 6 additions & 5 deletions ui/src/Components/SilenceModal/SilenceForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,9 @@ const SilenceForm = ({
// reset cluster request state
silenceFormStore.data.requestsByCluster = {};

if (
silenceFormStore.data.matchers.filter(
(m) => m.name !== "" || m.values.length
).length === 0
) {
if (silenceFormStore.data.autofillMatchers) {
silenceFormStore.data.matchers = [];

if (alertStore.filters.values.length > 0) {
alertStore.filters.values
.filter(
Expand All @@ -73,10 +71,13 @@ const SilenceForm = ({
});
}
}

if (silenceFormStore.data.matchers.length === 0) {
silenceFormStore.data.addEmptyMatcher();
}

silenceFormStore.data.autofillMatchers = false;

// populate author
if (silenceFormStore.data.author === "") {
silenceFormStore.data.author =
Expand Down
40 changes: 39 additions & 1 deletion ui/src/Components/SilenceModal/SilenceForm.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ describe("<SilenceForm /> matchers", () => {
expect(silenceFormStore.data.matchers).toHaveLength(1);
});

it("uses filters to populate default matchers", () => {
it("uses filters to populate default matchers when silenceFormStore.data.autofillMatchers=true", () => {
const filter = (name, matcher, value) => {
const f = NewUnappliedFilter(`${name}${matcher}${value}`);
f.name = name;
Expand All @@ -85,6 +85,7 @@ describe("<SilenceForm /> matchers", () => {
...filterCombos("cluster"),
...filterCombos("foo"),
];
silenceFormStore.data.autofillMatchers = true;
const tree = MountedSilenceForm();
const matchers = tree.find("SilenceMatch");
expect(matchers).toHaveLength(6);
Expand Down Expand Up @@ -151,6 +152,40 @@ describe("<SilenceForm /> matchers", () => {
});
});

it("doesn't use filters to populate default matchers when silenceFormStore.data.autofillMatchers=false", () => {
const filter = (name, matcher, value) => {
const f = NewUnappliedFilter(`${name}${matcher}${value}`);
f.name = name;
f.matcher = matcher;
f.value = value;
return f;
};

const filterCombos = (name) =>
Object.entries(QueryOperators).map(([k, v]) =>
filter(name, v, `${name}${k}`)
);

alertStore.filters.values = [
...filterCombos(StaticLabels.AlertName),
...filterCombos(StaticLabels.AlertManager),
...filterCombos(StaticLabels.Receiver),
...filterCombos(StaticLabels.State),
...filterCombos(StaticLabels.SilenceID),
...filterCombos("cluster"),
...filterCombos("foo"),
];
silenceFormStore.data.autofillMatchers = false;
const tree = MountedSilenceForm();
const matchers = tree.find("SilenceMatch");
expect(matchers).toHaveLength(1);
expect(silenceFormStore.data.matchers[0]).toMatchObject({
isRegex: false,
name: "",
values: [],
});
});

it("clicking 'Add more' button adds another matcher", () => {
const tree = MountedSilenceForm();
const button = tree.find("button[type='button']");
Expand All @@ -170,6 +205,7 @@ describe("<SilenceForm /> matchers", () => {
});

it("trash icon is visible when there are two matchers", () => {
silenceFormStore.data.autofillMatchers = false;
silenceFormStore.data.addEmptyMatcher();
silenceFormStore.data.addEmptyMatcher();
const tree = MountedSilenceForm();
Expand All @@ -181,6 +217,7 @@ describe("<SilenceForm /> matchers", () => {
});

it("clicking trash icon on a matcher select removes it", () => {
silenceFormStore.data.autofillMatchers = false;
silenceFormStore.data.addEmptyMatcher();
silenceFormStore.data.addEmptyMatcher();
silenceFormStore.data.addEmptyMatcher();
Expand Down Expand Up @@ -275,6 +312,7 @@ describe("<SilenceForm />", () => {
silenceFormStore.data.setAlertmanagers([{ label: "am1", value: ["am1"] }]);
silenceFormStore.data.author = "me@example.com";
silenceFormStore.data.comment = "fake silence";
silenceFormStore.data.autofillMatchers = false;
const tree = MountedSilenceForm();
tree.simulate("submit", { preventDefault: jest.fn() });
expect(silenceFormStore.data.currentStage).toBe(SilenceFormStage.Preview);
Expand Down
6 changes: 5 additions & 1 deletion ui/src/Components/SilenceModal/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const SilenceModalContent = React.lazy(() =>
);

const SilenceModal = ({ alertStore, silenceFormStore, settingsStore }) => {
// uses React.useCallback instead of useCallback for tests
const onDeleteModalClose = React.useCallback(() => {
const event = new CustomEvent("remountModal");
window.dispatchEvent(event);
Expand All @@ -46,7 +47,10 @@ const SilenceModal = ({ alertStore, silenceFormStore, settingsStore }) => {
<Modal
isOpen={silenceFormStore.toggle.visible}
toggleOpen={silenceFormStore.toggle.toggle}
onExited={silenceFormStore.data.resetProgress}
onExited={() => {
silenceFormStore.data.resetProgress();
silenceFormStore.data.autofillMatchers = true;
}}
>
<React.Suspense
fallback={
Expand Down
1 change: 1 addition & 0 deletions ui/src/Components/SilenceModal/index.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ storiesOf("SilenceModal", module)
};

silenceFormStore.toggle.visible = true;
silenceFormStore.data.autofillMatchers = false;
silenceFormStore.data.matchers = [
MockMatcher("cluster", ["prod"], false),
MockMatcher("instance", ["server1", "server3"], true),
Expand Down
3 changes: 3 additions & 0 deletions ui/src/Components/SilenceModal/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ describe("<SilenceModal />", () => {

// mark form as dirty, resetProgress() should change this value to false
silenceFormStore.data.wasValidated = true;
// disable autofill, closing modal should re-enable it
silenceFormStore.data.autofillMatchers = false;

// click to hide
toggle.simulate("click");
Expand All @@ -123,6 +125,7 @@ describe("<SilenceModal />", () => {
// form should be reset
expect(silenceFormStore.data.currentStage).toBe(SilenceFormStage.UserInput);
expect(silenceFormStore.data.wasValidated).toBe(false);
expect(silenceFormStore.data.autofillMatchers).toBe(true);
});

it("'modal-open' class is appended to body node when modal is visible", () => {
Expand Down
6 changes: 6 additions & 0 deletions ui/src/Stores/SilenceFormStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ class SilenceFormStore {
comment: "",
author: "",
requestsByCluster: {},
autofillMatchers: true,

get isValid() {
if (this.alertmanagers.length === 0) return false;
Expand Down Expand Up @@ -257,6 +258,8 @@ class SilenceFormStore {
// ensure that silenceID is nulled, since it's used to edit silences
// and this is used to silence groups
this.silenceID = null;
// disable matcher autofill
this.autofillMatchers = false;
},

fillFormFromSilence(alertmanager, silence) {
Expand Down Expand Up @@ -292,6 +295,9 @@ class SilenceFormStore {
this.endsAt = parseISO(silence.endsAt);
this.comment = silence.comment;
this.author = silence.createdBy;

// disable matcher autofill
this.autofillMatchers = false;
},

verifyStarEnd() {
Expand Down