Add support for settings (route and store).
parent
b46291f360
commit
43044750e3
|
@ -90,6 +90,8 @@ export const routeResolver = new RouteResolver({
|
||||||
},
|
},
|
||||||
new: 'new',
|
new: 'new',
|
||||||
},
|
},
|
||||||
|
settings: {
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const AppBarWitHistory = withRouter(
|
const AppBarWitHistory = withRouter(
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { History } from 'history';
|
||||||
|
|
||||||
|
import Select from '@material-ui/core/Select';
|
||||||
|
import MenuItem from '@material-ui/core/MenuItem';
|
||||||
|
import FormControl from '@material-ui/core/FormControl';
|
||||||
|
import InputLabel from '@material-ui/core/InputLabel';
|
||||||
|
|
||||||
|
import { store, StoreState, SettingsType } from '../store';
|
||||||
|
import { setSettings } from '../store/actions';
|
||||||
|
|
||||||
|
import Container from '../widgets/Container';
|
||||||
|
import AppBarOverride from '../widgets/AppBarOverride';
|
||||||
|
|
||||||
|
interface PropsType {
|
||||||
|
history: History;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface PropsTypeInner extends PropsType {
|
||||||
|
settings: SettingsType;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Settings extends React.PureComponent<PropsTypeInner> {
|
||||||
|
constructor(props: any) {
|
||||||
|
super(props);
|
||||||
|
this.onCancel = this.onCancel.bind(this);
|
||||||
|
this.handleChange = this.handleChange.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleChange(event: React.ChangeEvent<any>) {
|
||||||
|
const name = event.target.name;
|
||||||
|
const value = event.target.value;
|
||||||
|
|
||||||
|
const { settings } = this.props;
|
||||||
|
store.dispatch(setSettings({ ...settings, [name]: value}));
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { settings } = this.props;
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<AppBarOverride title="Settings" />
|
||||||
|
<Container>
|
||||||
|
<h1>Localization</h1>
|
||||||
|
<FormControl style={{width: '10em'}}>
|
||||||
|
<InputLabel>
|
||||||
|
Time & Date Style
|
||||||
|
</InputLabel>
|
||||||
|
<Select
|
||||||
|
name="locale"
|
||||||
|
value={settings.locale}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
>
|
||||||
|
<MenuItem value="en-gb">European</MenuItem>
|
||||||
|
<MenuItem value="en-us">American</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
</Container>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onCancel() {
|
||||||
|
this.props.history.goBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state: StoreState, props: PropsType) => {
|
||||||
|
return {
|
||||||
|
settings: state.settings,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps
|
||||||
|
)(Settings);
|
|
@ -5,6 +5,7 @@ import { List, ListItem, ListSubheader, ListDivider } from '../widgets/List';
|
||||||
import { Theme, withTheme } from '@material-ui/core/styles';
|
import { Theme, withTheme } from '@material-ui/core/styles';
|
||||||
import ActionCode from '@material-ui/icons/Code';
|
import ActionCode from '@material-ui/icons/Code';
|
||||||
import ActionHome from '@material-ui/icons/Home';
|
import ActionHome from '@material-ui/icons/Home';
|
||||||
|
import ActionSettings from '@material-ui/icons/Settings';
|
||||||
import ActionJournals from '@material-ui/icons/LibraryBooks';
|
import ActionJournals from '@material-ui/icons/LibraryBooks';
|
||||||
import ActionBugReport from '@material-ui/icons/BugReport';
|
import ActionBugReport from '@material-ui/icons/BugReport';
|
||||||
import ActionQuestionAnswer from '@material-ui/icons/QuestionAnswer';
|
import ActionQuestionAnswer from '@material-ui/icons/QuestionAnswer';
|
||||||
|
@ -59,6 +60,14 @@ class SideMenu extends React.PureComponent<PropsTypeInner> {
|
||||||
this.props.history.push(routeResolver.getRoute('journals'));
|
this.props.history.push(routeResolver.getRoute('journals'));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<ListItem
|
||||||
|
primaryText="Settings"
|
||||||
|
leftIcon={<ActionSettings />}
|
||||||
|
onClick={() => {
|
||||||
|
this.props.onCloseDrawerRequest();
|
||||||
|
this.props.history.push(routeResolver.getRoute('settings'));
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<ListItem primaryText="Log Out" leftIcon={<LogoutIcon/>} onClick={this.logout} />
|
<ListItem primaryText="Log Out" leftIcon={<LogoutIcon/>} onClick={this.logout} />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
|
|
|
@ -13,6 +13,7 @@ import LoadingIndicator from './widgets/LoadingIndicator';
|
||||||
import PrettyError from './widgets/PrettyError';
|
import PrettyError from './widgets/PrettyError';
|
||||||
|
|
||||||
import Journals from './Journals';
|
import Journals from './Journals';
|
||||||
|
import Settings from './Settings';
|
||||||
import Pim from './Pim';
|
import Pim from './Pim';
|
||||||
|
|
||||||
import * as EteSync from './api/EteSync';
|
import * as EteSync from './api/EteSync';
|
||||||
|
@ -218,6 +219,15 @@ class SyncGate extends React.PureComponent<PropsTypeInner> {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
path={routeResolver.getRoute('settings')}
|
||||||
|
exact={true}
|
||||||
|
render={({history}) => (
|
||||||
|
<Settings
|
||||||
|
history={history}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</Switch>
|
</Switch>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { createAction, createActions } from 'redux-actions';
|
||||||
import * as EteSync from '../api/EteSync';
|
import * as EteSync from '../api/EteSync';
|
||||||
import { UserInfo } from '../api/EteSync';
|
import { UserInfo } from '../api/EteSync';
|
||||||
|
|
||||||
import { CredentialsData, EntriesType, JournalsData } from './';
|
import { CredentialsData, EntriesType, JournalsData, SettingsType } from './';
|
||||||
|
|
||||||
export const { fetchCredentials, logout } = createActions({
|
export const { fetchCredentials, logout } = createActions({
|
||||||
FETCH_CREDENTIALS: (username: string, password: string, server: string) => {
|
FETCH_CREDENTIALS: (username: string, password: string, server: string) => {
|
||||||
|
@ -170,3 +170,11 @@ export function fetchAll(etesync: CredentialsData, currentEntries: EntriesType)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Move the rest to their own file
|
||||||
|
export const setSettings = createAction(
|
||||||
|
'SET_SETTINGS',
|
||||||
|
(settings: SettingsType) => {
|
||||||
|
return {...settings};
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { createLogger } from 'redux-logger';
|
||||||
import promiseMiddleware from './promise-middleware';
|
import promiseMiddleware from './promise-middleware';
|
||||||
|
|
||||||
import reducers from './reducers';
|
import reducers from './reducers';
|
||||||
import { CredentialsTypeRemote, JournalsType, EntriesType, UserInfoType } from './reducers';
|
import { CredentialsTypeRemote, JournalsType, EntriesType, UserInfoType, SettingsType } from './reducers';
|
||||||
|
|
||||||
// Workaround babel limitation
|
// Workaround babel limitation
|
||||||
export * from './reducers';
|
export * from './reducers';
|
||||||
|
@ -14,6 +14,7 @@ export * from './reducers';
|
||||||
export interface StoreState {
|
export interface StoreState {
|
||||||
fetchCount: number;
|
fetchCount: number;
|
||||||
credentials: CredentialsTypeRemote;
|
credentials: CredentialsTypeRemote;
|
||||||
|
settings: SettingsType;
|
||||||
encryptionKey: {key: string};
|
encryptionKey: {key: string};
|
||||||
cache: {
|
cache: {
|
||||||
journals: JournalsType;
|
journals: JournalsType;
|
||||||
|
|
|
@ -272,6 +272,25 @@ const fetchCount = handleAction(
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// FIXME Move all the below (potentially the fetchCount ones too) to their own file
|
||||||
|
export interface SettingsType {
|
||||||
|
locale: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const settingsReducer = handleActions(
|
||||||
|
{
|
||||||
|
[actions.setSettings.toString()]: (state: {key: string | null}, action: any) => (
|
||||||
|
{...action.payload}
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{ locale: 'en-gb' }
|
||||||
|
);
|
||||||
|
|
||||||
|
const settingsPersistConfig = {
|
||||||
|
key: 'settings',
|
||||||
|
storage: localforage,
|
||||||
|
};
|
||||||
|
|
||||||
const credentialsPersistConfig = {
|
const credentialsPersistConfig = {
|
||||||
key: 'credentials',
|
key: 'credentials',
|
||||||
storage: localforage,
|
storage: localforage,
|
||||||
|
@ -395,6 +414,7 @@ const cachePersistConfig = {
|
||||||
|
|
||||||
const reducers = combineReducers({
|
const reducers = combineReducers({
|
||||||
fetchCount,
|
fetchCount,
|
||||||
|
settings: persistReducer(settingsPersistConfig, settingsReducer),
|
||||||
credentials: persistReducer(credentialsPersistConfig, credentials),
|
credentials: persistReducer(credentialsPersistConfig, credentials),
|
||||||
encryptionKey: persistReducer(encryptionKeyPersistConfig, encryptionKeyReducer),
|
encryptionKey: persistReducer(encryptionKeyPersistConfig, encryptionKeyReducer),
|
||||||
cache: persistReducer(cachePersistConfig, combineReducers({
|
cache: persistReducer(cachePersistConfig, combineReducers({
|
||||||
|
|
Loading…
Reference in New Issue