mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 09:23:13 +01:00
Merge with master
This commit is contained in:
commit
aa00415a83
@ -17,23 +17,31 @@ class EditionListActions {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchEditionList(pieceId, page, pageSize, orderBy, orderAsc, filterBy) {
|
fetchEditionList({ pieceId, page, pageSize, orderBy, orderAsc, filterBy, maxEdition }) {
|
||||||
if((!orderBy && typeof orderAsc === 'undefined') || !orderAsc) {
|
if ((!orderBy && typeof orderAsc === 'undefined') || !orderAsc) {
|
||||||
orderBy = 'edition_number';
|
orderBy = 'edition_number';
|
||||||
orderAsc = true;
|
orderAsc = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Taken from: http://stackoverflow.com/a/519157/1263876
|
// 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;
|
page = 1;
|
||||||
pageSize = 10;
|
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) => {
|
return Q.Promise((resolve, reject) => {
|
||||||
EditionListFetcher
|
EditionListFetcher
|
||||||
.fetch(pieceId, page, pageSize, orderBy, orderAsc, filterBy)
|
.fetch({ pieceId, page, itemsToFetch, orderBy, orderAsc, filterBy })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if(res && !res.editions) {
|
if (res && !res.editions) {
|
||||||
throw new Error('Piece has no editions to fetch.');
|
throw new Error('Piece has no editions to fetch.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,8 +52,9 @@ class EditionListActions {
|
|||||||
orderBy,
|
orderBy,
|
||||||
orderAsc,
|
orderAsc,
|
||||||
filterBy,
|
filterBy,
|
||||||
'editionListOfPiece': res.editions,
|
maxEdition,
|
||||||
'count': res.count
|
count: res.count,
|
||||||
|
editionListOfPiece: res.editions
|
||||||
});
|
});
|
||||||
resolve(res);
|
resolve(res);
|
||||||
})
|
})
|
||||||
@ -54,7 +63,6 @@ class EditionListActions {
|
|||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
// To prevent flickering on a pagination request,
|
||||||
// we overwrite the piecelist with an empty list before
|
// we overwrite the piecelist with an empty list before
|
||||||
// pieceListCount === -1 defines the loading state
|
// pieceListCount === -1 defines the loading state
|
||||||
@ -34,7 +34,7 @@ class PieceListActions {
|
|||||||
// afterwards, we can load the list
|
// afterwards, we can load the list
|
||||||
return Q.Promise((resolve, reject) => {
|
return Q.Promise((resolve, reject) => {
|
||||||
PieceListFetcher
|
PieceListFetcher
|
||||||
.fetch(page, pageSize, search, orderBy, orderAsc, filterBy)
|
.fetch({ page, pageSize, search, orderBy, orderAsc, filterBy })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.actions.updatePieceList({
|
this.actions.updatePieceList({
|
||||||
page,
|
page,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import 'babel/polyfill';
|
import 'babel/polyfill';
|
||||||
|
import 'classlist-polyfill';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Router, Redirect } from 'react-router';
|
import { Router, Redirect } from 'react-router';
|
||||||
|
@ -19,9 +19,10 @@ import { getLangText } from '../../utils/lang_utils';
|
|||||||
|
|
||||||
let AccordionListItemEditionWidget = React.createClass({
|
let AccordionListItemEditionWidget = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
className: React.PropTypes.string,
|
|
||||||
piece: React.PropTypes.object.isRequired,
|
piece: React.PropTypes.object.isRequired,
|
||||||
toggleCreateEditionsDialog: React.PropTypes.func.isRequired,
|
toggleCreateEditionsDialog: React.PropTypes.func.isRequired,
|
||||||
|
|
||||||
|
className: React.PropTypes.string,
|
||||||
onPollingSuccess: React.PropTypes.func
|
onPollingSuccess: React.PropTypes.func
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -50,14 +51,15 @@ let AccordionListItemEditionWidget = React.createClass({
|
|||||||
* Calls the store to either show or hide the editionListTable
|
* Calls the store to either show or hide the editionListTable
|
||||||
*/
|
*/
|
||||||
toggleTable() {
|
toggleTable() {
|
||||||
let pieceId = this.props.piece.id;
|
const { piece: { id: pieceId } } = this.props;
|
||||||
let isEditionListOpen = this.state.isEditionListOpenForPieceId[pieceId] ? this.state.isEditionListOpenForPieceId[pieceId].show : false;
|
const { filterBy, isEditionListOpenForPieceId } = this.state;
|
||||||
|
const isEditionListOpen = isEditionListOpenForPieceId[pieceId] ? isEditionListOpenForPieceId[pieceId].show : false;
|
||||||
|
|
||||||
if(isEditionListOpen) {
|
if (isEditionListOpen) {
|
||||||
EditionListActions.toggleEditionList(pieceId);
|
EditionListActions.toggleEditionList(pieceId);
|
||||||
} else {
|
} else {
|
||||||
EditionListActions.toggleEditionList(pieceId);
|
EditionListActions.toggleEditionList(pieceId);
|
||||||
EditionListActions.fetchEditionList(pieceId, null, null, null, null, this.state.filterBy);
|
EditionListActions.fetchEditionList({ pieceId, filterBy });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -66,20 +66,28 @@ let AccordionListItemTableEditions = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
filterSelectedEditions() {
|
filterSelectedEditions() {
|
||||||
let selectedEditions = this.state.editionList[this.props.parentId]
|
return this.state
|
||||||
.filter((edition) => edition.selected);
|
.editionList[this.props.parentId]
|
||||||
return selectedEditions;
|
.filter((edition) => edition.selected);
|
||||||
},
|
},
|
||||||
|
|
||||||
loadFurtherEditions() {
|
loadFurtherEditions() {
|
||||||
|
const { parentId: pieceId } = this.props;
|
||||||
|
const { page, pageSize, orderBy, orderAsc, filterBy } = this.state.editionList[pieceId];
|
||||||
|
|
||||||
// trigger loading animation
|
// trigger loading animation
|
||||||
this.setState({
|
this.setState({
|
||||||
showMoreLoading: true
|
showMoreLoading: true
|
||||||
});
|
});
|
||||||
|
|
||||||
let editionList = this.state.editionList[this.props.parentId];
|
EditionListActions.fetchEditionList({
|
||||||
EditionListActions.fetchEditionList(this.props.parentId, editionList.page + 1, editionList.pageSize,
|
pieceId,
|
||||||
editionList.orderBy, editionList.orderAsc, editionList.filterBy);
|
pageSize,
|
||||||
|
orderBy,
|
||||||
|
orderAsc,
|
||||||
|
filterBy,
|
||||||
|
page: page + 1
|
||||||
|
});
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
const { className, parentId } = this.props;
|
const { className, parentId } = this.props;
|
||||||
|
@ -88,11 +88,12 @@ let AccordionListItemWallet = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
onPollingSuccess(pieceId) {
|
onPollingSuccess(pieceId) {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
|
||||||
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
EditionListActions.toggleEditionList(pieceId);
|
EditionListActions.toggleEditionList(pieceId);
|
||||||
|
|
||||||
let notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000);
|
const notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000);
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -28,6 +28,12 @@ let CreateEditionsButton = React.createClass({
|
|||||||
EditionListStore.listen(this.onChange);
|
EditionListStore.listen(this.onChange);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
if(this.props.piece.num_editions === 0 && typeof this.state.pollingIntervalIndex === 'undefined') {
|
||||||
|
this.startPolling();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
EditionListStore.unlisten(this.onChange);
|
EditionListStore.unlisten(this.onChange);
|
||||||
clearInterval(this.state.pollingIntervalIndex);
|
clearInterval(this.state.pollingIntervalIndex);
|
||||||
@ -37,28 +43,24 @@ let CreateEditionsButton = React.createClass({
|
|||||||
this.setState(state);
|
this.setState(state);
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidUpdate() {
|
|
||||||
if(this.props.piece.num_editions === 0 && typeof this.state.pollingIntervalIndex === 'undefined') {
|
|
||||||
this.startPolling();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
startPolling() {
|
startPolling() {
|
||||||
// start polling until editions are defined
|
// start polling until editions are defined
|
||||||
let pollingIntervalIndex = setInterval(() => {
|
let pollingIntervalIndex = setInterval(() => {
|
||||||
|
|
||||||
// requests, will try to merge the filterBy parameter with other parameters (mergeOptions).
|
// 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
|
// Therefore it can't but null but instead has to be an empty object
|
||||||
EditionListActions.fetchEditionList(this.props.piece.id, null, null, null, null, {})
|
EditionListActions
|
||||||
.then((res) => {
|
.fetchEditionList({
|
||||||
|
pieceId: this.props.piece.id,
|
||||||
clearInterval(this.state.pollingIntervalIndex);
|
filterBy: {}
|
||||||
this.props.onPollingSuccess(this.props.piece.id, res.editions[0].num_editions);
|
})
|
||||||
|
.then((res) => {
|
||||||
})
|
clearInterval(this.state.pollingIntervalIndex);
|
||||||
.catch((err) => {
|
this.props.onPollingSuccess(this.props.piece.id, res.editions[0].num_editions);
|
||||||
/* Ignore and keep going */
|
})
|
||||||
});
|
.catch((err) => {
|
||||||
|
/* Ignore and keep going */
|
||||||
|
});
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -79,9 +79,10 @@ let EditionActionPanel = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
refreshCollection() {
|
refreshCollection() {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
|
||||||
EditionListActions.refreshEditionList({pieceId: this.props.edition.parent});
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
|
EditionListActions.refreshEditionList({ pieceId: this.props.edition.parent });
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSuccess(response) {
|
handleSuccess(response) {
|
||||||
|
@ -144,15 +144,18 @@ let PieceContainer = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleEditionCreationSuccess() {
|
handleEditionCreationSuccess() {
|
||||||
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
|
|
||||||
PieceActions.updateProperty({ key: 'num_editions', value: 0 });
|
PieceActions.updateProperty({ key: 'num_editions', value: 0 });
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
|
||||||
this.toggleCreateEditionsDialog();
|
this.toggleCreateEditionsDialog();
|
||||||
},
|
},
|
||||||
|
|
||||||
handleDeleteSuccess(response) {
|
handleDeleteSuccess(response) {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
|
||||||
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
|
|
||||||
// since we're deleting a piece, we just need to close
|
// since we're deleting a piece, we just need to close
|
||||||
// all editions dialogs and not reload them
|
// all editions dialogs and not reload them
|
||||||
@ -181,6 +184,8 @@ let PieceContainer = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handlePollingSuccess(pieceId, numEditions) {
|
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
|
// we need to refresh the num_editions property of the actual piece we're looking at
|
||||||
PieceActions.updateProperty({
|
PieceActions.updateProperty({
|
||||||
key: 'num_editions',
|
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
|
// 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.
|
// 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
|
// 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,
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
|
||||||
|
|
||||||
const notification = new GlobalNotificationModel(getLangText('Editions successfully created'), 'success', 10000);
|
const notification = new GlobalNotificationModel(getLangText('Editions successfully created'), 'success', 10000);
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
@ -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 (
|
|
||||||
<div className="ascribe-global-action">
|
|
||||||
{item}
|
|
||||||
</div>);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let editionActions = null;
|
|
||||||
if (this.props.requestActions && this.props.requestActions.editions){
|
|
||||||
editionActions = Object.keys(this.props.requestActions.editions).map((pieceId) => {
|
|
||||||
return this.props.requestActions.editions[pieceId].map((item) => {
|
|
||||||
return (
|
|
||||||
<div className="ascribe-global-action">
|
|
||||||
{item}
|
|
||||||
</div>);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pieceActions || editionActions) {
|
|
||||||
return (
|
|
||||||
<div className="ascribe-global-action-wrapper">
|
|
||||||
{pieceActions}
|
|
||||||
{editionActions}
|
|
||||||
</div>);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default GlobalAction;
|
|
@ -196,13 +196,14 @@ let PieceList = React.createClass({
|
|||||||
this.state.pieceList
|
this.state.pieceList
|
||||||
.forEach((piece) => {
|
.forEach((piece) => {
|
||||||
// but only if they're actually open
|
// but only if they're actually open
|
||||||
if(this.state.isEditionListOpenForPieceId[piece.id].show) {
|
const isEditionListOpenForPiece = this.state.isEditionListOpenForPieceId[piece.id];
|
||||||
|
|
||||||
|
if (isEditionListOpenForPiece && isEditionListOpenForPiece.show) {
|
||||||
EditionListActions.refreshEditionList({
|
EditionListActions.refreshEditionList({
|
||||||
pieceId: piece.id,
|
pieceId: piece.id,
|
||||||
filterBy
|
filterBy
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -212,15 +213,15 @@ let PieceList = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
applyOrderBy(orderBy) {
|
applyOrderBy(orderBy) {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
const { filterBy, orderAsc, page, pageSize, search } = this.state;
|
||||||
orderBy, this.state.orderAsc, this.state.filterBy);
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
},
|
},
|
||||||
|
|
||||||
loadPieceList({ page, filterBy = this.state.filterBy, search = this.state.search }) {
|
loadPieceList({ page, filterBy = this.state.filterBy, search = this.state.search }) {
|
||||||
|
const { orderAsc, pageSize } = this.state;
|
||||||
const orderBy = this.state.orderBy || this.props.orderBy;
|
const orderBy = this.state.orderBy || this.props.orderBy;
|
||||||
|
|
||||||
return PieceListActions.fetchPieceList(page, this.state.pageSize, search,
|
return PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
orderBy, this.state.orderAsc, filterBy);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchSelectedPieceEditionList() {
|
fetchSelectedPieceEditionList() {
|
||||||
@ -246,8 +247,9 @@ let PieceList = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleAclSuccess() {
|
handleAclSuccess() {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
const { filterBy, orderBy, orderAsc, page, pageSize, search } = this.state;
|
||||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
|
||||||
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
|
|
||||||
this.fetchSelectedPieceEditionList()
|
this.fetchSelectedPieceEditionList()
|
||||||
.forEach((pieceId) => {
|
.forEach((pieceId) => {
|
||||||
|
@ -65,26 +65,21 @@ let RegisterPiece = React.createClass( {
|
|||||||
this.setState(state);
|
this.setState(state);
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSuccess(response){
|
handleSuccess(response) {
|
||||||
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
|
|
||||||
const notification = new GlobalNotificationModel(response.notification, 'success', 10000);
|
const notification = new GlobalNotificationModel(response.notification, 'success', 10000);
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
|
||||||
// once the user was able to register a piece successfully, we need to make sure to keep
|
// once the user was able to register a piece successfully, we need to make sure to keep
|
||||||
// the piece list up to date
|
// the piece list up to date
|
||||||
PieceListActions.fetchPieceList(
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
this.state.page,
|
|
||||||
this.state.pageSize,
|
|
||||||
this.state.searchTerm,
|
|
||||||
this.state.orderBy,
|
|
||||||
this.state.orderAsc,
|
|
||||||
this.state.filterBy
|
|
||||||
);
|
|
||||||
|
|
||||||
this.history.push(`/pieces/${response.piece.id}`);
|
this.history.push(`/pieces/${response.piece.id}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
getSpecifyEditions() {
|
getSpecifyEditions() {
|
||||||
if(this.state.whitelabel && this.state.whitelabel.acl_create_editions || Object.keys(this.state.whitelabel).length === 0) {
|
if (this.state.whitelabel && this.state.whitelabel.acl_create_editions || Object.keys(this.state.whitelabel).length === 0) {
|
||||||
return (
|
return (
|
||||||
<Property
|
<Property
|
||||||
name="num_editions"
|
name="num_editions"
|
||||||
|
@ -58,8 +58,9 @@ let AccordionListItemPrize = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleSubmitPrizeSuccess(response) {
|
handleSubmitPrizeSuccess(response) {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
|
||||||
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
|
|
||||||
let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
|
let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
@ -138,8 +139,9 @@ let AccordionListItemPrize = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
refreshPieceData() {
|
refreshPieceData() {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
|
||||||
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
},
|
},
|
||||||
|
|
||||||
onSelectChange(){
|
onSelectChange(){
|
||||||
|
@ -301,9 +301,10 @@ let PrizePieceRatings = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
refreshPieceData() {
|
refreshPieceData() {
|
||||||
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
|
|
||||||
this.props.loadPiece();
|
this.props.loadPiece();
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onSelectChange() {
|
onSelectChange() {
|
||||||
|
@ -52,8 +52,9 @@ let CylandAccordionListItem = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleSubmitSuccess(response) {
|
handleSubmitSuccess(response) {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
|
||||||
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
|
|
||||||
let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
|
let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
@ -77,8 +77,9 @@ let CylandPieceContainer = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleDeleteSuccess(response) {
|
handleDeleteSuccess(response) {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
|
||||||
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
|
|
||||||
// since we're deleting a piece, we just need to close
|
// since we're deleting a piece, we just need to close
|
||||||
// all editions dialogs and not reload them
|
// all editions dialogs and not reload them
|
||||||
|
@ -133,14 +133,9 @@ let CylandRegisterPiece = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
refreshPieceList() {
|
refreshPieceList() {
|
||||||
PieceListActions.fetchPieceList(
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
this.state.page,
|
|
||||||
this.state.pageSize,
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
this.state.searchTerm,
|
|
||||||
this.state.orderBy,
|
|
||||||
this.state.orderAsc,
|
|
||||||
this.state.filterBy
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -53,8 +53,9 @@ let IkonotvAccordionListItem = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleSubmitSuccess(response) {
|
handleSubmitSuccess(response) {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
|
||||||
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
|
|
||||||
let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
|
let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
|
||||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
@ -78,8 +78,9 @@ let IkonotvPieceContainer = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleDeleteSuccess(response) {
|
handleDeleteSuccess(response) {
|
||||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
|
||||||
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
|
|
||||||
// since we're deleting a piece, we just need to close
|
// since we're deleting a piece, we just need to close
|
||||||
// all editions dialogs and not reload them
|
// all editions dialogs and not reload them
|
||||||
|
@ -138,14 +138,9 @@ let IkonotvRegisterPiece = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
refreshPieceList() {
|
refreshPieceList() {
|
||||||
PieceListActions.fetchPieceList(
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
this.state.page,
|
|
||||||
this.state.pageSize,
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
this.state.searchTerm,
|
|
||||||
this.state.orderBy,
|
|
||||||
this.state.orderAsc,
|
|
||||||
this.state.filterBy
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
canSubmit() {
|
canSubmit() {
|
||||||
|
@ -105,14 +105,9 @@ let MarketRegisterPiece = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
refreshPieceList() {
|
refreshPieceList() {
|
||||||
PieceListActions.fetchPieceList(
|
const { filterBy, orderAsc, orderBy, page, pageSize, search } = this.state;
|
||||||
this.state.page,
|
|
||||||
this.state.pageSize,
|
PieceListActions.fetchPieceList({ page, pageSize, search, orderBy, orderAsc, filterBy });
|
||||||
this.state.searchTerm,
|
|
||||||
this.state.orderBy,
|
|
||||||
this.state.orderAsc,
|
|
||||||
this.state.filterBy
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -9,10 +9,10 @@ let EditionListFetcher = {
|
|||||||
/**
|
/**
|
||||||
* Fetches a list of editions from the API.
|
* Fetches a list of editions from the API.
|
||||||
*/
|
*/
|
||||||
fetch(pieceId, page, pageSize, orderBy, orderAsc, filterBy) {
|
fetch({ pieceId, page, pageSize, orderBy, orderAsc, filterBy }) {
|
||||||
let ordering = generateOrderingQueryParams(orderBy, orderAsc);
|
const ordering = generateOrderingQueryParams(orderBy, orderAsc);
|
||||||
|
|
||||||
let queryParams = mergeOptions(
|
const queryParams = mergeOptions(
|
||||||
{
|
{
|
||||||
page,
|
page,
|
||||||
pageSize,
|
pageSize,
|
||||||
|
@ -10,12 +10,12 @@ let PieceListFetcher = {
|
|||||||
* Fetches a list of pieces from the API.
|
* Fetches a list of pieces from the API.
|
||||||
* Can be called with all supplied queryparams the API.
|
* Can be called with all supplied queryparams the API.
|
||||||
*/
|
*/
|
||||||
fetch(page, pageSize, search, orderBy, orderAsc, filterBy) {
|
fetch({ page, pageSize, search, orderBy, orderAsc, filterBy }) {
|
||||||
let ordering = generateOrderingQueryParams(orderBy, orderAsc);
|
const ordering = generateOrderingQueryParams(orderBy, orderAsc);
|
||||||
|
|
||||||
// filterBy is an object of acl key-value pairs.
|
// filterBy is an object of acl key-value pairs.
|
||||||
// The values are booleans
|
// The values are booleans
|
||||||
let queryParams = mergeOptions(
|
const queryParams = mergeOptions(
|
||||||
{
|
{
|
||||||
page,
|
page,
|
||||||
pageSize,
|
pageSize,
|
||||||
|
@ -12,7 +12,11 @@ class EditionListStore {
|
|||||||
this.bindActions(EditionsListActions);
|
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.
|
Basically there are two modes an edition list can be updated.
|
||||||
|
|
||||||
@ -20,93 +24,107 @@ class EditionListStore {
|
|||||||
2. The elements are already defined => merge current objects with the new ones from the server
|
2. The elements are already defined => merge current objects with the new ones from the server
|
||||||
|
|
||||||
*/
|
*/
|
||||||
for (let i = 0; i < editionListOfPiece.length; i++) {
|
editionListOfPiece.forEach((updatedEdition, index) => {
|
||||||
|
// this is the index formula for accessing an edition starting from a specific page
|
||||||
// if editionList for a specific piece does not exist yet,
|
const storeEditionIndex = (page - 1) * pageSize + index;
|
||||||
// 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];
|
|
||||||
|
|
||||||
// if edition already exists, just merge
|
// if edition already exists, just merge
|
||||||
if(editionsForPieces[storeEditionIndex]) {
|
if (pieceEditionList[storeEditionIndex]) {
|
||||||
editionsForPieces[storeEditionIndex] = React.addons.update(editionsForPieces[storeEditionIndex], {$merge: editionListOfPiece[i]});
|
pieceEditionList[storeEditionIndex] = React.addons.update(pieceEditionList[storeEditionIndex], { $merge: updatedEdition });
|
||||||
} else {
|
} else {
|
||||||
// if does not exist, assign
|
// 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
|
* 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.
|
* therefore they need to be saved in relation to their parent-piece.
|
||||||
*
|
*
|
||||||
* Default values for both are set in the editon_list_actions.
|
* Default values for both are set in the editon_list_actions.
|
||||||
*/
|
*/
|
||||||
this.editionList[pieceId].page = page;
|
pieceEditionList.page = page;
|
||||||
this.editionList[pieceId].pageSize = pageSize;
|
pieceEditionList.pageSize = pageSize;
|
||||||
this.editionList[pieceId].orderBy = orderBy;
|
pieceEditionList.orderBy = orderBy;
|
||||||
this.editionList[pieceId].orderAsc = orderAsc;
|
pieceEditionList.orderAsc = orderAsc;
|
||||||
this.editionList[pieceId].count = count;
|
pieceEditionList.count = count;
|
||||||
this.editionList[pieceId].filterBy = filterBy;
|
pieceEditionList.filterBy = filterBy;
|
||||||
|
|
||||||
|
if (pieceEditionList.maxSeen == null || lastEdition.edition_number > pieceEditionList.maxSeen) {
|
||||||
|
pieceEditionList.maxSeen = lastEdition.edition_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.editionList[pieceId] = pieceEditionList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We often just have to refresh the edition list for a certain pieceId,
|
* We often just have to refresh the edition list for a certain pieceId,
|
||||||
* this method provides exactly that functionality without any side effects
|
* this method provides exactly that functionality without any side effects
|
||||||
*/
|
*/
|
||||||
onRefreshEditionList({ pieceId, filterBy = {} }) {
|
onRefreshEditionList({ pieceId, filterBy }) {
|
||||||
|
const pieceEditionList = this.editionList[pieceId];
|
||||||
|
|
||||||
// It may happen that the user enters the site logged in already
|
// It may happen that the user enters the site logged in already
|
||||||
// through /editions
|
// through /editions
|
||||||
// If he then tries to delete a piece/edition and this method is called,
|
// If he then tries to delete a piece/edition and this method is called,
|
||||||
// we'll not be able to refresh his edition list since its not yet there.
|
// we'll not be able to refresh his edition list since its not yet there.
|
||||||
// Therefore we can just return, since there is no data to be refreshed
|
// Therefore we can just return, since there is no data to be refreshed
|
||||||
if(!this.editionList[pieceId]) {
|
if (!this.editionList[pieceId]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let prevEditionListLength = this.editionList[pieceId].length;
|
if (typeof filterBy !== 'object') {
|
||||||
let prevEditionListPage = this.editionList[pieceId].page;
|
filterBy = pieceEditionList.filterBy;
|
||||||
let prevEditionListPageSize = this.editionList[pieceId].pageSize;
|
|
||||||
|
|
||||||
// we can also refresh the edition list using filterBy,
|
|
||||||
// if we decide not to do that then the old filter will just be applied.
|
|
||||||
if(filterBy && Object.keys(filterBy).length <= 0) {
|
|
||||||
filterBy = this.editionList[pieceId].filterBy;
|
|
||||||
prevEditionListLength = 10;
|
|
||||||
prevEditionListPage = 1;
|
|
||||||
prevEditionListPageSize = 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { maxSeen, orderAsc, orderBy, pageSize } = pieceEditionList;
|
||||||
|
|
||||||
// to clear an array, david walsh recommends to just set it's length to zero
|
// to clear an array, david walsh recommends to just set it's length to zero
|
||||||
// http://davidwalsh.name/empty-array
|
// http://davidwalsh.name/empty-array
|
||||||
this.editionList[pieceId].length = 0;
|
pieceEditionList.length = 0;
|
||||||
|
|
||||||
// refetch editions with adjusted page size
|
EditionsListActions
|
||||||
EditionsListActions.fetchEditionList(pieceId, 1, prevEditionListLength,
|
.fetchEditionList({
|
||||||
this.editionList[pieceId].orderBy,
|
pieceId,
|
||||||
this.editionList[pieceId].orderAsc,
|
pageSize,
|
||||||
filterBy)
|
orderBy,
|
||||||
.then(() => {
|
orderAsc,
|
||||||
// reset back to the normal pageSize and page
|
filterBy,
|
||||||
this.editionList[pieceId].page = prevEditionListPage;
|
maxSeen,
|
||||||
this.editionList[pieceId].pageSize = prevEditionListPageSize;
|
page: 1
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch(console.logGlobal);
|
||||||
console.logGlobal(err);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelectEdition({ pieceId, editionId, toValue }) {
|
onSelectEdition({ pieceId, editionId, toValue }) {
|
||||||
this.editionList[pieceId].forEach((edition) => {
|
this.editionList[pieceId].forEach((edition) => {
|
||||||
|
|
||||||
// Taken from: http://stackoverflow.com/a/519157/1263876
|
// Taken from: http://stackoverflow.com/a/519157/1263876
|
||||||
if(typeof toValue !== 'undefined' && edition.id === editionId) {
|
if (typeof toValue !== 'undefined' && edition.id === editionId) {
|
||||||
edition.selected = toValue;
|
edition.selected = toValue;
|
||||||
} else if(edition.id === editionId) {
|
} else if(edition.id === editionId) {
|
||||||
if(edition.selected) {
|
if(edition.selected) {
|
||||||
@ -132,7 +150,6 @@ class EditionListStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onToggleEditionList(pieceId) {
|
onToggleEditionList(pieceId) {
|
||||||
|
|
||||||
this.isEditionListOpenForPieceId[pieceId] = {
|
this.isEditionListOpenForPieceId[pieceId] = {
|
||||||
show: this.isEditionListOpenForPieceId[pieceId] ? !this.isEditionListOpenForPieceId[pieceId].show : true
|
show: this.isEditionListOpenForPieceId[pieceId] ? !this.isEditionListOpenForPieceId[pieceId].show : true
|
||||||
};
|
};
|
||||||
@ -141,7 +158,7 @@ class EditionListStore {
|
|||||||
// the merge fails, as the edition list is not refreshed when closed.
|
// the merge fails, as the edition list is not refreshed when closed.
|
||||||
// Therefore in the case of a filter application when closed, we need to reload the
|
// Therefore in the case of a filter application when closed, we need to reload the
|
||||||
// edition list
|
// edition list
|
||||||
if(!this.isEditionListOpenForPieceId[pieceId].show) {
|
if (!this.isEditionListOpenForPieceId[pieceId].show) {
|
||||||
// to clear an array, david walsh recommends to just set it's length to zero
|
// to clear an array, david walsh recommends to just set it's length to zero
|
||||||
// http://davidwalsh.name/empty-array
|
// http://davidwalsh.name/empty-array
|
||||||
|
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
export function onChangeOnce(component, store) {
|
|
||||||
const onChange = (state) => {
|
|
||||||
component.setState(state);
|
|
||||||
store.unlisten(onChange);
|
|
||||||
};
|
|
||||||
|
|
||||||
store.listen(onChange);
|
|
||||||
}
|
|
@ -48,6 +48,7 @@
|
|||||||
"browserify": "^9.0.8",
|
"browserify": "^9.0.8",
|
||||||
"browserify-shim": "^3.8.10",
|
"browserify-shim": "^3.8.10",
|
||||||
"camelcase": "^1.2.1",
|
"camelcase": "^1.2.1",
|
||||||
|
"classlist-polyfill": "^1.0.2",
|
||||||
"classnames": "^1.2.2",
|
"classnames": "^1.2.2",
|
||||||
"compression": "^1.4.4",
|
"compression": "^1.4.4",
|
||||||
"decamelize": "^1.1.1",
|
"decamelize": "^1.1.1",
|
||||||
|
@ -447,9 +447,9 @@ fieldset[disabled] .btn-secondary.active {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.search-bar > .form-group > .input-group {
|
.search-bar > .form-group > .input-group {
|
||||||
border: 1px solid rgba(0, 0, 0, 0);
|
border: 1px solid $ascribe-blue-border;
|
||||||
&:hover, &:focus, &:active {
|
&:hover, &:focus, &:active {
|
||||||
border-color: $ascribe-blue-border;
|
border-color: $ascribe-blue-border-active;
|
||||||
}
|
}
|
||||||
input::-webkit-input-placeholder {
|
input::-webkit-input-placeholder {
|
||||||
color: rgba($ascribe-dark-blue, 0.5);
|
color: rgba($ascribe-dark-blue, 0.5);
|
||||||
|
@ -5,6 +5,7 @@ $ascribe-light-blue: #D3DEE4;
|
|||||||
$ascribe-white: #F8F8F8;
|
$ascribe-white: #F8F8F8;
|
||||||
$ascribe-pink: #D10074;
|
$ascribe-pink: #D10074;
|
||||||
$ascribe-blue-border: rgba(0, 60, 105, 0.1);
|
$ascribe-blue-border: rgba(0, 60, 105, 0.1);
|
||||||
|
$ascribe-blue-border-active: rgba(0, 60, 105, 0.2);
|
||||||
$ascribe-red-error: rgb(169, 68, 66);
|
$ascribe-red-error: rgb(169, 68, 66);
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user