Fixed: Selecting edition for books in manual import

pull/1770/head
ta264 2 years ago
parent e4a3d7b273
commit f33e9f2bbc

@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Alert from 'Components/Alert';
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';
@ -9,7 +10,8 @@ import ModalHeader from 'Components/Modal/ModalHeader';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import { scrollDirections } from 'Helpers/Props';
import SelectEditionRow from './SelectEditionRow';
import translate from 'Utilities/String/translate';
import SelectEditionRowConnector from './SelectEditionRowConnector';
import styles from './SelectEditionModalContent.css';
const columns = [
@ -33,15 +35,30 @@ class SelectEditionModalContent extends Component {
render() {
const {
books,
isPopulated,
isFetching,
error,
onEditionSelect,
onModalClose,
...otherProps
} = this.props;
if (!isPopulated && !error) {
return (<LoadingIndicator />);
}
if (!isFetching && error) {
return (
<div>
{translate('LoadingEditionsFailed')}
</div>
);
}
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
Manual Import - Select Edition
{translate('ManualImportSelectEdition')}
</ModalHeader>
<ModalBody
@ -60,7 +77,7 @@ class SelectEditionModalContent extends Component {
{
books.map((item) => {
return (
<SelectEditionRow
<SelectEditionRowConnector
key={item.book.id}
matchedEditionId={item.matchedEditionId}
columns={columns}
@ -76,7 +93,7 @@ class SelectEditionModalContent extends Component {
<ModalFooter>
<Button onPress={onModalClose}>
Cancel
{translate('Cancel')}
</Button>
</ModalFooter>
</ModalContent>
@ -86,6 +103,9 @@ class SelectEditionModalContent extends Component {
SelectEditionModalContent.propTypes = {
books: PropTypes.arrayOf(PropTypes.object).isRequired,
isFetching: PropTypes.bool,
isPopulated: PropTypes.bool,
error: PropTypes.object,
onEditionSelect: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired
};

@ -1,27 +1,71 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { clearEditions, fetchEditions } from 'Store/Actions/editionActions';
import {
saveInteractiveImportItem,
updateInteractiveImportItem } from 'Store/Actions/interactiveImportActions';
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
import SelectEditionModalContent from './SelectEditionModalContent';
function createMapStateToProps() {
return {};
return createSelector(
(state) => state.editions,
(editions) => {
const {
isFetching,
isPopulated,
error
} = editions;
return {
isFetching,
isPopulated,
error
};
}
);
}
const mapDispatchToProps = {
fetchEditions,
clearEditions,
updateInteractiveImportItem,
saveInteractiveImportItem
};
class SelectEditionModalContentConnector extends Component {
//
// Lifecycle
componentDidMount() {
registerPagePopulator(this.populate);
this.populate();
}
componentWillUnmount() {
unregisterPagePopulator(this.populate);
this.unpopulate();
}
//
// Control
populate = () => {
const bookId = this.props.books.map((b) => b.book.id);
this.props.fetchEditions({ bookId });
}
unpopulate = () => {
this.props.clearEditions();
}
//
// Listeners
onEditionSelect = (bookId, foreignEditionId) => {
console.log(`book: ${bookId} id: ${foreignEditionId} ${typeof foreignEditionId}`);
const ids = this.props.importIdsByBook[bookId];
ids.forEach((id) => {
@ -55,6 +99,8 @@ class SelectEditionModalContentConnector extends Component {
SelectEditionModalContentConnector.propTypes = {
importIdsByBook: PropTypes.object.isRequired,
books: PropTypes.arrayOf(PropTypes.object).isRequired,
fetchEditions: PropTypes.func.isRequired,
clearEditions: PropTypes.func.isRequired,
updateInteractiveImportItem: PropTypes.func.isRequired,
saveInteractiveImportItem: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired

@ -0,0 +1,32 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import SelectEditionRow from './SelectEditionRow';
function createMapStateToProps() {
return createSelector(
(state, { id }) => id,
(state) => state.editions,
(id, editionState) => {
const editions = editionState.items.filter((e) => e.bookId === id);
return { editions };
}
);
}
class SelectEditionRowConnector extends Component {
render() {
return (
<SelectEditionRow
{...this.props}
/>
);
}
}
SelectEditionRowConnector.PropTypes = {
editions: PropTypes.arrayOf(PropTypes.object).isRequired
};
export default connect(createMapStateToProps)(SelectEditionRowConnector);

@ -11,7 +11,7 @@ namespace NzbDrone.Core.Books
{
List<Edition> GetAllMonitoredEditions();
Edition FindByForeignEditionId(string foreignEditionId);
List<Edition> FindByBook(int id);
List<Edition> FindByBook(IEnumerable<int> ids);
List<Edition> FindByAuthor(int id);
List<Edition> FindByAuthorMetadataId(int id, bool onlyMonitored);
Edition FindByTitle(int authorMetadataId, string title);
@ -43,14 +43,14 @@ namespace NzbDrone.Core.Books
return Query(r => r.BookId == bookId || foreignEditionIds.Contains(r.ForeignEditionId));
}
public List<Edition> FindByBook(int id)
public List<Edition> FindByBook(IEnumerable<int> ids)
{
// populate the books and author metadata also
// this hopefully speeds up the track matching a lot
var builder = new SqlBuilder(_database.DatabaseType)
.LeftJoin<Edition, Book>((e, b) => e.BookId == b.Id)
.LeftJoin<Book, AuthorMetadata>((b, a) => b.AuthorMetadataId == a.Id)
.Where<Edition>(r => r.BookId == id);
.Where<Edition>(r => ids.Contains(r.BookId));
return _database.QueryJoined<Edition, Book, AuthorMetadata>(builder, (edition, book, metadata) =>
{
@ -96,7 +96,7 @@ namespace NzbDrone.Core.Books
public List<Edition> SetMonitored(Edition edition)
{
var allEditions = FindByBook(edition.BookId);
var allEditions = FindByBook(new[] { edition.BookId });
allEditions.ForEach(r => r.Monitored = r.Id == edition.Id);
Ensure.That(allEditions.Count(x => x.Monitored) == 1).IsTrue();
UpdateMany(allEditions);

@ -18,6 +18,7 @@ namespace NzbDrone.Core.Books
void DeleteMany(List<Edition> editions);
List<Edition> GetEditionsForRefresh(int bookId, List<string> foreignEditionIds);
List<Edition> GetEditionsByBook(int bookId);
List<Edition> GetEditionsByBook(IEnumerable<int> bookIds);
List<Edition> GetEditionsByAuthor(int authorId);
Edition FindByTitle(int authorMetadataId, string title);
Edition FindByTitleInexact(int authorMetadataId, string title);
@ -79,7 +80,12 @@ namespace NzbDrone.Core.Books
public List<Edition> GetEditionsByBook(int bookId)
{
return _editionRepository.FindByBook(bookId);
return _editionRepository.FindByBook(new[] { bookId });
}
public List<Edition> GetEditionsByBook(IEnumerable<int> bookIds)
{
return _editionRepository.FindByBook(bookIds);
}
public List<Edition> GetEditionsByAuthor(int authorId)

@ -381,6 +381,7 @@
"ListsSettingsSummary": "Import Lists",
"LoadingBookFilesFailed": "Loading book files failed",
"LoadingBooksFailed": "Loading books failed",
"LoadingEditionsFailed": "Loading editions failed",
"Local": "Local",
"LogFiles": "Log Files",
"Logging": "Logging",
@ -395,6 +396,7 @@
"MaintenanceRelease": "Maintenance Release: bug fixes and other improvements. See Github Commit History for more details",
"ManualDownload": "Manual Download",
"ManualImport": "Manual Import",
"ManualImportSelectEdition": "Manual Import - Select Edition",
"MarkAsFailed": "Mark as Failed",
"MarkAsFailedMessageText": "Are you sure you want to mark '{0}' as failed?",
"MassBookSearch": "Mass Book Search",

@ -17,7 +17,7 @@ namespace NzbDrone.Api.V1.Editions
}
[HttpGet]
public List<EditionResource> GetEditions(int bookId)
public List<EditionResource> GetEditions([FromQuery]List<int> bookId)
{
var editions = _editionService.GetEditionsByBook(bookId);

Loading…
Cancel
Save