diff --git a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js index 22034f0d..233f4089 100644 --- a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js +++ b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js @@ -3,6 +3,7 @@ import React from 'react'; import PieceListToolbarFilterWidget from './piece_list_toolbar_filter_widget'; +import PieceListToolbarOrderWidget from './piece_list_toolbar_order_widget'; import Input from 'react-bootstrap/lib/Input'; import Glyphicon from 'react-bootstrap/lib/Glyphicon'; @@ -13,8 +14,12 @@ let PieceListToolbar = React.createClass({ propTypes: { className: React.PropTypes.string, searchFor: React.PropTypes.func, + filterParams: React.PropTypes.array, filterBy: React.PropTypes.object, applyFilterBy: React.PropTypes.func, + orderParams: React.PropTypes.array, + orderBy: React.PropTypes.string, + applyOrderBy: React.PropTypes.func, children: React.PropTypes.oneOfType([ React.PropTypes.arrayOf(React.PropTypes.element), React.PropTypes.element @@ -26,6 +31,29 @@ let PieceListToolbar = React.createClass({ this.props.searchFor(searchTerm); }, + getFilterWidget(){ + if (this.props.filterParams){ + return ( + + ); + } + return null; + }, + getOrderWidget(){ + if (this.props.orderParams){ + return ( + + ); + } + return null; + }, + render() { let searchIcon = ; @@ -37,7 +65,7 @@ let PieceListToolbar = React.createClass({ {this.props.children} - + - + {this.getOrderWidget()} + {this.getFilterWidget()} diff --git a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar_order_widget.js b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar_order_widget.js new file mode 100644 index 00000000..38b92b6d --- /dev/null +++ b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar_order_widget.js @@ -0,0 +1,86 @@ +'use strict'; + +import React from 'react'; + +import DropdownButton from 'react-bootstrap/lib/DropdownButton'; +import MenuItem from 'react-bootstrap/lib/MenuItem'; + +import { getLangText } from '../../utils/lang_utils.js'; + +let PieceListToolbarOrderWidget = React.createClass({ + propTypes: { + // An array of either strings (which represent acl enums) or objects of the form + // + // { + // key: , + // label: + // } + orderParams: React.PropTypes.arrayOf(React.PropTypes.any).isRequired, + orderBy: React.PropTypes.string, + applyOrderBy: React.PropTypes.func + }, + + generateOrderByStatement(param) { + let orderBy = this.props.orderBy; + return orderBy; + }, + + /** + * We need overloading here to find the correct parameter of the label + * the user is clicking on. + */ + orderBy(orderBy) { + return () => { + this.props.applyOrderBy(orderBy); + }; + }, + + isOrderActive() { + // We're hiding the star in that complicated matter so that, + // the surrounding button is not resized up on appearance + if(this.props.orderBy.length > 0) { + return { visibility: 'visible'}; + } else { + return { visibility: 'hidden' }; + } + }, + + render() { + let filterIcon = ( + + + * + + ); + return ( + + +
  • + {getLangText('Sort by')}: +
  • + {this.props.orderParams.map((param) => { + return ( + +
    + + {getLangText(param.replace('_', ' '))} + + -1} /> +
    +
    + ); + })} +
    + ); + } +}); + +export default PieceListToolbarOrderWidget; \ No newline at end of file diff --git a/js/components/piece_list.js b/js/components/piece_list.js index d47ff980..eac6ca15 100644 --- a/js/components/piece_list.js +++ b/js/components/piece_list.js @@ -26,17 +26,27 @@ let PieceList = React.createClass({ propTypes: { accordionListItemType: React.PropTypes.func, redirectTo: React.PropTypes.string, - customSubmitButton: React.PropTypes.element + customSubmitButton: React.PropTypes.element, + filterParams: React.PropTypes.array, + orderParams: React.PropTypes.array + }, mixins: [Router.Navigation, Router.State], getDefaultProps() { return { - accordionListItemType: AccordionListItemWallet + accordionListItemType: AccordionListItemWallet, + orderParams: ['artist_name', 'title'], + filterParams: [ + 'acl_transfer', + 'acl_consign', + { + key: 'acl_create_editions', + label: 'create editions' + }] }; }, - getInitialState() { return mergeOptions( PieceListStore.getState(), @@ -104,7 +114,7 @@ let PieceList = React.createClass({ this.transitionTo(this.getPathname(), {page: 1}); }, - applyFilterBy(filterBy) { + applyFilterBy(filterBy){ // first we need to apply the filter on the piece list PieceListActions.fetchPieceList(1, this.state.pageSize, this.state.search, this.state.orderBy, this.state.orderAsc, filterBy) @@ -128,9 +138,9 @@ let PieceList = React.createClass({ this.transitionTo(this.getPathname(), {page: 1}); }, - accordionChangeOrder(orderBy, orderAsc) { + applyOrderBy(orderBy, orderAsc) { PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, - orderBy, orderAsc, this.state.filterBy); + orderBy, this.state.orderAsc, this.state.filterBy); }, render() { @@ -141,8 +151,12 @@ let PieceList = React.createClass({ + orderBy={this.state.orderBy} + applyFilterBy={this.applyFilterBy} + applyOrderBy={this.applyOrderBy}> {this.props.customSubmitButton} diff --git a/js/components/whitelabel/prize/components/piece_list.js b/js/components/whitelabel/prize/components/piece_list.js index e63d2e01..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,6 +54,8 @@ let PrizePieceList = React.createClass({ ); diff --git a/sass/ascribe_piece_list_toolbar.scss b/sass/ascribe_piece_list_toolbar.scss index 902d5be9..8756adf4 100644 --- a/sass/ascribe_piece_list_toolbar.scss +++ b/sass/ascribe_piece_list_toolbar.scss @@ -11,9 +11,39 @@ } } -.ascribe-piece-list-toolbar-filter-widget { - margin-right: 1em; +.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: transparent; + > .filter-glyph { + color: #02b6a3; + } + border: 1px solid #02b6a3; + border-left: 0; + } +} +.ascribe-piece-list-toolbar-filter-widget { + button { + background-color: rgba(0,0,0,0); + color: #02b6a3; + border: 1px solid rgba(0,0,0,0); + padding: 6px 4px 6px 8px; + &:hover, &:active { + background-color: #02b6a3 !important; + color: white; + border: 1px solid #02b6a3 !important; + } + .caret { + display: none; + } + } .filter-widget-item { > a { 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;