From b571e6bfd325f1565612a75e5ca63a04bd3bc53d Mon Sep 17 00:00:00 2001 From: Yuri Astrakhan Date: Tue, 25 Aug 2020 11:42:39 -0400 Subject: [PATCH] Support operator in field_value_selection filters (#3922) * Support operator in field_value_selection filters Additionally adds a an operator example to the search bar demo, and use `OperatorType` in all other filters TS declaration. closes: #3920 * update docs for field_value_selection * changelog Co-authored-by: Chandler Prall --- CHANGELOG.md | 1 + src-docs/src/views/search_bar/props_info.js | 25 ++++++++++++++++++- src-docs/src/views/search_bar/search_bar.js | 1 + .../filters/field_value_selection_filter.tsx | 11 ++++---- .../filters/field_value_toggle_filter.tsx | 4 +-- .../field_value_toggle_group_filter.tsx | 3 ++- src/components/search_bar/query/query.ts | 9 +++++-- 7 files changed, 43 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc53cb87185..ab2e85b9288 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Updated browserslist configuration to remove IE accommodations ([#3911](https://github.com/elastic/eui/pull/3911)) - Removed docgenInfo from non-docs production builds ([#3911](https://github.com/elastic/eui/pull/3911)) - Added `regressionJob`, `outlierDetectionJob` and `classificationJob` icons to Machine Learning icon set, updated others. ([#3931](https://github.com/elastic/eui/pull/3931)) +- Added `operator` field to `EuiSearchBar`'s `field_value_selection` filter configuration ([#3922](https://github.com/elastic/eui/pull/3922)) **Bug fixes** diff --git a/src-docs/src/views/search_bar/props_info.js b/src-docs/src/views/search_bar/props_info.js index 20d0eb090ec..f3146bdca30 100644 --- a/src-docs/src/views/search_bar/props_info.js +++ b/src-docs/src/views/search_bar/props_info.js @@ -222,6 +222,15 @@ export const propsInfo = { required: true, type: { name: '#FieldValueOption[] | () => #FieldValueOption[]' }, }, + filterWith: { + description: + 'Specify how user input in the option dropdown will filter the available options.', + required: false, + defaultValue: { value: 'prefix' }, + type: { + name: 'prefix | includes | (name, query, options) => boolean', + }, + }, cache: { description: 'When set to a positive number, if `options` is a loading function, the loaded ' + @@ -233,7 +242,7 @@ export const propsInfo = { description: 'Indicates whether the user can filter by multiple values or by only a single one. ' + 'When set to "and" the filter will create queries by `and`ing the selected values. ' + - 'When set to "or" the filter will create quries by `or`ing the selected values', + 'When set to "or" the filter will create queries by `or`ing the selected values', required: false, defaultValue: { value: 'true ("and")' }, type: { name: 'boolean | "or" | "and"' }, @@ -266,6 +275,20 @@ export const propsInfo = { required: false, type: { name: '() => boolean' }, }, + autoClose: { + description: + 'Should the dropdown close after the user selects a value. Ignored if multiSelect is true.', + required: false, + defaultValue: { value: 'true' }, + type: { name: 'boolean' }, + }, + operator: { + description: + 'What operator should be used when adding selection to the search bar.', + required: false, + defaultValue: { value: 'eq' }, + type: { name: 'eq | exact | gt | gte | lt | lte' }, + }, }, }, }, diff --git a/src-docs/src/views/search_bar/search_bar.js b/src-docs/src/views/search_bar/search_bar.js index ba2690767f3..0e4d1accd4e 100644 --- a/src-docs/src/views/search_bar/search_bar.js +++ b/src-docs/src/views/search_bar/search_bar.js @@ -118,6 +118,7 @@ export const SearchBar = () => { field: 'tag', name: 'Tag', multiSelect: 'or', + operator: 'exact', cache: 10000, // will cache the loaded tags for 10 sec options: () => loadTags(), }, diff --git a/src/components/search_bar/filters/field_value_selection_filter.tsx b/src/components/search_bar/filters/field_value_selection_filter.tsx index 94f0608104d..43f8ceb6147 100644 --- a/src/components/search_bar/filters/field_value_selection_filter.tsx +++ b/src/components/search_bar/filters/field_value_selection_filter.tsx @@ -27,7 +27,7 @@ import { EuiLoadingChart } from '../../loading'; import { EuiSpacer } from '../../spacer'; import { EuiIcon } from '../../icon'; import { Query } from '../query'; -import { Clause, Value } from '../query/ast'; +import { Clause, Operator, OperatorType, Value } from '../query/ast'; export interface FieldValueOptionType { field?: string; @@ -59,6 +59,7 @@ export interface FieldValueSelectionFilterConfigType { searchThreshold?: number; available?: () => boolean; autoClose?: boolean; + operator?: OperatorType; } export interface FieldValueSelectionFilterProps { @@ -262,7 +263,7 @@ export class FieldValueSelectionFilter extends Component< ) { const multiSelect = this.resolveMultiSelect(); const { - config: { autoClose = true }, + config: { autoClose = true, operator = Operator.EQ }, } = this.props; // we're closing popover only if the user can only select one item... if the @@ -274,20 +275,20 @@ export class FieldValueSelectionFilter extends Component< ? this.props.query.removeSimpleFieldClauses(field) : this.props.query .removeSimpleFieldClauses(field) - .addSimpleFieldValue(field, value); + .addSimpleFieldValue(field, value, true, operator); 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.query.addOrFieldValue(field, value, true, operator); this.props.onChange(query); } else { const query = checked ? this.props.query.removeSimpleFieldValue(field, value) - : this.props.query.addSimpleFieldValue(field, value); + : this.props.query.addSimpleFieldValue(field, value, true, operator); this.props.onChange(query); } diff --git a/src/components/search_bar/filters/field_value_toggle_filter.tsx b/src/components/search_bar/filters/field_value_toggle_filter.tsx index df0afad147d..9f51b41f3fb 100644 --- a/src/components/search_bar/filters/field_value_toggle_filter.tsx +++ b/src/components/search_bar/filters/field_value_toggle_filter.tsx @@ -21,7 +21,7 @@ import React, { Component } from 'react'; import { EuiFilterButton } from '../../filter_group'; import { isNil } from '../../../services/predicate'; import { Query } from '../query'; -import { Clause, Value } from '../query/ast'; +import { Clause, OperatorType, Value } from '../query/ast'; export interface FieldValueToggleFilterConfigType { type: 'field_value_toggle'; @@ -30,7 +30,7 @@ export interface FieldValueToggleFilterConfigType { name: string; negatedName?: string; available?: () => boolean; - operator?: 'eq' | 'exact' | 'gt' | 'gte' | 'lt' | 'lte'; + operator?: OperatorType; } export interface FieldValueToggleFilterProps { diff --git a/src/components/search_bar/filters/field_value_toggle_group_filter.tsx b/src/components/search_bar/filters/field_value_toggle_group_filter.tsx index 040599e1294..a1ad0fc21ff 100644 --- a/src/components/search_bar/filters/field_value_toggle_group_filter.tsx +++ b/src/components/search_bar/filters/field_value_toggle_group_filter.tsx @@ -20,12 +20,13 @@ import React, { Component } from 'react'; import { EuiFilterButton } from '../../filter_group'; import { Query } from '../query'; +import { OperatorType } from '../query/ast'; export interface FieldValueToggleGroupFilterItemType { value: string | number | boolean; name: string; negatedName?: string; - operator?: 'eq' | 'exact' | 'gt' | 'gte' | 'lt' | 'lte'; + operator?: OperatorType; } export interface FieldValueToggleGroupFilterConfigType { diff --git a/src/components/search_bar/query/query.ts b/src/components/search_bar/query/query.ts index b03054d458b..d92ec35410d 100644 --- a/src/components/search_bar/query/query.ts +++ b/src/components/search_bar/query/query.ts @@ -103,8 +103,13 @@ export class Query { return this.ast.getOrFieldClause(field, value); } - addOrFieldValue(field: string, value: Value, must = true) { - const ast = this.ast.addOrFieldValue(field, value, must); + addOrFieldValue( + field: string, + value: Value, + must = true, + operator: OperatorType = Operator.EQ + ) { + const ast = this.ast.addOrFieldValue(field, value, must, operator); return new Query(ast, this.syntax); }