mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 09:23:13 +01:00
solve merge conflicts
This commit is contained in:
commit
7910384d99
@ -105,7 +105,7 @@ gulp.task('sass:build', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('sass:watch', function () {
|
gulp.task('sass:watch', function () {
|
||||||
gulp.watch('./sass/**/*.scss', ['sass']);
|
gulp.watch('./sass/**/*.scss', ['sass:build']);
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('copy', function () {
|
gulp.task('copy', function () {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="//brick.a.ssl.fastly.net/Source+Sans+Pro:400,600,700,900">
|
<link rel="stylesheet" href="//brick.a.ssl.fastly.net/Source+Sans+Pro:400,600,700,900">
|
||||||
<link rel="stylesheet" href="<%= BASE_URL %>static/css/main.css">
|
<link rel="stylesheet" href="<%= BASE_URL %>static/css/main.css">
|
||||||
|
<link rel="stylesheet" href="<%= BASE_URL %>static/css/maps/main.css.map">
|
||||||
<script>
|
<script>
|
||||||
window.BASE_URL = '<%= BASE_URL %>';
|
window.BASE_URL = '<%= BASE_URL %>';
|
||||||
window.API_ENDPOINT = '<%= API_ENDPOINT %>';
|
window.API_ENDPOINT = '<%= API_ENDPOINT %>';
|
||||||
|
@ -9,7 +9,9 @@ class EditionListActions {
|
|||||||
this.generateActions(
|
this.generateActions(
|
||||||
'updateEditionList',
|
'updateEditionList',
|
||||||
'selectEdition',
|
'selectEdition',
|
||||||
'clearAllEditionSelections'
|
'clearAllEditionSelections',
|
||||||
|
'closeAllEditionLists',
|
||||||
|
'toggleEditionList'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,19 +21,24 @@ class EditionListActions {
|
|||||||
orderAsc = true;
|
orderAsc = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
EditionListFetcher
|
return new Promise((resolve, reject) => {
|
||||||
.fetch(pieceId, orderBy, orderAsc)
|
EditionListFetcher
|
||||||
.then((res) => {
|
.fetch(pieceId, orderBy, orderAsc)
|
||||||
this.actions.updateEditionList({
|
.then((res) => {
|
||||||
'editionListOfPiece': res.editions,
|
this.actions.updateEditionList({
|
||||||
pieceId,
|
'editionListOfPiece': res.editions,
|
||||||
orderBy,
|
pieceId,
|
||||||
orderAsc
|
orderBy,
|
||||||
|
orderAsc
|
||||||
|
});
|
||||||
|
resolve(res);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
reject(err);
|
||||||
|
console.log(err);
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
.catch((err) => {
|
|
||||||
console.log(err);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,7 @@ import PieceListFetcher from '../fetchers/piece_list_fetcher';
|
|||||||
class PieceListActions {
|
class PieceListActions {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.generateActions(
|
this.generateActions(
|
||||||
'updatePieceList',
|
'updatePieceList'
|
||||||
'showEditionList',
|
|
||||||
'closeAllEditionLists'
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Router from 'react-router';
|
|
||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
let Link = Router.Link;
|
|
||||||
|
|
||||||
let AccordionListItem = React.createClass({
|
let AccordionListItem = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
className: React.PropTypes.string,
|
className: React.PropTypes.string,
|
||||||
|
@ -13,7 +13,6 @@ let AccordionListItemTable = React.createClass({
|
|||||||
parentId: React.PropTypes.number,
|
parentId: React.PropTypes.number,
|
||||||
itemList: React.PropTypes.array,
|
itemList: React.PropTypes.array,
|
||||||
columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(ColumnModel)),
|
columnList: React.PropTypes.arrayOf(React.PropTypes.instanceOf(ColumnModel)),
|
||||||
numOfTableItems: React.PropTypes.number,
|
|
||||||
show: React.PropTypes.bool,
|
show: React.PropTypes.bool,
|
||||||
changeOrder: React.PropTypes.func,
|
changeOrder: React.PropTypes.func,
|
||||||
orderBy: React.PropTypes.string,
|
orderBy: React.PropTypes.string,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Router from 'react-router';
|
|
||||||
|
|
||||||
import EditionListStore from '../../stores/edition_list_store';
|
import EditionListStore from '../../stores/edition_list_store';
|
||||||
import EditionListActions from '../../actions/edition_list_actions';
|
import EditionListActions from '../../actions/edition_list_actions';
|
||||||
@ -19,15 +18,11 @@ import TableItemAclFiltered from '../ascribe_table/table_item_acl_filtered';
|
|||||||
|
|
||||||
import { getLangText } from '../../utils/lang_utils';
|
import { getLangText } from '../../utils/lang_utils';
|
||||||
|
|
||||||
let Link = Router.Link;
|
|
||||||
|
|
||||||
let AccordionListItemTableEditions = React.createClass({
|
let AccordionListItemTableEditions = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
className: React.PropTypes.string,
|
className: React.PropTypes.string,
|
||||||
parentId: React.PropTypes.number,
|
parentId: React.PropTypes.number
|
||||||
numOfEditions: React.PropTypes.number,
|
|
||||||
show: React.PropTypes.bool
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
@ -64,8 +59,13 @@ let AccordionListItemTableEditions = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
toggleTable() {
|
toggleTable() {
|
||||||
PieceListActions.showEditionList(this.props.parentId);
|
let isEditionListOpen = this.state.isEditionListOpenForPieceId[this.props.parentId] ? this.state.isEditionListOpenForPieceId[this.props.parentId].show : false;
|
||||||
EditionListActions.fetchEditionList(this.props.parentId);
|
if(isEditionListOpen) {
|
||||||
|
EditionListActions.toggleEditionList(this.props.parentId);
|
||||||
|
} else {
|
||||||
|
EditionListActions.toggleEditionList(this.props.parentId);
|
||||||
|
EditionListActions.fetchEditionList(this.props.parentId);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
changeEditionListOrder(orderBy, orderAsc) {
|
changeEditionListOrder(orderBy, orderAsc) {
|
||||||
@ -77,6 +77,7 @@ let AccordionListItemTableEditions = React.createClass({
|
|||||||
let allEditionsCount = 0;
|
let allEditionsCount = 0;
|
||||||
let orderBy;
|
let orderBy;
|
||||||
let orderAsc;
|
let orderAsc;
|
||||||
|
let show;
|
||||||
|
|
||||||
// here we need to check if all editions of a specific
|
// here we need to check if all editions of a specific
|
||||||
// piece are already defined. Otherwise .length will throw an error and we'll not
|
// piece are already defined. Otherwise .length will throw an error and we'll not
|
||||||
@ -88,7 +89,11 @@ let AccordionListItemTableEditions = React.createClass({
|
|||||||
orderAsc = this.state.editionList[this.props.parentId].orderAsc;
|
orderAsc = this.state.editionList[this.props.parentId].orderAsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
let transition = new TransitionModel('edition', 'editionId', 'bitcoin_id', PieceListActions.closeAllEditionLists);
|
if(this.props.parentId in this.state.isEditionListOpenForPieceId) {
|
||||||
|
show = this.state.isEditionListOpenForPieceId[this.props.parentId].show;
|
||||||
|
}
|
||||||
|
|
||||||
|
let transition = new TransitionModel('edition', 'editionId', 'bitcoin_id');
|
||||||
|
|
||||||
let columnList = [
|
let columnList = [
|
||||||
new ColumnModel(
|
new ColumnModel(
|
||||||
@ -111,10 +116,10 @@ let AccordionListItemTableEditions = React.createClass({
|
|||||||
new ColumnModel(
|
new ColumnModel(
|
||||||
(item) => {
|
(item) => {
|
||||||
return {
|
return {
|
||||||
'content': item.edition_number
|
'content': item.edition_number + ' of ' + item.num_editions
|
||||||
}; },
|
}; },
|
||||||
'edition_number',
|
'edition_number',
|
||||||
'#',
|
'Edition',
|
||||||
TableItemText,
|
TableItemText,
|
||||||
1,
|
1,
|
||||||
true,
|
true,
|
||||||
@ -153,16 +158,14 @@ let AccordionListItemTableEditions = React.createClass({
|
|||||||
parentId={this.props.parentId}
|
parentId={this.props.parentId}
|
||||||
itemList={this.state.editionList[this.props.parentId]}
|
itemList={this.state.editionList[this.props.parentId]}
|
||||||
columnList={columnList}
|
columnList={columnList}
|
||||||
numOfTableItems={this.props.numOfEditions}
|
show={show}
|
||||||
show={this.props.show}
|
|
||||||
orderBy={orderBy}
|
orderBy={orderBy}
|
||||||
orderAsc={orderAsc}
|
orderAsc={orderAsc}
|
||||||
changeOrder={this.changeEditionListOrder}>
|
changeOrder={this.changeEditionListOrder}>
|
||||||
<AccordionListItemTableToggle
|
<AccordionListItemTableToggle
|
||||||
className="ascribe-accordion-list-table-toggle"
|
className="ascribe-accordion-list-table-toggle"
|
||||||
onClick={this.toggleTable}
|
onClick={this.toggleTable}
|
||||||
show={this.props.show}
|
show={show} />
|
||||||
numOfTableItems={this.props.numOfEditions} />
|
|
||||||
</AccordionListItemTable>
|
</AccordionListItemTable>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,8 +6,7 @@ let AccordionListItemTableToggle = React.createClass({
|
|||||||
propTypes: {
|
propTypes: {
|
||||||
className: React.PropTypes.string,
|
className: React.PropTypes.string,
|
||||||
onClick: React.PropTypes.func,
|
onClick: React.PropTypes.func,
|
||||||
show: React.PropTypes.bool,
|
show: React.PropTypes.bool
|
||||||
numOfTableItems: React.PropTypes.number
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -15,7 +14,7 @@ let AccordionListItemTableToggle = React.createClass({
|
|||||||
<span
|
<span
|
||||||
className={this.props.className}
|
className={this.props.className}
|
||||||
onClick={this.props.onClick}>
|
onClick={this.props.onClick}>
|
||||||
{this.props.show ? 'Hide all ' + this.props.numOfTableItems + ' Editions' : 'Show all ' + this.props.numOfTableItems + ' Editions'}
|
{this.props.show ? 'Hide all Editions' : 'Show all Editions'}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,16 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import ConsignForm from '../ascribe_forms/form_consign';
|
import ConsignForm from '../ascribe_forms/form_consign';
|
||||||
|
import UnConsignForm from '../ascribe_forms/form_unconsign';
|
||||||
import TransferForm from '../ascribe_forms/form_transfer';
|
import TransferForm from '../ascribe_forms/form_transfer';
|
||||||
import LoanForm from '../ascribe_forms/form_loan';
|
import LoanForm from '../ascribe_forms/form_loan';
|
||||||
import ShareForm from '../ascribe_forms/form_share_email';
|
import ShareForm from '../ascribe_forms/form_share_email';
|
||||||
import ModalWrapper from '../ascribe_modal/modal_wrapper';
|
import ModalWrapper from '../ascribe_modal/modal_wrapper';
|
||||||
import AppConstants from '../../constants/application_constants';
|
import AppConstants from '../../constants/application_constants';
|
||||||
|
|
||||||
|
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||||
|
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||||
|
|
||||||
let AclButton = React.createClass({
|
let AclButton = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
action: React.PropTypes.oneOf(AppConstants.aclList).isRequired,
|
action: React.PropTypes.oneOf(AppConstants.aclList).isRequired,
|
||||||
@ -23,31 +27,47 @@ let AclButton = React.createClass({
|
|||||||
return {
|
return {
|
||||||
title: 'Consign artwork',
|
title: 'Consign artwork',
|
||||||
tooltip: 'Have someone else sell the artwork',
|
tooltip: 'Have someone else sell the artwork',
|
||||||
form: <ConsignForm />
|
form: <ConsignForm currentUser={ this.props.currentUser } editions={ this.props.editions }/>,
|
||||||
|
handleSuccess: this.showNotification
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if (this.props.action === 'transfer') {
|
if (this.props.action === 'unconsign'){
|
||||||
|
return {
|
||||||
|
title: 'Unconsign artwork',
|
||||||
|
tooltip: 'Have the owner manage his sales again',
|
||||||
|
form: <UnConsignForm currentUser={ this.props.currentUser } editions={ this.props.editions }/>,
|
||||||
|
handleSuccess: this.showNotification
|
||||||
|
};
|
||||||
|
}else if (this.props.action === 'transfer') {
|
||||||
return {
|
return {
|
||||||
title: 'Transfer artwork',
|
title: 'Transfer artwork',
|
||||||
tooltip: 'Transfer the ownership of the artwork',
|
tooltip: 'Transfer the ownership of the artwork',
|
||||||
form: <TransferForm />
|
form: <TransferForm currentUser={ this.props.currentUser } editions={ this.props.editions }/>,
|
||||||
|
handleSuccess: this.showNotification
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if (this.props.action === 'loan'){
|
else if (this.props.action === 'loan'){
|
||||||
return {
|
return {
|
||||||
title: 'Loan artwork',
|
title: 'Loan artwork',
|
||||||
tooltip: 'Loan your artwork for a limited period of time',
|
tooltip: 'Loan your artwork for a limited period of time',
|
||||||
form: <LoanForm />
|
form: <LoanForm currentUser={ this.props.currentUser } editions={ this.props.editions }/>,
|
||||||
|
handleSuccess: this.showNotification
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if (this.props.action === 'share'){
|
else if (this.props.action === 'share'){
|
||||||
return {
|
return {
|
||||||
title: 'Share artwork',
|
title: 'Share artwork',
|
||||||
tooltip: 'Share the artwork',
|
tooltip: 'Share the artwork',
|
||||||
form: <ShareForm />
|
form: <ShareForm currentUser={ this.props.currentUser } editions={ this.props.editions }/>,
|
||||||
|
handleSuccess: this.showNotification
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
showNotification(response){
|
||||||
|
this.props.handleSuccess();
|
||||||
|
let notification = new GlobalNotificationModel(response.notification, 'success');
|
||||||
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
},
|
||||||
render() {
|
render() {
|
||||||
let shouldDisplay = this.props.availableAcls.indexOf(this.props.action) > -1;
|
let shouldDisplay = this.props.availableAcls.indexOf(this.props.action) > -1;
|
||||||
let aclProps = this.actionProperties();
|
let aclProps = this.actionProperties();
|
||||||
@ -58,9 +78,7 @@ let AclButton = React.createClass({
|
|||||||
{this.props.action.toUpperCase()}
|
{this.props.action.toUpperCase()}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
currentUser={ this.props.currentUser }
|
handleSuccess={ aclProps.handleSuccess }
|
||||||
editions={ this.props.editions }
|
|
||||||
handleSuccess={ this.props.handleSuccess }
|
|
||||||
title={ aclProps.title }
|
title={ aclProps.title }
|
||||||
tooltip={ aclProps.tooltip }>
|
tooltip={ aclProps.tooltip }>
|
||||||
{ aclProps.form }
|
{ aclProps.form }
|
||||||
|
@ -6,6 +6,7 @@ import UserActions from '../../actions/user_actions';
|
|||||||
import UserStore from '../../stores/user_store';
|
import UserStore from '../../stores/user_store';
|
||||||
|
|
||||||
import AclButton from '../ascribe_buttons/acl_button';
|
import AclButton from '../ascribe_buttons/acl_button';
|
||||||
|
import DeleteButton from '../ascribe_buttons/delete_button';
|
||||||
|
|
||||||
let AclButtonList = React.createClass({
|
let AclButtonList = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
@ -47,6 +48,12 @@ let AclButtonList = React.createClass({
|
|||||||
editions={this.props.editions}
|
editions={this.props.editions}
|
||||||
currentUser={this.state.currentUser}
|
currentUser={this.state.currentUser}
|
||||||
handleSuccess={this.props.handleSuccess} />
|
handleSuccess={this.props.handleSuccess} />
|
||||||
|
<AclButton
|
||||||
|
availableAcls={this.props.availableAcls}
|
||||||
|
action="unconsign"
|
||||||
|
editions={this.props.editions}
|
||||||
|
currentUser={this.state.currentUser}
|
||||||
|
handleSuccess={this.props.handleSuccess} />
|
||||||
<AclButton
|
<AclButton
|
||||||
availableAcls={this.props.availableAcls}
|
availableAcls={this.props.availableAcls}
|
||||||
action="loan"
|
action="loan"
|
||||||
@ -59,6 +66,7 @@ let AclButtonList = React.createClass({
|
|||||||
editions={this.props.editions}
|
editions={this.props.editions}
|
||||||
currentUser={this.state.currentUser}
|
currentUser={this.state.currentUser}
|
||||||
handleSuccess={this.props.handleSuccess} />
|
handleSuccess={this.props.handleSuccess} />
|
||||||
|
<DeleteButton editions={this.props.editions}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,19 +2,20 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
/*
|
|
||||||
Is this even used somewhere?
|
|
||||||
Deprecate? 5.6.15 - Tim
|
|
||||||
|
|
||||||
*/
|
|
||||||
let ButtonSubmitOrClose = React.createClass({
|
let ButtonSubmitOrClose = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
submitted: React.PropTypes.bool.isRequired,
|
||||||
|
text: React.PropTypes.string.isRequired,
|
||||||
|
onClose: React.PropTypes.func.isRequired
|
||||||
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.props.submitted){
|
if (this.props.submitted){
|
||||||
return (
|
return (
|
||||||
<div className="modal-footer">
|
<div className="modal-footer">
|
||||||
<img src="https://s3-us-west-2.amazonaws.com/ascribe0/media/thumbnails/ascribe_animated_medium.gif" />
|
<img src="https://s3-us-west-2.amazonaws.com/ascribe0/media/thumbnails/ascribe_animated_medium.gif" />
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className="modal-footer">
|
<div className="modal-footer">
|
||||||
|
67
js/components/ascribe_buttons/delete_button.js
Normal file
67
js/components/ascribe_buttons/delete_button.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import Router from 'react-router';
|
||||||
|
|
||||||
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
|
|
||||||
|
import EditionDeleteForm from '../ascribe_forms/form_delete_edition';
|
||||||
|
import EditionRemoveFromCollectionForm from '../ascribe_forms/form_remove_editions_from_collection';
|
||||||
|
import ModalWrapper from '../ascribe_modal/modal_wrapper';
|
||||||
|
|
||||||
|
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||||
|
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||||
|
|
||||||
|
import { getAvailableAcls } from '../../utils/acl_utils';
|
||||||
|
|
||||||
|
import EditionListActions from '../../actions/edition_list_actions';
|
||||||
|
|
||||||
|
let DeleteButton = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
editions: React.PropTypes.array.isRequired
|
||||||
|
},
|
||||||
|
|
||||||
|
mixins: [Router.Navigation],
|
||||||
|
|
||||||
|
showNotification(response) {
|
||||||
|
this.props.editions
|
||||||
|
.forEach((edition) => {
|
||||||
|
EditionListActions.fetchEditionList(edition.parent);
|
||||||
|
});
|
||||||
|
EditionListActions.clearAllEditionSelections();
|
||||||
|
EditionListActions.closeAllEditionLists();
|
||||||
|
this.transitionTo('pieces');
|
||||||
|
let notification = new GlobalNotificationModel(response.notification, 'success');
|
||||||
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
let availableAcls = getAvailableAcls(this.props.editions);
|
||||||
|
let btnDelete = null;
|
||||||
|
let content = null;
|
||||||
|
|
||||||
|
if (availableAcls.indexOf('delete') > -1) {
|
||||||
|
content = <EditionDeleteForm editions={ this.props.editions }/>;
|
||||||
|
btnDelete = <Button bsStyle="danger" bsSize="small">DELETE</Button>;
|
||||||
|
}
|
||||||
|
else if (availableAcls.indexOf('del_from_collection') > -1){
|
||||||
|
content = <EditionRemoveFromCollectionForm editions={ this.props.editions }/>;
|
||||||
|
btnDelete = <Button bsStyle="danger" bsSize="small">REMOVE FROM COLLECTION</Button>;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return <div></div>;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<ModalWrapper
|
||||||
|
button={ btnDelete }
|
||||||
|
handleSuccess={ this.showNotification }
|
||||||
|
title='Remove Edition'
|
||||||
|
tooltip='Click to remove edition'>
|
||||||
|
{ content }
|
||||||
|
</ModalWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default DeleteButton;
|
||||||
|
|
@ -4,6 +4,10 @@ import React from 'react';
|
|||||||
import Alert from 'react-bootstrap/lib/Alert';
|
import Alert from 'react-bootstrap/lib/Alert';
|
||||||
|
|
||||||
let AlertDismissable = React.createClass({
|
let AlertDismissable = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
error: React.PropTypes.array.isRequired
|
||||||
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return {
|
return {
|
||||||
alertVisible: true
|
alertVisible: true
|
||||||
@ -20,7 +24,6 @@ let AlertDismissable = React.createClass({
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.state.alertVisible) {
|
if (this.state.alertVisible) {
|
||||||
let key = this.props.error;
|
|
||||||
return (
|
return (
|
||||||
<Alert bsStyle='danger' onDismiss={this.hide}>
|
<Alert bsStyle='danger' onDismiss={this.hide}>
|
||||||
{this.props.error}
|
{this.props.error}
|
||||||
|
@ -11,6 +11,7 @@ import ButtonSubmitOrClose from '../ascribe_buttons/button_submit_close';
|
|||||||
let ConsignForm = React.createClass({
|
let ConsignForm = React.createClass({
|
||||||
mixins: [FormMixin],
|
mixins: [FormMixin],
|
||||||
|
|
||||||
|
|
||||||
url() {
|
url() {
|
||||||
return ApiUrls.ownership_consigns;
|
return ApiUrls.ownership_consigns;
|
||||||
},
|
},
|
||||||
|
35
js/components/ascribe_forms/form_delete_edition.js
Normal file
35
js/components/ascribe_forms/form_delete_edition.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import fetch from '../../utils/fetch';
|
||||||
|
import ApiUrls from '../../constants/api_urls';
|
||||||
|
import FormMixin from '../../mixins/form_mixin';
|
||||||
|
|
||||||
|
let EditionDeleteForm = React.createClass({
|
||||||
|
|
||||||
|
mixins: [FormMixin],
|
||||||
|
|
||||||
|
url() {
|
||||||
|
return fetch.prepareUrl(ApiUrls.edition_delete, {edition_id: this.getBitcoinIds().join()});
|
||||||
|
},
|
||||||
|
httpVerb(){
|
||||||
|
return 'delete';
|
||||||
|
},
|
||||||
|
|
||||||
|
renderForm () {
|
||||||
|
return (
|
||||||
|
<div className="modal-body">
|
||||||
|
<p>Are you sure you would like to permanently delete this edition?</p>
|
||||||
|
<p>This is an irrevocable action.</p>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button type="submit" className="btn btn-ascribe-inv" onClick={this.submit}>YES, DELETE</button>
|
||||||
|
<button className="btn btn-ascribe" onClick={this.props.onRequestHide}>CLOSE</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export default EditionDeleteForm;
|
@ -52,7 +52,7 @@ let LoanForm = React.createClass({
|
|||||||
loaneeHasContract: true
|
loaneeHasContract: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
this.resetLoanContract();
|
this.resetLoanContract();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -63,10 +63,11 @@ let LoanForm = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
resetLoanContract(){
|
resetLoanContract(){
|
||||||
this.setState({contract_key: null,
|
this.setState({
|
||||||
contract_url: null,
|
contract_key: null,
|
||||||
loaneeHasContract: false
|
contract_url: null,
|
||||||
});
|
loaneeHasContract: false
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
renderForm() {
|
renderForm() {
|
||||||
|
43
js/components/ascribe_forms/form_note_personal.js
Normal file
43
js/components/ascribe_forms/form_note_personal.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import apiUrls from '../../constants/api_urls';
|
||||||
|
import FormMixin from '../../mixins/form_mixin';
|
||||||
|
|
||||||
|
import InputTextAreaToggable from './input_textarea_toggable';
|
||||||
|
|
||||||
|
|
||||||
|
let PersonalNoteForm = React.createClass({
|
||||||
|
mixins: [FormMixin],
|
||||||
|
|
||||||
|
url() {
|
||||||
|
return apiUrls.note_notes;
|
||||||
|
},
|
||||||
|
|
||||||
|
getFormData() {
|
||||||
|
return {
|
||||||
|
bitcoin_id: this.getBitcoinIds().join(),
|
||||||
|
note: this.refs.personalNote.state.value
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
renderForm() {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form id="personal_note_content" role="form" key="personal_note_content">
|
||||||
|
<InputTextAreaToggable
|
||||||
|
ref="personalNote"
|
||||||
|
className="form-control"
|
||||||
|
defaultValue={this.props.editions[0].note_from_user}
|
||||||
|
rows={3}
|
||||||
|
editable={true}
|
||||||
|
required=""
|
||||||
|
onSubmit={this.submit}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default PersonalNoteForm;
|
48
js/components/ascribe_forms/form_piece_extradata.js
Normal file
48
js/components/ascribe_forms/form_piece_extradata.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import fetch from '../../utils/fetch';
|
||||||
|
|
||||||
|
import apiUrls from '../../constants/api_urls';
|
||||||
|
import FormMixin from '../../mixins/form_mixin';
|
||||||
|
|
||||||
|
import InputTextAreaToggable from './input_textarea_toggable';
|
||||||
|
|
||||||
|
|
||||||
|
let PieceExtraDataForm = React.createClass({
|
||||||
|
mixins: [FormMixin],
|
||||||
|
|
||||||
|
url() {
|
||||||
|
return fetch.prepareUrl(apiUrls.piece_extradata, {piece_id: this.props.editions[0].bitcoin_id});
|
||||||
|
},
|
||||||
|
|
||||||
|
getFormData() {
|
||||||
|
let extradata = {};
|
||||||
|
extradata[this.props.name] = this.refs[this.props.name].state.value;
|
||||||
|
return {
|
||||||
|
bitcoin_id: this.getBitcoinIds().join(),
|
||||||
|
extradata: extradata
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
renderForm() {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form role="form" key={this.props.name}>
|
||||||
|
<h5>{this.props.title}</h5>
|
||||||
|
<InputTextAreaToggable
|
||||||
|
ref={this.props.name}
|
||||||
|
className="form-control"
|
||||||
|
defaultValue={this.props.editions[0].extra_data[this.props.name]}
|
||||||
|
rows={3}
|
||||||
|
editable={true}
|
||||||
|
required=""
|
||||||
|
onSubmit={this.submit}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default PieceExtraDataForm;
|
@ -0,0 +1,35 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import fetch from '../../utils/fetch';
|
||||||
|
import apiUrls from '../../constants/api_urls';
|
||||||
|
import FormMixin from '../../mixins/form_mixin';
|
||||||
|
|
||||||
|
let EditionRemoveFromCollectionForm = React.createClass({
|
||||||
|
|
||||||
|
mixins: [FormMixin],
|
||||||
|
|
||||||
|
url() {
|
||||||
|
return fetch.prepareUrl(apiUrls.edition_remove_from_collection, {edition_id: this.getBitcoinIds().join()});
|
||||||
|
},
|
||||||
|
httpVerb(){
|
||||||
|
return 'delete';
|
||||||
|
},
|
||||||
|
|
||||||
|
renderForm () {
|
||||||
|
return (
|
||||||
|
<div className="modal-body">
|
||||||
|
<p>Are you sure you would like to remove these editions from your collection?</p>
|
||||||
|
<p>This is an irrevocable action.</p>
|
||||||
|
<div className="modal-footer">
|
||||||
|
<button type="submit" className="btn btn-ascribe-inv" onClick={this.submit}>YES, REMOVE</button>
|
||||||
|
<button className="btn btn-ascribe" onClick={this.props.onRequestHide}>CLOSE</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export default EditionRemoveFromCollectionForm;
|
79
js/components/ascribe_forms/form_request_action.js
Normal file
79
js/components/ascribe_forms/form_request_action.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import Alert from 'react-bootstrap/lib/Alert';
|
||||||
|
|
||||||
|
import apiUrls from '../../constants/api_urls';
|
||||||
|
import FormMixin from '../../mixins/form_mixin';
|
||||||
|
|
||||||
|
let RequestActionForm = React.createClass({
|
||||||
|
mixins: [FormMixin],
|
||||||
|
|
||||||
|
url(e){
|
||||||
|
let edition = this.props.editions[0];
|
||||||
|
if (e.target.id === 'request_accept'){
|
||||||
|
if (edition.request_action === 'consign'){
|
||||||
|
return apiUrls.ownership_consigns_confirm;
|
||||||
|
}
|
||||||
|
else if (edition.request_action === 'unconsign'){
|
||||||
|
return apiUrls.ownership_unconsigns;
|
||||||
|
}
|
||||||
|
else if (edition.request_action === 'loan'){
|
||||||
|
return apiUrls.ownership_loans_confirm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(e.target.id === 'request_deny'){
|
||||||
|
if (edition.request_action === 'consign') {
|
||||||
|
return apiUrls.ownership_consigns_deny;
|
||||||
|
}
|
||||||
|
else if (edition.request_action === 'unconsign') {
|
||||||
|
return apiUrls.ownership_unconsigns_deny;
|
||||||
|
}
|
||||||
|
else if (edition.request_action === 'loan') {
|
||||||
|
return apiUrls.ownership_loans_deny;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleRequest: function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
this.submit(e);
|
||||||
|
},
|
||||||
|
|
||||||
|
getFormData() {
|
||||||
|
return {
|
||||||
|
bitcoin_id: this.getBitcoinIds().join()
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
renderForm() {
|
||||||
|
let edition = this.props.editions[0];
|
||||||
|
let buttons = (
|
||||||
|
<span>
|
||||||
|
<span>
|
||||||
|
<div id="request_accept" onClick={this.handleRequest} className='btn btn-default btn-sm'>ACCEPT</div>
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<div id="request_deny" onClick={this.handleRequest} className='btn btn-default btn-sm'>REJECT</div>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
if (this.state.submitted){
|
||||||
|
buttons = (
|
||||||
|
<span>
|
||||||
|
<img src="https://s3-us-west-2.amazonaws.com/ascribe0/media/thumbnails/ascribe_animated_small.gif" />
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Alert bsStyle='warning'>
|
||||||
|
<span>{ edition.owner } requests you { edition.request_action } this edition. </span>
|
||||||
|
{buttons}
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export default RequestActionForm;
|
@ -17,19 +17,20 @@ let UnConsignForm = React.createClass({
|
|||||||
|
|
||||||
getFormData() {
|
getFormData() {
|
||||||
return {
|
return {
|
||||||
bitcoin_id: this.props.edition.bitcoin_id,
|
bitcoin_id: this.getBitcoinIds().join(),
|
||||||
unconsign_message: this.refs.unconsign_message.state.value,
|
unconsign_message: this.refs.unconsign_message.state.value,
|
||||||
password: this.refs.password.state.value
|
password: this.refs.password.state.value
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
renderForm() {
|
renderForm() {
|
||||||
let title = this.props.edition.title;
|
let title = this.getTitlesString().join('');
|
||||||
let username = this.props.currentUser.username;
|
let username = this.props.currentUser.username;
|
||||||
let message =
|
let message =
|
||||||
`Hi,
|
`Hi,
|
||||||
|
|
||||||
I un-consign \" ${title} \" from you.
|
I un-consign:
|
||||||
|
${title}from you.
|
||||||
|
|
||||||
Truly yours,
|
Truly yours,
|
||||||
${username}`;
|
${username}`;
|
||||||
|
@ -5,6 +5,11 @@ import React from 'react';
|
|||||||
import AlertMixin from '../../mixins/alert_mixin';
|
import AlertMixin from '../../mixins/alert_mixin';
|
||||||
|
|
||||||
let InputCheckbox = React.createClass({
|
let InputCheckbox = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
submitted: React.PropTypes.bool.isRequired,
|
||||||
|
required: React.PropTypes.string.isRequired,
|
||||||
|
label: React.PropTypes.string.isRequired
|
||||||
|
},
|
||||||
|
|
||||||
mixins: [AlertMixin],
|
mixins: [AlertMixin],
|
||||||
|
|
||||||
|
@ -6,6 +6,10 @@ import AlertMixin from '../../mixins/alert_mixin';
|
|||||||
import DatePicker from 'react-datepicker/dist/react-datepicker';
|
import DatePicker from 'react-datepicker/dist/react-datepicker';
|
||||||
|
|
||||||
let InputDate = React.createClass({
|
let InputDate = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
submitted: React.PropTypes.bool,
|
||||||
|
placeholderText: React.PropTypes.string
|
||||||
|
},
|
||||||
|
|
||||||
mixins: [AlertMixin],
|
mixins: [AlertMixin],
|
||||||
|
|
||||||
@ -20,11 +24,10 @@ let InputDate = React.createClass({
|
|||||||
handleChange(date) {
|
handleChange(date) {
|
||||||
this.setState({
|
this.setState({
|
||||||
value: date,
|
value: date,
|
||||||
value_formatted: date.format("YYYY-MM-DD")});
|
value_formatted: date.format('YYYY-MM-DD')});
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function () {
|
render: function () {
|
||||||
let className = 'form-control input-text-ascribe';
|
|
||||||
let alerts = (this.props.submitted) ? null : this.state.alerts;
|
let alerts = (this.props.submitted) ? null : this.state.alerts;
|
||||||
return (
|
return (
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
@ -37,24 +40,6 @@ let InputDate = React.createClass({
|
|||||||
placeholderText={this.props.placeholderText}/>
|
placeholderText={this.props.placeholderText}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
// CAN THIS BE REMOVED???
|
|
||||||
//
|
|
||||||
// - Tim?
|
|
||||||
//
|
|
||||||
//return (
|
|
||||||
// <div className="input-group date"
|
|
||||||
// ref={this.props.name + "_picker"}
|
|
||||||
// onChange={this.handleChange}>
|
|
||||||
// <input className={className}
|
|
||||||
// ref={this.props.name}
|
|
||||||
// placeholder={this.props.placeholder}
|
|
||||||
// required={this.props.required}
|
|
||||||
// type="text"/>
|
|
||||||
// <span className="input-group-addon input-text-ascribe">
|
|
||||||
// <span className="glyphicon glyphicon-calendar" style={{"color": "black"}}></span>
|
|
||||||
// </span>
|
|
||||||
// </div>
|
|
||||||
//)
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5,6 +5,10 @@ import React from 'react';
|
|||||||
import AlertMixin from '../../mixins/alert_mixin';
|
import AlertMixin from '../../mixins/alert_mixin';
|
||||||
|
|
||||||
let InputHidden = React.createClass({
|
let InputHidden = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
submitted: React.PropTypes.bool,
|
||||||
|
value: React.PropTypes.string
|
||||||
|
},
|
||||||
|
|
||||||
mixins: [AlertMixin],
|
mixins: [AlertMixin],
|
||||||
|
|
||||||
|
@ -5,6 +5,13 @@ import React from 'react';
|
|||||||
import AlertMixin from '../../mixins/alert_mixin';
|
import AlertMixin from '../../mixins/alert_mixin';
|
||||||
|
|
||||||
let InputText = React.createClass({
|
let InputText = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
submitted: React.PropTypes.bool,
|
||||||
|
onBlur: React.PropTypes.func,
|
||||||
|
type: React.PropTypes.string,
|
||||||
|
required: React.PropTypes.string,
|
||||||
|
placeHolder: React.PropTypes.string
|
||||||
|
},
|
||||||
|
|
||||||
mixins: [AlertMixin],
|
mixins: [AlertMixin],
|
||||||
|
|
||||||
|
@ -5,6 +5,11 @@ import React from 'react';
|
|||||||
import AlertMixin from '../../mixins/alert_mixin';
|
import AlertMixin from '../../mixins/alert_mixin';
|
||||||
|
|
||||||
let InputTextArea = React.createClass({
|
let InputTextArea = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
submitted: React.PropTypes.bool,
|
||||||
|
required: React.PropTypes.string,
|
||||||
|
defaultValue: React.PropTypes.string
|
||||||
|
},
|
||||||
|
|
||||||
mixins: [AlertMixin],
|
mixins: [AlertMixin],
|
||||||
|
|
||||||
|
81
js/components/ascribe_forms/input_textarea_toggable.js
Normal file
81
js/components/ascribe_forms/input_textarea_toggable.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import AlertMixin from '../../mixins/alert_mixin';
|
||||||
|
import TextareaAutosize from 'react-textarea-autosize';
|
||||||
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
|
|
||||||
|
let InputTextAreaToggable = React.createClass({
|
||||||
|
|
||||||
|
propTypes: {
|
||||||
|
editable: React.PropTypes.bool.isRequired,
|
||||||
|
submitted: React.PropTypes.bool,
|
||||||
|
rows: React.PropTypes.number.isRequired,
|
||||||
|
onSubmit: React.PropTypes.func.isRequired,
|
||||||
|
required: React.PropTypes.string,
|
||||||
|
defaultValue: React.PropTypes.string
|
||||||
|
},
|
||||||
|
|
||||||
|
mixins: [AlertMixin],
|
||||||
|
|
||||||
|
getInitialState() {
|
||||||
|
return {
|
||||||
|
value: this.props.defaultValue,
|
||||||
|
edited: false,
|
||||||
|
alerts: null // needed in AlertMixin
|
||||||
|
};
|
||||||
|
},
|
||||||
|
handleChange(event) {
|
||||||
|
this.setState({
|
||||||
|
value: event.target.value,
|
||||||
|
edited: true
|
||||||
|
});
|
||||||
|
},
|
||||||
|
reset(){
|
||||||
|
this.setState(this.getInitialState());
|
||||||
|
},
|
||||||
|
submit(){
|
||||||
|
this.props.onSubmit();
|
||||||
|
this.setState({edited: false});
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
let className = 'form-control ascribe-textarea';
|
||||||
|
let buttons = null;
|
||||||
|
let textarea = null;
|
||||||
|
if (this.props.editable && this.state.edited){
|
||||||
|
buttons = (
|
||||||
|
<div className="pull-right">
|
||||||
|
<Button className="ascribe-btn" onClick={this.submit}>Save</Button>
|
||||||
|
<Button className="ascribe-btn" onClick={this.reset}>Cancel</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (this.props.editable){
|
||||||
|
className = className + ' ascribe-textarea-editable';
|
||||||
|
textarea = (
|
||||||
|
<TextareaAutosize
|
||||||
|
className={className}
|
||||||
|
value={this.state.value}
|
||||||
|
rows={this.props.rows}
|
||||||
|
required={this.props.required}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
placeholder='Write something...' />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
textarea = <pre className="ascribe-pre">{this.state.value}</pre>;
|
||||||
|
}
|
||||||
|
let alerts = (this.props.submitted) ? null : this.state.alerts;
|
||||||
|
return (
|
||||||
|
<div className="form-group">
|
||||||
|
{alerts}
|
||||||
|
{textarea}
|
||||||
|
{buttons}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default InputTextAreaToggable;
|
@ -1,45 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import Modal from 'react-bootstrap/lib/Modal';
|
|
||||||
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
|
|
||||||
import ModalTrigger from 'react-bootstrap/lib/ModalTrigger';
|
|
||||||
import Tooltip from 'react-bootstrap/lib/Tooltip';
|
|
||||||
|
|
||||||
import LoanForm from '../ascribe_forms/form_loan';
|
|
||||||
import ModalMixin from '../../mixins/modal_mixin';
|
|
||||||
|
|
||||||
let LoanModalButton = React.createClass({
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<OverlayTrigger delay={500} placement="left"
|
|
||||||
overlay={<Tooltip>Loan your artwork for a limited period of time</Tooltip>}>
|
|
||||||
<ModalTrigger modal={<LoanModal edition={this.props.edition}
|
|
||||||
currentUser={this.props.currentUser}/>}>
|
|
||||||
<div className="btn btn-ascribe-inv">
|
|
||||||
LOAN
|
|
||||||
</div>
|
|
||||||
</ModalTrigger>
|
|
||||||
</OverlayTrigger>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let LoanModal = React.createClass({
|
|
||||||
mixins: [ModalMixin],
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Modal {...this.props} title="Loan artwork">
|
|
||||||
<div className="modal-body">
|
|
||||||
<LoanForm edition={this.props.edition}
|
|
||||||
currentUser={this.props.currentUser}
|
|
||||||
onRequestHide={this.onRequestHide}/>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export default LoanModalButton;
|
|
@ -1,44 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import Modal from 'react-bootstrap/lib/Modal';
|
|
||||||
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
|
|
||||||
import ModalTrigger from 'react-bootstrap/lib/ModalTrigger';
|
|
||||||
import Tooltip from 'react-bootstrap/lib/Tooltip';
|
|
||||||
|
|
||||||
import ModalMixin from '../../mixins/modal_mixin';
|
|
||||||
import ShareForm from '../ascribe_forms/form_share_email';
|
|
||||||
|
|
||||||
let ShareModalButton = React.createClass({
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<OverlayTrigger delay={500} placement="left" overlay={<Tooltip>Share the artwork</Tooltip>}>
|
|
||||||
<ModalTrigger modal={<ShareModal edition={this.props.edition}
|
|
||||||
currentUser={this.props.currentUser}/>}>
|
|
||||||
<div className="btn btn-ascribe-inv btn-glyph-ascribe">
|
|
||||||
<span className="glyph-ascribe-share2"></span>
|
|
||||||
</div>
|
|
||||||
</ModalTrigger>
|
|
||||||
</OverlayTrigger>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let ShareModal = React.createClass({
|
|
||||||
mixins: [ModalMixin],
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Modal {...this.props} title="Share artwork">
|
|
||||||
<div className="modal-body">
|
|
||||||
<ShareForm edition={this.props.edition}
|
|
||||||
currentUser={this.props.currentUser}
|
|
||||||
onRequestHide={this.onRequestHide}/>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export default ShareModalButton;
|
|
@ -1,45 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import Modal from 'react-bootstrap/lib/Modal';
|
|
||||||
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
|
|
||||||
import ModalTrigger from 'react-bootstrap/lib/ModalTrigger';
|
|
||||||
import Tooltip from 'react-bootstrap/lib/Tooltip';
|
|
||||||
|
|
||||||
import UnConsignForm from '../ascribe_forms/form_unconsign';
|
|
||||||
import ModalMixin from '../../mixins/modal_mixin';
|
|
||||||
|
|
||||||
let UnConsignModalButton = React.createClass({
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<OverlayTrigger delay={500} placement="left"
|
|
||||||
overlay={<Tooltip>Unconsign this artwork</Tooltip>}>
|
|
||||||
<ModalTrigger modal={<UnConsignModal edition={this.props.edition}
|
|
||||||
currentUser={this.props.currentUser}/>}>
|
|
||||||
<div className="btn btn-ascribe-inv">
|
|
||||||
UNCONSIGN
|
|
||||||
</div>
|
|
||||||
</ModalTrigger>
|
|
||||||
</OverlayTrigger>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let UnConsignModal = React.createClass({
|
|
||||||
mixins: [ModalMixin],
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Modal {...this.props} title="Consign artwork">
|
|
||||||
<div className="modal-body">
|
|
||||||
<UnConsignForm edition={this.props.edition}
|
|
||||||
currentUser={this.props.currentUser}
|
|
||||||
onRequestHide={this.onRequestHide}/>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export default UnConsignModalButton;
|
|
@ -1,45 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import Modal from 'react-bootstrap/lib/Modal';
|
|
||||||
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
|
|
||||||
import ModalTrigger from 'react-bootstrap/lib/ModalTrigger';
|
|
||||||
import Tooltip from 'react-bootstrap/lib/Tooltip';
|
|
||||||
|
|
||||||
import UnConsignRequestForm from '../ascribe_forms/form_unconsign_request';
|
|
||||||
import ModalMixin from '../../mixins/modal_mixin';
|
|
||||||
|
|
||||||
let UnConsignRequestModalButton = React.createClass({
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<OverlayTrigger delay={500} placement="left"
|
|
||||||
overlay={<Tooltip>Request to unconsign the artwork</Tooltip>}>
|
|
||||||
<ModalTrigger modal={<UnConsignRequestModal edition={this.props.edition}
|
|
||||||
currentUser={this.props.currentUser}/>}>
|
|
||||||
<div className="btn btn-ascribe-inv">
|
|
||||||
UNCONSIGN REQUEST
|
|
||||||
</div>
|
|
||||||
</ModalTrigger>
|
|
||||||
</OverlayTrigger>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let UnConsignRequestModal = React.createClass({
|
|
||||||
mixins: [ModalMixin],
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Modal {...this.props} title="Request to unconsign artwork">
|
|
||||||
<div className="modal-body">
|
|
||||||
<UnConsignRequestForm edition={this.props.edition}
|
|
||||||
currentUser={this.props.currentUser}
|
|
||||||
onRequestHide={this.onRequestHide}/>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export default UnConsignRequestModalButton;
|
|
@ -11,6 +11,14 @@ import Tooltip from 'react-bootstrap/lib/Tooltip';
|
|||||||
import ModalMixin from '../../mixins/modal_mixin';
|
import ModalMixin from '../../mixins/modal_mixin';
|
||||||
|
|
||||||
let ModalWrapper = React.createClass({
|
let ModalWrapper = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
title: React.PropTypes.string.isRequired,
|
||||||
|
onRequestHide: React.PropTypes.func,
|
||||||
|
handleSuccess: React.PropTypes.func.isRequired,
|
||||||
|
button: React.PropTypes.object.isRequired,
|
||||||
|
children: React.PropTypes.object,
|
||||||
|
tooltip: React.PropTypes.string.isRequired
|
||||||
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
@ -19,8 +27,6 @@ let ModalWrapper = React.createClass({
|
|||||||
<ModalTrigger modal={
|
<ModalTrigger modal={
|
||||||
<ModalBody
|
<ModalBody
|
||||||
title={this.props.title}
|
title={this.props.title}
|
||||||
editions={this.props.editions}
|
|
||||||
currentUser={this.props.currentUser}
|
|
||||||
handleSuccess={this.props.handleSuccess}>
|
handleSuccess={this.props.handleSuccess}>
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
@ -32,22 +38,26 @@ let ModalWrapper = React.createClass({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//
|
|
||||||
let ModalBody = React.createClass({
|
let ModalBody = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
onRequestHide: React.PropTypes.func,
|
||||||
|
handleSuccess: React.PropTypes.func,
|
||||||
|
children: React.PropTypes.object,
|
||||||
|
title: React.PropTypes.string.isRequired
|
||||||
|
},
|
||||||
|
|
||||||
mixins: [ModalMixin],
|
mixins: [ModalMixin],
|
||||||
|
|
||||||
handleSuccess(){
|
handleSuccess(response){
|
||||||
this.props.handleSuccess();
|
this.props.handleSuccess(response);
|
||||||
this.props.onRequestHide();
|
this.props.onRequestHide();
|
||||||
},
|
},
|
||||||
|
|
||||||
renderChildren() {
|
renderChildren() {
|
||||||
return ReactAddons.Children.map(this.props.children, (child) => {
|
return ReactAddons.Children.map(this.props.children, (child) => {
|
||||||
return ReactAddons.addons.cloneWithProps(child, {
|
return ReactAddons.addons.cloneWithProps(child, {
|
||||||
editions: this.props.editions,
|
onRequestHide: this.props.onRequestHide,
|
||||||
currentUser: this.props.currentUser,
|
|
||||||
onRequestHide: this.onRequestHide,
|
|
||||||
handleSuccess: this.handleSuccess
|
handleSuccess: this.handleSuccess
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -13,7 +13,9 @@ import UserActions from '../../actions/user_actions';
|
|||||||
import PieceListBulkModalSelectedEditionsWidget from './piece_list_bulk_modal_selected_editions_widget';
|
import PieceListBulkModalSelectedEditionsWidget from './piece_list_bulk_modal_selected_editions_widget';
|
||||||
import AclButtonList from '../ascribe_buttons/acl_button_list';
|
import AclButtonList from '../ascribe_buttons/acl_button_list';
|
||||||
|
|
||||||
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
|
||||||
|
import { getAvailableAcls } from '../../utils/acl_utils';
|
||||||
|
|
||||||
|
|
||||||
let PieceListBulkModal = React.createClass({
|
let PieceListBulkModal = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
@ -61,31 +63,9 @@ let PieceListBulkModal = React.createClass({
|
|||||||
return selectedEditionList;
|
return selectedEditionList;
|
||||||
},
|
},
|
||||||
|
|
||||||
intersectAcls(a, b) {
|
|
||||||
return a.filter((val) => b.indexOf(val) > -1);
|
|
||||||
},
|
|
||||||
|
|
||||||
getAvailableAcls() {
|
|
||||||
let availableAcls = [];
|
|
||||||
let selectedEditionList = this.fetchSelectedEditionList();
|
|
||||||
|
|
||||||
// If no edition has been selected, availableActions is empty
|
|
||||||
// If only one edition has been selected, their actions are available
|
|
||||||
// If more than one editions have been selected, their acl properties are intersected
|
|
||||||
if(selectedEditionList.length >= 1) {
|
|
||||||
availableAcls = selectedEditionList[0].acl;
|
|
||||||
}
|
|
||||||
if(selectedEditionList.length >= 2) {
|
|
||||||
for(let i = 1; i < selectedEditionList.length; i++) {
|
|
||||||
availableAcls = this.intersectAcls(availableAcls, selectedEditionList[i].acl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return availableAcls;
|
|
||||||
},
|
|
||||||
|
|
||||||
clearAllSelections() {
|
clearAllSelections() {
|
||||||
EditionListActions.clearAllEditionSelections();
|
EditionListActions.clearAllEditionSelections();
|
||||||
|
EditionListActions.closeAllEditionLists();
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSuccess() {
|
handleSuccess() {
|
||||||
@ -93,13 +73,12 @@ let PieceListBulkModal = React.createClass({
|
|||||||
.forEach((pieceId) => {
|
.forEach((pieceId) => {
|
||||||
EditionListActions.fetchEditionList(pieceId, this.state.orderBy, this.state.orderAsc);
|
EditionListActions.fetchEditionList(pieceId, this.state.orderBy, this.state.orderAsc);
|
||||||
});
|
});
|
||||||
GlobalNotificationActions.updateGlobalNotification({message: 'Transfer successful'});
|
|
||||||
EditionListActions.clearAllEditionSelections();
|
EditionListActions.clearAllEditionSelections();
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let availableAcls = this.getAvailableAcls();
|
|
||||||
let selectedEditions = this.fetchSelectedEditionList();
|
let selectedEditions = this.fetchSelectedEditionList();
|
||||||
|
let availableAcls = getAvailableAcls(selectedEditions);
|
||||||
|
|
||||||
if(availableAcls.length > 0) {
|
if(availableAcls.length > 0) {
|
||||||
return (
|
return (
|
||||||
|
@ -20,7 +20,6 @@ let Table = React.createClass({
|
|||||||
},
|
},
|
||||||
|
|
||||||
renderChildren() {
|
renderChildren() {
|
||||||
var that = this;
|
|
||||||
return ReactAddons.Children.map(this.props.children, (child, i) => {
|
return ReactAddons.Children.map(this.props.children, (child, i) => {
|
||||||
return ReactAddons.addons.cloneWithProps(child, {
|
return ReactAddons.addons.cloneWithProps(child, {
|
||||||
columnList: this.props.columnList,
|
columnList: this.props.columnList,
|
||||||
|
@ -17,7 +17,9 @@ let TableItemCheckbox = React.createClass({
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<input type="checkbox" onChange={this.selectItem} checked={this.props.selected}/>
|
<span>
|
||||||
|
<input type="checkbox" onChange={this.selectItem} checked={this.props.selected}/>
|
||||||
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -4,7 +4,6 @@ import React from 'react';
|
|||||||
import Router from 'react-router';
|
import Router from 'react-router';
|
||||||
|
|
||||||
import { ColumnModel } from './models/table_models';
|
import { ColumnModel } from './models/table_models';
|
||||||
import TableColumnMixin from '../../mixins/table_column_mixin';
|
|
||||||
|
|
||||||
let Link = Router.Link;
|
let Link = Router.Link;
|
||||||
|
|
||||||
@ -15,7 +14,7 @@ let TableItemWrapper = React.createClass({
|
|||||||
columnWidth: React.PropTypes.number.isRequired
|
columnWidth: React.PropTypes.number.isRequired
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [TableColumnMixin, Router.Navigation],
|
mixins: [Router.Navigation],
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
@ -25,8 +24,6 @@ let TableItemWrapper = React.createClass({
|
|||||||
let TypeElement = column.displayType;
|
let TypeElement = column.displayType;
|
||||||
let typeElementProps = column.transformFn(this.props.columnContent);
|
let typeElementProps = column.transformFn(this.props.columnContent);
|
||||||
|
|
||||||
let columnClass = this.calcColumnClasses(this.props.columnList, i, this.props.columnWidth);
|
|
||||||
|
|
||||||
if(!column.transition) {
|
if(!column.transition) {
|
||||||
return (
|
return (
|
||||||
<td
|
<td
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import MediaPlayer from './ascribe_media/media_player';
|
import MediaPlayer from './ascribe_media/media_player';
|
||||||
|
|
||||||
import CollapsibleMixin from 'react-bootstrap/lib/CollapsibleMixin';
|
import CollapsibleMixin from 'react-bootstrap/lib/CollapsibleMixin';
|
||||||
@ -8,11 +9,17 @@ import Row from 'react-bootstrap/lib/Row';
|
|||||||
import Col from 'react-bootstrap/lib/Col';
|
import Col from 'react-bootstrap/lib/Col';
|
||||||
import Button from 'react-bootstrap/lib/Button';
|
import Button from 'react-bootstrap/lib/Button';
|
||||||
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
|
||||||
import TextareaAutosize from 'react-textarea-autosize';
|
|
||||||
|
import PersonalNoteForm from './ascribe_forms/form_note_personal';
|
||||||
|
import PieceExtraDataForm from './ascribe_forms/form_piece_extradata';
|
||||||
|
import RequestActionForm from './ascribe_forms/form_request_action';
|
||||||
|
|
||||||
import EditionActions from '../actions/edition_actions';
|
import EditionActions from '../actions/edition_actions';
|
||||||
import AclButtonList from './ascribe_buttons/acl_button_list';
|
import AclButtonList from './ascribe_buttons/acl_button_list';
|
||||||
|
|
||||||
|
import GlobalNotificationModel from '../models/global_notification_model';
|
||||||
|
import GlobalNotificationActions from '../actions/global_notification_actions';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,9 +28,7 @@ import classNames from 'classnames';
|
|||||||
let Edition = React.createClass({
|
let Edition = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
edition: React.PropTypes.object,
|
edition: React.PropTypes.object,
|
||||||
currentUser: React.PropTypes.object,
|
loadEdition: React.PropTypes.func
|
||||||
deleteEdition: React.PropTypes.func,
|
|
||||||
savePersonalNote: React.PropTypes.func
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -39,10 +44,14 @@ let Edition = React.createClass({
|
|||||||
<a target="_blank" href={'https://www.blocktrail.com/BTC/address/' + this.props.edition.bitcoin_id}>{this.props.edition.bitcoin_id}</a>
|
<a target="_blank" href={'https://www.blocktrail.com/BTC/address/' + this.props.edition.bitcoin_id}>{this.props.edition.bitcoin_id}</a>
|
||||||
);
|
);
|
||||||
|
|
||||||
let hashOfArtwork = (
|
let hashOfArtwork = (
|
||||||
<a target="_blank" href={'https://www.blocktrail.com/BTC/address/' + this.props.edition.hash_as_address}>{this.props.edition.hash_as_address}</a>
|
<a target="_blank" href={'https://www.blocktrail.com/BTC/address/' + this.props.edition.hash_as_address}>{this.props.edition.hash_as_address}</a>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let ownerAddress = (
|
||||||
|
<a target="_blank" href={'https://www.blocktrail.com/BTC/address/' + this.props.edition.btc_owner_address_noprefix}>{this.props.edition.btc_owner_address_noprefix}</a>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row>
|
<Row>
|
||||||
<Col md={6}>
|
<Col md={6}>
|
||||||
@ -59,13 +68,19 @@ let Edition = React.createClass({
|
|||||||
<Col md={6} className="ascribe-edition-details">
|
<Col md={6} className="ascribe-edition-details">
|
||||||
<EditionHeader edition={this.props.edition}/>
|
<EditionHeader edition={this.props.edition}/>
|
||||||
<EditionSummary
|
<EditionSummary
|
||||||
edition={this.props.edition}
|
edition={this.props.edition} />
|
||||||
currentUser={ this.props.currentUser }/>
|
|
||||||
<CollapsibleEditionDetails
|
<CollapsibleEditionDetails
|
||||||
title="Personal Note"
|
title="Personal Note"
|
||||||
iconName="pencil">
|
iconName="pencil">
|
||||||
<EditionPersonalNote
|
<EditionPersonalNote
|
||||||
savePersonalNote={this.props.savePersonalNote}/>
|
handleSuccess={this.props.loadEdition}
|
||||||
|
edition={this.props.edition}/>
|
||||||
|
</CollapsibleEditionDetails>
|
||||||
|
<CollapsibleEditionDetails
|
||||||
|
title="Further Details">
|
||||||
|
<EditionFurtherDetails
|
||||||
|
handleSuccess={this.props.loadEdition}
|
||||||
|
edition={this.props.edition}/>
|
||||||
</CollapsibleEditionDetails>
|
</CollapsibleEditionDetails>
|
||||||
|
|
||||||
<CollapsibleEditionDetails
|
<CollapsibleEditionDetails
|
||||||
@ -75,6 +90,13 @@ let Edition = React.createClass({
|
|||||||
history={this.props.edition.ownership_history} />
|
history={this.props.edition.ownership_history} />
|
||||||
</CollapsibleEditionDetails>
|
</CollapsibleEditionDetails>
|
||||||
|
|
||||||
|
<CollapsibleEditionDetails
|
||||||
|
title="Consignment History"
|
||||||
|
show={this.props.edition.consign_history && this.props.edition.consign_history.length > 0}>
|
||||||
|
<EditionDetailHistoryIterator
|
||||||
|
history={this.props.edition.consign_history} />
|
||||||
|
</CollapsibleEditionDetails>
|
||||||
|
|
||||||
<CollapsibleEditionDetails
|
<CollapsibleEditionDetails
|
||||||
title="Loan History"
|
title="Loan History"
|
||||||
show={this.props.edition.loan_history && this.props.edition.loan_history.length > 0}>
|
show={this.props.edition.loan_history && this.props.edition.loan_history.length > 0}>
|
||||||
@ -92,16 +114,7 @@ let Edition = React.createClass({
|
|||||||
value={hashOfArtwork} />
|
value={hashOfArtwork} />
|
||||||
<EditionDetailProperty
|
<EditionDetailProperty
|
||||||
label="Owned by SPOOL address"
|
label="Owned by SPOOL address"
|
||||||
value="MISSING IN /editions/<id> RESOURCE!" />
|
value={ownerAddress} />
|
||||||
</CollapsibleEditionDetails>
|
|
||||||
|
|
||||||
<CollapsibleEditionDetails
|
|
||||||
title="Delete Actions">
|
|
||||||
<Button
|
|
||||||
bsStyle="danger"
|
|
||||||
onClick={this.props.deleteEdition}>
|
|
||||||
Remove this artwork from your list
|
|
||||||
</Button>
|
|
||||||
</CollapsibleEditionDetails>
|
</CollapsibleEditionDetails>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
@ -130,22 +143,31 @@ let EditionHeader = React.createClass({
|
|||||||
|
|
||||||
let EditionSummary = React.createClass({
|
let EditionSummary = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
edition: React.PropTypes.object,
|
edition: React.PropTypes.object
|
||||||
currentUser: React.PropTypes.object
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSuccess(){
|
handleSuccess(){
|
||||||
EditionActions.fetchOne(this.props.edition.id);
|
EditionActions.fetchOne(this.props.edition.id);
|
||||||
},
|
},
|
||||||
|
showNotification(response){
|
||||||
|
this.handleSuccess();
|
||||||
|
let notification = new GlobalNotificationModel(response.notification, 'success');
|
||||||
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
},
|
||||||
render() {
|
render() {
|
||||||
return (
|
let status = null;
|
||||||
<div className="ascribe-detail-header">
|
if (this.props.edition.status.length > 0){
|
||||||
<EditionDetailProperty label="EDITION"
|
status = <EditionDetailProperty label="STATUS" value={ this.props.edition.status.join().replace(/_/, ' ') } />;
|
||||||
value={this.props.edition.edition_number + ' of ' + this.props.edition.num_editions} />
|
}
|
||||||
<EditionDetailProperty label="ID" value={ this.props.edition.bitcoin_id } />
|
let actions = null;
|
||||||
<EditionDetailProperty label="OWNER" value={ this.props.edition.owner } />
|
if (this.props.edition.request_action){
|
||||||
<br/>
|
actions = (
|
||||||
|
<RequestActionForm
|
||||||
|
editions={ [this.props.edition] }
|
||||||
|
handleSuccess={this.showNotification}/>);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
actions = (
|
||||||
<Row>
|
<Row>
|
||||||
<Col md={12}>
|
<Col md={12}>
|
||||||
<AclButtonList
|
<AclButtonList
|
||||||
@ -154,7 +176,18 @@ let EditionSummary = React.createClass({
|
|||||||
editions={[this.props.edition]}
|
editions={[this.props.edition]}
|
||||||
handleSuccess={this.handleSuccess} />
|
handleSuccess={this.handleSuccess} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="ascribe-detail-header">
|
||||||
|
<EditionDetailProperty label="EDITION"
|
||||||
|
value={this.props.edition.edition_number + ' of ' + this.props.edition.num_editions} />
|
||||||
|
<EditionDetailProperty label="ID" value={ this.props.edition.bitcoin_id } />
|
||||||
|
<EditionDetailProperty label="OWNER" value={ this.props.edition.owner } />
|
||||||
|
{status}
|
||||||
|
<br/>
|
||||||
|
{actions}
|
||||||
<hr/>
|
<hr/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -257,8 +290,8 @@ let EditionDetailProperty = React.createClass({
|
|||||||
getDefaultProps() {
|
getDefaultProps() {
|
||||||
return {
|
return {
|
||||||
separator: ':',
|
separator: ':',
|
||||||
labelClassName: 'col-xs-5 col-sm-5 col-md-5 col-lg-5',
|
labelClassName: 'col-xs-5 col-sm-4 col-md-3 col-lg-3',
|
||||||
valueClassName: 'col-xs-7 col-sm-7 col-md-7 col-lg-7'
|
valueClassName: 'col-xs-7 col-sm-8 col-md-9 col-lg-9'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -267,7 +300,7 @@ let EditionDetailProperty = React.createClass({
|
|||||||
<div className="row ascribe-detail-property">
|
<div className="row ascribe-detail-property">
|
||||||
<div className="row-same-height">
|
<div className="row-same-height">
|
||||||
<div className={this.props.labelClassName + ' col-xs-height col-bottom'}>
|
<div className={this.props.labelClassName + ' col-xs-height col-bottom'}>
|
||||||
<div>{ this.props.label }{this.props.separator}</div>
|
<div>{ this.props.label + this.props.separator}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={this.props.valueClassName + ' col-xs-height col-bottom'}>
|
<div className={this.props.valueClassName + ' col-xs-height col-bottom'}>
|
||||||
<div>{ this.props.value }</div>
|
<div>{ this.props.value }</div>
|
||||||
@ -304,26 +337,21 @@ let EditionDetailHistoryIterator = React.createClass({
|
|||||||
|
|
||||||
let EditionPersonalNote = React.createClass({
|
let EditionPersonalNote = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
savePersonalNote: React.PropTypes.func
|
edition: React.PropTypes.object,
|
||||||
|
handleSuccess: React.PropTypes.func
|
||||||
},
|
},
|
||||||
|
showNotification(){
|
||||||
prepareSavePersonalNote() {
|
this.props.handleSuccess();
|
||||||
let personalNote = React.findDOMNode(this.refs.personalNote).value;
|
let notification = new GlobalNotificationModel('Note saved', 'success');
|
||||||
this.props.savePersonalNote(personalNote);
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Row>
|
<Row>
|
||||||
<Col md={12} className="ascribe-edition-personal-note">
|
<Col md={12} className="ascribe-edition-personal-note">
|
||||||
<TextareaAutosize
|
<PersonalNoteForm
|
||||||
ref="personalNote"
|
handleSuccess={this.showNotification}
|
||||||
className="form-control"
|
editions={[this.props.edition]} />
|
||||||
rows={3}
|
|
||||||
placeholder='Write something...' />
|
|
||||||
<Button
|
|
||||||
onClick={this.prepareSavePersonalNote}
|
|
||||||
className="pull-right">Save</Button>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
@ -331,4 +359,41 @@ let EditionPersonalNote = React.createClass({
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let EditionFurtherDetails = React.createClass({
|
||||||
|
propTypes: {
|
||||||
|
edition: React.PropTypes.object,
|
||||||
|
handleSuccess: React.PropTypes.func
|
||||||
|
},
|
||||||
|
showNotification(){
|
||||||
|
this.props.handleSuccess();
|
||||||
|
let notification = new GlobalNotificationModel('Details updated', 'success');
|
||||||
|
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||||
|
},
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Row>
|
||||||
|
<Col md={12} className="ascribe-edition-personal-note">
|
||||||
|
<PieceExtraDataForm
|
||||||
|
name='artist_contact_info'
|
||||||
|
title='Artist Contact Info'
|
||||||
|
handleSuccess={this.showNotification}
|
||||||
|
editions={[this.props.edition]} />
|
||||||
|
<PieceExtraDataForm
|
||||||
|
name='display_instructions'
|
||||||
|
title='Display Instructions'
|
||||||
|
handleSuccess={this.showNotification}
|
||||||
|
editions={[this.props.edition]} />
|
||||||
|
<PieceExtraDataForm
|
||||||
|
name='technology_details'
|
||||||
|
title='Technology Details'
|
||||||
|
handleSuccess={this.showNotification}
|
||||||
|
editions={[this.props.edition]} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export default Edition;
|
export default Edition;
|
||||||
|
@ -2,12 +2,8 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { mergeOptions } from '../utils/general_utils';
|
|
||||||
|
|
||||||
import EditionActions from '../actions/edition_actions';
|
import EditionActions from '../actions/edition_actions';
|
||||||
import EditionStore from '../stores/edition_store';
|
import EditionStore from '../stores/edition_store';
|
||||||
import UserActions from '../actions/user_actions';
|
|
||||||
import UserStore from '../stores/user_store';
|
|
||||||
|
|
||||||
import Edition from './edition';
|
import Edition from './edition';
|
||||||
|
|
||||||
@ -16,7 +12,7 @@ import Edition from './edition';
|
|||||||
*/
|
*/
|
||||||
let EditionContainer = React.createClass({
|
let EditionContainer = React.createClass({
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return mergeOptions(UserStore.getState(), EditionStore.getState());
|
return EditionStore.getState();
|
||||||
},
|
},
|
||||||
|
|
||||||
onChange(state) {
|
onChange(state) {
|
||||||
@ -25,24 +21,16 @@ let EditionContainer = React.createClass({
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
EditionStore.listen(this.onChange);
|
EditionStore.listen(this.onChange);
|
||||||
UserStore.listen(this.onChange);
|
|
||||||
|
|
||||||
UserActions.fetchCurrentUser();
|
|
||||||
EditionActions.fetchOne(this.props.params.editionId);
|
EditionActions.fetchOne(this.props.params.editionId);
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
EditionStore.unlisten(this.onChange);
|
EditionStore.unlisten(this.onChange);
|
||||||
UserStore.unlisten(this.onChange);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteEdition() {
|
|
||||||
// Delete Edition from server
|
|
||||||
},
|
|
||||||
|
|
||||||
savePersonalNote(note) {
|
loadEdition() {
|
||||||
console.log(note);
|
EditionActions.fetchOne(this.props.params.editionId);
|
||||||
// Save personalNote to server
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -50,9 +38,7 @@ let EditionContainer = React.createClass({
|
|||||||
return (
|
return (
|
||||||
<Edition
|
<Edition
|
||||||
edition={this.state.edition}
|
edition={this.state.edition}
|
||||||
currentUser={this.state.currentUser}
|
loadEdition={this.loadEdition}/>
|
||||||
deleteEdition={this.deleteEdition}
|
|
||||||
savePersonalNote={this.savePersonalNote}/>
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
|
@ -38,7 +38,7 @@ let Header = React.createClass({
|
|||||||
return (
|
return (
|
||||||
<Navbar>
|
<Navbar>
|
||||||
<Nav>
|
<Nav>
|
||||||
<Link className="navbar-brand" to="pieces">
|
<Link className="navbar-brand" to="pieces" path="/?page=1">
|
||||||
<span>ascribe </span>
|
<span>ascribe </span>
|
||||||
<span className="glyph-ascribe-spool-chunked ascribe-color"></span>
|
<span className="glyph-ascribe-spool-chunked ascribe-color"></span>
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -27,7 +27,10 @@ let PieceList = React.createClass({
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
let page = this.props.query.page || 1;
|
let page = this.props.query.page || 1;
|
||||||
PieceListStore.listen(this.onChange);
|
PieceListStore.listen(this.onChange);
|
||||||
PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc);
|
if (this.state.pieceList.length === 0){
|
||||||
|
PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc);
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
@ -74,9 +77,7 @@ let PieceList = React.createClass({
|
|||||||
key={i}>
|
key={i}>
|
||||||
<AccordionListItemTableEditions
|
<AccordionListItemTableEditions
|
||||||
className="ascribe-accordion-list-item-table col-xs-12 col-sm-8 col-md-6 col-lg-6 col-sm-offset-2 col-md-offset-3 col-lg-offset-3"
|
className="ascribe-accordion-list-item-table col-xs-12 col-sm-8 col-md-6 col-lg-6 col-sm-offset-2 col-md-offset-3 col-lg-offset-3"
|
||||||
parentId={item.id}
|
parentId={item.id} />
|
||||||
show={item.show}
|
|
||||||
numOfEditions={item.num_editions}/>
|
|
||||||
</AccordionListItem>
|
</AccordionListItem>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@ -3,17 +3,26 @@
|
|||||||
import AppConstants from './application_constants';
|
import AppConstants from './application_constants';
|
||||||
|
|
||||||
let apiUrls = {
|
let apiUrls = {
|
||||||
'ownership_shares_mail': AppConstants.apiEndpoint + 'ownership/shares/mail/',
|
|
||||||
'ownership_transfers': AppConstants.apiEndpoint + 'ownership/transfers/',
|
|
||||||
'user': AppConstants.apiEndpoint + 'users/',
|
'user': AppConstants.apiEndpoint + 'users/',
|
||||||
'pieces_list': AppConstants.apiEndpoint + 'pieces/',
|
|
||||||
'piece': AppConstants.apiEndpoint + 'pieces/${piece_id}',
|
'piece': AppConstants.apiEndpoint + 'pieces/${piece_id}',
|
||||||
|
'pieces_list': AppConstants.apiEndpoint + 'pieces/',
|
||||||
|
'piece_extradata': AppConstants.apiEndpoint + 'pieces/${piece_id}/extradata/',
|
||||||
'edition': AppConstants.apiEndpoint + 'editions/${bitcoin_id}/',
|
'edition': AppConstants.apiEndpoint + 'editions/${bitcoin_id}/',
|
||||||
'editions_list': AppConstants.apiEndpoint + 'pieces/${piece_id}/editions/',
|
'editions_list': AppConstants.apiEndpoint + 'pieces/${piece_id}/editions/',
|
||||||
'ownership_loans': AppConstants.apiEndpoint + 'ownership/loans/',
|
'edition_delete': AppConstants.apiEndpoint + 'editions/${edition_id}/',
|
||||||
|
'edition_remove_from_collection': AppConstants.apiEndpoint + 'ownership/shares/${edition_id}/',
|
||||||
|
'ownership_shares_mail': AppConstants.apiEndpoint + 'ownership/shares/mail/',
|
||||||
|
'ownership_transfers': AppConstants.apiEndpoint + 'ownership/transfers/',
|
||||||
'ownership_consigns': AppConstants.apiEndpoint + 'ownership/consigns/',
|
'ownership_consigns': AppConstants.apiEndpoint + 'ownership/consigns/',
|
||||||
|
'ownership_consigns_confirm': AppConstants.apiEndpoint + 'ownership/consigns/confirm/',
|
||||||
|
'ownership_consigns_deny': AppConstants.apiEndpoint + 'ownership/consigns/deny/',
|
||||||
'ownership_unconsigns': AppConstants.apiEndpoint + 'ownership/unconsigns/',
|
'ownership_unconsigns': AppConstants.apiEndpoint + 'ownership/unconsigns/',
|
||||||
'ownership_unconsigns_request': AppConstants.apiEndpoint + 'ownership/unconsigns/request/'
|
'ownership_unconsigns_request': AppConstants.apiEndpoint + 'ownership/unconsigns/request/',
|
||||||
|
'ownership_unconsigns_deny': AppConstants.apiEndpoint + 'ownership/unconsigns/deny/',
|
||||||
|
'ownership_loans': AppConstants.apiEndpoint + 'ownership/loans/',
|
||||||
|
'ownership_loans_confirm': AppConstants.apiEndpoint + 'ownership/loans/confirm/',
|
||||||
|
'ownership_loans_deny': AppConstants.apiEndpoint + 'ownership/loans/deny/',
|
||||||
|
'note_notes': AppConstants.apiEndpoint + 'note/notes/'
|
||||||
};
|
};
|
||||||
|
|
||||||
export default apiUrls;
|
export default apiUrls;
|
||||||
|
@ -8,7 +8,8 @@ let constants = {
|
|||||||
'baseUrl': window.BASE_URL,
|
'baseUrl': window.BASE_URL,
|
||||||
'apiEndpoint': window.API_ENDPOINT,
|
'apiEndpoint': window.API_ENDPOINT,
|
||||||
'debugCredentialBase64': 'ZGltaUBtYWlsaW5hdG9yLmNvbTowMDAwMDAwMDAw', // dimi@mailinator:0000000000
|
'debugCredentialBase64': 'ZGltaUBtYWlsaW5hdG9yLmNvbTowMDAwMDAwMDAw', // dimi@mailinator:0000000000
|
||||||
'aclList': ['edit', 'consign', 'transfer', 'loan', 'share', 'download', 'view', 'delete', 'del_from_collection', 'add_to_collection']
|
'aclList': ['edit', 'consign', 'consign_request', 'unconsign', 'unconsign_request', 'transfer',
|
||||||
|
'loan', 'loan_request', 'share', 'download', 'view', 'delete', 'del_from_collection', 'add_to_collection']
|
||||||
};
|
};
|
||||||
|
|
||||||
export default constants;
|
export default constants;
|
||||||
|
@ -6,6 +6,11 @@ import React from 'react';
|
|||||||
import AlertDismissable from '../components/ascribe_forms/alert';
|
import AlertDismissable from '../components/ascribe_forms/alert';
|
||||||
|
|
||||||
export const FormMixin = {
|
export const FormMixin = {
|
||||||
|
propTypes: {
|
||||||
|
editions: React.PropTypes.array,
|
||||||
|
currentUser: React.PropTypes.object
|
||||||
|
},
|
||||||
|
|
||||||
getInitialState() {
|
getInitialState() {
|
||||||
return {
|
return {
|
||||||
submitted: false,
|
submitted: false,
|
||||||
@ -14,22 +19,44 @@ export const FormMixin = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
submit(e) {
|
submit(e) {
|
||||||
e.preventDefault();
|
if (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
this.setState({submitted: true});
|
this.setState({submitted: true});
|
||||||
this.clearErrors();
|
this.clearErrors();
|
||||||
|
let action = (this.httpVerb && this.httpVerb()) || 'post';
|
||||||
|
this[action](e);
|
||||||
|
},
|
||||||
|
|
||||||
|
post(e){
|
||||||
fetch
|
fetch
|
||||||
.post(this.url(), { body: this.getFormData() })
|
.post(this.url(e), { body: this.getFormData() })
|
||||||
.then(() => this.props.handleSuccess())
|
.then(this.handleSuccess)
|
||||||
|
.catch(this.handleError);
|
||||||
|
},
|
||||||
|
|
||||||
|
delete(e){
|
||||||
|
fetch
|
||||||
|
.delete(this.url(e))
|
||||||
|
.then(this.handleSuccess)
|
||||||
.catch(this.handleError);
|
.catch(this.handleError);
|
||||||
},
|
},
|
||||||
|
|
||||||
clearErrors(){
|
clearErrors(){
|
||||||
for (var ref in this.refs){
|
for (var ref in this.refs){
|
||||||
this.refs[ref].clearAlerts();
|
if ('clearAlerts' in this.refs[ref]){
|
||||||
|
this.refs[ref].clearAlerts();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
this.setState({errors: []});
|
this.setState({errors: []});
|
||||||
},
|
},
|
||||||
|
handleSuccess(response){
|
||||||
|
if ('handleSuccess' in this.props){
|
||||||
|
this.props.handleSuccess(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
handleError(err){
|
handleError(err){
|
||||||
if (err.json) {
|
if (err.json) {
|
||||||
for (var input in err.json.errors){
|
for (var input in err.json.errors){
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
export default class GlobalNotificationModel {
|
export default class GlobalNotificationModel {
|
||||||
constructor(message, type = 'info', dismissAfter = 3500) {
|
constructor(message, type = 'info', dismissAfter = 5000) {
|
||||||
if(message) {
|
if(message) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
} else {
|
} else {
|
||||||
|
@ -8,6 +8,7 @@ import EditionsListActions from '../actions/edition_list_actions';
|
|||||||
class EditionListStore {
|
class EditionListStore {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.editionList = {};
|
this.editionList = {};
|
||||||
|
this.isEditionListOpenForPieceId = {};
|
||||||
this.bindActions(EditionsListActions);
|
this.bindActions(EditionsListActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -16,13 +17,16 @@ class EditionListStore {
|
|||||||
this.editionList[pieceId].forEach((edition, i) => {
|
this.editionList[pieceId].forEach((edition, i) => {
|
||||||
// This uses the index of the new editionList for determining the edition.
|
// This uses the index of the new editionList for determining the edition.
|
||||||
// If the list of editions can be sorted in the future, this needs to be changed!
|
// If the list of editions can be sorted in the future, this needs to be changed!
|
||||||
editionListOfPiece[i] = React.addons.update(edition, {$merge: editionListOfPiece[i]});
|
if (editionListOfPiece[i]) {
|
||||||
|
editionListOfPiece[i] = React.addons.update(edition, {$merge: editionListOfPiece[i]});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.editionList[pieceId] = editionListOfPiece;
|
this.editionList[pieceId] = editionListOfPiece;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* orderBy and orderAsc are specific to a single list of editons
|
* orderBy and orderAsc 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.
|
||||||
@ -34,7 +38,7 @@ class EditionListStore {
|
|||||||
onSelectEdition({pieceId, editionId, toValue}) {
|
onSelectEdition({pieceId, editionId, toValue}) {
|
||||||
this.editionList[pieceId].forEach((edition) => {
|
this.editionList[pieceId].forEach((edition) => {
|
||||||
|
|
||||||
// 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) {
|
||||||
@ -55,12 +59,20 @@ class EditionListStore {
|
|||||||
.forEach((edition) => {
|
.forEach((edition) => {
|
||||||
try {
|
try {
|
||||||
delete edition.selected;
|
delete edition.selected;
|
||||||
} catch(err) {
|
} catch(err) {/* ignore and keep going */}
|
||||||
//just ignore
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onToggleEditionList(pieceId) {
|
||||||
|
this.isEditionListOpenForPieceId[pieceId] = {
|
||||||
|
show: this.isEditionListOpenForPieceId[pieceId] ? !this.isEditionListOpenForPieceId[pieceId].show : true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onCloseAllEditionLists() {
|
||||||
|
this.isEditionListOpenForPieceId = {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default alt.createStore(EditionListStore, 'EditionListStore');
|
export default alt.createStore(EditionListStore, 'EditionListStore');
|
@ -1,5 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
import alt from '../alt';
|
import alt from '../alt';
|
||||||
|
|
||||||
import PieceListActions from '../actions/piece_list_actions';
|
import PieceListActions from '../actions/piece_list_actions';
|
||||||
@ -27,7 +28,7 @@ class PieceListStore {
|
|||||||
this.bindActions(PieceListActions);
|
this.bindActions(PieceListActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
onShowEditionList(pieceId) {
|
/*onShowEditionList(pieceId) {
|
||||||
this.pieceList
|
this.pieceList
|
||||||
.forEach((piece) => {
|
.forEach((piece) => {
|
||||||
if(piece.id === pieceId) {
|
if(piece.id === pieceId) {
|
||||||
@ -38,14 +39,14 @@ class PieceListStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}*/
|
||||||
|
|
||||||
onCloseAllEditionLists() {
|
/*onCloseAllEditionLists() {
|
||||||
this.pieceList
|
this.pieceList
|
||||||
.forEach((piece) => {
|
.forEach((piece) => {
|
||||||
piece.show = false;
|
piece.show = false;
|
||||||
});
|
});
|
||||||
}
|
}*/
|
||||||
|
|
||||||
onUpdatePieceList({ page, pageSize, search, pieceList, orderBy, orderAsc, pieceListCount }) {
|
onUpdatePieceList({ page, pageSize, search, pieceList, orderBy, orderAsc, pieceListCount }) {
|
||||||
this.page = page;
|
this.page = page;
|
||||||
@ -72,6 +73,16 @@ class PieceListStore {
|
|||||||
* We did not implement this, as we're going to add pagination to pieceList at some
|
* We did not implement this, as we're going to add pagination to pieceList at some
|
||||||
* point anyway. Then, this problem is automatically resolved.
|
* point anyway. Then, this problem is automatically resolved.
|
||||||
*/
|
*/
|
||||||
|
pieceList.forEach((piece, i) => {
|
||||||
|
let oldPiece = this.pieceList[i];
|
||||||
|
if(oldPiece) {
|
||||||
|
piece = React.addons.update(piece, {
|
||||||
|
show: { $set: oldPiece.show }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
this.pieceList = pieceList;
|
this.pieceList = pieceList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
js/utils/acl_utils.js
Normal file
23
js/utils/acl_utils.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
export function getAvailableAcls(editions) {
|
||||||
|
let availableAcls = [];
|
||||||
|
|
||||||
|
// If no edition has been selected, availableActions is empty
|
||||||
|
// If only one edition has been selected, their actions are available
|
||||||
|
// If more than one editions have been selected, their acl properties are intersected
|
||||||
|
if(editions.length >= 1) {
|
||||||
|
availableAcls = editions[0].acl;
|
||||||
|
}
|
||||||
|
if(editions.length >= 2) {
|
||||||
|
for(let i = 1; i < editions.length; i++) {
|
||||||
|
availableAcls = intersectAcls(availableAcls, editions[i].acl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return availableAcls;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function intersectAcls(a, b) {
|
||||||
|
return a.filter((val) => b.indexOf(val) > -1);
|
||||||
|
}
|
@ -88,19 +88,25 @@ class Fetch {
|
|||||||
|
|
||||||
get(url, params) {
|
get(url, params) {
|
||||||
let paramsCopy = this._merge(params);
|
let paramsCopy = this._merge(params);
|
||||||
let newUrl = this.prepareUrl(url, params, true);
|
let newUrl = this.prepareUrl(url, paramsCopy, true);
|
||||||
return this.request('get', newUrl);
|
return this.request('get', newUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete(url, params) {
|
||||||
|
let paramsCopy = this._merge(params);
|
||||||
|
let newUrl = this.prepareUrl(url, paramsCopy, true);
|
||||||
|
return this.request('delete', newUrl);
|
||||||
|
}
|
||||||
|
|
||||||
post(url, params) {
|
post(url, params) {
|
||||||
let paramsCopy = this._merge(params);
|
let paramsCopy = this._merge(params);
|
||||||
let newUrl = this.prepareUrl(url, params);
|
let newUrl = this.prepareUrl(url, paramsCopy);
|
||||||
let body = null;
|
let body = null;
|
||||||
|
|
||||||
if (params.body) {
|
if (paramsCopy && paramsCopy.body) {
|
||||||
body = JSON.stringify(params.body);
|
body = JSON.stringify(paramsCopy.body);
|
||||||
}
|
}
|
||||||
return this.request('post', url, { body });
|
return this.request('post', newUrl, { body });
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults(options) {
|
defaults(options) {
|
||||||
|
44
sass/ascribe_table.scss
Normal file
44
sass/ascribe_table.scss
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
.ascribe-table {
|
||||||
|
margin-bottom:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*This is aligning the first checkbox in pieclist detail with all the other ones*/
|
||||||
|
.table > thead:first-child > tr:first-child > th {
|
||||||
|
padding-left:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ascribe-table-header-column > span {
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
font-family: 'Source Sans Pro';
|
||||||
|
font-weight: 600;
|
||||||
|
color: #424242;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ascribe-table-item-column {
|
||||||
|
display: table;
|
||||||
|
font-family: 'Source Sans Pro';
|
||||||
|
font-size: .8em;
|
||||||
|
height:3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ascribe-table-item-column > * {
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ascribe-table-item-column > span > input {
|
||||||
|
margin-top:14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ascribe-table-item-selected {
|
||||||
|
background-color: rgba(2, 182, 163, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ascribe-table-item-selectable {
|
||||||
|
cursor: default;
|
||||||
|
}
|
21
sass/ascribe_textarea.scss
Normal file
21
sass/ascribe_textarea.scss
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
.ascribe-textarea {
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ascribe-textarea-editable:hover {
|
||||||
|
border: 1px solid #AAA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ascribe-pre{
|
||||||
|
word-break: break-word;
|
||||||
|
/* white-space: pre-wrap; */
|
||||||
|
white-space: -moz-pre-wrap;
|
||||||
|
white-space: -pre-wrap;
|
||||||
|
white-space: -o-pre-wrap;
|
||||||
|
/* word-wrap: break-word; */
|
||||||
|
font-family: inherit;
|
||||||
|
text-align: justify;
|
||||||
|
background-color: white;
|
||||||
|
}
|
@ -9,10 +9,12 @@ $BASE_URL: '<%= BASE_URL %>';
|
|||||||
@import '../node_modules/react-datepicker/dist/react-datepicker';
|
@import '../node_modules/react-datepicker/dist/react-datepicker';
|
||||||
@import './ascribe-fonts/style';
|
@import './ascribe-fonts/style';
|
||||||
@import './ascribe-fonts/ascribe-fonts';
|
@import './ascribe-fonts/ascribe-fonts';
|
||||||
|
@import 'ascribe_table';
|
||||||
@import 'ascribe_accordion_list';
|
@import 'ascribe_accordion_list';
|
||||||
@import 'ascribe_piece_list_bulk_modal';
|
@import 'ascribe_piece_list_bulk_modal';
|
||||||
@import 'ascribe_piece_list_toolbar';
|
@import 'ascribe_piece_list_toolbar';
|
||||||
@import 'ascribe_edition';
|
@import 'ascribe_edition';
|
||||||
|
@import 'ascribe_textarea';
|
||||||
@import 'ascribe_media_player';
|
@import 'ascribe_media_player';
|
||||||
@import 'ascribe-global-notification';
|
@import 'ascribe-global-notification';
|
||||||
@import 'offset_right';
|
@import 'offset_right';
|
||||||
@ -28,6 +30,10 @@ $BASE_URL: '<%= BASE_URL %>';
|
|||||||
border-top:0;
|
border-top:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.navbar-right {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.clear-paddings {
|
.clear-paddings {
|
||||||
padding-left:0;
|
padding-left:0;
|
||||||
padding-right:0;
|
padding-right:0;
|
||||||
@ -44,45 +50,6 @@ $BASE_URL: '<%= BASE_URL %>';
|
|||||||
float: none;
|
float: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ascribe-table {
|
|
||||||
margin-bottom:0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ascribe-table-header-column > span {
|
|
||||||
display: table-cell;
|
|
||||||
vertical-align: middle;
|
|
||||||
font-family: 'Source Sans Pro';
|
|
||||||
font-weight: 600;
|
|
||||||
color: #424242;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ascribe-table-header-column > span > .glyphicon {
|
|
||||||
font-size: .5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ascribe-table-item-column {
|
|
||||||
display: table;
|
|
||||||
font-family: 'Source Sans Pro';
|
|
||||||
font-size: .8em;
|
|
||||||
height:3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ascribe-table-item-column > * {
|
|
||||||
display: table-cell;
|
|
||||||
vertical-align: middle;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ascribe-table-item-selected {
|
|
||||||
background-color: rgba(2, 182, 163, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.ascribe-table-item-selectable {
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-margin {
|
.no-margin {
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
@ -95,7 +62,6 @@ $BASE_URL: '<%= BASE_URL %>';
|
|||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
font-family: sans-serif !important;
|
font-family: sans-serif !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-ascribe, .btn-ascribe-inv:active, .btn-ascribe-inv:hover {
|
.btn-ascribe, .btn-ascribe-inv:active, .btn-ascribe-inv:hover {
|
||||||
@ -125,7 +91,6 @@ $BASE_URL: '<%= BASE_URL %>';
|
|||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
font-family: sans-serif !important;
|
font-family: sans-serif !important;
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-ascribe-green, .btn-ascribe-green-inv:active, .btn-ascribe-green-inv:hover {
|
.btn-ascribe-green, .btn-ascribe-green-inv:active, .btn-ascribe-green-inv:hover {
|
||||||
@ -144,7 +109,6 @@ $BASE_URL: '<%= BASE_URL %>';
|
|||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.ascribe-detail-title {
|
.ascribe-detail-title {
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
margin-bottom: -0.2em;
|
margin-bottom: -0.2em;
|
||||||
|
Loading…
Reference in New Issue
Block a user