mirror of
https://github.com/hibiken/asynqmon.git
synced 2025-01-19 03:05:53 +08:00
Persist slice of redux state in local storage
This commit is contained in:
parent
b1398742b9
commit
1df5004203
@ -26,7 +26,7 @@ import DoubleArrowIcon from "@material-ui/icons/DoubleArrow";
|
||||
import CloseIcon from "@material-ui/icons/Close";
|
||||
import { AppState } from "./store";
|
||||
import { paths } from "./paths";
|
||||
import { makeTheme } from "./theme";
|
||||
import { useTheme } from "./theme";
|
||||
import { closeSnackbar } from "./actions/snackbarActions";
|
||||
import ListItemLink from "./components/ListItemLink";
|
||||
import SchedulersView from "./views/SchedulersView";
|
||||
@ -146,7 +146,7 @@ function SlideUpTransition(props: TransitionProps) {
|
||||
}
|
||||
|
||||
function App(props: ConnectedProps<typeof connector>) {
|
||||
const theme = makeTheme(props.themePreference);
|
||||
const theme = useTheme(props.themePreference);
|
||||
const classes = useStyles(theme)();
|
||||
const [open, setOpen] = useState(true);
|
||||
const toggleDrawer = () => setOpen(!open);
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { ThemePreference } from "../reducers/settingsReducer";
|
||||
|
||||
// List of settings related action types.
|
||||
export const POLL_INTERVAL_CHANGE = "POLL_INTERVAL_CHANGE";
|
||||
export const THEME_PREFERENCE_CHANGE = "THEME_PREFERENCE_CHANGE";
|
||||
|
@ -5,6 +5,11 @@ import { Provider } from "react-redux";
|
||||
import App from "./App";
|
||||
import store from "./store";
|
||||
import * as serviceWorker from "./serviceWorker";
|
||||
import { saveState } from "./localStorage";
|
||||
|
||||
store.subscribe(() => {
|
||||
saveState(store.getState());
|
||||
});
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
|
24
ui/src/localStorage.ts
Normal file
24
ui/src/localStorage.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { AppState } from "./store";
|
||||
|
||||
const LOCAL_STORAGE_KEY = "asynqmon:state";
|
||||
|
||||
export function loadState(): AppState | undefined {
|
||||
try {
|
||||
const serializedState = localStorage.getItem(LOCAL_STORAGE_KEY);
|
||||
if (serializedState === null) {
|
||||
return undefined;
|
||||
}
|
||||
return JSON.parse(serializedState);
|
||||
} catch (err) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function saveState(state: AppState) {
|
||||
try {
|
||||
const serializedState = JSON.stringify({ settings: state.settings });
|
||||
localStorage.setItem(LOCAL_STORAGE_KEY, serializedState);
|
||||
} catch (err) {
|
||||
console.error("saveState: could not save state: ", err);
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ import schedulerEntriesReducer from "./reducers/schedulerEntriesReducer";
|
||||
import snackbarReducer from "./reducers/snackbarReducer";
|
||||
import queueStatsReducer from "./reducers/queueStatsReducer";
|
||||
import redisInfoReducer from "./reducers/redisInfoReducer";
|
||||
import { loadState } from "./localStorage";
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
settings: settingsReducer,
|
||||
@ -19,9 +20,14 @@ const rootReducer = combineReducers({
|
||||
redis: redisInfoReducer,
|
||||
});
|
||||
|
||||
const preloadedState = loadState();
|
||||
|
||||
// AppState is the top-level application state maintained by redux store.
|
||||
export type AppState = ReturnType<typeof rootReducer>;
|
||||
|
||||
export default configureStore({
|
||||
const store = configureStore({
|
||||
reducer: rootReducer,
|
||||
preloadedState,
|
||||
});
|
||||
|
||||
export default store;
|
||||
|
@ -2,8 +2,7 @@ import { createMuiTheme, Theme } from "@material-ui/core/styles";
|
||||
import { ThemePreference } from "./reducers/settingsReducer";
|
||||
import useMediaQuery from "@material-ui/core/useMediaQuery";
|
||||
|
||||
export function makeTheme(themePreference: ThemePreference): Theme {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
export function useTheme(themePreference: ThemePreference): Theme {
|
||||
let prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)");
|
||||
if (themePreference === ThemePreference.Always) {
|
||||
prefersDarkMode = true;
|
||||
|
@ -63,14 +63,14 @@ function SettingsView(props: PropsFromRedux) {
|
||||
props.selectTheme(event.target.value as ThemePreference);
|
||||
};
|
||||
return (
|
||||
<Container maxWidth="lg" className={classes.container}>
|
||||
<Container maxWidth="md" className={classes.container}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h5" color="textPrimary">
|
||||
Settings
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={5}>
|
||||
<Grid item xs={6}>
|
||||
<Paper className={classes.paper} variant="outlined">
|
||||
<Typography color="textPrimary">Polling Interval</Typography>
|
||||
<Typography gutterBottom color="textSecondary" variant="subtitle1">
|
||||
@ -93,22 +93,26 @@ function SettingsView(props: PropsFromRedux) {
|
||||
/>
|
||||
</Paper>
|
||||
</Grid>
|
||||
<FormControl variant="outlined" className={classes.formControl}>
|
||||
<InputLabel id="theme-label">Dark theme</InputLabel>
|
||||
<Select
|
||||
labelId="theme-label"
|
||||
id="theme-selected"
|
||||
value={props.themePreference}
|
||||
onChange={handleThemeChange}
|
||||
label="theme preference"
|
||||
>
|
||||
<MenuItem value={ThemePreference.SystemDefault}>
|
||||
System Default
|
||||
</MenuItem>
|
||||
<MenuItem value={ThemePreference.Always}>Always</MenuItem>
|
||||
<MenuItem value={ThemePreference.Never}>Never</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
<Grid item>
|
||||
<Paper className={classes.paper} variant="outlined">
|
||||
<FormControl variant="outlined" className={classes.formControl}>
|
||||
<InputLabel id="theme-label">Dark theme</InputLabel>
|
||||
<Select
|
||||
labelId="theme-label"
|
||||
id="theme-selected"
|
||||
value={props.themePreference}
|
||||
onChange={handleThemeChange}
|
||||
label="theme preference"
|
||||
>
|
||||
<MenuItem value={ThemePreference.SystemDefault}>
|
||||
System Default
|
||||
</MenuItem>
|
||||
<MenuItem value={ThemePreference.Always}>Always</MenuItem>
|
||||
<MenuItem value={ThemePreference.Never}>Never</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Paper>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Container>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user