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,19 +125,33 @@ class SelectEpisodeModalContent extends Component {
</ModalHeader> </ModalHeader>
<ModalBody> <ModalBody
className={styles.modalBody}
scrollDirection={scrollDirections.NONE}
>
<TextInput
className={styles.filterInput}
placeholder="Filter episodes by title or number"
name="filter"
value={filter}
autoFocus={true}
onChange={this.onFilterChange}
/>
<Scroller
className={styles.scroller}
autoFocus={false}
>
{ {
isFetching && isFetching ? <LoadingIndicator /> : null
<LoadingIndicator />
} }
{ {
error && error ? <div>{errorMessage}</div> : null
<div>{errorMessage}</div>
} }
{ {
isPopulated && !!items.length && isPopulated && !!items.length ?
<Table <Table
columns={columns} columns={columns}
selectAll={true} selectAll={true}
@ -142,7 +165,9 @@ class SelectEpisodeModalContent extends Component {
<TableBody> <TableBody>
{ {
items.map((item) => { items.map((item) => {
return ( return item.title.toLowerCase().includes(filter) ||
item.episodeNumber === filterEpisodeNumber ?
(
<SelectEpisodeRow <SelectEpisodeRow
key={item.id} key={item.id}
id={item.id} id={item.id}
@ -152,17 +177,21 @@ class SelectEpisodeModalContent extends Component {
isSelected={selectedState[item.id]} isSelected={selectedState[item.id]}
onSelectedChange={this.onSelectedChange} onSelectedChange={this.onSelectedChange}
/> />
); ) :
null;
}) })
} }
</TableBody> </TableBody>
</Table> </Table> :
null
} }
{ {
isPopulated && !items.length && isPopulated && !items.length ?
'No episodes were found for the selected season' 'No episodes were found for the selected season' :
null
} }
</Scroller>
</ModalBody> </ModalBody>
<ModalFooter className={styles.footer}> <ModalFooter className={styles.footer}>

Loading…
Cancel
Save