1
0
mirror of https://github.com/ascribe/onion.git synced 2024-12-23 09:50:31 +01:00
onion/js/components/piece_list.js
Brett Sun ac1b43d24b Set the consignee email by using the server's white label settings
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.
2015-10-26 19:17:06 +01:00

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;