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:
parent
48508d5756
commit
a96aa1005f
@ -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,
|
||||||
|
@ -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>
|
||||||
|
@ -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}
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user