1
0
mirror of https://github.com/ascribe/onion.git synced 2024-06-30 13:41:57 +02:00

Carry down currentUser as prop to MediaContainer instead of adding state

This commit is contained in:
Brett Sun 2015-12-16 17:49:30 +01:00
parent 875e98dd3b
commit f2f775f20c
6 changed files with 160 additions and 160 deletions

View File

@ -1,7 +1,7 @@
'use strict'; 'use strict';
import React from 'react'; import React from 'react';
import { Link, History } from 'react-router'; import { Link } from 'react-router';
import Moment from 'moment'; import Moment from 'moment';
import Row from 'react-bootstrap/lib/Row'; import Row from 'react-bootstrap/lib/Row';
@ -44,8 +44,6 @@ let Edition = React.createClass({
loadEdition: React.PropTypes.func loadEdition: React.PropTypes.func
}, },
mixins: [History],
getDefaultProps() { getDefaultProps() {
return { return {
furtherDetailsType: FurtherDetails furtherDetailsType: FurtherDetails
@ -53,98 +51,103 @@ let Edition = React.createClass({
}, },
render() { render() {
let FurtherDetailsType = this.props.furtherDetailsType; const {
actionPanelButtonListType,
coaError,
currentUser,
edition,
furtherDetailsType: FurtherDetailsType,
loadEdition } = this.props;
return ( return (
<Row> <Row>
<Col md={6}> <Col md={6}>
<MediaContainer <MediaContainer
content={this.props.edition}/> content={edition}
currentUser={currentUser} />
</Col> </Col>
<Col md={6} className="ascribe-edition-details"> <Col md={6} className="ascribe-edition-details">
<div className="ascribe-detail-header"> <div className="ascribe-detail-header">
<hr style={{marginTop: 0}}/> <hr style={{marginTop: 0}}/>
<h1 className="ascribe-detail-title">{this.props.edition.title}</h1> <h1 className="ascribe-detail-title">{edition.title}</h1>
<EditionDetailProperty label="BY" value={this.props.edition.artist_name} /> <EditionDetailProperty label="BY" value={edition.artist_name} />
<EditionDetailProperty label="DATE" value={Moment(this.props.edition.date_created, 'YYYY-MM-DD').year()} /> <EditionDetailProperty label="DATE" value={Moment(edition.date_created, 'YYYY-MM-DD').year()} />
<hr/> <hr/>
</div> </div>
<EditionSummary <EditionSummary
actionPanelButtonListType={this.props.actionPanelButtonListType} actionPanelButtonListType={actionPanelButtonListType}
edition={this.props.edition} edition={edition}
currentUser={this.props.currentUser} currentUser={currentUser}
handleSuccess={this.props.loadEdition}/> handleSuccess={loadEdition}/>
<CollapsibleParagraph <CollapsibleParagraph
title={getLangText('Certificate of Authenticity')} title={getLangText('Certificate of Authenticity')}
show={this.props.edition.acl.acl_coa === true}> show={edition.acl.acl_coa === true}>
<CoaDetails <CoaDetails
coa={this.props.edition.coa} coa={edition.coa}
coaError={this.props.coaError} coaError={coaError}
editionId={this.props.edition.bitcoin_id}/> editionId={edition.bitcoin_id}/>
</CollapsibleParagraph> </CollapsibleParagraph>
<CollapsibleParagraph <CollapsibleParagraph
title={getLangText('Provenance/Ownership History')} title={getLangText('Provenance/Ownership History')}
show={this.props.edition.ownership_history && this.props.edition.ownership_history.length > 0}> show={edition.ownership_history && edition.ownership_history.length > 0}>
<HistoryIterator <HistoryIterator
history={this.props.edition.ownership_history} /> history={edition.ownership_history} />
</CollapsibleParagraph> </CollapsibleParagraph>
<CollapsibleParagraph <CollapsibleParagraph
title={getLangText('Consignment History')} title={getLangText('Consignment History')}
show={this.props.edition.consign_history && this.props.edition.consign_history.length > 0}> show={edition.consign_history && edition.consign_history.length > 0}>
<HistoryIterator <HistoryIterator
history={this.props.edition.consign_history} /> history={edition.consign_history} />
</CollapsibleParagraph> </CollapsibleParagraph>
<CollapsibleParagraph <CollapsibleParagraph
title={getLangText('Loan History')} title={getLangText('Loan History')}
show={this.props.edition.loan_history && this.props.edition.loan_history.length > 0}> show={edition.loan_history && edition.loan_history.length > 0}>
<HistoryIterator <HistoryIterator
history={this.props.edition.loan_history} /> history={edition.loan_history} />
</CollapsibleParagraph> </CollapsibleParagraph>
<CollapsibleParagraph <CollapsibleParagraph
title="Notes" title="Notes"
show={!!(this.props.currentUser.username show={!!(currentUser.username || edition.acl.acl_edit || edition.public_note)}>
|| this.props.edition.acl.acl_edit
|| this.props.edition.public_note)}>
<Note <Note
id={() => {return {'bitcoin_id': this.props.edition.bitcoin_id}; }} id={() => {return {'bitcoin_id': edition.bitcoin_id}; }}
label={getLangText('Personal note (private)')} label={getLangText('Personal note (private)')}
defaultValue={this.props.edition.private_note ? this.props.edition.private_note : null} defaultValue={edition.private_note ? edition.private_note : null}
placeholder={getLangText('Enter your comments ...')} placeholder={getLangText('Enter your comments ...')}
editable={true} editable={true}
successMessage={getLangText('Private note saved')} successMessage={getLangText('Private note saved')}
url={ApiUrls.note_private_edition} url={ApiUrls.note_private_edition}
currentUser={this.props.currentUser}/> currentUser={currentUser}/>
<Note <Note
id={() => {return {'bitcoin_id': this.props.edition.bitcoin_id}; }} id={() => {return {'bitcoin_id': edition.bitcoin_id}; }}
label={getLangText('Personal note (public)')} label={getLangText('Personal note (public)')}
defaultValue={this.props.edition.public_note ? this.props.edition.public_note : null} defaultValue={edition.public_note ? edition.public_note : null}
placeholder={getLangText('Enter your comments ...')} placeholder={getLangText('Enter your comments ...')}
editable={!!this.props.edition.acl.acl_edit} editable={!!edition.acl.acl_edit}
show={!!this.props.edition.public_note || !!this.props.edition.acl.acl_edit} show={!!edition.public_note || !!edition.acl.acl_edit}
successMessage={getLangText('Public edition note saved')} successMessage={getLangText('Public edition note saved')}
url={ApiUrls.note_public_edition} url={ApiUrls.note_public_edition}
currentUser={this.props.currentUser}/> currentUser={currentUser}/>
</CollapsibleParagraph> </CollapsibleParagraph>
<CollapsibleParagraph <CollapsibleParagraph
title={getLangText('Further Details')} title={getLangText('Further Details')}
show={this.props.edition.acl.acl_edit show={edition.acl.acl_edit ||
|| Object.keys(this.props.edition.extra_data).length > 0 Object.keys(edition.extra_data).length > 0 ||
|| this.props.edition.other_data.length > 0}> edition.other_data.length > 0}>
<FurtherDetailsType <FurtherDetailsType
editable={this.props.edition.acl.acl_edit} editable={edition.acl.acl_edit}
pieceId={this.props.edition.parent} pieceId={edition.parent}
extraData={this.props.edition.extra_data} extraData={edition.extra_data}
otherData={this.props.edition.other_data} otherData={edition.other_data}
handleSuccess={this.props.loadEdition} /> handleSuccess={loadEdition} />
</CollapsibleParagraph> </CollapsibleParagraph>
<CollapsibleParagraph <CollapsibleParagraph
title={getLangText('SPOOL Details')}> title={getLangText('SPOOL Details')}>
<SpoolDetails <SpoolDetails
edition={this.props.edition} /> edition={edition} />
</CollapsibleParagraph> </CollapsibleParagraph>
</Col> </Col>
</Row> </Row>

View File

@ -14,10 +14,6 @@ import CollapsibleButton from './../ascribe_collapsible/collapsible_button';
import AclProxy from '../acl_proxy'; import AclProxy from '../acl_proxy';
import UserActions from '../../actions/user_actions';
import UserStore from '../../stores/user_store';
import { mergeOptions } from '../../utils/general_utils.js';
import { getLangText } from '../../utils/lang_utils.js'; import { getLangText } from '../../utils/lang_utils.js';
const EMBED_IFRAME_HEIGHT = { const EMBED_IFRAME_HEIGHT = {
@ -28,25 +24,22 @@ const EMBED_IFRAME_HEIGHT = {
let MediaContainer = React.createClass({ let MediaContainer = React.createClass({
propTypes: { propTypes: {
content: React.PropTypes.object, content: React.PropTypes.object,
currentUser: React.PropTypes.object,
refreshObject: React.PropTypes.func refreshObject: React.PropTypes.func
}, },
getInitialState() { getInitialState() {
return mergeOptions( return {
UserStore.getState(), timerId: null
{ };
timerId: null
});
}, },
componentDidMount() { componentDidMount() {
UserStore.listen(this.onChange);
UserActions.fetchCurrentUser();
if (!this.props.content.digital_work) { if (!this.props.content.digital_work) {
return; return;
} }
let isEncoding = this.props.content.digital_work.isEncoding;
const isEncoding = this.props.content.digital_work.isEncoding;
if (this.props.content.digital_work.mime === 'video' && typeof isEncoding === 'number' && isEncoding !== 100 && !this.state.timerId) { if (this.props.content.digital_work.mime === 'video' && typeof isEncoding === 'number' && isEncoding !== 100 && !this.state.timerId) {
let timerId = window.setInterval(this.props.refreshObject, 10000); let timerId = window.setInterval(this.props.refreshObject, 10000);
this.setState({timerId: timerId}); this.setState({timerId: timerId});
@ -60,22 +53,16 @@ let MediaContainer = React.createClass({
}, },
componentWillUnmount() { componentWillUnmount() {
UserStore.unlisten(this.onChange);
window.clearInterval(this.state.timerId); window.clearInterval(this.state.timerId);
}, },
onChange(state) {
this.setState(state);
},
render() { render() {
const { content } = this.props; const { content, currentUser } = this.props;
// Pieces and editions are joined to the user by a foreign key in the database, so // Pieces and editions are joined to the user by a foreign key in the database, so
// the information in content will be updated if a user updates their username. // the information in content will be updated if a user updates their username.
// We also force uniqueness of usernames, so this check is safe to dtermine if the // We also force uniqueness of usernames, so this check is safe to dtermine if the
// content was registered by the current user. // content was registered by the current user.
const didUserRegisterContent = this.state.currentUser && (this.state.currentUser.username === content.user_registered); const didUserRegisterContent = currentUser && (currentUser.username === content.user_registered);
let thumbnail = content.thumbnail.thumbnail_sizes && content.thumbnail.thumbnail_sizes['600x600'] ? let thumbnail = content.thumbnail.thumbnail_sizes && content.thumbnail.thumbnail_sizes['600x600'] ?
content.thumbnail.thumbnail_sizes['600x600'] : content.thumbnail.url_safe; content.thumbnail.thumbnail_sizes['600x600'] : content.thumbnail.url_safe;
@ -125,8 +112,12 @@ let MediaContainer = React.createClass({
show={['video', 'audio', 'image'].indexOf(mimetype) === -1 || content.acl.acl_download} show={['video', 'audio', 'image'].indexOf(mimetype) === -1 || content.acl.acl_download}
aclObject={content.acl} aclObject={content.acl}
aclName="acl_download"> aclName="acl_download">
<Button bsSize="xsmall" className="ascribe-margin-1px" href={this.props.content.digital_work.url} target="_blank"> <Button
Download .{mimetype} <Glyphicon glyph="cloud-download"/> bsSize="xsmall"
className="ascribe-margin-1px"
href={content.digital_work.url}
target="_blank">
{getLangText('Download')} .{mimetype} <Glyphicon glyph="cloud-download"/>
</Button> </Button>
</AclProxy> </AclProxy>
{embed} {embed}

View File

@ -16,10 +16,10 @@ import MediaContainer from './media_container';
let Piece = React.createClass({ let Piece = React.createClass({
propTypes: { propTypes: {
piece: React.PropTypes.object, piece: React.PropTypes.object,
currentUser: React.PropTypes.object,
header: React.PropTypes.object, header: React.PropTypes.object,
subheader: React.PropTypes.object, subheader: React.PropTypes.object,
buttons: React.PropTypes.object, buttons: React.PropTypes.object,
loadPiece: React.PropTypes.func,
children: React.PropTypes.oneOfType([ children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element), React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element React.PropTypes.element
@ -32,20 +32,22 @@ let Piece = React.createClass({
}, },
render() { render() {
const { buttons, children, currentUser, header, piece, subheader } = this.props;
return ( return (
<Row> <Row>
<Col md={6}> <Col md={6}>
<MediaContainer <MediaContainer
refreshObject={this.updateObject} content={piece}
content={this.props.piece}/> currentUser={currentUser}
refreshObject={this.updateObject} />
</Col> </Col>
<Col md={6} className="ascribe-edition-details"> <Col md={6} className="ascribe-edition-details">
{this.props.header} {header}
{this.props.subheader} {subheader}
{this.props.buttons} {buttons}
{this.props.children}
{children}
</Col> </Col>
</Row> </Row>
); );

View File

@ -247,76 +247,76 @@ let PieceContainer = React.createClass({
}, },
render() { render() {
if (this.state.piece && this.state.piece.id) { const { furtherDetailsType: FurtherDetailsType } = this.props;
let FurtherDetailsType = this.props.furtherDetailsType; const { currentUser, piece } = this.state;
setDocumentTitle([this.state.piece.artist_name, this.state.piece.title].join(', '));
if (piece && piece.id) {
setDocumentTitle([piece.artist_name, piece.title].join(', '));
return ( return (
<Piece <Piece
piece={this.state.piece} piece={piece}
loadPiece={this.loadPiece} currentUser={currentUser}
header={ header={
<div className="ascribe-detail-header"> <div className="ascribe-detail-header">
<hr style={{marginTop: 0}}/> <hr style={{marginTop: 0}}/>
<h1 className="ascribe-detail-title">{this.state.piece.title}</h1> <h1 className="ascribe-detail-title">{piece.title}</h1>
<DetailProperty label="BY" value={this.state.piece.artist_name} /> <DetailProperty label="BY" value={piece.artist_name} />
<DetailProperty label="DATE" value={Moment(this.state.piece.date_created, 'YYYY-MM-DD').year() } /> <DetailProperty label="DATE" value={Moment(piece.date_created, 'YYYY-MM-DD').year() } />
{this.state.piece.num_editions > 0 ? <DetailProperty label="EDITIONS" value={ this.state.piece.num_editions } /> : null} {piece.num_editions > 0 ? <DetailProperty label="EDITIONS" value={ piece.num_editions } /> : null}
<hr/> <hr/>
</div> </div>
} }
subheader={ subheader={
<div className="ascribe-detail-header"> <div className="ascribe-detail-header">
<DetailProperty label={getLangText('REGISTREE')} value={ this.state.piece.user_registered } /> <DetailProperty label={getLangText('REGISTREE')} value={ piece.user_registered } />
<DetailProperty label={getLangText('ID')} value={ this.state.piece.bitcoin_id } ellipsis={true} /> <DetailProperty label={getLangText('ID')} value={ piece.bitcoin_id } ellipsis={true} />
<LicenseDetail license={this.state.piece.license_type} /> <LicenseDetail license={piece.license_type} />
</div> </div>
} }
buttons={this.getActions()}> buttons={this.getActions()}>
{this.getCreateEditionsDialog()} {this.getCreateEditionsDialog()}
<CollapsibleParagraph <CollapsibleParagraph
title={getLangText('Loan History')} title={getLangText('Loan History')}
show={this.state.piece.loan_history && this.state.piece.loan_history.length > 0}> show={piece.loan_history && piece.loan_history.length > 0}>
<HistoryIterator <HistoryIterator
history={this.state.piece.loan_history} /> history={piece.loan_history} />
</CollapsibleParagraph> </CollapsibleParagraph>
<CollapsibleParagraph <CollapsibleParagraph
title={getLangText('Notes')} title={getLangText('Notes')}
show={!!(this.state.currentUser.username show={!!(currentUser.username || piece.acl.acl_edit || piece.public_note)}>
|| this.state.piece.acl.acl_edit
|| this.state.piece.public_note)}>
<Note <Note
id={this.getId} id={this.getId}
label={getLangText('Personal note (private)')} label={getLangText('Personal note (private)')}
defaultValue={this.state.piece.private_note || null} defaultValue={piece.private_note || null}
show = {!!this.state.currentUser.username} show = {!!currentUser.username}
placeholder={getLangText('Enter your comments ...')} placeholder={getLangText('Enter your comments ...')}
editable={true} editable={true}
successMessage={getLangText('Private note saved')} successMessage={getLangText('Private note saved')}
url={ApiUrls.note_private_piece} url={ApiUrls.note_private_piece}
currentUser={this.state.currentUser}/> currentUser={currentUser}/>
<Note <Note
id={this.getId} id={this.getId}
label={getLangText('Personal note (public)')} label={getLangText('Personal note (public)')}
defaultValue={this.state.piece.public_note || null} defaultValue={piece.public_note || null}
placeholder={getLangText('Enter your comments ...')} placeholder={getLangText('Enter your comments ...')}
editable={!!this.state.piece.acl.acl_edit} editable={!!piece.acl.acl_edit}
show={!!(this.state.piece.public_note || this.state.piece.acl.acl_edit)} show={!!(piece.public_note || piece.acl.acl_edit)}
successMessage={getLangText('Public note saved')} successMessage={getLangText('Public note saved')}
url={ApiUrls.note_public_piece} url={ApiUrls.note_public_piece}
currentUser={this.state.currentUser}/> currentUser={currentUser}/>
</CollapsibleParagraph> </CollapsibleParagraph>
<CollapsibleParagraph <CollapsibleParagraph
title={getLangText('Further Details')} title={getLangText('Further Details')}
show={this.state.piece.acl.acl_edit show={piece.acl.acl_edit
|| Object.keys(this.state.piece.extra_data).length > 0 || Object.keys(piece.extra_data).length > 0
|| this.state.piece.other_data.length > 0} || piece.other_data.length > 0}
defaultExpanded={true}> defaultExpanded={true}>
<FurtherDetailsType <FurtherDetailsType
editable={this.state.piece.acl.acl_edit} editable={piece.acl.acl_edit}
pieceId={this.state.piece.id} pieceId={piece.id}
extraData={this.state.piece.extra_data} extraData={piece.extra_data}
otherData={this.state.piece.other_data} otherData={piece.other_data}
handleSuccess={this.loadPiece} /> handleSuccess={this.loadPiece} />
</CollapsibleParagraph> </CollapsibleParagraph>

View File

@ -107,20 +107,22 @@ let PieceContainer = React.createClass({
}, },
getActions() { getActions() {
if (this.state.piece && const { currentUser, piece } = this.state;
this.state.piece.notifications &&
this.state.piece.notifications.length > 0) { if (piece && piece.notifications && piece.notifications.length > 0) {
return ( return (
<ListRequestActions <ListRequestActions
pieceOrEditions={this.state.piece} pieceOrEditions={piece}
currentUser={this.state.currentUser} currentUser={currentUser}
handleSuccess={this.loadPiece} handleSuccess={this.loadPiece}
notifications={this.state.piece.notifications}/>); notifications={piece.notifications}/>);
} }
}, },
render() { render() {
if(this.state.piece && this.state.piece.id) { const { currentUser, piece } = this.state;
if (piece && piece.id) {
/* /*
This really needs a refactor! This really needs a refactor!
@ -129,37 +131,32 @@ let PieceContainer = React.createClass({
*/ */
// Only show the artist name if you are the participant or if you are a judge and the piece is shortlisted // Only show the artist name if you are the participant or if you are a judge and the piece is shortlisted
let artistName = ((this.state.currentUser.is_jury && !this.state.currentUser.is_judge) || let artistName;
(this.state.currentUser.is_judge && !this.state.piece.selected )) ? if ((currentUser.is_jury && !currentUser.is_judge) || (currentUser.is_judge && !piece.selected )) {
null : this.state.piece.artist_name; artistName = <span className="glyphicon glyphicon-eye-close" aria-hidden="true"/>;
setDocumentTitle(piece.title);
} else {
artistName = piece.artist_name;
setDocumentTitle([artistName, piece.title].join(', '));
}
// Only show the artist email if you are a judge and the piece is shortlisted // Only show the artist email if you are a judge and the piece is shortlisted
let artistEmail = (this.state.currentUser.is_judge && this.state.piece.selected ) ? const artistEmail = (currentUser.is_judge && piece.selected ) ?
<DetailProperty label={getLangText('REGISTREE')} value={ this.state.piece.user_registered } /> : null; <DetailProperty label={getLangText('REGISTREE')} value={ piece.user_registered } /> : null;
if (artistName === null) {
setDocumentTitle(this.state.piece.title);
} else {
setDocumentTitle([artistName, this.state.piece.title].join(', '));
}
if (artistName === null) {
artistName = <span className="glyphicon glyphicon-eye-close" aria-hidden="true"/>;
}
return ( return (
<Piece <Piece
piece={this.state.piece} piece={piece}
loadPiece={this.loadPiece} currentUser={currentUser}
header={ header={
<div className="ascribe-detail-header"> <div className="ascribe-detail-header">
<NavigationHeader <NavigationHeader
piece={this.state.piece} piece={piece}
currentUser={this.state.currentUser}/> currentUser={currentUser}/>
<h1 className="ascribe-detail-title">{this.state.piece.title}</h1> <h1 className="ascribe-detail-title">{piece.title}</h1>
<DetailProperty label={getLangText('BY')} value={artistName} /> <DetailProperty label={getLangText('BY')} value={artistName} />
<DetailProperty label={getLangText('DATE')} value={Moment(this.state.piece.date_created, 'YYYY-MM-DD').year()} /> <DetailProperty label={getLangText('DATE')} value={Moment(piece.date_created, 'YYYY-MM-DD').year()} />
{artistEmail} {artistEmail}
{this.getActions()} {this.getActions()}
<hr/> <hr/>
@ -168,10 +165,10 @@ let PieceContainer = React.createClass({
subheader={ subheader={
<PrizePieceRatings <PrizePieceRatings
loadPiece={this.loadPiece} loadPiece={this.loadPiece}
piece={this.state.piece} piece={piece}
currentUser={this.state.currentUser}/> currentUser={currentUser}/>
}> }>
<PrizePieceDetails piece={this.state.piece} /> <PrizePieceDetails piece={piece} />
</Piece> </Piece>
); );
} else { } else {

View File

@ -28,56 +28,63 @@ let WalletPieceContainer = React.createClass({
submitButtonType: React.PropTypes.func.isRequired submitButtonType: React.PropTypes.func.isRequired
}, },
render() { render() {
if(this.props.piece && this.props.piece.id) { const {
children,
currentUser,
handleDeleteSuccess,
loadPiece,
piece,
submitButtonType } = this.props;
if(piece && piece.id) {
return ( return (
<Piece <Piece
piece={this.props.piece} piece={piece}
loadPiece={this.props.loadPiece} currentUser={currentUser}
header={ header={
<div className="ascribe-detail-header"> <div className="ascribe-detail-header">
<hr style={{marginTop: 0}}/> <hr style={{marginTop: 0}}/>
<h1 className="ascribe-detail-title">{this.props.piece.title}</h1> <h1 className="ascribe-detail-title">{piece.title}</h1>
<DetailProperty label="BY" value={this.props.piece.artist_name} /> <DetailProperty label="BY" value={piece.artist_name} />
<DetailProperty label="DATE" value={Moment(this.props.piece.date_created, 'YYYY-MM-DD').year()} /> <DetailProperty label="DATE" value={Moment(piece.date_created, 'YYYY-MM-DD').year()} />
<hr/> <hr/>
</div> </div>
} }
subheader={ subheader={
<div className="ascribe-detail-header"> <div className="ascribe-detail-header">
<DetailProperty label={getLangText('REGISTREE')} value={ this.props.piece.user_registered } /> <DetailProperty label={getLangText('REGISTREE')} value={ piece.user_registered } />
<DetailProperty label={getLangText('ID')} value={ this.props.piece.bitcoin_id } ellipsis={true} /> <DetailProperty label={getLangText('ID')} value={ piece.bitcoin_id } ellipsis={true} />
<hr/> <hr/>
</div> </div>
}> }>
<WalletActionPanel <WalletActionPanel
piece={this.props.piece} piece={piece}
currentUser={this.props.currentUser} currentUser={currentUser}
loadPiece={this.props.loadPiece} loadPiece={loadPiece}
handleDeleteSuccess={this.props.handleDeleteSuccess} handleDeleteSuccess={handleDeleteSuccess}
submitButtonType={this.props.submitButtonType}/> submitButtonType={submitButtonType}/>
<CollapsibleParagraph <CollapsibleParagraph
title={getLangText('Loan History')} title={getLangText('Loan History')}
show={this.props.piece.loan_history && this.props.piece.loan_history.length > 0}> show={piece.loan_history && piece.loan_history.length > 0}>
<HistoryIterator <HistoryIterator
history={this.props.piece.loan_history}/> history={piece.loan_history}/>
</CollapsibleParagraph> </CollapsibleParagraph>
<CollapsibleParagraph <CollapsibleParagraph
title={getLangText('Notes')} title={getLangText('Notes')}
show={!!(this.props.currentUser.username || this.props.piece.public_note)}> show={!!(currentUser.username || piece.public_note)}>
<Note <Note
id={() => {return {'id': this.props.piece.id}; }} id={() => {return {'id': piece.id}; }}
label={getLangText('Personal note (private)')} label={getLangText('Personal note (private)')}
defaultValue={this.props.piece.private_note || null} defaultValue={piece.private_note || null}
placeholder={getLangText('Enter your comments ...')} placeholder={getLangText('Enter your comments ...')}
editable={true} editable={true}
successMessage={getLangText('Private note saved')} successMessage={getLangText('Private note saved')}
url={ApiUrls.note_private_piece} url={ApiUrls.note_private_piece}
currentUser={this.props.currentUser}/> currentUser={currentUser}/>
</CollapsibleParagraph> </CollapsibleParagraph>
{this.props.children} {children}
</Piece> </Piece>
); );
} }