mirror of
https://github.com/ascribe/onion.git
synced 2024-12-23 09:50:31 +01:00
ac1b43d24b
Consignee email is available through the white label settings we get from the server, so we don’t need to hardcode them into the constants. Separated out AclButtonList from PieceListbulkModal to make the modal more flexible and separated in concerns.
272 lines
11 KiB
JavaScript
272 lines
11 KiB
JavaScript
'use strict';
|
|
|
|
import React from 'react';
|
|
import { History } from 'react-router';
|
|
|
|
import PieceListStore from '../stores/piece_list_store';
|
|
import PieceListActions from '../actions/piece_list_actions';
|
|
|
|
import EditionListStore from '../stores/edition_list_store';
|
|
import EditionListActions from '../actions/edition_list_actions';
|
|
|
|
import AccordionList from './ascribe_accordion_list/accordion_list';
|
|
import AccordionListItemWallet from './ascribe_accordion_list/accordion_list_item_wallet';
|
|
import AccordionListItemTableEditions from './ascribe_accordion_list/accordion_list_item_table_editions';
|
|
|
|
import AclButtonList from './ascribe_buttons/acl_button_list.js';
|
|
import DeleteButton from './ascribe_buttons/delete_button';
|
|
|
|
import Pagination from './ascribe_pagination/pagination';
|
|
|
|
import PieceListFilterDisplay from './piece_list_filter_display';
|
|
|
|
import PieceListBulkModal from './ascribe_piece_list_bulk_modal/piece_list_bulk_modal';
|
|
import PieceListToolbar from './ascribe_piece_list_toolbar/piece_list_toolbar';
|
|
|
|
import AscribeSpinner from './ascribe_spinner';
|
|
|
|
import AppConstants from '../constants/application_constants';
|
|
|
|
import { getAvailableAcls } from '../utils/acl_utils';
|
|
import { mergeOptions } from '../utils/general_utils';
|
|
import { getLangText } from '../utils/lang_utils';
|
|
import { setDocumentTitle } from '../utils/dom_utils';
|
|
|
|
|
|
let PieceList = React.createClass({
|
|
propTypes: {
|
|
accordionListItemType: React.PropTypes.func,
|
|
bulkModalButtonListType: React.PropTypes.func,
|
|
redirectTo: React.PropTypes.string,
|
|
customSubmitButton: React.PropTypes.element,
|
|
filterParams: React.PropTypes.array,
|
|
orderParams: React.PropTypes.array,
|
|
orderBy: React.PropTypes.string,
|
|
location: React.PropTypes.object
|
|
},
|
|
|
|
mixins: [History],
|
|
|
|
getDefaultProps() {
|
|
return {
|
|
accordionListItemType: AccordionListItemWallet,
|
|
bulkModalButtonListType: AclButtonList,
|
|
orderParams: ['artist_name', 'title'],
|
|
filterParams: [{
|
|
label: getLangText('Show works I can'),
|
|
items: [
|
|
'acl_transfer',
|
|
'acl_consign',
|
|
'acl_create_editions'
|
|
]
|
|
}]
|
|
};
|
|
},
|
|
getInitialState() {
|
|
return mergeOptions(
|
|
PieceListStore.getState(),
|
|
EditionListStore.getState()
|
|
);
|
|
},
|
|
|
|
componentDidMount() {
|
|
let page = this.props.location.query.page || 1;
|
|
|
|
PieceListStore.listen(this.onChange);
|
|
EditionListStore.listen(this.onChange);
|
|
|
|
let orderBy = this.props.orderBy ? this.props.orderBy : this.state.orderBy;
|
|
if (this.state.pieceList.length === 0 || this.state.page !== page){
|
|
PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search,
|
|
orderBy, this.state.orderAsc, this.state.filterBy);
|
|
}
|
|
},
|
|
|
|
componentDidUpdate() {
|
|
if (this.props.redirectTo && this.state.unfilteredPieceListCount === 0) {
|
|
// FIXME: hack to redirect out of the dispatch cycle
|
|
window.setTimeout(() => this.history.pushState(null, this.props.redirectTo, this.props.location.query), 0);
|
|
}
|
|
},
|
|
|
|
componentWillUnmount() {
|
|
PieceListStore.unlisten(this.onChange);
|
|
EditionListStore.unlisten(this.onChange);
|
|
},
|
|
|
|
onChange(state) {
|
|
this.setState(state);
|
|
},
|
|
|
|
paginationGoToPage(page) {
|
|
return () => {
|
|
// if the users clicks a pager of the pagination,
|
|
// the site should go to the top
|
|
document.body.scrollTop = document.documentElement.scrollTop = 0;
|
|
PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search,
|
|
this.state.orderBy, this.state.orderAsc,
|
|
this.state.filterBy);
|
|
};
|
|
},
|
|
|
|
getPagination() {
|
|
let currentPage = parseInt(this.props.location.query.page, 10) || 1;
|
|
let totalPages = Math.ceil(this.state.pieceListCount / this.state.pageSize);
|
|
|
|
if (this.state.pieceListCount > 20) {
|
|
return (
|
|
<Pagination
|
|
currentPage={currentPage}
|
|
totalPages={totalPages}
|
|
goToPage={this.paginationGoToPage} />
|
|
);
|
|
}
|
|
},
|
|
|
|
searchFor(searchTerm) {
|
|
PieceListActions.fetchPieceList(1, this.state.pageSize, searchTerm, this.state.orderBy,
|
|
this.state.orderAsc, this.state.filterBy);
|
|
this.history.pushState(null, this.props.location.pathname, {page: 1});
|
|
},
|
|
|
|
applyFilterBy(filterBy){
|
|
// first we need to apply the filter on the piece list
|
|
PieceListActions.fetchPieceList(1, this.state.pageSize, this.state.search,
|
|
this.state.orderBy, this.state.orderAsc, filterBy)
|
|
.then(() => {
|
|
// but also, we need to filter all the open edition lists
|
|
this.state.pieceList
|
|
.forEach((piece) => {
|
|
// but only if they're actually open
|
|
if(this.state.isEditionListOpenForPieceId[piece.id].show) {
|
|
EditionListActions.refreshEditionList({
|
|
pieceId: piece.id,
|
|
filterBy
|
|
});
|
|
}
|
|
|
|
});
|
|
});
|
|
|
|
// we have to redirect the user always to page one as it could be that there is no page two
|
|
// for filtered pieces
|
|
this.history.pushState(null, this.props.location.pathname, {page: 1});
|
|
},
|
|
|
|
applyOrderBy(orderBy) {
|
|
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
|
orderBy, this.state.orderAsc, this.state.filterBy);
|
|
},
|
|
|
|
fetchSelectedPieceEditionList() {
|
|
let filteredPieceIdList = Object.keys(this.state.editionList)
|
|
.filter((pieceId) => {
|
|
return this.state.editionList[pieceId]
|
|
.filter((edition) => edition.selected).length > 0;
|
|
});
|
|
return filteredPieceIdList;
|
|
},
|
|
|
|
fetchSelectedEditionList() {
|
|
let selectedEditionList = [];
|
|
|
|
Object
|
|
.keys(this.state.editionList)
|
|
.forEach((pieceId) => {
|
|
let filteredEditionsForPiece = this.state.editionList[pieceId].filter((edition) => edition.selected);
|
|
selectedEditionList = selectedEditionList.concat(filteredEditionsForPiece);
|
|
});
|
|
|
|
return selectedEditionList;
|
|
},
|
|
|
|
handleAclSuccess() {
|
|
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
|
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
|
|
|
this.fetchSelectedPieceEditionList()
|
|
.forEach((pieceId) => {
|
|
EditionListActions.refreshEditionList({pieceId, filterBy: {}});
|
|
});
|
|
EditionListActions.clearAllEditionSelections();
|
|
},
|
|
|
|
render() {
|
|
const loadingElement = <AscribeSpinner color='dark-blue' size='lg'/>;
|
|
const AccordionListItemType = this.props.accordionListItemType;
|
|
const BulkModalButtonListType = this.props.bulkModalButtonListType;
|
|
|
|
const selectedEditions = this.fetchSelectedEditionList();
|
|
const availableAcls = getAvailableAcls(selectedEditions, (aclName) => aclName !== 'acl_view');
|
|
|
|
setDocumentTitle(getLangText('Collection'));
|
|
|
|
return (
|
|
<div>
|
|
<PieceListToolbar
|
|
className="ascribe-piece-list-toolbar"
|
|
searchFor={this.searchFor}
|
|
searchQuery={this.state.search}
|
|
filterParams={this.props.filterParams}
|
|
orderParams={this.props.orderParams}
|
|
filterBy={this.state.filterBy}
|
|
orderBy={this.state.orderBy}
|
|
applyFilterBy={this.applyFilterBy}
|
|
applyOrderBy={this.applyOrderBy}>
|
|
{this.props.customSubmitButton ?
|
|
this.props.customSubmitButton :
|
|
<button className="btn btn-default btn-ascribe-add">
|
|
<span className="icon-ascribe icon-ascribe-add" />
|
|
</button>
|
|
}
|
|
</PieceListToolbar>
|
|
<PieceListBulkModal
|
|
availableAcls={availableAcls}
|
|
selectedEditions={selectedEditions}
|
|
className="ascribe-piece-list-bulk-modal">
|
|
<BulkModalButtonListType
|
|
availableAcls={availableAcls}
|
|
editions={selectedEditions}
|
|
handleSuccess={this.handleAclSuccess}
|
|
className="text-center ascribe-button-list collapse-group">
|
|
<DeleteButton
|
|
handleSuccess={this.handleAclSuccess}
|
|
editions={selectedEditions}/>
|
|
</BulkModalButtonListType>
|
|
</PieceListBulkModal>
|
|
<PieceListFilterDisplay
|
|
filterBy={this.state.filterBy}
|
|
filterParams={this.props.filterParams}/>
|
|
<AccordionList
|
|
className="ascribe-accordion-list"
|
|
changeOrder={this.accordionChangeOrder}
|
|
itemList={this.state.pieceList}
|
|
count={this.state.pieceListCount}
|
|
orderBy={this.state.orderBy}
|
|
orderAsc={this.state.orderAsc}
|
|
search={this.state.search}
|
|
searchFor={this.searchFor}
|
|
page={this.state.page}
|
|
pageSize={this.state.pageSize}
|
|
loadingElement={loadingElement}>
|
|
{this.state.pieceList.map((piece, i) => {
|
|
return (
|
|
<AccordionListItemType
|
|
className="col-xs-12 col-sm-10 col-md-8 col-lg-8 col-sm-offset-1 col-md-offset-2 col-lg-offset-2 ascribe-accordion-list-item"
|
|
content={piece}
|
|
key={i}>
|
|
<AccordionListItemTableEditions
|
|
className="ascribe-accordion-list-item-table col-xs-12 col-sm-10 col-md-8 col-lg-8 col-sm-offset-1 col-md-offset-2 col-lg-offset-2"
|
|
parentId={piece.id} />
|
|
</AccordionListItemType>
|
|
);
|
|
})}
|
|
</AccordionList>
|
|
{this.getPagination()}
|
|
</div>
|
|
);
|
|
}
|
|
});
|
|
|
|
export default PieceList;
|