mirror of
https://github.com/prymitive/karma
synced 2026-05-05 03:16:51 +00:00
refactor(ui): cleanup label color/style selection
Merge into a single function since both className & style are tied together and as such are better of if selected using a single logic. Fixes some minor UI glitches like ellipsis color on truncated labels with custom color
This commit is contained in:
@@ -1,27 +1,29 @@
|
||||
import { StaticLabels } from "./Query";
|
||||
// fallback class for labels
|
||||
const DefaultLabelClass = "badge-warning components-label-dark";
|
||||
|
||||
const StaticColorLabelClass = "info";
|
||||
const DefaultLabelClass = "warning";
|
||||
// labels configured as static will have badge-${this class}
|
||||
const StaticColorLabelClass = "badge-info components-label-dark";
|
||||
|
||||
// returns bootstrap class for coloring based on pased label name & value
|
||||
function GetLabelColorClass(name, value) {
|
||||
if (name === StaticLabels.AlertName) {
|
||||
// special case for alertname label, which is the name of an alert
|
||||
return "dark";
|
||||
}
|
||||
// alertname label will use this one
|
||||
const AlertNameLabelClass = "badge-dark components-label-dark";
|
||||
|
||||
if (name === StaticLabels.State) {
|
||||
switch (value) {
|
||||
case "active":
|
||||
return "danger";
|
||||
case "suppressed":
|
||||
return "success";
|
||||
default:
|
||||
return "secondary";
|
||||
}
|
||||
}
|
||||
// alert state label will use one of those, based on the value
|
||||
const StateLabelClassMap = Object.freeze({
|
||||
active: "badge-danger components-label-dark",
|
||||
suppressed: "badge-success components-label-dark",
|
||||
unprocessed: "badge-secondary components-label-bright"
|
||||
});
|
||||
// same but for borders
|
||||
const BorderClassMap = Object.freeze({
|
||||
active: "border-danger",
|
||||
suppressed: "border-success",
|
||||
unprocessed: "border-secondary"
|
||||
});
|
||||
|
||||
return DefaultLabelClass;
|
||||
}
|
||||
|
||||
export { GetLabelColorClass, StaticColorLabelClass, DefaultLabelClass };
|
||||
export {
|
||||
DefaultLabelClass,
|
||||
StaticColorLabelClass,
|
||||
AlertNameLabelClass,
|
||||
StateLabelClassMap,
|
||||
BorderClassMap
|
||||
};
|
||||
|
||||
@@ -69,7 +69,7 @@ exports[`<Alert /> matches snapshot with showAlertmanagers=false showReceiver=fa
|
||||
aria-describedby=\\"tippy-tooltip-1\\"
|
||||
data-original-title=\\"Click to only show alerts with this label\\"
|
||||
>
|
||||
<span class=\\"components-label components-label-with-hover text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark components-label-with-hover\\">
|
||||
<span class=\\"components-label-name\\">
|
||||
job:
|
||||
</span>
|
||||
@@ -84,7 +84,7 @@ exports[`<Alert /> matches snapshot with showAlertmanagers=false showReceiver=fa
|
||||
aria-describedby=\\"tippy-tooltip-2\\"
|
||||
data-original-title=\\"Click to only show alerts with this label\\"
|
||||
>
|
||||
<span class=\\"components-label components-label-with-hover text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark components-label-with-hover\\">
|
||||
<span class=\\"components-label-name\\">
|
||||
cluster:
|
||||
</span>
|
||||
|
||||
@@ -5,7 +5,7 @@ import { observer } from "mobx-react";
|
||||
|
||||
import { APIAlert, APIGroup } from "Models/API";
|
||||
import { SilenceFormStore } from "Stores/SilenceFormStore";
|
||||
import { GetLabelColorClass } from "Common/Colors";
|
||||
import { BorderClassMap } from "Common/Colors";
|
||||
import { StaticLabels } from "Common/Query";
|
||||
import { FilteringLabel } from "Components/Labels/FilteringLabel";
|
||||
import { RenderNonLinkAnnotation, RenderLinkAnnotation } from "../Annotation";
|
||||
@@ -42,23 +42,21 @@ const Alert = observer(
|
||||
"my-1",
|
||||
"rounded-0",
|
||||
"border-left-1 border-right-0 border-top-0 border-bottom-0",
|
||||
`border-${GetLabelColorClass(StaticLabels.State, alert.state)}`
|
||||
BorderClassMap[alert.state] || "border-warning"
|
||||
];
|
||||
|
||||
return (
|
||||
<li className={classNames.join(" ")}>
|
||||
<div className="mb-1">
|
||||
{alert.annotations
|
||||
.filter(a => a.isLink === false)
|
||||
.map(a => (
|
||||
<RenderNonLinkAnnotation
|
||||
key={a.name}
|
||||
name={a.name}
|
||||
value={a.value}
|
||||
visible={a.visible}
|
||||
afterUpdate={afterUpdate}
|
||||
/>
|
||||
))}
|
||||
{alert.annotations.filter(a => a.isLink === false).map(a => (
|
||||
<RenderNonLinkAnnotation
|
||||
key={a.name}
|
||||
name={a.name}
|
||||
value={a.value}
|
||||
visible={a.visible}
|
||||
afterUpdate={afterUpdate}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<AlertMenu
|
||||
group={group}
|
||||
@@ -83,15 +81,9 @@ const Alert = observer(
|
||||
value={alert.receiver}
|
||||
/>
|
||||
) : null}
|
||||
{alert.annotations
|
||||
.filter(a => a.isLink === true)
|
||||
.map(a => (
|
||||
<RenderLinkAnnotation
|
||||
key={a.name}
|
||||
name={a.name}
|
||||
value={a.value}
|
||||
/>
|
||||
))}
|
||||
{alert.annotations.filter(a => a.isLink === true).map(a => (
|
||||
<RenderLinkAnnotation key={a.name} name={a.name} value={a.value} />
|
||||
))}
|
||||
{alert.alertmanager.map(am =>
|
||||
am.silencedBy.map(silenceID => (
|
||||
<Silence
|
||||
|
||||
@@ -11,6 +11,7 @@ import toDiffableHtml from "diffable-html";
|
||||
import { MockAlert, MockAnnotation, MockAlertGroup } from "__mocks__/Alerts.js";
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
import { SilenceFormStore } from "Stores/SilenceFormStore";
|
||||
import { BorderClassMap } from "Common/Colors";
|
||||
import { Alert } from ".";
|
||||
|
||||
let alertStore;
|
||||
@@ -25,6 +26,7 @@ beforeEach(() => {
|
||||
afterEach(() => {
|
||||
// reset Date() to current time
|
||||
clear();
|
||||
jest.restoreAllMocks();
|
||||
});
|
||||
|
||||
const MockAfterUpdate = jest.fn();
|
||||
@@ -93,4 +95,54 @@ describe("<Alert />", () => {
|
||||
expect(silence).toHaveLength(1);
|
||||
expect(silence.html()).toMatch(/silence123456789/);
|
||||
});
|
||||
|
||||
it("uses BorderClassMap.active when @state=active", () => {
|
||||
const alert = MockedAlert();
|
||||
alert.state = "active";
|
||||
const group = MockAlertGroup({}, [alert], [], {});
|
||||
const tree = MountedAlert(alert, group, false, false);
|
||||
expect(
|
||||
tree
|
||||
.find(".components-grid-alertgrid-alertgroup-alert")
|
||||
.hasClass(BorderClassMap.active)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("uses BorderClassMap.suppressed when @state=suppressed", () => {
|
||||
const alert = MockedAlert();
|
||||
alert.state = "suppressed";
|
||||
const group = MockAlertGroup({}, [alert], [], {});
|
||||
const tree = MountedAlert(alert, group, false, false);
|
||||
expect(
|
||||
tree
|
||||
.find(".components-grid-alertgrid-alertgroup-alert")
|
||||
.hasClass(BorderClassMap.suppressed)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("uses BorderClassMap.unprocessed when @state=unprocessed", () => {
|
||||
const alert = MockedAlert();
|
||||
alert.state = "unprocessed";
|
||||
const group = MockAlertGroup({}, [alert], [], {});
|
||||
const tree = MountedAlert(alert, group, false, false);
|
||||
expect(
|
||||
tree
|
||||
.find(".components-grid-alertgrid-alertgroup-alert")
|
||||
.hasClass(BorderClassMap.unprocessed)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("uses 'border-warning' with unknown @state", () => {
|
||||
jest.spyOn(console, "error").mockImplementation(() => {});
|
||||
|
||||
const alert = MockedAlert();
|
||||
alert.state = "foobar";
|
||||
const group = MockAlertGroup({}, [alert], [], {});
|
||||
const tree = MountedAlert(alert, group, false, false);
|
||||
expect(
|
||||
tree
|
||||
.find(".components-grid-alertgrid-alertgroup-alert")
|
||||
.hasClass("border-warning")
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -48,7 +48,7 @@ exports[`<GroupFooter /> matches snapshot 1`] = `
|
||||
aria-describedby=\\"tippy-tooltip-1\\"
|
||||
data-original-title=\\"Click to only show alerts with this label\\"
|
||||
>
|
||||
<span class=\\"components-label components-label-with-hover text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark components-label-with-hover\\">
|
||||
<span class=\\"components-label-name\\">
|
||||
label1:
|
||||
</span>
|
||||
@@ -63,7 +63,7 @@ exports[`<GroupFooter /> matches snapshot 1`] = `
|
||||
aria-describedby=\\"tippy-tooltip-2\\"
|
||||
data-original-title=\\"Click to only show alerts with this label\\"
|
||||
>
|
||||
<span class=\\"components-label components-label-with-hover text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark components-label-with-hover\\">
|
||||
<span class=\\"components-label-name\\">
|
||||
label2:
|
||||
</span>
|
||||
@@ -78,7 +78,7 @@ exports[`<GroupFooter /> matches snapshot 1`] = `
|
||||
aria-describedby=\\"tippy-tooltip-3\\"
|
||||
data-original-title=\\"Click to only show alerts with this label\\"
|
||||
>
|
||||
<span class=\\"components-label components-label-with-hover text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark components-label-with-hover\\">
|
||||
<span class=\\"components-label-name\\">
|
||||
@alertmanager:
|
||||
</span>
|
||||
@@ -93,7 +93,7 @@ exports[`<GroupFooter /> matches snapshot 1`] = `
|
||||
aria-describedby=\\"tippy-tooltip-4\\"
|
||||
data-original-title=\\"Click to only show alerts with this label\\"
|
||||
>
|
||||
<span class=\\"components-label components-label-with-hover text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark components-label-with-hover\\">
|
||||
<span class=\\"components-label-name\\">
|
||||
@receiver:
|
||||
</span>
|
||||
|
||||
@@ -108,7 +108,7 @@ exports[`<Silence /> matches snapshot with expaned details 1`] = `
|
||||
aria-describedby=\\"tippy-tooltip-6\\"
|
||||
data-original-title=\\"Click to only show alerts with this label\\"
|
||||
>
|
||||
<span class=\\"components-label components-label-with-hover text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark components-label-with-hover\\">
|
||||
<span class=\\"components-label-name\\">
|
||||
@alertmanager:
|
||||
</span>
|
||||
|
||||
@@ -9,7 +9,7 @@ exports[`<LabelSetList /> matches snapshot with populated list 1`] = `
|
||||
<div>
|
||||
<ul class=\\"list-group list-group-flush mb-3\\">
|
||||
<li class=\\"list-group-item px-0 pt-2 pb-1\\">
|
||||
<span class=\\"components-label text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark \\">
|
||||
<span class=\\"components-label-name\\">
|
||||
foo:
|
||||
</span>
|
||||
@@ -19,7 +19,7 @@ exports[`<LabelSetList /> matches snapshot with populated list 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li class=\\"list-group-item px-0 pt-2 pb-1\\">
|
||||
<span class=\\"components-label text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark \\">
|
||||
<span class=\\"components-label-name\\">
|
||||
job:
|
||||
</span>
|
||||
@@ -29,7 +29,7 @@ exports[`<LabelSetList /> matches snapshot with populated list 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li class=\\"list-group-item px-0 pt-2 pb-1\\">
|
||||
<span class=\\"components-label text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark \\">
|
||||
<span class=\\"components-label-name\\">
|
||||
instance:
|
||||
</span>
|
||||
@@ -39,7 +39,7 @@ exports[`<LabelSetList /> matches snapshot with populated list 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li class=\\"list-group-item px-0 pt-2 pb-1\\">
|
||||
<span class=\\"components-label text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark \\">
|
||||
<span class=\\"components-label-name\\">
|
||||
cluster:
|
||||
</span>
|
||||
|
||||
@@ -2,8 +2,13 @@ import { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
import { GetLabelColorClass, StaticColorLabelClass } from "Common/Colors";
|
||||
import { QueryOperators, FormatQuery } from "Common/Query";
|
||||
import {
|
||||
StaticColorLabelClass,
|
||||
StateLabelClassMap,
|
||||
DefaultLabelClass,
|
||||
AlertNameLabelClass
|
||||
} from "Common/Colors";
|
||||
import { QueryOperators, FormatQuery, StaticLabels } from "Common/Query";
|
||||
|
||||
import "./index.scss";
|
||||
|
||||
@@ -17,49 +22,54 @@ class BaseLabel extends Component {
|
||||
value: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
isStaticColorLabel(name) {
|
||||
getClassAndStyle(name, value, extraClass = "") {
|
||||
const { alertStore } = this.props;
|
||||
|
||||
return alertStore.settings.values.staticColorLabels.includes(name);
|
||||
}
|
||||
const data = {
|
||||
style: {},
|
||||
className: "",
|
||||
baseClassNames: [
|
||||
"components-label",
|
||||
"badge",
|
||||
"text-nowrap",
|
||||
"text-truncate",
|
||||
"mw-100"
|
||||
],
|
||||
colorClassNames: []
|
||||
};
|
||||
|
||||
isBackgroundDark(name, value) {
|
||||
const { alertStore } = this.props;
|
||||
if (name === StaticLabels.AlertName) {
|
||||
data.colorClassNames.push(AlertNameLabelClass);
|
||||
} else if (name === StaticLabels.State) {
|
||||
data.colorClassNames.push(StateLabelClassMap[value] || DefaultLabelClass);
|
||||
} else if (alertStore.settings.values.staticColorLabels.includes(name)) {
|
||||
data.colorClassNames.push(StaticColorLabelClass);
|
||||
} else {
|
||||
const c = alertStore.data.getColorData(name, value);
|
||||
if (c) {
|
||||
// if there's color information use it
|
||||
data.style["backgroundColor"] = `rgba(${[
|
||||
c.background.red,
|
||||
c.background.green,
|
||||
c.background.blue,
|
||||
c.background.alpha
|
||||
].join(", ")})`;
|
||||
|
||||
const c = alertStore.data.getColorData(name, value);
|
||||
if (c) {
|
||||
return isBackgroundDark(c.brightness);
|
||||
data.colorClassNames.push(
|
||||
isBackgroundDark(c.brightness)
|
||||
? "components-label-dark"
|
||||
: "components-label-bright"
|
||||
);
|
||||
} else {
|
||||
// if not fall back to class
|
||||
data.colorClassNames.push(DefaultLabelClass);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
data.className = `${[...data.baseClassNames, ...data.colorClassNames].join(
|
||||
" "
|
||||
)} ${extraClass}`;
|
||||
|
||||
getColorClass(name, value) {
|
||||
if (this.isStaticColorLabel(name)) {
|
||||
return StaticColorLabelClass;
|
||||
}
|
||||
return GetLabelColorClass(name, value);
|
||||
}
|
||||
|
||||
getColorStyle(name, value) {
|
||||
const { alertStore } = this.props;
|
||||
|
||||
let style = {};
|
||||
|
||||
if (this.isStaticColorLabel(name)) {
|
||||
// static labels only get class, no unique colors
|
||||
return style;
|
||||
}
|
||||
|
||||
const c = alertStore.data.getColorData(name, value);
|
||||
if (c) {
|
||||
style["backgroundColor"] = `rgba(${[
|
||||
c.background.red,
|
||||
c.background.green,
|
||||
c.background.blue,
|
||||
c.background.alpha
|
||||
].join(", ")})`;
|
||||
}
|
||||
return style;
|
||||
return data;
|
||||
}
|
||||
|
||||
handleClick = event => {
|
||||
|
||||
@@ -3,7 +3,12 @@ import React from "react";
|
||||
import { shallow } from "enzyme";
|
||||
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
|
||||
import {
|
||||
StaticColorLabelClass,
|
||||
DefaultLabelClass,
|
||||
AlertNameLabelClass,
|
||||
StateLabelClassMap
|
||||
} from "Common/Colors";
|
||||
import { BaseLabel } from ".";
|
||||
|
||||
let alertStore;
|
||||
@@ -12,56 +17,92 @@ beforeEach(() => {
|
||||
alertStore = new AlertStore([]);
|
||||
});
|
||||
|
||||
const FakeBaseLabel = () => {
|
||||
// BaseLabel doesn't implement render since it's an abstract component
|
||||
// Add a dummy implementation for testing
|
||||
const FakeBaseLabel = (name = "foo", value = "bar") => {
|
||||
class RenderableBaseLabel extends BaseLabel {
|
||||
render() {
|
||||
return null;
|
||||
const { name, value } = this.props;
|
||||
let cs = this.getClassAndStyle(name, value);
|
||||
return (
|
||||
<span className={cs.className} style={cs.style}>
|
||||
<span className="components-label-name">{name}:</span>{" "}
|
||||
<span className="components-label-value">{value}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
return shallow(
|
||||
<RenderableBaseLabel alertStore={alertStore} name="foo" value="bar" />
|
||||
<RenderableBaseLabel alertStore={alertStore} name={name} value={value} />
|
||||
);
|
||||
};
|
||||
|
||||
describe("<BaseLabel />", () => {
|
||||
it("isStaticColorLabel() returns true for labels present in staticColorLabels", () => {
|
||||
it("static label uses StaticColorLabelClass", () => {
|
||||
alertStore.settings.values.staticColorLabels = ["foo", "job", "bar"];
|
||||
const instance = FakeBaseLabel().instance();
|
||||
expect(instance.isStaticColorLabel("job")).toBeTruthy();
|
||||
const tree = FakeBaseLabel();
|
||||
expect(tree.find(".components-label").hasClass(StaticColorLabelClass)).toBe(
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it("isStaticColorLabel() returns false for labels not present in staticColorLabels", () => {
|
||||
alertStore.settings.values.staticColorLabels = ["foo"];
|
||||
const instance = FakeBaseLabel().instance();
|
||||
expect(instance.isStaticColorLabel("job")).toBeFalsy();
|
||||
it("non-static label doesn't use StaticColorLabelClass", () => {
|
||||
alertStore.settings.values.staticColorLabels = [];
|
||||
const tree = FakeBaseLabel();
|
||||
expect(tree.find(".components-label").hasClass(StaticColorLabelClass)).toBe(
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
it("getColorClass() on a label included in staticColorLabels should return 'info'", () => {
|
||||
alertStore.settings.values.staticColorLabels = ["job"];
|
||||
const instance = FakeBaseLabel().instance();
|
||||
expect(instance.getColorClass("job", "foo")).toBe("info");
|
||||
it("label with no special color information should use DefaultLabelClass", () => {
|
||||
const tree = FakeBaseLabel();
|
||||
expect(tree.find(".components-label").hasClass(DefaultLabelClass)).toBe(
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it("getColorClass() on a label without any special color should return 'warning'", () => {
|
||||
const instance = FakeBaseLabel().instance();
|
||||
expect(instance.getColorClass("foo", "bar")).toBe("warning");
|
||||
it("alertname label should use AlertNameLabelClass", () => {
|
||||
const tree = FakeBaseLabel("alertname", "foo");
|
||||
expect(tree.find(".components-label").hasClass(AlertNameLabelClass)).toBe(
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it("getColorClass() on 'alertname' label should return 'dark'", () => {
|
||||
const instance = FakeBaseLabel().instance();
|
||||
expect(instance.getColorClass("alertname", "foo")).toBe("dark");
|
||||
it("@state=active label should use StateLabelClassMap.active class", () => {
|
||||
const tree = FakeBaseLabel("@state", "active");
|
||||
expect(
|
||||
tree.find(".components-label").hasClass(StateLabelClassMap.active)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("getColorStyle() on a label included in staticColorLabels should be empty", () => {
|
||||
alertStore.settings.values.staticColorLabels = ["job"];
|
||||
const instance = FakeBaseLabel().instance();
|
||||
expect(instance.getColorStyle("job", "bar")).toMatchObject({});
|
||||
it("@state=suppressed label should use StateLabelClassMap.suppressed class", () => {
|
||||
const tree = FakeBaseLabel("@state", "suppressed");
|
||||
expect(
|
||||
tree.find(".components-label").hasClass(StateLabelClassMap.suppressed)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("getColorStyle() on a label without any color information should be empty", () => {
|
||||
const instance = FakeBaseLabel().instance();
|
||||
expect(instance.getColorStyle("foo", "bar")).toMatchObject({});
|
||||
it("@state=unprocessed label should use StateLabelClassMap.unprocessed class", () => {
|
||||
const tree = FakeBaseLabel("@state", "unprocessed");
|
||||
expect(
|
||||
tree.find(".components-label").hasClass(StateLabelClassMap.unprocessed)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("@state with unknown label should use DefaultLabelClass", () => {
|
||||
const tree = FakeBaseLabel("@state", "foobar");
|
||||
expect(tree.find(".components-label").hasClass(DefaultLabelClass)).toBe(
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it("style prop on a label included in staticColorLabels should be empty", () => {
|
||||
alertStore.settings.values.staticColorLabels = ["foo", "job", "bar"];
|
||||
const tree = FakeBaseLabel();
|
||||
expect(tree.find(".components-label").props().style).toEqual({});
|
||||
});
|
||||
|
||||
it("style prop on a label without any color information should be empty", () => {
|
||||
alertStore.settings.values.staticColorLabels = [];
|
||||
const tree = FakeBaseLabel();
|
||||
expect(tree.find(".components-label").props().style).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,7 +10,6 @@ import { faExclamationCircle } from "@fortawesome/free-solid-svg-icons/faExclama
|
||||
import { faSpinner } from "@fortawesome/free-solid-svg-icons/faSpinner";
|
||||
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
import { DefaultLabelClass } from "Common/Colors";
|
||||
import { QueryOperators } from "Common/Query";
|
||||
import { TooltipWrapper } from "Components/TooltipWrapper";
|
||||
import { BaseLabel } from "Components/Labels/BaseLabel";
|
||||
@@ -46,43 +45,32 @@ const FilterInputLabel = observer(
|
||||
render() {
|
||||
const { filter, alertStore } = this.props;
|
||||
|
||||
let classNames = [
|
||||
"components-label",
|
||||
"components-filteredinputlabel",
|
||||
"badge",
|
||||
"text-nowrap",
|
||||
"text-truncate",
|
||||
"mw-100"
|
||||
];
|
||||
let badgeClass = "";
|
||||
let style = {};
|
||||
if (!filter.applied) {
|
||||
classNames.push("badge-secondary");
|
||||
} else if (filter.matcher === QueryOperators.Equal) {
|
||||
// only pass color class & style for equality matchers (foo=bar)
|
||||
// if we have foo!=bar filter then it should't get the color we use
|
||||
// for "foo: bar" labels
|
||||
classNames.push(
|
||||
`badge-${this.getColorClass(filter.name, filter.value)}`
|
||||
);
|
||||
style = this.getColorStyle(filter.name, filter.value);
|
||||
|
||||
badgeClass = this.isBackgroundDark(filter.name, filter.value)
|
||||
? "components-label-dark"
|
||||
: "components-label-bright";
|
||||
} else {
|
||||
classNames.push(`badge-${DefaultLabelClass}`);
|
||||
}
|
||||
let cs = this.getClassAndStyle(
|
||||
filter.matcher === QueryOperators.Equal ? filter.name : "",
|
||||
filter.matcher === QueryOperators.Equal ? filter.value : "",
|
||||
"components-filteredinputlabel"
|
||||
);
|
||||
|
||||
return (
|
||||
<span className={classNames.join(" ")} style={style}>
|
||||
<span
|
||||
className={
|
||||
filter.applied
|
||||
? cs.className
|
||||
: ["badge-secondary", ...cs.baseClassNames].join(" ")
|
||||
}
|
||||
style={cs.style}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
className="close ml-1"
|
||||
style={style}
|
||||
style={cs.style}
|
||||
onClick={() => alertStore.filters.removeFilter(filter.raw)}
|
||||
>
|
||||
<span className={`align-text-bottom ${badgeClass}`}>×</span>
|
||||
<span
|
||||
className={`align-text-bottom ${cs.colorClassNames.join(" ")}`}
|
||||
>
|
||||
×
|
||||
</span>
|
||||
</button>
|
||||
{filter.isValid ? (
|
||||
filter.applied ? (
|
||||
@@ -105,7 +93,7 @@ const FilterInputLabel = observer(
|
||||
value={filter.raw}
|
||||
propName="raw"
|
||||
change={this.onChange}
|
||||
className={badgeClass}
|
||||
className={cs.colorClassNames.join(" ")}
|
||||
classEditing="py-0 border-0 bg-light"
|
||||
/>
|
||||
</TooltipWrapper>
|
||||
|
||||
@@ -25,14 +25,17 @@ const FilteringCounterBadge = inject("alertStore")(
|
||||
|
||||
if (counter === 0) return null;
|
||||
|
||||
let cs = this.getClassAndStyle(
|
||||
name,
|
||||
value,
|
||||
"badge-pill components-label-with-hover"
|
||||
);
|
||||
|
||||
return (
|
||||
<TooltipWrapper title={`Click to only show ${value} alerts`}>
|
||||
<span
|
||||
className={`components-label components-label-with-hover text-nowrap text-truncate badge badge-${this.getColorClass(
|
||||
name,
|
||||
value
|
||||
)} badge-pill`}
|
||||
style={this.getColorStyle(name, value)}
|
||||
className={cs.className}
|
||||
style={cs.style}
|
||||
onClick={e => this.handleClick(e)}
|
||||
>
|
||||
{counter}
|
||||
|
||||
@@ -8,7 +8,7 @@ exports[`<FilteringLabel /> matches snapshot 1`] = `
|
||||
aria-describedby=\\"tippy-tooltip-1\\"
|
||||
data-original-title=\\"Click to only show alerts with this label\\"
|
||||
>
|
||||
<span class=\\"components-label components-label-with-hover text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark components-label-with-hover\\">
|
||||
<span class=\\"components-label-name\\">
|
||||
foo:
|
||||
</span>
|
||||
|
||||
@@ -12,22 +12,17 @@ const FilteringLabel = inject("alertStore")(
|
||||
render() {
|
||||
const { name, value } = this.props;
|
||||
|
||||
const classNames = [
|
||||
"components-label",
|
||||
"components-label-with-hover",
|
||||
"text-nowrap text-truncate mw-100",
|
||||
"badge",
|
||||
`badge-${this.getColorClass(name, value)}`,
|
||||
this.isBackgroundDark(name, value)
|
||||
? "components-label-dark"
|
||||
: "components-label-bright"
|
||||
];
|
||||
let cs = this.getClassAndStyle(
|
||||
name,
|
||||
value,
|
||||
"components-label-with-hover"
|
||||
);
|
||||
|
||||
return (
|
||||
<TooltipWrapper title="Click to only show alerts with this label">
|
||||
<span
|
||||
className={`${classNames.join(" ")}`}
|
||||
style={this.getColorStyle(name, value)}
|
||||
className={cs.className}
|
||||
style={cs.style}
|
||||
onClick={e => this.handleClick(e)}
|
||||
>
|
||||
<span className="components-label-name">{name}:</span>{" "}
|
||||
|
||||
@@ -3,7 +3,6 @@ import PropTypes from "prop-types";
|
||||
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
import { DefaultLabelClass } from "Common/Colors";
|
||||
import { QueryOperators } from "Common/Query";
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
import { BaseLabel } from "Components/Labels/BaseLabel";
|
||||
@@ -22,28 +21,14 @@ const HistoryLabel = observer(
|
||||
render() {
|
||||
const { name, matcher, value } = this.props;
|
||||
|
||||
let classNames = [
|
||||
"components-label",
|
||||
"components-label-history",
|
||||
"text-nowrap",
|
||||
"text-truncate",
|
||||
"badge",
|
||||
"mw-100",
|
||||
"components-label-value",
|
||||
this.isBackgroundDark(name, value)
|
||||
? "components-label-dark"
|
||||
: "components-label-bright"
|
||||
];
|
||||
let style = {};
|
||||
if (matcher === QueryOperators.Equal) {
|
||||
classNames.push(`badge-${this.getColorClass(name, value)}`);
|
||||
style = this.getColorStyle(name, value);
|
||||
} else {
|
||||
classNames.push(`badge-${DefaultLabelClass}`);
|
||||
}
|
||||
let cs = this.getClassAndStyle(
|
||||
matcher === QueryOperators.Equal ? name : "",
|
||||
matcher === QueryOperators.Equal ? value : "",
|
||||
"components-label-history components-label-value"
|
||||
);
|
||||
|
||||
return (
|
||||
<span className={classNames.join(" ")} style={style}>
|
||||
<span className={cs.className} style={cs.style}>
|
||||
{name ? `${name}${matcher}` : null}
|
||||
{value}
|
||||
</span>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
exports[`<StaticLabel /> matches snapshot 1`] = `
|
||||
"
|
||||
<span class=\\"components-label text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark \\">
|
||||
<span class=\\"components-label-name\\">
|
||||
foo:
|
||||
</span>
|
||||
|
||||
@@ -11,21 +11,10 @@ const StaticLabel = inject("alertStore")(
|
||||
render() {
|
||||
const { name, value } = this.props;
|
||||
|
||||
const classNames = [
|
||||
"components-label",
|
||||
"text-nowrap text-truncate mw-100",
|
||||
"badge",
|
||||
`badge-${this.getColorClass(name, value)}`,
|
||||
this.isBackgroundDark(name, value)
|
||||
? "components-label-dark"
|
||||
: "components-label-bright"
|
||||
];
|
||||
let cs = this.getClassAndStyle(name, value);
|
||||
|
||||
return (
|
||||
<span
|
||||
className={`${classNames.join(" ")}`}
|
||||
style={this.getColorStyle(name, value)}
|
||||
>
|
||||
<span className={cs.className} style={cs.style}>
|
||||
<span className="components-label-name">{name}:</span>{" "}
|
||||
<span className="components-label-value">{value}</span>
|
||||
</span>
|
||||
|
||||
@@ -10,7 +10,7 @@ exports[`<SilencePreview /> matches snapshot 1`] = `
|
||||
<div>
|
||||
<ul class=\\"list-group list-group-flush mb-3\\">
|
||||
<li class=\\"list-group-item px-0 pt-2 pb-1\\">
|
||||
<span class=\\"components-label text-nowrap text-truncate mw-100 badge badge-dark components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-dark components-label-dark \\">
|
||||
<span class=\\"components-label-name\\">
|
||||
alertname:
|
||||
</span>
|
||||
@@ -18,7 +18,7 @@ exports[`<SilencePreview /> matches snapshot 1`] = `
|
||||
foo
|
||||
</span>
|
||||
</span>
|
||||
<span class=\\"components-label text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark \\">
|
||||
<span class=\\"components-label-name\\">
|
||||
job:
|
||||
</span>
|
||||
@@ -26,7 +26,7 @@ exports[`<SilencePreview /> matches snapshot 1`] = `
|
||||
foo
|
||||
</span>
|
||||
</span>
|
||||
<span class=\\"components-label text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark \\">
|
||||
<span class=\\"components-label-name\\">
|
||||
instance:
|
||||
</span>
|
||||
@@ -36,7 +36,7 @@ exports[`<SilencePreview /> matches snapshot 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li class=\\"list-group-item px-0 pt-2 pb-1\\">
|
||||
<span class=\\"components-label text-nowrap text-truncate mw-100 badge badge-dark components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-dark components-label-dark \\">
|
||||
<span class=\\"components-label-name\\">
|
||||
alertname:
|
||||
</span>
|
||||
@@ -44,7 +44,7 @@ exports[`<SilencePreview /> matches snapshot 1`] = `
|
||||
bar
|
||||
</span>
|
||||
</span>
|
||||
<span class=\\"components-label text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark \\">
|
||||
<span class=\\"components-label-name\\">
|
||||
job:
|
||||
</span>
|
||||
@@ -52,7 +52,7 @@ exports[`<SilencePreview /> matches snapshot 1`] = `
|
||||
bar
|
||||
</span>
|
||||
</span>
|
||||
<span class=\\"components-label text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark \\">
|
||||
<span class=\\"components-label-name\\">
|
||||
instance:
|
||||
</span>
|
||||
@@ -62,7 +62,7 @@ exports[`<SilencePreview /> matches snapshot 1`] = `
|
||||
</span>
|
||||
</li>
|
||||
<li class=\\"list-group-item px-0 pt-2 pb-1\\">
|
||||
<span class=\\"components-label text-nowrap text-truncate mw-100 badge badge-dark components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-dark components-label-dark \\">
|
||||
<span class=\\"components-label-name\\">
|
||||
alertname:
|
||||
</span>
|
||||
@@ -70,7 +70,7 @@ exports[`<SilencePreview /> matches snapshot 1`] = `
|
||||
bar
|
||||
</span>
|
||||
</span>
|
||||
<span class=\\"components-label text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark \\">
|
||||
<span class=\\"components-label-name\\">
|
||||
job:
|
||||
</span>
|
||||
@@ -78,7 +78,7 @@ exports[`<SilencePreview /> matches snapshot 1`] = `
|
||||
bar
|
||||
</span>
|
||||
</span>
|
||||
<span class=\\"components-label text-nowrap text-truncate mw-100 badge badge-warning components-label-dark\\">
|
||||
<span class=\\"components-label badge text-nowrap text-truncate mw-100 badge-warning components-label-dark \\">
|
||||
<span class=\\"components-label-name\\">
|
||||
instance:
|
||||
</span>
|
||||
|
||||
Reference in New Issue
Block a user