1
0
mirror of https://github.com/ascribe/onion.git synced 2025-01-03 10:25:08 +01:00

Make PieceListToolbar filters generic

This commit is contained in:
Tim Daubenschütz 2015-09-16 23:36:21 +02:00
parent 48508d5756
commit a96aa1005f
6 changed files with 126 additions and 50 deletions

View File

@ -14,7 +14,12 @@ let PieceListToolbar = React.createClass({
propTypes: { propTypes: {
className: React.PropTypes.string, className: React.PropTypes.string,
searchFor: React.PropTypes.func, searchFor: React.PropTypes.func,
filterParams: React.PropTypes.array, filterParams: React.PropTypes.arrayOf(
React.PropTypes.shape({
label: React.PropTypes.string,
items: React.PropTypes.array
})
),
filterBy: React.PropTypes.object, filterBy: React.PropTypes.object,
applyFilterBy: React.PropTypes.func, applyFilterBy: React.PropTypes.func,
orderParams: React.PropTypes.array, orderParams: React.PropTypes.array,

View File

@ -16,7 +16,12 @@ let PieceListToolbarFilterWidgetFilter = React.createClass({
// label: <a human readable string> // label: <a human readable string>
// } // }
// //
filterParams: React.PropTypes.arrayOf(React.PropTypes.any).isRequired, filterParams: React.PropTypes.arrayOf(
React.PropTypes.shape({
label: React.PropTypes.string,
items: React.PropTypes.array
})
).isRequired,
filterBy: React.PropTypes.object, filterBy: React.PropTypes.object,
applyFilterBy: React.PropTypes.func applyFilterBy: React.PropTypes.func
}, },
@ -79,35 +84,43 @@ let PieceListToolbarFilterWidgetFilter = React.createClass({
<DropdownButton <DropdownButton
title={filterIcon} title={filterIcon}
className="ascribe-piece-list-toolbar-filter-widget"> className="ascribe-piece-list-toolbar-filter-widget">
<li style={{'textAlign': 'center'}}> {this.props.filterParams.map(({ label, items }, i) => {
<em>{getLangText('Show works I can')}:</em>
</li>
{this.props.filterParams.map((param, i) => {
let label;
if(typeof param !== 'string') {
label = param.label;
param = param.key;
} else {
param = param;
label = param.split('_')[1];
}
return ( return (
<MenuItem <div>
key={i} <li
onClick={this.filterBy(param)} style={{'textAlign': 'center'}}
className="filter-widget-item"> key={i}>
<div className="checkbox-line"> <em>{label}:</em>
<span> </li>
{getLangText(label)} {items.map((param, j) => {
</span> let label;
<input
readOnly if(typeof param !== 'string') {
type="checkbox" label = param.label;
checked={this.props.filterBy[param]} /> param = param.key;
</div> } else {
</MenuItem> param = param;
label = param.split('_')[1];
}
return (
<li
key={j}
onClick={this.filterBy(param)}
className="filter-widget-item">
<div className="checkbox-line">
<span>
{getLangText(label)}
</span>
<input
readOnly
type="checkbox"
checked={this.props.filterBy[param]} />
</div>
</li>
);
})}
</div>
); );
})} })}
</DropdownButton> </DropdownButton>

View File

@ -35,7 +35,6 @@ let PieceList = React.createClass({
filterParams: React.PropTypes.array, filterParams: React.PropTypes.array,
orderParams: React.PropTypes.array, orderParams: React.PropTypes.array,
orderBy: React.PropTypes.string orderBy: React.PropTypes.string
}, },
mixins: [Router.Navigation, Router.State], mixins: [Router.Navigation, Router.State],
@ -44,13 +43,20 @@ let PieceList = React.createClass({
return { return {
accordionListItemType: AccordionListItemWallet, accordionListItemType: AccordionListItemWallet,
orderParams: ['artist_name', 'title'], orderParams: ['artist_name', 'title'],
filterParams: [ filterParams: [{
label: getLangText('Show works I can'),
items: [
'acl_transfer', 'acl_transfer',
'acl_consign', 'acl_consign',
{ {
key: 'acl_create_editions', key: 'acl_create_editions',
label: 'create editions' label: 'create editions'
}] }]
},
{
label: getLangText('Show works I have'),
items: ['acl_loaned']
}]
}; };
}, },
getInitialState() { getInitialState() {
@ -95,8 +101,8 @@ let PieceList = React.createClass({
// the site should go to the top // the site should go to the top
document.body.scrollTop = document.documentElement.scrollTop = 0; document.body.scrollTop = document.documentElement.scrollTop = 0;
PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search, PieceListActions.fetchPieceList(page, this.state.pageSize, this.state.search,
this.state.orderBy, this.state.orderAsc, this.state.orderBy, this.state.orderAsc,
this.state.filterBy); this.state.filterBy);
}; };
}, },
@ -167,7 +173,9 @@ let PieceList = React.createClass({
{this.props.customSubmitButton} {this.props.customSubmitButton}
</PieceListToolbar> </PieceListToolbar>
<PieceListBulkModal className="ascribe-piece-list-bulk-modal" /> <PieceListBulkModal className="ascribe-piece-list-bulk-modal" />
<PieceListFilterDisplay filterBy={this.state.filterBy} /> <PieceListFilterDisplay
filterBy={this.state.filterBy}
filterParams={this.props.filterParams}/>
<AccordionList <AccordionList
className="ascribe-accordion-list" className="ascribe-accordion-list"
changeOrder={this.accordionChangeOrder} changeOrder={this.accordionChangeOrder}

View File

@ -7,24 +7,68 @@ import { getLangText } from '../utils/lang_utils';
let PieceListFilterDisplay = React.createClass({ let PieceListFilterDisplay = React.createClass({
propTypes: { propTypes: {
filterBy: React.PropTypes.string filterBy: React.PropTypes.object,
filterParams: React.PropTypes.arrayOf(
React.PropTypes.shape({
label: React.PropTypes.string,
items: React.PropTypes.array
})
)
}, },
getFilterText() { transformFilterParamsItemsToBools() {
let { filterBy } = this.props; let { filterParams, filterBy } = this.props;
let filterText = '';
filterText += getLangText('Showing works that I can: ') return filterParams.map((filterParam) => {
// take every filter, split it on acl_ and join the resulting array as a comma separated list return {
filterText += Object.keys(filterBy).map((filter) => filter.split('acl_')[1]).join(', '); label: filterParam.label,
items: filterParam.items.map((item) => {
if(typeof item !== 'string' && typeof item.key === 'string' && typeof item.label === 'string') {
return {
key: item.key,
label: item.label,
value: filterBy[item.key] ? filterBy[item.key] : false
};
} else {
return {
key: item,
label: item.split('acl_')[1].replace(/_/g, ' '),
value: filterBy[item] ? filterBy[item] : false
}
}
})
}
});
},
// there are acls, like acl_create_editions that still have underscores in them, getFilterText(filtersWithLabel) {
// therefore we need to replace all underscores with spaces let filterTextList = filtersWithLabel
return filterText.replace(/_/g, ' '); .map((filterWithLabel) => {
let activeFilterWithLabel = filterWithLabel
.items
.map((filter) => {
if(filter.value) {
return filter.label;
}
})
.filter((filterName) => !!filterName)
.join(', ');
if(activeFilterWithLabel) {
return filterWithLabel.label + ': ' + activeFilterWithLabel
}
})
.filter((filterText) => !!filterText)
// if there are multiple sentences, capitalize the first one and lowercase the others
.map((filterText, i) => i === 0 ? filterText.charAt(0).toUpperCase() + filterText.substr(1) : filterText.charAt(0).toLowerCase() + filterText.substr(1))
.join(' and ');
return filterTextList;
}, },
render() { render() {
let { filterBy } = this.props; let { filterBy } = this.props;
let filtersWithLabel = this.transformFilterParamsItemsToBools();
// do not show the FilterDisplay if there are no filters applied // do not show the FilterDisplay if there are no filters applied
if(filterBy && Object.keys(filterBy).length === 0) { if(filterBy && Object.keys(filterBy).length === 0) {
@ -33,7 +77,7 @@ let PieceListFilterDisplay = React.createClass({
return ( return (
<div className="row"> <div className="row">
<div className="ascribe-piece-list-filter-display col-xs-12 col-sm-10 col-md-8 col-lg-8 col-sm-offset-1 col-md-offset-2 col-lg-offset-2"> <div className="ascribe-piece-list-filter-display col-xs-12 col-sm-10 col-md-8 col-lg-8 col-sm-offset-1 col-md-offset-2 col-lg-offset-2">
{this.getFilterText()} {this.getFilterText(filtersWithLabel)}
<hr /> <hr />
</div> </div>
</div> </div>

View File

@ -54,8 +54,7 @@
} }
.filter-widget-item { .filter-widget-item {
a {
> a {
padding-left: 0; padding-left: 0;
padding-right: 0; padding-right: 0;
} }
@ -64,6 +63,13 @@
.checkbox-line { .checkbox-line {
height: 25px; height: 25px;
position: relative; position: relative;
color: #333333;
/* Fuck you react-bootstrap */
&:hover {
background-color: $dropdown-link-hover-bg;
cursor: pointer;
}
span { span {
cursor: pointer; cursor: pointer;

View File

@ -490,8 +490,8 @@ hr {
.ascribe-piece-list-filter-display { .ascribe-piece-list-filter-display {
padding-left: 0; padding-left: 10px;
padding-right: 0; padding-right: 10px;
> span { > span {
font-size: 1.1em; font-size: 1.1em;