mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
New: Bulk Grab Releases and Parameter Search
This commit is contained in:
@@ -18,6 +18,9 @@ import * as keyCodes from 'Utilities/Constants/keyCodes';
|
||||
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
||||
import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||
import selectAll from 'Utilities/Table/selectAll';
|
||||
import toggleSelected from 'Utilities/Table/toggleSelected';
|
||||
import SearchIndexFilterMenu from './Menus/SearchIndexFilterMenu';
|
||||
import SearchIndexSortMenu from './Menus/SearchIndexSortMenu';
|
||||
import NoSearchResults from './NoSearchResults';
|
||||
@@ -44,12 +47,16 @@ class SearchIndex extends Component {
|
||||
isAddIndexerModalOpen: false,
|
||||
isEditIndexerModalOpen: false,
|
||||
searchType: null,
|
||||
lastToggled: null
|
||||
lastToggled: null,
|
||||
allSelected: false,
|
||||
allUnselected: false,
|
||||
selectedState: {}
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setJumpBarItems();
|
||||
this.setSelectedState();
|
||||
|
||||
window.addEventListener('keyup', this.onKeyUp);
|
||||
}
|
||||
@@ -66,6 +73,7 @@ class SearchIndex extends Component {
|
||||
hasDifferentItemsOrOrder(prevProps.items, items)
|
||||
) {
|
||||
this.setJumpBarItems();
|
||||
this.setSelectedState();
|
||||
}
|
||||
|
||||
if (this.state.jumpToCharacter != null) {
|
||||
@@ -80,6 +88,48 @@ class SearchIndex extends Component {
|
||||
this.setState({ scroller: ref });
|
||||
}
|
||||
|
||||
getSelectedIds = () => {
|
||||
if (this.state.allUnselected) {
|
||||
return [];
|
||||
}
|
||||
return getSelectedIds(this.state.selectedState, { parseIds: false });
|
||||
}
|
||||
|
||||
setSelectedState() {
|
||||
const {
|
||||
items
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
selectedState
|
||||
} = this.state;
|
||||
|
||||
const newSelectedState = {};
|
||||
|
||||
items.forEach((release) => {
|
||||
const isItemSelected = selectedState[release.guid];
|
||||
|
||||
if (isItemSelected) {
|
||||
newSelectedState[release.guid] = isItemSelected;
|
||||
} else {
|
||||
newSelectedState[release.guid] = false;
|
||||
}
|
||||
});
|
||||
|
||||
const selectedCount = getSelectedIds(newSelectedState).length;
|
||||
const newStateCount = Object.keys(newSelectedState).length;
|
||||
let isAllSelected = false;
|
||||
let isAllUnselected = false;
|
||||
|
||||
if (selectedCount === 0) {
|
||||
isAllUnselected = true;
|
||||
} else if (selectedCount === newStateCount) {
|
||||
isAllSelected = true;
|
||||
}
|
||||
|
||||
this.setState({ selectedState: newSelectedState, allSelected: isAllSelected, allUnselected: isAllUnselected });
|
||||
}
|
||||
|
||||
setJumpBarItems() {
|
||||
const {
|
||||
items,
|
||||
@@ -146,8 +196,14 @@ class SearchIndex extends Component {
|
||||
this.setState({ jumpToCharacter });
|
||||
}
|
||||
|
||||
onSearchPress = (query, indexerIds, categories) => {
|
||||
this.props.onSearchPress({ query, indexerIds, categories });
|
||||
onSearchPress = (query, indexerIds, categories, type) => {
|
||||
this.props.onSearchPress({ query, indexerIds, categories, type });
|
||||
}
|
||||
|
||||
onBulkGrabPress = () => {
|
||||
const selectedIds = this.getSelectedIds();
|
||||
const result = _.filter(this.props.items, (release) => _.indexOf(selectedIds, release.guid) !== -1);
|
||||
this.props.onBulkGrabPress(result);
|
||||
}
|
||||
|
||||
onKeyUp = (event) => {
|
||||
@@ -162,6 +218,20 @@ class SearchIndex extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
onSelectAllChange = ({ value }) => {
|
||||
this.setState(selectAll(this.state.selectedState, value));
|
||||
}
|
||||
|
||||
onSelectAllPress = () => {
|
||||
this.onSelectAllChange({ value: !this.state.allSelected });
|
||||
}
|
||||
|
||||
onSelectedChange = ({ id, value, shiftKey = false }) => {
|
||||
this.setState((state) => {
|
||||
return toggleSelected(state, this.props.items, id, value, shiftKey);
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
@@ -169,7 +239,9 @@ class SearchIndex extends Component {
|
||||
const {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
isGrabbing,
|
||||
error,
|
||||
grabError,
|
||||
totalItems,
|
||||
items,
|
||||
columns,
|
||||
@@ -190,9 +262,14 @@ class SearchIndex extends Component {
|
||||
jumpBarItems,
|
||||
isAddIndexerModalOpen,
|
||||
isEditIndexerModalOpen,
|
||||
jumpToCharacter
|
||||
jumpToCharacter,
|
||||
selectedState,
|
||||
allSelected,
|
||||
allUnselected
|
||||
} = this.state;
|
||||
|
||||
const selectedIndexerIds = this.getSelectedIds();
|
||||
|
||||
const ViewComponent = getViewComponent();
|
||||
const isLoaded = !!(!error && isPopulated && items.length && scroller);
|
||||
const hasNoIndexer = !totalItems;
|
||||
@@ -263,6 +340,11 @@ class SearchIndex extends Component {
|
||||
sortDirection={sortDirection}
|
||||
columns={columns}
|
||||
jumpToCharacter={jumpToCharacter}
|
||||
allSelected={allSelected}
|
||||
allUnselected={allUnselected}
|
||||
onSelectedChange={this.onSelectedChange}
|
||||
onSelectAllChange={this.onSelectAllChange}
|
||||
selectedState={selectedState}
|
||||
{...otherProps}
|
||||
/>
|
||||
</div>
|
||||
@@ -293,8 +375,14 @@ class SearchIndex extends Component {
|
||||
|
||||
<SearchFooterConnector
|
||||
isFetching={isFetching}
|
||||
isPopulated={isPopulated}
|
||||
isGrabbing={isGrabbing}
|
||||
grabError={grabError}
|
||||
selectedCount={selectedIndexerIds.length}
|
||||
itemCount={items.length}
|
||||
hasIndexers={hasIndexers}
|
||||
onSearchPress={this.onSearchPress}
|
||||
onBulkGrabPress={this.onBulkGrabPress}
|
||||
/>
|
||||
|
||||
<AddIndexerModal
|
||||
@@ -314,7 +402,9 @@ class SearchIndex extends Component {
|
||||
SearchIndex.propTypes = {
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired,
|
||||
isGrabbing: PropTypes.bool.isRequired,
|
||||
error: PropTypes.object,
|
||||
grabError: PropTypes.object,
|
||||
totalItems: PropTypes.number.isRequired,
|
||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
@@ -327,6 +417,7 @@ SearchIndex.propTypes = {
|
||||
onSortSelect: PropTypes.func.isRequired,
|
||||
onFilterSelect: PropTypes.func.isRequired,
|
||||
onSearchPress: PropTypes.func.isRequired,
|
||||
onBulkGrabPress: PropTypes.func.isRequired,
|
||||
onScroll: PropTypes.func.isRequired,
|
||||
hasIndexers: PropTypes.bool.isRequired
|
||||
};
|
||||
|
Reference in New Issue
Block a user