New: Filter episodes by title or number in Manual Import

Closes #3862
pull/3902/head
Andrew Champion 4 years ago committed by Mark McDowall
parent a6b8a34ac9
commit 73ed5f6ee2

@ -52,6 +52,7 @@ function Table(props) {
scrollDirections.HORIZONTAL : scrollDirections.HORIZONTAL :
scrollDirections.NONE scrollDirections.NONE
} }
autoFocus={false}
> >
<table className={className}> <table className={className}>
<TableHeader> <TableHeader>

@ -1,3 +1,22 @@
.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 { .footer {
composes: modalFooter from '~Components/Modal/ModalFooter.css'; composes: modalFooter from '~Components/Modal/ModalFooter.css';

@ -4,13 +4,15 @@ import getErrorMessage from 'Utilities/Object/getErrorMessage';
import getSelectedIds from 'Utilities/Table/getSelectedIds'; import getSelectedIds from 'Utilities/Table/getSelectedIds';
import selectAll from 'Utilities/Table/selectAll'; import selectAll from 'Utilities/Table/selectAll';
import toggleSelected from 'Utilities/Table/toggleSelected'; import toggleSelected from 'Utilities/Table/toggleSelected';
import { kinds } from 'Helpers/Props'; import { kinds, scrollDirections } from 'Helpers/Props';
import TextInput from 'Components/Form/TextInput';
import Button from 'Components/Link/Button'; import Button from 'Components/Link/Button';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import ModalContent from 'Components/Modal/ModalContent'; import ModalContent from 'Components/Modal/ModalContent';
import ModalHeader from 'Components/Modal/ModalHeader'; import ModalHeader from 'Components/Modal/ModalHeader';
import ModalBody from 'Components/Modal/ModalBody'; import ModalBody from 'Components/Modal/ModalBody';
import ModalFooter from 'Components/Modal/ModalFooter'; import ModalFooter from 'Components/Modal/ModalFooter';
import Scroller from 'Components/Scroller/Scroller';
import Table from 'Components/Table/Table'; import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody'; import TableBody from 'Components/Table/TableBody';
import SelectEpisodeRow from './SelectEpisodeRow'; import SelectEpisodeRow from './SelectEpisodeRow';
@ -46,6 +48,7 @@ class SelectEpisodeModalContent extends Component {
this.state = { this.state = {
allSelected: false, allSelected: false,
allUnselected: false, allUnselected: false,
filter: '',
lastToggled: null, lastToggled: null,
selectedState: {} selectedState: {}
}; };
@ -61,6 +64,10 @@ class SelectEpisodeModalContent extends Component {
// //
// Listeners // Listeners
onFilterChange = ({ value }) => {
this.setState({ filter: value.toLowerCase() });
}
onSelectAllChange = ({ value }) => { onSelectAllChange = ({ value }) => {
this.setState(selectAll(this.state.selectedState, value)); this.setState(selectAll(this.state.selectedState, value));
} }
@ -95,8 +102,10 @@ class SelectEpisodeModalContent extends Component {
const { const {
allSelected, allSelected,
allUnselected, allUnselected,
filter,
selectedState selectedState
} = this.state; } = this.state;
const filterEpisodeNumber = parseInt(filter);
const errorMessage = getErrorMessage(error, 'Unable to load episodes'); const errorMessage = getErrorMessage(error, 'Unable to load episodes');
@ -116,53 +125,73 @@ class SelectEpisodeModalContent extends Component {
</ModalHeader> </ModalHeader>
<ModalBody> <ModalBody
{ className={styles.modalBody}
isFetching && scrollDirection={scrollDirections.NONE}
<LoadingIndicator /> >
} <TextInput
className={styles.filterInput}
{ placeholder="Filter episodes by title or number"
error && name="filter"
<div>{errorMessage}</div> value={filter}
} autoFocus={true}
onChange={this.onFilterChange}
{ />
isPopulated && !!items.length &&
<Table <Scroller
columns={columns} className={styles.scroller}
selectAll={true} autoFocus={false}
allSelected={allSelected} >
allUnselected={allUnselected} {
sortKey={sortKey} isFetching ? <LoadingIndicator /> : null
sortDirection={sortDirection} }
onSortPress={onSortPress}
onSelectAllChange={this.onSelectAllChange} {
> error ? <div>{errorMessage}</div> : null
<TableBody> }
{
items.map((item) => { {
return ( isPopulated && !!items.length ?
<SelectEpisodeRow <Table
key={item.id} columns={columns}
id={item.id} selectAll={true}
episodeNumber={item.episodeNumber} allSelected={allSelected}
title={item.title} allUnselected={allUnselected}
airDate={item.airDate} sortKey={sortKey}
isSelected={selectedState[item.id]} sortDirection={sortDirection}
onSelectedChange={this.onSelectedChange} onSortPress={onSortPress}
/> onSelectAllChange={this.onSelectAllChange}
); >
}) <TableBody>
} {
</TableBody> items.map((item) => {
</Table> return item.title.toLowerCase().includes(filter) ||
} item.episodeNumber === filterEpisodeNumber ?
(
{ <SelectEpisodeRow
isPopulated && !items.length && key={item.id}
'No episodes were found for the selected season' id={item.id}
} episodeNumber={item.episodeNumber}
title={item.title}
airDate={item.airDate}
isSelected={selectedState[item.id]}
onSelectedChange={this.onSelectedChange}
/>
) :
null;
})
}
</TableBody>
</Table> :
null
}
{
isPopulated && !items.length ?
'No episodes were found for the selected season' :
null
}
</Scroller>
</ModalBody> </ModalBody>
<ModalFooter className={styles.footer}> <ModalFooter className={styles.footer}>

Loading…
Cancel
Save