mirror of
https://github.com/prymitive/karma
synced 2026-05-09 03:36:44 +00:00
Merge pull request #1105 from prymitive/no-inject
chore(ui): avoid using inject
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
import React, { Component } from "react";
|
||||
|
||||
import { Provider } from "mobx-react";
|
||||
|
||||
import { AlertStore, DecodeLocationSearch } from "Stores/AlertStore";
|
||||
import { Settings } from "Stores/Settings";
|
||||
import { SilenceFormStore } from "Stores/SilenceFormStore";
|
||||
@@ -92,13 +90,11 @@ class App extends Component<AppProps, {}> {
|
||||
settingsStore={this.settingsStore}
|
||||
silenceFormStore={this.silenceFormStore}
|
||||
/>
|
||||
<Provider alertStore={this.alertStore}>
|
||||
<Grid
|
||||
alertStore={this.alertStore}
|
||||
settingsStore={this.settingsStore}
|
||||
silenceFormStore={this.silenceFormStore}
|
||||
/>
|
||||
</Provider>
|
||||
<Grid
|
||||
alertStore={this.alertStore}
|
||||
settingsStore={this.settingsStore}
|
||||
silenceFormStore={this.silenceFormStore}
|
||||
/>
|
||||
<Fetcher
|
||||
alertStore={this.alertStore}
|
||||
settingsStore={this.settingsStore}
|
||||
|
||||
@@ -1,31 +1,27 @@
|
||||
import { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { inject } from "mobx-react";
|
||||
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
|
||||
const FetchPauser = inject("alertStore")(
|
||||
class FetchPauser extends Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.any,
|
||||
alertStore: PropTypes.instanceOf(AlertStore).isRequired
|
||||
};
|
||||
class FetchPauser extends Component {
|
||||
static propTypes = {
|
||||
children: PropTypes.any,
|
||||
alertStore: PropTypes.instanceOf(AlertStore).isRequired
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const { alertStore } = this.props;
|
||||
alertStore.status.pause();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
const { alertStore } = this.props;
|
||||
alertStore.status.resume();
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.props.children;
|
||||
}
|
||||
componentDidMount() {
|
||||
const { alertStore } = this.props;
|
||||
alertStore.status.pause();
|
||||
}
|
||||
);
|
||||
|
||||
componentWillUnmount() {
|
||||
const { alertStore } = this.props;
|
||||
alertStore.status.resume();
|
||||
}
|
||||
|
||||
render() {
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
export { FetchPauser };
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import React from "react";
|
||||
|
||||
import { Provider } from "mobx-react";
|
||||
|
||||
import { mount } from "enzyme";
|
||||
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
@@ -15,11 +13,9 @@ beforeEach(() => {
|
||||
|
||||
const MountedFetchPauser = () => {
|
||||
return mount(
|
||||
<Provider alertStore={alertStore}>
|
||||
<FetchPauser>
|
||||
<div />
|
||||
</FetchPauser>
|
||||
</Provider>
|
||||
<FetchPauser alertStore={alertStore}>
|
||||
<div />
|
||||
</FetchPauser>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ const MenuContent = onClickOutside(
|
||||
silenceFormStore
|
||||
}) => {
|
||||
return (
|
||||
<FetchPauser>
|
||||
<FetchPauser alertStore={alertStore}>
|
||||
<div
|
||||
className="dropdown-menu d-block shadow"
|
||||
ref={popperRef}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import React from "react";
|
||||
|
||||
import { Provider } from "mobx-react";
|
||||
|
||||
import { mount } from "enzyme";
|
||||
|
||||
import { MockAlertGroup, MockAlert } from "__mocks__/Alerts.js";
|
||||
@@ -26,16 +24,14 @@ const MockSetIsMenuOpen = jest.fn();
|
||||
|
||||
const MountedAlertMenu = group => {
|
||||
return mount(
|
||||
<Provider alertStore={alertStore}>
|
||||
<AlertMenu
|
||||
group={group}
|
||||
alert={alert}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
setIsMenuOpen={MockSetIsMenuOpen}
|
||||
/>
|
||||
</Provider>
|
||||
).find("AlertMenu");
|
||||
<AlertMenu
|
||||
group={group}
|
||||
alert={alert}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
setIsMenuOpen={MockSetIsMenuOpen}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
describe("<AlertMenu />", () => {
|
||||
@@ -65,18 +61,16 @@ describe("<AlertMenu />", () => {
|
||||
|
||||
const MountedMenuContent = group => {
|
||||
return mount(
|
||||
<Provider alertStore={alertStore}>
|
||||
<MenuContent
|
||||
popperPlacement="top"
|
||||
popperRef={null}
|
||||
popperStyle={{}}
|
||||
group={group}
|
||||
alert={alert}
|
||||
afterClick={MockAfterClick}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
/>
|
||||
</Provider>
|
||||
<MenuContent
|
||||
popperPlacement="top"
|
||||
popperRef={null}
|
||||
popperStyle={{}}
|
||||
group={group}
|
||||
alert={alert}
|
||||
afterClick={MockAfterClick}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ const Alert = observer(
|
||||
value={a.value}
|
||||
visible={a.visible}
|
||||
afterUpdate={afterUpdate}
|
||||
alertStore={alertStore}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@@ -106,7 +107,12 @@ const Alert = observer(
|
||||
</TooltipWrapper>
|
||||
) : null}
|
||||
{Object.entries(alert.labels).map(([name, value]) => (
|
||||
<FilteringLabel key={name} name={name} value={value} />
|
||||
<FilteringLabel
|
||||
key={name}
|
||||
name={name}
|
||||
value={value}
|
||||
alertStore={alertStore}
|
||||
/>
|
||||
))}
|
||||
{showAlertmanagers
|
||||
? alert.alertmanager.map(am => (
|
||||
@@ -114,6 +120,7 @@ const Alert = observer(
|
||||
key={am.name}
|
||||
name={StaticLabels.AlertManager}
|
||||
value={am.name}
|
||||
alertStore={alertStore}
|
||||
/>
|
||||
))
|
||||
: null}
|
||||
@@ -121,6 +128,7 @@ const Alert = observer(
|
||||
<FilteringLabel
|
||||
name={StaticLabels.Receiver}
|
||||
value={alert.receiver}
|
||||
alertStore={alertStore}
|
||||
/>
|
||||
) : null}
|
||||
{alert.annotations
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import React from "react";
|
||||
|
||||
import { Provider } from "mobx-react";
|
||||
|
||||
import { mount } from "enzyme";
|
||||
|
||||
import { advanceTo, clear } from "jest-date-mock";
|
||||
@@ -53,18 +51,16 @@ const MockedAlert = () => {
|
||||
|
||||
const MountedAlert = (alert, group, showAlertmanagers, showReceiver) => {
|
||||
return mount(
|
||||
<Provider alertStore={alertStore}>
|
||||
<Alert
|
||||
alert={alert}
|
||||
group={group}
|
||||
showAlertmanagers={showAlertmanagers}
|
||||
showReceiver={showReceiver}
|
||||
afterUpdate={MockAfterUpdate}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
setIsMenuOpen={MockSetIsMenuOpen}
|
||||
/>
|
||||
</Provider>
|
||||
<Alert
|
||||
alert={alert}
|
||||
group={group}
|
||||
showAlertmanagers={showAlertmanagers}
|
||||
showReceiver={showReceiver}
|
||||
afterUpdate={MockAfterUpdate}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
setIsMenuOpen={MockSetIsMenuOpen}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { observable, action } from "mobx";
|
||||
import { observer, inject } from "mobx-react";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
import Linkify from "react-linkify";
|
||||
|
||||
@@ -18,93 +18,91 @@ import { TooltipWrapper } from "Components/TooltipWrapper";
|
||||
|
||||
import "./index.css";
|
||||
|
||||
const RenderNonLinkAnnotation = inject("alertStore")(
|
||||
observer(
|
||||
class RenderNonLinkAnnotation extends Component {
|
||||
static propTypes = {
|
||||
alertStore: PropTypes.instanceOf(AlertStore).isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
visible: PropTypes.bool.isRequired,
|
||||
afterUpdate: PropTypes.func.isRequired
|
||||
};
|
||||
const RenderNonLinkAnnotation = observer(
|
||||
class RenderNonLinkAnnotation extends Component {
|
||||
static propTypes = {
|
||||
alertStore: PropTypes.instanceOf(AlertStore).isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
visible: PropTypes.bool.isRequired,
|
||||
afterUpdate: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
// keep state of this annotation visibility, this is controlled by user
|
||||
toggle = observable(
|
||||
{
|
||||
visible: true,
|
||||
show(e) {
|
||||
// Linkify only handles value, no need to check for links of
|
||||
// collapsed annotation
|
||||
this.visible = true;
|
||||
},
|
||||
hide(e) {
|
||||
this.visible = false;
|
||||
}
|
||||
// keep state of this annotation visibility, this is controlled by user
|
||||
toggle = observable(
|
||||
{
|
||||
visible: true,
|
||||
show(e) {
|
||||
// Linkify only handles value, no need to check for links of
|
||||
// collapsed annotation
|
||||
this.visible = true;
|
||||
},
|
||||
{
|
||||
show: action.bound,
|
||||
hide: action.bound
|
||||
hide(e) {
|
||||
this.visible = false;
|
||||
}
|
||||
);
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.toggle.visible = props.visible;
|
||||
},
|
||||
{
|
||||
show: action.bound,
|
||||
hide: action.bound
|
||||
}
|
||||
);
|
||||
|
||||
componentDidUpdate() {
|
||||
const { afterUpdate } = this.props;
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
afterUpdate();
|
||||
}
|
||||
this.toggle.visible = props.visible;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { name, value } = this.props;
|
||||
componentDidUpdate() {
|
||||
const { afterUpdate } = this.props;
|
||||
|
||||
const className =
|
||||
"mr-1 mb-1 p-1 bg-light d-inline-block rounded components-grid-annotation text-break mw-100";
|
||||
afterUpdate();
|
||||
}
|
||||
|
||||
if (!this.toggle.visible) {
|
||||
return (
|
||||
<TooltipWrapper title="Click to show annotation value">
|
||||
<div
|
||||
className={`${className} cursor-pointer`}
|
||||
onClick={this.toggle.show}
|
||||
>
|
||||
<FontAwesomeIcon icon={faSearchPlus} className="mr-1" />
|
||||
{name}
|
||||
</div>
|
||||
</TooltipWrapper>
|
||||
);
|
||||
}
|
||||
render() {
|
||||
const { name, value } = this.props;
|
||||
|
||||
const className =
|
||||
"mr-1 mb-1 p-1 bg-light d-inline-block rounded components-grid-annotation text-break mw-100";
|
||||
|
||||
if (!this.toggle.visible) {
|
||||
return (
|
||||
<TooltipWrapper title="Click the icon to hide annotation value">
|
||||
<div key={name} className={className}>
|
||||
<FontAwesomeIcon
|
||||
icon={faSearchMinus}
|
||||
className="mr-1 cursor-pointer"
|
||||
onClick={this.toggle.hide}
|
||||
/>
|
||||
<span className="text-muted">{name}: </span>
|
||||
<Linkify
|
||||
properties={{
|
||||
target: "_blank",
|
||||
rel: "noopener noreferrer"
|
||||
}}
|
||||
>
|
||||
<Flash spy={value}>
|
||||
<span>{value}</span>
|
||||
</Flash>
|
||||
</Linkify>
|
||||
<TooltipWrapper title="Click to show annotation value">
|
||||
<div
|
||||
className={`${className} cursor-pointer`}
|
||||
onClick={this.toggle.show}
|
||||
>
|
||||
<FontAwesomeIcon icon={faSearchPlus} className="mr-1" />
|
||||
{name}
|
||||
</div>
|
||||
</TooltipWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TooltipWrapper title="Click the icon to hide annotation value">
|
||||
<div key={name} className={className}>
|
||||
<FontAwesomeIcon
|
||||
icon={faSearchMinus}
|
||||
className="mr-1 cursor-pointer"
|
||||
onClick={this.toggle.hide}
|
||||
/>
|
||||
<span className="text-muted">{name}: </span>
|
||||
<Linkify
|
||||
properties={{
|
||||
target: "_blank",
|
||||
rel: "noopener noreferrer"
|
||||
}}
|
||||
>
|
||||
<Flash spy={value}>
|
||||
<span>{value}</span>
|
||||
</Flash>
|
||||
</Linkify>
|
||||
</div>
|
||||
</TooltipWrapper>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
const RenderLinkAnnotation = ({ name, value }) => {
|
||||
|
||||
@@ -44,20 +44,31 @@ const GroupFooter = observer(
|
||||
value={a.value}
|
||||
visible={a.visible}
|
||||
afterUpdate={afterUpdate}
|
||||
alertStore={alertStore}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{Object.entries(group.shared.labels).map(([name, value]) => (
|
||||
<FilteringLabel key={name} name={name} value={value} />
|
||||
<FilteringLabel
|
||||
key={name}
|
||||
name={name}
|
||||
value={value}
|
||||
alertStore={alertStore}
|
||||
/>
|
||||
))}
|
||||
{alertmanagers.map(am => (
|
||||
<FilteringLabel
|
||||
key={am}
|
||||
name={StaticLabels.AlertManager}
|
||||
value={am}
|
||||
alertStore={alertStore}
|
||||
/>
|
||||
))}
|
||||
<FilteringLabel name={StaticLabels.Receiver} value={group.receiver} />
|
||||
<FilteringLabel
|
||||
name={StaticLabels.Receiver}
|
||||
value={group.receiver}
|
||||
alertStore={alertStore}
|
||||
/>
|
||||
{group.shared.annotations
|
||||
.filter(a => a.isLink === true)
|
||||
.map(a => (
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import React from "react";
|
||||
|
||||
import { Provider } from "mobx-react";
|
||||
|
||||
import { mount } from "enzyme";
|
||||
|
||||
import toDiffableHtml from "diffable-html";
|
||||
@@ -59,15 +57,13 @@ afterEach(() => {
|
||||
|
||||
const MountedGroupFooter = () => {
|
||||
return mount(
|
||||
<Provider alertStore={alertStore}>
|
||||
<GroupFooter
|
||||
group={group}
|
||||
alertmanagers={["default"]}
|
||||
afterUpdate={MockAfterUpdate}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
/>
|
||||
</Provider>
|
||||
<GroupFooter
|
||||
group={group}
|
||||
alertmanagers={["default"]}
|
||||
afterUpdate={MockAfterUpdate}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ const MenuContent = onClickOutside(
|
||||
const groupLink = `${baseURL}?${FormatAlertsQ(groupFilters)}`;
|
||||
|
||||
return (
|
||||
<FetchPauser>
|
||||
<FetchPauser alertStore={alertStore}>
|
||||
<div
|
||||
className="dropdown-menu d-block shadow"
|
||||
ref={popperRef}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import React from "react";
|
||||
|
||||
import { Provider } from "mobx-react";
|
||||
|
||||
import { mount } from "enzyme";
|
||||
|
||||
import copy from "copy-to-clipboard";
|
||||
@@ -24,15 +22,13 @@ const MockSetIsMenuOpen = jest.fn();
|
||||
|
||||
const MountedGroupMenu = (group, themed) => {
|
||||
return mount(
|
||||
<Provider alertStore={alertStore}>
|
||||
<GroupMenu
|
||||
group={group}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
themed={themed}
|
||||
setIsMenuOpen={MockSetIsMenuOpen}
|
||||
/>
|
||||
</Provider>
|
||||
<GroupMenu
|
||||
group={group}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
themed={themed}
|
||||
setIsMenuOpen={MockSetIsMenuOpen}
|
||||
/>
|
||||
).find("GroupMenu");
|
||||
};
|
||||
|
||||
@@ -67,17 +63,15 @@ describe("<GroupMenu />", () => {
|
||||
|
||||
const MountedMenuContent = group => {
|
||||
return mount(
|
||||
<Provider alertStore={alertStore}>
|
||||
<MenuContent
|
||||
popperPlacement="top"
|
||||
popperRef={null}
|
||||
popperStyle={{}}
|
||||
group={group}
|
||||
afterClick={MockAfterClick}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
/>
|
||||
</Provider>
|
||||
<MenuContent
|
||||
popperPlacement="top"
|
||||
popperRef={null}
|
||||
popperStyle={{}}
|
||||
group={group}
|
||||
afterClick={MockAfterClick}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ const GroupHeader = observer(
|
||||
key={name}
|
||||
name={name}
|
||||
value={group.labels[name]}
|
||||
alertStore={alertStore}
|
||||
/>
|
||||
))}
|
||||
</span>
|
||||
@@ -69,18 +70,21 @@ const GroupHeader = observer(
|
||||
value="unprocessed"
|
||||
counter={group.stateCount.unprocessed}
|
||||
themed={themedCounters}
|
||||
alertStore={alertStore}
|
||||
/>
|
||||
<FilteringCounterBadge
|
||||
name="@state"
|
||||
value="suppressed"
|
||||
counter={group.stateCount.suppressed}
|
||||
themed={themedCounters}
|
||||
alertStore={alertStore}
|
||||
/>
|
||||
<FilteringCounterBadge
|
||||
name="@state"
|
||||
value="active"
|
||||
counter={group.stateCount.active}
|
||||
themed={themedCounters}
|
||||
alertStore={alertStore}
|
||||
/>
|
||||
<span
|
||||
className={`${
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import React from "react";
|
||||
|
||||
import { Provider } from "mobx-react";
|
||||
|
||||
import { mount } from "enzyme";
|
||||
|
||||
import moment from "moment";
|
||||
@@ -58,16 +56,14 @@ const MockAlerts = alertCount => {
|
||||
|
||||
const MountedAlertGroup = (afterUpdate, showAlertmanagers) => {
|
||||
return mount(
|
||||
<Provider alertStore={alertStore}>
|
||||
<AlertGroup
|
||||
afterUpdate={afterUpdate}
|
||||
group={group}
|
||||
showAlertmanagers={showAlertmanagers}
|
||||
settingsStore={settingsStore}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
/>
|
||||
</Provider>
|
||||
<AlertGroup
|
||||
afterUpdate={afterUpdate}
|
||||
group={group}
|
||||
showAlertmanagers={showAlertmanagers}
|
||||
settingsStore={settingsStore}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@ import React from "react";
|
||||
|
||||
import { storiesOf } from "@storybook/react";
|
||||
|
||||
import { Provider } from "mobx-react";
|
||||
|
||||
import moment from "moment";
|
||||
|
||||
import { MockAlert, MockAlertGroup } from "__mocks__/Alerts.js";
|
||||
@@ -173,12 +171,10 @@ storiesOf("Grid", module)
|
||||
alertStore.data.groups = groups;
|
||||
|
||||
return (
|
||||
<Provider alertStore={alertStore}>
|
||||
<Grid
|
||||
alertStore={alertStore}
|
||||
settingsStore={settingsStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
/>
|
||||
</Provider>
|
||||
<Grid
|
||||
alertStore={alertStore}
|
||||
settingsStore={settingsStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
import Flash from "react-reveal/Flash";
|
||||
|
||||
@@ -12,53 +12,51 @@ import { BaseLabel } from "Components/Labels/BaseLabel";
|
||||
// Same as FilteringLabel but for labels that are counters (usually @state)
|
||||
// and only renders a pill badge with the counter, it doesn't render anything
|
||||
// if the counter is 0
|
||||
const FilteringCounterBadge = inject("alertStore")(
|
||||
observer(
|
||||
class FilteringCounterBadge extends BaseLabel {
|
||||
static propTypes = {
|
||||
alertStore: PropTypes.instanceOf(AlertStore).isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
counter: PropTypes.number.isRequired,
|
||||
themed: PropTypes.bool.isRequired
|
||||
};
|
||||
const FilteringCounterBadge = observer(
|
||||
class FilteringCounterBadge extends BaseLabel {
|
||||
static propTypes = {
|
||||
alertStore: PropTypes.instanceOf(AlertStore).isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
counter: PropTypes.number.isRequired,
|
||||
themed: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
render() {
|
||||
const { name, value, counter, themed } = this.props;
|
||||
render() {
|
||||
const { name, value, counter, themed } = this.props;
|
||||
|
||||
if (counter === 0) return null;
|
||||
if (counter === 0) return null;
|
||||
|
||||
const cs = this.getClassAndStyle(
|
||||
name,
|
||||
value,
|
||||
"badge-pill components-label-with-hover"
|
||||
);
|
||||
const cs = this.getClassAndStyle(
|
||||
name,
|
||||
value,
|
||||
"badge-pill components-label-with-hover"
|
||||
);
|
||||
|
||||
return (
|
||||
<TooltipWrapper
|
||||
title={`Click to only show ${value} alerts or Alt+Click to hide them`}
|
||||
>
|
||||
<Flash spy={counter}>
|
||||
<span
|
||||
className={
|
||||
themed
|
||||
? cs.className
|
||||
: [
|
||||
"badge-light badge-pill components-label-with-hover",
|
||||
...cs.baseClassNames
|
||||
].join(" ")
|
||||
}
|
||||
style={themed ? {} : cs.style}
|
||||
onClick={e => this.handleClick(e)}
|
||||
>
|
||||
{counter}
|
||||
</span>
|
||||
</Flash>
|
||||
</TooltipWrapper>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<TooltipWrapper
|
||||
title={`Click to only show ${value} alerts or Alt+Click to hide them`}
|
||||
>
|
||||
<Flash spy={counter}>
|
||||
<span
|
||||
className={
|
||||
themed
|
||||
? cs.className
|
||||
: [
|
||||
"badge-light badge-pill components-label-with-hover",
|
||||
...cs.baseClassNames
|
||||
].join(" ")
|
||||
}
|
||||
style={themed ? {} : cs.style}
|
||||
onClick={e => this.handleClick(e)}
|
||||
>
|
||||
{counter}
|
||||
</span>
|
||||
</Flash>
|
||||
</TooltipWrapper>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
export { FilteringCounterBadge };
|
||||
|
||||
@@ -1,38 +1,36 @@
|
||||
import React from "react";
|
||||
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
import { TooltipWrapper } from "Components/TooltipWrapper";
|
||||
import { BaseLabel } from "Components/Labels/BaseLabel";
|
||||
|
||||
// Renders a label element that after clicking adds current label as a filter
|
||||
const FilteringLabel = inject("alertStore")(
|
||||
observer(
|
||||
class FilteringLabel extends BaseLabel {
|
||||
render() {
|
||||
const { name, value } = this.props;
|
||||
const FilteringLabel = observer(
|
||||
class FilteringLabel extends BaseLabel {
|
||||
render() {
|
||||
const { name, value } = this.props;
|
||||
|
||||
let cs = this.getClassAndStyle(
|
||||
name,
|
||||
value,
|
||||
"components-label-with-hover"
|
||||
);
|
||||
let cs = this.getClassAndStyle(
|
||||
name,
|
||||
value,
|
||||
"components-label-with-hover"
|
||||
);
|
||||
|
||||
return (
|
||||
<TooltipWrapper title="Click to only show alerts with this label or Alt+Click to hide them">
|
||||
<span
|
||||
className={cs.className}
|
||||
style={cs.style}
|
||||
onClick={e => this.handleClick(e)}
|
||||
>
|
||||
<span className="components-label-name">{name}:</span>{" "}
|
||||
<span className="components-label-value">{value}</span>
|
||||
</span>
|
||||
</TooltipWrapper>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<TooltipWrapper title="Click to only show alerts with this label or Alt+Click to hide them">
|
||||
<span
|
||||
className={cs.className}
|
||||
style={cs.style}
|
||||
onClick={e => this.handleClick(e)}
|
||||
>
|
||||
<span className="components-label-name">{name}:</span>{" "}
|
||||
<span className="components-label-value">{value}</span>
|
||||
</span>
|
||||
</TooltipWrapper>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
export { FilteringLabel };
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { faTimes } from "@fortawesome/free-solid-svg-icons/faTimes";
|
||||
@@ -12,86 +12,80 @@ import { BaseLabel } from "Components/Labels/BaseLabel";
|
||||
|
||||
import "./index.scss";
|
||||
|
||||
const LabelWithPercent = inject("alertStore")(
|
||||
observer(
|
||||
class LabelWithPercent extends BaseLabel {
|
||||
static propTypes = {
|
||||
alertStore: PropTypes.instanceOf(AlertStore).isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
hits: PropTypes.number.isRequired,
|
||||
percent: PropTypes.number.isRequired,
|
||||
offset: PropTypes.number.isRequired,
|
||||
isActive: PropTypes.bool.isRequired
|
||||
};
|
||||
const LabelWithPercent = observer(
|
||||
class LabelWithPercent extends BaseLabel {
|
||||
static propTypes = {
|
||||
alertStore: PropTypes.instanceOf(AlertStore).isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
hits: PropTypes.number.isRequired,
|
||||
percent: PropTypes.number.isRequired,
|
||||
offset: PropTypes.number.isRequired,
|
||||
isActive: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
removeFromFilters = () => {
|
||||
const { alertStore, name, value } = this.props;
|
||||
alertStore.filters.removeFilter(
|
||||
FormatQuery(name, QueryOperators.Equal, value)
|
||||
);
|
||||
};
|
||||
removeFromFilters = () => {
|
||||
const { alertStore, name, value } = this.props;
|
||||
alertStore.filters.removeFilter(
|
||||
FormatQuery(name, QueryOperators.Equal, value)
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { name, value, hits, percent, offset, isActive } = this.props;
|
||||
render() {
|
||||
const { name, value, hits, percent, offset, isActive } = this.props;
|
||||
|
||||
let cs = this.getClassAndStyle(
|
||||
name,
|
||||
value,
|
||||
"components-label-with-hover mb-0 pl-0 text-left"
|
||||
);
|
||||
let cs = this.getClassAndStyle(
|
||||
name,
|
||||
value,
|
||||
"components-label-with-hover mb-0 pl-0 text-left"
|
||||
);
|
||||
|
||||
const progressBarBg =
|
||||
percent > 66
|
||||
? "bg-danger"
|
||||
: percent > 33
|
||||
? "bg-warning"
|
||||
: "bg-success";
|
||||
const progressBarBg =
|
||||
percent > 66 ? "bg-danger" : percent > 33 ? "bg-warning" : "bg-success";
|
||||
|
||||
return (
|
||||
<div className="d-inline-block mw-100">
|
||||
<span className={cs.className} style={cs.style}>
|
||||
<span className="mr-1 px-1 bg-primary text-white components-labelWithPercent-percent">
|
||||
{hits}
|
||||
</span>
|
||||
<span onClick={e => this.handleClick(e)}>
|
||||
<span className="components-label-name">{name}:</span>{" "}
|
||||
<span className="components-label-value">{value}</span>
|
||||
</span>
|
||||
{isActive ? (
|
||||
<FontAwesomeIcon
|
||||
className="cursor-pointer text-reset ml-1 close"
|
||||
style={{ fontSize: "100%" }}
|
||||
icon={faTimes}
|
||||
onClick={this.removeFromFilters}
|
||||
/>
|
||||
) : null}
|
||||
return (
|
||||
<div className="d-inline-block mw-100">
|
||||
<span className={cs.className} style={cs.style}>
|
||||
<span className="mr-1 px-1 bg-primary text-white components-labelWithPercent-percent">
|
||||
{hits}
|
||||
</span>
|
||||
<div className="progress components-labelWithPercent-progress mr-1">
|
||||
{offset === 0 ? null : (
|
||||
<div
|
||||
className="progress-bar bg-transparent"
|
||||
role="progressbar"
|
||||
style={{ width: offset + "%" }}
|
||||
aria-valuenow={offset}
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
/>
|
||||
)}
|
||||
<span onClick={e => this.handleClick(e)}>
|
||||
<span className="components-label-name">{name}:</span>{" "}
|
||||
<span className="components-label-value">{value}</span>
|
||||
</span>
|
||||
{isActive ? (
|
||||
<FontAwesomeIcon
|
||||
className="cursor-pointer text-reset ml-1 close"
|
||||
style={{ fontSize: "100%" }}
|
||||
icon={faTimes}
|
||||
onClick={this.removeFromFilters}
|
||||
/>
|
||||
) : null}
|
||||
</span>
|
||||
<div className="progress components-labelWithPercent-progress mr-1">
|
||||
{offset === 0 ? null : (
|
||||
<div
|
||||
className={`progress-bar ${progressBarBg}`}
|
||||
className="progress-bar bg-transparent"
|
||||
role="progressbar"
|
||||
style={{ width: percent + "%" }}
|
||||
aria-valuenow={percent}
|
||||
style={{ width: offset + "%" }}
|
||||
aria-valuenow={offset}
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={`progress-bar ${progressBarBg}`}
|
||||
role="progressbar"
|
||||
style={{ width: percent + "%" }}
|
||||
aria-valuenow={percent}
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="100"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
export { LabelWithPercent };
|
||||
|
||||
@@ -1,27 +1,25 @@
|
||||
import React from "react";
|
||||
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
import { BaseLabel } from "Components/Labels/BaseLabel";
|
||||
|
||||
// Renders a static label element, no click actions, no hover
|
||||
const StaticLabel = inject("alertStore")(
|
||||
observer(
|
||||
class FilteringLabel extends BaseLabel {
|
||||
render() {
|
||||
const { name, value } = this.props;
|
||||
const StaticLabel = observer(
|
||||
class FilteringLabel extends BaseLabel {
|
||||
render() {
|
||||
const { name, value } = this.props;
|
||||
|
||||
let cs = this.getClassAndStyle(name, value);
|
||||
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 (
|
||||
<span className={cs.className} style={cs.style}>
|
||||
<span className="components-label-name">{name}:</span>{" "}
|
||||
<span className="components-label-value">{value}</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
export { StaticLabel };
|
||||
|
||||
@@ -26,6 +26,7 @@ const TableRows = observer(({ alertStore, nameStats }) =>
|
||||
<td width="75%" className="mw-100 p-1">
|
||||
{nameStats.values.slice(0, 9).map((valueStats, i) => (
|
||||
<LabelWithPercent
|
||||
alertStore={alertStore}
|
||||
key={valueStats.value}
|
||||
name={nameStats.name}
|
||||
value={valueStats.value}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import React from "react";
|
||||
|
||||
import { Provider } from "mobx-react";
|
||||
|
||||
import { mount } from "enzyme";
|
||||
|
||||
import toDiffableHtml from "diffable-html";
|
||||
@@ -27,9 +25,7 @@ const MountedOverviewModalContent = () =>
|
||||
// https://github.com/airbnb/enzyme/issues/1213
|
||||
mount(
|
||||
<span>
|
||||
<Provider alertStore={alertStore}>
|
||||
<OverviewModalContent alertStore={alertStore} onHide={onHide} />
|
||||
</Provider>
|
||||
<OverviewModalContent alertStore={alertStore} onHide={onHide} />
|
||||
</span>
|
||||
);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { observer, Provider } from "mobx-react";
|
||||
import { observer } from "mobx-react";
|
||||
import { observable, action } from "mobx";
|
||||
|
||||
import Flash from "react-reveal/Flash";
|
||||
@@ -70,13 +70,11 @@ const OverviewModal = observer(
|
||||
</h1>
|
||||
}
|
||||
>
|
||||
<Provider alertStore={alertStore}>
|
||||
<OverviewModalContent
|
||||
alertStore={alertStore}
|
||||
onHide={this.toggle.hide}
|
||||
isVisible={this.toggle.show}
|
||||
/>
|
||||
</Provider>
|
||||
<OverviewModalContent
|
||||
alertStore={alertStore}
|
||||
onHide={this.toggle.hide}
|
||||
isVisible={this.toggle.show}
|
||||
/>
|
||||
</React.Suspense>
|
||||
</Modal>
|
||||
</React.Fragment>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import { observable, action } from "mobx";
|
||||
import { observer, Provider } from "mobx-react";
|
||||
import { observer } from "mobx-react";
|
||||
|
||||
import { debounce } from "lodash";
|
||||
|
||||
@@ -232,23 +232,21 @@ const Browser = observer(
|
||||
<Placeholder content="Nothing to show" />
|
||||
) : (
|
||||
<React.Fragment>
|
||||
<Provider alertStore={alertStore}>
|
||||
{this.dataSource.silences
|
||||
.slice(
|
||||
(this.pagination.activePage - 1) * this.maxPerPage,
|
||||
this.pagination.activePage * this.maxPerPage
|
||||
)
|
||||
.map(silence => (
|
||||
<ManagedSilence
|
||||
key={`${silence.cluster}/${silence.silence.id}`}
|
||||
cluster={silence.cluster}
|
||||
silence={silence.silence}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
onDeleteModalClose={onDeleteModalClose}
|
||||
/>
|
||||
))}
|
||||
</Provider>
|
||||
{this.dataSource.silences
|
||||
.slice(
|
||||
(this.pagination.activePage - 1) * this.maxPerPage,
|
||||
this.pagination.activePage * this.maxPerPage
|
||||
)
|
||||
.map(silence => (
|
||||
<ManagedSilence
|
||||
key={`${silence.cluster}/${silence.silence.id}`}
|
||||
cluster={silence.cluster}
|
||||
silence={silence.silence}
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
onDeleteModalClose={onDeleteModalClose}
|
||||
/>
|
||||
))}
|
||||
{this.dataSource.silences.length > this.maxPerPage ? (
|
||||
<div className="mt-3">
|
||||
<Pagination
|
||||
|
||||
Reference in New Issue
Block a user