New: Clear all history from History page

pull/40/head
Qstick 3 years ago
parent aa6bda7226
commit eb328d7c22

@ -1,5 +1,6 @@
export const APPLICATION_UPDATE = 'ApplicationUpdate';
export const BACKUP = 'Backup';
export const CLEAR_HISTORY = 'ClearHistory';
export const CLEAR_LOGS = 'ClearLog';
export const DELETE_LOG_FILES = 'DeleteLogFiles';
export const DELETE_UPDATE_LOG_FILES = 'DeleteUpdateLogFiles';

@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import FilterMenu from 'Components/Menu/FilterMenu';
import ConfirmModal from 'Components/Modal/ConfirmModal';
import PageContent from 'Components/Page/PageContent';
import PageContentBody from 'Components/Page/PageContentBody';
import PageToolbar from 'Components/Page/Toolbar/PageToolbar';
@ -11,13 +12,40 @@ import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
import TablePager from 'Components/Table/TablePager';
import { align, icons } from 'Helpers/Props';
import { align, icons, kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import HistoryOptionsConnector from './HistoryOptionsConnector';
import HistoryRowConnector from './HistoryRowConnector';
class History extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
this.state = {
isClearHistoryModalOpen: false
};
}
//
// Listeners
onClearHistoryPress = () => {
this.setState({ isClearHistoryModalOpen: true });
}
onClearHistoryModalClose = () => {
this.setState({ isClearHistoryModalOpen: false });
}
onConfirmClearHistory = () => {
this.setState({ isClearHistoryModalOpen: false });
this.props.onClearHistoryPress();
}
//
// Render
@ -25,9 +53,10 @@ class History extends Component {
const {
isFetching,
isPopulated,
isHistoryClearing,
error,
isMoviesFetching,
isMoviesPopulated,
isIndexersFetching,
isIndexersPopulated,
indexersError,
items,
columns,
@ -36,11 +65,12 @@ class History extends Component {
totalRecords,
onFilterSelect,
onFirstPagePress,
onClearHistoryPress,
...otherProps
} = this.props;
const isFetchingAny = isFetching || isMoviesFetching;
const isAllPopulated = isPopulated && (isMoviesPopulated || !items.length);
const isFetchingAny = isFetching || isIndexersFetching;
const isAllPopulated = isPopulated && (isIndexersPopulated || !items.length);
const hasError = error || indexersError;
return (
@ -53,6 +83,12 @@ class History extends Component {
isSpinning={isFetching}
onPress={onFirstPagePress}
/>
<PageToolbarButton
label={translate('Clear')}
iconName={icons.DELETE}
isSpinning={isHistoryClearing}
onPress={this.onClearHistoryPress}
/>
</PageToolbarSection>
<PageToolbarSection alignContent={align.RIGHT}>
@ -131,6 +167,16 @@ class History extends Component {
</div>
}
</PageContentBody>
<ConfirmModal
isOpen={this.state.isClearHistoryModalOpen}
kind={kinds.DANGER}
title={translate('ClearHistory')}
message={translate('ClearHistoryMessageText')}
confirmLabel={translate('Delete')}
onConfirm={this.onConfirmClearHistory}
onCancel={this.onClearHistoryModalClose}
/>
</PageContent>
);
}
@ -139,9 +185,10 @@ class History extends Component {
History.propTypes = {
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
isHistoryClearing: PropTypes.bool.isRequired,
error: PropTypes.object,
isMoviesFetching: PropTypes.bool.isRequired,
isMoviesPopulated: PropTypes.bool.isRequired,
isIndexersFetching: PropTypes.bool.isRequired,
isIndexersPopulated: PropTypes.bool.isRequired,
indexersError: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
@ -149,7 +196,8 @@ History.propTypes = {
filters: PropTypes.arrayOf(PropTypes.object).isRequired,
totalRecords: PropTypes.number,
onFilterSelect: PropTypes.func.isRequired,
onFirstPagePress: PropTypes.func.isRequired
onFirstPagePress: PropTypes.func.isRequired,
onClearHistoryPress: PropTypes.func.isRequired
};
export default History;

@ -2,8 +2,11 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import * as commandNames from 'Commands/commandNames';
import withCurrentPage from 'Components/withCurrentPage';
import { executeCommand } from 'Store/Actions/commandActions';
import * as historyActions from 'Store/Actions/historyActions';
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
import History from './History';
@ -11,11 +14,13 @@ function createMapStateToProps() {
return createSelector(
(state) => state.history,
(state) => state.indexers,
(history, indexers) => {
createCommandExecutingSelector(commandNames.CLEAR_HISTORY),
(history, indexers, isHistoryClearing) => {
return {
isMoviesFetching: indexers.isFetching,
isMoviesPopulated: indexers.isPopulated,
isIndexersFetching: indexers.isFetching,
isIndexersPopulated: indexers.isPopulated,
indexersError: indexers.error,
isHistoryClearing,
...history
};
}
@ -23,6 +28,7 @@ function createMapStateToProps() {
}
const mapDispatchToProps = {
executeCommand,
...historyActions
};
@ -47,6 +53,12 @@ class HistoryConnector extends Component {
}
}
componentDidUpdate(prevProps) {
if (prevProps.isHistoryClearing && !this.props.isHistoryClearing) {
this.props.gotoHistoryFirstPage();
}
}
componentWillUnmount() {
unregisterPagePopulator(this.repopulate);
this.props.clearHistory();
@ -90,6 +102,10 @@ class HistoryConnector extends Component {
this.props.setHistoryFilter({ selectedFilterKey });
}
onClearHistoryPress = () => {
this.props.executeCommand({ name: commandNames.CLEAR_HISTORY });
}
onTableOptionChange = (payload) => {
this.props.setHistoryTableOption(payload);
@ -112,6 +128,7 @@ class HistoryConnector extends Component {
onSortPress={this.onSortPress}
onFilterSelect={this.onFilterSelect}
onTableOptionChange={this.onTableOptionChange}
onClearHistoryPress={this.onClearHistoryPress}
{...this.props}
/>
);
@ -122,6 +139,8 @@ HistoryConnector.propTypes = {
useCurrentPage: PropTypes.bool.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
fetchHistory: PropTypes.func.isRequired,
clearHistory: PropTypes.func.isRequired,
isHistoryClearing: PropTypes.bool.isRequired,
gotoHistoryFirstPage: PropTypes.func.isRequired,
gotoHistoryPreviousPage: PropTypes.func.isRequired,
gotoHistoryNextPage: PropTypes.func.isRequired,
@ -130,7 +149,7 @@ HistoryConnector.propTypes = {
setHistorySort: PropTypes.func.isRequired,
setHistoryFilter: PropTypes.func.isRequired,
setHistoryTableOption: PropTypes.func.isRequired,
clearHistory: PropTypes.func.isRequired
executeCommand: PropTypes.func.isRequired
};
export default withCurrentPage(

@ -51,8 +51,6 @@ class HistoryRow extends Component {
});
}
console.log(categories);
this.props.onSearchPress(data.query, indexer.id, categories);
}

@ -34,7 +34,6 @@ class SearchFooterConnector extends Component {
// Listeners
onInputChange = ({ name, value }) => {
console.log(name, value);
this.props.setSearchDefault({ [name]: value });
}

@ -108,7 +108,6 @@ export const defaultState = {
sortPredicates: {
age: function(item) {
console.log(item);
return item.ageMinutes;
},

@ -0,0 +1,9 @@
using NzbDrone.Core.Messaging.Commands;
namespace NzbDrone.Core.History
{
public class ClearHistoryCommand : Command
{
public override bool SendUpdatesToClient => true;
}
}

@ -31,7 +31,8 @@ namespace NzbDrone.Core.History
IHandle<IndexerQueryEvent>,
IHandle<IndexerDownloadEvent>,
IHandle<IndexerAuthEvent>,
IExecute<CleanUpHistoryCommand>
IExecute<CleanUpHistoryCommand>,
IExecute<ClearHistoryCommand>
{
private readonly IHistoryRepository _historyRepository;
private readonly IConfigService _configService;
@ -197,5 +198,10 @@ namespace NzbDrone.Core.History
{
Cleanup();
}
public void Execute(ClearHistoryCommand message)
{
_historyRepository.Purge(vacuum: true);
}
}
}

@ -47,6 +47,8 @@
"CertificateValidationHelpText": "Change how strict HTTPS certification validation is",
"ChangeHasNotBeenSavedYet": "Change has not been saved yet",
"Clear": "Clear",
"ClearHistory": "Clear History",
"ClearHistoryMessageText": "Are you sure you want to clear all Prowlarr history?",
"ClientPriority": "Client Priority",
"CloneIndexer": "Clone Indexer",
"Close": "Close",

Loading…
Cancel
Save