mirror of
https://github.com/prymitive/karma
synced 2026-05-07 03:26:52 +00:00
feat(ui): save last used silence author to local storage
Silence form should default to last used author email so there's no need to re-type it all the time
This commit is contained in:
@@ -50,6 +50,7 @@ const NavBar = observer(
|
||||
<SilenceModal
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
settingsStore={settingsStore}
|
||||
/>
|
||||
<MainModal
|
||||
alertStore={alertStore}
|
||||
|
||||
@@ -55,7 +55,8 @@ const SilenceForm = observer(
|
||||
class SilenceForm extends Component {
|
||||
static propTypes = {
|
||||
alertStore: PropTypes.object.isRequired,
|
||||
silenceFormStore: PropTypes.object.isRequired
|
||||
silenceFormStore: PropTypes.object.isRequired,
|
||||
settingsStore: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
// store preview visibility state here, by default preview is collapsed
|
||||
@@ -72,11 +73,16 @@ const SilenceForm = observer(
|
||||
);
|
||||
|
||||
componentDidMount() {
|
||||
const { silenceFormStore } = this.props;
|
||||
const { silenceFormStore, settingsStore } = this.props;
|
||||
|
||||
if (silenceFormStore.data.matchers.length === 0) {
|
||||
silenceFormStore.data.addEmptyMatcher();
|
||||
}
|
||||
|
||||
if (silenceFormStore.data.author === "") {
|
||||
silenceFormStore.data.author =
|
||||
settingsStore.silenceFormConfig.config.author;
|
||||
}
|
||||
}
|
||||
|
||||
addMore = action(event => {
|
||||
@@ -98,10 +104,12 @@ const SilenceForm = observer(
|
||||
});
|
||||
|
||||
handleSubmit = action(event => {
|
||||
const { silenceFormStore } = this.props;
|
||||
const { silenceFormStore, settingsStore } = this.props;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
settingsStore.silenceFormConfig.saveAuthor(silenceFormStore.data.author);
|
||||
|
||||
if (silenceFormStore.data.isValid)
|
||||
silenceFormStore.data.inProgress = true;
|
||||
|
||||
|
||||
@@ -3,26 +3,37 @@ import React from "react";
|
||||
import { mount, shallow } from "enzyme";
|
||||
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
import { Settings } from "Stores/Settings";
|
||||
import { SilenceFormStore, NewEmptyMatcher } from "Stores/SilenceFormStore";
|
||||
import { SilenceForm } from "./SilenceForm";
|
||||
|
||||
let alertStore;
|
||||
let settingsStore;
|
||||
let silenceFormStore;
|
||||
|
||||
beforeEach(() => {
|
||||
alertStore = new AlertStore([]);
|
||||
settingsStore = new Settings();
|
||||
silenceFormStore = new SilenceFormStore();
|
||||
});
|
||||
|
||||
const ShallowSilenceForm = () => {
|
||||
return shallow(
|
||||
<SilenceForm alertStore={alertStore} silenceFormStore={silenceFormStore} />
|
||||
<SilenceForm
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
settingsStore={settingsStore}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const MountedSilenceForm = () => {
|
||||
return mount(
|
||||
<SilenceForm alertStore={alertStore} silenceFormStore={silenceFormStore} />
|
||||
<SilenceForm
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
settingsStore={settingsStore}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -105,6 +116,22 @@ describe("<SilenceForm /> preview", () => {
|
||||
});
|
||||
|
||||
describe("<SilenceForm /> inputs", () => {
|
||||
it("default author value comes from Settings store", () => {
|
||||
settingsStore.silenceFormConfig.config.author = "foo@example.com";
|
||||
const tree = MountedSilenceForm();
|
||||
const input = tree.find("input[placeholder='Author email']");
|
||||
expect(input.props().value).toBe("foo@example.com");
|
||||
expect(silenceFormStore.data.author).toBe("foo@example.com");
|
||||
});
|
||||
|
||||
it("default author value is empty if nothing is stored in Settings", () => {
|
||||
settingsStore.silenceFormConfig.config.author = "";
|
||||
const tree = MountedSilenceForm();
|
||||
const input = tree.find("input[placeholder='Author email']");
|
||||
expect(input.text()).toBe("");
|
||||
expect(silenceFormStore.data.author).toBe("");
|
||||
});
|
||||
|
||||
it("changing author input updates SilenceFormStore", () => {
|
||||
const tree = MountedSilenceForm();
|
||||
const input = tree.find("input[placeholder='Author email']");
|
||||
@@ -141,4 +168,13 @@ describe("<SilenceForm />", () => {
|
||||
tree.simulate("submit", { preventDefault: jest.fn() });
|
||||
expect(silenceFormStore.data.inProgress).toBe(true);
|
||||
});
|
||||
|
||||
it("calling submit saves author value to the Settings store", () => {
|
||||
silenceFormStore.data.author = "user@example.com";
|
||||
const tree = ShallowSilenceForm();
|
||||
tree.simulate("submit", { preventDefault: jest.fn() });
|
||||
expect(settingsStore.silenceFormConfig.config.author).toBe(
|
||||
"user@example.com"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,7 +13,8 @@ const SilenceModalContent = observer(
|
||||
class SilenceModalContent extends Component {
|
||||
static propTypes = {
|
||||
alertStore: PropTypes.object.isRequired,
|
||||
silenceFormStore: PropTypes.object.isRequired
|
||||
silenceFormStore: PropTypes.object.isRequired,
|
||||
settingsStore: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
@@ -25,7 +26,7 @@ const SilenceModalContent = observer(
|
||||
}
|
||||
|
||||
render() {
|
||||
const { alertStore, silenceFormStore } = this.props;
|
||||
const { alertStore, silenceFormStore, settingsStore } = this.props;
|
||||
|
||||
return ReactDOM.createPortal(
|
||||
<div className="modal d-block bg-primary-transparent-80" role="dialog">
|
||||
@@ -50,6 +51,7 @@ const SilenceModalContent = observer(
|
||||
<SilenceForm
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
settingsStore={settingsStore}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -3,14 +3,17 @@ import React from "react";
|
||||
import { shallow } from "enzyme";
|
||||
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
import { Settings } from "Stores/Settings";
|
||||
import { SilenceFormStore } from "Stores/SilenceFormStore";
|
||||
import { SilenceModalContent } from "./SilenceModalContent";
|
||||
|
||||
let alertStore;
|
||||
let settingsStore;
|
||||
let silenceFormStore;
|
||||
|
||||
beforeEach(() => {
|
||||
alertStore = new AlertStore([]);
|
||||
settingsStore = new Settings();
|
||||
silenceFormStore = new SilenceFormStore();
|
||||
});
|
||||
|
||||
@@ -18,6 +21,7 @@ const ShallowSilenceModalContent = () => {
|
||||
return shallow(
|
||||
<SilenceModalContent
|
||||
alertStore={alertStore}
|
||||
settingsStore={settingsStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -14,7 +14,8 @@ const SilenceModal = observer(
|
||||
class SilenceModal extends Component {
|
||||
static propTypes = {
|
||||
alertStore: PropTypes.object.isRequired,
|
||||
silenceFormStore: PropTypes.object.isRequired
|
||||
silenceFormStore: PropTypes.object.isRequired,
|
||||
settingsStore: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
componentDidUpdate() {
|
||||
@@ -31,7 +32,7 @@ const SilenceModal = observer(
|
||||
}
|
||||
|
||||
render() {
|
||||
const { alertStore, silenceFormStore } = this.props;
|
||||
const { alertStore, silenceFormStore, settingsStore } = this.props;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
@@ -47,6 +48,7 @@ const SilenceModal = observer(
|
||||
<SilenceModalContent
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
settingsStore={settingsStore}
|
||||
/>
|
||||
) : null}
|
||||
</React.Fragment>
|
||||
|
||||
@@ -3,26 +3,37 @@ import React from "react";
|
||||
import { shallow, mount } from "enzyme";
|
||||
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
import { Settings } from "Stores/Settings";
|
||||
import { SilenceFormStore } from "Stores/SilenceFormStore";
|
||||
import { SilenceModal } from ".";
|
||||
|
||||
let alertStore;
|
||||
let settingsStore;
|
||||
let silenceFormStore;
|
||||
|
||||
beforeEach(() => {
|
||||
alertStore = new AlertStore([]);
|
||||
settingsStore = new Settings();
|
||||
silenceFormStore = new SilenceFormStore();
|
||||
});
|
||||
|
||||
const ShallowSilenceModal = () => {
|
||||
return shallow(
|
||||
<SilenceModal alertStore={alertStore} silenceFormStore={silenceFormStore} />
|
||||
<SilenceModal
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
settingsStore={settingsStore}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const MountedSilenceModal = () => {
|
||||
return mount(
|
||||
<SilenceModal alertStore={alertStore} silenceFormStore={silenceFormStore} />
|
||||
<SilenceModal
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
settingsStore={settingsStore}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -46,11 +46,20 @@ class AlertGroupConfig {
|
||||
});
|
||||
}
|
||||
|
||||
class SilenceFormConfig {
|
||||
config = localStored("silenceFormConfig", { author: "" }, { delay: 100 });
|
||||
|
||||
saveAuthor = action(newAuthor => {
|
||||
this.config.author = newAuthor;
|
||||
});
|
||||
}
|
||||
|
||||
class Settings {
|
||||
constructor() {
|
||||
this.savedFilters = new SavedFilters();
|
||||
this.fetchConfig = new FetchConfig();
|
||||
this.alertGroupConfig = new AlertGroupConfig();
|
||||
this.silenceFormConfig = new SilenceFormConfig();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user