diff --git a/frontend/src/Activity/History/History.js b/frontend/src/Activity/History/History.js
index baeab9cd1..f6e156602 100644
--- a/frontend/src/Activity/History/History.js
+++ b/frontend/src/Activity/History/History.js
@@ -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
diff --git a/frontend/src/Activity/History/HistoryConnector.js b/frontend/src/Activity/History/HistoryConnector.js
index 9976fcb67..1a1828d0c 100644
--- a/frontend/src/Activity/History/HistoryConnector.js
+++ b/frontend/src/Activity/History/HistoryConnector.js
@@ -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(
diff --git a/frontend/src/Activity/Queue/QueueConnector.js b/frontend/src/Activity/Queue/QueueConnector.js
index 95881ff6c..7c152ea6d 100644
--- a/frontend/src/Activity/Queue/QueueConnector.js
+++ b/frontend/src/Activity/Queue/QueueConnector.js
@@ -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
};
diff --git a/frontend/src/App/AppRoutes.js b/frontend/src/App/AppRoutes.js
index 1159264c2..27a0b984d 100644
--- a/frontend/src/App/AppRoutes.js
+++ b/frontend/src/App/AppRoutes.js
@@ -88,11 +88,13 @@ function AppRoutes(props) {
/>
diff --git a/frontend/src/Author/Details/AuthorDetailsConnector.js b/frontend/src/Author/Details/AuthorDetailsConnector.js
index 06164cec4..1d7108682 100644
--- a/frontend/src/Author/Details/AuthorDetailsConnector.js
+++ b/frontend/src/Author/Details/AuthorDetailsConnector.js
@@ -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,
diff --git a/frontend/src/Author/Details/AuthorDetailsSeasonConnector.js b/frontend/src/Author/Details/AuthorDetailsSeasonConnector.js
index 9857cf828..e324c5379 100644
--- a/frontend/src/Author/Details/AuthorDetailsSeasonConnector.js
+++ b/frontend/src/Author/Details/AuthorDetailsSeasonConnector.js
@@ -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
};
diff --git a/frontend/src/Book/Details/BookDetailsConnector.js b/frontend/src/Book/Details/BookDetailsConnector.js
index 87f26fea0..f36c8e9b3 100644
--- a/frontend/src/Book/Details/BookDetailsConnector.js
+++ b/frontend/src/Book/Details/BookDetailsConnector.js
@@ -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 {};
diff --git a/frontend/src/Book/Details/BookDetailsPageConnector.js b/frontend/src/Book/Details/BookDetailsPageConnector.js
index 56a3c2117..debde146c 100644
--- a/frontend/src/Book/Details/BookDetailsPageConnector.js
+++ b/frontend/src/Book/Details/BookDetailsPageConnector.js
@@ -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
};
diff --git a/frontend/src/Book/Index/BookIndexConnector.js b/frontend/src/Book/Index/BookIndexConnector.js
index c25ae2eeb..589edfc10 100644
--- a/frontend/src/Book/Index/BookIndexConnector.js
+++ b/frontend/src/Book/Index/BookIndexConnector.js
@@ -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
};
diff --git a/frontend/src/Bookshelf/Bookshelf.js b/frontend/src/Bookshelf/Bookshelf.js
index c1db2b96f..a0eab10e5 100644
--- a/frontend/src/Bookshelf/Bookshelf.js
+++ b/frontend/src/Bookshelf/Bookshelf.js
@@ -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 &&
{
- 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
};
diff --git a/frontend/src/Components/Page/PageConnector.js b/frontend/src/Components/Page/PageConnector.js
index 5eff6ff93..a9139024e 100644
--- a/frontend/src/Components/Page/PageConnector.js
+++ b/frontend/src/Components/Page/PageConnector.js
@@ -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,
diff --git a/frontend/src/Components/Page/Sidebar/PageSidebar.js b/frontend/src/Components/Page/Sidebar/PageSidebar.js
index 4a08194fc..d625f8d0a 100644
--- a/frontend/src/Components/Page/Sidebar/PageSidebar.js
+++ b/frontend/src/Components/Page/Sidebar/PageSidebar.js
@@ -42,7 +42,7 @@ const links = [
},
{
title: 'Bookshelf',
- to: '/bookshelf'
+ to: '/shelf'
},
{
title: 'Unmapped Files',
diff --git a/frontend/src/Components/SignalRConnector.js b/frontend/src/Components/SignalRConnector.js
index 715ea1755..45918a90f 100644
--- a/frontend/src/Components/SignalRConnector.js
+++ b/frontend/src/Components/SignalRConnector.js
@@ -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,
diff --git a/frontend/src/Store/Actions/authorDetailsActions.js b/frontend/src/Store/Actions/authorDetailsActions.js
new file mode 100644
index 000000000..900dec408
--- /dev/null
+++ b/frontend/src/Store/Actions/authorDetailsActions.js
@@ -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);
diff --git a/frontend/src/Store/Actions/bookActions.js b/frontend/src/Store/Actions/bookActions.js
index 7238f3f00..fcbfb61b8 100644
--- a/frontend/src/Store/Actions/bookActions.js
+++ b/frontend/src/Store/Actions/bookActions.js
@@ -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,
diff --git a/frontend/src/Store/Actions/index.js b/frontend/src/Store/Actions/index.js
index 9053ab5b3..90bbd0d25 100644
--- a/frontend/src/Store/Actions/index.js
+++ b/frontend/src/Store/Actions/index.js
@@ -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,
diff --git a/frontend/src/Store/Actions/searchActions.js b/frontend/src/Store/Actions/searchActions.js
index f27046354..503d93cbb 100644
--- a/frontend/src/Store/Actions/searchActions.js
+++ b/frontend/src/Store/Actions/searchActions.js
@@ -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({