Add support for settings (route and store).

master
Tom Hacohen 6 years ago
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…
Cancel
Save