Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to shown options for several different fields in same filter #1179

Merged
merged 4 commits into from
Sep 10, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- Added `maxWidth` prop to `EuiModal` ([#1165](https://github.com/elastic/eui/pull/1165))
- Added ability to include multiple fields in a value selection filter for `EuiSearchBar` ([#1179](https://github.com/elastic/eui/pull/1179))

**Bug fixes**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ exports[`EuiSearchFilters render - with filters 1`] = `
key="filter_1"
>
<FieldValueSelectionFilter
autoClose={true}
config={
Object {
"field": "tag",
Expand Down
53 changes: 42 additions & 11 deletions src/components/search_bar/filters/field_value_selection_filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { EuiIcon } from '../../icon/icon';
import { Query } from '../query';

const FieldValueOptionType = PropTypes.shape({
field: PropTypes.string,
value: PropTypes.any.isRequired,
name: PropTypes.string,
view: PropTypes.node
Expand All @@ -25,7 +26,8 @@ const FieldValueOptionsType = PropTypes.oneOfType([

export const FieldValueSelectionFilterConfigType = PropTypes.shape({
type: EuiPropTypes.is('field_value_selection').isRequired,
field: PropTypes.string.isRequired,
field: PropTypes.string,
autoClose: PropTypes.boolean,
name: PropTypes.string.isRequired,
options: FieldValueOptionsType.isRequired,
cache: PropTypes.number,
Expand Down Expand Up @@ -56,6 +58,10 @@ export class FieldValueSelectionFilter extends Component {

static propTypes = FieldValueSelectionFilterPropTypes;

static defaultProps = {
autoClose: true,
}

constructor(props) {
super(props);
this.selectItems = [];
Expand Down Expand Up @@ -154,24 +160,30 @@ export class FieldValueSelectionFilter extends Component {

onOptionClick(field, value, checked) {
const multiSelect = this.resolveMultiSelect();
if (!multiSelect) {
// we're closing popover only if the user can only select one item... if the
// user can select more, we'll leave it open so she can continue selecting
const { autoClose } = this.props;

// we're closing popover only if the user can only select one item... if the
// user can select more, we'll leave it open so she can continue selecting

if (!multiSelect && autoClose) {
this.closePopover();
const query = checked ?
this.props.query.removeSimpleFieldClauses(field) :
this.props.query.removeSimpleFieldClauses(field).addSimpleFieldValue(field, value);

this.props.onChange(query);
} else {
if (multiSelect === 'or') {
const query = checked ?
this.props.query.removeOrFieldValue(field, value) :
this.props.query.addOrFieldValue(field, value);

this.props.onChange(query);
} else {
const query = checked ?
this.props.query.removeSimpleFieldValue(field, value) :
this.props.query.addSimpleFieldValue(field, value);

this.props.onChange(query);
}
}
Expand Down Expand Up @@ -209,9 +221,14 @@ export class FieldValueSelectionFilter extends Component {
render() {
const { index, query, config } = this.props;
const multiSelect = this.resolveMultiSelect();
const active = multiSelect === 'or' ?
query.hasOrFieldClause(config.field) :
query.hasSimpleFieldClause(config.field);

const activeTop = this.isActiveField(config.field);
const activeItem = this.state.options
? this.state.options.all.some(item => this.isActiveField(item.field))
: false;

const active = activeTop || activeItem;

const button = (
<EuiFilterButton
iconType="arrowDown"
Expand All @@ -224,7 +241,6 @@ export class FieldValueSelectionFilter extends Component {
</EuiFilterButton>
);


const searchBox = this.renderSearchBox();
const content = this.renderContent(config.field, query, config, multiSelect);
const threshold = this.props.config.searchThreshold || defaults.config.searchThreshold;
Expand Down Expand Up @@ -277,14 +293,18 @@ export class FieldValueSelectionFilter extends Component {
return this.renderNoOptions();
}
const items = this.state.options.shown.reduce((items, option, index) => {
const optionField = option.field || field;

const clause = multiSelect === 'or' ?
query.getOrFieldClause(field, option.value) :
query.getSimpleFieldClause(field, option.value);
query.getOrFieldClause(optionField, option.value) :
query.getSimpleFieldClause(optionField, option.value);

const checked = this.resolveChecked(clause);
const onClick = () => {
// clicking a checked item will uncheck it and effective remove the filter (value = undefined)
this.onOptionClick(field, option.value, checked);
this.onOptionClick(optionField, option.value, checked);
};

const item = (
<EuiFilterSelectItem
key={index}
Expand Down Expand Up @@ -355,4 +375,15 @@ export class FieldValueSelectionFilter extends Component {
</div>
);
}

isActiveField(field) {
const { query } = this.props;
const multiSelect = this.resolveMultiSelect();

if (multiSelect === 'or') {
return query.hasOrFieldClause(field);
}

return query.hasSimpleFieldClause(field);
}
}