onion/js/components/ascribe_piece_list_toolbar/piece_list_toolbar_filter_w...

149 lines
5.7 KiB
JavaScript
Raw Normal View History

'use strict';
2015-06-02 11:40:55 +02:00
import React from 'react';
import DropdownButton from 'react-bootstrap/lib/DropdownButton';
2015-08-04 10:06:02 +02:00
import { getLangText } from '../../utils/lang_utils.js';
2015-06-02 11:40:55 +02:00
2015-11-03 10:39:01 +01:00
let PieceListToolbarFilterWidget = React.createClass({
propTypes: {
2015-09-16 23:36:21 +02:00
filterParams: React.PropTypes.arrayOf(
React.PropTypes.shape({
label: React.PropTypes.string,
items: React.PropTypes.arrayOf(
React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.shape({
key: React.PropTypes.string,
label: React.PropTypes.string
})
])
)
2015-09-16 23:36:21 +02:00
})
).isRequired,
2015-08-06 13:15:52 +02:00
filterBy: React.PropTypes.object,
applyFilterBy: React.PropTypes.func
},
generateFilterByStatement(param) {
2015-11-24 19:26:45 +01:00
const filterBy = Object.assign({}, this.props.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 () => {
const filterBy = this.generateFilterByStatement(param);
2015-08-06 13:15:52 +02:00
this.props.applyFilterBy(filterBy);
};
},
2015-08-04 10:06:02 +02:00
isFilterActive() {
const trueValuesOnly = Object.keys(this.props.filterBy).filter((acl) => acl);
// We're hiding the star in that complicated matter so that,
// the surrounding button is not resized up on appearance
if (trueValuesOnly.length) {
return { visibility: 'visible'};
} else {
return { visibility: 'hidden' };
}
},
2015-06-02 11:40:55 +02:00
render() {
const filterIcon = (
<span>
2015-10-09 13:14:29 +02:00
<span className="ascribe-icon icon-ascribe-filter" aria-hidden="true"></span>
<span style={this.isFilterActive()}>*</span>
</span>
);
2015-06-02 11:40:55 +02:00
if (this.props.filterParams && this.props.filterParams.length) {
return (
<DropdownButton
id="ascribe-piece-list-toolbar-filter-widget-dropdown"
pullRight={true}
title={filterIcon}
className="ascribe-piece-list-toolbar-filter-widget">
{/* We iterate over filterParams, to receive the label and then for each
label also iterate over its items, to get all filterable options */}
{this.props.filterParams.map(({ label, items }, i) => {
return (
2016-01-11 11:36:50 +01:00
<div key={label}>
<li style={{'textAlign': 'center'}}>
<em>{label}:</em>
</li>
{items.map((paramItem) => {
let itemLabel;
let param;
// As can be seen in the PropTypes, a param can either
// be a string or an object of the shape:
//
// {
// key: <String>,
// label: <String>
// }
//
// This is why we need to distinguish between both here.
if (typeof paramItem !== 'string') {
param = paramItem.key;
itemLabel = paramItem.label;
} else {
param = paramItem;
itemLabel = paramItem.split('acl_')[1].replace(/_/g, ' ');
}
return (
<li
key={itemLabel}
onClick={this.filterBy(param)}
className="filter-widget-item">
<div className="checkbox-line">
<span>
{getLangText(itemLabel)}
</span>
<input
readOnly
type="checkbox"
checked={this.props.filterBy[param]} />
</div>
</li>
);
})}
</div>
);
})}
</DropdownButton>
);
} else {
return null;
}
2015-06-02 11:40:55 +02:00
}
});
export default PieceListToolbarFilterWidget;