1
0
mirror of https://github.com/ascribe/onion.git synced 2024-12-22 17:33:14 +01:00

add details to piece detail page

This commit is contained in:
Tim Daubenschütz 2015-06-05 14:22:02 +02:00
parent a7478cdcb5
commit 76a41a23b9
6 changed files with 189 additions and 58 deletions

View File

@ -2,7 +2,6 @@
import React from 'react'; import React from 'react';
/* /*
Is this even used somewhere? Is this even used somewhere?
Deprecate? 5.6.15 - Tim Deprecate? 5.6.15 - Tim

View File

@ -11,7 +11,7 @@ import InputDate from './input_date';
import InputTextArea from './input_textarea'; import InputTextArea from './input_textarea';
import OwnershipFetcher from '../../fetchers/ownership_fetcher'; import OwnershipFetcher from '../../fetchers/ownership_fetcher';
import ButtonSubmitOrClose from './button_submit_close'; import ButtonSubmitOrClose from '../ascribe_buttons/button_submit_close';
let LoanForm = React.createClass({ let LoanForm = React.createClass({

View File

@ -10,30 +10,77 @@ import ResourceViewer from './ascribe_media/resource_viewer';
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 classNames from 'classnames';
/** /**
* This is the component that implements display-specific functionality * This is the component that implements display-specific functionality
*/ */
let Edition = React.createClass({ let Edition = React.createClass({
propTypes: { propTypes: {
edition: React.PropTypes.object, edition: React.PropTypes.object,
currentUser: React.PropTypes.object currentUser: React.PropTypes.object,
deleteEdition: React.PropTypes.func
}, },
render() { render() {
let thumbnail = this.props.edition.thumbnail; let thumbnail = this.props.edition.thumbnail;
let mimetype = this.props.edition.digital_work.mime; let mimetype = this.props.edition.digital_work.mime;
let bitcoinIdValue = (
<a target="_blank" href={'https://www.blocktrail.com/BTC/address/' + this.props.edition.bitcoin_id}>{this.props.edition.bitcoin_id}</a>
);
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>
);
return ( return (
<div> <div>
<div className="col-sm-6"> <div className="col-sm-5">
<ResourceViewer thumbnail={thumbnail} <ResourceViewer thumbnail={thumbnail}
mimetype={mimetype} mimetype={mimetype}/>
/>
</div> </div>
<div className="col-sm-6"> <div className="col-sm-7">
<EditionHeader edition={this.props.edition}/> <EditionHeader edition={this.props.edition}/>
<EditionSummary edition={this.props.edition} currentUser={ this.props.currentUser }/> <EditionSummary
<EditionDetails edition={this.props.edition} currentUser={ this.props.currentUser }/> edition={this.props.edition}
currentUser={ this.props.currentUser }/>
<CollapsibleEditionDetails
title="Provenance/Ownership History"
show={this.props.edition.ownership_history && this.props.edition.ownership_history.length > 0}>
<EditionDetailHistoryIterator
history={this.props.edition.ownership_history} />
</CollapsibleEditionDetails>
<CollapsibleEditionDetails
title="Loan History"
show={this.props.edition.loan_history && this.props.edition.loan_history.length > 0}>
<EditionDetailHistoryIterator
history={this.props.edition.loan_history} />
</CollapsibleEditionDetails>
<CollapsibleEditionDetails
title="SPOOL Details">
<EditionDetailProperty
label="Artwork ID"
value={bitcoinIdValue} />
<EditionDetailProperty
label="Hash of Artwork, title, etc"
value={hashOfArtwork} />
<EditionDetailProperty
label="Owned by SPOOL address"
value="MISSING IN /editions/<id> RESOURCE!" />
</CollapsibleEditionDetails>
<CollapsibleEditionDetails
title="Delete Actions">
<Button
bsStyle="danger"
onClick={this.props.deleteEdition}>
Remove this artwork from your list
</Button>
</CollapsibleEditionDetails>
</div> </div>
</div> </div>
@ -50,9 +97,9 @@ let EditionHeader = React.createClass({
var titleHtml = <div className="ascribe-detail-title">{this.props.edition.title}</div>; var titleHtml = <div className="ascribe-detail-title">{this.props.edition.title}</div>;
return ( return (
<div className="ascribe-detail-header"> <div className="ascribe-detail-header">
<EditionDetailProperty label="title" value={titleHtml} /> <EditionDetailProperty label="TITLE" value={titleHtml} />
<EditionDetailProperty label="by" value={this.props.edition.artist_name} /> <EditionDetailProperty label="BY" value={this.props.edition.artist_name} />
<EditionDetailProperty label="date" value={ this.props.edition.date_created.slice(0, 4) } /> <EditionDetailProperty label="DATE" value={ this.props.edition.date_created.slice(0, 4) } />
<hr/> <hr/>
</div> </div>
); );
@ -73,10 +120,10 @@ let EditionSummary = React.createClass({
render() { render() {
return ( return (
<div className="ascribe-detail-header"> <div className="ascribe-detail-header">
<EditionDetailProperty label="edition" <EditionDetailProperty label="EDITION"
value={this.props.edition.edition_number + ' of ' + this.props.edition.num_editions} /> value={this.props.edition.edition_number + ' of ' + this.props.edition.num_editions} />
<EditionDetailProperty label="id" value={ this.props.edition.bitcoin_id } /> <EditionDetailProperty label="ID" value={ this.props.edition.bitcoin_id } />
<EditionDetailProperty label="owner" value={ this.props.edition.owner } /> <EditionDetailProperty label="OWNER" value={ this.props.edition.owner } />
<br/> <br/>
<AclButtonList <AclButtonList
availableAcls={this.props.edition.acl} availableAcls={this.props.edition.acl}
@ -89,50 +136,78 @@ let EditionSummary = React.createClass({
} }
}); });
let EditionDetails = React.createClass({ let CollapsibleEditionDetails = React.createClass({
handleSuccess(){ propTypes: {
EditionActions.fetchOne(this.props.edition.id); title: React.PropTypes.string,
children: React.PropTypes.oneOfType([
React.PropTypes.object,
React.PropTypes.array
]),
show: React.PropTypes.bool
}, },
render() {
return (
<div className="ascribe-detail-header">
<CollapsibleParagraph>
Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
</CollapsibleParagraph>
<hr/>
</div>
);
getDefaultProps() {
return {
show: true
};
},
render() {
if(this.props.show) {
return (
<div className="ascribe-detail-header">
<CollapsibleParagraph title={this.props.title}>
{this.props.children}
</CollapsibleParagraph>
<hr/>
</div>
);
} else {
return null;
}
} }
}); });
let CollapsibleParagraph = React.createClass({ const CollapsibleParagraph = React.createClass({
mixins: [CollapsibleMixin],
getCollapsibleDOMNode(){ propTypes: {
return React.findDOMNode(this.refs.panel); title: React.PropTypes.string,
}, children: React.PropTypes.oneOfType([
React.PropTypes.object,
React.PropTypes.array
])
},
getCollapsibleDimensionValue(){ mixins: [CollapsibleMixin],
return React.findDOMNode(this.refs.panel).scrollHeight;
},
onHandleToggle(e){ getCollapsibleDOMNode(){
e.preventDefault(); return React.findDOMNode(this.refs.panel);
this.setState({expanded:!this.state.expanded}); },
},
render(){ getCollapsibleDimensionValue(){
let text = this.isExpanded() ? 'Hide' : 'Show'; return React.findDOMNode(this.refs.panel).scrollHeight;
return ( },
<div>
<Button onClick={this.onHandleToggle}>{text} Content</Button> onHandleToggle(e){
<div ref='panel'> e.preventDefault();
{this.props.children} this.setState({expanded: !this.state.expanded});
</div> },
</div>
); render(){
} let styles = this.getCollapsibleClassSet();
let text = this.isExpanded() ? 'Hide' : 'Show';
return (
<div className="ascribe-edition-collapsible-wrapper">
<div onClick={this.onHandleToggle}>
<span>{this.props.title} </span>
<a>{text}</a>
</div>
<div ref='panel' className={classNames(styles) + ' ascribe-edition-collapible-content'}>
{this.props.children}
</div>
</div>
);
}
}); });
@ -142,17 +217,28 @@ let EditionDetailProperty = React.createClass({
value: React.PropTypes.oneOfType([ value: React.PropTypes.oneOfType([
React.PropTypes.string, React.PropTypes.string,
React.PropTypes.element React.PropTypes.element
]) ]),
separator: React.PropTypes.string,
labelClassName: React.PropTypes.string,
valueClassName: React.PropTypes.string
},
getDefaultProps() {
return {
separator: ':',
labelClassName: 'col-xs-5 col-sm-5 col-md-5 col-lg-5',
valueClassName: 'col-xs-7 col-sm-7 col-md-7 col-lg-7'
};
}, },
render() { render() {
return ( return (
<div className="row ascribe-detail-property"> <div className="row ascribe-detail-property">
<div className="row-same-height"> <div className="row-same-height">
<div className="col-xs-4 col-sm-3 col-xs-height col-bottom"> <div className={this.props.labelClassName + ' col-xs-height col-bottom'}>
<div>{ this.props.label }:</div> <div>{ this.props.label }{this.props.separator}</div>
</div> </div>
<div className="col-xs-8 col-sm-9 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>
</div> </div>
</div> </div>
@ -161,5 +247,29 @@ let EditionDetailProperty = React.createClass({
} }
}); });
let EditionDetailHistoryIterator = React.createClass({
propTypes: {
history: React.PropTypes.array
},
render() {
return (
<div>
{this.props.history.map((historicalEvent, i) => {
return (
<EditionDetailProperty
key={i}
label={historicalEvent[0]}
value={historicalEvent[1]}
labelClassName="col-xs-4 col-sm-4 col-md-4 col-lg-4"
valueClassName="col-xs-8 col-sm-8 col-md-8 col-lg-8"
separator="" />
);
})}
</div>
);
}
});
export default Edition; export default Edition;

View File

@ -36,12 +36,17 @@ let EditionContainer = React.createClass({
UserStore.unlisten(this.onChange); UserStore.unlisten(this.onChange);
}, },
deleteEdition() {
},
render() { render() {
if('title' in this.state.edition) { if('title' in this.state.edition) {
return ( return (
<Edition <Edition
edition={this.state.edition} edition={this.state.edition}
currentUser={this.state.currentUser} /> currentUser={this.state.currentUser}
deleteEdition={this.deleteEdition}/>
); );
} else { } else {
return ( return (

19
sass/ascribe_edition.scss Normal file
View File

@ -0,0 +1,19 @@
.ascribe-edition-collapsible-wrapper {
vertical-align: bottom;
width:100%;
}
.ascribe-edition-collapsible-wrapper > div:first-child {
width:100%;
cursor:pointer;
}
.ascribe-edition-collapsible-wrapper > div > span {
font-size:1.4em;
margin-right: .5em;
}
.ascribe-edition-collapible-content {
width:100%;
margin-top: 1em;
}

View File

@ -9,6 +9,7 @@
@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 'offset_right'; @import 'offset_right';
.hidden { .hidden {
@ -146,9 +147,6 @@
.ascribe-detail-property { .ascribe-detail-property {
padding-bottom: 0.4em; padding-bottom: 0.4em;
} }
.ascribe-detail-property > .row-same-height > .col-xs-4 {
text-transform: uppercase;
}
.input-text-ascribe, .input-text-ascribe,
.datepicker__input { .datepicker__input {