Added option to customize initial state fo the 'Validate URL' option

This commit is contained in:
Alejandro Celaya
2021-02-14 13:23:42 +01:00
parent 872890e674
commit 4885088d59
8 changed files with 89 additions and 22 deletions

View File

@@ -1,9 +1,17 @@
import { FC } from 'react';
import { Row } from 'reactstrap';
import NoMenuLayout from '../common/NoMenuLayout';
const Settings = (RealTimeUpdates: FC) => () => (
const Settings = (RealTimeUpdates: FC, ShortUrlCreation: FC) => () => (
<NoMenuLayout>
<RealTimeUpdates />
<Row>
<div className="col-lg-6">
<RealTimeUpdates />
</div>
<div className="col-lg-6">
<ShortUrlCreation />
</div>
</Row>
</NoMenuLayout>
);

View File

@@ -0,0 +1,29 @@
import { FC } from 'react';
import { FormGroup } from 'reactstrap';
import { SimpleCard } from '../utils/SimpleCard';
import ToggleSwitch from '../utils/ToggleSwitch';
import { Settings, ShortUrlCreationSettings } from './reducers/settings';
interface ShortUrlCreationProps {
settings: Settings;
setShortUrlCreationSettings: (settings: ShortUrlCreationSettings) => void;
}
export const ShortUrlCreation: FC<ShortUrlCreationProps> = (
{ settings: { shortUrlCreation }, setShortUrlCreationSettings },
) => (
<SimpleCard title="Short URLs creation">
<FormGroup className="mb-0">
<ToggleSwitch
checked={shortUrlCreation?.validateUrls ?? false}
onChange={(validateUrls) => setShortUrlCreationSettings({ validateUrls })}
>
By default, request validation on long URLs when creating new short URLs.
<small className="form-text text-muted">
The initial state of the <b>Validate URL</b> checkbox will
be <b>{shortUrlCreation?.validateUrls ? 'checked' : 'unchecked'}</b>.
</small>
</ToggleSwitch>
</FormGroup>
</SimpleCard>
);

View File

@@ -1,23 +1,36 @@
import { Action } from 'redux';
import { mergeDeepRight } from 'ramda';
import { dissoc, mergeDeepRight } from 'ramda';
import { buildReducer } from '../../utils/helpers/redux';
import { RecursivePartial } from '../../utils/utils';
export const SET_REAL_TIME_UPDATES = 'shlink/realTimeUpdates/SET_REAL_TIME_UPDATES';
export const SET_SETTINGS = 'shlink/realTimeUpdates/SET_SETTINGS';
interface RealTimeUpdates {
/**
* Important! When adding new props in the main Settings interface or any of the nested props, they have to be set as
* optional, as old instances of the app will load partial objects from local storage until it is saved again.
*/
interface RealTimeUpdatesSettings {
enabled: boolean;
interval?: number;
}
export interface ShortUrlCreationSettings {
validateUrls: boolean;
}
export interface Settings {
realTimeUpdates: RealTimeUpdates;
realTimeUpdates: RealTimeUpdatesSettings;
shortUrlCreation?: ShortUrlCreationSettings;
}
const initialState: Settings = {
realTimeUpdates: {
enabled: true,
},
shortUrlCreation: {
validateUrls: false,
},
};
type SettingsAction = Action & Settings;
@@ -25,15 +38,20 @@ type SettingsAction = Action & Settings;
type PartialSettingsAction = Action & RecursivePartial<Settings>;
export default buildReducer<Settings, SettingsAction>({
[SET_REAL_TIME_UPDATES]: (state, { realTimeUpdates }) => mergeDeepRight(state, { realTimeUpdates }),
[SET_SETTINGS]: (state, action) => mergeDeepRight(state, dissoc('type', action)),
}, initialState);
export const toggleRealTimeUpdates = (enabled: boolean): PartialSettingsAction => ({
type: SET_REAL_TIME_UPDATES,
type: SET_SETTINGS,
realTimeUpdates: { enabled },
});
export const setRealTimeUpdatesInterval = (interval: number): PartialSettingsAction => ({
type: SET_REAL_TIME_UPDATES,
type: SET_SETTINGS,
realTimeUpdates: { interval },
});
export const setShortUrlCreationSettings = (settings: ShortUrlCreationSettings): PartialSettingsAction => ({
type: SET_SETTINGS,
shortUrlCreation: settings,
});

View File

@@ -1,26 +1,30 @@
import Bottle from 'bottlejs';
import RealTimeUpdates from '../RealTimeUpdates';
import Settings from '../Settings';
import { setRealTimeUpdatesInterval, toggleRealTimeUpdates } from '../reducers/settings';
import { setRealTimeUpdatesInterval, setShortUrlCreationSettings, toggleRealTimeUpdates } from '../reducers/settings';
import { ConnectDecorator } from '../../container/types';
import { withoutSelectedServer } from '../../servers/helpers/withoutSelectedServer';
import { ShortUrlCreation } from '../ShortUrlCreation';
const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
// Components
bottle.serviceFactory('Settings', Settings, 'RealTimeUpdates');
bottle.serviceFactory('Settings', Settings, 'RealTimeUpdates', 'ShortUrlCreation');
bottle.decorator('Settings', withoutSelectedServer);
bottle.decorator('Settings', connect(null, [ 'resetSelectedServer' ]));
// Services
bottle.serviceFactory('RealTimeUpdates', () => RealTimeUpdates);
bottle.decorator(
'RealTimeUpdates',
connect([ 'settings' ], [ 'toggleRealTimeUpdates', 'setRealTimeUpdatesInterval' ]),
);
bottle.serviceFactory('ShortUrlCreation', () => ShortUrlCreation);
bottle.decorator('ShortUrlCreation', connect([ 'settings' ], [ 'setShortUrlCreationSettings' ]));
// Actions
bottle.serviceFactory('toggleRealTimeUpdates', () => toggleRealTimeUpdates);
bottle.serviceFactory('setRealTimeUpdatesInterval', () => setRealTimeUpdatesInterval);
bottle.serviceFactory('setShortUrlCreationSettings', () => setShortUrlCreationSettings);
};
export default provideServices;