New: Filter tracks by title or number in Manual Import

(cherry picked from commit 73ed5f6ee27a9de1844d6e7caf26f765b082fe21)
This commit is contained in:
Andrew Champion 2020-07-10 11:25:24 +01:00 committed by bakerboy448
parent 6adbbf81ed
commit 95089080f4
5 changed files with 151 additions and 57 deletions

View file

@ -197,7 +197,6 @@ class ArtistDetails extends Component {
overview,
links,
images,
artistType,
alternateTitles,
tags,
isSaving,

View file

@ -0,0 +1,51 @@
.modalBody {
composes: modalBody from '~Components/Modal/ModalBody.css';
display: flex;
flex: 1 1 auto;
flex-direction: column;
}
.filterInput {
composes: input from '~Components/Form/TextInput.css';
flex: 0 0 auto;
margin-bottom: 20px;
}
.scroller {
flex: 1 1 auto;
}
.footer {
composes: modalFooter from '~Components/Modal/ModalFooter.css';
display: flex;
justify-content: space-between;
overflow: hidden;
}
.path {
margin-right: 20px;
color: var(--dimColor);
}
.buttons {
display: flex;
}
@media only screen and (max-width: $breakpointSmall) {
.footer {
display: block;
}
.path {
margin-right: 0;
margin-bottom: 10px;
}
.buttons {
justify-content: space-between;
flex-grow: 1;
}
}

View file

@ -0,0 +1,12 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'buttons': string;
'filterInput': string;
'footer': string;
'modalBody': string;
'path': string;
'scroller': string;
}
export const cssExports: CssExports;
export default cssExports;

View file

@ -1,15 +1,17 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import TextInput from 'Components/Form/TextInput';
import Button from 'Components/Link/Button';
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 Scroller from 'Components/Scroller/Scroller';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import { kinds } from 'Helpers/Props';
import { kinds, scrollDirections } from 'Helpers/Props';
import ExpandingFileDetails from 'TrackFile/ExpandingFileDetails';
import getErrorMessage from 'Utilities/Object/getErrorMessage';
import translate from 'Utilities/String/translate';
@ -17,6 +19,7 @@ import getSelectedIds from 'Utilities/Table/getSelectedIds';
import selectAll from 'Utilities/Table/selectAll';
import toggleSelected from 'Utilities/Table/toggleSelected';
import SelectTrackRow from './SelectTrackRow';
import styles from './SelectTrackModalContent.css';
const columns = [
{
@ -65,11 +68,12 @@ class SelectTrackModalContent extends Component {
this.state = {
allSelected: false,
allUnselected: false,
filter: '',
lastToggled: null,
selectedState: init
};
props.onSortPress( props.sortKey, props.sortDirection );
props.onSortPress(props.sortKey, props.sortDirection);
}
//
@ -82,6 +86,10 @@ class SelectTrackModalContent extends Component {
//
// Listeners
onFilterChange = ({ value }) => {
this.setState({ filter: value.toLowerCase() });
};
onSelectAllChange = ({ value }) => {
this.setState(selectAll(this.state.selectedState, value));
};
@ -119,8 +127,10 @@ class SelectTrackModalContent extends Component {
const {
allSelected,
allUnselected,
filter,
selectedState
} = this.state;
const filterTrackNumber = parseInt(filter);
const errorMessage = getErrorMessage(error, 'Unable to load tracks');
@ -141,15 +151,29 @@ class SelectTrackModalContent extends Component {
{translate('ManualImport')} - {translate('SelectTracks')}
</ModalHeader>
<ModalBody>
<ModalBody
className={styles.modalBody}
scrollDirection={scrollDirections.NONE}
>
<TextInput
className={styles.filterInput}
placeholder={translate('FilterTracksByTitleOrNumber')}
name="filter"
value={filter}
autoFocus={true}
onChange={this.onFilterChange}
/>
<Scroller
className={styles.scroller}
autoFocus={false}
>
{
isFetching &&
<LoadingIndicator />
isFetching ? <LoadingIndicator /> : null
}
{
error &&
<div>{errorMessage}</div>
error ? <div>{errorMessage}</div> : null
}
<ExpandingFileDetails
@ -160,7 +184,7 @@ class SelectTrackModalContent extends Component {
/>
{
isPopulated && !!items.length &&
isPopulated && !!items.length ?
<Table
columns={selectAllEnabled ? columns : selectAllBlankColumn.concat(columns)}
selectAll={selectAllEnabled}
@ -174,7 +198,10 @@ class SelectTrackModalContent extends Component {
<TableBody>
{
items.map((item) => {
return (
return item.title.toLowerCase().includes(filter) ||
item.absoluteTrackNumber === filterTrackNumber ||
item.trackNumber === filterTrackNumber ?
(
<SelectTrackRow
key={item.id}
id={item.id}
@ -187,17 +214,21 @@ class SelectTrackModalContent extends Component {
isSelected={selectedState[item.id]}
onSelectedChange={this.onSelectedChange}
/>
);
) :
null;
})
}
</TableBody>
</Table>
</Table> :
null
}
{
isPopulated && !items.length &&
'No tracks were found for the selected album'
isPopulated && !items.length ?
translate('NoTracksFoundForSelectedAlbum') :
null
}
</Scroller>
</ModalBody>
<ModalFooter>

View file

@ -830,6 +830,7 @@
"NoMediumInformation": "No medium information is available.",
"NoMinimumForAnyDuration": "No minimum for any duration",
"NoMissingItems": "No missing items",
"NoTracksFoundForSelectedAlbum": "No tracks were found for the selected album",
"NoResultsFound": "No results found",
"NoTagsHaveBeenAddedYet": "No tags have been added yet",
"NoTracksInThisMedium": "No tracks in this medium",