Purge import exclusions lists

This commit is contained in:
Flavio De Stefano 2024-05-15 19:58:28 +00:00
parent 685f462959
commit 964cd05900
8 changed files with 107 additions and 16 deletions

View File

@ -13,12 +13,9 @@
flex: 0 0 70px;
}
.addImportExclusion {
.footerButtons {
display: flex;
justify-content: flex-end;
padding-right: 10px;
}
.addButton {
text-align: center;
gap: 10px;
}

View File

@ -1,8 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'addButton': string;
'addImportExclusion': string;
'footerButtons': string;
'importListExclusionsHeader': string;
'movieYear': string;
'title': string;

View File

@ -3,8 +3,9 @@ import React, { Component } from 'react';
import FieldSet from 'Components/FieldSet';
import Icon from 'Components/Icon';
import Link from 'Components/Link/Link';
import ConfirmModal from 'Components/Modal/ConfirmModal';
import PageSectionContent from 'Components/Page/PageSectionContent';
import { icons } from 'Helpers/Props';
import { icons, kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import EditImportListExclusionModalConnector from './EditImportListExclusionModalConnector';
import ImportListExclusion from './ImportListExclusion';
@ -19,7 +20,8 @@ class ImportListExclusions extends Component {
super(props, context);
this.state = {
isAddImportExclusionModalOpen: false
isAddImportExclusionModalOpen: false,
isPurgeImportExclusionModalOpen: false
};
}
@ -34,6 +36,19 @@ class ImportListExclusions extends Component {
this.setState({ isAddImportExclusionModalOpen: false });
};
onPurgeImportExclusionPress = () => {
this.setState({ isPurgeImportExclusionModalOpen: true });
};
onPurgeImportExclusionModalClose = () => {
this.setState({ isPurgeImportExclusionModalOpen: false });
};
onConfirmPurgeImportExclusions = () => {
this.props.onConfirmPurgeImportExclusions();
this.onPurgeImportExclusionModalClose();
};
//
// Render
@ -78,7 +93,14 @@ class ImportListExclusions extends Component {
}
</div>
<div className={styles.addImportExclusion}>
<div className={styles.footerButtons}>
<Link
className={styles.purgeButton}
onPress={this.onPurgeImportExclusionPress}
>
<Icon name={icons.DELETE} />
</Link>
<Link
className={styles.addButton}
onPress={this.onAddImportExclusionPress}
@ -92,6 +114,15 @@ class ImportListExclusions extends Component {
onModalClose={this.onModalClose}
/>
<ConfirmModal
isOpen={this.state.isPurgeImportExclusionModalOpen}
kind={kinds.DANGER}
title={translate('PurgeImportListExclusions')}
message={translate('PurgeImportListExclusionMessageText')}
confirmLabel={translate('Purge')}
onConfirm={this.onConfirmPurgeImportExclusions}
onCancel={this.onPurgeImportExclusionModalClose}
/>
</PageSectionContent>
</FieldSet>
);
@ -102,7 +133,8 @@ ImportListExclusions.propTypes = {
isFetching: PropTypes.bool.isRequired,
error: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
onConfirmDeleteImportExclusion: PropTypes.func.isRequired
onConfirmDeleteImportExclusion: PropTypes.func.isRequired,
onConfirmPurgeImportExclusions: PropTypes.func.isRequired
};
export default ImportListExclusions;

View File

@ -2,7 +2,11 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { deleteImportExclusion, fetchImportExclusions } from 'Store/Actions/settingsActions';
import {
deleteImportExclusion,
fetchImportExclusions,
purgeImportExclusions
} from 'Store/Actions/settingsActions';
import ImportListExclusions from './ImportListExclusions';
function createMapStateToProps() {
@ -18,11 +22,11 @@ function createMapStateToProps() {
const mapDispatchToProps = {
fetchImportExclusions,
deleteImportExclusion
deleteImportExclusion,
purgeImportExclusions
};
class ImportExclusionsConnector extends Component {
//
// Lifecycle
@ -37,6 +41,10 @@ class ImportExclusionsConnector extends Component {
this.props.deleteImportExclusion({ id });
};
onConfirmPurgeImportExclusions = () => {
this.props.purgeImportExclusions();
};
//
// Render
@ -46,6 +54,7 @@ class ImportExclusionsConnector extends Component {
{...this.state}
{...this.props}
onConfirmDeleteImportExclusion={this.onConfirmDeleteImportExclusion}
onConfirmPurgeImportExclusions={this.onConfirmPurgeImportExclusions}
/>
);
}
@ -53,7 +62,8 @@ class ImportExclusionsConnector extends Component {
ImportExclusionsConnector.propTypes = {
fetchImportExclusions: PropTypes.func.isRequired,
deleteImportExclusion: PropTypes.func.isRequired
deleteImportExclusion: PropTypes.func.isRequired,
purgeImportExclusions: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(ImportExclusionsConnector);

View File

@ -0,0 +1,36 @@
import createAjaxRequest from 'Utilities/createAjaxRequest';
import { set } from '../baseActions';
function createPurgeHandler(section, url) {
return function(getState, payload, dispatch) {
dispatch(set({ section, isPurging: true }));
const ajaxOptions = {
url: `${url}/purge`,
method: 'POST'
};
const { request } = createAjaxRequest(ajaxOptions);
request.done((data) => {
dispatch(
set({
section,
isPurging: false,
purgeError: null
})
);
});
request.fail((xhr) => {
dispatch(
set({
section,
isPurging: false
})
);
});
};
}
export default createPurgeHandler;

View File

@ -4,6 +4,7 @@ import createRemoveItemHandler from 'Store/Actions/Creators/createRemoveItemHand
import createSaveProviderHandler from 'Store/Actions/Creators/createSaveProviderHandler';
import createSetSettingValueReducer from 'Store/Actions/Creators/Reducers/createSetSettingValueReducer';
import { createThunk } from 'Store/thunks';
import createPurgeHandler from '../Creators/createPurgeHandler';
//
// Variables
@ -17,6 +18,7 @@ export const FETCH_IMPORT_EXCLUSIONS = 'settings/importExclusions/fetchImportExc
export const SAVE_IMPORT_EXCLUSION = 'settings/importExclusions/saveImportExclusion';
export const DELETE_IMPORT_EXCLUSION = 'settings/importExclusions/deleteImportExclusion';
export const SET_IMPORT_EXCLUSION_VALUE = 'settings/importExclusions/setImportExclusionValue';
export const PURGE_IMPORT_EXCLUSIONS = 'settings/importExclusions/purge';
//
// Action Creators
@ -26,6 +28,8 @@ export const fetchImportExclusions = createThunk(FETCH_IMPORT_EXCLUSIONS);
export const saveImportExclusion = createThunk(SAVE_IMPORT_EXCLUSION);
export const deleteImportExclusion = createThunk(DELETE_IMPORT_EXCLUSION);
export const purgeImportExclusions = createThunk(PURGE_IMPORT_EXCLUSIONS);
export const setImportExclusionValue = createAction(SET_IMPORT_EXCLUSION_VALUE, (payload) => {
return {
section,
@ -58,7 +62,8 @@ export default {
[FETCH_IMPORT_EXCLUSIONS]: createFetchHandler(section, '/exclusions'),
[SAVE_IMPORT_EXCLUSION]: createSaveProviderHandler(section, '/exclusions'),
[DELETE_IMPORT_EXCLUSION]: createRemoveItemHandler(section, '/exclusions')
[DELETE_IMPORT_EXCLUSION]: createRemoveItemHandler(section, '/exclusions'),
[PURGE_IMPORT_EXCLUSIONS]: createPurgeHandler(section, '/exclusions')
},
//

View File

@ -15,6 +15,7 @@ namespace NzbDrone.Core.ImportLists.ImportExclusions
void RemoveExclusion(ImportExclusion exclusion);
ImportExclusion GetById(int id);
ImportExclusion Update(ImportExclusion exclusion);
void Purge();
}
public class ImportExclusionsService : IImportExclusionsService, IHandleAsync<MoviesDeletedEvent>
@ -91,5 +92,10 @@ namespace NzbDrone.Core.ImportLists.ImportExclusions
.Where(x => !existingExclusions.Contains(x.TmdbId))
.ToList();
}
public void Purge()
{
_exclusionRepository.Purge();
}
}
}

View File

@ -63,5 +63,11 @@ namespace Radarr.Api.V3.ImportLists
{
_exclusionService.RemoveExclusion(new ImportExclusion { Id = id });
}
[HttpPost("purge")]
public void PurgeExclusions()
{
_exclusionService.Purge();
}
}
}