mirror of
https://github.com/ascribe/onion.git
synced 2024-12-22 09:23:13 +01:00
refactored piece container and detail
This commit is contained in:
parent
d5efd79d14
commit
22727c2703
@ -23,7 +23,7 @@ const CollapsibleParagraph = React.createClass({
|
||||
|
||||
getInitialState() {
|
||||
return {
|
||||
expanded: false
|
||||
expanded: this.props.defaultExpanded
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -18,8 +18,8 @@ let DetailProperty = React.createClass({
|
||||
getDefaultProps() {
|
||||
return {
|
||||
separator: ':',
|
||||
labelClassName: 'col-xs-3 col-sm-3 col-md-2 col-lg-2',
|
||||
valueClassName: 'col-xs-9 col-sm-9 col-md-10 col-lg-10'
|
||||
labelClassName: 'col-xs-3 col-sm-3 col-md-2 col-lg-2 col-xs-height col-bottom ascribe-detail-property-label',
|
||||
valueClassName: 'col-xs-9 col-sm-9 col-md-10 col-lg-10 col-xs-height col-bottom ascribe-detail-property-value'
|
||||
};
|
||||
},
|
||||
|
||||
@ -52,11 +52,11 @@ let DetailProperty = React.createClass({
|
||||
return (
|
||||
<div className="row ascribe-detail-property">
|
||||
<div className="row-same-height">
|
||||
<div className={this.props.labelClassName + ' col-xs-height col-bottom ascribe-detail-property-label'}>
|
||||
{ this.props.label + this.props.separator}
|
||||
<div className={this.props.labelClassName}>
|
||||
{ this.props.label } { this.props.separator}
|
||||
</div>
|
||||
<div
|
||||
className={this.props.valueClassName + ' col-xs-height col-bottom ascribe-detail-property-value'}
|
||||
className={this.props.valueClassName}
|
||||
style={styles}>
|
||||
{value}
|
||||
</div>
|
||||
|
@ -19,7 +19,33 @@ const EMBED_IFRAME_HEIGHT = {
|
||||
|
||||
let MediaContainer = React.createClass({
|
||||
propTypes: {
|
||||
content: React.PropTypes.object
|
||||
content: React.PropTypes.object,
|
||||
refreshObject: React.PropTypes.func
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return {timerId: null};
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
if (!this.props.content.digital_work) {
|
||||
return;
|
||||
}
|
||||
let isEncoding = this.props.content.digital_work.isEncoding;
|
||||
if (this.props.content.digital_work.mime === 'video' && typeof isEncoding === 'number' && isEncoding !== 100 && !this.state.timerId) {
|
||||
let timerId = window.setInterval(this.props.refreshObject, 10000);
|
||||
this.setState({timerId: timerId});
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUpdate() {
|
||||
if (this.props.content.digital_work.isEncoding === 100) {
|
||||
window.clearInterval(this.state.timerId);
|
||||
}
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
window.clearInterval(this.state.timerId);
|
||||
},
|
||||
|
||||
render() {
|
||||
|
@ -1,38 +1,14 @@
|
||||
'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 DetailProperty from './detail_property';
|
||||
|
||||
import UserActions from '../../actions/user_actions';
|
||||
import UserStore from '../../stores/user_store';
|
||||
|
||||
import PieceListActions from '../../actions/piece_list_actions';
|
||||
import PieceListStore from '../../stores/piece_list_store';
|
||||
|
||||
import EditionListActions from '../../actions/edition_list_actions';
|
||||
|
||||
import PieceActions from '../../actions/piece_actions';
|
||||
|
||||
import MediaContainer from './media_container';
|
||||
|
||||
import EditionDetailProperty from './detail_property';
|
||||
|
||||
import AclButtonList from './../ascribe_buttons/acl_button_list';
|
||||
import CreateEditionsForm from '../ascribe_forms/create_editions_form';
|
||||
import CreateEditionsButton from '../ascribe_buttons/create_editions_button';
|
||||
import DeleteButton from '../ascribe_buttons/delete_button';
|
||||
|
||||
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||
|
||||
import { getLangText } from '../../utils/lang_utils';
|
||||
import { mergeOptions } from '../../utils/general_utils';
|
||||
|
||||
|
||||
/**
|
||||
* This is the component that implements display-specific functionality
|
||||
@ -40,97 +16,16 @@ import { mergeOptions } from '../../utils/general_utils';
|
||||
let Piece = React.createClass({
|
||||
propTypes: {
|
||||
piece: React.PropTypes.object,
|
||||
header: React.PropTypes.object,
|
||||
subheader: React.PropTypes.object,
|
||||
buttons: React.PropTypes.object,
|
||||
loadPiece: React.PropTypes.func,
|
||||
children: React.PropTypes.object
|
||||
},
|
||||
|
||||
mixins: [Router.Navigation],
|
||||
|
||||
getInitialState() {
|
||||
return mergeOptions(
|
||||
UserStore.getState(),
|
||||
PieceListStore.getState(),
|
||||
{
|
||||
showCreateEditionsDialog: false
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
UserStore.listen(this.onChange);
|
||||
PieceListStore.listen(this.onChange);
|
||||
UserActions.fetchCurrentUser();
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
UserStore.unlisten(this.onChange);
|
||||
PieceListStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
toggleCreateEditionsDialog() {
|
||||
this.setState({
|
||||
showCreateEditionsDialog: !this.state.showCreateEditionsDialog
|
||||
});
|
||||
},
|
||||
|
||||
handleEditionCreationSuccess() {
|
||||
PieceActions.updateProperty({key: 'num_editions', value: 0});
|
||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
||||
this.toggleCreateEditionsDialog();
|
||||
},
|
||||
|
||||
handleDeleteSuccess(response) {
|
||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
||||
|
||||
// since we're deleting a piece, we just need to close
|
||||
// all editions dialogs and not reload them
|
||||
EditionListActions.closeAllEditionLists();
|
||||
EditionListActions.clearAllEditionSelections();
|
||||
|
||||
let notification = new GlobalNotificationModel(response.notification, 'success');
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
|
||||
this.transitionTo('pieces');
|
||||
},
|
||||
|
||||
getCreateEditionsDialog() {
|
||||
if(this.props.piece.num_editions < 1 && this.state.showCreateEditionsDialog) {
|
||||
return (
|
||||
<div style={{marginTop: '1em'}}>
|
||||
<CreateEditionsForm
|
||||
pieceId={this.props.piece.id}
|
||||
handleSuccess={this.handleEditionCreationSuccess} />
|
||||
<hr/>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (<hr/>);
|
||||
}
|
||||
},
|
||||
|
||||
handlePollingSuccess(pieceId, numEditions) {
|
||||
|
||||
// we need to refresh the num_editions property of the actual piece we're looking at
|
||||
PieceActions.updateProperty({
|
||||
key: 'num_editions',
|
||||
value: numEditions
|
||||
});
|
||||
|
||||
// as well as its representation in the collection
|
||||
// btw.: It's not sufficient to just set num_editions to numEditions, since a single accordion
|
||||
// list item also uses the firstEdition property which we can only get from the server in that case.
|
||||
// Therefore we need to at least refetch the changed piece from the server or on our case simply all
|
||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
||||
|
||||
let notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
updateObject() {
|
||||
return PieceActions.fetchOne(this.props.piece.id);
|
||||
},
|
||||
|
||||
render() {
|
||||
@ -138,38 +33,14 @@ let Piece = React.createClass({
|
||||
<Row>
|
||||
<Col md={6}>
|
||||
<MediaContainer
|
||||
refreshObject={this.updateObject}
|
||||
content={this.props.piece}/>
|
||||
</Col>
|
||||
<Col md={6} className="ascribe-edition-details">
|
||||
<div className="ascribe-detail-header">
|
||||
<h1 className="ascribe-detail-title">{this.props.piece.title}</h1>
|
||||
<hr/>
|
||||
<EditionDetailProperty label="BY" value={this.props.piece.artist_name} />
|
||||
<EditionDetailProperty label="DATE" value={ this.props.piece.date_created.slice(0, 4) } />
|
||||
{this.props.piece.num_editions > 0 ? <EditionDetailProperty label="EDITIONS" value={ this.props.piece.num_editions } /> : null}
|
||||
<hr/>
|
||||
</div>
|
||||
<div className="ascribe-detail-header">
|
||||
<DetailProperty label={getLangText('REGISTREE')} value={ this.props.piece.user_registered } />
|
||||
</div>
|
||||
{this.props.header}
|
||||
{this.props.subheader}
|
||||
{this.props.buttons}
|
||||
|
||||
<AclButtonList
|
||||
className="text-center ascribe-button-list"
|
||||
availableAcls={this.props.piece.acl}
|
||||
editions={this.props.piece}
|
||||
handleSuccess={this.props.loadPiece}>
|
||||
<CreateEditionsButton
|
||||
label={getLangText('CREATE EDITIONS')}
|
||||
className="btn-sm"
|
||||
piece={this.props.piece}
|
||||
toggleCreateEditionsDialog={this.toggleCreateEditionsDialog}
|
||||
onPollingSuccess={this.handlePollingSuccess}/>
|
||||
<DeleteButton
|
||||
handleSuccess={this.handleDeleteSuccess}
|
||||
piece={this.props.piece}/>
|
||||
</AclButtonList>
|
||||
|
||||
{this.getCreateEditionsDialog()}
|
||||
{this.props.children}
|
||||
|
||||
</Col>
|
||||
|
@ -1,37 +1,59 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import Router from 'react-router';
|
||||
|
||||
import PieceActions from '../../actions/piece_actions';
|
||||
import PieceStore from '../../stores/piece_store';
|
||||
|
||||
import PieceListActions from '../../actions/piece_list_actions';
|
||||
import PieceListStore from '../../stores/piece_list_store';
|
||||
|
||||
import UserActions from '../../actions/user_actions';
|
||||
import UserStore from '../../stores/user_store';
|
||||
|
||||
import EditionListActions from '../../actions/edition_list_actions';
|
||||
|
||||
import Piece from './piece';
|
||||
import CollapsibleParagraph from './../ascribe_collapsible/collapsible_paragraph';
|
||||
import FurtherDetails from './further_details';
|
||||
|
||||
import DetailProperty from './detail_property';
|
||||
|
||||
import AclButtonList from './../ascribe_buttons/acl_button_list';
|
||||
import CreateEditionsForm from '../ascribe_forms/create_editions_form';
|
||||
import CreateEditionsButton from '../ascribe_buttons/create_editions_button';
|
||||
import DeleteButton from '../ascribe_buttons/delete_button';
|
||||
|
||||
import GlobalNotificationModel from '../../models/global_notification_model';
|
||||
import GlobalNotificationActions from '../../actions/global_notification_actions';
|
||||
|
||||
import AppConstants from '../../constants/application_constants';
|
||||
import { mergeOptions } from '../../utils/general_utils';
|
||||
import { getLangText } from '../../utils/lang_utils';
|
||||
|
||||
/**
|
||||
* This is the component that implements resource/data specific functionality
|
||||
*/
|
||||
let PieceContainer = React.createClass({
|
||||
getInitialState() {
|
||||
return PieceStore.getState();
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
if (!state.piece.digital_work) {
|
||||
return;
|
||||
}
|
||||
let isEncoding = state.piece.digital_work.isEncoding;
|
||||
if (state.piece.digital_work.mime === 'video' && typeof isEncoding === 'number' && isEncoding !== 100 && !this.state.timerId) {
|
||||
let timerId = window.setInterval(() => PieceActions.fetchOne(this.props.params.pieceId), 10000);
|
||||
this.setState({timerId: timerId});
|
||||
}
|
||||
mixins: [Router.Navigation],
|
||||
|
||||
getInitialState() {
|
||||
return mergeOptions(
|
||||
UserStore.getState(),
|
||||
PieceListStore.getState(),
|
||||
PieceStore.getState(),
|
||||
{
|
||||
showCreateEditionsDialog: false
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
UserStore.listen(this.onChange);
|
||||
PieceListStore.listen(this.onChange);
|
||||
UserActions.fetchCurrentUser();
|
||||
PieceStore.listen(this.onChange);
|
||||
PieceActions.fetchOne(this.props.params.pieceId);
|
||||
},
|
||||
@ -42,21 +64,121 @@ let PieceContainer = React.createClass({
|
||||
// as it will otherwise display wrong/old data once the user loads
|
||||
// the piece detail a second time
|
||||
PieceActions.updatePiece({});
|
||||
window.clearInterval(this.state.timerId);
|
||||
PieceStore.unlisten(this.onChange);
|
||||
UserStore.unlisten(this.onChange);
|
||||
PieceListStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
loadPiece() {
|
||||
PieceActions.fetchOne(this.props.params.pieceId);
|
||||
},
|
||||
|
||||
|
||||
toggleCreateEditionsDialog() {
|
||||
this.setState({
|
||||
showCreateEditionsDialog: !this.state.showCreateEditionsDialog
|
||||
});
|
||||
},
|
||||
|
||||
handleEditionCreationSuccess() {
|
||||
PieceActions.updateProperty({key: 'num_editions', value: 0});
|
||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
||||
this.toggleCreateEditionsDialog();
|
||||
},
|
||||
|
||||
handleDeleteSuccess(response) {
|
||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
||||
|
||||
// since we're deleting a piece, we just need to close
|
||||
// all editions dialogs and not reload them
|
||||
EditionListActions.closeAllEditionLists();
|
||||
EditionListActions.clearAllEditionSelections();
|
||||
|
||||
let notification = new GlobalNotificationModel(response.notification, 'success');
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
|
||||
this.transitionTo('pieces');
|
||||
},
|
||||
|
||||
getCreateEditionsDialog() {
|
||||
if(this.state.piece.num_editions < 1 && this.state.showCreateEditionsDialog) {
|
||||
return (
|
||||
<div style={{marginTop: '1em'}}>
|
||||
<CreateEditionsForm
|
||||
pieceId={this.state.piece.id}
|
||||
handleSuccess={this.handleEditionCreationSuccess} />
|
||||
<hr/>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (<hr/>);
|
||||
}
|
||||
},
|
||||
|
||||
handlePollingSuccess(pieceId, numEditions) {
|
||||
|
||||
// we need to refresh the num_editions property of the actual piece we're looking at
|
||||
PieceActions.updateProperty({
|
||||
key: 'num_editions',
|
||||
value: numEditions
|
||||
});
|
||||
|
||||
// as well as its representation in the collection
|
||||
// btw.: It's not sufficient to just set num_editions to numEditions, since a single accordion
|
||||
// list item also uses the firstEdition property which we can only get from the server in that case.
|
||||
// Therefore we need to at least refetch the changed piece from the server or on our case simply all
|
||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
|
||||
|
||||
let notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000);
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
},
|
||||
|
||||
render() {
|
||||
if('title' in this.state.piece) {
|
||||
return (
|
||||
<Piece
|
||||
piece={this.state.piece}
|
||||
loadPiece={this.loadPiece}>
|
||||
loadPiece={this.loadPiece}
|
||||
header={
|
||||
<div className="ascribe-detail-header">
|
||||
<h1 className="ascribe-detail-title">{this.state.piece.title}</h1>
|
||||
<hr/>
|
||||
<DetailProperty label="BY" value={this.state.piece.artist_name} />
|
||||
<DetailProperty label="DATE" value={ this.state.piece.date_created.slice(0, 4) } />
|
||||
{this.state.piece.num_editions > 0 ? <DetailProperty label="EDITIONS" value={ this.state.piece.num_editions } /> : null}
|
||||
<hr/>
|
||||
</div>
|
||||
}
|
||||
subheader={
|
||||
<div className="ascribe-detail-header">
|
||||
<DetailProperty label={getLangText('REGISTREE')} value={ this.state.piece.user_registered } />
|
||||
</div>
|
||||
}
|
||||
buttons={
|
||||
<AclButtonList
|
||||
className="text-center ascribe-button-list"
|
||||
availableAcls={this.state.piece.acl}
|
||||
editions={this.state.piece}
|
||||
handleSuccess={this.state.loadPiece}>
|
||||
<CreateEditionsButton
|
||||
label={getLangText('CREATE EDITIONS')}
|
||||
className="btn-sm"
|
||||
piece={this.state.piece}
|
||||
toggleCreateEditionsDialog={this.toggleCreateEditionsDialog}
|
||||
onPollingSuccess={this.handlePollingSuccess}/>
|
||||
<DeleteButton
|
||||
handleSuccess={this.handleDeleteSuccess}
|
||||
piece={this.state.piece}/>
|
||||
</AclButtonList>
|
||||
}>
|
||||
{this.getCreateEditionsDialog()}
|
||||
<CollapsibleParagraph
|
||||
title="Further Details"
|
||||
show={this.state.piece.acl.acl_edit
|
||||
|
@ -24,7 +24,7 @@ import { mergeOptions } from '../utils/general_utils';
|
||||
|
||||
let PieceList = React.createClass({
|
||||
propTypes: {
|
||||
accordionListItemType: React.PropTypes.object,
|
||||
accordionListItemType: React.PropTypes.func,
|
||||
redirectTo: React.PropTypes.string,
|
||||
customSubmitButton: React.PropTypes.element
|
||||
},
|
||||
|
@ -1,13 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
import Router from 'react-router';
|
||||
import StarRating from 'react-star-rating';
|
||||
|
||||
import AccordionListItemPiece from '../../../../ascribe_accordion_list/accordion_list_item_piece';
|
||||
|
||||
import PieceListActions from '../../../../../actions/piece_list_actions';
|
||||
import PieceListStore from '../../../../../stores/piece_list_store';
|
||||
|
||||
import WhitelabelStore from '../../../../../stores/whitelabel_store';
|
||||
import UserStore from '../../../../../stores/user_store';
|
||||
|
||||
import GlobalNotificationModel from '../../../../../models/global_notification_model';
|
||||
import GlobalNotificationActions from '../../../../../actions/global_notification_actions';
|
||||
@ -15,11 +17,14 @@ import GlobalNotificationActions from '../../../../../actions/global_notificatio
|
||||
import AclProxy from '../../../../acl_proxy';
|
||||
import SubmitToPrizeButton from './../ascribe_buttons/submit_to_prize_button';
|
||||
|
||||
|
||||
import { getLangText } from '../../../../../utils/lang_utils';
|
||||
import { mergeOptions } from '../../../../../utils/general_utils';
|
||||
|
||||
let Link = Router.Link;
|
||||
|
||||
let AccordionListItemWallet = React.createClass({
|
||||
|
||||
let AccordionListItemPrize = React.createClass({
|
||||
propTypes: {
|
||||
className: React.PropTypes.string,
|
||||
content: React.PropTypes.object,
|
||||
@ -32,18 +37,18 @@ let AccordionListItemWallet = React.createClass({
|
||||
getInitialState() {
|
||||
return mergeOptions(
|
||||
PieceListStore.getState(),
|
||||
WhitelabelStore.getState()
|
||||
UserStore.getState()
|
||||
);
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
PieceListStore.listen(this.onChange);
|
||||
WhitelabelStore.listen(this.onChange);
|
||||
UserStore.listen(this.onChange);
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
PieceListStore.unlisten(this.onChange);
|
||||
WhitelabelStore.unlisten(this.onChange);
|
||||
UserStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
@ -58,6 +63,51 @@ let AccordionListItemWallet = React.createClass({
|
||||
GlobalNotificationActions.appendGlobalNotification(notification);
|
||||
},
|
||||
|
||||
getPrizeButtons() {
|
||||
if (this.state.currentUser && this.state.currentUser.is_jury){
|
||||
if (this.props.content.ratings && this.props.content.ratings.rating){
|
||||
// jury and rating available
|
||||
let rating = parseInt(this.props.content.ratings.rating, 10);
|
||||
return (
|
||||
<div className="pull-right">
|
||||
<Link to='piece' params={{pieceId: this.props.content.id}}>
|
||||
<StarRating
|
||||
ref='rating'
|
||||
name="prize-rating"
|
||||
caption="Your rating"
|
||||
step={1}
|
||||
size='sm'
|
||||
rating={rating}
|
||||
ratingAmount={5} />
|
||||
</Link>
|
||||
</div>);
|
||||
}
|
||||
else {
|
||||
// jury and no rating yet
|
||||
return (
|
||||
<div className="react-rating-caption pull-right">
|
||||
<Link to='piece' params={{pieceId: this.props.content.id}}>
|
||||
Submit your rating
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
// participant
|
||||
return (
|
||||
<div>
|
||||
<AclProxy
|
||||
aclObject={this.props.content.acl}
|
||||
aclName="acl_submit_to_prize">
|
||||
<SubmitToPrizeButton
|
||||
className="pull-right"
|
||||
piece={this.props.content}
|
||||
handleSuccess={this.handleSubmitPrizeSuccess}/>
|
||||
</AclProxy>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
@ -68,22 +118,11 @@ let AccordionListItemWallet = React.createClass({
|
||||
<div className="pull-left">
|
||||
<span>{this.props.content.date_created.split('-')[0]}</span>
|
||||
</div>}
|
||||
buttons={
|
||||
<div>
|
||||
<AclProxy
|
||||
aclObject={this.props.content.acl}
|
||||
aclName="acl_submit_to_prize">
|
||||
<SubmitToPrizeButton
|
||||
className="pull-right"
|
||||
piece={this.props.content}
|
||||
handleSuccess={this.handleSubmitPrizeSuccess}/>
|
||||
</AclProxy>
|
||||
</div>}
|
||||
>
|
||||
buttons={this.getPrizeButtons()}>
|
||||
{this.props.children}
|
||||
</AccordionListItemPiece>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default AccordionListItemWallet;
|
||||
export default AccordionListItemPrize;
|
||||
|
@ -7,6 +7,9 @@ import StarRating from 'react-star-rating';
|
||||
import PieceActions from '../../../../../actions/piece_actions';
|
||||
import PieceStore from '../../../../../stores/piece_store';
|
||||
|
||||
import PieceListStore from '../../../../../stores/piece_list_store';
|
||||
import PieceListActions from '../../../../../actions/piece_list_actions';
|
||||
|
||||
import PrizeRatingActions from '../../actions/prize_rating_actions';
|
||||
import PrizeRatingStore from '../../stores/prize_rating_store';
|
||||
|
||||
@ -19,6 +22,10 @@ import Property from '../../../../../components/ascribe_forms/property';
|
||||
import InputTextAreaToggable from '../../../../../components/ascribe_forms/input_textarea_toggable';
|
||||
import CollapsibleParagraph from '../../../../../components/ascribe_collapsible/collapsible_paragraph';
|
||||
|
||||
import DetailProperty from '../../../../ascribe_detail/detail_property';
|
||||
|
||||
import { mergeOptions } from '../../../../../utils/general_utils';
|
||||
import { getLangText } from '../../../../../utils/lang_utils';
|
||||
/**
|
||||
* This is the component that implements resource/data specific functionality
|
||||
*/
|
||||
@ -27,10 +34,6 @@ let PieceContainer = React.createClass({
|
||||
return PieceStore.getState();
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
PieceStore.listen(this.onChange);
|
||||
PieceActions.fetchOne(this.props.params.pieceId);
|
||||
@ -42,10 +45,12 @@ let PieceContainer = React.createClass({
|
||||
// as it will otherwise display wrong/old data once the user loads
|
||||
// the piece detail a second time
|
||||
PieceActions.updatePiece({});
|
||||
|
||||
PieceStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
},
|
||||
|
||||
loadPiece() {
|
||||
PieceActions.fetchOne(this.props.params.pieceId);
|
||||
@ -56,7 +61,19 @@ let PieceContainer = React.createClass({
|
||||
return (
|
||||
<Piece
|
||||
piece={this.state.piece}
|
||||
loadPiece={this.loadPiece}>
|
||||
loadPiece={this.loadPiece}
|
||||
header={
|
||||
<div className="ascribe-detail-header">
|
||||
<h1 className="ascribe-detail-title">{this.state.piece.title}</h1>
|
||||
<hr/>
|
||||
<DetailProperty label="BY" value={this.state.piece.artist_name} />
|
||||
<DetailProperty label="DATE" value={ this.state.piece.date_created.slice(0, 4) } />
|
||||
<hr/>
|
||||
</div>
|
||||
}
|
||||
subheader={
|
||||
<PrizePieceRatings piece={this.state.piece}/>
|
||||
}>
|
||||
<PrizePieceDetails piece={this.state.piece}/>
|
||||
</Piece>
|
||||
);
|
||||
@ -70,23 +87,22 @@ let PieceContainer = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
let PrizePieceDetails = React.createClass({
|
||||
let PrizePieceRatings = React.createClass({
|
||||
propTypes: {
|
||||
piece: React.PropTypes.object
|
||||
},
|
||||
|
||||
getInitialState() {
|
||||
return PrizeRatingStore.getState();
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
return mergeOptions(
|
||||
PieceListStore.getState(),
|
||||
PrizeRatingStore.getState()
|
||||
);
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
PrizeRatingStore.listen(this.onChange);
|
||||
PrizeRatingActions.fetchOne(this.props.piece.id);
|
||||
PieceListStore.listen(this.onChange);
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
@ -96,11 +112,52 @@ let PrizePieceDetails = React.createClass({
|
||||
// the piece detail a second time
|
||||
PrizeRatingActions.updateRating({});
|
||||
PrizeRatingStore.unlisten(this.onChange);
|
||||
PieceListStore.unlisten(this.onChange);
|
||||
},
|
||||
|
||||
onChange(state) {
|
||||
this.setState(state);
|
||||
if (this.refs.rating) {
|
||||
this.refs.rating.state.ratingCache = {
|
||||
pos: this.refs.rating.state.pos,
|
||||
rating: this.state.currentRating,
|
||||
caption: this.refs.rating.props.caption,
|
||||
name: this.refs.rating.props.name
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
onRatingClick(event, args) {
|
||||
event.preventDefault();
|
||||
PrizeRatingActions.createRating(this.props.piece.id, args.rating);
|
||||
PrizeRatingActions.createRating(this.props.piece.id, args.rating).then(
|
||||
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
|
||||
this.state.orderBy, this.state.orderAsc, this.state.filterBy)
|
||||
);
|
||||
},
|
||||
render(){
|
||||
return (
|
||||
<DetailProperty
|
||||
labelClassName='col-xs-3 col-sm-3 col-md-2 col-lg-2 col-xs-height col-middle ascribe-detail-property-label'
|
||||
label={
|
||||
<span>YOUR VOTE</span>
|
||||
}
|
||||
value={
|
||||
<StarRating
|
||||
ref='rating'
|
||||
name="prize-rating"
|
||||
caption=""
|
||||
step={1}
|
||||
size='md'
|
||||
rating={this.state.currentRating}
|
||||
onRatingClick={this.onRatingClick}
|
||||
ratingAmount={5} />}
|
||||
/>);
|
||||
}
|
||||
});
|
||||
|
||||
let PrizePieceDetails = React.createClass({
|
||||
propTypes: {
|
||||
piece: React.PropTypes.object
|
||||
},
|
||||
|
||||
render() {
|
||||
|
@ -387,4 +387,8 @@ hr {
|
||||
.rating-container .rating-stars {
|
||||
width: 25px;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.react-rating-caption {
|
||||
font-size: 1em;
|
||||
}
|
Loading…
Reference in New Issue
Block a user