From 63141f339fe2a295d5f768be1d623793670bacf2 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 30 Jul 2019 19:07:13 -0700 Subject: [PATCH] New: Bulk select episodes in Manual Import --- .../Episode/SelectEpisodeModalContent.js | 24 ++++++++++++--- .../SelectEpisodeModalContentConnector.js | 29 ++++++++++++++----- .../InteractiveImportModalContent.js | 25 +++++++++++++++- .../Interactive/InteractiveImportRow.js | 2 +- 4 files changed, 67 insertions(+), 13 deletions(-) diff --git a/frontend/src/InteractiveImport/Episode/SelectEpisodeModalContent.js b/frontend/src/InteractiveImport/Episode/SelectEpisodeModalContent.js index 3dbda3c48..e10eeddec 100644 --- a/frontend/src/InteractiveImport/Episode/SelectEpisodeModalContent.js +++ b/frontend/src/InteractiveImport/Episode/SelectEpisodeModalContent.js @@ -80,6 +80,7 @@ class SelectEpisodeModalContent extends Component { render() { const { + ids, isFetching, isPopulated, error, @@ -99,6 +100,13 @@ class SelectEpisodeModalContent extends Component { const errorMessage = getErrorMessage(error, 'Unable to load episodes'); + const selectedFilesCount = ids.length; + const selectedCount = this.getSelectedIds().length; + const selectionIsValid = ( + selectedCount > 0 && + selectedCount % selectedFilesCount === 0 + ); + return ( @@ -158,18 +166,25 @@ class SelectEpisodeModalContent extends Component { -
{relativePath}
+
+ { + relativePath ? + relativePath : + `${selectedFilesCount} selected files` + } +
@@ -179,11 +194,12 @@ class SelectEpisodeModalContent extends Component { } SelectEpisodeModalContent.propTypes = { + ids: PropTypes.arrayOf(PropTypes.number).isRequired, isFetching: PropTypes.bool.isRequired, isPopulated: PropTypes.bool.isRequired, error: PropTypes.object, items: PropTypes.arrayOf(PropTypes.object).isRequired, - relativePath: PropTypes.string.isRequired, + relativePath: PropTypes.string, sortKey: PropTypes.string, sortDirection: PropTypes.string, onSortPress: PropTypes.func.isRequired, diff --git a/frontend/src/InteractiveImport/Episode/SelectEpisodeModalContentConnector.js b/frontend/src/InteractiveImport/Episode/SelectEpisodeModalContentConnector.js index 016cc7a66..80ceb0fc1 100644 --- a/frontend/src/InteractiveImport/Episode/SelectEpisodeModalContentConnector.js +++ b/frontend/src/InteractiveImport/Episode/SelectEpisodeModalContentConnector.js @@ -1,4 +1,3 @@ -import _ from 'lodash'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; import { connect } from 'react-redux'; @@ -56,7 +55,13 @@ class SelectEpisodeModalContentConnector extends Component { } onEpisodesSelect = (episodeIds) => { - const episodes = _.reduce(this.props.items, (acc, item) => { + const { + ids, + items, + onModalClose + } = this.props; + + const selectedEpisodes = items.reduce((acc, item) => { if (episodeIds.indexOf(item.id) > -1) { acc.push(item); } @@ -64,12 +69,22 @@ class SelectEpisodeModalContentConnector extends Component { return acc; }, []); - this.props.updateInteractiveImportItem({ - id: this.props.id, - episodes: _.sortBy(episodes, 'episodeNumber') + const episodesPerFile = selectedEpisodes.length / ids.length; + const sortedEpisodes = selectedEpisodes.sort((a, b) => { + return a.seasonNumber - b.seasonNumber; }); - this.props.onModalClose(true); + ids.forEach((id, index) => { + const startingIndex = index * episodesPerFile; + const episodes = sortedEpisodes.slice(startingIndex, startingIndex + episodesPerFile); + + this.props.updateInteractiveImportItem({ + id, + episodes + }); + }); + + onModalClose(true); } // @@ -87,7 +102,7 @@ class SelectEpisodeModalContentConnector extends Component { } SelectEpisodeModalContentConnector.propTypes = { - id: PropTypes.number.isRequired, + ids: PropTypes.arrayOf(PropTypes.number).isRequired, seriesId: PropTypes.number.isRequired, seasonNumber: PropTypes.number.isRequired, items: PropTypes.arrayOf(PropTypes.object).isRequired, diff --git a/frontend/src/InteractiveImport/Interactive/InteractiveImportModalContent.js b/frontend/src/InteractiveImport/Interactive/InteractiveImportModalContent.js index c0bc08baf..6f04d983b 100644 --- a/frontend/src/InteractiveImport/Interactive/InteractiveImportModalContent.js +++ b/frontend/src/InteractiveImport/Interactive/InteractiveImportModalContent.js @@ -20,6 +20,7 @@ import ModalBody from 'Components/Modal/ModalBody'; import ModalFooter from 'Components/Modal/ModalFooter'; import Table from 'Components/Table/Table'; import TableBody from 'Components/Table/TableBody'; +import SelectEpisodeModal from 'InteractiveImport/Episode/SelectEpisodeModal'; import SelectLanguageModal from 'InteractiveImport/Language/SelectLanguageModal'; import SelectQualityModal from 'InteractiveImport/Quality/SelectQualityModal'; import SelectSeriesModal from 'InteractiveImport/Series/SelectSeriesModal'; @@ -90,6 +91,7 @@ const importModeOptions = [ const SELECT = 'select'; const SERIES = 'series'; const SEASON = 'season'; +const EPISODE = 'episode'; const LANGUAGE = 'language'; const QUALITY = 'quality'; @@ -208,12 +210,25 @@ class InteractiveImportModalContent extends Component { } = this.state; const selectedIds = this.getSelectedIds(); - const selectedItem = selectedIds.length ? _.find(items, { id: selectedIds[0] }) : null; + + const orderedSelectedIds = items.reduce((acc, file) => { + if (selectedIds.includes(file.id)) { + acc.push(file.id); + } + + return acc; + }, []); + + const selectedItem = selectedIds.length ? + items.find((file) => file.id === selectedIds[0]) : + null; + const errorMessage = getErrorMessage(error, 'Unable to load manual import items'); const bulkSelectOptions = [ { key: SELECT, value: 'Select...', disabled: true }, { key: SEASON, value: 'Select Season' }, + { key: EPISODE, value: 'Select Episode(s)' }, { key: LANGUAGE, value: 'Select Language' }, { key: QUALITY, value: 'Select Quality' } ]; @@ -374,6 +389,14 @@ class InteractiveImportModalContent extends Component { onModalClose={this.onSelectModalClose} /> + +