From 4fa25ca446102731971ab76c7f380d23926df6da Mon Sep 17 00:00:00 2001 From: Brett Sun Date: Tue, 8 Dec 2015 13:41:15 +0100 Subject: [PATCH] Add option to specify the max edition to fetch and update the edition list to --- js/actions/edition_list_actions.js | 20 ++++++--- js/components/piece_list.js | 2 +- js/stores/edition_list_store.js | 69 ++++++++++++++++++++---------- 3 files changed, 62 insertions(+), 29 deletions(-) diff --git a/js/actions/edition_list_actions.js b/js/actions/edition_list_actions.js index 6f9881ee..7d1e47e7 100644 --- a/js/actions/edition_list_actions.js +++ b/js/actions/edition_list_actions.js @@ -17,7 +17,7 @@ class EditionListActions { ); } - fetchEditionList(pieceId, page, pageSize, orderBy, orderAsc, filterBy) { + fetchEditionList(pieceId, page, pageSize, orderBy, orderAsc, filterBy, maxEdition) { if((!orderBy && typeof orderAsc === 'undefined') || !orderAsc) { orderBy = 'edition_number'; orderAsc = true; @@ -29,23 +29,32 @@ class EditionListActions { 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.'); } this.actions.updateEditionList({ pieceId, + editionListOfPiece: res.editions, page, pageSize, orderBy, orderAsc, + count: res.count, filterBy, - 'editionListOfPiece': res.editions, - 'count': res.count + maxEdition }); resolve(res); }) @@ -54,7 +63,6 @@ class EditionListActions { reject(err); }); }); - } } diff --git a/js/components/piece_list.js b/js/components/piece_list.js index 4a269aa8..85706d7c 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -63,7 +63,7 @@ let PieceList = React.createClass({ componentDidMount() { let page = this.props.location.query.page || 1; - + PieceListStore.listen(this.onChange); EditionListStore.listen(this.onChange); diff --git a/js/stores/edition_list_store.js b/js/stores/edition_list_store.js index 6b4d64f9..4f33dc6f 100644 --- a/js/stores/edition_list_store.js +++ b/js/stores/edition_list_store.js @@ -12,7 +12,11 @@ class EditionListStore { this.bindActions(EditionsListActions); } - onUpdateEditionList({pieceId, editionListOfPiece, page, pageSize, orderBy, orderAsc, count, filterBy}) { + onUpdateEditionList({pieceId, editionListOfPiece, page, pageSize, orderBy, orderAsc, count, filterBy, maxEdition}) { + // if editionList for a specific piece does not exist yet, + // just initialize a new array + const pieceEditionList = this.editionList[pieceId] || []; + /* Basically there are two modes an edition list can be updated. @@ -20,40 +24,61 @@ class EditionListStore { 2. The elements are already defined => merge current objects with the new ones from the server */ - for(let i = 0; i < editionListOfPiece.length; i++) { - - // if editionList for a specific piece does not exist yet, - // just initialize a new array - if(!this.editionList[pieceId]) { - this.editionList[pieceId] = []; - } - - // this is the index formula for accessing an edition of a specific - // page - let storeEditionIndex = (page - 1) * pageSize + i; - let editionsForPieces = this.editionList[pieceId]; + editionListOfPiece.forEach((updatedEdition, index) => { + // this is the index formula for accessing an edition starting from a specific page + const storeEditionIndex = (page - 1) * pageSize + index; // if edition already exists, just merge - if(editionsForPieces[storeEditionIndex]) { - editionsForPieces[storeEditionIndex] = React.addons.update(editionsForPieces[storeEditionIndex], {$merge: editionListOfPiece[i]}); + if(pieceEditionList[storeEditionIndex]) { + pieceEditionList[storeEditionIndex] = React.addons.update(pieceEditionList[storeEditionIndex], {$merge: updatedEdition}); } else { // if does not exist, assign - editionsForPieces[storeEditionIndex] = editionListOfPiece[i]; + pieceEditionList[storeEditionIndex] = updatedEdition; + } + }); + + // Remove editions after specified max by finding the index of the first + // edition larger than the max edition and using that to cut off the rest of the list + if (typeof maxEdition === 'number') { + const largerThanMaxIndex = pieceEditionList.findIndex(edition => edition.edition_number > maxEdition); + + if (largerThanMaxIndex !== -1) { + // The API defines inflexible page buckets based on the page number + // and page size, so we cannot just arbitrarily cut off the end of + // a page and expect get the rest of it on the next pagination request. + // Hence, we use the max edition index as a guide for which page to + // cut off to so as to always provide complete pages. + page = Math.ceil(largerThanMaxIndex / pageSize); + + // We only want to cut off the list if there are more editions than + // there should be (ie. we're not already at the end of the editions) + const totalPageSize = page * pageSize; + if (pieceEditionList.length > totalPageSize) { + pieceEditionList.length = totalPageSize; + } } } + const lastEdition = pieceEditionList[pieceEditionList.length - 1]; + /** * page, pageSize, orderBy, orderAsc and count are specific to a single list of editions * therefore they need to be saved in relation to their parent-piece. * * Default values for both are set in the editon_list_actions. */ - this.editionList[pieceId].page = page; - this.editionList[pieceId].pageSize = pageSize; - this.editionList[pieceId].orderBy = orderBy; - this.editionList[pieceId].orderAsc = orderAsc; - this.editionList[pieceId].count = count; - this.editionList[pieceId].filterBy = filterBy; + pieceEditionList.page = page; + pieceEditionList.pageSize = pageSize; + pieceEditionList.orderBy = orderBy; + pieceEditionList.orderAsc = orderAsc; + pieceEditionList.count = count; + pieceEditionList.filterBy = filterBy; + + if (pieceEditionList.maxSeen == null || lastEdition.edition_number > pieceEditionList.maxSeen) { + pieceEditionList.maxSeen = lastEdition.edition_number; + } + + this.editionList[pieceId] = pieceEditionList; } /**