diff --git a/js/actions/edition_list_actions.js b/js/actions/edition_list_actions.js index 6f9881ee..a52e32b9 100644 --- a/js/actions/edition_list_actions.js +++ b/js/actions/edition_list_actions.js @@ -17,23 +17,31 @@ class EditionListActions { ); } - fetchEditionList(pieceId, page, pageSize, orderBy, orderAsc, filterBy) { - if((!orderBy && typeof orderAsc === 'undefined') || !orderAsc) { + fetchEditionList({ pieceId, page, pageSize, orderBy, orderAsc, filterBy, maxEdition }) { + if ((!orderBy && typeof orderAsc === 'undefined') || !orderAsc) { orderBy = 'edition_number'; orderAsc = true; } // Taken from: http://stackoverflow.com/a/519157/1263876 - if((typeof page === 'undefined' || !page) && (typeof pageSize === 'undefined' || !pageSize)) { + if ((typeof page === 'undefined' || !page) && (typeof pageSize === 'undefined' || !pageSize)) { page = 1; pageSize = 10; } + let itemsToFetch = pageSize; + // If we only want to fetch up to a specified edition, fetch all pages up to it + // as one page and adjust afterwards + if (typeof maxEdition === 'number') { + itemsToFetch = Math.ceil(maxEdition / pageSize) * pageSize; + page = 1; + } + return Q.Promise((resolve, reject) => { EditionListFetcher - .fetch(pieceId, page, pageSize, orderBy, orderAsc, filterBy) + .fetch({ pieceId, page, itemsToFetch, orderBy, orderAsc, filterBy }) .then((res) => { - if(res && !res.editions) { + if (res && !res.editions) { throw new Error('Piece has no editions to fetch.'); } @@ -44,8 +52,9 @@ class EditionListActions { orderBy, orderAsc, filterBy, - 'editionListOfPiece': res.editions, - 'count': res.count + maxEdition, + count: res.count, + editionListOfPiece: res.editions }); resolve(res); }) @@ -54,7 +63,6 @@ class EditionListActions { reject(err); }); }); - } } diff --git a/js/actions/piece_list_actions.js b/js/actions/piece_list_actions.js index 7ef9cb59..c52ef5e2 100644 --- a/js/actions/piece_list_actions.js +++ b/js/actions/piece_list_actions.js @@ -15,7 +15,7 @@ class PieceListActions { ); } - fetchPieceList(page, pageSize, search, orderBy, orderAsc, filterBy) { + fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy }) { // To prevent flickering on a pagination request, // we overwrite the piecelist with an empty list before // pieceListCount === -1 defines the loading state @@ -34,7 +34,7 @@ class PieceListActions { // afterwards, we can load the list return Q.Promise((resolve, reject) => { PieceListFetcher - .fetch(page, pageSize, search, orderBy, orderAsc, filterBy) + .fetch({ page, pageSize, search, orderBy, orderAsc, filterBy }) .then((res) => { this.actions.updatePieceList({ page, diff --git a/js/app.js b/js/app.js index dc8204cf..226409ec 100644 --- a/js/app.js +++ b/js/app.js @@ -1,6 +1,7 @@ 'use strict'; import 'babel/polyfill'; +import 'classlist-polyfill'; import React from 'react'; import { Router, Redirect } from 'react-router'; diff --git a/js/components/ascribe_accordion_list/accordion_list_item_edition_widget.js b/js/components/ascribe_accordion_list/accordion_list_item_edition_widget.js index 27657e04..2bb8b2d0 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_edition_widget.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_edition_widget.js @@ -19,9 +19,10 @@ import { getLangText } from '../../utils/lang_utils'; let AccordionListItemEditionWidget = React.createClass({ propTypes: { - className: React.PropTypes.string, piece: React.PropTypes.object.isRequired, toggleCreateEditionsDialog: React.PropTypes.func.isRequired, + + className: React.PropTypes.string, onPollingSuccess: React.PropTypes.func }, @@ -50,14 +51,15 @@ let AccordionListItemEditionWidget = React.createClass({ * Calls the store to either show or hide the editionListTable */ toggleTable() { - let pieceId = this.props.piece.id; - let isEditionListOpen = this.state.isEditionListOpenForPieceId[pieceId] ? this.state.isEditionListOpenForPieceId[pieceId].show : false; + const { piece: { id: pieceId } } = this.props; + const { filterBy, isEditionListOpenForPieceId } = this.state; + const isEditionListOpen = isEditionListOpenForPieceId[pieceId] ? isEditionListOpenForPieceId[pieceId].show : false; - if(isEditionListOpen) { + if (isEditionListOpen) { EditionListActions.toggleEditionList(pieceId); } else { EditionListActions.toggleEditionList(pieceId); - EditionListActions.fetchEditionList(pieceId, null, null, null, null, this.state.filterBy); + EditionListActions.fetchEditionList({ pieceId, filterBy }); } }, diff --git a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js index 586b75a2..3b0bb02e 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_table_editions.js @@ -66,20 +66,28 @@ let AccordionListItemTableEditions = React.createClass({ }, filterSelectedEditions() { - let selectedEditions = this.state.editionList[this.props.parentId] - .filter((edition) => edition.selected); - return selectedEditions; + return this.state + .editionList[this.props.parentId] + .filter((edition) => edition.selected); }, loadFurtherEditions() { + const { parentId: pieceId } = this.props; + const { page, pageSize, orderBy, orderAsc, filterBy } = this.state.editionList[pieceId]; + // trigger loading animation this.setState({ showMoreLoading: true }); - let editionList = this.state.editionList[this.props.parentId]; - EditionListActions.fetchEditionList(this.props.parentId, editionList.page + 1, editionList.pageSize, - editionList.orderBy, editionList.orderAsc, editionList.filterBy); + EditionListActions.fetchEditionList({ + pieceId, + pageSize, + orderBy, + orderAsc, + filterBy, + page: page + 1 + }); }, render() { const { className, parentId } = this.props; diff --git a/js/components/ascribe_accordion_list/accordion_list_item_wallet.js b/js/components/ascribe_accordion_list/accordion_list_item_wallet.js index a8cab166..f6712d37 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_wallet.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_wallet.js @@ -88,11 +88,12 @@ let AccordionListItemWallet = React.createClass({ }, onPollingSuccess(pieceId) { - PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, - this.state.orderBy, this.state.orderAsc, this.state.filterBy); + const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state; + + PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy }); EditionListActions.toggleEditionList(pieceId); - let notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000); + const notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000); GlobalNotificationActions.appendGlobalNotification(notification); }, diff --git a/js/components/ascribe_buttons/create_editions_button.js b/js/components/ascribe_buttons/create_editions_button.js index 08fb76ce..c78b0d63 100644 --- a/js/components/ascribe_buttons/create_editions_button.js +++ b/js/components/ascribe_buttons/create_editions_button.js @@ -28,6 +28,12 @@ let CreateEditionsButton = React.createClass({ EditionListStore.listen(this.onChange); }, + componentDidUpdate() { + if(this.props.piece.num_editions === 0 && typeof this.state.pollingIntervalIndex === 'undefined') { + this.startPolling(); + } + }, + componentWillUnmount() { EditionListStore.unlisten(this.onChange); clearInterval(this.state.pollingIntervalIndex); @@ -37,28 +43,24 @@ let CreateEditionsButton = React.createClass({ this.setState(state); }, - componentDidUpdate() { - if(this.props.piece.num_editions === 0 && typeof this.state.pollingIntervalIndex === 'undefined') { - this.startPolling(); - } - }, - startPolling() { // start polling until editions are defined let pollingIntervalIndex = setInterval(() => { // requests, will try to merge the filterBy parameter with other parameters (mergeOptions). // Therefore it can't but null but instead has to be an empty object - EditionListActions.fetchEditionList(this.props.piece.id, null, null, null, null, {}) - .then((res) => { - - clearInterval(this.state.pollingIntervalIndex); - this.props.onPollingSuccess(this.props.piece.id, res.editions[0].num_editions); - - }) - .catch((err) => { - /* Ignore and keep going */ - }); + EditionListActions + .fetchEditionList({ + pieceId: this.props.piece.id, + filterBy: {} + }) + .then((res) => { + clearInterval(this.state.pollingIntervalIndex); + this.props.onPollingSuccess(this.props.piece.id, res.editions[0].num_editions); + }) + .catch((err) => { + /* Ignore and keep going */ + }); }, 5000); this.setState({ diff --git a/js/components/ascribe_detail/edition_action_panel.js b/js/components/ascribe_detail/edition_action_panel.js index 92c51c32..71bf38fe 100644 --- a/js/components/ascribe_detail/edition_action_panel.js +++ b/js/components/ascribe_detail/edition_action_panel.js @@ -79,9 +79,10 @@ let EditionActionPanel = React.createClass({ }, refreshCollection() { - PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, - this.state.orderBy, this.state.orderAsc, this.state.filterBy); - EditionListActions.refreshEditionList({pieceId: this.props.edition.parent}); + const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state; + + PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy }); + EditionListActions.refreshEditionList({ pieceId: this.props.edition.parent }); }, handleSuccess(response) { diff --git a/js/components/ascribe_detail/piece_container.js b/js/components/ascribe_detail/piece_container.js index cd1559a2..f7ef024f 100644 --- a/js/components/ascribe_detail/piece_container.js +++ b/js/components/ascribe_detail/piece_container.js @@ -144,15 +144,18 @@ let PieceContainer = React.createClass({ }, handleEditionCreationSuccess() { + const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state; + PieceActions.updateProperty({ key: 'num_editions', value: 0 }); - PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, - this.state.orderBy, this.state.orderAsc, this.state.filterBy); + PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy }); + this.toggleCreateEditionsDialog(); }, handleDeleteSuccess(response) { - PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, - this.state.orderBy, this.state.orderAsc, this.state.filterBy); + const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state; + + PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy }); // since we're deleting a piece, we just need to close // all editions dialogs and not reload them @@ -181,6 +184,8 @@ let PieceContainer = React.createClass({ }, handlePollingSuccess(pieceId, numEditions) { + const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state; + // we need to refresh the num_editions property of the actual piece we're looking at PieceActions.updateProperty({ key: 'num_editions', @@ -191,8 +196,7 @@ let PieceContainer = React.createClass({ // btw.: It's not sufficient to just set num_editions to numEditions, since a single accordion // list item also uses the firstEdition property which we can only get from the server in that case. // Therefore we need to at least refetch the changed piece from the server or on our case simply all - PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, - this.state.orderBy, this.state.orderAsc, this.state.filterBy); + PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy }); const notification = new GlobalNotificationModel(getLangText('Editions successfully created'), 'success', 10000); GlobalNotificationActions.appendGlobalNotification(notification); diff --git a/js/components/global_action.js b/js/components/global_action.js deleted file mode 100644 index 80df0c75..00000000 --- a/js/components/global_action.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict'; - -import React from 'react'; - -let GlobalAction = React.createClass({ - propTypes: { - requestActions: React.PropTypes.object - }, - - render() { - let pieceActions = null; - if (this.props.requestActions && this.props.requestActions.pieces){ - pieceActions = this.props.requestActions.pieces.map((item) => { - return ( -