1
0
mirror of https://github.com/ascribe/onion.git synced 2024-11-15 09:35:10 +01:00

Merged in AD-806-webapp-users-cannot-withdraw-a-pe (pull request #88)

withdraw consign
This commit is contained in:
diminator 2015-10-01 09:49:56 +02:00
commit 708cf1b3da
3 changed files with 184 additions and 119 deletions

View File

@ -6,15 +6,11 @@ import Router from 'react-router';
import Row from 'react-bootstrap/lib/Row'; import Row from 'react-bootstrap/lib/Row';
import Col from 'react-bootstrap/lib/Col'; import Col from 'react-bootstrap/lib/Col';
import Glyphicon from 'react-bootstrap/lib/Glyphicon'; import Glyphicon from 'react-bootstrap/lib/Glyphicon';
import Button from 'react-bootstrap/lib/Button';
import UserActions from '../../actions/user_actions'; import UserActions from '../../actions/user_actions';
import UserStore from '../../stores/user_store'; import UserStore from '../../stores/user_store';
import CoaActions from '../../actions/coa_actions'; import CoaActions from '../../actions/coa_actions';
import CoaStore from '../../stores/coa_store'; import CoaStore from '../../stores/coa_store';
import PieceListActions from '../../actions/piece_list_actions';
import PieceListStore from '../../stores/piece_list_store';
import EditionListActions from '../../actions/edition_list_actions';
import HistoryIterator from './history_iterator'; import HistoryIterator from './history_iterator';
@ -28,13 +24,7 @@ import EditionDetailProperty from './detail_property';
import LicenseDetail from './license_detail'; import LicenseDetail from './license_detail';
import EditionFurtherDetails from './further_details'; import EditionFurtherDetails from './further_details';
import ListRequestActions from './../ascribe_forms/list_form_request_actions'; import EditionActionPanel from './edition_action_panel';
import AclButtonList from './../ascribe_buttons/acl_button_list';
import UnConsignRequestButton from './../ascribe_buttons/unconsign_request_button';
import DeleteButton from '../ascribe_buttons/delete_button';
import GlobalNotificationModel from '../../models/global_notification_model';
import GlobalNotificationActions from '../../actions/global_notification_actions';
import Note from './note'; import Note from './note';
@ -42,7 +32,6 @@ import ApiUrls from '../../constants/api_urls';
import AppConstants from '../../constants/application_constants'; import AppConstants from '../../constants/application_constants';
import { getLangText } from '../../utils/lang_utils'; import { getLangText } from '../../utils/lang_utils';
import { mergeOptions } from '../../utils/general_utils';
let Link = Router.Link; let Link = Router.Link;
/** /**
@ -57,15 +46,11 @@ let Edition = React.createClass({
mixins: [Router.Navigation], mixins: [Router.Navigation],
getInitialState() { getInitialState() {
return mergeOptions( return UserStore.getState();
UserStore.getState(),
PieceListStore.getState()
);
}, },
componentDidMount() { componentDidMount() {
UserStore.listen(this.onChange); UserStore.listen(this.onChange);
PieceListStore.listen(this.onChange);
UserActions.fetchCurrentUser(); UserActions.fetchCurrentUser();
}, },
@ -80,31 +65,12 @@ let Edition = React.createClass({
CoaActions.flushCoa(); CoaActions.flushCoa();
UserStore.unlisten(this.onChange); UserStore.unlisten(this.onChange);
PieceListStore.unlisten(this.onChange);
}, },
onChange(state) { onChange(state) {
this.setState(state); this.setState(state);
}, },
handleDeleteSuccess(response) {
this.refreshCollection();
EditionListActions.closeAllEditionLists();
EditionListActions.clearAllEditionSelections();
let notification = new GlobalNotificationModel(response.notification, 'success');
GlobalNotificationActions.appendGlobalNotification(notification);
this.transitionTo('pieces');
},
refreshCollection() {
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
EditionListActions.refreshEditionList({pieceId: this.props.edition.parent});
},
render() { render() {
return ( return (
<Row> <Row>
@ -121,12 +87,9 @@ let Edition = React.createClass({
<hr/> <hr/>
</div> </div>
<EditionSummary <EditionSummary
handleSuccess={this.props.loadEdition}
refreshCollection={this.refreshCollection}
currentUser={this.state.currentUser}
edition={this.props.edition} edition={this.props.edition}
handleDeleteSuccess={this.handleDeleteSuccess}/> currentUser={this.state.currentUser}
handleSuccess={this.props.loadEdition}/>
<CollapsibleParagraph <CollapsibleParagraph
title={getLangText('Certificate of Authenticity')} title={getLangText('Certificate of Authenticity')}
show={this.props.edition.acl.acl_coa === true}> show={this.props.edition.acl.acl_coa === true}>
@ -209,29 +172,14 @@ let Edition = React.createClass({
let EditionSummary = React.createClass({ let EditionSummary = React.createClass({
propTypes: { propTypes: {
edition: React.PropTypes.object, edition: React.PropTypes.object,
handleSuccess: React.PropTypes.func,
currentUser: React.PropTypes.object, currentUser: React.PropTypes.object,
handleDeleteSuccess: React.PropTypes.func, handleSuccess: React.PropTypes.func
refreshCollection: React.PropTypes.func
},
getTransferWithdrawData(){
return {'bitcoin_id': this.props.edition.bitcoin_id};
}, },
handleSuccess() { handleSuccess() {
this.props.refreshCollection();
this.props.handleSuccess(); this.props.handleSuccess();
}, },
showNotification(response){
this.props.handleSuccess();
if (response){
let notification = new GlobalNotificationModel(response.notification, 'success');
GlobalNotificationActions.appendGlobalNotification(notification);
}
},
getStatus(){ getStatus(){
let status = null; let status = null;
if (this.props.edition.status.length > 0){ if (this.props.edition.status.length > 0){
@ -246,79 +194,26 @@ let EditionSummary = React.createClass({
return status; return status;
}, },
getActions(){
let actions = null;
if (this.props.edition &&
this.props.edition.notifications &&
this.props.edition.notifications.length > 0){
actions = (
<ListRequestActions
pieceOrEditions={[this.props.edition]}
currentUser={this.props.currentUser}
handleSuccess={this.showNotification}
notifications={this.props.edition.notifications}/>);
}
else {
let withdrawButton = null;
if (this.props.edition.status.length > 0 && this.props.edition.pending_new_owner && this.props.edition.acl.acl_withdraw_transfer) {
withdrawButton = (
<Form
url={ApiUrls.ownership_transfers_withdraw}
getFormData={this.getTransferWithdrawData}
handleSuccess={this.showNotification}
className='inline'
isInline={true}>
<Button bsStyle="danger" className="btn-delete pull-center" bsSize="small" type="submit">
WITHDRAW TRANSFER
</Button>
</Form>
);
}
let unconsignRequestButton = null;
if (this.props.edition.acl.acl_request_unconsign) {
unconsignRequestButton = (
<UnConsignRequestButton
currentUser={this.props.currentUser}
edition={this.props.edition}
handleSuccess={this.props.handleSuccess} />
);
}
actions = (
<Row>
<Col md={12}>
<AclButtonList
className="text-center ascribe-button-list"
availableAcls={this.props.edition.acl}
editions={[this.props.edition]}
handleSuccess={this.handleSuccess}>
{withdrawButton}
<DeleteButton
handleSuccess={this.props.handleDeleteSuccess}
editions={[this.props.edition]}/>
{unconsignRequestButton}
</AclButtonList>
</Col>
</Row>);
}
return actions;
},
render() { render() {
let { edition, currentUser } = this.props;
return ( return (
<div className="ascribe-detail-header"> <div className="ascribe-detail-header">
<EditionDetailProperty <EditionDetailProperty
label={getLangText('EDITION')} label={getLangText('EDITION')}
value={this.props.edition.edition_number + ' ' + getLangText('of') + ' ' + this.props.edition.num_editions} /> value={ edition.edition_number + ' ' + getLangText('of') + ' ' + edition.num_editions} />
<EditionDetailProperty <EditionDetailProperty
label={getLangText('ID')} label={getLangText('ID')}
value={ this.props.edition.bitcoin_id } value={ edition.bitcoin_id }
ellipsis={true} /> ellipsis={true} />
<EditionDetailProperty <EditionDetailProperty
label={getLangText('OWNER')} label={getLangText('OWNER')}
value={ this.props.edition.owner } /> value={ edition.owner } />
<LicenseDetail license={this.props.edition.license_type}/> <LicenseDetail license={edition.license_type}/>
{this.getStatus()} {this.getStatus()}
{this.getActions()} <EditionActionPanel
edition={edition}
currentUser={currentUser}
handleSuccess={this.handleSuccess} />
<hr/> <hr/>
</div> </div>
); );

View File

@ -0,0 +1,169 @@
'use strict';
import React from 'react';
import Router from 'react-router';
import Row from 'react-bootstrap/lib/Row';
import Col from 'react-bootstrap/lib/Col';
import Button from 'react-bootstrap/lib/Button';
import EditionListActions from '../../actions/edition_list_actions';
import PieceListActions from '../../actions/piece_list_actions';
import PieceListStore from '../../stores/piece_list_store';
import Form from './../ascribe_forms/form';
import Property from './../ascribe_forms/property';
import ListRequestActions from './../ascribe_forms/list_form_request_actions';
import AclButtonList from './../ascribe_buttons/acl_button_list';
import UnConsignRequestButton from './../ascribe_buttons/unconsign_request_button';
import DeleteButton from '../ascribe_buttons/delete_button';
import GlobalNotificationModel from '../../models/global_notification_model';
import GlobalNotificationActions from '../../actions/global_notification_actions';
import AclProxy from '../acl_proxy';
import ApiUrls from '../../constants/api_urls';
import { getLangText } from '../../utils/lang_utils';
/*
A component that handles all the actions inside of the edition detail
handleSuccess requires a loadEdition action (could be refactored)
*/
let EditionActionPanel = React.createClass({
propTypes: {
edition: React.PropTypes.object,
currentUser: React.PropTypes.object,
handleSuccess: React.PropTypes.func
},
mixins: [Router.Navigation],
getInitialState() {
return PieceListStore.getState();
},
componentDidMount() {
PieceListStore.listen(this.onChange);
},
componentWillUnmount() {
PieceListStore.unlisten(this.onChange);
},
onChange(state) {
this.setState(state);
},
handleDeleteSuccess(response) {
this.refreshCollection();
EditionListActions.closeAllEditionLists();
EditionListActions.clearAllEditionSelections();
let notification = new GlobalNotificationModel(response.notification, 'success');
GlobalNotificationActions.appendGlobalNotification(notification);
this.transitionTo('pieces');
},
refreshCollection() {
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
EditionListActions.refreshEditionList({pieceId: this.props.edition.parent});
},
handleSuccess(response){
this.refreshCollection();
this.props.handleSuccess();
if (response){
let notification = new GlobalNotificationModel(response.notification, 'success');
GlobalNotificationActions.appendGlobalNotification(notification);
}
},
render(){
let {edition, currentUser} = this.props;
if (edition &&
edition.notifications &&
edition.notifications.length > 0){
return (
<ListRequestActions
pieceOrEditions={[edition]}
currentUser={currentUser}
handleSuccess={this.handleSuccess}
notifications={edition.notifications}/>);
}
else {
return (
<Row>
<Col md={12}>
<AclButtonList
className="text-center ascribe-button-list"
availableAcls={edition.acl}
editions={[edition]}
handleSuccess={this.handleSuccess}>
<AclProxy
aclObject={edition.acl}
aclName="acl_withdraw_transfer">
<Form
url={ApiUrls.ownership_transfers_withdraw}
handleSuccess={this.handleSuccess}
className='inline'
isInline={true}>
<Property
name="bitcoin_id"
hidden={true}>
<input
type="text"
value={edition.bitcoin_id} />
</Property>
<Button bsStyle="danger" className="btn-delete pull-center" bsSize="small" type="submit">
{getLangText('WITHDRAW TRANSFER')}
</Button>
</Form>
</AclProxy>
<AclProxy
aclObject={edition.acl}
aclName="acl_withdraw_consign">
<Form
url={ApiUrls.ownership_consigns_withdraw}
handleSuccess={this.handleSuccess}
className='inline'
isInline={true}>
<Property
name="bitcoin_id"
hidden={true}>
<input
type="text"
value={edition.bitcoin_id} />
</Property>
<Button bsStyle="danger" className="btn-delete pull-center" bsSize="small" type="submit">
{getLangText('WITHDRAW CONSIGN')}
</Button>
</Form>
</AclProxy>
<AclProxy
aclObject={edition.acl}
aclName="acl_request_unconsign">
<UnConsignRequestButton
currentUser={currentUser}
edition={edition}
handleSuccess={this.handleSuccess} />
</AclProxy>
<DeleteButton
handleSuccess={this.handleDeleteSuccess}
editions={[edition]}/>
</AclButtonList>
</Col>
</Row>
);
}
}
});
export default EditionActionPanel;

View File

@ -38,6 +38,7 @@ let ApiUrls = {
'ownership_consigns': AppConstants.apiEndpoint + 'ownership/consigns/', 'ownership_consigns': AppConstants.apiEndpoint + 'ownership/consigns/',
'ownership_consigns_confirm': AppConstants.apiEndpoint + 'ownership/consigns/confirm/', 'ownership_consigns_confirm': AppConstants.apiEndpoint + 'ownership/consigns/confirm/',
'ownership_consigns_deny': AppConstants.apiEndpoint + 'ownership/consigns/deny/', 'ownership_consigns_deny': AppConstants.apiEndpoint + 'ownership/consigns/deny/',
'ownership_consigns_withdraw': AppConstants.apiEndpoint + 'ownership/consigns/withdraw/',
'ownership_loans_pieces': AppConstants.apiEndpoint + 'ownership/loans/pieces/', 'ownership_loans_pieces': AppConstants.apiEndpoint + 'ownership/loans/pieces/',
'ownership_loans_pieces_confirm': AppConstants.apiEndpoint + 'ownership/loans/pieces/confirm/', 'ownership_loans_pieces_confirm': AppConstants.apiEndpoint + 'ownership/loans/pieces/confirm/',
'ownership_loans_pieces_deny': AppConstants.apiEndpoint + 'ownership/loans/pieces/deny/', 'ownership_loans_pieces_deny': AppConstants.apiEndpoint + 'ownership/loans/pieces/deny/',