mirror of
https://github.com/prymitive/karma
synced 2026-08-28 11:17:28 +00:00
committed by
Łukasz Mierzwa
parent
8d41c67681
commit
ce4a9c3e67
@@ -27,10 +27,10 @@ import { ThemeContext } from "Components/Theme";
|
||||
import { useOnClickOutside } from "Hooks/useOnClickOutside";
|
||||
|
||||
const specialLabels: OptionT[] = [
|
||||
{ label: "Automatic selection", value: "@auto" },
|
||||
{ label: "@alertmanager", value: "@alertmanager" },
|
||||
{ label: "@cluster", value: "@cluster" },
|
||||
{ label: "@receiver", value: "@receiver" },
|
||||
{ label: "Automatic selection", value: "@auto", wasCreated: false },
|
||||
{ label: "@alertmanager", value: "@alertmanager", wasCreated: false },
|
||||
{ label: "@cluster", value: "@cluster", wasCreated: false },
|
||||
{ label: "@receiver", value: "@receiver", wasCreated: false },
|
||||
];
|
||||
|
||||
const NullContainer: FC = () => null;
|
||||
|
||||
@@ -24,6 +24,7 @@ const AlertGroupCollapseConfiguration: FC<{
|
||||
return {
|
||||
label: settingsStore.alertGroupConfig.options[val].label,
|
||||
value: val,
|
||||
wasCreated: false,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -30,7 +30,11 @@ const AlertGroupSortConfiguration: FC<{
|
||||
};
|
||||
|
||||
const valueToOption = (val: SortOrderT): OptionT => {
|
||||
return { label: settingsStore.gridConfig.options[val].label, value: val };
|
||||
return {
|
||||
label: settingsStore.gridConfig.options[val].label,
|
||||
value: val,
|
||||
wasCreated: false,
|
||||
};
|
||||
};
|
||||
|
||||
const hideReverse =
|
||||
|
||||
@@ -14,14 +14,15 @@ const disabledLabel = "Disable multi-grid";
|
||||
const valueToOption = (v: string) => ({
|
||||
label: v ? v : disabledLabel,
|
||||
value: v,
|
||||
wasCreated: false,
|
||||
});
|
||||
|
||||
const staticValues = [
|
||||
{ label: disabledLabel, value: "" },
|
||||
{ label: "Automatic selection", value: "@auto" },
|
||||
{ label: "@alertmanager", value: "@alertmanager" },
|
||||
{ label: "@cluster", value: "@cluster" },
|
||||
{ label: "@receiver", value: "@receiver" },
|
||||
{ label: disabledLabel, value: "", wasCreated: false },
|
||||
{ label: "Automatic selection", value: "@auto", wasCreated: false },
|
||||
{ label: "@alertmanager", value: "@alertmanager", wasCreated: false },
|
||||
{ label: "@cluster", value: "@cluster", wasCreated: false },
|
||||
{ label: "@receiver", value: "@receiver", wasCreated: false },
|
||||
];
|
||||
|
||||
const GridLabelName: FC<{
|
||||
@@ -35,7 +36,7 @@ const GridLabelName: FC<{
|
||||
|
||||
const defaultValue =
|
||||
settingsStore.multiGridConfig.config.gridLabel === "@auto"
|
||||
? { label: "Automatic selection", value: "@auto" }
|
||||
? { label: "Automatic selection", value: "@auto", wasCreated: false }
|
||||
: valueToOption(settingsStore.multiGridConfig.config.gridLabel);
|
||||
|
||||
return (
|
||||
|
||||
@@ -24,6 +24,7 @@ const ThemeConfiguration: FC<{
|
||||
return {
|
||||
label: settingsStore.themeConfig.options[val].label,
|
||||
value: val,
|
||||
wasCreated: false,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
import { FormatQuery, QueryOperators, StaticLabels } from "Common/Query";
|
||||
import type { MultiValueOptionT } from "Common/Select";
|
||||
import { MatcherT, MatcherToOperator } from "Stores/SilenceFormStore";
|
||||
import {
|
||||
MatcherT,
|
||||
MatcherToOperator,
|
||||
EscapeRegex,
|
||||
} from "Stores/SilenceFormStore";
|
||||
|
||||
const MatcherToFilter = (matcher: MatcherT): string => {
|
||||
const values = matcher.values.map((v) =>
|
||||
v.wasCreated
|
||||
? v
|
||||
: matcher.isRegex
|
||||
? { ...v, value: EscapeRegex(v.value) }
|
||||
: v
|
||||
);
|
||||
const value =
|
||||
matcher.values.length > 1
|
||||
? `(${matcher.values.map((v) => v.value).join("|")})`
|
||||
: matcher.values[0].value;
|
||||
values.length > 1
|
||||
? `(${values.map((v) => v.value).join("|")})`
|
||||
: values[0].value;
|
||||
return FormatQuery(
|
||||
matcher.name,
|
||||
MatcherToOperator(matcher),
|
||||
|
||||
@@ -110,6 +110,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: "alertnameEqual",
|
||||
value: "alertnameEqual",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -122,6 +123,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: "alertnameNotEqual",
|
||||
value: "alertnameNotEqual",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -134,6 +136,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: ".*alertnameRegex.*",
|
||||
value: ".*alertnameRegex.*",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -146,6 +149,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: ".*alertnameNegativeRegex.*",
|
||||
value: ".*alertnameNegativeRegex.*",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -158,6 +162,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: "clusterEqual",
|
||||
value: "clusterEqual",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -170,6 +175,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: "clusterNotEqual",
|
||||
value: "clusterNotEqual",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -182,6 +188,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: ".*clusterRegex.*",
|
||||
value: ".*clusterRegex.*",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -194,6 +201,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: ".*clusterNegativeRegex.*",
|
||||
value: ".*clusterNegativeRegex.*",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -206,6 +214,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: "fooEqual",
|
||||
value: "fooEqual",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -218,6 +227,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: "fooNotEqual",
|
||||
value: "fooNotEqual",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -230,6 +240,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: ".*fooRegex.*",
|
||||
value: ".*fooRegex.*",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -242,6 +253,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: ".*fooNegativeRegex.*",
|
||||
value: ".*fooNegativeRegex.*",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -288,6 +300,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: "alertnameEqual",
|
||||
value: "alertnameEqual",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -300,6 +313,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: "alertnameNotEqual",
|
||||
value: "alertnameNotEqual",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -312,6 +326,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: ".*alertnameRegex.*",
|
||||
value: ".*alertnameRegex.*",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -324,6 +339,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: ".*alertnameNegativeRegex.*",
|
||||
value: ".*alertnameNegativeRegex.*",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -336,6 +352,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: "clusterEqual",
|
||||
value: "clusterEqual",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -348,6 +365,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: "clusterNotEqual",
|
||||
value: "clusterNotEqual",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -360,6 +378,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: ".*clusterRegex.*",
|
||||
value: ".*clusterRegex.*",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -372,6 +391,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: ".*clusterNegativeRegex.*",
|
||||
value: ".*clusterNegativeRegex.*",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -384,6 +404,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: "fooEqual",
|
||||
value: "fooEqual",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -396,6 +417,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: "fooNotEqual",
|
||||
value: "fooNotEqual",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -408,6 +430,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: ".*fooRegex.*",
|
||||
value: ".*fooRegex.*",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -420,6 +443,7 @@ describe("<SilenceForm /> matchers", () => {
|
||||
{
|
||||
label: ".*fooNegativeRegex.*",
|
||||
value: ".*fooNegativeRegex.*",
|
||||
wasCreated: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -531,7 +555,9 @@ describe("<SilenceForm /> preview", () => {
|
||||
it("clicking on the copy button copies form link to the clipboard", () => {
|
||||
const matcher = NewEmptyMatcher();
|
||||
matcher.name = "job";
|
||||
matcher.values = [{ label: "node_exporter", value: "node_exporter" }];
|
||||
matcher.values = [
|
||||
{ label: "node_exporter", value: "node_exporter", wasCreated: false },
|
||||
];
|
||||
silenceFormStore.data.setMatchers([matcher]);
|
||||
silenceFormStore.data.setAlertmanagers([{ label: "am1", value: ["am1"] }]);
|
||||
silenceFormStore.data.setAuthor("me@example.com");
|
||||
@@ -550,7 +576,9 @@ describe("<SilenceForm /> preview", () => {
|
||||
it("silence form share link doesn't change on new input", () => {
|
||||
const matcher = NewEmptyMatcher();
|
||||
matcher.name = "job";
|
||||
matcher.values = [{ label: "node_exporter", value: "node_exporter" }];
|
||||
matcher.values = [
|
||||
{ label: "node_exporter", value: "node_exporter", wasCreated: false },
|
||||
];
|
||||
silenceFormStore.data.setMatchers([matcher]);
|
||||
silenceFormStore.data.setAlertmanagers([{ label: "am1", value: ["am1"] }]);
|
||||
silenceFormStore.data.setAuthor("me@example.com");
|
||||
@@ -620,7 +648,9 @@ describe("<SilenceForm />", () => {
|
||||
it("calling submit move form to the 'Preview' stage when form is valid", () => {
|
||||
const matcher = NewEmptyMatcher();
|
||||
matcher.name = "job";
|
||||
matcher.values = [{ label: "node_exporter", value: "node_exporter" }];
|
||||
matcher.values = [
|
||||
{ label: "node_exporter", value: "node_exporter", wasCreated: false },
|
||||
];
|
||||
silenceFormStore.data.setMatchers([matcher]);
|
||||
silenceFormStore.data.setAlertmanagers([{ label: "am1", value: ["am1"] }]);
|
||||
silenceFormStore.data.setAuthor("me@example.com");
|
||||
|
||||
@@ -10,8 +10,9 @@ import {
|
||||
MatcherWithIDT,
|
||||
} from "Stores/SilenceFormStore";
|
||||
import { ThemeContext } from "Components/Theme";
|
||||
import { StringToOption } from "Common/Select";
|
||||
import { OptionT, StringToOption } from "Common/Select";
|
||||
import { LabelValueInput } from "./LabelValueInput";
|
||||
import { act } from "react-dom/test-utils";
|
||||
|
||||
let silenceFormStore: SilenceFormStore;
|
||||
let matcher: MatcherWithIDT;
|
||||
@@ -123,6 +124,22 @@ describe("<LabelValueInput />", () => {
|
||||
expect(matcher.isRegex).toBe(true);
|
||||
});
|
||||
|
||||
it("creating a manual option sets wasCreated=true", () => {
|
||||
const tree = MountedLabelValueInput(true);
|
||||
const input = tree.find("Select").instance();
|
||||
const options: OptionT[] = [
|
||||
{ label: "foo", value: "foo", wasCreated: false },
|
||||
];
|
||||
act(() => {
|
||||
(input.props as any).onChange(options, { action: "create-option" });
|
||||
});
|
||||
expect(matcher.values[0]).toStrictEqual({
|
||||
label: "foo",
|
||||
value: "foo",
|
||||
wasCreated: true,
|
||||
});
|
||||
});
|
||||
|
||||
it("removing last value sets matcher.values to []", () => {
|
||||
matcher.values = [StringToOption("dev"), StringToOption("staging")];
|
||||
const tree = MountedLabelValueInput(true);
|
||||
|
||||
@@ -90,13 +90,16 @@ const LabelValueInput: FC<{
|
||||
placeholder={isValid ? "Label value" : <ValidationError />}
|
||||
onChange={(
|
||||
newValue: OnChangeValue<OptionT, true>,
|
||||
_: ActionMeta<OptionT>
|
||||
meta: ActionMeta<OptionT>
|
||||
) => {
|
||||
matcher.values = newValue as OptionT[];
|
||||
// force regex if we have multiple values
|
||||
if (matcher.values.length > 1 && matcher.isRegex === false) {
|
||||
matcher.isRegex = true;
|
||||
}
|
||||
if (meta.action === "create-option") {
|
||||
matcher.values[matcher.values.length - 1].wasCreated = true;
|
||||
}
|
||||
}}
|
||||
hideSelectedOptions
|
||||
isMulti
|
||||
|
||||
@@ -145,6 +145,50 @@ describe("<MatchCounter />", () => {
|
||||
).toBe("./alertList.json?q=foo%3D~%5Ebar%24");
|
||||
});
|
||||
|
||||
it("sends correct query string for a 'foo=(x)' matcher with wasCreated=true & isRegex=false", () => {
|
||||
const v = StringToOption("(x)");
|
||||
v.wasCreated = true;
|
||||
matcher.values = [v];
|
||||
matcher.isRegex = false;
|
||||
MountedMatchCounter();
|
||||
expect(
|
||||
(useFetchGet as jest.MockedFunction<typeof useFetchGet>).mock.calls[0][0]
|
||||
).toBe("./alertList.json?q=foo%3D%28x%29");
|
||||
});
|
||||
|
||||
it("sends correct query string for a 'foo=(x)' matcher with wasCreated=true & isRegex=true", () => {
|
||||
const v = StringToOption("(x)");
|
||||
v.wasCreated = true;
|
||||
matcher.values = [v];
|
||||
matcher.isRegex = true;
|
||||
MountedMatchCounter();
|
||||
expect(
|
||||
(useFetchGet as jest.MockedFunction<typeof useFetchGet>).mock.calls[0][0]
|
||||
).toBe("./alertList.json?q=foo%3D~%5E%28x%29%24");
|
||||
});
|
||||
|
||||
it("sends correct query string for a 'foo=(x)' matcher with wasCreated=false & isRegex=false", () => {
|
||||
const v = StringToOption("(x)");
|
||||
v.wasCreated = false;
|
||||
matcher.values = [v];
|
||||
matcher.isRegex = false;
|
||||
MountedMatchCounter();
|
||||
expect(
|
||||
(useFetchGet as jest.MockedFunction<typeof useFetchGet>).mock.calls[0][0]
|
||||
).toBe("./alertList.json?q=foo%3D%28x%29");
|
||||
});
|
||||
|
||||
it("sends correct query string for a 'foo=(x)' matcher with wasCreated=false & isRegex=true", () => {
|
||||
const v = StringToOption("(x)");
|
||||
v.wasCreated = false;
|
||||
matcher.values = [v];
|
||||
matcher.isRegex = true;
|
||||
MountedMatchCounter();
|
||||
expect(
|
||||
(useFetchGet as jest.MockedFunction<typeof useFetchGet>).mock.calls[0][0]
|
||||
).toBe("./alertList.json?q=foo%3D~%5E%5C%28x%5C%29%24");
|
||||
});
|
||||
|
||||
it("sends correct query string for a 'foo=~(bar|baz)' matcher", () => {
|
||||
matcher.values = [StringToOption("bar"), StringToOption("baz")];
|
||||
matcher.isRegex = true;
|
||||
|
||||
Reference in New Issue
Block a user