mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
Search and History Improvements
This commit is contained in:
@@ -30,7 +30,7 @@ function SearchIndexSortMenu(props) {
|
||||
</SortMenuItem>
|
||||
|
||||
<SortMenuItem
|
||||
name="sortTitle"
|
||||
name="title"
|
||||
sortKey={sortKey}
|
||||
sortDirection={sortDirection}
|
||||
onPress={onSortSelect}
|
||||
|
@@ -4,6 +4,7 @@ import IndexersSelectInputConnector from 'Components/Form/IndexersSelectInputCon
|
||||
import TextInput from 'Components/Form/TextInput';
|
||||
import SpinnerButton from 'Components/Link/SpinnerButton';
|
||||
import PageContentFooter from 'Components/Page/PageContentFooter';
|
||||
import SearchFooterLabel from './SearchFooterLabel';
|
||||
import styles from './SearchFooter.css';
|
||||
|
||||
class SearchFooter extends Component {
|
||||
@@ -61,9 +62,13 @@ class SearchFooter extends Component {
|
||||
return (
|
||||
<PageContentFooter>
|
||||
<div className={styles.inputContainer}>
|
||||
<SearchFooterLabel
|
||||
label={'Query'}
|
||||
isSaving={false}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
name='searchQuery'
|
||||
placeholder='Query'
|
||||
value={searchQuery}
|
||||
isDisabled={isFetching}
|
||||
onChange={this.onInputChange}
|
||||
@@ -71,6 +76,11 @@ class SearchFooter extends Component {
|
||||
</div>
|
||||
|
||||
<div className={styles.indexerContainer}>
|
||||
<SearchFooterLabel
|
||||
label={'Indexers'}
|
||||
isSaving={false}
|
||||
/>
|
||||
|
||||
<IndexersSelectInputConnector
|
||||
name='indexerIds'
|
||||
placeholder='Indexers'
|
||||
|
8
frontend/src/Search/SearchFooterLabel.css
Normal file
8
frontend/src/Search/SearchFooterLabel.css
Normal file
@@ -0,0 +1,8 @@
|
||||
.label {
|
||||
margin-bottom: 3px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.savingIcon {
|
||||
margin-left: 8px;
|
||||
}
|
40
frontend/src/Search/SearchFooterLabel.js
Normal file
40
frontend/src/Search/SearchFooterLabel.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import SpinnerIcon from 'Components/SpinnerIcon';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import styles from './SearchFooterLabel.css';
|
||||
|
||||
function SearchFooterLabel(props) {
|
||||
const {
|
||||
className,
|
||||
label,
|
||||
isSaving
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
{label}
|
||||
|
||||
{
|
||||
isSaving &&
|
||||
<SpinnerIcon
|
||||
className={styles.savingIcon}
|
||||
name={icons.SPINNER}
|
||||
isSpinning={true}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
SearchFooterLabel.propTypes = {
|
||||
className: PropTypes.string.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
isSaving: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
SearchFooterLabel.defaultProps = {
|
||||
className: styles.label
|
||||
};
|
||||
|
||||
export default SearchFooterLabel;
|
@@ -11,6 +11,7 @@ import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
|
||||
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
|
||||
import { align, icons, sortDirections } from 'Helpers/Props';
|
||||
import NoIndexer from 'Indexer/NoIndexer';
|
||||
import * as keyCodes from 'Utilities/Constants/keyCodes';
|
||||
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
||||
import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder';
|
||||
@@ -83,7 +84,7 @@ class SearchIndex extends Component {
|
||||
} = this.props;
|
||||
|
||||
// Reset if not sorting by sortTitle
|
||||
if (sortKey !== 'sortTitle') {
|
||||
if (sortKey !== 'title') {
|
||||
this.setState({ jumpBarItems: { order: [] } });
|
||||
return;
|
||||
}
|
||||
@@ -161,6 +162,7 @@ class SearchIndex extends Component {
|
||||
onScroll,
|
||||
onSortSelect,
|
||||
onFilterSelect,
|
||||
hasIndexers,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
@@ -174,8 +176,6 @@ class SearchIndex extends Component {
|
||||
const isLoaded = !!(!error && isPopulated && items.length && scroller);
|
||||
const hasNoIndexer = !totalItems;
|
||||
|
||||
console.log(hasNoIndexer);
|
||||
|
||||
return (
|
||||
<PageContent>
|
||||
<PageToolbar>
|
||||
@@ -247,7 +247,12 @@ class SearchIndex extends Component {
|
||||
}
|
||||
|
||||
{
|
||||
!error && !isFetching && !items.length &&
|
||||
!error && !isFetching && !hasIndexers &&
|
||||
<NoIndexer />
|
||||
}
|
||||
|
||||
{
|
||||
!error && !isFetching && hasIndexers && !items.length &&
|
||||
<NoSearchResults totalItems={totalItems} />
|
||||
}
|
||||
</PageContentBody>
|
||||
@@ -286,7 +291,8 @@ SearchIndex.propTypes = {
|
||||
onSortSelect: PropTypes.func.isRequired,
|
||||
onFilterSelect: PropTypes.func.isRequired,
|
||||
onSearchPress: PropTypes.func.isRequired,
|
||||
onScroll: PropTypes.func.isRequired
|
||||
onScroll: PropTypes.func.isRequired,
|
||||
hasIndexers: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default SearchIndex;
|
||||
|
@@ -6,19 +6,23 @@ import withScrollPosition from 'Components/withScrollPosition';
|
||||
import { fetchReleases, setReleasesFilter, setReleasesSort, setReleasesTableOption } from 'Store/Actions/releaseActions';
|
||||
import scrollPositions from 'Store/scrollPositions';
|
||||
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
|
||||
import createIndexerClientSideCollectionItemsSelector from 'Store/Selectors/createIndexerClientSideCollectionItemsSelector';
|
||||
import createReleaseClientSideCollectionItemsSelector from 'Store/Selectors/createReleaseClientSideCollectionItemsSelector';
|
||||
import SearchIndex from './SearchIndex';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createIndexerClientSideCollectionItemsSelector('indexerIndex'),
|
||||
createReleaseClientSideCollectionItemsSelector('releases'),
|
||||
createDimensionsSelector(),
|
||||
(
|
||||
movies,
|
||||
indexers,
|
||||
releases,
|
||||
dimensionsState
|
||||
) => {
|
||||
return {
|
||||
...movies,
|
||||
...releases,
|
||||
hasIndexers: indexers.items.length > 0,
|
||||
isSmallScreen: dimensionsState.isSmallScreen
|
||||
};
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
.status {
|
||||
.protocol {
|
||||
composes: headerCell from '~Components/Table/VirtualTableHeaderCell.css';
|
||||
|
||||
flex: 0 0 60px;
|
||||
|
@@ -5,7 +5,7 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.status {
|
||||
.protocol {
|
||||
composes: cell;
|
||||
|
||||
flex: 0 0 60px;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { setMovieSort } from 'Store/Actions/indexerIndexActions';
|
||||
import { setReleasesSort } from 'Store/Actions/releaseActions';
|
||||
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
|
||||
import SearchIndexTable from './SearchIndexTable';
|
||||
|
||||
@@ -23,7 +23,7 @@ function createMapStateToProps() {
|
||||
function createMapDispatchToProps(dispatch, props) {
|
||||
return {
|
||||
onSortPress(sortKey) {
|
||||
dispatch(setMovieSort({ sortKey }));
|
||||
dispatch(setReleasesSort({ sortKey }));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user