mirror of
https://github.com/Readarr/Readarr
synced 2026-01-08 08:33:30 +01:00
Fixed: Selecting edition for books in manual import
This commit is contained in:
parent
e4a3d7b273
commit
f33e9f2bbc
7 changed files with 118 additions and 12 deletions
|
|
@ -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 @@ public interface IEditionRepository : IBasicRepository<Edition>
|
|||
{
|
||||
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 @@ public List<Edition> GetEditionsForRefresh(int bookId, List<string> foreignEditi
|
|||
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 @@ public Edition FindByTitle(int authorMetadataId, string title)
|
|||
|
||||
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 @@ public interface IEditionService
|
|||
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 @@ public List<Edition> GetEditionsForRefresh(int bookId, List<string> foreignEditi
|
|||
|
||||
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 @@ public EditionController(IEditionService editionService)
|
|||
}
|
||||
|
||||
[HttpGet]
|
||||
public List<EditionResource> GetEditions(int bookId)
|
||||
public List<EditionResource> GetEditions([FromQuery]List<int> bookId)
|
||||
{
|
||||
var editions = _editionService.GetEditionsByBook(bookId);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue