mirror of
https://github.com/prymitive/karma
synced 2026-05-07 03:26:52 +00:00
fix(ui): rewrite ManagedSilence component with hooks
This commit is contained in:
committed by
Łukasz Mierzwa
parent
2dbbbb542c
commit
38a57fc24d
@@ -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 };
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user