From d5efd79d1478c518af67118167424be30c1e0453 Mon Sep 17 00:00:00 2001 From: diminator Date: Tue, 11 Aug 2015 12:06:01 +0200 Subject: [PATCH 01/13] 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 --- .../accordion_list_item.js | 189 ++---------------- .../accordion_list_item_piece.js | 76 +++++++ .../accordion_list_item_wallet.js | 156 +++++++++++++++ js/components/piece_list.js | 14 +- .../accordion_list_item_prize.js | 89 +++++++++ .../whitelabel/prize/components/piece_list.js | 3 +- 6 files changed, 350 insertions(+), 177 deletions(-) create mode 100644 js/components/ascribe_accordion_list/accordion_list_item_piece.js create mode 100644 js/components/ascribe_accordion_list/accordion_list_item_wallet.js create mode 100644 js/components/whitelabel/prize/components/ascribe_accordion_list/accordion_list_item_prize.js diff --git a/js/components/ascribe_accordion_list/accordion_list_item.js b/js/components/ascribe_accordion_list/accordion_list_item.js index 6c07a891..37803ad2 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item.js +++ b/js/components/ascribe_accordion_list/accordion_list_item.js @@ -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 ( - {getLangText('You have actions pending in one of your editions')}}> - - ); - } - 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 ( -
- -
- ); - } - }, - - getLicences() { - // convert this to acl_view_licences later - if (this.state.whitelabel && this.state.whitelabel.name === 'Creative Commons France') { - return ( - - , - - {getLangText('%s license', this.props.content.license_type.code)} - - - ); - } - }, - 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 (
@@ -155,52 +28,22 @@ let AccordionListItem = React.createClass({
- - - + {this.props.thumbnail}
- -

{this.props.content.title}

- - -

{getLangText('by %s', this.props.content.artist_name)}

- -
- {this.props.content.date_created.split('-')[0]} - - - - - - - - {this.getLicences()} -
+ {this.props.heading} + {this.props.subheading} + {this.props.subsubheading} + {this.props.buttons}
- {this.getGlyphicon()} + {this.props.badge}
- - {this.getCreateEditionsDialog()} - - {/* this.props.children is AccordionListItemTableEditions */} {this.props.children} ); diff --git a/js/components/ascribe_accordion_list/accordion_list_item_piece.js b/js/components/ascribe_accordion_list/accordion_list_item_piece.js new file mode 100644 index 00000000..65b6454c --- /dev/null +++ b/js/components/ascribe_accordion_list/accordion_list_item_piece.js @@ -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 ( + + + } + heading={ + +

{this.props.piece.title}

+ } + subheading={ +

+ {getLangText('by %s', this.props.piece.artist_name)} +

+ } + subsubheading={this.props.subsubheading} + buttons={this.props.buttons} + badge={this.props.badge} + > + {this.props.children} +
+ ); + } +}); + +export default AccordionListItemPiece; diff --git a/js/components/ascribe_accordion_list/accordion_list_item_wallet.js b/js/components/ascribe_accordion_list/accordion_list_item_wallet.js new file mode 100644 index 00000000..3cb557ef --- /dev/null +++ b/js/components/ascribe_accordion_list/accordion_list_item_wallet.js @@ -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 ( + {getLangText('You have actions pending in one of your editions')}}> + + ); + } + 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 ( +
+ +
+ ); + } + }, + + getLicences() { + // convert this to acl_view_licences later + if (this.state.whitelabel && this.state.whitelabel.name === 'Creative Commons France') { + return ( + + , + + {getLangText('%s license', this.props.content.license_type.code)} + + + ); + } + }, + + render() { + + return ( + + {this.props.content.date_created.split('-')[0]} + {this.getLicences()} + } + buttons={ +
+ + + +
} + badge={this.getGlyphicon()}> + {this.getCreateEditionsDialog()} + {/* this.props.children is AccordionListItemTableEditions */} + {this.props.children} +
+ ); + } +}); + +export default AccordionListItemWallet; diff --git a/js/components/piece_list.js b/js/components/piece_list.js index 78917f61..566921f2 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -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 = (); + let AccordionListItemType = this.props.accordionListItemType; return (
{this.state.pieceList.map((piece, i) => { return ( - - + ); })} diff --git a/js/components/whitelabel/prize/components/ascribe_accordion_list/accordion_list_item_prize.js b/js/components/whitelabel/prize/components/ascribe_accordion_list/accordion_list_item_prize.js new file mode 100644 index 00000000..263d7f08 --- /dev/null +++ b/js/components/whitelabel/prize/components/ascribe_accordion_list/accordion_list_item_prize.js @@ -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 ( + + {this.props.content.date_created.split('-')[0]} +
} + buttons={ +
+ + + +
} + > + {this.props.children} + + ); + } +}); + +export default AccordionListItemWallet; diff --git a/js/components/whitelabel/prize/components/piece_list.js b/js/components/whitelabel/prize/components/piece_list.js index 73674e25..230bf7de 100644 --- a/js/components/whitelabel/prize/components/piece_list.js +++ b/js/components/whitelabel/prize/components/piece_list.js @@ -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({
Submit to prize From 22727c2703600114703b0e1ab9b95f1bcf7a4155 Mon Sep 17 00:00:00 2001 From: diminator Date: Tue, 11 Aug 2015 17:12:12 +0200 Subject: [PATCH 02/13] refactored piece container and detail --- .../collapsible_paragraph.js | 2 +- .../ascribe_detail/detail_property.js | 10 +- .../ascribe_detail/media_container.js | 28 +++- js/components/ascribe_detail/piece.js | 147 ++--------------- .../ascribe_detail/piece_container.js | 152 ++++++++++++++++-- js/components/piece_list.js | 2 +- .../accordion_list_item_prize.js | 75 ++++++--- .../ascribe_detail/piece_container.js | 85 ++++++++-- sass/main.scss | 4 + 9 files changed, 312 insertions(+), 193 deletions(-) diff --git a/js/components/ascribe_collapsible/collapsible_paragraph.js b/js/components/ascribe_collapsible/collapsible_paragraph.js index e04e82c2..8b3b3cf4 100644 --- a/js/components/ascribe_collapsible/collapsible_paragraph.js +++ b/js/components/ascribe_collapsible/collapsible_paragraph.js @@ -23,7 +23,7 @@ const CollapsibleParagraph = React.createClass({ getInitialState() { return { - expanded: false + expanded: this.props.defaultExpanded }; }, diff --git a/js/components/ascribe_detail/detail_property.js b/js/components/ascribe_detail/detail_property.js index f220fc98..991226f9 100644 --- a/js/components/ascribe_detail/detail_property.js +++ b/js/components/ascribe_detail/detail_property.js @@ -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 (
-
- { this.props.label + this.props.separator} +
+ { this.props.label } { this.props.separator}
{value}
diff --git a/js/components/ascribe_detail/media_container.js b/js/components/ascribe_detail/media_container.js index 529817c3..6ac2f745 100644 --- a/js/components/ascribe_detail/media_container.js +++ b/js/components/ascribe_detail/media_container.js @@ -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() { diff --git a/js/components/ascribe_detail/piece.js b/js/components/ascribe_detail/piece.js index 3fabb055..ed312f5f 100644 --- a/js/components/ascribe_detail/piece.js +++ b/js/components/ascribe_detail/piece.js @@ -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 ( -
- -
-
- ); - } else { - return (
); - } - }, - - 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({ -
-

{this.props.piece.title}

-
- - - {this.props.piece.num_editions > 0 ? : null} -
-
-
- -
+ {this.props.header} + {this.props.subheader} + {this.props.buttons} - - - - - - {this.getCreateEditionsDialog()} {this.props.children} diff --git a/js/components/ascribe_detail/piece_container.js b/js/components/ascribe_detail/piece_container.js index 8e3a5750..8625f7a0 100644 --- a/js/components/ascribe_detail/piece_container.js +++ b/js/components/ascribe_detail/piece_container.js @@ -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 ( +
+ +
+
+ ); + } else { + return (
); + } + }, + + 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 ( + loadPiece={this.loadPiece} + header={ +
+

{this.state.piece.title}

+
+ + + {this.state.piece.num_editions > 0 ? : null} +
+
+ } + subheader={ +
+ +
+ } + buttons={ + + + + + }> + {this.getCreateEditionsDialog()} + + + +
); + } + else { + // jury and no rating yet + return ( +
+ + Submit your rating + +
+ ); + } + } + // participant + return ( +
+ + + +
+ ); + }, + render() { return ( @@ -68,22 +118,11 @@ let AccordionListItemWallet = React.createClass({
{this.props.content.date_created.split('-')[0]}
} - buttons={ -
- - - -
} - > + buttons={this.getPrizeButtons()}> {this.props.children} ); } }); -export default AccordionListItemWallet; +export default AccordionListItemPrize; diff --git a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js index b6363868..a455b1a4 100644 --- a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js +++ b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js @@ -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 ( + loadPiece={this.loadPiece} + header={ +
+

{this.state.piece.title}

+
+ + +
+
+ } + subheader={ + + }>
); @@ -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 ( + YOUR VOTE + } + value={ + } + />); + } +}); + +let PrizePieceDetails = React.createClass({ + propTypes: { + piece: React.PropTypes.object }, render() { diff --git a/sass/main.scss b/sass/main.scss index c83379b3..a81f303f 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -387,4 +387,8 @@ hr { .rating-container .rating-stars { width: 25px; color: #000; +} + +.react-rating-caption { + font-size: 1em; } \ No newline at end of file From c25de71b4bbf9abb63663c0db115074f18cb42ec Mon Sep 17 00:00:00 2001 From: diminator Date: Wed, 12 Aug 2015 13:21:05 +0200 Subject: [PATCH 03/13] notes and bug fixes --- .../ascribe_detail/piece_container.js | 107 +++++++++++++++--- .../whitelabel/prize/constants/api_urls.js | 5 +- .../prize/fetchers/prize_rating_fetcher.js | 2 +- 3 files changed, 94 insertions(+), 20 deletions(-) diff --git a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js index a455b1a4..b552f073 100644 --- a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js +++ b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js @@ -13,6 +13,8 @@ import PieceListActions from '../../../../../actions/piece_list_actions'; import PrizeRatingActions from '../../actions/prize_rating_actions'; import PrizeRatingStore from '../../stores/prize_rating_store'; +import UserStore from '../../../../../stores/user_store'; + import Piece from '../../../../../components/ascribe_detail/piece'; import AppConstants from '../../../../../constants/application_constants'; @@ -22,8 +24,12 @@ 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 GlobalNotificationModel from '../../../../../models/global_notification_model'; +import GlobalNotificationActions from '../../../../../actions/global_notification_actions'; + import DetailProperty from '../../../../ascribe_detail/detail_property'; +import ApiUrls from '../../../../../constants/api_urls'; import { mergeOptions } from '../../../../../utils/general_utils'; import { getLangText } from '../../../../../utils/lang_utils'; /** @@ -64,6 +70,7 @@ let PieceContainer = React.createClass({ loadPiece={this.loadPiece} header={
+

{this.state.piece.title}


@@ -87,6 +94,21 @@ let PieceContainer = React.createClass({ } }); +let NavigationHeader = React.createClass({ + propTypes: { + piece: React.PropTypes.object + }, + + render() { + return ( +
+ navigation +
+ ); + } +}); + + let PrizePieceRatings = React.createClass({ propTypes: { piece: React.PropTypes.object @@ -95,7 +117,8 @@ let PrizePieceRatings = React.createClass({ getInitialState() { return mergeOptions( PieceListStore.getState(), - PrizeRatingStore.getState() + PrizeRatingStore.getState(), + UserStore.getState() ); }, @@ -103,6 +126,7 @@ let PrizePieceRatings = React.createClass({ PrizeRatingStore.listen(this.onChange); PrizeRatingActions.fetchOne(this.props.piece.id); PieceListStore.listen(this.onChange); + UserStore.listen(this.onChange); }, componentWillUnmount() { @@ -113,6 +137,7 @@ let PrizePieceRatings = React.createClass({ PrizeRatingActions.updateRating({}); PrizeRatingStore.unlisten(this.onChange); PieceListStore.unlisten(this.onChange); + UserStore.unlisten(this.onChange); }, onChange(state) { @@ -135,26 +160,72 @@ let PrizePieceRatings = React.createClass({ ); }, render(){ - return ( - YOUR VOTE - } - value={ - } - />); + if (this.state.currentUser && this.state.currentUser.is_jury) { + return ( +
+ YOUR VOTE + } + value={ + + }/> + +
); + } + return null; } }); +let PersonalNote = React.createClass({ + propTypes: { + piece: React.PropTypes.object, + currentUser: React.PropTypes.object + }, + showNotification(){ + let notification = new GlobalNotificationModel(getLangText('Jury note saved'), 'success'); + GlobalNotificationActions.appendGlobalNotification(notification); + }, + + render() { + if (this.props.currentUser.username && true || false) { + return ( +
+ + + + +
+
+ ); + } + return null; + } +}); + + let PrizePieceDetails = React.createClass({ propTypes: { piece: React.PropTypes.object diff --git a/js/components/whitelabel/prize/constants/api_urls.js b/js/components/whitelabel/prize/constants/api_urls.js index 480e8d4f..a62d455b 100644 --- a/js/components/whitelabel/prize/constants/api_urls.js +++ b/js/components/whitelabel/prize/constants/api_urls.js @@ -16,7 +16,10 @@ function getApiUrls(subdomain) { 'jury_activate': AppPrizeConstants.prizeApiEndpoint + subdomain + '/jury/${email}/activate/', 'jury_resend': AppPrizeConstants.prizeApiEndpoint + subdomain + '/jury/${email}/resend/', 'ratings': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/', - 'rating': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/${piece_id}/' + 'rating': AppPrizeConstants.prizeApiEndpoint + subdomain + '/ratings/${piece_id}/', + 'notes': AppPrizeConstants.prizeApiEndpoint + subdomain + '/notes/', + 'note': AppPrizeConstants.prizeApiEndpoint + subdomain + '/notes/${piece_id}/' + }; } diff --git a/js/components/whitelabel/prize/fetchers/prize_rating_fetcher.js b/js/components/whitelabel/prize/fetchers/prize_rating_fetcher.js index 91da0051..b7af8845 100644 --- a/js/components/whitelabel/prize/fetchers/prize_rating_fetcher.js +++ b/js/components/whitelabel/prize/fetchers/prize_rating_fetcher.js @@ -13,7 +13,7 @@ let PrizeRatingFetcher = { }, rate(pieceId, rating) { - return requests.post('ratings', {body: {'piece_id': pieceId, 'rating': rating}}); + return requests.post('ratings', {body: {'piece_id': pieceId, 'value': rating}}); } }; From 97c298e304d26af80115fac043ac6d1c0f582a33 Mon Sep 17 00:00:00 2001 From: diminator Date: Wed, 12 Aug 2015 16:47:16 +0200 Subject: [PATCH 04/13] piece navigation prev next WIP --- .../ascribe_detail/detail_property.js | 2 +- .../ascribe_detail/piece_container.js | 61 ++++++++++++++----- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/js/components/ascribe_detail/detail_property.js b/js/components/ascribe_detail/detail_property.js index 991226f9..828ed81a 100644 --- a/js/components/ascribe_detail/detail_property.js +++ b/js/components/ascribe_detail/detail_property.js @@ -17,7 +17,7 @@ let DetailProperty = React.createClass({ getDefaultProps() { return { - separator: ':', + separator: '', 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' }; diff --git a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js index b552f073..069548ce 100644 --- a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js +++ b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js @@ -1,6 +1,7 @@ 'use strict'; import React from 'react'; +import Router from 'react-router'; import StarRating from 'react-star-rating'; @@ -32,17 +33,23 @@ import DetailProperty from '../../../../ascribe_detail/detail_property'; import ApiUrls from '../../../../../constants/api_urls'; import { mergeOptions } from '../../../../../utils/general_utils'; import { getLangText } from '../../../../../utils/lang_utils'; + +let Link = Router.Link; + /** * This is the component that implements resource/data specific functionality */ let PieceContainer = React.createClass({ getInitialState() { - return PieceStore.getState(); + return mergeOptions( + PieceStore.getState(), + UserStore.getState() + ); }, componentDidMount() { PieceStore.listen(this.onChange); - PieceActions.fetchOne(this.props.params.pieceId); + UserStore.listen(this.onChange); }, componentWillUnmount() { @@ -52,6 +59,16 @@ let PieceContainer = React.createClass({ // the piece detail a second time PieceActions.updatePiece({}); PieceStore.unlisten(this.onChange); + UserStore.unlisten(this.onChange); + }, + + componentDidUpdate() { + console.log('call me ') + PieceActions.fetchOne(this.props.params.pieceId); + }, + + shouldComponentUpdate(nextProps, nextState) { + return this.props.params.pieceId !== nextProps.params.pieceId }, onChange(state) { @@ -63,6 +80,7 @@ let PieceContainer = React.createClass({ }, render() { + console.log(this.props) if('title' in this.state.piece) { return ( - +

{this.state.piece.title}


@@ -79,7 +99,9 @@ let PieceContainer = React.createClass({
} subheader={ - + }> @@ -96,13 +118,26 @@ let PieceContainer = React.createClass({ let NavigationHeader = React.createClass({ propTypes: { - piece: React.PropTypes.object + piece: React.PropTypes.object, + currentUser: React.PropTypes.object }, render() { return ( -
- navigation +
+
+ + + + + + Next + + + +
); } @@ -111,14 +146,14 @@ let NavigationHeader = React.createClass({ let PrizePieceRatings = React.createClass({ propTypes: { - piece: React.PropTypes.object + piece: React.PropTypes.object, + currentUser: React.PropTypes.object }, getInitialState() { return mergeOptions( PieceListStore.getState(), - PrizeRatingStore.getState(), - UserStore.getState() + PrizeRatingStore.getState() ); }, @@ -126,7 +161,6 @@ let PrizePieceRatings = React.createClass({ PrizeRatingStore.listen(this.onChange); PrizeRatingActions.fetchOne(this.props.piece.id); PieceListStore.listen(this.onChange); - UserStore.listen(this.onChange); }, componentWillUnmount() { @@ -137,7 +171,6 @@ let PrizePieceRatings = React.createClass({ PrizeRatingActions.updateRating({}); PrizeRatingStore.unlisten(this.onChange); PieceListStore.unlisten(this.onChange); - UserStore.unlisten(this.onChange); }, onChange(state) { @@ -160,7 +193,7 @@ let PrizePieceRatings = React.createClass({ ); }, render(){ - if (this.state.currentUser && this.state.currentUser.is_jury) { + if (this.props.currentUser && this.props.currentUser.is_jury) { return (
+ currentUser={this.props.currentUser}/>
); } return null; From 7c0e2312a11fead7e9f014632978d0b98c9062ee Mon Sep 17 00:00:00 2001 From: diminator Date: Wed, 12 Aug 2015 17:09:48 +0200 Subject: [PATCH 05/13] revert piece navigation and bug fix in navigation serializer --- .../ascribe_detail/piece_container.js | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js index 069548ce..768a18e9 100644 --- a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js +++ b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js @@ -49,6 +49,7 @@ let PieceContainer = React.createClass({ componentDidMount() { PieceStore.listen(this.onChange); + PieceActions.fetchOne(this.props.params.pieceId); UserStore.listen(this.onChange); }, @@ -62,15 +63,6 @@ let PieceContainer = React.createClass({ UserStore.unlisten(this.onChange); }, - componentDidUpdate() { - console.log('call me ') - PieceActions.fetchOne(this.props.params.pieceId); - }, - - shouldComponentUpdate(nextProps, nextState) { - return this.props.params.pieceId !== nextProps.params.pieceId - }, - onChange(state) { this.setState(state); }, @@ -123,23 +115,27 @@ let NavigationHeader = React.createClass({ }, render() { - return ( -
-
- - - - - - Next - - - + if (this.props.currentUser && this.props.currentUser.is_jury && this.props.piece.navigation) { + let nav = this.props.piece.navigation; + return ( +
+
+ + + + + + Next + + + +
-
- ); + ); + } + return null; } }); From 81ff4641c7b04cf9938eef364fbad485cad669d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Wed, 12 Aug 2015 17:30:39 +0200 Subject: [PATCH 06/13] fix prev and next button for navigationheader --- .../components/ascribe_detail/piece_container.js | 12 +++++++++--- sass/main.scss | 7 +++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js index 768a18e9..175757d7 100644 --- a/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js +++ b/js/components/whitelabel/prize/components/ascribe_detail/piece_container.js @@ -63,6 +63,13 @@ let PieceContainer = React.createClass({ UserStore.unlisten(this.onChange); }, + componentWillReceiveProps(nextProps) { + if(this.props.params.pieceId !== nextProps.params.pieceId) { + PieceActions.updatePiece({}); + PieceActions.fetchOne(nextProps.params.pieceId); + } + }, + onChange(state) { this.setState(state); }, @@ -72,7 +79,6 @@ let PieceContainer = React.createClass({ }, render() { - console.log(this.props) if('title' in this.state.piece) { return (
- + - + Next diff --git a/sass/main.scss b/sass/main.scss index a81f303f..4071e727 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -391,4 +391,11 @@ hr { .react-rating-caption { font-size: 1em; +} + +.disable-select { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } \ No newline at end of file From 247cca3ee20865e9058b890ac25dcaa84b758175 Mon Sep 17 00:00:00 2001 From: diminator Date: Thu, 13 Aug 2015 13:28:09 +0200 Subject: [PATCH 07/13] piece rating + navigation OK close prize --- .../accordion_list_item_piece.js | 3 +- .../prize/actions/prize_rating_actions.js | 2 - .../accordion_list_item_prize.js | 7 +- .../ascribe_detail/piece_container.js | 34 ++++---- .../whitelabel/prize/components/landing.js | 77 +++++++++++++++---- .../whitelabel/prize/components/piece_list.js | 36 +++++++-- sass/main.scss | 10 +++ 7 files changed, 126 insertions(+), 43 deletions(-) diff --git a/js/components/ascribe_accordion_list/accordion_list_item_piece.js b/js/components/ascribe_accordion_list/accordion_list_item_piece.js index 65b6454c..e1271b0a 100644 --- a/js/components/ascribe_accordion_list/accordion_list_item_piece.js +++ b/js/components/ascribe_accordion_list/accordion_list_item_piece.js @@ -60,7 +60,8 @@ let AccordionListItemPiece = React.createClass({ } subheading={

- {getLangText('by %s', this.props.piece.artist_name)} + {getLangText('by ')} + {this.props.artistName ? this.props.artistName : this.props.piece.artist_name}

} subsubheading={this.props.subsubheading} diff --git a/js/components/whitelabel/prize/actions/prize_rating_actions.js b/js/components/whitelabel/prize/actions/prize_rating_actions.js index 536445f8..e36023a0 100644 --- a/js/components/whitelabel/prize/actions/prize_rating_actions.js +++ b/js/components/whitelabel/prize/actions/prize_rating_actions.js @@ -37,7 +37,6 @@ class PrizeRatingActions { resolve(res); }) .catch((err) => { - console.logGlobal(err); reject(err); }); }); @@ -52,7 +51,6 @@ class PrizeRatingActions { resolve(res); }) .catch((err) => { - console.logGlobal(err); reject(err); }); }); diff --git a/js/components/whitelabel/prize/components/ascribe_accordion_list/accordion_list_item_prize.js b/js/components/whitelabel/prize/components/ascribe_accordion_list/accordion_list_item_prize.js index 0c41ca57..73c82ca4 100644 --- a/js/components/whitelabel/prize/components/ascribe_accordion_list/accordion_list_item_prize.js +++ b/js/components/whitelabel/prize/components/ascribe_accordion_list/accordion_list_item_prize.js @@ -69,7 +69,7 @@ let AccordionListItemPrize = React.createClass({ // jury and rating available let rating = parseInt(this.props.content.ratings.rating, 10); return ( -
+
@@ -121,18 +123,18 @@ let NavigationHeader = React.createClass({ }, render() { - if (this.props.currentUser && this.props.currentUser.is_jury && this.props.piece.navigation) { + if (this.props.currentUser && this.props.piece.navigation) { let nav = this.props.piece.navigation; return (
-
diff --git a/js/components/whitelabel/prize/components/piece_list.js b/js/components/whitelabel/prize/components/piece_list.js index 2e570aed..2c838b6d 100644 --- a/js/components/whitelabel/prize/components/piece_list.js +++ b/js/components/whitelabel/prize/components/piece_list.js @@ -3,23 +3,34 @@ import React from 'react'; import PieceList from '../../../piece_list'; +import UserActions from '../../../../actions/user_actions'; +import UserStore from '../../../../stores/user_store'; + import PrizeActions from '../actions/prize_actions'; import PrizeStore from '../stores/prize_store'; import ButtonLink from 'react-router-bootstrap/lib/ButtonLink'; import AccordionListItemPrize from './ascribe_accordion_list/accordion_list_item_prize'; +import { mergeOptions } from '../../../../utils/general_utils'; + let PrizePieceList = React.createClass({ getInitialState() { - return PrizeStore.getState(); + return mergeOptions( + PrizeStore.getState(), + UserStore.getState() + ); }, componentDidMount() { + UserStore.listen(this.onChange); + UserActions.fetchCurrentUser(); PrizeStore.listen(this.onChange); PrizeActions.fetchPrize(); }, componentWillUnmount() { + UserStore.unlisten(this.onChange); PrizeStore.unlisten(this.onChange); }, @@ -43,7 +54,8 @@ let PrizePieceList = React.createClass({
); diff --git a/sass/ascribe_piece_list_toolbar.scss b/sass/ascribe_piece_list_toolbar.scss index 44ded8a6..8756adf4 100644 --- a/sass/ascribe_piece_list_toolbar.scss +++ b/sass/ascribe_piece_list_toolbar.scss @@ -14,11 +14,13 @@ .ascribe-input-glyph > .form-group > .input-group { margin-left: 6px; input { + box-shadow: none; + background-color: transparent; border: 1px solid #02b6a3; border-right: 0; } > .input-group-addon { - background-color: white; + background-color: transparent; > .filter-glyph { color: #02b6a3; } diff --git a/sass/main.scss b/sass/main.scss index a657b002..de166b0c 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -80,6 +80,25 @@ hr { font-size: 0.8em; } +.navbar-default .navbar-nav > .active { + a { + background-color: transparent!important; + > span {color: #02b6a3;} + color: #02b6a3; + border-bottom: 1px solid #02b6a3; + + &:hover, &:focus{ + > span {color: #02b6a3;} + color: #02b6a3; + background-color: transparent; + border-bottom: 1px solid #02b6a3; + } + } +} +.navbar-default .navbar-nav > li > a { + border: 1px solid rgba(0,0,0,0); +} + .img-brand { padding: 0; height: 45px;