From e3b46c69a52de738ea38f6a6fcff17e4f3e865ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Daubensch=C3=BCtz?= Date: Tue, 4 Aug 2015 11:39:33 +0200 Subject: [PATCH] implement piece list filter widget functionality --- js/actions/piece_list_actions.js | 6 +- .../piece_list_toolbar.js | 3 +- .../piece_list_toolbar_filter_widget.js | 87 ++++++++++++++++--- js/fetchers/piece_list_fetcher.js | 20 ++++- js/stores/piece_list_store.js | 4 +- sass/ascribe_piece_list_toolbar.scss | 6 +- 6 files changed, 105 insertions(+), 21 deletions(-) diff --git a/js/actions/piece_list_actions.js b/js/actions/piece_list_actions.js index dfb9bd44..1ebe7f42 100644 --- a/js/actions/piece_list_actions.js +++ b/js/actions/piece_list_actions.js @@ -14,7 +14,7 @@ class PieceListActions { ); } - fetchPieceList(page, pageSize, search, orderBy, orderAsc) { + fetchPieceList(page, pageSize, search, orderBy, orderAsc, filterBy) { // To prevent flickering on a pagination request, // we overwrite the piecelist with an empty list before // pieceListCount === -1 defines the loading state @@ -24,6 +24,7 @@ class PieceListActions { search, orderBy, orderAsc, + filterBy, 'pieceList': [], 'pieceListCount': -1 }); @@ -32,7 +33,7 @@ class PieceListActions { return Q.Promise((resolve, reject) => { PieceListFetcher - .fetch(page, pageSize, search, orderBy, orderAsc) + .fetch(page, pageSize, search, orderBy, orderAsc, filterBy) .then((res) => { this.actions.updatePieceList({ page, @@ -40,6 +41,7 @@ class PieceListActions { search, orderBy, orderAsc, + filterBy, 'pieceList': res.pieces, 'pieceListCount': res.count }); 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 85c3c2b9..6f206c36 100644 --- a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js +++ b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar.js @@ -44,7 +44,8 @@ let PieceListToolbar = React.createClass({ addonAfter={searchIcon} /> - + diff --git a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar_filter_widget.js b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar_filter_widget.js index 389f201c..975bb9fc 100644 --- a/js/components/ascribe_piece_list_toolbar/piece_list_toolbar_filter_widget.js +++ b/js/components/ascribe_piece_list_toolbar/piece_list_toolbar_filter_widget.js @@ -2,12 +2,70 @@ import React from 'react'; +import PieceListStore from '../../stores/piece_list_store'; +import PieceListActions from '../../actions/piece_list_actions'; + import Glyphicon from 'react-bootstrap/lib/Glyphicon'; import DropdownButton from 'react-bootstrap/lib/DropdownButton'; import MenuItem from 'react-bootstrap/lib/MenuItem'; + import { getLangText } from '../../utils/lang_utils.js'; let PieceListToolbarFilterWidgetFilter = React.createClass({ + propTypes: { + filterParams: React.PropTypes.arrayOf(React.PropTypes.string).isRequired + }, + + getInitialState() { + return PieceListStore.getState(); + }, + + componentDidMount() { + PieceListStore.listen(this.onChange); + }, + + componentWillUnmount() { + PieceListStore.unlisten(this.onChange); + }, + + onChange(state) { + this.setState(state); + }, + + generateFilterByStatement(param) { + let filterBy = this.state.filterBy; + + if(filterBy) { + // we need hasOwnProperty since the values are all booleans + if(filterBy.hasOwnProperty(param)) { + filterBy[param] = !filterBy[param]; + + // if the parameter is false, then we want to remove it again + // from the list of queryParameters as this component is only about + // which actions *CAN* be done and not what *CANNOT* + if(!filterBy[param]) { + delete filterBy[param]; + } + + } else { + filterBy[param] = true; + } + } + + return filterBy; + }, + + /** + * We need overloading here to find the correct parameter of the label + * the user is clicking on. + */ + filterBy(param) { + return () => { + let filterBy = this.generateFilterByStatement(param); + PieceListActions.fetchPieceList(this.state.page, this.state.pageSize, this.state.search, + this.state.orderBy, this.state.orderAsc, filterBy); + }; + }, render() { let filterIcon = ; @@ -17,18 +75,25 @@ let PieceListToolbarFilterWidgetFilter = React.createClass({ title={filterIcon} className="ascribe-piece-list-toolbar-filter-widget">
  • - {getLangText('Show Pieces that')}: + {getLangText('Show works that')}:
  • - -
    - -
    -
    - -
    - -
    -
    + {this.props.filterParams.map((param, i) => { + let name = param.split('_')[1]; + return ( + +
    + + {getLangText('I can') + ' ' + getLangText(name)} + + +
    +
    + ); + })} ); } diff --git a/js/fetchers/piece_list_fetcher.js b/js/fetchers/piece_list_fetcher.js index bdf0ea5e..8e58402a 100644 --- a/js/fetchers/piece_list_fetcher.js +++ b/js/fetchers/piece_list_fetcher.js @@ -1,17 +1,31 @@ 'use strict'; -import { generateOrderingQueryParams } from '../utils/fetch_api_utils'; import requests from '../utils/requests'; +import { mergeOptions } from '../utils/general_utils'; +import { generateOrderingQueryParams } from '../utils/fetch_api_utils'; let PieceListFetcher = { /** * Fetches a list of pieces from the API. * Can be called with all supplied queryparams the API. */ - fetch(page, pageSize, search, orderBy, orderAsc) { + fetch(page, pageSize, search, orderBy, orderAsc, filterBy) { let ordering = generateOrderingQueryParams(orderBy, orderAsc); - return requests.get('pieces_list', { page, pageSize, search, ordering }); + + // filterBy is an object of acl key-value pairs. + // The values are booleans + let queryParams = mergeOptions( + { + page, + pageSize, + search, + ordering + }, + filterBy + ); + + return requests.get('pieces_list', queryParams); }, fetchRequestActions() { diff --git a/js/stores/piece_list_store.js b/js/stores/piece_list_store.js index a8b73e44..c1622d99 100644 --- a/js/stores/piece_list_store.js +++ b/js/stores/piece_list_store.js @@ -26,16 +26,18 @@ class PieceListStore { this.search = ''; this.orderBy = 'artist_name'; this.orderAsc = true; + this.filterBy = {}; this.bindActions(PieceListActions); } - onUpdatePieceList({ page, pageSize, search, pieceList, orderBy, orderAsc, pieceListCount }) { + onUpdatePieceList({ page, pageSize, search, pieceList, orderBy, orderAsc, pieceListCount, filterBy }) { this.page = page; this.pageSize = pageSize; this.search = search; this.orderAsc = orderAsc; this.orderBy = orderBy; this.pieceListCount = pieceListCount; + this.filterBy = filterBy; /** * Pagination - Known Issue: diff --git a/sass/ascribe_piece_list_toolbar.scss b/sass/ascribe_piece_list_toolbar.scss index cb133b4e..81141c55 100644 --- a/sass/ascribe_piece_list_toolbar.scss +++ b/sass/ascribe_piece_list_toolbar.scss @@ -5,7 +5,7 @@ } .search-bar { - max-width: 160px; + max-width: 200px; input { height: 33px; } @@ -14,8 +14,8 @@ .ascribe-piece-list-toolbar-filter-widget { margin-right: 1em; .checkbox-line { - label { - font-weight: normal; + span { + cursor: pointer; } input { position: relative;