fix(ui): rewrite ManagedSilence component with hooks

This commit is contained in:
Łukasz Mierzwa
2020-05-01 16:15:57 +01:00
committed by Łukasz Mierzwa
parent 2dbbbb542c
commit 38a57fc24d
2 changed files with 90 additions and 121 deletions

View File

@@ -1,8 +1,7 @@
import React, { Component } from "react";
import React, { useEffect } from "react";
import PropTypes from "prop-types";
import { observable, action } from "mobx";
import { observer } from "mobx-react";
import { useObserver, useLocalStore } from "mobx-react";
import { Fade } from "react-reveal";
@@ -13,107 +12,88 @@ import { ThemeContext } from "Components/Theme";
import { SilenceComment } from "./SilenceComment";
import { SilenceDetails } from "./SilenceDetails";
const ManagedSilence = observer(
class ManagedSilence extends Component {
static propTypes = {
cluster: PropTypes.string.isRequired,
alertCount: PropTypes.number.isRequired,
alertCountAlwaysVisible: PropTypes.bool.isRequired,
silence: APISilence.isRequired,
alertStore: PropTypes.instanceOf(AlertStore).isRequired,
silenceFormStore: PropTypes.instanceOf(SilenceFormStore).isRequired,
onDidUpdate: PropTypes.func,
onDeleteModalClose: PropTypes.func,
isOpen: PropTypes.bool,
};
static defaultProps = {
isOpen: false,
};
const GetAlertmanager = (alertStore, cluster) =>
alertStore.data.readWriteAlertmanagers
.filter((u) => u.cluster === cluster)
.slice(0, 1)[0];
constructor(props) {
super(props);
const ManagedSilence = ({
cluster,
alertCount,
alertCountAlwaysVisible,
silence,
alertStore,
silenceFormStore,
isOpen,
onDidUpdate,
onDeleteModalClose,
}) => {
useEffect(() => {
if (onDidUpdate) onDidUpdate();
});
// 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 }
);
}
const collapse = useLocalStore(() => ({
value: !isOpen,
toggle() {
this.value = !this.value;
},
}));
getAlertmanager = () =>
this.props.alertStore.data.readWriteAlertmanagers
.filter((u) => u.cluster === this.props.cluster)
.slice(0, 1)[0];
const onEditSilence = () => {
const alertmanager = GetAlertmanager(alertStore, cluster);
onEditSilence = () => {
const { silenceFormStore, silence } = this.props;
silenceFormStore.data.fillFormFromSilence(alertmanager, silence);
silenceFormStore.data.resetProgress();
silenceFormStore.tab.setTab(SilenceTabNames.Editor);
silenceFormStore.toggle.show();
};
const alertmanager = this.getAlertmanager();
const context = React.useContext(ThemeContext);
silenceFormStore.data.fillFormFromSilence(alertmanager, silence);
silenceFormStore.data.resetProgress();
silenceFormStore.tab.setTab(SilenceTabNames.Editor);
silenceFormStore.toggle.show();
};
return useObserver(() => (
<Fade in={context.animations.in} duration={context.animations.duration}>
<div className="card my-1 components-managed-silence">
<div className="card-header rounded-0 border-bottom-0 px-3">
<SilenceComment
alertStore={alertStore}
cluster={cluster}
silence={silence}
alertCount={alertCount}
alertCountAlwaysVisible={alertCountAlwaysVisible}
collapsed={collapse.value}
collapseToggle={collapse.toggle}
/>
</div>
componentDidUpdate() {
const { onDidUpdate } = this.props;
if (onDidUpdate) onDidUpdate();
}
render() {
const {
cluster,
alertCount,
alertCountAlwaysVisible,
silence,
alertStore,
silenceFormStore,
onDeleteModalClose,
} = this.props;
return (
<Fade
in={this.context.animations.in}
duration={this.context.animations.duration}
>
<div className="card my-1 components-managed-silence">
<div className="card-header rounded-0 border-bottom-0 px-3">
<SilenceComment
alertStore={alertStore}
cluster={cluster}
silence={silence}
alertCount={alertCount}
alertCountAlwaysVisible={alertCountAlwaysVisible}
collapsed={this.collapse.value}
collapseToggle={this.collapse.toggle}
/>
</div>
{this.collapse.value ? null : (
<div className="card-body pt-0">
<SilenceDetails
cluster={cluster}
silence={silence}
alertStore={alertStore}
silenceFormStore={silenceFormStore}
onEditSilence={this.onEditSilence}
onDeleteModalClose={onDeleteModalClose}
/>
</div>
)}
{collapse.value ? null : (
<div className="card-body pt-0">
<SilenceDetails
cluster={cluster}
silence={silence}
alertStore={alertStore}
silenceFormStore={silenceFormStore}
onEditSilence={onEditSilence}
onDeleteModalClose={onDeleteModalClose}
/>
</div>
</Fade>
);
}
}
);
ManagedSilence.contextType = ThemeContext;
)}
</div>
</Fade>
));
};
ManagedSilence.propTypes = {
cluster: PropTypes.string.isRequired,
alertCount: PropTypes.number.isRequired,
alertCountAlwaysVisible: PropTypes.bool.isRequired,
silence: APISilence.isRequired,
alertStore: PropTypes.instanceOf(AlertStore).isRequired,
silenceFormStore: PropTypes.instanceOf(SilenceFormStore).isRequired,
onDidUpdate: PropTypes.func,
onDeleteModalClose: PropTypes.func,
isOpen: PropTypes.bool,
};
ManagedSilence.defaultProps = {
isOpen: false,
};
export { ManagedSilence };
export { ManagedSilence, GetAlertmanager };

View File

@@ -12,7 +12,7 @@ import { MockThemeContext } from "__mocks__/Theme";
import { AlertStore } from "Stores/AlertStore";
import { SilenceFormStore } from "Stores/SilenceFormStore";
import { ThemeContext } from "Components/Theme";
import { ManagedSilence } from ".";
import { ManagedSilence, GetAlertmanager } from ".";
let alertStore;
let silenceFormStore;
@@ -80,23 +80,19 @@ describe("<ManagedSilence />", () => {
it("clicking on expand toggle shows silence details", () => {
const tree = MountedManagedSilence();
const toggle = tree.find("svg.text-muted.cursor-pointer");
toggle.simulate("click");
tree.find("svg.text-muted.cursor-pointer").simulate("click");
const details = tree.find("SilenceDetails");
expect(details).toHaveLength(1);
});
it("matches snapshot with expaned details", () => {
const tree = MountedManagedSilence();
tree.instance().collapse.toggle();
tree.update();
tree.find("svg.text-muted.cursor-pointer").simulate("click");
expect(toDiffableHtml(tree.html())).toMatchSnapshot();
});
it("getAlertmanager() returns alertmanager object from alertStore.data.upstreams.instances", () => {
const tree = MountedManagedSilence();
const instance = tree.instance();
const am = instance.getAlertmanager();
it("GetAlertmanager() returns alertmanager object from alertStore.data.upstreams.instances", () => {
const am = GetAlertmanager(alertStore, cluster);
expect(am).toEqual({
name: "am1",
cluster: "am",
@@ -111,7 +107,7 @@ describe("<ManagedSilence />", () => {
});
});
it("getAlertmanager() returns only writable instances", () => {
it("GetAlertmanager() returns only writable instances", () => {
alertStore.data.upstreams = {
instances: [
{
@@ -142,9 +138,7 @@ describe("<ManagedSilence />", () => {
clusters: { am: ["am1", "am2"] },
};
const tree = MountedManagedSilence();
const instance = tree.instance();
const am = instance.getAlertmanager();
const am = GetAlertmanager(alertStore, cluster);
expect(am).toEqual({
name: "am1",
cluster: "am",
@@ -161,8 +155,7 @@ describe("<ManagedSilence />", () => {
it("shows Edit button on unexpired silence", () => {
const tree = MountedManagedSilence();
tree.instance().collapse.toggle();
tree.update();
tree.find("svg.text-muted.cursor-pointer").simulate("click");
const button = tree.find(".btn-primary");
expect(button.text()).toBe("Edit");
@@ -170,8 +163,7 @@ describe("<ManagedSilence />", () => {
it("shows Delete button on unexpired silence", () => {
const tree = MountedManagedSilence();
tree.instance().collapse.toggle();
tree.update();
tree.find("svg.text-muted.cursor-pointer").simulate("click");
const button = tree.find(".btn-danger");
expect(button.text()).toBe("Delete");
@@ -180,8 +172,7 @@ describe("<ManagedSilence />", () => {
it("shows Recreate button on expired silence", () => {
advanceTo(moment.utc([2000, 0, 1, 23, 30, 0]));
const tree = MountedManagedSilence();
tree.instance().collapse.toggle();
tree.update();
tree.find("svg.text-muted.cursor-pointer").simulate("click");
const button = tree.find(".btn-primary");
expect(button.text()).toBe("Recreate");
@@ -189,8 +180,7 @@ describe("<ManagedSilence />", () => {
it("clicking on Edit calls ", () => {
const tree = MountedManagedSilence();
tree.instance().collapse.toggle();
tree.update();
tree.find("svg.text-muted.cursor-pointer").simulate("click");
expect(silenceFormStore.data.silenceID).toBeNull();
@@ -206,8 +196,7 @@ describe("<ManagedSilence />", () => {
it("call onDidUpdate if passed", () => {
const fakeUpdate = jest.fn();
const tree = MountedManagedSilence(fakeUpdate);
tree.instance().collapse.toggle();
tree.update();
tree.find("svg.text-muted.cursor-pointer").simulate("click");
expect(fakeUpdate).toHaveBeenCalled();
});
});