parent
de9899c60e
commit
4285691064
|
@ -38,6 +38,7 @@ export interface AppSectionItemState<T> {
|
||||||
isFetching: boolean;
|
isFetching: boolean;
|
||||||
isPopulated: boolean;
|
isPopulated: boolean;
|
||||||
error: Error;
|
error: Error;
|
||||||
|
pendingChanges: Partial<T>;
|
||||||
item: T;
|
item: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,12 @@ import AppSectionState, {
|
||||||
AppSectionItemState,
|
AppSectionItemState,
|
||||||
AppSectionSaveState,
|
AppSectionSaveState,
|
||||||
AppSectionSchemaState,
|
AppSectionSchemaState,
|
||||||
|
PagedAppSectionState,
|
||||||
} from 'App/State/AppSectionState';
|
} from 'App/State/AppSectionState';
|
||||||
import Language from 'Language/Language';
|
import Language from 'Language/Language';
|
||||||
import DownloadClient from 'typings/DownloadClient';
|
import DownloadClient from 'typings/DownloadClient';
|
||||||
import ImportList from 'typings/ImportList';
|
import ImportList from 'typings/ImportList';
|
||||||
|
import ImportListExclusion from 'typings/ImportListExclusion';
|
||||||
import ImportListOptionsSettings from 'typings/ImportListOptionsSettings';
|
import ImportListOptionsSettings from 'typings/ImportListOptionsSettings';
|
||||||
import Indexer from 'typings/Indexer';
|
import Indexer from 'typings/Indexer';
|
||||||
import IndexerFlag from 'typings/IndexerFlag';
|
import IndexerFlag from 'typings/IndexerFlag';
|
||||||
|
@ -41,6 +43,14 @@ export interface ImportListOptionsSettingsAppState
|
||||||
extends AppSectionItemState<ImportListOptionsSettings>,
|
extends AppSectionItemState<ImportListOptionsSettings>,
|
||||||
AppSectionSaveState {}
|
AppSectionSaveState {}
|
||||||
|
|
||||||
|
export interface ImportListExclusionsSettingsAppState
|
||||||
|
extends AppSectionState<ImportListExclusion>,
|
||||||
|
AppSectionSaveState,
|
||||||
|
PagedAppSectionState,
|
||||||
|
AppSectionDeleteState {
|
||||||
|
pendingChanges: Partial<ImportListExclusion>;
|
||||||
|
}
|
||||||
|
|
||||||
export type IndexerFlagSettingsAppState = AppSectionState<IndexerFlag>;
|
export type IndexerFlagSettingsAppState = AppSectionState<IndexerFlag>;
|
||||||
export type LanguageSettingsAppState = AppSectionState<Language>;
|
export type LanguageSettingsAppState = AppSectionState<Language>;
|
||||||
export type UiSettingsAppState = AppSectionItemState<UiSettings>;
|
export type UiSettingsAppState = AppSectionItemState<UiSettings>;
|
||||||
|
@ -48,6 +58,7 @@ export type UiSettingsAppState = AppSectionItemState<UiSettings>;
|
||||||
interface SettingsAppState {
|
interface SettingsAppState {
|
||||||
advancedSettings: boolean;
|
advancedSettings: boolean;
|
||||||
downloadClients: DownloadClientAppState;
|
downloadClients: DownloadClientAppState;
|
||||||
|
importListExclusions: ImportListExclusionsSettingsAppState;
|
||||||
importListOptions: ImportListOptionsSettingsAppState;
|
importListOptions: ImportListOptionsSettingsAppState;
|
||||||
importLists: ImportListAppState;
|
importLists: ImportListAppState;
|
||||||
indexerFlags: IndexerFlagSettingsAppState;
|
indexerFlags: IndexerFlagSettingsAppState;
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { useCallback, useState } from 'react';
|
||||||
|
|
||||||
|
export default function useModalOpenState(
|
||||||
|
initialState: boolean
|
||||||
|
): [boolean, () => void, () => void] {
|
||||||
|
const [isOpen, setOpen] = useState(initialState);
|
||||||
|
|
||||||
|
const setModalOpen = useCallback(() => {
|
||||||
|
setOpen(true);
|
||||||
|
}, [setOpen]);
|
||||||
|
|
||||||
|
const setModalClosed = useCallback(() => {
|
||||||
|
setOpen(false);
|
||||||
|
}, [setOpen]);
|
||||||
|
|
||||||
|
return [isOpen, setModalOpen, setModalClosed];
|
||||||
|
}
|
|
@ -1,27 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
import Modal from 'Components/Modal/Modal';
|
|
||||||
import { sizes } from 'Helpers/Props';
|
|
||||||
import EditImportListExclusionModalContentConnector from './EditImportListExclusionModalContentConnector';
|
|
||||||
|
|
||||||
function EditImportListExclusionModal({ isOpen, onModalClose, ...otherProps }) {
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
size={sizes.MEDIUM}
|
|
||||||
isOpen={isOpen}
|
|
||||||
onModalClose={onModalClose}
|
|
||||||
>
|
|
||||||
<EditImportListExclusionModalContentConnector
|
|
||||||
{...otherProps}
|
|
||||||
onModalClose={onModalClose}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
EditImportListExclusionModal.propTypes = {
|
|
||||||
isOpen: PropTypes.bool.isRequired,
|
|
||||||
onModalClose: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EditImportListExclusionModal;
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
import React, { useCallback } from 'react';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
import Modal from 'Components/Modal/Modal';
|
||||||
|
import { sizes } from 'Helpers/Props';
|
||||||
|
import { clearPendingChanges } from 'Store/Actions/baseActions';
|
||||||
|
import EditImportListExclusionModalContent from './EditImportListExclusionModalContent';
|
||||||
|
|
||||||
|
interface EditImportListExclusionModalProps {
|
||||||
|
id?: number;
|
||||||
|
isOpen: boolean;
|
||||||
|
onModalClose: () => void;
|
||||||
|
onDeleteImportListExclusionPress?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function EditImportListExclusionModal(
|
||||||
|
props: EditImportListExclusionModalProps
|
||||||
|
) {
|
||||||
|
const { isOpen, onModalClose, ...otherProps } = props;
|
||||||
|
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const onModalClosePress = useCallback(() => {
|
||||||
|
dispatch(
|
||||||
|
clearPendingChanges({
|
||||||
|
section: 'settings.importListExclusions',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
onModalClose();
|
||||||
|
}, [dispatch, onModalClose]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal size={sizes.MEDIUM} isOpen={isOpen} onModalClose={onModalClosePress}>
|
||||||
|
<EditImportListExclusionModalContent
|
||||||
|
{...otherProps}
|
||||||
|
onModalClose={onModalClose}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EditImportListExclusionModal;
|
|
@ -1,43 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { clearPendingChanges } from 'Store/Actions/baseActions';
|
|
||||||
import EditImportListExclusionModal from './EditImportListExclusionModal';
|
|
||||||
|
|
||||||
function mapStateToProps() {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
|
||||||
clearPendingChanges
|
|
||||||
};
|
|
||||||
|
|
||||||
class EditImportListExclusionModalConnector extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onModalClose = () => {
|
|
||||||
this.props.clearPendingChanges({ section: 'settings.importListExclusions' });
|
|
||||||
this.props.onModalClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<EditImportListExclusionModal
|
|
||||||
{...this.props}
|
|
||||||
onModalClose={this.onModalClose}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EditImportListExclusionModalConnector.propTypes = {
|
|
||||||
onModalClose: PropTypes.func.isRequired,
|
|
||||||
clearPendingChanges: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(EditImportListExclusionModalConnector);
|
|
|
@ -1,139 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
|
||||||
import Alert from 'Components/Alert';
|
|
||||||
import Form from 'Components/Form/Form';
|
|
||||||
import FormGroup from 'Components/Form/FormGroup';
|
|
||||||
import FormInputGroup from 'Components/Form/FormInputGroup';
|
|
||||||
import FormLabel from 'Components/Form/FormLabel';
|
|
||||||
import Button from 'Components/Link/Button';
|
|
||||||
import SpinnerErrorButton from 'Components/Link/SpinnerErrorButton';
|
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
|
||||||
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 { inputTypes, kinds } from 'Helpers/Props';
|
|
||||||
import { numberSettingShape, stringSettingShape } from 'Helpers/Props/Shapes/settingShape';
|
|
||||||
import translate from 'Utilities/String/translate';
|
|
||||||
import styles from './EditImportListExclusionModalContent.css';
|
|
||||||
|
|
||||||
function EditImportListExclusionModalContent(props) {
|
|
||||||
const {
|
|
||||||
id,
|
|
||||||
isFetching,
|
|
||||||
error,
|
|
||||||
isSaving,
|
|
||||||
saveError,
|
|
||||||
item,
|
|
||||||
onInputChange,
|
|
||||||
onSavePress,
|
|
||||||
onModalClose,
|
|
||||||
onDeleteImportListExclusionPress,
|
|
||||||
...otherProps
|
|
||||||
} = props;
|
|
||||||
|
|
||||||
const {
|
|
||||||
title,
|
|
||||||
tvdbId
|
|
||||||
} = item;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ModalContent onModalClose={onModalClose}>
|
|
||||||
<ModalHeader>
|
|
||||||
{id ? translate('EditImportListExclusion') : translate('AddImportListExclusion')}
|
|
||||||
</ModalHeader>
|
|
||||||
|
|
||||||
<ModalBody className={styles.body}>
|
|
||||||
{
|
|
||||||
isFetching &&
|
|
||||||
<LoadingIndicator />
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
!isFetching && !!error &&
|
|
||||||
<Alert kind={kinds.DANGER}>
|
|
||||||
{translate('AddImportListExclusionError')}
|
|
||||||
</Alert>
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
!isFetching && !error &&
|
|
||||||
<Form
|
|
||||||
{...otherProps}
|
|
||||||
>
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('Title')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.TEXT}
|
|
||||||
name="title"
|
|
||||||
helpText={translate('SeriesTitleToExcludeHelpText')}
|
|
||||||
{...title}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
|
|
||||||
<FormGroup>
|
|
||||||
<FormLabel>{translate('TvdbId')}</FormLabel>
|
|
||||||
|
|
||||||
<FormInputGroup
|
|
||||||
type={inputTypes.TEXT}
|
|
||||||
name="tvdbId"
|
|
||||||
helpText={translate('TvdbIdExcludeHelpText')}
|
|
||||||
{...tvdbId}
|
|
||||||
onChange={onInputChange}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
</Form>
|
|
||||||
}
|
|
||||||
</ModalBody>
|
|
||||||
|
|
||||||
<ModalFooter>
|
|
||||||
{
|
|
||||||
id &&
|
|
||||||
<Button
|
|
||||||
className={styles.deleteButton}
|
|
||||||
kind={kinds.DANGER}
|
|
||||||
onPress={onDeleteImportListExclusionPress}
|
|
||||||
>
|
|
||||||
{translate('Delete')}
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
|
|
||||||
<Button
|
|
||||||
onPress={onModalClose}
|
|
||||||
>
|
|
||||||
{translate('Cancel')}
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
<SpinnerErrorButton
|
|
||||||
isSpinning={isSaving}
|
|
||||||
error={saveError}
|
|
||||||
onPress={onSavePress}
|
|
||||||
>
|
|
||||||
{translate('Save')}
|
|
||||||
</SpinnerErrorButton>
|
|
||||||
</ModalFooter>
|
|
||||||
</ModalContent>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const ImportListExclusionShape = {
|
|
||||||
title: PropTypes.shape(stringSettingShape).isRequired,
|
|
||||||
tvdbId: PropTypes.shape(numberSettingShape).isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
EditImportListExclusionModalContent.propTypes = {
|
|
||||||
id: PropTypes.number,
|
|
||||||
isFetching: PropTypes.bool.isRequired,
|
|
||||||
error: PropTypes.object,
|
|
||||||
isSaving: PropTypes.bool.isRequired,
|
|
||||||
saveError: PropTypes.object,
|
|
||||||
item: PropTypes.shape(ImportListExclusionShape).isRequired,
|
|
||||||
onInputChange: PropTypes.func.isRequired,
|
|
||||||
onSavePress: PropTypes.func.isRequired,
|
|
||||||
onModalClose: PropTypes.func.isRequired,
|
|
||||||
onDeleteImportListExclusionPress: PropTypes.func
|
|
||||||
};
|
|
||||||
|
|
||||||
export default EditImportListExclusionModalContent;
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
import React, { useCallback, useEffect } from 'react';
|
||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import AppState from 'App/State/AppState';
|
||||||
|
import Alert from 'Components/Alert';
|
||||||
|
import Form from 'Components/Form/Form';
|
||||||
|
import FormGroup from 'Components/Form/FormGroup';
|
||||||
|
import FormInputGroup from 'Components/Form/FormInputGroup';
|
||||||
|
import FormLabel from 'Components/Form/FormLabel';
|
||||||
|
import Button from 'Components/Link/Button';
|
||||||
|
import SpinnerErrorButton from 'Components/Link/SpinnerErrorButton';
|
||||||
|
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
|
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 usePrevious from 'Helpers/Hooks/usePrevious';
|
||||||
|
import { inputTypes, kinds } from 'Helpers/Props';
|
||||||
|
import {
|
||||||
|
saveImportListExclusion,
|
||||||
|
setImportListExclusionValue,
|
||||||
|
} from 'Store/Actions/settingsActions';
|
||||||
|
import selectSettings from 'Store/Selectors/selectSettings';
|
||||||
|
import ImportListExclusion from 'typings/ImportListExclusion';
|
||||||
|
import { PendingSection } from 'typings/pending';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
|
import styles from './EditImportListExclusionModalContent.css';
|
||||||
|
|
||||||
|
const newImportListExclusion = {
|
||||||
|
title: '',
|
||||||
|
tvdbId: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
interface EditImportListExclusionModalContentProps {
|
||||||
|
id?: number;
|
||||||
|
onModalClose: () => void;
|
||||||
|
onDeleteImportListExclusionPress?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createImportListExclusionSelector(id?: number) {
|
||||||
|
return createSelector(
|
||||||
|
(state: AppState) => state.settings.importListExclusions,
|
||||||
|
(importListExclusions) => {
|
||||||
|
const { isFetching, error, isSaving, saveError, pendingChanges, items } =
|
||||||
|
importListExclusions;
|
||||||
|
|
||||||
|
const mapping = id
|
||||||
|
? items.find((i) => i.id === id)
|
||||||
|
: newImportListExclusion;
|
||||||
|
const settings = selectSettings(mapping, pendingChanges, saveError);
|
||||||
|
|
||||||
|
return {
|
||||||
|
id,
|
||||||
|
isFetching,
|
||||||
|
error,
|
||||||
|
isSaving,
|
||||||
|
saveError,
|
||||||
|
item: settings.settings as PendingSection<ImportListExclusion>,
|
||||||
|
...settings,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function EditImportListExclusionModalContent(
|
||||||
|
props: EditImportListExclusionModalContentProps
|
||||||
|
) {
|
||||||
|
const { id, onModalClose, onDeleteImportListExclusionPress } = props;
|
||||||
|
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const dispatchSetImportListExclusionValue = (payload: {
|
||||||
|
name: string;
|
||||||
|
value: string | number;
|
||||||
|
}) => {
|
||||||
|
// @ts-expect-error 'setImportListExclusionValue' isn't typed yet
|
||||||
|
dispatch(setImportListExclusionValue(payload));
|
||||||
|
};
|
||||||
|
|
||||||
|
const { isFetching, isSaving, item, error, saveError, ...otherProps } =
|
||||||
|
useSelector(createImportListExclusionSelector(props.id));
|
||||||
|
const previousIsSaving = usePrevious(isSaving);
|
||||||
|
|
||||||
|
const { title, tvdbId } = item;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!id) {
|
||||||
|
Object.keys(newImportListExclusion).forEach((name) => {
|
||||||
|
dispatchSetImportListExclusionValue({
|
||||||
|
name,
|
||||||
|
value:
|
||||||
|
newImportListExclusion[name as keyof typeof newImportListExclusion],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (previousIsSaving && !isSaving && !saveError) {
|
||||||
|
onModalClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSavePress = useCallback(() => {
|
||||||
|
dispatch(saveImportListExclusion({ id }));
|
||||||
|
}, [dispatch, id]);
|
||||||
|
|
||||||
|
const onInputChange = useCallback(
|
||||||
|
(payload: { name: string; value: string | number }) => {
|
||||||
|
// @ts-expect-error 'setImportListExclusionValue' isn't typed yet
|
||||||
|
dispatch(setImportListExclusionValue(payload));
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ModalContent onModalClose={onModalClose}>
|
||||||
|
<ModalHeader>
|
||||||
|
{id
|
||||||
|
? translate('EditImportListExclusion')
|
||||||
|
: translate('AddImportListExclusion')}
|
||||||
|
</ModalHeader>
|
||||||
|
|
||||||
|
<ModalBody className={styles.body}>
|
||||||
|
{isFetching && <LoadingIndicator />}
|
||||||
|
|
||||||
|
{!isFetching && !!error && (
|
||||||
|
<Alert kind={kinds.DANGER}>
|
||||||
|
{translate('AddImportListExclusionError')}
|
||||||
|
</Alert>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!isFetching && !error && (
|
||||||
|
<Form {...otherProps}>
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('Title')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.TEXT}
|
||||||
|
name="title"
|
||||||
|
helpText={translate('SeriesTitleToExcludeHelpText')}
|
||||||
|
{...title}
|
||||||
|
onChange={onInputChange}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('TvdbId')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.NUMBER}
|
||||||
|
name="tvdbId"
|
||||||
|
helpText={translate('TvdbIdExcludeHelpText')}
|
||||||
|
{...tvdbId}
|
||||||
|
onChange={onInputChange}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</ModalBody>
|
||||||
|
|
||||||
|
<ModalFooter>
|
||||||
|
{id && (
|
||||||
|
<Button
|
||||||
|
className={styles.deleteButton}
|
||||||
|
kind={kinds.DANGER}
|
||||||
|
onPress={onDeleteImportListExclusionPress}
|
||||||
|
>
|
||||||
|
{translate('Delete')}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
|
||||||
|
|
||||||
|
<SpinnerErrorButton
|
||||||
|
isSpinning={isSaving}
|
||||||
|
error={saveError}
|
||||||
|
onPress={onSavePress}
|
||||||
|
>
|
||||||
|
{translate('Save')}
|
||||||
|
</SpinnerErrorButton>
|
||||||
|
</ModalFooter>
|
||||||
|
</ModalContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EditImportListExclusionModalContent;
|
|
@ -1,117 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { createSelector } from 'reselect';
|
|
||||||
import { saveImportListExclusion, setImportListExclusionValue } from 'Store/Actions/settingsActions';
|
|
||||||
import selectSettings from 'Store/Selectors/selectSettings';
|
|
||||||
import EditImportListExclusionModalContent from './EditImportListExclusionModalContent';
|
|
||||||
|
|
||||||
const newImportListExclusion = {
|
|
||||||
title: '',
|
|
||||||
tvdbId: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
function createImportListExclusionSelector() {
|
|
||||||
return createSelector(
|
|
||||||
(state, { id }) => id,
|
|
||||||
(state) => state.settings.importListExclusions,
|
|
||||||
(id, importListExclusions) => {
|
|
||||||
const {
|
|
||||||
isFetching,
|
|
||||||
error,
|
|
||||||
isSaving,
|
|
||||||
saveError,
|
|
||||||
pendingChanges,
|
|
||||||
items
|
|
||||||
} = importListExclusions;
|
|
||||||
|
|
||||||
const mapping = id ? items.find((i) => i.id === id) : newImportListExclusion;
|
|
||||||
const settings = selectSettings(mapping, pendingChanges, saveError);
|
|
||||||
|
|
||||||
return {
|
|
||||||
id,
|
|
||||||
isFetching,
|
|
||||||
error,
|
|
||||||
isSaving,
|
|
||||||
saveError,
|
|
||||||
item: settings.settings,
|
|
||||||
...settings
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createMapStateToProps() {
|
|
||||||
return createSelector(
|
|
||||||
createImportListExclusionSelector(),
|
|
||||||
(importListExclusion) => {
|
|
||||||
return {
|
|
||||||
...importListExclusion
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
|
||||||
setImportListExclusionValue,
|
|
||||||
saveImportListExclusion
|
|
||||||
};
|
|
||||||
|
|
||||||
class EditImportListExclusionModalContentConnector extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
if (!this.props.id) {
|
|
||||||
Object.keys(newImportListExclusion).forEach((name) => {
|
|
||||||
this.props.setImportListExclusionValue({
|
|
||||||
name,
|
|
||||||
value: newImportListExclusion[name]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate(prevProps, prevState) {
|
|
||||||
if (prevProps.isSaving && !this.props.isSaving && !this.props.saveError) {
|
|
||||||
this.props.onModalClose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onInputChange = ({ name, value }) => {
|
|
||||||
this.props.setImportListExclusionValue({ name, value });
|
|
||||||
};
|
|
||||||
|
|
||||||
onSavePress = () => {
|
|
||||||
this.props.saveImportListExclusion({ id: this.props.id });
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<EditImportListExclusionModalContent
|
|
||||||
{...this.props}
|
|
||||||
onSavePress={this.onSavePress}
|
|
||||||
onInputChange={this.onInputChange}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EditImportListExclusionModalContentConnector.propTypes = {
|
|
||||||
id: PropTypes.number,
|
|
||||||
isSaving: PropTypes.bool.isRequired,
|
|
||||||
saveError: PropTypes.object,
|
|
||||||
item: PropTypes.object.isRequired,
|
|
||||||
setImportListExclusionValue: PropTypes.func.isRequired,
|
|
||||||
saveImportListExclusion: PropTypes.func.isRequired,
|
|
||||||
onModalClose: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(createMapStateToProps, mapDispatchToProps)(EditImportListExclusionModalContentConnector);
|
|
|
@ -1,25 +0,0 @@
|
||||||
.importListExclusion {
|
|
||||||
display: flex;
|
|
||||||
align-items: stretch;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
height: 30px;
|
|
||||||
border-bottom: 1px solid var(--borderColor);
|
|
||||||
line-height: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
@add-mixin truncate;
|
|
||||||
|
|
||||||
flex: 0 1 600px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tvdbId {
|
|
||||||
flex: 0 0 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
flex: 1 0 auto;
|
|
||||||
padding-right: 10px;
|
|
||||||
}
|
|
|
@ -2,9 +2,6 @@
|
||||||
// Please do not change this file!
|
// Please do not change this file!
|
||||||
interface CssExports {
|
interface CssExports {
|
||||||
'actions': string;
|
'actions': string;
|
||||||
'importListExclusion': string;
|
|
||||||
'title': string;
|
|
||||||
'tvdbId': string;
|
|
||||||
}
|
}
|
||||||
export const cssExports: CssExports;
|
export const cssExports: CssExports;
|
||||||
export default cssExports;
|
export default cssExports;
|
||||||
|
|
|
@ -1,112 +0,0 @@
|
||||||
import classNames from 'classnames';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import Icon from 'Components/Icon';
|
|
||||||
import Link from 'Components/Link/Link';
|
|
||||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
|
||||||
import { icons, kinds } from 'Helpers/Props';
|
|
||||||
import translate from 'Utilities/String/translate';
|
|
||||||
import EditImportListExclusionModalConnector from './EditImportListExclusionModalConnector';
|
|
||||||
import styles from './ImportListExclusion.css';
|
|
||||||
|
|
||||||
class ImportListExclusion extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
constructor(props, context) {
|
|
||||||
super(props, context);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
isEditImportListExclusionModalOpen: false,
|
|
||||||
isDeleteImportListExclusionModalOpen: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onEditImportListExclusionPress = () => {
|
|
||||||
this.setState({ isEditImportListExclusionModalOpen: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
onEditImportListExclusionModalClose = () => {
|
|
||||||
this.setState({ isEditImportListExclusionModalOpen: false });
|
|
||||||
};
|
|
||||||
|
|
||||||
onDeleteImportListExclusionPress = () => {
|
|
||||||
this.setState({
|
|
||||||
isEditImportListExclusionModalOpen: false,
|
|
||||||
isDeleteImportListExclusionModalOpen: true
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
onDeleteImportListExclusionModalClose = () => {
|
|
||||||
this.setState({ isDeleteImportListExclusionModalOpen: false });
|
|
||||||
};
|
|
||||||
|
|
||||||
onConfirmDeleteImportListExclusion = () => {
|
|
||||||
this.props.onConfirmDeleteImportListExclusion(this.props.id);
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
id,
|
|
||||||
title,
|
|
||||||
tvdbId
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={classNames(
|
|
||||||
styles.importListExclusion
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div className={styles.title}>{title}</div>
|
|
||||||
<div className={styles.tvdbId}>{tvdbId}</div>
|
|
||||||
|
|
||||||
<div className={styles.actions}>
|
|
||||||
<Link
|
|
||||||
onPress={this.onEditImportListExclusionPress}
|
|
||||||
>
|
|
||||||
<Icon name={icons.EDIT} />
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<EditImportListExclusionModalConnector
|
|
||||||
id={id}
|
|
||||||
isOpen={this.state.isEditImportListExclusionModalOpen}
|
|
||||||
onModalClose={this.onEditImportListExclusionModalClose}
|
|
||||||
onDeleteImportListExclusionPress={this.onDeleteImportListExclusionPress}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<ConfirmModal
|
|
||||||
isOpen={this.state.isDeleteImportListExclusionModalOpen}
|
|
||||||
kind={kinds.DANGER}
|
|
||||||
title={translate('DeleteImportListExclusion')}
|
|
||||||
message={translate('DeleteImportListExclusionMessageText')}
|
|
||||||
confirmLabel={translate('Delete')}
|
|
||||||
onConfirm={this.onConfirmDeleteImportListExclusion}
|
|
||||||
onCancel={this.onDeleteImportListExclusionModalClose}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImportListExclusion.propTypes = {
|
|
||||||
id: PropTypes.number.isRequired,
|
|
||||||
title: PropTypes.string.isRequired,
|
|
||||||
tvdbId: PropTypes.number.isRequired,
|
|
||||||
onConfirmDeleteImportListExclusion: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
ImportListExclusion.defaultProps = {
|
|
||||||
// The drag preview will not connect the drag handle.
|
|
||||||
connectDragSource: (node) => node
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ImportListExclusion;
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
.actions {
|
||||||
|
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||||
|
|
||||||
|
width: 35px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
7
frontend/src/Settings/ImportLists/ImportListExclusions/ImportListExclusionRow.css.d.ts
vendored
Normal file
7
frontend/src/Settings/ImportLists/ImportListExclusions/ImportListExclusionRow.css.d.ts
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// This file is automatically generated.
|
||||||
|
// Please do not change this file!
|
||||||
|
interface CssExports {
|
||||||
|
'actions': string;
|
||||||
|
}
|
||||||
|
export const cssExports: CssExports;
|
||||||
|
export default cssExports;
|
|
@ -0,0 +1,68 @@
|
||||||
|
import React, { useCallback } from 'react';
|
||||||
|
import IconButton from 'Components/Link/IconButton';
|
||||||
|
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||||
|
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
|
import TableRow from 'Components/Table/TableRow';
|
||||||
|
import useModalOpenState from 'Helpers/Hooks/useModalOpenState';
|
||||||
|
import { icons, kinds } from 'Helpers/Props';
|
||||||
|
import ImportListExclusion from 'typings/ImportListExclusion';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
|
import EditImportListExclusionModal from './EditImportListExclusionModal';
|
||||||
|
import styles from './ImportListExclusionRow.css';
|
||||||
|
|
||||||
|
interface ImportListExclusionRowProps extends ImportListExclusion {
|
||||||
|
onConfirmDeleteImportListExclusion: (id: number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ImportListExclusionRow(props: ImportListExclusionRowProps) {
|
||||||
|
const { id, title, tvdbId, onConfirmDeleteImportListExclusion } = props;
|
||||||
|
|
||||||
|
const [
|
||||||
|
isEditImportListExclusionModalOpen,
|
||||||
|
setEditImportListExclusionModalOpen,
|
||||||
|
setEditImportListExclusionModalClosed,
|
||||||
|
] = useModalOpenState(false);
|
||||||
|
|
||||||
|
const [
|
||||||
|
isDeleteImportListExclusionModalOpen,
|
||||||
|
setDeleteImportListExclusionModalOpen,
|
||||||
|
setDeleteImportListExclusionModalClosed,
|
||||||
|
] = useModalOpenState(false);
|
||||||
|
|
||||||
|
const onConfirmDeleteImportListExclusionPress = useCallback(() => {
|
||||||
|
onConfirmDeleteImportListExclusion(id);
|
||||||
|
}, [id, onConfirmDeleteImportListExclusion]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableRow>
|
||||||
|
<TableRowCell>{title}</TableRowCell>
|
||||||
|
<TableRowCell>{tvdbId}</TableRowCell>
|
||||||
|
|
||||||
|
<TableRowCell className={styles.actions}>
|
||||||
|
<IconButton
|
||||||
|
name={icons.EDIT}
|
||||||
|
onPress={setEditImportListExclusionModalOpen}
|
||||||
|
/>
|
||||||
|
</TableRowCell>
|
||||||
|
|
||||||
|
<EditImportListExclusionModal
|
||||||
|
id={id}
|
||||||
|
isOpen={isEditImportListExclusionModalOpen}
|
||||||
|
onModalClose={setEditImportListExclusionModalClosed}
|
||||||
|
onDeleteImportListExclusionPress={setDeleteImportListExclusionModalOpen}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ConfirmModal
|
||||||
|
isOpen={isDeleteImportListExclusionModalOpen}
|
||||||
|
kind={kinds.DANGER}
|
||||||
|
title={translate('DeleteImportListExclusion')}
|
||||||
|
message={translate('DeleteImportListExclusionMessageText')}
|
||||||
|
confirmLabel={translate('Delete')}
|
||||||
|
onConfirm={onConfirmDeleteImportListExclusionPress}
|
||||||
|
onCancel={setDeleteImportListExclusionModalClosed}
|
||||||
|
/>
|
||||||
|
</TableRow>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ImportListExclusionRow;
|
|
@ -1,23 +0,0 @@
|
||||||
.importListExclusionsHeader {
|
|
||||||
display: flex;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
flex: 0 1 600px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tvdbId {
|
|
||||||
flex: 0 0 70px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.addImportListExclusion {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
padding-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.addButton {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
|
@ -3,9 +3,6 @@
|
||||||
interface CssExports {
|
interface CssExports {
|
||||||
'addButton': string;
|
'addButton': string;
|
||||||
'addImportListExclusion': string;
|
'addImportListExclusion': string;
|
||||||
'importListExclusionsHeader': string;
|
|
||||||
'title': string;
|
|
||||||
'tvdbId': string;
|
|
||||||
}
|
}
|
||||||
export const cssExports: CssExports;
|
export const cssExports: CssExports;
|
||||||
export default cssExports;
|
export default cssExports;
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import FieldSet from 'Components/FieldSet';
|
|
||||||
import Icon from 'Components/Icon';
|
|
||||||
import Link from 'Components/Link/Link';
|
|
||||||
import PageSectionContent from 'Components/Page/PageSectionContent';
|
|
||||||
import { icons } from 'Helpers/Props';
|
|
||||||
import translate from 'Utilities/String/translate';
|
|
||||||
import EditImportListExclusionModalConnector from './EditImportListExclusionModalConnector';
|
|
||||||
import ImportListExclusion from './ImportListExclusion';
|
|
||||||
import styles from './ImportListExclusions.css';
|
|
||||||
|
|
||||||
class ImportListExclusions extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
constructor(props, context) {
|
|
||||||
super(props, context);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
isAddImportListExclusionModalOpen: false
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onAddImportListExclusionPress = () => {
|
|
||||||
this.setState({ isAddImportListExclusionModalOpen: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
onModalClose = () => {
|
|
||||||
this.setState({ isAddImportListExclusionModalOpen: false });
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const {
|
|
||||||
items,
|
|
||||||
onConfirmDeleteImportListExclusion,
|
|
||||||
...otherProps
|
|
||||||
} = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FieldSet legend={translate('ImportListExclusions')}>
|
|
||||||
<PageSectionContent
|
|
||||||
errorMessage={translate('ImportListExclusionsLoadError')}
|
|
||||||
{...otherProps}
|
|
||||||
>
|
|
||||||
<div className={styles.importListExclusionsHeader}>
|
|
||||||
<div className={styles.title}>
|
|
||||||
{translate('Title')}
|
|
||||||
</div>
|
|
||||||
<div className={styles.tvdbId}>
|
|
||||||
{translate('TvdbId')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
{
|
|
||||||
items.map((item, index) => {
|
|
||||||
return (
|
|
||||||
<ImportListExclusion
|
|
||||||
key={item.id}
|
|
||||||
{...item}
|
|
||||||
{...otherProps}
|
|
||||||
index={index}
|
|
||||||
onConfirmDeleteImportListExclusion={onConfirmDeleteImportListExclusion}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.addImportListExclusion}>
|
|
||||||
<Link
|
|
||||||
className={styles.addButton}
|
|
||||||
onPress={this.onAddImportListExclusionPress}
|
|
||||||
>
|
|
||||||
<Icon name={icons.ADD} />
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<EditImportListExclusionModalConnector
|
|
||||||
isOpen={this.state.isAddImportListExclusionModalOpen}
|
|
||||||
onModalClose={this.onModalClose}
|
|
||||||
/>
|
|
||||||
|
|
||||||
</PageSectionContent>
|
|
||||||
</FieldSet>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImportListExclusions.propTypes = {
|
|
||||||
isFetching: PropTypes.bool.isRequired,
|
|
||||||
error: PropTypes.object,
|
|
||||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
||||||
onConfirmDeleteImportListExclusion: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ImportListExclusions;
|
|
|
@ -0,0 +1,234 @@
|
||||||
|
import React, { useCallback, useEffect } from 'react';
|
||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import AppState from 'App/State/AppState';
|
||||||
|
import FieldSet from 'Components/FieldSet';
|
||||||
|
import IconButton from 'Components/Link/IconButton';
|
||||||
|
import PageSectionContent from 'Components/Page/PageSectionContent';
|
||||||
|
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
|
import Table from 'Components/Table/Table';
|
||||||
|
import TableBody from 'Components/Table/TableBody';
|
||||||
|
import TablePager from 'Components/Table/TablePager';
|
||||||
|
import TableRow from 'Components/Table/TableRow';
|
||||||
|
import useModalOpenState from 'Helpers/Hooks/useModalOpenState';
|
||||||
|
import { icons } from 'Helpers/Props';
|
||||||
|
import * as importListExclusionActions from 'Store/Actions/Settings/importListExclusions';
|
||||||
|
import {
|
||||||
|
registerPagePopulator,
|
||||||
|
unregisterPagePopulator,
|
||||||
|
} from 'Utilities/pagePopulator';
|
||||||
|
import translate from 'Utilities/String/translate';
|
||||||
|
import EditImportListExclusionModal from './EditImportListExclusionModal';
|
||||||
|
import ImportListExclusionRow from './ImportListExclusionRow';
|
||||||
|
|
||||||
|
const COLUMNS = [
|
||||||
|
{
|
||||||
|
name: 'title',
|
||||||
|
label: () => translate('Title'),
|
||||||
|
isVisible: true,
|
||||||
|
isSortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'tvdbid',
|
||||||
|
label: () => translate('TvdbId'),
|
||||||
|
isVisible: true,
|
||||||
|
isSortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'actions',
|
||||||
|
isVisible: true,
|
||||||
|
isSortable: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
interface ImportListExclusionsProps {
|
||||||
|
useCurrentPage: number;
|
||||||
|
totalRecords: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createImportListExlucionsSelector() {
|
||||||
|
return createSelector(
|
||||||
|
(state: AppState) => state.settings.importListExclusions,
|
||||||
|
(importListExclusions) => {
|
||||||
|
return {
|
||||||
|
...importListExclusions,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ImportListExclusions(props: ImportListExclusionsProps) {
|
||||||
|
const { useCurrentPage, totalRecords } = props;
|
||||||
|
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const fetchImportListExclusions = useCallback(() => {
|
||||||
|
dispatch(importListExclusionActions.fetchImportListExclusions());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
const deleteImportListExclusion = useCallback(
|
||||||
|
(payload: { id: number }) => {
|
||||||
|
dispatch(importListExclusionActions.deleteImportListExclusion(payload));
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
);
|
||||||
|
|
||||||
|
const gotoImportListExclusionFirstPage = useCallback(() => {
|
||||||
|
dispatch(importListExclusionActions.gotoImportListExclusionFirstPage());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
const gotoImportListExclusionPreviousPage = useCallback(() => {
|
||||||
|
dispatch(importListExclusionActions.gotoImportListExclusionPreviousPage());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
const gotoImportListExclusionNextPage = useCallback(() => {
|
||||||
|
dispatch(importListExclusionActions.gotoImportListExclusionNextPage());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
const gotoImportListExclusionLastPage = useCallback(() => {
|
||||||
|
dispatch(importListExclusionActions.gotoImportListExclusionLastPage());
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
const gotoImportListExclusionPage = useCallback(
|
||||||
|
(page: number) => {
|
||||||
|
dispatch(
|
||||||
|
importListExclusionActions.gotoImportListExclusionPage({ page })
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
);
|
||||||
|
|
||||||
|
const setImportListExclusionSort = useCallback(
|
||||||
|
(sortKey: { sortKey: string }) => {
|
||||||
|
dispatch(
|
||||||
|
importListExclusionActions.setImportListExclusionSort({ sortKey })
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
);
|
||||||
|
|
||||||
|
const setImportListTableOption = useCallback(
|
||||||
|
(payload: { pageSize: number }) => {
|
||||||
|
dispatch(
|
||||||
|
importListExclusionActions.setImportListExclusionTableOption(payload)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (payload.pageSize) {
|
||||||
|
dispatch(importListExclusionActions.gotoImportListExclusionFirstPage());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
);
|
||||||
|
|
||||||
|
const repopulate = useCallback(() => {
|
||||||
|
gotoImportListExclusionFirstPage();
|
||||||
|
}, [gotoImportListExclusionFirstPage]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
registerPagePopulator(repopulate);
|
||||||
|
|
||||||
|
if (useCurrentPage) {
|
||||||
|
fetchImportListExclusions();
|
||||||
|
} else {
|
||||||
|
gotoImportListExclusionFirstPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => unregisterPagePopulator(repopulate);
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onConfirmDeleteImportListExclusion = useCallback(
|
||||||
|
(id: number) => {
|
||||||
|
deleteImportListExclusion({ id });
|
||||||
|
repopulate();
|
||||||
|
},
|
||||||
|
[deleteImportListExclusion, repopulate]
|
||||||
|
);
|
||||||
|
|
||||||
|
const selected = useSelector(createImportListExlucionsSelector());
|
||||||
|
|
||||||
|
const {
|
||||||
|
isFetching,
|
||||||
|
isPopulated,
|
||||||
|
items,
|
||||||
|
pageSize,
|
||||||
|
sortKey,
|
||||||
|
error,
|
||||||
|
sortDirection,
|
||||||
|
...otherProps
|
||||||
|
} = selected;
|
||||||
|
|
||||||
|
const [
|
||||||
|
isAddImportListExclusionModalOpen,
|
||||||
|
setAddImportListExclusionModalOpen,
|
||||||
|
setAddImportListExclusionModalClosed,
|
||||||
|
] = useModalOpenState(false);
|
||||||
|
|
||||||
|
const isFetchingForFirstTime = isFetching && !isPopulated;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FieldSet legend={translate('ImportListExclusions')}>
|
||||||
|
<PageSectionContent
|
||||||
|
errorMessage={translate('ImportListExclusionsLoadError')}
|
||||||
|
isFetching={isFetchingForFirstTime}
|
||||||
|
isPopulated={isPopulated}
|
||||||
|
error={error}
|
||||||
|
>
|
||||||
|
<Table
|
||||||
|
columns={COLUMNS}
|
||||||
|
canModifyColumns={false}
|
||||||
|
pageSize={pageSize}
|
||||||
|
sortKey={sortKey}
|
||||||
|
sortDirection={sortDirection}
|
||||||
|
onSortPress={setImportListExclusionSort}
|
||||||
|
onTableOptionChange={setImportListTableOption}
|
||||||
|
>
|
||||||
|
<TableBody>
|
||||||
|
{items.map((item) => {
|
||||||
|
return (
|
||||||
|
<ImportListExclusionRow
|
||||||
|
key={item.id}
|
||||||
|
{...item}
|
||||||
|
onConfirmDeleteImportListExclusion={
|
||||||
|
onConfirmDeleteImportListExclusion
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
<TableRow>
|
||||||
|
<TableRowCell />
|
||||||
|
<TableRowCell />
|
||||||
|
|
||||||
|
<TableRowCell>
|
||||||
|
<IconButton
|
||||||
|
name={icons.ADD}
|
||||||
|
onPress={setAddImportListExclusionModalOpen}
|
||||||
|
/>
|
||||||
|
</TableRowCell>
|
||||||
|
</TableRow>
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
|
||||||
|
<TablePager
|
||||||
|
totalRecords={totalRecords}
|
||||||
|
pageSize={pageSize}
|
||||||
|
isFetching={isFetching}
|
||||||
|
onFirstPagePress={gotoImportListExclusionFirstPage}
|
||||||
|
onPreviousPagePress={gotoImportListExclusionPreviousPage}
|
||||||
|
onNextPagePress={gotoImportListExclusionNextPage}
|
||||||
|
onLastPagePress={gotoImportListExclusionLastPage}
|
||||||
|
onPageSelect={gotoImportListExclusionPage}
|
||||||
|
{...otherProps}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<EditImportListExclusionModal
|
||||||
|
isOpen={isAddImportListExclusionModalOpen}
|
||||||
|
onModalClose={setAddImportListExclusionModalClosed}
|
||||||
|
/>
|
||||||
|
</PageSectionContent>
|
||||||
|
</FieldSet>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ImportListExclusions;
|
|
@ -1,59 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { createSelector } from 'reselect';
|
|
||||||
import { deleteImportListExclusion, fetchImportListExclusions } from 'Store/Actions/settingsActions';
|
|
||||||
import ImportListExclusions from './ImportListExclusions';
|
|
||||||
|
|
||||||
function createMapStateToProps() {
|
|
||||||
return createSelector(
|
|
||||||
(state) => state.settings.importListExclusions,
|
|
||||||
(importListExclusions) => {
|
|
||||||
return {
|
|
||||||
...importListExclusions
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
|
||||||
fetchImportListExclusions,
|
|
||||||
deleteImportListExclusion
|
|
||||||
};
|
|
||||||
|
|
||||||
class ImportListExclusionsConnector extends Component {
|
|
||||||
|
|
||||||
//
|
|
||||||
// Lifecycle
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.props.fetchImportListExclusions();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Listeners
|
|
||||||
|
|
||||||
onConfirmDeleteImportListExclusion = (id) => {
|
|
||||||
this.props.deleteImportListExclusion({ id });
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Render
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<ImportListExclusions
|
|
||||||
{...this.state}
|
|
||||||
{...this.props}
|
|
||||||
onConfirmDeleteImportListExclusion={this.onConfirmDeleteImportListExclusion}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImportListExclusionsConnector.propTypes = {
|
|
||||||
fetchImportListExclusions: PropTypes.func.isRequired,
|
|
||||||
deleteImportListExclusion: PropTypes.func.isRequired
|
|
||||||
};
|
|
||||||
|
|
||||||
export default connect(createMapStateToProps, mapDispatchToProps)(ImportListExclusionsConnector);
|
|
|
@ -7,7 +7,7 @@ import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||||
import { icons } from 'Helpers/Props';
|
import { icons } from 'Helpers/Props';
|
||||||
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
import ImportListsExclusionsConnector from './ImportListExclusions/ImportListExclusionsConnector';
|
import ImportListsExclusions from './ImportListExclusions/ImportListExclusions';
|
||||||
import ImportListsConnector from './ImportLists/ImportListsConnector';
|
import ImportListsConnector from './ImportLists/ImportListsConnector';
|
||||||
import ManageImportListsModal from './ImportLists/Manage/ManageImportListsModal';
|
import ManageImportListsModal from './ImportLists/Manage/ManageImportListsModal';
|
||||||
import ImportListOptions from './Options/ImportListOptions';
|
import ImportListOptions from './Options/ImportListOptions';
|
||||||
|
@ -113,7 +113,7 @@ class ImportListSettings extends Component {
|
||||||
onChildStateChange={this.onChildStateChange}
|
onChildStateChange={this.onChildStateChange}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ImportListsExclusionsConnector />
|
<ImportListsExclusions />
|
||||||
<ManageImportListsModal
|
<ManageImportListsModal
|
||||||
isOpen={isManageImportListsOpen}
|
isOpen={isManageImportListsOpen}
|
||||||
onModalClose={this.onManageImportListsModalClose}
|
onModalClose={this.onManageImportListsModalClose}
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import { createAction } from 'redux-actions';
|
import { createAction } from 'redux-actions';
|
||||||
import createFetchHandler from 'Store/Actions/Creators/createFetchHandler';
|
|
||||||
import createRemoveItemHandler from 'Store/Actions/Creators/createRemoveItemHandler';
|
import createRemoveItemHandler from 'Store/Actions/Creators/createRemoveItemHandler';
|
||||||
import createSaveProviderHandler from 'Store/Actions/Creators/createSaveProviderHandler';
|
import createSaveProviderHandler from 'Store/Actions/Creators/createSaveProviderHandler';
|
||||||
import createSetSettingValueReducer from 'Store/Actions/Creators/Reducers/createSetSettingValueReducer';
|
import createSetSettingValueReducer from 'Store/Actions/Creators/Reducers/createSetSettingValueReducer';
|
||||||
import { createThunk } from 'Store/thunks';
|
import { createThunk, handleThunks } from 'Store/thunks';
|
||||||
|
import serverSideCollectionHandlers from 'Utilities/serverSideCollectionHandlers';
|
||||||
|
import createServerSideCollectionHandlers from '../Creators/createServerSideCollectionHandlers';
|
||||||
|
import createSetTableOptionReducer from '../Creators/Reducers/createSetTableOptionReducer';
|
||||||
|
|
||||||
//
|
//
|
||||||
// Variables
|
// Variables
|
||||||
|
@ -14,6 +16,13 @@ const section = 'settings.importListExclusions';
|
||||||
// Actions Types
|
// Actions Types
|
||||||
|
|
||||||
export const FETCH_IMPORT_LIST_EXCLUSIONS = 'settings/importListExclusions/fetchImportListExclusions';
|
export const FETCH_IMPORT_LIST_EXCLUSIONS = 'settings/importListExclusions/fetchImportListExclusions';
|
||||||
|
export const GOTO_FIRST_IMPORT_LIST_EXCLUSION_PAGE = 'settings/importListExclusions/gotoImportListExclusionFirstPage';
|
||||||
|
export const GOTO_PREVIOUS_IMPORT_LIST_EXCLUSION_PAGE = 'settings/importListExclusions/gotoImportListExclusionPreviousPage';
|
||||||
|
export const GOTO_NEXT_IMPORT_LIST_EXCLUSION_PAGE = 'settings/importListExclusions/gotoImportListExclusionNextPage';
|
||||||
|
export const GOTO_LAST_IMPORT_LIST_EXCLUSION_PAGE = 'settings/importListExclusions/gotoImportListExclusionLastPage';
|
||||||
|
export const GOTO_IMPORT_LIST_EXCLUSION_PAGE = 'settings/importListExclusions/gotoImportListExclusionPage';
|
||||||
|
export const SET_IMPORT_LIST_EXCLUSION_SORT = 'settings/importListExclusions/setImportListExclusionSort';
|
||||||
|
export const SET_IMPORT_LIST_EXCLUSION_TABLE_OPTION = 'settings/importListExclusions/setImportListExclusionTableOption';
|
||||||
export const SAVE_IMPORT_LIST_EXCLUSION = 'settings/importListExclusions/saveImportListExclusion';
|
export const SAVE_IMPORT_LIST_EXCLUSION = 'settings/importListExclusions/saveImportListExclusion';
|
||||||
export const DELETE_IMPORT_LIST_EXCLUSION = 'settings/importListExclusions/deleteImportListExclusion';
|
export const DELETE_IMPORT_LIST_EXCLUSION = 'settings/importListExclusions/deleteImportListExclusion';
|
||||||
export const SET_IMPORT_LIST_EXCLUSION_VALUE = 'settings/importListExclusions/setImportListExclusionValue';
|
export const SET_IMPORT_LIST_EXCLUSION_VALUE = 'settings/importListExclusions/setImportListExclusionValue';
|
||||||
|
@ -22,9 +31,16 @@ export const SET_IMPORT_LIST_EXCLUSION_VALUE = 'settings/importListExclusions/se
|
||||||
// Action Creators
|
// Action Creators
|
||||||
|
|
||||||
export const fetchImportListExclusions = createThunk(FETCH_IMPORT_LIST_EXCLUSIONS);
|
export const fetchImportListExclusions = createThunk(FETCH_IMPORT_LIST_EXCLUSIONS);
|
||||||
|
export const gotoImportListExclusionFirstPage = createThunk(GOTO_FIRST_IMPORT_LIST_EXCLUSION_PAGE);
|
||||||
|
export const gotoImportListExclusionPreviousPage = createThunk(GOTO_PREVIOUS_IMPORT_LIST_EXCLUSION_PAGE);
|
||||||
|
export const gotoImportListExclusionNextPage = createThunk(GOTO_NEXT_IMPORT_LIST_EXCLUSION_PAGE);
|
||||||
|
export const gotoImportListExclusionLastPage = createThunk(GOTO_LAST_IMPORT_LIST_EXCLUSION_PAGE);
|
||||||
|
export const gotoImportListExclusionPage = createThunk(GOTO_IMPORT_LIST_EXCLUSION_PAGE);
|
||||||
|
export const setImportListExclusionSort = createThunk(SET_IMPORT_LIST_EXCLUSION_SORT);
|
||||||
export const saveImportListExclusion = createThunk(SAVE_IMPORT_LIST_EXCLUSION);
|
export const saveImportListExclusion = createThunk(SAVE_IMPORT_LIST_EXCLUSION);
|
||||||
export const deleteImportListExclusion = createThunk(DELETE_IMPORT_LIST_EXCLUSION);
|
export const deleteImportListExclusion = createThunk(DELETE_IMPORT_LIST_EXCLUSION);
|
||||||
|
|
||||||
|
export const setImportListExclusionTableOption = createAction(SET_IMPORT_LIST_EXCLUSION_TABLE_OPTION);
|
||||||
export const setImportListExclusionValue = createAction(SET_IMPORT_LIST_EXCLUSION_VALUE, (payload) => {
|
export const setImportListExclusionValue = createAction(SET_IMPORT_LIST_EXCLUSION_VALUE, (payload) => {
|
||||||
return {
|
return {
|
||||||
section,
|
section,
|
||||||
|
@ -44,6 +60,7 @@ export default {
|
||||||
isFetching: false,
|
isFetching: false,
|
||||||
isPopulated: false,
|
isPopulated: false,
|
||||||
error: null,
|
error: null,
|
||||||
|
pageSize: 20,
|
||||||
items: [],
|
items: [],
|
||||||
isSaving: false,
|
isSaving: false,
|
||||||
saveError: null,
|
saveError: null,
|
||||||
|
@ -53,17 +70,31 @@ export default {
|
||||||
//
|
//
|
||||||
// Action Handlers
|
// Action Handlers
|
||||||
|
|
||||||
actionHandlers: {
|
actionHandlers: handleThunks({
|
||||||
[FETCH_IMPORT_LIST_EXCLUSIONS]: createFetchHandler(section, '/importlistexclusion'),
|
...createServerSideCollectionHandlers(
|
||||||
|
section,
|
||||||
|
'/importlistexclusion/paged',
|
||||||
|
fetchImportListExclusions,
|
||||||
|
{
|
||||||
|
[serverSideCollectionHandlers.FETCH]: FETCH_IMPORT_LIST_EXCLUSIONS,
|
||||||
|
[serverSideCollectionHandlers.FIRST_PAGE]: GOTO_FIRST_IMPORT_LIST_EXCLUSION_PAGE,
|
||||||
|
[serverSideCollectionHandlers.PREVIOUS_PAGE]: GOTO_PREVIOUS_IMPORT_LIST_EXCLUSION_PAGE,
|
||||||
|
[serverSideCollectionHandlers.NEXT_PAGE]: GOTO_NEXT_IMPORT_LIST_EXCLUSION_PAGE,
|
||||||
|
[serverSideCollectionHandlers.LAST_PAGE]: GOTO_LAST_IMPORT_LIST_EXCLUSION_PAGE,
|
||||||
|
[serverSideCollectionHandlers.EXACT_PAGE]: GOTO_IMPORT_LIST_EXCLUSION_PAGE,
|
||||||
|
[serverSideCollectionHandlers.SORT]: SET_IMPORT_LIST_EXCLUSION_SORT
|
||||||
|
}
|
||||||
|
),
|
||||||
[SAVE_IMPORT_LIST_EXCLUSION]: createSaveProviderHandler(section, '/importlistexclusion'),
|
[SAVE_IMPORT_LIST_EXCLUSION]: createSaveProviderHandler(section, '/importlistexclusion'),
|
||||||
[DELETE_IMPORT_LIST_EXCLUSION]: createRemoveItemHandler(section, '/importlistexclusion')
|
[DELETE_IMPORT_LIST_EXCLUSION]: createRemoveItemHandler(section, '/importlistexclusion')
|
||||||
},
|
}),
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reducers
|
// Reducers
|
||||||
|
|
||||||
reducers: {
|
reducers: {
|
||||||
[SET_IMPORT_LIST_EXCLUSION_VALUE]: createSetSettingValueReducer(section)
|
[SET_IMPORT_LIST_EXCLUSION_VALUE]: createSetSettingValueReducer(section),
|
||||||
|
[SET_IMPORT_LIST_EXCLUSION_TABLE_OPTION]: createSetTableOptionReducer(section)
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,45 +1,44 @@
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import AppSectionState, {
|
import { AppSectionItemState } from 'App/State/AppSectionState';
|
||||||
AppSectionItemState,
|
|
||||||
} from 'App/State/AppSectionState';
|
|
||||||
import AppState from 'App/State/AppState';
|
import AppState from 'App/State/AppState';
|
||||||
|
import SettingsAppState from 'App/State/SettingsAppState';
|
||||||
import selectSettings from 'Store/Selectors/selectSettings';
|
import selectSettings from 'Store/Selectors/selectSettings';
|
||||||
import { PendingSection } from 'typings/pending';
|
import { PendingSection } from 'typings/pending';
|
||||||
|
|
||||||
type SettingNames = keyof Omit<AppState['settings'], 'advancedSettings'>;
|
type SectionsWithItemNames = {
|
||||||
type GetSectionState<Name extends SettingNames> = AppState['settings'][Name];
|
[K in keyof SettingsAppState]: SettingsAppState[K] extends AppSectionItemState<unknown>
|
||||||
type GetSettingsSectionItemType<Name extends SettingNames> =
|
? K
|
||||||
GetSectionState<Name> extends AppSectionItemState<infer R>
|
|
||||||
? R
|
|
||||||
: GetSectionState<Name> extends AppSectionState<infer R>
|
|
||||||
? R
|
|
||||||
: never;
|
: never;
|
||||||
|
}[keyof SettingsAppState];
|
||||||
|
|
||||||
type AppStateWithPending<Name extends SettingNames> = {
|
type GetSectionState<Name extends SectionsWithItemNames> =
|
||||||
item?: GetSettingsSectionItemType<Name>;
|
SettingsAppState[Name];
|
||||||
pendingChanges?: Partial<GetSettingsSectionItemType<Name>>;
|
type GetSettingsSectionItemType<Name extends SectionsWithItemNames> =
|
||||||
saveError?: Error;
|
GetSectionState<Name> extends AppSectionItemState<infer R> ? R : never;
|
||||||
} & GetSectionState<Name>;
|
|
||||||
|
|
||||||
function createSettingsSectionSelector<Name extends SettingNames>(
|
function createSettingsSectionSelector<
|
||||||
section: Name
|
Name extends SectionsWithItemNames,
|
||||||
) {
|
T extends GetSettingsSectionItemType<Name>
|
||||||
|
>(section: Name) {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
(state: AppState) => state.settings[section],
|
(state: AppState) => state.settings[section],
|
||||||
(sectionSettings) => {
|
(sectionSettings) => {
|
||||||
const { item, pendingChanges, saveError, ...other } =
|
const { item, pendingChanges, ...other } = sectionSettings;
|
||||||
sectionSettings as AppStateWithPending<Name>;
|
|
||||||
|
|
||||||
const { settings, ...rest } = selectSettings(
|
const saveError =
|
||||||
item,
|
'saveError' in sectionSettings ? sectionSettings.saveError : undefined;
|
||||||
pendingChanges,
|
|
||||||
saveError
|
const {
|
||||||
);
|
settings,
|
||||||
|
pendingChanges: selectedPendingChanges,
|
||||||
|
...rest
|
||||||
|
} = selectSettings(item, pendingChanges, saveError);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...other,
|
...other,
|
||||||
saveError,
|
saveError,
|
||||||
settings: settings as PendingSection<GetSettingsSectionItemType<Name>>,
|
settings: settings as PendingSection<T>,
|
||||||
|
pendingChanges: selectedPendingChanges as Partial<T>,
|
||||||
...rest,
|
...rest,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
import ModelBase from 'App/ModelBase';
|
||||||
|
|
||||||
|
export default interface ImportListExclusion extends ModelBase {
|
||||||
|
tvdbId: number;
|
||||||
|
title: string;
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Messaging.Events;
|
using NzbDrone.Core.Messaging.Events;
|
||||||
using NzbDrone.Core.Tv.Events;
|
using NzbDrone.Core.Tv.Events;
|
||||||
|
|
||||||
|
@ -9,6 +10,7 @@ namespace NzbDrone.Core.ImportLists.Exclusions
|
||||||
{
|
{
|
||||||
ImportListExclusion Add(ImportListExclusion importListExclusion);
|
ImportListExclusion Add(ImportListExclusion importListExclusion);
|
||||||
List<ImportListExclusion> All();
|
List<ImportListExclusion> All();
|
||||||
|
PagingSpec<ImportListExclusion> Paged(PagingSpec<ImportListExclusion> pagingSpec);
|
||||||
void Delete(int id);
|
void Delete(int id);
|
||||||
ImportListExclusion Get(int id);
|
ImportListExclusion Get(int id);
|
||||||
ImportListExclusion FindByTvdbId(int tvdbId);
|
ImportListExclusion FindByTvdbId(int tvdbId);
|
||||||
|
@ -54,6 +56,11 @@ namespace NzbDrone.Core.ImportLists.Exclusions
|
||||||
return _repo.All().ToList();
|
return _repo.All().ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PagingSpec<ImportListExclusion> Paged(PagingSpec<ImportListExclusion> pagingSpec)
|
||||||
|
{
|
||||||
|
return _repo.GetPaged(pagingSpec);
|
||||||
|
}
|
||||||
|
|
||||||
public void HandleAsync(SeriesDeletedEvent message)
|
public void HandleAsync(SeriesDeletedEvent message)
|
||||||
{
|
{
|
||||||
if (!message.AddImportListExclusion)
|
if (!message.AddImportListExclusion)
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using FluentValidation;
|
using FluentValidation;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using NzbDrone.Core.ImportLists.Exclusions;
|
using NzbDrone.Core.ImportLists.Exclusions;
|
||||||
using Sonarr.Http;
|
using Sonarr.Http;
|
||||||
|
using Sonarr.Http.Extensions;
|
||||||
using Sonarr.Http.REST;
|
using Sonarr.Http.REST;
|
||||||
using Sonarr.Http.REST.Attributes;
|
using Sonarr.Http.REST.Attributes;
|
||||||
|
|
||||||
|
@ -29,11 +31,22 @@ namespace Sonarr.Api.V3.ImportLists
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Produces("application/json")]
|
[Produces("application/json")]
|
||||||
|
[Obsolete("Deprecated")]
|
||||||
public List<ImportListExclusionResource> GetImportListExclusions()
|
public List<ImportListExclusionResource> GetImportListExclusions()
|
||||||
{
|
{
|
||||||
return _importListExclusionService.All().ToResource();
|
return _importListExclusionService.All().ToResource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("paged")]
|
||||||
|
[Produces("application/json")]
|
||||||
|
public PagingResource<ImportListExclusionResource> GetImportListExclusionsPaged([FromQuery] PagingRequestResource paging)
|
||||||
|
{
|
||||||
|
var pagingResource = new PagingResource<ImportListExclusionResource>(paging);
|
||||||
|
var pageSpec = pagingResource.MapToPagingSpec<ImportListExclusionResource, ImportListExclusion>();
|
||||||
|
|
||||||
|
return pageSpec.ApplyToPage(_importListExclusionService.Paged, ImportListExclusionResourceMapper.ToResource);
|
||||||
|
}
|
||||||
|
|
||||||
[RestPostById]
|
[RestPostById]
|
||||||
[Consumes("application/json")]
|
[Consumes("application/json")]
|
||||||
public ActionResult<ImportListExclusionResource> AddImportListExclusion(ImportListExclusionResource resource)
|
public ActionResult<ImportListExclusionResource> AddImportListExclusion(ImportListExclusionResource resource)
|
||||||
|
|
Loading…
Reference in New Issue