From 468ebc330766c74caeaaea3d830d83130d85d7a1 Mon Sep 17 00:00:00 2001 From: ta264 Date: Wed, 1 Sep 2021 21:04:39 +0100 Subject: [PATCH] New: Load all books on page load and store in the browser --- frontend/src/Activity/History/History.js | 22 ----- .../src/Activity/History/HistoryConnector.js | 23 +---- frontend/src/Activity/Queue/QueueConnector.js | 19 ---- frontend/src/App/AppRoutes.js | 4 +- .../Author/Details/AuthorDetailsConnector.js | 7 -- .../Details/AuthorDetailsSeasonConnector.js | 25 +++-- .../src/Book/Details/BookDetailsConnector.js | 9 +- .../Book/Details/BookDetailsPageConnector.js | 20 +--- frontend/src/Book/Index/BookIndexConnector.js | 33 ------- frontend/src/Bookshelf/Bookshelf.js | 15 +-- frontend/src/Bookshelf/BookshelfConnector.js | 27 ------ frontend/src/Components/Page/PageConnector.js | 7 ++ .../Components/Page/Sidebar/PageSidebar.js | 2 +- frontend/src/Components/SignalRConnector.js | 5 +- .../src/Store/Actions/authorDetailsActions.js | 97 +++++++++++++++++++ frontend/src/Store/Actions/bookActions.js | 21 +++- frontend/src/Store/Actions/index.js | 26 ++--- frontend/src/Store/Actions/searchActions.js | 1 + 18 files changed, 172 insertions(+), 191 deletions(-) create mode 100644 frontend/src/Store/Actions/authorDetailsActions.js 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({