Created new settings card for tags-related options

This commit is contained in:
Alejandro Celaya
2021-12-23 17:53:06 +01:00
parent e77508edcc
commit 5598fe0f53
14 changed files with 121 additions and 58 deletions

View File

@@ -7,7 +7,7 @@ const SettingsSections: FC<{ items: ReactNode[][] }> = ({ items }) => (
{items.map((child, index) => (
<Row key={index}>
{child.map((subChild, subIndex) => (
<div key={subIndex} className="col-lg-6 mb-3">
<div key={subIndex} className={`col-lg-${12 / child.length} mb-3`}>
{subChild}
</div>
))}
@@ -16,12 +16,13 @@ const SettingsSections: FC<{ items: ReactNode[][] }> = ({ items }) => (
</>
);
const Settings = (RealTimeUpdates: FC, ShortUrlCreation: FC, UserInterface: FC, Visits: FC) => () => (
const Settings = (RealTimeUpdates: FC, ShortUrlCreation: FC, UserInterface: FC, Visits: FC, Tags: FC) => () => (
<NoMenuLayout>
<SettingsSections
items={[
[ <UserInterface />, <Visits /> ], // eslint-disable-line react/jsx-key
[ <UserInterface /> ], // eslint-disable-line react/jsx-key
[ <ShortUrlCreation />, <RealTimeUpdates /> ], // eslint-disable-line react/jsx-key
[ <Tags />, <Visits /> ], // eslint-disable-line react/jsx-key
]}
/>
</NoMenuLayout>

25
src/settings/Tags.tsx Normal file
View File

@@ -0,0 +1,25 @@
import { FC } from 'react';
import { FormGroup } from 'reactstrap';
import { SimpleCard } from '../utils/SimpleCard';
import { TagsModeDropdown } from '../tags/TagsModeDropdown';
import { capitalize } from '../utils/utils';
import { Settings, TagsSettings } from './reducers/settings';
interface TagsProps {
settings: Settings;
setTagsSettings: (settings: TagsSettings) => void;
}
export const Tags: FC<TagsProps> = ({ settings: { tags }, setTagsSettings }) => (
<SimpleCard title="Tags">
<FormGroup className="mb-0">
<label>Default display mode when managing tags:</label>
<TagsModeDropdown
mode={tags?.defaultMode ?? 'cards'}
renderTitle={(tagsMode) => capitalize(tagsMode)}
onChange={(defaultMode) => setTagsSettings({ ...tags, defaultMode })}
/>
<small className="form-text text-muted">Tags will be displayed as <b>{tags?.defaultMode ?? 'cards'}</b>.</small>
</FormGroup>
</SimpleCard>
);

View File

@@ -5,8 +5,6 @@ import { FormGroup } from 'reactstrap';
import { SimpleCard } from '../utils/SimpleCard';
import ToggleSwitch from '../utils/ToggleSwitch';
import { changeThemeInMarkup, Theme } from '../utils/theme';
import { TagsModeDropdown } from '../tags/TagsModeDropdown';
import { capitalize } from '../utils/utils';
import { Settings, UiSettings } from './reducers/settings';
import './UserInterface.scss';
@@ -31,14 +29,5 @@ export const UserInterface: FC<UserInterfaceProps> = ({ settings: { ui }, setUiS
Use dark theme.
</ToggleSwitch>
</FormGroup>
<FormGroup className="mb-0">
<label>Default display mode when managing tags:</label>
<TagsModeDropdown
mode={ui?.tagsMode ?? 'cards'}
renderTitle={(tagsMode) => capitalize(tagsMode)}
onChange={(tagsMode) => setUiSettings({ ...ui ?? { theme: 'light' }, tagsMode })}
/>
<small className="form-text text-muted">Tags will be displayed as <b>{ui?.tagsMode ?? 'cards'}</b>.</small>
</FormGroup>
</SimpleCard>
);

View File

@@ -0,0 +1,17 @@
import { ShlinkState } from '../../container/types';
export const migrateDeprecatedSettings = (state: ShlinkState): ShlinkState => {
// The "last180Days" interval had a typo, with a lowercase d
if ((state.settings.visits?.defaultInterval as any) === 'last180days') {
state.settings.visits && (state.settings.visits.defaultInterval = 'last180Days');
}
// The "tags display mode" option has been moved from "ui" to "tags"
state.settings.tags = {
...state.settings.tags,
defaultMode: state.settings.tags?.defaultMode ?? (state.settings.ui as any)?.tagsMode,
};
state.settings.ui && delete (state.settings.ui as any).tagsMode;
return state;
};

View File

@@ -4,6 +4,7 @@ import { buildReducer } from '../../utils/helpers/redux';
import { RecursivePartial } from '../../utils/utils';
import { Theme } from '../../utils/theme';
import { DateInterval } from '../../utils/dates/types';
import { TagsOrder } from '../../tags/data/TagsListChildrenProps';
export const SET_SETTINGS = 'shlink/realTimeUpdates/SET_SETTINGS';
@@ -29,18 +30,23 @@ export type TagsMode = 'cards' | 'list';
export interface UiSettings {
theme: Theme;
tagsMode?: TagsMode;
}
export interface VisitsSettings {
defaultInterval: DateInterval;
}
export interface TagsSettings {
defaultOrdering?: TagsOrder;
defaultMode?: TagsMode;
}
export interface Settings {
realTimeUpdates: RealTimeUpdatesSettings;
shortUrlCreation?: ShortUrlCreationSettings;
ui?: UiSettings;
visits?: VisitsSettings;
tags?: TagsSettings;
}
const initialState: Settings = {
@@ -90,3 +96,8 @@ export const setVisitsSettings = (settings: VisitsSettings): PartialSettingsActi
type: SET_SETTINGS,
visits: settings,
});
export const setTagsSettings = (settings: TagsSettings): PartialSettingsAction => ({
type: SET_SETTINGS,
tags: settings,
});

View File

@@ -4,6 +4,7 @@ import Settings from '../Settings';
import {
setRealTimeUpdatesInterval,
setShortUrlCreationSettings,
setTagsSettings,
setUiSettings,
setVisitsSettings,
toggleRealTimeUpdates,
@@ -13,10 +14,11 @@ import { withoutSelectedServer } from '../../servers/helpers/withoutSelectedServ
import { ShortUrlCreation } from '../ShortUrlCreation';
import { UserInterface } from '../UserInterface';
import { Visits } from '../Visits';
import { Tags } from '../Tags';
const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
// Components
bottle.serviceFactory('Settings', Settings, 'RealTimeUpdates', 'ShortUrlCreation', 'UserInterface', 'Visits');
bottle.serviceFactory('Settings', Settings, 'RealTimeUpdates', 'ShortUrlCreation', 'UserInterface', 'Visits', 'Tags');
bottle.decorator('Settings', withoutSelectedServer);
bottle.decorator('Settings', connect(null, [ 'resetSelectedServer' ]));
@@ -35,12 +37,16 @@ const provideServices = (bottle: Bottle, connect: ConnectDecorator) => {
bottle.serviceFactory('Visits', () => Visits);
bottle.decorator('Visits', connect([ 'settings' ], [ 'setVisitsSettings' ]));
bottle.serviceFactory('Tags', () => Tags);
bottle.decorator('Tags', connect([ 'settings' ], [ 'setTagsSettings' ]));
// Actions
bottle.serviceFactory('toggleRealTimeUpdates', () => toggleRealTimeUpdates);
bottle.serviceFactory('setRealTimeUpdatesInterval', () => setRealTimeUpdatesInterval);
bottle.serviceFactory('setShortUrlCreationSettings', () => setShortUrlCreationSettings);
bottle.serviceFactory('setUiSettings', () => setUiSettings);
bottle.serviceFactory('setVisitsSettings', () => setVisitsSettings);
bottle.serviceFactory('setTagsSettings', () => setTagsSettings);
};
export default provideServices;