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

refactored accordion list item:

accordion-list-item
accordion-list-item-piece < accordion-list-item
accordion-list-item-wallet < accordion-list-item-piece
accordion-list-item-prize < accordion-list-item-piece
This commit is contained in:
diminator 2015-08-11 12:06:01 +02:00
parent f5b34222a9
commit d5efd79d14
6 changed files with 350 additions and 177 deletions

View File

@ -3,151 +3,24 @@
import React from 'react';
import Router from 'react-router';
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
import Tooltip from 'react-bootstrap/lib/Tooltip';
import AccordionListItemEditionWidget from './accordion_list_item_edition_widget';
import CreateEditionsForm from '../ascribe_forms/create_editions_form';
import PieceListActions from '../../actions/piece_list_actions';
import PieceListStore from '../../stores/piece_list_store';
import WhitelabelStore from '../../stores/whitelabel_store';
import EditionListActions from '../../actions/edition_list_actions';
import GlobalNotificationModel from '../../models/global_notification_model';
import GlobalNotificationActions from '../../actions/global_notification_actions';
import AclProxy from '../acl_proxy';
import SubmitToPrizeButton from '../whitelabel/prize/components/ascribe_buttons/submit_to_prize_button';
import { getLangText } from '../../utils/lang_utils';
import { mergeOptions } from '../../utils/general_utils';
let Link = Router.Link;
let AccordionListItem = React.createClass({
propTypes: {
badge: React.PropTypes.object,
className: React.PropTypes.string,
content: React.PropTypes.object,
children: React.PropTypes.object
thumbnail: React.PropTypes.object,
heading: React.PropTypes.object,
subheading: React.PropTypes.object,
subsubheading: React.PropTypes.object,
buttons: React.PropTypes.object,
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element
])
},
mixins: [Router.Navigation],
getInitialState() {
return mergeOptions(
{
showCreateEditionsDialog: false
},
PieceListStore.getState(),
WhitelabelStore.getState()
);
},
componentDidMount() {
PieceListStore.listen(this.onChange);
WhitelabelStore.listen(this.onChange);
},
componentWillUnmount() {
PieceListStore.unlisten(this.onChange);
WhitelabelStore.unlisten(this.onChange);
},
onChange(state) {
this.setState(state);
},
getGlyphicon(){
if (this.props.content.requestAction) {
return (
<OverlayTrigger
delay={500}
placement="left"
overlay={<Tooltip>{getLangText('You have actions pending in one of your editions')}</Tooltip>}>
<Glyphicon glyph='bell'/>
</OverlayTrigger>);
}
return null;
},
toggleCreateEditionsDialog() {
this.setState({
showCreateEditionsDialog: !this.state.showCreateEditionsDialog
});
},
handleEditionCreationSuccess() {
PieceListActions.updatePropertyForPiece({pieceId: this.props.content.id, key: 'num_editions', value: 0});
this.toggleCreateEditionsDialog();
},
handleSubmitPrizeSuccess(response) {
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
GlobalNotificationActions.appendGlobalNotification(notification);
},
onPollingSuccess(pieceId) {
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
EditionListActions.toggleEditionList(pieceId);
let notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000);
GlobalNotificationActions.appendGlobalNotification(notification);
},
getCreateEditionsDialog() {
if (this.props.content.num_editions < 1 && this.state.showCreateEditionsDialog) {
return (
<div
className="ascribe-accordion-list-item-table col-xs-12 col-sm-10 col-md-8 col-lg-8 col-sm-offset-1 col-md-offset-2 col-lg-offset-2">
<CreateEditionsForm
pieceId={this.props.content.id}
handleSuccess={this.handleEditionCreationSuccess}/>
</div>
);
}
},
getLicences() {
// convert this to acl_view_licences later
if (this.state.whitelabel && this.state.whitelabel.name === 'Creative Commons France') {
return (
<span>
<span>, </span>
<a href={this.props.content.license_type.url} target="_blank">
{getLangText('%s license', this.props.content.license_type.code)}
</a>
</span>
);
}
},
render() {
let linkData;
if (this.props.content.num_editions < 1 || !this.props.content.first_edition) {
linkData = {
to: 'piece',
params: {
pieceId: this.props.content.id
}
};
} else {
linkData = {
to: 'edition',
params: {
editionId: this.props.content.first_edition.bitcoin_id
}
};
}
return (
<div className="row">
@ -155,52 +28,22 @@ let AccordionListItem = React.createClass({
<div className="wrapper">
<div className="col-xs-4 col-sm-3 col-md-2 col-lg-2 clear-paddings">
<div className="thumbnail-wrapper">
<Link {...linkData}>
<img src={this.props.content.thumbnail.url_safe}/>
</Link>
{this.props.thumbnail}
</div>
</div>
<div className="col-xs-8 col-sm-9 col-md-9 col-lg-9 col-md-offset-1 col-lg-offset-1 accordion-list-item-header">
<Link {...linkData}>
<h1>{this.props.content.title}</h1>
</Link>
<h3>{getLangText('by %s', this.props.content.artist_name)}</h3>
<div>
<span className="pull-left">{this.props.content.date_created.split('-')[0]}</span>
<AclProxy
aclObject={this.props.content.acl}
aclName="acl_view_editions">
<AccordionListItemEditionWidget
className="pull-right"
piece={this.props.content}
toggleCreateEditionsDialog={this.toggleCreateEditionsDialog}
onPollingSuccess={this.onPollingSuccess}/>
</AclProxy>
<AclProxy
aclObject={this.props.content.acl}
aclName="acl_submit_to_prize">
<SubmitToPrizeButton
className="pull-right"
piece={this.props.content}
handleSuccess={this.handleSubmitPrizeSuccess}/>
</AclProxy>
{this.getLicences()}
</div>
{this.props.heading}
{this.props.subheading}
{this.props.subsubheading}
{this.props.buttons}
</div>
<span style={{'clear': 'both'}}></span>
<div className="request-action-batch">
{this.getGlyphicon()}
{this.props.badge}
</div>
</div>
</div>
{this.getCreateEditionsDialog()}
{/* this.props.children is AccordionListItemTableEditions */}
{this.props.children}
</div>
);

View File

@ -0,0 +1,76 @@
'use strict';
import React from 'react';
import Router from 'react-router';
import AccordionListItem from './accordion_list_item';
import { getLangText } from '../../utils/lang_utils';
let Link = Router.Link;
let AccordionListItemPiece = React.createClass({
propTypes: {
className: React.PropTypes.string,
piece: React.PropTypes.object,
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element
]),
subsubheading: React.PropTypes.object,
buttons: React.PropTypes.object,
badge: React.PropTypes.object
},
mixins: [Router.Navigation],
getLinkData(){
let linkData;
if (this.props.piece.num_editions < 1 || !this.props.piece.first_edition) {
linkData = {
to: 'piece',
params: {
pieceId: this.props.piece.id
}
};
} else {
linkData = {
to: 'edition',
params: {
editionId: this.props.piece.first_edition.bitcoin_id
}
};
}
return linkData;
},
render() {
return (
<AccordionListItem
className={this.props.className}
thumbnail={
<Link {...this.getLinkData()}>
<img src={this.props.piece.thumbnail.url_safe}/>
</Link>}
heading={
<Link {...this.getLinkData()}>
<h1>{this.props.piece.title}</h1>
</Link>}
subheading={
<h3>
{getLangText('by %s', this.props.piece.artist_name)}
</h3>
}
subsubheading={this.props.subsubheading}
buttons={this.props.buttons}
badge={this.props.badge}
>
{this.props.children}
</AccordionListItem>
);
}
});
export default AccordionListItemPiece;

View File

@ -0,0 +1,156 @@
'use strict';
import React from 'react';
import Glyphicon from 'react-bootstrap/lib/Glyphicon';
import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
import Tooltip from 'react-bootstrap/lib/Tooltip';
import AccordionListItemPiece from './accordion_list_item_piece';
import AccordionListItemEditionWidget from './accordion_list_item_edition_widget';
import CreateEditionsForm from '../ascribe_forms/create_editions_form';
import PieceListActions from '../../actions/piece_list_actions';
import PieceListStore from '../../stores/piece_list_store';
import WhitelabelStore from '../../stores/whitelabel_store';
import EditionListActions from '../../actions/edition_list_actions';
import GlobalNotificationModel from '../../models/global_notification_model';
import GlobalNotificationActions from '../../actions/global_notification_actions';
import AclProxy from '../acl_proxy';
import { getLangText } from '../../utils/lang_utils';
import { mergeOptions } from '../../utils/general_utils';
let AccordionListItemWallet = React.createClass({
propTypes: {
className: React.PropTypes.string,
content: React.PropTypes.object,
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element
])
},
getInitialState() {
return mergeOptions(
{
showCreateEditionsDialog: false
},
PieceListStore.getState(),
WhitelabelStore.getState()
);
},
componentDidMount() {
PieceListStore.listen(this.onChange);
WhitelabelStore.listen(this.onChange);
},
componentWillUnmount() {
PieceListStore.unlisten(this.onChange);
WhitelabelStore.unlisten(this.onChange);
},
onChange(state) {
this.setState(state);
},
getGlyphicon(){
if (this.props.content.requestAction) {
return (
<OverlayTrigger
delay={500}
placement="left"
overlay={<Tooltip>{getLangText('You have actions pending in one of your editions')}</Tooltip>}>
<Glyphicon glyph='bell'/>
</OverlayTrigger>);
}
return null;
},
toggleCreateEditionsDialog() {
this.setState({
showCreateEditionsDialog: !this.state.showCreateEditionsDialog
});
},
handleEditionCreationSuccess() {
PieceListActions.updatePropertyForPiece({pieceId: this.props.content.id, key: 'num_editions', value: 0});
this.toggleCreateEditionsDialog();
},
onPollingSuccess(pieceId) {
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
EditionListActions.toggleEditionList(pieceId);
let notification = new GlobalNotificationModel('Editions successfully created', 'success', 10000);
GlobalNotificationActions.appendGlobalNotification(notification);
},
getCreateEditionsDialog() {
if (this.props.content.num_editions < 1 && this.state.showCreateEditionsDialog) {
return (
<div
className="ascribe-accordion-list-item-table col-xs-12 col-sm-10 col-md-8 col-lg-8 col-sm-offset-1 col-md-offset-2 col-lg-offset-2">
<CreateEditionsForm
pieceId={this.props.content.id}
handleSuccess={this.handleEditionCreationSuccess}/>
</div>
);
}
},
getLicences() {
// convert this to acl_view_licences later
if (this.state.whitelabel && this.state.whitelabel.name === 'Creative Commons France') {
return (
<span>
<span>, </span>
<a href={this.props.content.license_type.url} target="_blank">
{getLangText('%s license', this.props.content.license_type.code)}
</a>
</span>
);
}
},
render() {
return (
<AccordionListItemPiece
className={this.props.className}
piece={this.props.content}
subsubheading={
<div className="pull-left">
<span>{this.props.content.date_created.split('-')[0]}</span>
{this.getLicences()}
</div>}
buttons={
<div>
<AclProxy
aclObject={this.props.content.acl}
aclName="acl_view_editions">
<AccordionListItemEditionWidget
className="pull-right"
piece={this.props.content}
toggleCreateEditionsDialog={this.toggleCreateEditionsDialog}
onPollingSuccess={this.onPollingSuccess}/>
</AclProxy>
</div>}
badge={this.getGlyphicon()}>
{this.getCreateEditionsDialog()}
{/* this.props.children is AccordionListItemTableEditions */}
{this.props.children}
</AccordionListItemPiece>
);
}
});
export default AccordionListItemWallet;

View File

@ -10,7 +10,7 @@ import EditionListStore from '../stores/edition_list_store';
import EditionListActions from '../actions/edition_list_actions';
import AccordionList from './ascribe_accordion_list/accordion_list';
import AccordionListItem from './ascribe_accordion_list/accordion_list_item';
import AccordionListItemWallet from './ascribe_accordion_list/accordion_list_item_wallet';
import AccordionListItemTableEditions from './ascribe_accordion_list/accordion_list_item_table_editions';
import Pagination from './ascribe_pagination/pagination';
@ -24,12 +24,19 @@ import { mergeOptions } from '../utils/general_utils';
let PieceList = React.createClass({
propTypes: {
accordionListItemType: React.PropTypes.object,
redirectTo: React.PropTypes.string,
customSubmitButton: React.PropTypes.element
},
mixins: [Router.Navigation, Router.State],
getDefaultProps() {
return {
accordionListItemType: AccordionListItemWallet
};
},
getInitialState() {
return mergeOptions(
PieceListStore.getState(),
@ -128,6 +135,7 @@ let PieceList = React.createClass({
render() {
let loadingElement = (<img src={AppConstants.baseUrl + 'static/img/ascribe_animated_medium.gif'} />);
let AccordionListItemType = this.props.accordionListItemType;
return (
<div>
<PieceListToolbar
@ -151,14 +159,14 @@ let PieceList = React.createClass({
loadingElement={loadingElement}>
{this.state.pieceList.map((piece, i) => {
return (
<AccordionListItem
<AccordionListItemType
className="col-xs-12 col-sm-10 col-md-8 col-lg-8 col-sm-offset-1 col-md-offset-2 col-lg-offset-2 ascribe-accordion-list-item"
content={piece}
key={i}>
<AccordionListItemTableEditions
className="ascribe-accordion-list-item-table col-xs-12 col-sm-10 col-md-8 col-lg-8 col-sm-offset-1 col-md-offset-2 col-lg-offset-2"
parentId={piece.id} />
</AccordionListItem>
</AccordionListItemType>
);
})}
</AccordionList>

View File

@ -0,0 +1,89 @@
'use strict';
import React from 'react';
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 GlobalNotificationModel from '../../../../../models/global_notification_model';
import GlobalNotificationActions from '../../../../../actions/global_notification_actions';
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 AccordionListItemWallet = React.createClass({
propTypes: {
className: React.PropTypes.string,
content: React.PropTypes.object,
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element
])
},
getInitialState() {
return mergeOptions(
PieceListStore.getState(),
WhitelabelStore.getState()
);
},
componentDidMount() {
PieceListStore.listen(this.onChange);
WhitelabelStore.listen(this.onChange);
},
componentWillUnmount() {
PieceListStore.unlisten(this.onChange);
WhitelabelStore.unlisten(this.onChange);
},
onChange(state) {
this.setState(state);
},
handleSubmitPrizeSuccess(response) {
PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search,
this.state.orderBy, this.state.orderAsc, this.state.filterBy);
let notification = new GlobalNotificationModel(response.notification, 'success', 10000);
GlobalNotificationActions.appendGlobalNotification(notification);
},
render() {
return (
<AccordionListItemPiece
className={this.props.className}
piece={this.props.content}
subsubheading={
<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>}
>
{this.props.children}
</AccordionListItemPiece>
);
}
});
export default AccordionListItemWallet;

View File

@ -4,7 +4,7 @@ import React from 'react';
import PieceList from '../../../piece_list';
import ButtonLink from 'react-router-bootstrap/lib/ButtonLink';
import AccordionListItemPrize from './ascribe_accordion_list/accordion_list_item_prize';
let PrizePieceList = React.createClass({
render() {
@ -12,6 +12,7 @@ let PrizePieceList = React.createClass({
<div>
<PieceList
redirectTo="register_piece"
accordionListItemType={AccordionListItemPrize}
customSubmitButton={
<ButtonLink to="register_piece">
Submit to prize