Created settings page and reducers to handle real-time updates config

This commit is contained in:
Alejandro Celaya
2020-04-25 09:49:54 +02:00
parent 7516ca8dd9
commit 41f885d8ec
9 changed files with 131 additions and 18 deletions

View File

@@ -0,0 +1,31 @@
import React from 'react';
import { Card, CardBody, CardHeader, UncontrolledTooltip } from 'reactstrap';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faInfoCircle } from '@fortawesome/free-solid-svg-icons';
import Checkbox from '../utils/Checkbox';
import { RealTimeUpdatesType } from './reducers/realTimeUpdates';
const propTypes = {
realTimeUpdates: RealTimeUpdatesType,
setRealTimeUpdates: PropTypes.func,
};
const RealTimeUpdates = ({ realTimeUpdates, setRealTimeUpdates }) => (
<Card>
<CardHeader>Real-time updates</CardHeader>
<CardBody>
<Checkbox checked={realTimeUpdates.enabled} onChange={setRealTimeUpdates}>
Enable real-time updates
<FontAwesomeIcon icon={faInfoCircle} className="ml-2" id="realTimeUpdatesInfo" />
</Checkbox>
<UncontrolledTooltip target="realTimeUpdatesInfo">
Enable or disable real-time updates, when using Shlink v2.2.0 or newer.
</UncontrolledTooltip>
</CardBody>
</Card>
);
RealTimeUpdates.propTypes = propTypes;
export default RealTimeUpdates;

View File

@@ -1,6 +1,10 @@
import React from 'react';
import NoMenuLayout from '../common/NoMenuLayout';
const Settings = () => <NoMenuLayout>Settings</NoMenuLayout>;
const Settings = (RealTimeUpdates) => () => (
<NoMenuLayout>
<RealTimeUpdates />
</NoMenuLayout>
);
export default Settings;

View File

@@ -0,0 +1,32 @@
import { handleActions } from 'redux-actions';
import PropTypes from 'prop-types';
const LOAD_REAL_TIME_UPDATES = 'shlink/realTimeUpdates/LOAD_REAL_TIME_UPDATES';
export const RealTimeUpdatesType = PropTypes.shape({
enabled: PropTypes.bool.isRequired,
});
const initialState = {
enabled: true,
};
export default handleActions({
[LOAD_REAL_TIME_UPDATES]: (state, { enabled }) => ({ ...state, enabled }),
}, initialState);
export const setRealTimeUpdates = ({ updateSettings }, loadRealTimeUpdatesAction) => (enabled) => {
updateSettings({ realTimeUpdates: { enabled } });
return loadRealTimeUpdatesAction();
};
export const loadRealTimeUpdates = ({ loadSettings }) => () => {
const { realTimeUpdates = {} } = loadSettings();
const { enabled = true } = realTimeUpdates;
return {
type: LOAD_REAL_TIME_UPDATES,
enabled,
};
};

View File

@@ -0,0 +1,14 @@
const SETTINGS_STORAGE_KEY = 'settings';
export default class SettingsService {
constructor(storage) {
this.storage = storage;
}
loadSettings = () => this.storage.get(SETTINGS_STORAGE_KEY) || {};
updateSettings = (settingsToUpdate) => this.storage.set(SETTINGS_STORAGE_KEY, {
...this.loadSettings(),
...settingsToUpdate,
})
}

View File

@@ -0,0 +1,21 @@
import RealTimeUpdates from '../RealTimeUpdates';
import Settings from '../Settings';
import { loadRealTimeUpdates, setRealTimeUpdates } from '../reducers/realTimeUpdates';
import SettingsService from './SettingsService';
const provideServices = (bottle, connect) => {
// Components
bottle.serviceFactory('Settings', Settings, 'RealTimeUpdates');
bottle.serviceFactory('RealTimeUpdates', () => RealTimeUpdates);
bottle.decorator('RealTimeUpdates', connect([ 'realTimeUpdates' ], [ 'setRealTimeUpdates' ]));
// Services
bottle.service('SettingsService', SettingsService, 'Storage');
// Actions
bottle.serviceFactory('setRealTimeUpdates', setRealTimeUpdates, 'SettingsService', 'loadRealTimeUpdates');
bottle.serviceFactory('loadRealTimeUpdates', loadRealTimeUpdates, 'SettingsService');
};
export default provideServices;