mirror of
https://github.com/fergalmoran/Readarr.git
synced 2026-01-07 09:15:58 +00:00
New: Load all books on page load and store in the browser
This commit is contained in:
@@ -12,33 +12,11 @@ import TableBody from 'Components/Table/TableBody';
|
||||
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
|
||||
import TablePager from 'Components/Table/TablePager';
|
||||
import { align, icons } from 'Helpers/Props';
|
||||
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import HistoryRowConnector from './HistoryRowConnector';
|
||||
|
||||
class History extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
// Don't update when fetching has completed if items have changed,
|
||||
// before books start fetching or when books start fetching.
|
||||
|
||||
if (
|
||||
(
|
||||
this.props.isFetching &&
|
||||
nextProps.isPopulated &&
|
||||
hasDifferentItems(this.props.items, nextProps.items)
|
||||
) ||
|
||||
(!this.props.isBooksFetching && nextProps.isBooksFetching)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
|
||||
@@ -3,10 +3,7 @@ import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import withCurrentPage from 'Components/withCurrentPage';
|
||||
import { clearBooks, fetchBooks } from 'Store/Actions/bookActions';
|
||||
import * as historyActions from 'Store/Actions/historyActions';
|
||||
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
|
||||
import selectUniqueIds from 'Utilities/Object/selectUniqueIds';
|
||||
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
|
||||
import History from './History';
|
||||
|
||||
@@ -29,9 +26,7 @@ function createMapStateToProps() {
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
...historyActions,
|
||||
fetchBooks,
|
||||
clearBooks
|
||||
...historyActions
|
||||
};
|
||||
|
||||
class HistoryConnector extends Component {
|
||||
@@ -55,21 +50,9 @@ class HistoryConnector extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (hasDifferentItems(prevProps.items, this.props.items)) {
|
||||
const bookIds = selectUniqueIds(this.props.items, 'bookId');
|
||||
if (bookIds.length) {
|
||||
this.props.fetchBooks({ bookIds });
|
||||
} else {
|
||||
this.props.clearBooks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
unregisterPagePopulator(this.repopulate);
|
||||
this.props.clearHistory();
|
||||
this.props.clearBooks();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -150,9 +133,7 @@ HistoryConnector.propTypes = {
|
||||
setHistorySort: PropTypes.func.isRequired,
|
||||
setHistoryFilter: PropTypes.func.isRequired,
|
||||
setHistoryTableOption: PropTypes.func.isRequired,
|
||||
clearHistory: PropTypes.func.isRequired,
|
||||
fetchBooks: PropTypes.func.isRequired,
|
||||
clearBooks: PropTypes.func.isRequired
|
||||
clearHistory: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default withCurrentPage(
|
||||
|
||||
@@ -4,12 +4,9 @@ import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import * as commandNames from 'Commands/commandNames';
|
||||
import withCurrentPage from 'Components/withCurrentPage';
|
||||
import { clearBooks, fetchBooks } from 'Store/Actions/bookActions';
|
||||
import { executeCommand } from 'Store/Actions/commandActions';
|
||||
import * as queueActions from 'Store/Actions/queueActions';
|
||||
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
|
||||
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
|
||||
import selectUniqueIds from 'Utilities/Object/selectUniqueIds';
|
||||
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
|
||||
import Queue from './Queue';
|
||||
|
||||
@@ -37,8 +34,6 @@ function createMapStateToProps() {
|
||||
|
||||
const mapDispatchToProps = {
|
||||
...queueActions,
|
||||
fetchBooks,
|
||||
clearBooks,
|
||||
executeCommand
|
||||
};
|
||||
|
||||
@@ -67,16 +62,6 @@ class QueueConnector extends Component {
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (hasDifferentItems(prevProps.items, this.props.items)) {
|
||||
const bookIds = selectUniqueIds(this.props.items, 'bookId');
|
||||
|
||||
if (bookIds.length) {
|
||||
this.props.fetchBooks({ bookIds });
|
||||
} else {
|
||||
this.props.clearBooks();
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
this.props.includeUnknownAuthorItems !==
|
||||
prevProps.includeUnknownAuthorItems
|
||||
@@ -87,8 +72,6 @@ class QueueConnector extends Component {
|
||||
|
||||
componentWillUnmount() {
|
||||
unregisterPagePopulator(this.repopulate);
|
||||
this.props.clearQueue();
|
||||
this.props.clearBooks();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -185,8 +168,6 @@ QueueConnector.propTypes = {
|
||||
clearQueue: PropTypes.func.isRequired,
|
||||
grabQueueItems: PropTypes.func.isRequired,
|
||||
removeQueueItems: PropTypes.func.isRequired,
|
||||
fetchBooks: PropTypes.func.isRequired,
|
||||
clearBooks: PropTypes.func.isRequired,
|
||||
executeCommand: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
|
||||
@@ -88,11 +88,13 @@ function AppRoutes(props) {
|
||||
/>
|
||||
|
||||
<Route
|
||||
path="/bookshelf"
|
||||
exact={true}
|
||||
path="/shelf"
|
||||
component={BookshelfConnector}
|
||||
/>
|
||||
|
||||
<Route
|
||||
exact={true}
|
||||
path="/books"
|
||||
component={BookIndexConnector}
|
||||
/>
|
||||
|
||||
@@ -6,7 +6,6 @@ import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import * as commandNames from 'Commands/commandNames';
|
||||
import { toggleAuthorMonitored } from 'Store/Actions/authorActions';
|
||||
import { clearBooks, fetchBooks } from 'Store/Actions/bookActions';
|
||||
import { clearBookFiles, fetchBookFiles } from 'Store/Actions/bookFileActions';
|
||||
import { executeCommand } from 'Store/Actions/commandActions';
|
||||
import { clearQueueDetails, fetchQueueDetails } from 'Store/Actions/queueActions';
|
||||
@@ -186,8 +185,6 @@ function createMapStateToProps() {
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
fetchBooks,
|
||||
clearBooks,
|
||||
fetchSeries,
|
||||
clearSeries,
|
||||
fetchBookFiles,
|
||||
@@ -248,7 +245,6 @@ class AuthorDetailsConnector extends Component {
|
||||
populate = () => {
|
||||
const authorId = this.props.id;
|
||||
|
||||
this.props.fetchBooks({ authorId });
|
||||
this.props.fetchSeries({ authorId });
|
||||
this.props.fetchBookFiles({ authorId });
|
||||
this.props.fetchQueueDetails({ authorId });
|
||||
@@ -256,7 +252,6 @@ class AuthorDetailsConnector extends Component {
|
||||
|
||||
unpopulate = () => {
|
||||
this.props.cancelFetchReleases();
|
||||
this.props.clearBooks();
|
||||
this.props.clearSeries();
|
||||
this.props.clearBookFiles();
|
||||
this.props.clearQueueDetails();
|
||||
@@ -310,8 +305,6 @@ AuthorDetailsConnector.propTypes = {
|
||||
isRefreshing: PropTypes.bool.isRequired,
|
||||
isRenamingFiles: PropTypes.bool.isRequired,
|
||||
isRenamingAuthor: PropTypes.bool.isRequired,
|
||||
fetchBooks: PropTypes.func.isRequired,
|
||||
clearBooks: PropTypes.func.isRequired,
|
||||
fetchSeries: PropTypes.func.isRequired,
|
||||
clearSeries: PropTypes.func.isRequired,
|
||||
fetchBookFiles: PropTypes.func.isRequired,
|
||||
|
||||
@@ -4,24 +4,22 @@ import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { setBooksSort, setBooksTableOption, toggleBooksMonitored } from 'Store/Actions/bookActions';
|
||||
import { setAuthorDetailsId, setAuthorDetailsSort } from 'Store/Actions/authorDetailsActions';
|
||||
import { setBooksTableOption, toggleBooksMonitored } from 'Store/Actions/bookActions';
|
||||
import { executeCommand } from 'Store/Actions/commandActions';
|
||||
import createAuthorSelector from 'Store/Selectors/createAuthorSelector';
|
||||
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
||||
import createCommandsSelector from 'Store/Selectors/createCommandsSelector';
|
||||
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
|
||||
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
|
||||
import AuthorDetailsSeason from './AuthorDetailsSeason';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state, { label }) => label,
|
||||
createClientSideCollectionSelector('books'),
|
||||
createClientSideCollectionSelector('books', 'authorDetails'),
|
||||
createAuthorSelector(),
|
||||
createCommandsSelector(),
|
||||
createDimensionsSelector(),
|
||||
createUISettingsSelector(),
|
||||
(label, books, author, commands, dimensions, uiSettings) => {
|
||||
(books, author, dimensions, uiSettings) => {
|
||||
|
||||
const booksInGroup = books.items;
|
||||
|
||||
@@ -47,14 +45,22 @@ function createMapStateToProps() {
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
setAuthorDetailsId,
|
||||
setAuthorDetailsSort,
|
||||
toggleBooksMonitored,
|
||||
setBooksTableOption,
|
||||
dispatchSetBookSort: setBooksSort,
|
||||
executeCommand
|
||||
};
|
||||
|
||||
class AuthorDetailsSeasonConnector extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
componentDidMount() {
|
||||
this.props.setAuthorDetailsId({ authorId: this.props.authorId });
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
@@ -63,7 +69,7 @@ class AuthorDetailsSeasonConnector extends Component {
|
||||
}
|
||||
|
||||
onSortPress = (sortKey) => {
|
||||
this.props.dispatchSetBookSort({ sortKey });
|
||||
this.props.setAuthorDetailsSort({ sortKey });
|
||||
}
|
||||
|
||||
onMonitorBookPress = (bookIds, monitored) => {
|
||||
@@ -92,7 +98,8 @@ AuthorDetailsSeasonConnector.propTypes = {
|
||||
authorId: PropTypes.number.isRequired,
|
||||
toggleBooksMonitored: PropTypes.func.isRequired,
|
||||
setBooksTableOption: PropTypes.func.isRequired,
|
||||
dispatchSetBookSort: PropTypes.func.isRequired,
|
||||
setAuthorDetailsId: PropTypes.func.isRequired,
|
||||
setAuthorDetailsSort: PropTypes.func.isRequired,
|
||||
executeCommand: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
|
||||
@@ -48,10 +48,11 @@ function createMapStateToProps() {
|
||||
createUISettingsSelector(),
|
||||
createDimensionsSelector(),
|
||||
(titleSlug, bookFiles, books, authors, commands, uiSettings, dimensions) => {
|
||||
const sortedBooks = _.orderBy(books.items, 'releaseDate');
|
||||
const bookIndex = _.findIndex(sortedBooks, { titleSlug });
|
||||
const book = sortedBooks[bookIndex];
|
||||
const author = _.find(authors, { id: book.authorId });
|
||||
const book = books.items.find((b) => b.titleSlug === titleSlug);
|
||||
const author = authors.find((a) => a.id === book.authorId);
|
||||
const sortedBooks = books.items.filter((b) => b.authorId === book.authorId);
|
||||
sortedBooks.sort((a, b) => ((a.releaseDate > b.releaseDate) ? 1 : -1));
|
||||
const bookIndex = sortedBooks.findIndex((b) => b.id === book.id);
|
||||
|
||||
if (!book) {
|
||||
return {};
|
||||
|
||||
@@ -8,7 +8,6 @@ import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import NotFound from 'Components/NotFound';
|
||||
import PageContent from 'Components/Page/PageContent';
|
||||
import PageContentBody from 'Components/Page/PageContentBody';
|
||||
import { clearBooks, fetchBooks } from 'Store/Actions/bookActions';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import BookDetailsConnector from './BookDetailsConnector';
|
||||
|
||||
@@ -44,9 +43,7 @@ function createMapStateToProps() {
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
push,
|
||||
fetchBooks,
|
||||
clearBooks
|
||||
push
|
||||
};
|
||||
|
||||
class BookDetailsPageConnector extends Component {
|
||||
@@ -62,24 +59,11 @@ class BookDetailsPageConnector extends Component {
|
||||
this.populate();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.unpopulate();
|
||||
}
|
||||
|
||||
//
|
||||
// Control
|
||||
|
||||
populate = () => {
|
||||
const titleSlug = this.props.titleSlug;
|
||||
this.setState({ hasMounted: true });
|
||||
this.props.fetchBooks({
|
||||
titleSlug,
|
||||
includeAllAuthorBooks: true
|
||||
});
|
||||
}
|
||||
|
||||
unpopulate = () => {
|
||||
this.props.clearBooks();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -125,8 +109,6 @@ BookDetailsPageConnector.propTypes = {
|
||||
titleSlug: PropTypes.string,
|
||||
match: PropTypes.shape({ params: PropTypes.shape({ titleSlug: PropTypes.string.isRequired }).isRequired }).isRequired,
|
||||
push: PropTypes.func.isRequired,
|
||||
fetchBooks: PropTypes.func.isRequired,
|
||||
clearBooks: PropTypes.func.isRequired,
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
@@ -5,7 +5,6 @@ import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import * as commandNames from 'Commands/commandNames';
|
||||
import withScrollPosition from 'Components/withScrollPosition';
|
||||
import { clearBooks, fetchBooks } from 'Store/Actions/bookActions';
|
||||
import { setBookFilter, setBookSort, setBookTableOption, setBookView } from 'Store/Actions/bookIndexActions';
|
||||
import { executeCommand } from 'Store/Actions/commandActions';
|
||||
import scrollPositions from 'Store/scrollPositions';
|
||||
@@ -67,42 +66,12 @@ function createMapDispatchToProps(dispatch, props) {
|
||||
dispatch(executeCommand({
|
||||
name: commandNames.RSS_SYNC
|
||||
}));
|
||||
},
|
||||
|
||||
dispatchFetchBooks() {
|
||||
dispatch(fetchBooks());
|
||||
},
|
||||
|
||||
dispatchClearBooks() {
|
||||
dispatch(clearBooks());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class BookIndexConnector extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
componentDidMount() {
|
||||
this.populate();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.unpopulate();
|
||||
}
|
||||
|
||||
//
|
||||
// Control
|
||||
|
||||
populate = () => {
|
||||
this.props.dispatchFetchBooks();
|
||||
}
|
||||
|
||||
unpopulate = () => {
|
||||
this.props.dispatchClearBooks();
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
@@ -131,8 +100,6 @@ class BookIndexConnector extends Component {
|
||||
BookIndexConnector.propTypes = {
|
||||
isSmallScreen: PropTypes.bool.isRequired,
|
||||
view: PropTypes.string.isRequired,
|
||||
dispatchFetchBooks: PropTypes.func.isRequired,
|
||||
dispatchClearBooks: PropTypes.func.isRequired,
|
||||
dispatchSetBookView: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
|
||||
@@ -308,19 +308,6 @@ class Bookshelf extends Component {
|
||||
this.cache.clearAll();
|
||||
}
|
||||
|
||||
// onSectionRendered = ({ rowStartIndex }) => {
|
||||
// console.log(`rendered starting ${rowStartIndex}, aiming for ${this.state.scrollIndex}`);
|
||||
|
||||
// const {
|
||||
// scrollIndex
|
||||
// } = this.state;
|
||||
|
||||
// if (rowStartIndex === scrollIndex) {
|
||||
// console.log('resetting scrollindex');
|
||||
// this.setState({ scrollIndex: null });
|
||||
// }
|
||||
// }
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
@@ -385,7 +372,7 @@ class Bookshelf extends Component {
|
||||
}
|
||||
|
||||
{
|
||||
!error && isPopulated && !!items.length &&
|
||||
!error && isPopulated && !!items.length && scroller &&
|
||||
<div className={styles.contentBodyContainer}>
|
||||
<VirtualTable
|
||||
items={items}
|
||||
|
||||
@@ -2,7 +2,6 @@ import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { clearBooks, fetchBooks } from 'Store/Actions/bookActions';
|
||||
import { saveBookshelf, setBookshelfFilter, setBookshelfSort } from 'Store/Actions/bookshelfActions';
|
||||
import createAuthorClientSideCollectionItemsSelector from 'Store/Selectors/createAuthorClientSideCollectionItemsSelector';
|
||||
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
|
||||
@@ -44,8 +43,6 @@ function createMapStateToProps() {
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
fetchBooks,
|
||||
clearBooks,
|
||||
setBookshelfSort,
|
||||
setBookshelfFilter,
|
||||
saveBookshelf
|
||||
@@ -53,28 +50,6 @@ const mapDispatchToProps = {
|
||||
|
||||
class BookshelfConnector extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
componentDidMount() {
|
||||
this.populate();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.unpopulate();
|
||||
}
|
||||
|
||||
//
|
||||
// Control
|
||||
|
||||
populate = () => {
|
||||
this.props.fetchBooks();
|
||||
}
|
||||
|
||||
unpopulate = () => {
|
||||
this.props.clearBooks();
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
@@ -108,8 +83,6 @@ class BookshelfConnector extends Component {
|
||||
BookshelfConnector.propTypes = {
|
||||
setBookshelfSort: PropTypes.func.isRequired,
|
||||
setBookshelfFilter: PropTypes.func.isRequired,
|
||||
fetchBooks: PropTypes.func.isRequired,
|
||||
clearBooks: PropTypes.func.isRequired,
|
||||
saveBookshelf: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { withRouter } from 'react-router-dom';
|
||||
import { createSelector } from 'reselect';
|
||||
import { saveDimensions, setIsSidebarVisible } from 'Store/Actions/appActions';
|
||||
import { fetchAuthor } from 'Store/Actions/authorActions';
|
||||
import { fetchBooks } from 'Store/Actions/bookActions';
|
||||
import { fetchCustomFilters } from 'Store/Actions/customFilterActions';
|
||||
import { fetchImportLists, fetchLanguages, fetchMetadataProfiles, fetchQualityProfiles, fetchUISettings } from 'Store/Actions/settingsActions';
|
||||
import { fetchStatus } from 'Store/Actions/systemActions';
|
||||
@@ -148,6 +149,9 @@ function createMapDispatchToProps(dispatch, props) {
|
||||
dispatchFetchAuthor() {
|
||||
dispatch(fetchAuthor());
|
||||
},
|
||||
dispatchFetchBooks() {
|
||||
dispatch(fetchBooks());
|
||||
},
|
||||
dispatchFetchCustomFilters() {
|
||||
dispatch(fetchCustomFilters());
|
||||
},
|
||||
@@ -197,6 +201,7 @@ class PageConnector extends Component {
|
||||
componentDidMount() {
|
||||
if (!this.props.isPopulated) {
|
||||
this.props.dispatchFetchAuthor();
|
||||
this.props.dispatchFetchBooks();
|
||||
this.props.dispatchFetchCustomFilters();
|
||||
this.props.dispatchFetchTags();
|
||||
this.props.dispatchFetchLanguages();
|
||||
@@ -223,6 +228,7 @@ class PageConnector extends Component {
|
||||
isPopulated,
|
||||
hasError,
|
||||
dispatchFetchAuthor,
|
||||
dispatchFetchBooks,
|
||||
dispatchFetchTags,
|
||||
dispatchFetchLanguages,
|
||||
dispatchFetchQualityProfiles,
|
||||
@@ -262,6 +268,7 @@ PageConnector.propTypes = {
|
||||
hasError: PropTypes.bool.isRequired,
|
||||
isSidebarVisible: PropTypes.bool.isRequired,
|
||||
dispatchFetchAuthor: PropTypes.func.isRequired,
|
||||
dispatchFetchBooks: PropTypes.func.isRequired,
|
||||
dispatchFetchCustomFilters: PropTypes.func.isRequired,
|
||||
dispatchFetchTags: PropTypes.func.isRequired,
|
||||
dispatchFetchLanguages: PropTypes.func.isRequired,
|
||||
|
||||
@@ -42,7 +42,7 @@ const links = [
|
||||
},
|
||||
{
|
||||
title: 'Bookshelf',
|
||||
to: '/bookshelf'
|
||||
to: '/shelf'
|
||||
},
|
||||
{
|
||||
title: 'Unmapped Files',
|
||||
|
||||
@@ -6,6 +6,7 @@ import { createSelector } from 'reselect';
|
||||
import { setAppValue, setVersion } from 'Store/Actions/appActions';
|
||||
import { fetchAuthor } from 'Store/Actions/authorActions';
|
||||
import { removeItem, update, updateItem } from 'Store/Actions/baseActions';
|
||||
import { deleteAuthorBooks } from 'Store/Actions/bookActions';
|
||||
import { fetchCommands, finishCommand, updateCommand } from 'Store/Actions/commandActions';
|
||||
import { fetchQueue, fetchQueueDetails } from 'Store/Actions/queueActions';
|
||||
import { fetchRootFolders } from 'Store/Actions/settingsActions';
|
||||
@@ -45,6 +46,7 @@ const mapDispatchToProps = {
|
||||
dispatchUpdate: update,
|
||||
dispatchUpdateItem: updateItem,
|
||||
dispatchRemoveItem: removeItem,
|
||||
dispatchDeleteAuthorBooks: deleteAuthorBooks,
|
||||
dispatchFetchAuthor: fetchAuthor,
|
||||
dispatchFetchHealth: fetchHealth,
|
||||
dispatchFetchQueue: fetchQueue,
|
||||
@@ -182,7 +184,6 @@ class SignalRConnector extends Component {
|
||||
if (action === 'updated') {
|
||||
this.props.dispatchUpdateItem({
|
||||
section,
|
||||
updateOnly: true,
|
||||
...body.resource
|
||||
});
|
||||
} else if (action === 'deleted') {
|
||||
@@ -218,6 +219,7 @@ class SignalRConnector extends Component {
|
||||
this.props.dispatchUpdateItem({ section, ...body.resource });
|
||||
} else if (action === 'deleted') {
|
||||
this.props.dispatchRemoveItem({ section, id: body.resource.id });
|
||||
this.props.dispatchDeleteAuthorBooks({ authorId: body.resource.id });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,6 +367,7 @@ SignalRConnector.propTypes = {
|
||||
dispatchUpdate: PropTypes.func.isRequired,
|
||||
dispatchUpdateItem: PropTypes.func.isRequired,
|
||||
dispatchRemoveItem: PropTypes.func.isRequired,
|
||||
dispatchDeleteAuthorBooks: PropTypes.func.isRequired,
|
||||
dispatchFetchAuthor: PropTypes.func.isRequired,
|
||||
dispatchFetchHealth: PropTypes.func.isRequired,
|
||||
dispatchFetchQueue: PropTypes.func.isRequired,
|
||||
|
||||
97
frontend/src/Store/Actions/authorDetailsActions.js
Normal file
97
frontend/src/Store/Actions/authorDetailsActions.js
Normal file
@@ -0,0 +1,97 @@
|
||||
import { createAction } from 'redux-actions';
|
||||
import { sortDirections } from 'Helpers/Props';
|
||||
import { createThunk, handleThunks } from 'Store/thunks';
|
||||
import { set } from './baseActions';
|
||||
import { filterPredicates, sortPredicates } from './bookActions';
|
||||
import createHandleActions from './Creators/createHandleActions';
|
||||
import createSetClientSideCollectionSortReducer from './Creators/Reducers/createSetClientSideCollectionSortReducer';
|
||||
|
||||
//
|
||||
// Variables
|
||||
|
||||
export const section = 'authorDetails';
|
||||
|
||||
//
|
||||
// State
|
||||
|
||||
export const defaultState = {
|
||||
sortKey: 'releaseDate',
|
||||
sortDirection: sortDirections.DESCENDING,
|
||||
secondarySortKey: 'releaseDate',
|
||||
secondarySortDirection: sortDirections.DESCENDING,
|
||||
|
||||
selectedFilterKey: 'authorId',
|
||||
|
||||
sortPredicates: {
|
||||
...sortPredicates
|
||||
},
|
||||
|
||||
filters: [
|
||||
{
|
||||
key: 'authorId',
|
||||
label: 'Author',
|
||||
filters: [
|
||||
{
|
||||
key: 'authorId',
|
||||
value: 0
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
filterPredicates
|
||||
|
||||
};
|
||||
|
||||
export const persistState = [
|
||||
'authorDetails.sortKey',
|
||||
'authorDetails.sortDirection'
|
||||
];
|
||||
|
||||
//
|
||||
// Actions Types
|
||||
|
||||
export const SET_AUTHOR_DETAILS_SORT = 'authorIndex/setAuthorDetailsSort';
|
||||
export const SET_AUTHOR_DETAILS_ID = 'authorIndex/setAuthorDetailsId';
|
||||
|
||||
//
|
||||
// Action Creators
|
||||
|
||||
export const setAuthorDetailsSort = createAction(SET_AUTHOR_DETAILS_SORT);
|
||||
export const setAuthorDetailsId = createThunk(SET_AUTHOR_DETAILS_ID);
|
||||
|
||||
//
|
||||
// Action Handlers
|
||||
|
||||
export const actionHandlers = handleThunks({
|
||||
[SET_AUTHOR_DETAILS_ID]: function(getState, payload, dispatch) {
|
||||
const {
|
||||
authorId
|
||||
} = payload;
|
||||
|
||||
dispatch(set({
|
||||
section,
|
||||
filters: [
|
||||
{
|
||||
key: 'authorId',
|
||||
label: 'Author',
|
||||
filters: [
|
||||
{
|
||||
key: 'authorId',
|
||||
value: authorId
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// Reducers
|
||||
|
||||
export const reducers = createHandleActions({
|
||||
|
||||
[SET_AUTHOR_DETAILS_SORT]: createSetClientSideCollectionSortReducer(section)
|
||||
|
||||
}, defaultState, section);
|
||||
@@ -6,7 +6,7 @@ import { filterTypePredicates, filterTypes, sortDirections } from 'Helpers/Props
|
||||
import { createThunk, handleThunks } from 'Store/thunks';
|
||||
import createAjaxRequest from 'Utilities/createAjaxRequest';
|
||||
import dateFilterPredicate from 'Utilities/Date/dateFilterPredicate';
|
||||
import { updateItem } from './baseActions';
|
||||
import { removeItem, updateItem } from './baseActions';
|
||||
import createFetchHandler from './Creators/createFetchHandler';
|
||||
import createHandleActions from './Creators/createHandleActions';
|
||||
import createRemoveItemHandler from './Creators/createRemoveItemHandler';
|
||||
@@ -213,6 +213,7 @@ export const CLEAR_BOOKS = 'books/clearBooks';
|
||||
export const SET_BOOK_VALUE = 'books/setBookValue';
|
||||
export const SAVE_BOOK = 'books/saveBook';
|
||||
export const DELETE_BOOK = 'books/deleteBook';
|
||||
export const DELETE_AUTHOR_BOOKS = 'books/deleteAuthorBooks';
|
||||
export const TOGGLE_BOOK_MONITORED = 'books/toggleBookMonitored';
|
||||
export const TOGGLE_BOOKS_MONITORED = 'books/toggleBooksMonitored';
|
||||
|
||||
@@ -238,6 +239,15 @@ export const deleteBook = createThunk(DELETE_BOOK, (payload) => {
|
||||
};
|
||||
});
|
||||
|
||||
export const deleteAuthorBooks = createThunk(DELETE_AUTHOR_BOOKS, (payload) => {
|
||||
return {
|
||||
...payload,
|
||||
queryParams: {
|
||||
authorId: payload.authorId
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
export const setBookValue = createAction(SET_BOOK_VALUE, (payload) => {
|
||||
return {
|
||||
section: 'books',
|
||||
@@ -253,6 +263,15 @@ export const actionHandlers = handleThunks({
|
||||
[SAVE_BOOK]: createSaveProviderHandler(section, '/book'),
|
||||
[DELETE_BOOK]: createRemoveItemHandler(section, '/book'),
|
||||
|
||||
[DELETE_AUTHOR_BOOKS]: function(getState, payload, dispatch) {
|
||||
const { authorId } = payload;
|
||||
const books = getState().books.items;
|
||||
|
||||
const toDelete = books.filter((x) => x.authorId === authorId);
|
||||
|
||||
dispatch(batchActions(toDelete.map((b) => removeItem({ section, id: b.id }))));
|
||||
},
|
||||
|
||||
[TOGGLE_BOOK_MONITORED]: function(getState, payload, dispatch) {
|
||||
const {
|
||||
bookId,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as app from './appActions';
|
||||
import * as author from './authorActions';
|
||||
import * as authorDetails from './authorDetailsActions';
|
||||
import * as authorEditor from './authorEditorActions';
|
||||
import * as authorHistory from './authorHistoryActions';
|
||||
import * as authorIndex from './authorIndexActions';
|
||||
@@ -31,31 +32,32 @@ import * as wanted from './wantedActions';
|
||||
|
||||
export default [
|
||||
app,
|
||||
author,
|
||||
authorDetails,
|
||||
authorEditor,
|
||||
authorHistory,
|
||||
authorIndex,
|
||||
blacklist,
|
||||
captcha,
|
||||
calendar,
|
||||
commands,
|
||||
customFilters,
|
||||
books,
|
||||
bookFiles,
|
||||
bookHistory,
|
||||
bookIndex,
|
||||
books,
|
||||
bookStudio,
|
||||
calendar,
|
||||
captcha,
|
||||
commands,
|
||||
customFilters,
|
||||
history,
|
||||
interactiveImportActions,
|
||||
oAuth,
|
||||
organizePreview,
|
||||
retagPreview,
|
||||
paths,
|
||||
providerOptions,
|
||||
queue,
|
||||
releases,
|
||||
bookStudio,
|
||||
author,
|
||||
authorEditor,
|
||||
authorHistory,
|
||||
authorIndex,
|
||||
series,
|
||||
retagPreview,
|
||||
search,
|
||||
series,
|
||||
settings,
|
||||
system,
|
||||
tags,
|
||||
|
||||
@@ -163,6 +163,7 @@ export const actionHandlers = handleThunks({
|
||||
itemToAdd.book = data;
|
||||
dispatch(batchActions([
|
||||
updateItem({ section: 'authors', ...data.author }),
|
||||
updateItem({ section: 'books', ...data }),
|
||||
updateItem({ section, ...itemToAdd }),
|
||||
|
||||
set({
|
||||
|
||||
Reference in New Issue
Block a user