diff --git a/ui/src/App.js b/ui/src/App.js index b746372b2..263a8b134 100644 --- a/ui/src/App.js +++ b/ui/src/App.js @@ -4,6 +4,7 @@ import PropTypes from "prop-types"; import { Provider } from "mobx-react"; import { AlertStore, DecodeLocationSearch } from "Stores/AlertStore"; +import { Settings } from "Stores/Settings"; import { NavBar } from "Components/NavBar"; import { Grid } from "Components/Grid"; import { Fetcher } from "Components/Fetcher"; @@ -20,6 +21,8 @@ class App extends Component { const { defaultFilters } = this.props; + this.settingsStore = new Settings(); + let filters; // parse and decode request query args @@ -27,8 +30,12 @@ class App extends Component { // p.defaultsUsed means that unsee URI didn't have ?q=foo query args if (p.defaultsUsed) { - // no ?q=foo set, use defaults from backend config - filters = defaultFilters; + // no ?q=foo set, use defaults saved by the user or from backend config + if (this.settingsStore.savedFilters.present) { + filters = this.settingsStore.savedFilters.filters; + } else { + filters = defaultFilters; + } } else { // user passed ?q=foo, use it as initial filters filters = p.params.q; @@ -40,7 +47,10 @@ class App extends Component { render() { return ( - + diff --git a/ui/src/Components/NavBar/FilterInput/History.js b/ui/src/Components/NavBar/FilterInput/History.js index 8676cc5ad..4e66dc437 100644 --- a/ui/src/Components/NavBar/FilterInput/History.js +++ b/ui/src/Components/NavBar/FilterInput/History.js @@ -10,8 +10,12 @@ import onClickOutside from "react-onclickoutside"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faCaretDown } from "@fortawesome/free-solid-svg-icons/faCaretDown"; +import { faSave } from "@fortawesome/free-regular-svg-icons/faSave"; +import { faUndoAlt } from "@fortawesome/free-solid-svg-icons/faUndoAlt"; +import { faTrash } from "@fortawesome/free-solid-svg-icons/faTrash"; import { AlertStore } from "Stores/AlertStore"; +import { Settings } from "Stores/Settings"; import { HistoryLabel } from "Components/Labels/HistoryLabel"; const defaultHistory = { @@ -36,7 +40,9 @@ const HistoryMenu = onClickOutside( popperStyle, filters, alertStore, - afterClick + settingsStore, + afterClick, + onClear }) => { return (
)) )} +
+
+ + + +
); } @@ -80,13 +118,16 @@ HistoryMenu.propTypes = { popperStyle: PropTypes.object, filters: PropTypes.array.isRequired, alertStore: PropTypes.instanceOf(AlertStore).isRequired, - afterClick: PropTypes.func.isRequired + settingsStore: PropTypes.instanceOf(Settings).isRequired, + afterClick: PropTypes.func.isRequired, + onClear: PropTypes.func.isRequired }; const History = observer( class History extends Component { static propTypes = { - alertStore: PropTypes.instanceOf(AlertStore).isRequired + alertStore: PropTypes.instanceOf(AlertStore).isRequired, + settingsStore: PropTypes.instanceOf(Settings).isRequired }; // how many filter sets do we store in local storage and render in the @@ -137,6 +178,10 @@ const History = observer( this.history.filters = newHistory; }); + clearHistory = action(() => { + this.history.filters = []; + }); + componentDidUpdate() { // every time this component updates we will rewrite history // (if there are changes) @@ -148,7 +193,7 @@ const History = observer( }); render() { - const { alertStore } = this.props; + const { alertStore, settingsStore } = this.props; return ( // data-filters is there to register filters for observation in mobx @@ -189,7 +234,9 @@ const History = observer( popperRef={ref} popperStyle={style} filters={this.history.filters} + onClear={this.clearHistory} alertStore={alertStore} + settingsStore={settingsStore} afterClick={this.collapse.hide} handleClickOutside={this.collapse.hide} outsideClickIgnoreClass="components-navbar-history" diff --git a/ui/src/Components/NavBar/FilterInput/index.js b/ui/src/Components/NavBar/FilterInput/index.js index 1034915b4..8e7199e99 100644 --- a/ui/src/Components/NavBar/FilterInput/index.js +++ b/ui/src/Components/NavBar/FilterInput/index.js @@ -14,6 +14,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faSearch } from "@fortawesome/free-solid-svg-icons/faSearch"; import { AlertStore, FormatUnseeBackendURI } from "Stores/AlertStore"; +import { Settings } from "Stores/Settings"; import { FilterInputLabel } from "Components/Labels/FilterInputLabel"; import { AutosuggestTheme } from "./Constants"; import { History } from "./History"; @@ -23,7 +24,8 @@ import "./index.css"; const FilterInput = observer( class FilterInput extends Component { static propTypes = { - alertStore: PropTypes.instanceOf(AlertStore).isRequired + alertStore: PropTypes.instanceOf(AlertStore).isRequired, + settingsStore: PropTypes.instanceOf(Settings).isRequired }; inputStore = observable( @@ -103,7 +105,12 @@ const FilterInput = observer( }; renderInputComponent = inputProps => { - var { inputReference, alertStore, ...otherProps } = inputProps; + var { + inputReference, + alertStore, + settingsStore, + ...otherProps + } = inputProps; return (
@@ -132,14 +139,14 @@ const FilterInput = observer( />
- +
); }; render() { - const { alertStore } = this.props; + const { alertStore, settingsStore } = this.props; return ( // data-filters is there to register filters for observation in mobx @@ -163,7 +170,8 @@ const FilterInput = observer( value: this.inputStore.value, onChange: this.onChange, inputReference: this.inputStore.ref, - alertStore: alertStore + alertStore: alertStore, + settingsStore: settingsStore }} theme={AutosuggestTheme} /> diff --git a/ui/src/Components/NavBar/index.js b/ui/src/Components/NavBar/index.js index dfb26d14f..66575cc4e 100644 --- a/ui/src/Components/NavBar/index.js +++ b/ui/src/Components/NavBar/index.js @@ -6,6 +6,7 @@ import { observer } from "mobx-react"; import ReactResizeDetector from "react-resize-detector"; import { AlertStore } from "Stores/AlertStore"; +import { Settings } from "Stores/Settings"; import { FetchIndicator } from "./FetchIndicator"; import { FilterInput } from "./FilterInput"; import { MainModal } from "Components/MainModal"; @@ -19,11 +20,12 @@ const navbarResize = function(width, height) { const NavBar = observer( class NavBar extends Component { static propTypes = { - alertStore: PropTypes.instanceOf(AlertStore).isRequired + alertStore: PropTypes.instanceOf(AlertStore).isRequired, + settingsStore: PropTypes.instanceOf(Settings).isRequired }; render() { - const { alertStore } = this.props; + const { alertStore, settingsStore } = this.props; return (
diff --git a/ui/src/Stores/Settings.js b/ui/src/Stores/Settings.js new file mode 100644 index 000000000..f36c00a13 --- /dev/null +++ b/ui/src/Stores/Settings.js @@ -0,0 +1,26 @@ +import { localStored } from "mobx-stored"; + +import { action } from "mobx"; + +const defaultSavedFilters = { + filters: [], + present: false +}; + +class Settings { + savedFilters = localStored("savedFilters", defaultSavedFilters, { + delay: 100 + }); + + saveFilters = action(newFilters => { + this.savedFilters.filters = newFilters; + this.savedFilters.present = true; + }); + + clearSavedFilters = action(() => { + this.savedFilters.filters = []; + this.savedFilters.present = false; + }); +} + +export { Settings };