Persist app state to localStorage
parent
6e95f46ce2
commit
e9e6c0b7a3
|
@ -23,10 +23,17 @@ import 'src/style/chronograf.scss';
|
|||
|
||||
const defaultTimeRange = {upper: null, lower: 'now() - 15m'};
|
||||
const lsTimeRange = window.localStorage.getItem('timeRange');
|
||||
const persistedPanels = window.localStorage.getItem('panels');
|
||||
const persistedQueryConfigs = window.localStorage.getItem('queryConfigs');
|
||||
const parsedTimeRange = JSON.parse(lsTimeRange) || {};
|
||||
const timeRange = Object.assign(defaultTimeRange, parsedTimeRange);
|
||||
|
||||
const store = configureStore({timeRange});
|
||||
const store = configureStore({
|
||||
timeRange,
|
||||
panels: JSON.parse(persistedPanels),
|
||||
queryConfigs: JSON.parse(persistedQueryConfigs),
|
||||
});
|
||||
|
||||
const rootNode = document.getElementById('react-root');
|
||||
|
||||
let browserHistory;
|
||||
|
|
|
@ -5,6 +5,7 @@ import makeQueryExecuter from 'src/shared/middleware/queryExecuter';
|
|||
import * as chronografReducers from 'src/data_explorer/reducers';
|
||||
import * as sharedReducers from 'src/shared/reducers';
|
||||
import rulesReducer from 'src/kapacitor/reducers/rules';
|
||||
import persistStateEnhancer from './persistStateEnhancer';
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
...sharedReducers,
|
||||
|
@ -16,6 +17,7 @@ const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
|
|||
|
||||
export default function configureStore(initialState) {
|
||||
const createPersistentStore = composeEnhancers(
|
||||
persistStateEnhancer(),
|
||||
applyMiddleware(thunkMiddleware, makeQueryExecuter()),
|
||||
)(createStore);
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/**
|
||||
* Redux store enhancer (https://github.com/reactjs/redux/blob/master/docs/Glossary.md)
|
||||
* responsible for sending updates on data explorer state to a server to persist.
|
||||
* It subscribes a listener function to the store -- meaning every time the store emits an update
|
||||
* (after some state has changed), we'll have a chance to react.
|
||||
*
|
||||
* After the store emits an update, we'll queue a function to request a save in x number of
|
||||
* seconds. The previous timer is cleared out as well, meaning we won't end up firing a ton of
|
||||
* saves in a short period of time. Only after the store has been idle for x seconds will the save occur.
|
||||
*/
|
||||
|
||||
const autoSaveTimer = (() => {
|
||||
let timer;
|
||||
|
||||
return {
|
||||
set(cb) {
|
||||
const timeUntilSave = 300;
|
||||
timer = setTimeout(cb, timeUntilSave);
|
||||
},
|
||||
|
||||
clear() {
|
||||
clearInterval(timer);
|
||||
},
|
||||
};
|
||||
})();
|
||||
|
||||
export default function persistState() {
|
||||
return (next) => (reducer, initialState, enhancer) => {
|
||||
const store = next(reducer, initialState, enhancer);
|
||||
|
||||
store.subscribe(() => {
|
||||
const state = {...store.getState()};
|
||||
const {panels, queryConfigs, timeRange} = state;
|
||||
|
||||
window.localStorage.setItem('timeRange', JSON.stringify(timeRange));
|
||||
window.localStorage.setItem('panels', JSON.stringify(panels));
|
||||
window.localStorage.setItem('queryConfigs', JSON.stringify(queryConfigs));
|
||||
|
||||
autoSaveTimer.clear();
|
||||
autoSaveTimer.set(() => {
|
||||
try {
|
||||
// save to localStorage
|
||||
} catch (err) {
|
||||
// console.error('Unable to save data explorer session: ', JSON.parse(response).error); // eslint-disable-line no-console
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return store;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue