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 all 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
Expand Up @@ -2,6 +2,7 @@

- Added `maxWidth` prop to `EuiModal` ([#1165](https://github.com/elastic/eui/pull/1165))
- Support field names with `_` characters in search queries ([#1180](https://github.com/elastic/eui/pull/1180))
- 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
Original file line number Diff line number Diff line change
@@ -1,5 +1,189 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`FieldValueSelectionFilter active - field is global 1`] = `
<EuiPopover
anchorPosition="downCenter"
button={
<EuiFilterButton
color="text"
grow={true}
hasActiveFilters={true}
iconSide="right"
iconType="arrowDown"
onClick={[Function]}
type="button"
>
Tag
</EuiFilterButton>
}
closePopover={[Function]}
hasArrow={true}
id="field_value_selection_0"
isOpen={false}
ownFocus={true}
panelClassName="euiFilterGroup__popoverPanel"
panelPaddingSize="none"
withTitle={null}
>
<div
className="euiFilterSelect__note"
>
<div
className="euiFilterSelect__noteContent"
>
<EuiLoadingChart
mono={false}
size="m"
/>
<EuiSpacer
size="xs"
/>
<p>
Loading...
</p>
</div>
</div>
</EuiPopover>
`;

exports[`FieldValueSelectionFilter active - fields in options 1`] = `
<EuiPopover
anchorPosition="downCenter"
button={
<EuiFilterButton
color="text"
grow={true}
hasActiveFilters={true}
iconSide="right"
iconType="arrowDown"
onClick={[Function]}
type="button"
>
Tag
</EuiFilterButton>
}
closePopover={[Function]}
hasArrow={true}
id="field_value_selection_0"
isOpen={false}
ownFocus={true}
panelClassName="euiFilterGroup__popoverPanel"
panelPaddingSize="none"
withTitle={null}
>
<div
className="euiFilterSelect__note"
>
<div
className="euiFilterSelect__noteContent"
>
<EuiLoadingChart
mono={false}
size="m"
/>
<EuiSpacer
size="xs"
/>
<p>
Loading...
</p>
</div>
</div>
</EuiPopover>
`;

exports[`FieldValueSelectionFilter inactive - field is global 1`] = `
<EuiPopover
anchorPosition="downCenter"
button={
<EuiFilterButton
color="text"
grow={true}
hasActiveFilters={false}
iconSide="right"
iconType="arrowDown"
onClick={[Function]}
type="button"
>
Tag
</EuiFilterButton>
}
closePopover={[Function]}
hasArrow={true}
id="field_value_selection_0"
isOpen={false}
ownFocus={true}
panelClassName="euiFilterGroup__popoverPanel"
panelPaddingSize="none"
withTitle={null}
>
<div
className="euiFilterSelect__note"
>
<div
className="euiFilterSelect__noteContent"
>
<EuiLoadingChart
mono={false}
size="m"
/>
<EuiSpacer
size="xs"
/>
<p>
Loading...
</p>
</div>
</div>
</EuiPopover>
`;

exports[`FieldValueSelectionFilter inactive - fields in options 1`] = `
<EuiPopover
anchorPosition="downCenter"
button={
<EuiFilterButton
color="text"
grow={true}
hasActiveFilters={false}
iconSide="right"
iconType="arrowDown"
onClick={[Function]}
type="button"
>
Tag
</EuiFilterButton>
}
closePopover={[Function]}
hasArrow={true}
id="field_value_selection_0"
isOpen={false}
ownFocus={true}
panelClassName="euiFilterGroup__popoverPanel"
panelPaddingSize="none"
withTitle={null}
>
<div
className="euiFilterSelect__note"
>
<div
className="euiFilterSelect__noteContent"
>
<EuiLoadingChart
mono={false}
size="m"
/>
<EuiSpacer
size="xs"
/>
<p>
Loading...
</p>
</div>
</div>
</EuiPopover>
`;

exports[`FieldValueSelectionFilter render - all configurations 1`] = `
<EuiPopover
anchorPosition="downCenter"
Expand Down Expand Up @@ -46,6 +230,52 @@ exports[`FieldValueSelectionFilter render - all configurations 1`] = `
</EuiPopover>
`;

exports[`FieldValueSelectionFilter render - fields in options 1`] = `
<EuiPopover
anchorPosition="downCenter"
button={
<EuiFilterButton
color="text"
grow={true}
hasActiveFilters={false}
iconSide="right"
iconType="arrowDown"
onClick={[Function]}
type="button"
>
Tag
</EuiFilterButton>
}
closePopover={[Function]}
hasArrow={true}
id="field_value_selection_0"
isOpen={false}
ownFocus={true}
panelClassName="euiFilterGroup__popoverPanel"
panelPaddingSize="none"
withTitle={null}
>
<div
className="euiFilterSelect__note"
>
<div
className="euiFilterSelect__noteContent"
>
<EuiLoadingChart
mono={false}
size="m"
/>
<EuiSpacer
size="xs"
/>
<p>
Loading...
</p>
</div>
</div>
</EuiPopover>
`;

exports[`FieldValueSelectionFilter render - multi-select OR 1`] = `
<EuiPopover
anchorPosition="downCenter"
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);
}
}
Loading