mirror of
https://github.com/Radarr/Radarr
synced 2025-12-06 16:32:36 +01:00
Convert SettingsToolbar to TypeScript
(cherry picked from commit fd09ca6e719a96f760006ed0f08756faa20b6f75)
This commit is contained in:
parent
187dd79b9c
commit
e6980df590
30 changed files with 323 additions and 546 deletions
|
|
@ -16,10 +16,10 @@ const BUTTON_WIDTH = parseInt(dimensions.toolbarButtonWidth);
|
||||||
const SEPARATOR_MARGIN = parseInt(dimensions.toolbarSeparatorMargin);
|
const SEPARATOR_MARGIN = parseInt(dimensions.toolbarSeparatorMargin);
|
||||||
const SEPARATOR_WIDTH = 2 * SEPARATOR_MARGIN + 1;
|
const SEPARATOR_WIDTH = 2 * SEPARATOR_MARGIN + 1;
|
||||||
|
|
||||||
interface PageToolbarSectionProps {
|
export interface PageToolbarSectionProps {
|
||||||
children?:
|
children?:
|
||||||
| (ReactElement<PageToolbarButtonProps> | ReactElement<never>)
|
| (ReactElement<PageToolbarButtonProps> | ReactElement<never> | null)
|
||||||
| (ReactElement<PageToolbarButtonProps> | ReactElement<never>)[];
|
| (ReactElement<PageToolbarButtonProps> | ReactElement<never> | null)[];
|
||||||
alignContent?: Extract<Align, keyof typeof styles>;
|
alignContent?: Extract<Align, keyof typeof styles>;
|
||||||
collapseButtons?: boolean;
|
collapseButtons?: boolean;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
import classNames from 'classnames';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
import Icon from 'Components/Icon';
|
|
||||||
import Link from 'Components/Link/Link';
|
|
||||||
import { icons } from 'Helpers/Props';
|
|
||||||
import translate from 'Utilities/String/translate';
|
|
||||||
import styles from './AdvancedSettingsButton.css';
|
|
||||||
|
|
||||||
function AdvancedSettingsButton(props) {
|
|
||||||
const {
|
|
||||||
advancedSettings,
|
|
||||||
onAdvancedSettingsPress,
|
|
||||||
showLabel
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Link
|
|
||||||
className={styles.button}
|
|
||||||
title={advancedSettings ? translate('ShownClickToHide') : translate('HiddenClickToShow')}
|
|
||||||
onPress={onAdvancedSettingsPress}
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
name={icons.ADVANCED_SETTINGS}
|
|
||||||
size={21}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span
|
|
||||||
className={classNames(
|
|
||||||
styles.indicatorContainer,
|
|
||||||
'fa-layers fa-fw'
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Icon
|
|
||||||
className={styles.indicatorBackground}
|
|
||||||
name={icons.CIRCLE}
|
|
||||||
size={16}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Icon
|
|
||||||
className={advancedSettings ? styles.enabled : styles.disabled}
|
|
||||||
name={advancedSettings ? icons.CHECK : icons.CLOSE}
|
|
||||||
size={10}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
{
|
|
||||||
showLabel ?
|
|
||||||
<div className={styles.labelContainer}>
|
|
||||||
<div className={styles.label}>
|
|
||||||
{advancedSettings ? translate('HideAdvanced') : translate('ShowAdvanced')}
|
|
||||||
</div>
|
|
||||||
</div> :
|
|
||||||
null
|
|
||||||
}
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
AdvancedSettingsButton.propTypes = {
|
|
||||||
advancedSettings: PropTypes.bool.isRequired,
|
|
||||||
onAdvancedSettingsPress: PropTypes.func.isRequired,
|
|
||||||
showLabel: PropTypes.bool.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
AdvancedSettingsButton.defaultProps = {
|
|
||||||
showLabel: true
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AdvancedSettingsButton;
|
|
||||||
67
frontend/src/Settings/AdvancedSettingsButton.tsx
Normal file
67
frontend/src/Settings/AdvancedSettingsButton.tsx
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import React, { useCallback } from 'react';
|
||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
import AppState from 'App/State/AppState';
|
||||||
|
import Icon from 'Components/Icon';
|
||||||
|
import Link from 'Components/Link/Link';
|
||||||
|
import { icons } from 'Helpers/Props';
|
||||||
|
import { toggleAdvancedSettings } from 'Store/Actions/settingsActions';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
|
import styles from './AdvancedSettingsButton.css';
|
||||||
|
|
||||||
|
interface AdvancedSettingsButtonProps {
|
||||||
|
showLabel: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function AdvancedSettingsButton({ showLabel }: AdvancedSettingsButtonProps) {
|
||||||
|
const showAdvancedSettings = useSelector(
|
||||||
|
(state: AppState) => state.settings.advancedSettings
|
||||||
|
);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const handlePress = useCallback(() => {
|
||||||
|
dispatch(toggleAdvancedSettings());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
className={styles.button}
|
||||||
|
title={
|
||||||
|
showAdvancedSettings
|
||||||
|
? translate('ShownClickToHide')
|
||||||
|
: translate('HiddenClickToShow')
|
||||||
|
}
|
||||||
|
onPress={handlePress}
|
||||||
|
>
|
||||||
|
<Icon name={icons.ADVANCED_SETTINGS} size={21} />
|
||||||
|
|
||||||
|
<span
|
||||||
|
className={classNames(styles.indicatorContainer, 'fa-layers fa-fw')}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
className={styles.indicatorBackground}
|
||||||
|
name={icons.CIRCLE}
|
||||||
|
size={16}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
className={showAdvancedSettings ? styles.enabled : styles.disabled}
|
||||||
|
name={showAdvancedSettings ? icons.CHECK : icons.CLOSE}
|
||||||
|
size={10}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{showLabel ? (
|
||||||
|
<div className={styles.labelContainer}>
|
||||||
|
<div className={styles.label}>
|
||||||
|
{showAdvancedSettings
|
||||||
|
? translate('HideAdvanced')
|
||||||
|
: translate('ShowAdvanced')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AdvancedSettingsButton;
|
||||||
|
|
@ -5,7 +5,7 @@ import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||||
import ParseToolbarButton from 'Parse/ParseToolbarButton';
|
import ParseToolbarButton from 'Parse/ParseToolbarButton';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbar from 'Settings/SettingsToolbar';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import CustomFormatsConnector from './CustomFormats/CustomFormatsConnector';
|
import CustomFormatsConnector from './CustomFormats/CustomFormatsConnector';
|
||||||
import ManageCustomFormatsToolbarButton from './CustomFormats/Manage/ManageCustomFormatsToolbarButton';
|
import ManageCustomFormatsToolbarButton from './CustomFormats/Manage/ManageCustomFormatsToolbarButton';
|
||||||
|
|
@ -13,9 +13,7 @@ import ManageCustomFormatsToolbarButton from './CustomFormats/Manage/ManageCusto
|
||||||
function CustomFormatSettingsPage() {
|
function CustomFormatSettingsPage() {
|
||||||
return (
|
return (
|
||||||
<PageContent title={translate('CustomFormatsSettings')}>
|
<PageContent title={translate('CustomFormatsSettings')}>
|
||||||
<SettingsToolbarConnector
|
<SettingsToolbar
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
showSave={false}
|
showSave={false}
|
||||||
additionalButtons={
|
additionalButtons={
|
||||||
<>
|
<>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
||||||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||||
import { icons } from 'Helpers/Props';
|
import { icons } from 'Helpers/Props';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbar from 'Settings/SettingsToolbar';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import DownloadClientsConnector from './DownloadClients/DownloadClientsConnector';
|
import DownloadClientsConnector from './DownloadClients/DownloadClientsConnector';
|
||||||
import ManageDownloadClientsModal from './DownloadClients/Manage/ManageDownloadClientsModal';
|
import ManageDownloadClientsModal from './DownloadClients/Manage/ManageDownloadClientsModal';
|
||||||
|
|
@ -71,7 +71,7 @@ class DownloadClientSettings extends Component {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContent title={translate('DownloadClientSettings')}>
|
<PageContent title={translate('DownloadClientSettings')}>
|
||||||
<SettingsToolbarConnector
|
<SettingsToolbar
|
||||||
isSaving={isSaving}
|
isSaving={isSaving}
|
||||||
hasPendingChanges={hasPendingChanges}
|
hasPendingChanges={hasPendingChanges}
|
||||||
additionalButtons={
|
additionalButtons={
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ class EditDownloadClientModalContent extends Component {
|
||||||
onModalClose,
|
onModalClose,
|
||||||
onSavePress,
|
onSavePress,
|
||||||
onTestPress,
|
onTestPress,
|
||||||
onAdvancedSettingsPress,
|
|
||||||
onDeleteDownloadClientPress,
|
onDeleteDownloadClientPress,
|
||||||
...otherProps
|
...otherProps
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
@ -198,8 +197,6 @@ class EditDownloadClientModalContent extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
<AdvancedSettingsButton
|
<AdvancedSettingsButton
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
onAdvancedSettingsPress={onAdvancedSettingsPress}
|
|
||||||
showLabel={false}
|
showLabel={false}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -243,7 +240,6 @@ EditDownloadClientModalContent.propTypes = {
|
||||||
onModalClose: PropTypes.func.isRequired,
|
onModalClose: PropTypes.func.isRequired,
|
||||||
onSavePress: PropTypes.func.isRequired,
|
onSavePress: PropTypes.func.isRequired,
|
||||||
onTestPress: PropTypes.func.isRequired,
|
onTestPress: PropTypes.func.isRequired,
|
||||||
onAdvancedSettingsPress: PropTypes.func.isRequired,
|
|
||||||
onDeleteDownloadClientPress: PropTypes.func
|
onDeleteDownloadClientPress: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@ import {
|
||||||
saveDownloadClient,
|
saveDownloadClient,
|
||||||
setDownloadClientFieldValue,
|
setDownloadClientFieldValue,
|
||||||
setDownloadClientValue,
|
setDownloadClientValue,
|
||||||
testDownloadClient,
|
testDownloadClient
|
||||||
toggleAdvancedSettings
|
|
||||||
} from 'Store/Actions/settingsActions';
|
} from 'Store/Actions/settingsActions';
|
||||||
import createProviderSettingsSelector from 'Store/Selectors/createProviderSettingsSelector';
|
import createProviderSettingsSelector from 'Store/Selectors/createProviderSettingsSelector';
|
||||||
import EditDownloadClientModalContent from './EditDownloadClientModalContent';
|
import EditDownloadClientModalContent from './EditDownloadClientModalContent';
|
||||||
|
|
@ -29,8 +28,7 @@ const mapDispatchToProps = {
|
||||||
setDownloadClientValue,
|
setDownloadClientValue,
|
||||||
setDownloadClientFieldValue,
|
setDownloadClientFieldValue,
|
||||||
saveDownloadClient,
|
saveDownloadClient,
|
||||||
testDownloadClient,
|
testDownloadClient
|
||||||
toggleAdvancedSettings
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EditDownloadClientModalContentConnector extends Component {
|
class EditDownloadClientModalContentConnector extends Component {
|
||||||
|
|
@ -63,10 +61,6 @@ class EditDownloadClientModalContentConnector extends Component {
|
||||||
this.props.testDownloadClient({ id: this.props.id });
|
this.props.testDownloadClient({ id: this.props.id });
|
||||||
};
|
};
|
||||||
|
|
||||||
onAdvancedSettingsPress = () => {
|
|
||||||
this.props.toggleAdvancedSettings();
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Render
|
// Render
|
||||||
|
|
||||||
|
|
@ -76,7 +70,6 @@ class EditDownloadClientModalContentConnector extends Component {
|
||||||
{...this.props}
|
{...this.props}
|
||||||
onSavePress={this.onSavePress}
|
onSavePress={this.onSavePress}
|
||||||
onTestPress={this.onTestPress}
|
onTestPress={this.onTestPress}
|
||||||
onAdvancedSettingsPress={this.onAdvancedSettingsPress}
|
|
||||||
onInputChange={this.onInputChange}
|
onInputChange={this.onInputChange}
|
||||||
onFieldChange={this.onFieldChange}
|
onFieldChange={this.onFieldChange}
|
||||||
/>
|
/>
|
||||||
|
|
@ -94,7 +87,6 @@ EditDownloadClientModalContentConnector.propTypes = {
|
||||||
setDownloadClientFieldValue: PropTypes.func.isRequired,
|
setDownloadClientFieldValue: PropTypes.func.isRequired,
|
||||||
saveDownloadClient: PropTypes.func.isRequired,
|
saveDownloadClient: PropTypes.func.isRequired,
|
||||||
testDownloadClient: PropTypes.func.isRequired,
|
testDownloadClient: PropTypes.func.isRequired,
|
||||||
toggleAdvancedSettings: PropTypes.func.isRequired,
|
|
||||||
onModalClose: PropTypes.func.isRequired
|
onModalClose: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import { kinds } from 'Helpers/Props';
|
import { kinds } from 'Helpers/Props';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbar from 'Settings/SettingsToolbar';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import AnalyticSettings from './AnalyticSettings';
|
import AnalyticSettings from './AnalyticSettings';
|
||||||
import BackupSettings from './BackupSettings';
|
import BackupSettings from './BackupSettings';
|
||||||
|
|
@ -113,7 +113,7 @@ class GeneralSettings extends Component {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContent title={translate('GeneralSettings')}>
|
<PageContent title={translate('GeneralSettings')}>
|
||||||
<SettingsToolbarConnector
|
<SettingsToolbar
|
||||||
{...otherProps}
|
{...otherProps}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
||||||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||||
import { icons } from 'Helpers/Props';
|
import { icons } from 'Helpers/Props';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbar from 'Settings/SettingsToolbar';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import ImportListExclusions from './ImportListExclusions/ImportListExclusions';
|
import ImportListExclusions from './ImportListExclusions/ImportListExclusions';
|
||||||
import ImportListsConnector from './ImportLists/ImportListsConnector';
|
import ImportListsConnector from './ImportLists/ImportListsConnector';
|
||||||
|
|
@ -71,7 +71,7 @@ class ImportListSettings extends Component {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContent title={translate('ImportListSettings')}>
|
<PageContent title={translate('ImportListSettings')}>
|
||||||
<SettingsToolbarConnector
|
<SettingsToolbar
|
||||||
isSaving={isSaving}
|
isSaving={isSaving}
|
||||||
hasPendingChanges={hasPendingChanges}
|
hasPendingChanges={hasPendingChanges}
|
||||||
additionalButtons={
|
additionalButtons={
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ function EditImportListModalContent(props) {
|
||||||
onModalClose,
|
onModalClose,
|
||||||
onSavePress,
|
onSavePress,
|
||||||
onTestPress,
|
onTestPress,
|
||||||
onAdvancedSettingsPress,
|
|
||||||
onDeleteImportListPress,
|
onDeleteImportListPress,
|
||||||
...otherProps
|
...otherProps
|
||||||
} = props;
|
} = props;
|
||||||
|
|
@ -258,7 +257,6 @@ function EditImportListModalContent(props) {
|
||||||
|
|
||||||
<AdvancedSettingsButton
|
<AdvancedSettingsButton
|
||||||
advancedSettings={advancedSettings}
|
advancedSettings={advancedSettings}
|
||||||
onAdvancedSettingsPress={onAdvancedSettingsPress}
|
|
||||||
showLabel={false}
|
showLabel={false}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -301,7 +299,6 @@ EditImportListModalContent.propTypes = {
|
||||||
onModalClose: PropTypes.func.isRequired,
|
onModalClose: PropTypes.func.isRequired,
|
||||||
onSavePress: PropTypes.func.isRequired,
|
onSavePress: PropTypes.func.isRequired,
|
||||||
onTestPress: PropTypes.func.isRequired,
|
onTestPress: PropTypes.func.isRequired,
|
||||||
onAdvancedSettingsPress: PropTypes.func.isRequired,
|
|
||||||
onDeleteImportListPress: PropTypes.func
|
onDeleteImportListPress: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@ import {
|
||||||
saveImportList,
|
saveImportList,
|
||||||
setImportListFieldValue,
|
setImportListFieldValue,
|
||||||
setImportListValue,
|
setImportListValue,
|
||||||
testImportList,
|
testImportList
|
||||||
toggleAdvancedSettings
|
|
||||||
} from 'Store/Actions/settingsActions';
|
} from 'Store/Actions/settingsActions';
|
||||||
import createProviderSettingsSelector from 'Store/Selectors/createProviderSettingsSelector';
|
import createProviderSettingsSelector from 'Store/Selectors/createProviderSettingsSelector';
|
||||||
import EditImportListModalContent from './EditImportListModalContent';
|
import EditImportListModalContent from './EditImportListModalContent';
|
||||||
|
|
@ -29,8 +28,7 @@ const mapDispatchToProps = {
|
||||||
setImportListValue,
|
setImportListValue,
|
||||||
setImportListFieldValue,
|
setImportListFieldValue,
|
||||||
saveImportList,
|
saveImportList,
|
||||||
testImportList,
|
testImportList
|
||||||
toggleAdvancedSettings
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EditImportListModalContentConnector extends Component {
|
class EditImportListModalContentConnector extends Component {
|
||||||
|
|
@ -63,10 +61,6 @@ class EditImportListModalContentConnector extends Component {
|
||||||
this.props.testImportList({ id: this.props.id });
|
this.props.testImportList({ id: this.props.id });
|
||||||
};
|
};
|
||||||
|
|
||||||
onAdvancedSettingsPress = () => {
|
|
||||||
this.props.toggleAdvancedSettings();
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Render
|
// Render
|
||||||
|
|
||||||
|
|
@ -76,7 +70,6 @@ class EditImportListModalContentConnector extends Component {
|
||||||
{...this.props}
|
{...this.props}
|
||||||
onSavePress={this.onSavePress}
|
onSavePress={this.onSavePress}
|
||||||
onTestPress={this.onTestPress}
|
onTestPress={this.onTestPress}
|
||||||
onAdvancedSettingsPress={this.onAdvancedSettingsPress}
|
|
||||||
onInputChange={this.onInputChange}
|
onInputChange={this.onInputChange}
|
||||||
onFieldChange={this.onFieldChange}
|
onFieldChange={this.onFieldChange}
|
||||||
/>
|
/>
|
||||||
|
|
@ -94,7 +87,6 @@ EditImportListModalContentConnector.propTypes = {
|
||||||
setImportListFieldValue: PropTypes.func.isRequired,
|
setImportListFieldValue: PropTypes.func.isRequired,
|
||||||
saveImportList: PropTypes.func.isRequired,
|
saveImportList: PropTypes.func.isRequired,
|
||||||
testImportList: PropTypes.func.isRequired,
|
testImportList: PropTypes.func.isRequired,
|
||||||
toggleAdvancedSettings: PropTypes.func.isRequired,
|
|
||||||
onModalClose: PropTypes.func.isRequired
|
onModalClose: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
||||||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||||
import { icons } from 'Helpers/Props';
|
import { icons } from 'Helpers/Props';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbar from 'Settings/SettingsToolbar';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import IndexersConnector from './Indexers/IndexersConnector';
|
import IndexersConnector from './Indexers/IndexersConnector';
|
||||||
import ManageIndexersModal from './Indexers/Manage/ManageIndexersModal';
|
import ManageIndexersModal from './Indexers/Manage/ManageIndexersModal';
|
||||||
|
|
@ -70,7 +70,7 @@ class IndexerSettings extends Component {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContent title={translate('IndexerSettings')}>
|
<PageContent title={translate('IndexerSettings')}>
|
||||||
<SettingsToolbarConnector
|
<SettingsToolbar
|
||||||
isSaving={isSaving}
|
isSaving={isSaving}
|
||||||
hasPendingChanges={hasPendingChanges}
|
hasPendingChanges={hasPendingChanges}
|
||||||
additionalButtons={
|
additionalButtons={
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ function EditIndexerModalContent(props) {
|
||||||
onSavePress,
|
onSavePress,
|
||||||
onTestPress,
|
onTestPress,
|
||||||
onDeleteIndexerPress,
|
onDeleteIndexerPress,
|
||||||
onAdvancedSettingsPress,
|
|
||||||
...otherProps
|
...otherProps
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
|
@ -204,8 +203,6 @@ function EditIndexerModalContent(props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
<AdvancedSettingsButton
|
<AdvancedSettingsButton
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
onAdvancedSettingsPress={onAdvancedSettingsPress}
|
|
||||||
showLabel={false}
|
showLabel={false}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -248,7 +245,6 @@ EditIndexerModalContent.propTypes = {
|
||||||
onModalClose: PropTypes.func.isRequired,
|
onModalClose: PropTypes.func.isRequired,
|
||||||
onSavePress: PropTypes.func.isRequired,
|
onSavePress: PropTypes.func.isRequired,
|
||||||
onTestPress: PropTypes.func.isRequired,
|
onTestPress: PropTypes.func.isRequired,
|
||||||
onAdvancedSettingsPress: PropTypes.func.isRequired,
|
|
||||||
onDeleteIndexerPress: PropTypes.func
|
onDeleteIndexerPress: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import { saveIndexer, setIndexerFieldValue, setIndexerValue, testIndexer, toggleAdvancedSettings } from 'Store/Actions/settingsActions';
|
import { saveIndexer, setIndexerFieldValue, setIndexerValue, testIndexer } from 'Store/Actions/settingsActions';
|
||||||
import createProviderSettingsSelector from 'Store/Selectors/createProviderSettingsSelector';
|
import createProviderSettingsSelector from 'Store/Selectors/createProviderSettingsSelector';
|
||||||
import EditIndexerModalContent from './EditIndexerModalContent';
|
import EditIndexerModalContent from './EditIndexerModalContent';
|
||||||
|
|
||||||
|
|
@ -23,8 +23,7 @@ const mapDispatchToProps = {
|
||||||
setIndexerValue,
|
setIndexerValue,
|
||||||
setIndexerFieldValue,
|
setIndexerFieldValue,
|
||||||
saveIndexer,
|
saveIndexer,
|
||||||
testIndexer,
|
testIndexer
|
||||||
toggleAdvancedSettings
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EditIndexerModalContentConnector extends Component {
|
class EditIndexerModalContentConnector extends Component {
|
||||||
|
|
@ -57,10 +56,6 @@ class EditIndexerModalContentConnector extends Component {
|
||||||
this.props.testIndexer({ id: this.props.id });
|
this.props.testIndexer({ id: this.props.id });
|
||||||
};
|
};
|
||||||
|
|
||||||
onAdvancedSettingsPress = () => {
|
|
||||||
this.props.toggleAdvancedSettings();
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Render
|
// Render
|
||||||
|
|
||||||
|
|
@ -70,7 +65,6 @@ class EditIndexerModalContentConnector extends Component {
|
||||||
{...this.props}
|
{...this.props}
|
||||||
onSavePress={this.onSavePress}
|
onSavePress={this.onSavePress}
|
||||||
onTestPress={this.onTestPress}
|
onTestPress={this.onTestPress}
|
||||||
onAdvancedSettingsPress={this.onAdvancedSettingsPress}
|
|
||||||
onInputChange={this.onInputChange}
|
onInputChange={this.onInputChange}
|
||||||
onFieldChange={this.onFieldChange}
|
onFieldChange={this.onFieldChange}
|
||||||
/>
|
/>
|
||||||
|
|
@ -86,7 +80,6 @@ EditIndexerModalContentConnector.propTypes = {
|
||||||
item: PropTypes.object.isRequired,
|
item: PropTypes.object.isRequired,
|
||||||
setIndexerValue: PropTypes.func.isRequired,
|
setIndexerValue: PropTypes.func.isRequired,
|
||||||
setIndexerFieldValue: PropTypes.func.isRequired,
|
setIndexerFieldValue: PropTypes.func.isRequired,
|
||||||
toggleAdvancedSettings: PropTypes.func.isRequired,
|
|
||||||
saveIndexer: PropTypes.func.isRequired,
|
saveIndexer: PropTypes.func.isRequired,
|
||||||
testIndexer: PropTypes.func.isRequired,
|
testIndexer: PropTypes.func.isRequired,
|
||||||
onModalClose: PropTypes.func.isRequired
|
onModalClose: PropTypes.func.isRequired
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import { inputTypes, kinds, sizes } from 'Helpers/Props';
|
import { inputTypes, kinds, sizes } from 'Helpers/Props';
|
||||||
import RootFolders from 'RootFolder/RootFolders';
|
import RootFolders from 'RootFolder/RootFolders';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbar from 'Settings/SettingsToolbar';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import Naming from './Naming/Naming';
|
import Naming from './Naming/Naming';
|
||||||
import AddRootFolder from './RootFolder/AddRootFolder';
|
import AddRootFolder from './RootFolder/AddRootFolder';
|
||||||
|
|
@ -99,7 +99,7 @@ class MediaManagement extends Component {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContent title={translate('MediaManagementSettings')}>
|
<PageContent title={translate('MediaManagementSettings')}>
|
||||||
<SettingsToolbarConnector
|
<SettingsToolbar
|
||||||
advancedSettings={advancedSettings}
|
advancedSettings={advancedSettings}
|
||||||
{...otherProps}
|
{...otherProps}
|
||||||
onSavePress={onSavePress}
|
onSavePress={onSavePress}
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ function Naming() {
|
||||||
dispatch(fetchNamingExamples());
|
dispatch(fetchNamingExamples());
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
dispatch(clearPendingChanges({ section: SECTION }));
|
dispatch(clearPendingChanges({ section: 'settings.naming' }));
|
||||||
};
|
};
|
||||||
}, [dispatch]);
|
}, [dispatch]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbar from 'Settings/SettingsToolbar';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import Metadatas from './Metadata/Metadatas';
|
import Metadatas from './Metadata/Metadatas';
|
||||||
import MetadataOptionsConnector from './Options/MetadataOptionsConnector';
|
import MetadataOptionsConnector from './Options/MetadataOptionsConnector';
|
||||||
|
|
@ -50,7 +50,7 @@ class MetadataSettings extends Component {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContent title={translate('MetadataSettings')}>
|
<PageContent title={translate('MetadataSettings')}>
|
||||||
<SettingsToolbarConnector
|
<SettingsToolbar
|
||||||
isSaving={isSaving}
|
isSaving={isSaving}
|
||||||
hasPendingChanges={hasPendingChanges}
|
hasPendingChanges={hasPendingChanges}
|
||||||
onSavePress={this.onSavePress}
|
onSavePress={this.onSavePress}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbar from 'Settings/SettingsToolbar';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import NotificationsConnector from './Notifications/NotificationsConnector';
|
import NotificationsConnector from './Notifications/NotificationsConnector';
|
||||||
|
|
||||||
function NotificationSettings() {
|
function NotificationSettings() {
|
||||||
return (
|
return (
|
||||||
<PageContent title={translate('ConnectSettings')}>
|
<PageContent title={translate('ConnectSettings')}>
|
||||||
<SettingsToolbarConnector
|
<SettingsToolbar
|
||||||
showSave={false}
|
showSave={false}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,6 @@ function EditNotificationModalContent(props) {
|
||||||
onModalClose,
|
onModalClose,
|
||||||
onSavePress,
|
onSavePress,
|
||||||
onTestPress,
|
onTestPress,
|
||||||
onAdvancedSettingsPress,
|
|
||||||
onDeleteNotificationPress,
|
onDeleteNotificationPress,
|
||||||
...otherProps
|
...otherProps
|
||||||
} = props;
|
} = props;
|
||||||
|
|
@ -139,8 +138,6 @@ function EditNotificationModalContent(props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
<AdvancedSettingsButton
|
<AdvancedSettingsButton
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
onAdvancedSettingsPress={onAdvancedSettingsPress}
|
|
||||||
showLabel={false}
|
showLabel={false}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -183,7 +180,6 @@ EditNotificationModalContent.propTypes = {
|
||||||
onModalClose: PropTypes.func.isRequired,
|
onModalClose: PropTypes.func.isRequired,
|
||||||
onSavePress: PropTypes.func.isRequired,
|
onSavePress: PropTypes.func.isRequired,
|
||||||
onTestPress: PropTypes.func.isRequired,
|
onTestPress: PropTypes.func.isRequired,
|
||||||
onAdvancedSettingsPress: PropTypes.func.isRequired,
|
|
||||||
onDeleteNotificationPress: PropTypes.func
|
onDeleteNotificationPress: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@ import {
|
||||||
saveNotification,
|
saveNotification,
|
||||||
setNotificationFieldValues,
|
setNotificationFieldValues,
|
||||||
setNotificationValue,
|
setNotificationValue,
|
||||||
testNotification,
|
testNotification
|
||||||
toggleAdvancedSettings
|
|
||||||
} from 'Store/Actions/settingsActions';
|
} from 'Store/Actions/settingsActions';
|
||||||
import createProviderSettingsSelector from 'Store/Selectors/createProviderSettingsSelector';
|
import createProviderSettingsSelector from 'Store/Selectors/createProviderSettingsSelector';
|
||||||
import EditNotificationModalContent from './EditNotificationModalContent';
|
import EditNotificationModalContent from './EditNotificationModalContent';
|
||||||
|
|
@ -29,8 +28,7 @@ const mapDispatchToProps = {
|
||||||
setNotificationValue,
|
setNotificationValue,
|
||||||
setNotificationFieldValues,
|
setNotificationFieldValues,
|
||||||
saveNotification,
|
saveNotification,
|
||||||
testNotification,
|
testNotification
|
||||||
toggleAdvancedSettings
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EditNotificationModalContentConnector extends Component {
|
class EditNotificationModalContentConnector extends Component {
|
||||||
|
|
@ -63,10 +61,6 @@ class EditNotificationModalContentConnector extends Component {
|
||||||
this.props.testNotification({ id: this.props.id });
|
this.props.testNotification({ id: this.props.id });
|
||||||
};
|
};
|
||||||
|
|
||||||
onAdvancedSettingsPress = () => {
|
|
||||||
this.props.toggleAdvancedSettings();
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Render
|
// Render
|
||||||
|
|
||||||
|
|
@ -76,7 +70,6 @@ class EditNotificationModalContentConnector extends Component {
|
||||||
{...this.props}
|
{...this.props}
|
||||||
onSavePress={this.onSavePress}
|
onSavePress={this.onSavePress}
|
||||||
onTestPress={this.onTestPress}
|
onTestPress={this.onTestPress}
|
||||||
onAdvancedSettingsPress={this.onAdvancedSettingsPress}
|
|
||||||
onInputChange={this.onInputChange}
|
onInputChange={this.onInputChange}
|
||||||
onFieldChange={this.onFieldChange}
|
onFieldChange={this.onFieldChange}
|
||||||
/>
|
/>
|
||||||
|
|
@ -94,7 +87,6 @@ EditNotificationModalContentConnector.propTypes = {
|
||||||
setNotificationFieldValues: PropTypes.func.isRequired,
|
setNotificationFieldValues: PropTypes.func.isRequired,
|
||||||
saveNotification: PropTypes.func.isRequired,
|
saveNotification: PropTypes.func.isRequired,
|
||||||
testNotification: PropTypes.func.isRequired,
|
testNotification: PropTypes.func.isRequired,
|
||||||
toggleAdvancedSettings: PropTypes.func.isRequired,
|
|
||||||
onModalClose: PropTypes.func.isRequired
|
onModalClose: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { useEffect } from 'react';
|
|
||||||
import keyboardShortcuts from 'Components/keyboardShortcuts';
|
|
||||||
import Button from 'Components/Link/Button';
|
|
||||||
import Modal from 'Components/Modal/Modal';
|
|
||||||
import ModalBody from 'Components/Modal/ModalBody';
|
|
||||||
import ModalContent from 'Components/Modal/ModalContent';
|
|
||||||
import ModalFooter from 'Components/Modal/ModalFooter';
|
|
||||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
|
||||||
import { kinds } from 'Helpers/Props';
|
|
||||||
import translate from 'Utilities/String/translate';
|
|
||||||
|
|
||||||
function PendingChangesModal(props) {
|
|
||||||
const {
|
|
||||||
isOpen,
|
|
||||||
onConfirm,
|
|
||||||
onCancel,
|
|
||||||
bindShortcut,
|
|
||||||
unbindShortcut
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isOpen) {
|
|
||||||
bindShortcut('enter', onConfirm);
|
|
||||||
|
|
||||||
return () => unbindShortcut('enter', onConfirm);
|
|
||||||
}
|
|
||||||
}, [bindShortcut, unbindShortcut, isOpen, onConfirm]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
isOpen={isOpen}
|
|
||||||
onModalClose={onCancel}
|
|
||||||
>
|
|
||||||
<ModalContent onModalClose={onCancel}>
|
|
||||||
<ModalHeader>{translate('UnsavedChanges')}</ModalHeader>
|
|
||||||
|
|
||||||
<ModalBody>
|
|
||||||
{translate('PendingChangesMessage')}
|
|
||||||
</ModalBody>
|
|
||||||
|
|
||||||
<ModalFooter>
|
|
||||||
<Button
|
|
||||||
kind={kinds.DEFAULT}
|
|
||||||
onPress={onCancel}
|
|
||||||
>
|
|
||||||
{translate('PendingChangesStayReview')}
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
autoFocus={true}
|
|
||||||
kind={kinds.DANGER}
|
|
||||||
onPress={onConfirm}
|
|
||||||
>
|
|
||||||
{translate('PendingChangesDiscardChanges')}
|
|
||||||
</Button>
|
|
||||||
</ModalFooter>
|
|
||||||
</ModalContent>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
PendingChangesModal.propTypes = {
|
|
||||||
className: PropTypes.string,
|
|
||||||
isOpen: PropTypes.bool.isRequired,
|
|
||||||
kind: PropTypes.oneOf(kinds.all),
|
|
||||||
onConfirm: PropTypes.func.isRequired,
|
|
||||||
onCancel: PropTypes.func.isRequired,
|
|
||||||
bindShortcut: PropTypes.func.isRequired,
|
|
||||||
unbindShortcut: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
PendingChangesModal.defaultProps = {
|
|
||||||
kind: kinds.PRIMARY
|
|
||||||
};
|
|
||||||
|
|
||||||
export default keyboardShortcuts(PendingChangesModal);
|
|
||||||
55
frontend/src/Settings/PendingChangesModal.tsx
Normal file
55
frontend/src/Settings/PendingChangesModal.tsx
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import Button from 'Components/Link/Button';
|
||||||
|
import Modal from 'Components/Modal/Modal';
|
||||||
|
import ModalBody from 'Components/Modal/ModalBody';
|
||||||
|
import ModalContent from 'Components/Modal/ModalContent';
|
||||||
|
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||||
|
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||||
|
import useKeyboardShortcuts from 'Helpers/Hooks/useKeyboardShortcuts';
|
||||||
|
import { kinds } from 'Helpers/Props';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
|
|
||||||
|
interface PendingChangesModalProps {
|
||||||
|
className?: string;
|
||||||
|
isOpen: boolean;
|
||||||
|
onConfirm: () => void;
|
||||||
|
onCancel: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function PendingChangesModal({
|
||||||
|
isOpen,
|
||||||
|
onConfirm,
|
||||||
|
onCancel,
|
||||||
|
}: PendingChangesModalProps) {
|
||||||
|
const { bindShortcut, unbindShortcut } = useKeyboardShortcuts();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isOpen) {
|
||||||
|
bindShortcut('acceptConfirmModal', onConfirm);
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => unbindShortcut('acceptConfirmModal');
|
||||||
|
}, [bindShortcut, unbindShortcut, isOpen, onConfirm]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal isOpen={isOpen} onModalClose={onCancel}>
|
||||||
|
<ModalContent onModalClose={onCancel}>
|
||||||
|
<ModalHeader>{translate('UnsavedChanges')}</ModalHeader>
|
||||||
|
|
||||||
|
<ModalBody>{translate('PendingChangesMessage')}</ModalBody>
|
||||||
|
|
||||||
|
<ModalFooter>
|
||||||
|
<Button kind={kinds.DEFAULT} onPress={onCancel}>
|
||||||
|
{translate('PendingChangesStayReview')}
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button autoFocus={true} kind={kinds.DANGER} onPress={onConfirm}>
|
||||||
|
{translate('PendingChangesDiscardChanges')}
|
||||||
|
</Button>
|
||||||
|
</ModalFooter>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PendingChangesModal;
|
||||||
|
|
@ -3,7 +3,7 @@ import { DndProvider } from 'react-dnd-multi-backend';
|
||||||
import HTML5toTouch from 'react-dnd-multi-backend/dist/esm/HTML5toTouch';
|
import HTML5toTouch from 'react-dnd-multi-backend/dist/esm/HTML5toTouch';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbar from 'Settings/SettingsToolbar';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import DelayProfilesConnector from './Delay/DelayProfilesConnector';
|
import DelayProfilesConnector from './Delay/DelayProfilesConnector';
|
||||||
import QualityProfilesConnector from './Quality/QualityProfilesConnector';
|
import QualityProfilesConnector from './Quality/QualityProfilesConnector';
|
||||||
|
|
@ -20,7 +20,7 @@ class Profiles extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<PageContent title={translate('Profiles')}>
|
<PageContent title={translate('Profiles')}>
|
||||||
<SettingsToolbarConnector showSave={false} />
|
<SettingsToolbar showSave={false} />
|
||||||
|
|
||||||
<PageContentBody>
|
<PageContentBody>
|
||||||
<DndProvider options={HTML5toTouch}>
|
<DndProvider options={HTML5toTouch}>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
||||||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||||
import { icons } from 'Helpers/Props';
|
import { icons } from 'Helpers/Props';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbar from 'Settings/SettingsToolbar';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import QualityDefinitionsConnector from './Definition/QualityDefinitionsConnector';
|
import QualityDefinitionsConnector from './Definition/QualityDefinitionsConnector';
|
||||||
import ResetQualityDefinitionsModal from './Reset/ResetQualityDefinitionsModal';
|
import ResetQualityDefinitionsModal from './Reset/ResetQualityDefinitionsModal';
|
||||||
|
|
@ -64,7 +64,7 @@ class Quality extends Component {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContent title={translate('QualitySettings')}>
|
<PageContent title={translate('QualitySettings')}>
|
||||||
<SettingsToolbarConnector
|
<SettingsToolbar
|
||||||
isSaving={isSaving}
|
isSaving={isSaving}
|
||||||
hasPendingChanges={hasPendingChanges}
|
hasPendingChanges={hasPendingChanges}
|
||||||
additionalButtons={
|
additionalButtons={
|
||||||
|
|
|
||||||
|
|
@ -3,21 +3,16 @@ import Link from 'Components/Link/Link';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import SettingsToolbarConnector from './SettingsToolbarConnector';
|
import SettingsToolbar from './SettingsToolbar';
|
||||||
import styles from './Settings.css';
|
import styles from './Settings.css';
|
||||||
|
|
||||||
function Settings() {
|
function Settings() {
|
||||||
return (
|
return (
|
||||||
<PageContent title={translate('Settings')}>
|
<PageContent title={translate('Settings')}>
|
||||||
<SettingsToolbarConnector
|
<SettingsToolbar hasPendingChanges={false} />
|
||||||
hasPendingChanges={false}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<PageContentBody>
|
<PageContentBody>
|
||||||
<Link
|
<Link className={styles.link} to="/settings/mediamanagement">
|
||||||
className={styles.link}
|
|
||||||
to="/settings/mediamanagement"
|
|
||||||
>
|
|
||||||
{translate('MediaManagement')}
|
{translate('MediaManagement')}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|
@ -25,10 +20,7 @@ function Settings() {
|
||||||
{translate('MediaManagementSettingsSummary')}
|
{translate('MediaManagementSettingsSummary')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link
|
<Link className={styles.link} to="/settings/profiles">
|
||||||
className={styles.link}
|
|
||||||
to="/settings/profiles"
|
|
||||||
>
|
|
||||||
{translate('Profiles')}
|
{translate('Profiles')}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|
@ -36,10 +28,7 @@ function Settings() {
|
||||||
{translate('ProfilesSettingsSummary')}
|
{translate('ProfilesSettingsSummary')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link
|
<Link className={styles.link} to="/settings/quality">
|
||||||
className={styles.link}
|
|
||||||
to="/settings/quality"
|
|
||||||
>
|
|
||||||
{translate('Quality')}
|
{translate('Quality')}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|
@ -47,10 +36,7 @@ function Settings() {
|
||||||
{translate('QualitySettingsSummary')}
|
{translate('QualitySettingsSummary')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link
|
<Link className={styles.link} to="/settings/customformats">
|
||||||
className={styles.link}
|
|
||||||
to="/settings/customformats"
|
|
||||||
>
|
|
||||||
{translate('CustomFormats')}
|
{translate('CustomFormats')}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|
@ -58,10 +44,7 @@ function Settings() {
|
||||||
{translate('CustomFormatsSettingsSummary')}
|
{translate('CustomFormatsSettingsSummary')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link
|
<Link className={styles.link} to="/settings/indexers">
|
||||||
className={styles.link}
|
|
||||||
to="/settings/indexers"
|
|
||||||
>
|
|
||||||
{translate('Indexers')}
|
{translate('Indexers')}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|
@ -69,10 +52,7 @@ function Settings() {
|
||||||
{translate('IndexersSettingsSummary')}
|
{translate('IndexersSettingsSummary')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link
|
<Link className={styles.link} to="/settings/downloadclients">
|
||||||
className={styles.link}
|
|
||||||
to="/settings/downloadclients"
|
|
||||||
>
|
|
||||||
{translate('DownloadClients')}
|
{translate('DownloadClients')}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|
@ -80,10 +60,7 @@ function Settings() {
|
||||||
{translate('DownloadClientsSettingsSummary')}
|
{translate('DownloadClientsSettingsSummary')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link
|
<Link className={styles.link} to="/settings/importlists">
|
||||||
className={styles.link}
|
|
||||||
to="/settings/importlists"
|
|
||||||
>
|
|
||||||
{translate('ImportLists')}
|
{translate('ImportLists')}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|
@ -91,10 +68,7 @@ function Settings() {
|
||||||
{translate('ImportListsSettingsSummary')}
|
{translate('ImportListsSettingsSummary')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link
|
<Link className={styles.link} to="/settings/connect">
|
||||||
className={styles.link}
|
|
||||||
to="/settings/connect"
|
|
||||||
>
|
|
||||||
{translate('Connect')}
|
{translate('Connect')}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|
@ -102,10 +76,7 @@ function Settings() {
|
||||||
{translate('ConnectSettingsSummary')}
|
{translate('ConnectSettingsSummary')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link
|
<Link className={styles.link} to="/settings/metadata">
|
||||||
className={styles.link}
|
|
||||||
to="/settings/metadata"
|
|
||||||
>
|
|
||||||
{translate('Metadata')}
|
{translate('Metadata')}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|
@ -113,21 +84,13 @@ function Settings() {
|
||||||
{translate('MetadataSettingsMovieSummary')}
|
{translate('MetadataSettingsMovieSummary')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link
|
<Link className={styles.link} to="/settings/tags">
|
||||||
className={styles.link}
|
|
||||||
to="/settings/tags"
|
|
||||||
>
|
|
||||||
{translate('Tags')}
|
{translate('Tags')}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<div className={styles.summary}>
|
<div className={styles.summary}>{translate('TagsSettingsSummary')}</div>
|
||||||
{translate('TagsSettingsSummary')}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Link
|
<Link className={styles.link} to="/settings/general">
|
||||||
className={styles.link}
|
|
||||||
to="/settings/general"
|
|
||||||
>
|
|
||||||
{translate('General')}
|
{translate('General')}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|
@ -135,22 +98,14 @@ function Settings() {
|
||||||
{translate('GeneralSettingsSummary')}
|
{translate('GeneralSettingsSummary')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Link
|
<Link className={styles.link} to="/settings/ui">
|
||||||
className={styles.link}
|
|
||||||
to="/settings/ui"
|
|
||||||
>
|
|
||||||
{translate('Ui')}
|
{translate('Ui')}
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<div className={styles.summary}>
|
<div className={styles.summary}>{translate('UiSettingsSummary')}</div>
|
||||||
{translate('UiSettingsSummary')}
|
|
||||||
</div>
|
|
||||||
</PageContentBody>
|
</PageContentBody>
|
||||||
</PageContent>
|
</PageContent>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings.propTypes = {
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Settings;
|
export default Settings;
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import keyboardShortcuts, { shortcuts } from 'Components/keyboardShortcuts';
|
|
||||||
import PageToolbar from 'Components/Page/Toolbar/PageToolbar';
|
|
||||||
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
|
||||||
import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
|
|
||||||
import { icons } from 'Helpers/Props';
|
|
||||||
import translate from 'Utilities/String/translate';
|
|
||||||
import AdvancedSettingsButton from './AdvancedSettingsButton';
|
|
||||||
import PendingChangesModal from './PendingChangesModal';
|
|
||||||
|
|
||||||
class SettingsToolbar extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.props.bindShortcut(shortcuts.SAVE_SETTINGS.key, this.saveSettings, { isGlobal: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Control
|
|
||||||
|
|
||||||
saveSettings = (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const {
|
|
||||||
hasPendingChanges,
|
|
||||||
onSavePress
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
if (hasPendingChanges) {
|
|
||||||
onSavePress();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
advancedSettings,
|
|
||||||
showSave,
|
|
||||||
isSaving,
|
|
||||||
hasPendingChanges,
|
|
||||||
hasPendingLocation,
|
|
||||||
additionalButtons,
|
|
||||||
onSavePress,
|
|
||||||
onConfirmNavigation,
|
|
||||||
onCancelNavigation,
|
|
||||||
onAdvancedSettingsPress
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PageToolbar>
|
|
||||||
<PageToolbarSection>
|
|
||||||
<AdvancedSettingsButton
|
|
||||||
advancedSettings={advancedSettings}
|
|
||||||
onAdvancedSettingsPress={onAdvancedSettingsPress}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{
|
|
||||||
showSave &&
|
|
||||||
<PageToolbarButton
|
|
||||||
label={hasPendingChanges ? translate('SaveChanges') : translate('NoChanges')}
|
|
||||||
iconName={icons.SAVE}
|
|
||||||
isSpinning={isSaving}
|
|
||||||
isDisabled={!hasPendingChanges}
|
|
||||||
onPress={onSavePress}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
additionalButtons
|
|
||||||
}
|
|
||||||
</PageToolbarSection>
|
|
||||||
|
|
||||||
<PendingChangesModal
|
|
||||||
isOpen={hasPendingLocation}
|
|
||||||
onConfirm={onConfirmNavigation}
|
|
||||||
onCancel={onCancelNavigation}
|
|
||||||
/>
|
|
||||||
</PageToolbar>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsToolbar.propTypes = {
|
|
||||||
advancedSettings: PropTypes.bool.isRequired,
|
|
||||||
showSave: PropTypes.bool.isRequired,
|
|
||||||
isSaving: PropTypes.bool,
|
|
||||||
hasPendingLocation: PropTypes.bool.isRequired,
|
|
||||||
hasPendingChanges: PropTypes.bool,
|
|
||||||
additionalButtons: PropTypes.node,
|
|
||||||
onSavePress: PropTypes.func,
|
|
||||||
onAdvancedSettingsPress: PropTypes.func.isRequired,
|
|
||||||
onConfirmNavigation: PropTypes.func.isRequired,
|
|
||||||
onCancelNavigation: PropTypes.func.isRequired,
|
|
||||||
bindShortcut: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
SettingsToolbar.defaultProps = {
|
|
||||||
showSave: true
|
|
||||||
};
|
|
||||||
|
|
||||||
export default keyboardShortcuts(SettingsToolbar);
|
|
||||||
149
frontend/src/Settings/SettingsToolbar.tsx
Normal file
149
frontend/src/Settings/SettingsToolbar.tsx
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
import { Action, Location, UnregisterCallback } from 'history';
|
||||||
|
import React, {
|
||||||
|
ReactElement,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from 'react';
|
||||||
|
import { useHistory } from 'react-router';
|
||||||
|
import PageToolbar from 'Components/Page/Toolbar/PageToolbar';
|
||||||
|
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
||||||
|
import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
|
||||||
|
import useKeyboardShortcuts from 'Helpers/Hooks/useKeyboardShortcuts';
|
||||||
|
import { icons } from 'Helpers/Props';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
|
import AdvancedSettingsButton from './AdvancedSettingsButton';
|
||||||
|
import PendingChangesModal from './PendingChangesModal';
|
||||||
|
|
||||||
|
interface SettingsToolbarProps {
|
||||||
|
showSave?: boolean;
|
||||||
|
isSaving?: boolean;
|
||||||
|
hasPendingChanges?: boolean;
|
||||||
|
// TODO: This should do type checking like PageToolbarSectionProps,
|
||||||
|
// but this works for the time being.
|
||||||
|
additionalButtons?: ReactElement | null;
|
||||||
|
onSavePress?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function SettingsToolbar({
|
||||||
|
showSave = true,
|
||||||
|
isSaving,
|
||||||
|
hasPendingChanges,
|
||||||
|
additionalButtons = null,
|
||||||
|
onSavePress,
|
||||||
|
}: SettingsToolbarProps) {
|
||||||
|
const { bindShortcut, unbindShortcut } = useKeyboardShortcuts();
|
||||||
|
const history = useHistory();
|
||||||
|
const [nextLocation, setNextLocation] = useState<Location | null>(null);
|
||||||
|
const [nextLocationAction, setNextLocationAction] = useState<Action | null>(
|
||||||
|
null
|
||||||
|
);
|
||||||
|
const hasConfirmed = useRef(false);
|
||||||
|
const unblocker = useRef<UnregisterCallback>();
|
||||||
|
|
||||||
|
const handleConfirmNavigation = useCallback(() => {
|
||||||
|
if (!nextLocation) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const path = `${nextLocation.pathname}${nextLocation.search}`;
|
||||||
|
|
||||||
|
hasConfirmed.current = true;
|
||||||
|
|
||||||
|
if (nextLocationAction === 'PUSH') {
|
||||||
|
history.push(path);
|
||||||
|
} else {
|
||||||
|
// Unfortunately back and forward both use POP,
|
||||||
|
// which means we don't actually know which direction
|
||||||
|
// the user wanted to go, assuming back.
|
||||||
|
|
||||||
|
history.goBack();
|
||||||
|
}
|
||||||
|
}, [nextLocation, nextLocationAction, history]);
|
||||||
|
|
||||||
|
const handleCancelNavigation = useCallback(() => {
|
||||||
|
setNextLocation(null);
|
||||||
|
setNextLocationAction(null);
|
||||||
|
hasConfirmed.current = false;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleRouterLeaving = useCallback(
|
||||||
|
(routerLocation: Location, routerAction: Action) => {
|
||||||
|
if (hasConfirmed.current) {
|
||||||
|
setNextLocation(null);
|
||||||
|
setNextLocationAction(null);
|
||||||
|
hasConfirmed.current = false;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasPendingChanges) {
|
||||||
|
setNextLocation(routerLocation);
|
||||||
|
setNextLocationAction(routerAction);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
[hasPendingChanges]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
unblocker.current = history.block(handleRouterLeaving);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
unblocker.current?.();
|
||||||
|
};
|
||||||
|
}, [history, handleRouterLeaving]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
bindShortcut(
|
||||||
|
'saveSettings',
|
||||||
|
() => {
|
||||||
|
if (hasPendingChanges) {
|
||||||
|
onSavePress?.();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isGlobal: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
unbindShortcut('saveSettings');
|
||||||
|
};
|
||||||
|
}, [hasPendingChanges, bindShortcut, unbindShortcut, onSavePress]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<PageToolbar>
|
||||||
|
<PageToolbarSection>
|
||||||
|
<AdvancedSettingsButton showLabel={true} />
|
||||||
|
{showSave ? (
|
||||||
|
<PageToolbarButton
|
||||||
|
label={
|
||||||
|
hasPendingChanges
|
||||||
|
? translate('SaveChanges')
|
||||||
|
: translate('NoChanges')
|
||||||
|
}
|
||||||
|
iconName={icons.SAVE}
|
||||||
|
isSpinning={isSaving}
|
||||||
|
isDisabled={!hasPendingChanges}
|
||||||
|
onPress={onSavePress}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
{additionalButtons}
|
||||||
|
</PageToolbarSection>
|
||||||
|
|
||||||
|
<PendingChangesModal
|
||||||
|
isOpen={nextLocation !== null}
|
||||||
|
onConfirm={handleConfirmNavigation}
|
||||||
|
onCancel={handleCancelNavigation}
|
||||||
|
/>
|
||||||
|
</PageToolbar>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SettingsToolbar;
|
||||||
|
|
@ -1,148 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { withRouter } from 'react-router-dom';
|
|
||||||
import { toggleAdvancedSettings } from 'Store/Actions/settingsActions';
|
|
||||||
import SettingsToolbar from './SettingsToolbar';
|
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
|
||||||
return {
|
|
||||||
advancedSettings: state.settings.advancedSettings
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
|
||||||
toggleAdvancedSettings
|
|
||||||
};
|
|
||||||
|
|
||||||
class SettingsToolbarConnector extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
constructor(props, context) {
|
|
||||||
super(props, context);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
nextLocation: null,
|
|
||||||
nextLocationAction: null,
|
|
||||||
confirmed: false
|
|
||||||
};
|
|
||||||
|
|
||||||
this._unblock = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this._unblock = this.props.history.block(this.routerWillLeave);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
if (this._unblock) {
|
|
||||||
this._unblock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Control
|
|
||||||
|
|
||||||
routerWillLeave = (nextLocation, nextLocationAction) => {
|
|
||||||
if (this.state.confirmed) {
|
|
||||||
this.setState({
|
|
||||||
nextLocation: null,
|
|
||||||
nextLocationAction: null,
|
|
||||||
confirmed: false
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.hasPendingChanges ) {
|
|
||||||
this.setState({
|
|
||||||
nextLocation,
|
|
||||||
nextLocationAction
|
|
||||||
});
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onAdvancedSettingsPress = () => {
|
|
||||||
this.props.toggleAdvancedSettings();
|
|
||||||
};
|
|
||||||
|
|
||||||
onConfirmNavigation = () => {
|
|
||||||
const {
|
|
||||||
nextLocation,
|
|
||||||
nextLocationAction
|
|
||||||
} = this.state;
|
|
||||||
|
|
||||||
const history = this.props.history;
|
|
||||||
|
|
||||||
const path = `${nextLocation.pathname}${nextLocation.search}`;
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
confirmed: true
|
|
||||||
}, () => {
|
|
||||||
if (nextLocationAction === 'PUSH') {
|
|
||||||
history.push(path);
|
|
||||||
} else {
|
|
||||||
// Unfortunately back and forward both use POP,
|
|
||||||
// which means we don't actually know which direction
|
|
||||||
// the user wanted to go, assuming back.
|
|
||||||
|
|
||||||
history.goBack();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onCancelNavigation = () => {
|
|
||||||
this.setState({
|
|
||||||
nextLocation: null,
|
|
||||||
nextLocationAction: null,
|
|
||||||
confirmed: false
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const hasPendingLocation = this.state.nextLocation !== null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SettingsToolbar
|
|
||||||
hasPendingLocation={hasPendingLocation}
|
|
||||||
onSavePress={this.props.onSavePress}
|
|
||||||
onAdvancedSettingsPress={this.onAdvancedSettingsPress}
|
|
||||||
onConfirmNavigation={this.onConfirmNavigation}
|
|
||||||
onCancelNavigation={this.onCancelNavigation}
|
|
||||||
{...this.props}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const historyShape = {
|
|
||||||
block: PropTypes.func.isRequired,
|
|
||||||
goBack: PropTypes.func.isRequired,
|
|
||||||
push: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
SettingsToolbarConnector.propTypes = {
|
|
||||||
showSave: PropTypes.bool,
|
|
||||||
hasPendingChanges: PropTypes.bool.isRequired,
|
|
||||||
history: PropTypes.shape(historyShape).isRequired,
|
|
||||||
onSavePress: PropTypes.func,
|
|
||||||
toggleAdvancedSettings: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
SettingsToolbarConnector.defaultProps = {
|
|
||||||
hasPendingChanges: false
|
|
||||||
};
|
|
||||||
|
|
||||||
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(SettingsToolbarConnector));
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbar from 'Settings/SettingsToolbar';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import AutoTaggings from './AutoTagging/AutoTaggings';
|
import AutoTaggings from './AutoTagging/AutoTaggings';
|
||||||
import TagsConnector from './TagsConnector';
|
import TagsConnector from './TagsConnector';
|
||||||
|
|
@ -9,7 +9,7 @@ import TagsConnector from './TagsConnector';
|
||||||
function TagSettings() {
|
function TagSettings() {
|
||||||
return (
|
return (
|
||||||
<PageContent title={translate('Tags')}>
|
<PageContent title={translate('Tags')}>
|
||||||
<SettingsToolbarConnector
|
<SettingsToolbar
|
||||||
showSave={false}
|
showSave={false}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import { inputTypes, kinds } from 'Helpers/Props';
|
import { inputTypes, kinds } from 'Helpers/Props';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbar from 'Settings/SettingsToolbar';
|
||||||
import themes from 'Styles/Themes';
|
import themes from 'Styles/Themes';
|
||||||
import titleCase from 'Utilities/String/titleCase';
|
import titleCase from 'Utilities/String/titleCase';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
|
|
@ -85,7 +85,7 @@ class UISettings extends Component {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContent title={translate('UiSettings')}>
|
<PageContent title={translate('UiSettings')}>
|
||||||
<SettingsToolbarConnector
|
<SettingsToolbar
|
||||||
{...otherProps}
|
{...otherProps}
|
||||||
onSavePress={onSavePress}
|
onSavePress={onSavePress}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue