@@ -104,7 +70,7 @@ let PieceListBulkModal = React.createClass({
+ numberOfSelectedEditions={this.props.selectedEditions.length} />
-
-
-
+ {this.props.children}
diff --git a/js/components/piece_list.js b/js/components/piece_list.js
index c427a911..528ee409 100644
--- a/js/components/piece_list.js
+++ b/js/components/piece_list.js
@@ -13,6 +13,9 @@ 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';
@@ -24,6 +27,7 @@ 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';
@@ -32,6 +36,7 @@ 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,
@@ -45,6 +50,7 @@ let PieceList = React.createClass({
getDefaultProps() {
return {
accordionListItemType: AccordionListItemWallet,
+ bulkModalButtonListType: AclButtonList,
orderParams: ['artist_name', 'title'],
filterParams: [{
label: getLangText('Show works I can'),
@@ -152,9 +158,46 @@ let PieceList = React.createClass({
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() {
- let loadingElement =
;
- let AccordionListItemType = this.props.accordionListItemType;
+ const loadingElement =
;
+ 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'));
@@ -178,7 +221,19 @@ let PieceList = React.createClass({
}
+ availableAcls={availableAcls}
+ selectedEditions={selectedEditions}
+ className="ascribe-piece-list-bulk-modal">
+
+
+
+
diff --git a/js/components/whitelabel/wallet/components/lumenus/lumenus_buttons/lumenus_acl_button_list.js b/js/components/whitelabel/wallet/components/lumenus/lumenus_buttons/lumenus_acl_button_list.js
new file mode 100644
index 00000000..6c1aa0ae
--- /dev/null
+++ b/js/components/whitelabel/wallet/components/lumenus/lumenus_buttons/lumenus_acl_button_list.js
@@ -0,0 +1,39 @@
+'use strict';
+
+import React from 'react';
+
+import LumenusSubmitButton from './lumenus_submit_button';
+
+import AclProxy from '../../../../../acl_proxy';
+
+import DeleteButton from '../../../../../ascribe_buttons/delete_button';
+
+let LumenusAclButtonList = React.createClass({
+ propTypes: {
+ availableAcls: React.PropTypes.object.isRequired,
+ className: React.PropTypes.string,
+ editions: React.PropTypes.array,
+ handleSuccess: React.PropTypes.func,
+ children: React.PropTypes.oneOfType([
+ React.PropTypes.arrayOf(React.PropTypes.element),
+ React.PropTypes.element
+ ])
+ },
+
+ render() {
+ return (
+
+
+
+
+ {this.props.children}
+
+ );
+ }
+});
+
+export default LumenusAclButtonList;
diff --git a/js/components/whitelabel/wallet/components/lumenus/lumenus_buttons/lumenus_submit_button.js b/js/components/whitelabel/wallet/components/lumenus/lumenus_buttons/lumenus_submit_button.js
new file mode 100644
index 00000000..13483502
--- /dev/null
+++ b/js/components/whitelabel/wallet/components/lumenus/lumenus_buttons/lumenus_submit_button.js
@@ -0,0 +1,91 @@
+'use strict';
+
+import React from 'react';
+import classNames from 'classnames';
+
+
+import GlobalNotificationModel from '../../../../../../models/global_notification_model';
+import GlobalNotificationActions from '../../../../../../actions/global_notification_actions';
+import UserActions from '../../../../../../actions/user_actions';
+import UserStore from '../../../../../../stores/user_store';
+import WhitelabelActions from '../../../../../../actions/whitelabel_actions';
+import WhitelabelStore from '../../../../../../stores/whitelabel_store';
+
+import ConsignForm from '../../../../../ascribe_forms/form_consign';
+
+import ModalWrapper from '../../../../../ascribe_modal/modal_wrapper';
+
+import ApiUrls from '../../../../../../constants/api_urls';
+
+import { getAclFormMessage, getAclFormDataId } from '../../../../../../utils/form_utils';
+import { mergeOptions } from '../../../../../../utils/general_utils';
+import { getLangText } from '../../../../../../utils/lang_utils';
+
+let LumenusSubmitButton = React.createClass({
+ propTypes: {
+ className: React.PropTypes.string,
+ editions: React.PropTypes.array,
+ handleSuccess: React.PropTypes.func,
+ },
+
+ getInitialState() {
+ return mergeOptions(
+ UserStore.getState(),
+ WhitelabelStore.getState()
+ );
+ },
+
+ componentDidMount() {
+ UserStore.listen(this.onChange);
+ UserActions.fetchCurrentUser();
+ WhitelabelStore.listen(this.onChange);
+ WhitelabelActions.fetchWhitelabel();
+ },
+
+ componentWillUnmount() {
+ UserStore.unlisten(this.onChange);
+ WhitelabelStore.unlisten(this.onChange);
+ },
+
+ onChange(state) {
+ this.setState(state);
+ },
+
+ showNotification(response) {
+ this.props.handleSuccess();
+ if (response.notification) {
+ let notification = new GlobalNotificationModel(response.notification, 'success');
+ GlobalNotificationActions.appendGlobalNotification(notification);
+ }
+ },
+
+ render() {
+ const { className, editions, handleSuccess } = this.props;
+ const title = getLangText('Consign to Lumenus');
+ const message = getAclFormMessage({
+ aclName: 'acl_consign',
+ entities: editions,
+ isPiece: false,
+ senderName: this.state.currentUser.username
+ });
+
+ return (
+
+ {title}
+
+ }
+ handleSuccess={this.showNotification}
+ title={title}>
+
+
+ );
+ }
+});
+
+export default LumenusSubmitButton;
diff --git a/js/components/whitelabel/wallet/components/lumenus/lumenus_piece_list.js b/js/components/whitelabel/wallet/components/lumenus/lumenus_piece_list.js
index c3f01374..403e226b 100644
--- a/js/components/whitelabel/wallet/components/lumenus/lumenus_piece_list.js
+++ b/js/components/whitelabel/wallet/components/lumenus/lumenus_piece_list.js
@@ -1,6 +1,9 @@
'use strict';
import React from 'react';
+
+import LumenusAclButtonList from './lumenus_buttons/lumenus_acl_button_list';
+
import PieceList from '../../../../piece_list';
import UserActions from '../../../../../actions/user_actions';
@@ -39,6 +42,7 @@ let LumenusPieceList = React.createClass({
= 1) {
+ if (editionsCopy.length >= 1) {
availableAcls = editionsCopy[0].acl;
- }
- if(editionsCopy.length >= 2) {
- for(let i = 1; i < editionsCopy.length; i++) {
+ } else if (editionsCopy.length >= 2) {
+ for (let i = 1; i < editionsCopy.length; i++) {
availableAcls = intersectAcls(availableAcls, editionsCopy[i].acl);
}
}
// convert acls back to key-value object
let availableAclsObj = {};
- for(let i = 0; i < availableAcls.length; i++) {
+ for (let i = 0; i < availableAcls.length; i++) {
availableAclsObj[availableAcls[i]] = true;
}
return availableAclsObj;
-}
\ No newline at end of file
+}
diff --git a/js/utils/form_utils.js b/js/utils/form_utils.js
index a98d956f..d2d2cd29 100644
--- a/js/utils/form_utils.js
+++ b/js/utils/form_utils.js
@@ -5,15 +5,19 @@ import { getLangText } from './lang_utils';
import AppConstants from '../constants/application_constants';
/**
- * Gets a dictionary of settings for a form based on the environment
- * (ie. if on a whitelabel)
- * @param {string} formName Name of the form
- * @return {object} Settings key-val dictionary
+ * Get the data ids of the given piece or editions.
+ * @param {boolean} isPiece Is the given entities parameter a piece? (False: array of editions)
+ * @param {(object|object[])} pieceOrEditions Piece or array of editions
+ * @return {(object|object[])} Data IDs of the pieceOrEditions for the form
*/
-export function getSubdomainFormSettings(formName) {
- let subdomainFormSettings = AppConstants.whitelabel.formSettings || {};
-
- return subdomainFormSettings[formName] || {};
+export function getAclFormDataId(isPiece, pieceOrEditions) {
+ if (isPiece) {
+ return {piece_id: pieceOrEditions.id};
+ } else {
+ return {bitcoin_id: pieceOrEditions.map(function(edition){
+ return edition.bitcoin_id;
+ }).join()};
+ }
}
/**
@@ -21,6 +25,7 @@ export function getSubdomainFormSettings(formName) {
* @param {object} options Options object for creating the message:
* @param {string} options.aclName Enum name of an acl
* @param {(object|object[])} options.entities Piece or array of Editions
+ * @param {boolean} options.isPiece Is the given entities parameter a piece? (False: array of editions)
* @param {string} [options.senderName] Name of the sender
* @return {string} Completed message
*/