Skip to content

Commit

Permalink
[Unified Search] Provide an option to hide specified filter actions f…
Browse files Browse the repository at this point in the history
…rom SearchBar filter panels (#132037)

* [Unified Search] Configurable filter menu options

* [Unified Search] Add tests for query menu

* [Unified Search] Add a story

* [Unified Search] Update comments
  • Loading branch information
jughosta authored May 12, 2022
1 parent 8d1baec commit cb83c9a
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -428,4 +428,35 @@ storiesOf('SearchBar', module)
showQueryInput: true,
showSubmitButton: false,
} as SearchBarProps)
)
.add('with filter bar on but pinning option is hidden from menus', () =>
wrapSearchBarInContext({
showDatePicker: false,
showFilterBar: true,
showQueryInput: true,
hiddenFilterPanelOptions: ['pinFilter'],
filters: [
{
meta: {
index: '1234',
alias: null,
negate: false,
disabled: false,
type: 'phrase',
key: 'category.keyword',
params: {
query: "Men's Accessories",
},
},
query: {
match_phrase: {
'category.keyword': "Men's Accessories",
},
},
$state: {
store: 'appState',
},
},
],
} as unknown as SearchBarProps)
);
4 changes: 3 additions & 1 deletion src/plugins/unified_search/public/filter_bar/filter_bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { InjectedIntl, injectI18n } from '@kbn/i18n-react';
import type { Filter } from '@kbn/es-query';
import React, { useRef } from 'react';
import { DataView } from '@kbn/data-views-plugin/public';
import FilterItems from './filter_item/filter_items';
import FilterItems, { Props as FilterItemsProps } from './filter_item/filter_items';

import { filterBarStyles } from './filter_bar.styles';

Expand All @@ -22,6 +22,7 @@ export interface Props {
indexPatterns: DataView[];
intl: InjectedIntl;
timeRangeForSuggestionsOverride?: boolean;
hiddenPanelOptions?: FilterItemsProps['hiddenPanelOptions'];
/**
* Applies extra styles necessary when coupled with the query bar
*/
Expand All @@ -48,6 +49,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) {
onFiltersUpdated={props.onFiltersUpdated}
indexPatterns={props.indexPatterns!}
timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride}
hiddenPanelOptions={props.hiddenPanelOptions}
/>
</EuiFlexGroup>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ import {
import { FilterEditor } from '../filter_editor';
import { FilterView } from '../filter_view';
import { getIndexPatterns } from '../../services';

type PanelOptions = 'pinFilter' | 'editFilter' | 'negateFilter' | 'disableFilter' | 'deleteFilter';
import { FilterPanelOption } from '../../types';

export interface FilterItemProps {
id: string;
Expand All @@ -41,7 +40,7 @@ export interface FilterItemProps {
onRemove: () => void;
intl: InjectedIntl;
uiSettings: IUiSettingsClient;
hiddenPanelOptions?: PanelOptions[];
hiddenPanelOptions?: FilterPanelOption[];
timeRangeForSuggestionsOverride?: boolean;
readonly?: boolean;
}
Expand Down Expand Up @@ -248,7 +247,7 @@ export function FilterItem(props: FilterItemProps) {

if (hiddenPanelOptions && hiddenPanelOptions.length > 0) {
mainPanelItems = mainPanelItems.filter(
(pItem) => !hiddenPanelOptions.includes(pItem['data-test-subj'] as PanelOptions)
(pItem) => !hiddenPanelOptions.includes(pItem['data-test-subj'] as FilterPanelOption)
);
}
return [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ import { IDataPluginServices } from '@kbn/data-plugin/public';
import { METRIC_TYPE } from '@kbn/analytics';
import { DataView } from '@kbn/data-views-plugin/public';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { FilterItem } from './filter_item';
import { FilterItem, FilterItemProps } from './filter_item';

export interface Props {
filters: Filter[];
onFiltersUpdated?: (filters: Filter[]) => void;
indexPatterns: DataView[];
intl: InjectedIntl;
timeRangeForSuggestionsOverride?: boolean;
hiddenPanelOptions?: FilterItemProps['hiddenPanelOptions'];
}

const FilterItemsUI = React.memo(function FilterItemsUI(props: Props) {
Expand Down Expand Up @@ -56,6 +57,7 @@ const FilterItemsUI = React.memo(function FilterItemsUI(props: Props) {
onRemove={() => onRemove(i)}
indexPatterns={props.indexPatterns}
uiSettings={uiSettings!}
hiddenPanelOptions={props.hiddenPanelOptions}
timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride}
/>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import React from 'react';
import { I18nProvider } from '@kbn/i18n-react';
import { act } from 'react-dom/test-utils';
import { waitFor } from '@testing-library/react';
import { mountWithIntl as mount } from '@kbn/test-jest-helpers';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { coreMock } from '@kbn/core/public/mocks';
Expand Down Expand Up @@ -40,6 +41,30 @@ describe('Querybar Menu component', () => {
return storage;
};

const filtersMock = [
{
meta: {
index: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f',
alias: null,
negate: false,
disabled: false,
type: 'phrase',
key: 'category.keyword',
params: {
query: "Men's Accessories",
},
},
query: {
match_phrase: {
'category.keyword': "Men's Accessories",
},
},
$state: {
store: 'appState',
},
},
] as Filter[];

const startMock = coreMock.createStart();
let dataMock = dataPluginMock.createStartContract();
function wrapQueryBarMenuComponentInContext(testProps: QueryBarMenuProps, storageValue: string) {
Expand Down Expand Up @@ -181,29 +206,7 @@ describe('Querybar Menu component', () => {
...props,
openQueryBarMenu: true,
showFilterBar: true,
filters: [
{
meta: {
index: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f',
alias: null,
negate: false,
disabled: false,
type: 'phrase',
key: 'category.keyword',
params: {
query: "Men's Accessories",
},
},
query: {
match_phrase: {
'category.keyword': "Men's Accessories",
},
},
$state: {
store: 'appState',
},
},
] as Filter[],
filters: filtersMock,
};
const component = mount(wrapQueryBarMenuComponentInContext(newProps, 'kuery'));
const applyToAllFiltersButton = component.find(
Expand All @@ -229,29 +232,7 @@ describe('Querybar Menu component', () => {
...props,
openQueryBarMenu: true,
showSaveQuery: true,
filters: [
{
meta: {
index: 'ff959d40-b880-11e8-a6d9-e546fe2bba5f',
alias: null,
negate: false,
disabled: false,
type: 'phrase',
key: 'category.keyword',
params: {
query: "Men's Accessories",
},
},
query: {
match_phrase: {
'category.keyword': "Men's Accessories",
},
},
$state: {
store: 'appState',
},
},
] as Filter[],
filters: filtersMock,
savedQuery: {
id: '8a0b7cd0-b0c4-11ec-92b2-73d62e0d28a9',
attributes: {
Expand All @@ -275,4 +256,91 @@ describe('Querybar Menu component', () => {
);
expect(saveChangesAsNewButton.length).toBeTruthy();
});

it('should render all filter panel options by default', async () => {
const newProps: QueryBarMenuProps = {
...props,
openQueryBarMenu: true,
showFilterBar: true,
filters: filtersMock,
hiddenPanelOptions: undefined,
};
const component = mount(wrapQueryBarMenuComponentInContext(newProps, 'kuery'));

expect(component.find('[data-test-subj="filter-sets-removeAllFilters"]').length).toBeTruthy();
component.find('[data-test-subj="filter-sets-applyToAllFilters"]').first().simulate('click');

await waitFor(() => {
component.update();
expect(component.find('[data-test-subj="contextMenuPanelTitleButton"]').length).toBeTruthy();
});

expect(component.find('[data-test-subj="filter-sets-pinAllFilters"]').length).toBeTruthy();
expect(component.find('[data-test-subj="filter-sets-unpinAllFilters"]').length).toBeTruthy();
expect(component.find('[data-test-subj="filter-sets-invertAllFilters"]').length).toBeTruthy();
expect(component.find('[data-test-subj="filter-sets-disableAllFilters"]').length).toBeTruthy();
expect(component.find('[data-test-subj="filter-sets-enableAllFilters"]').length).toBeTruthy();
});

it('should hide pinning filter panel options', async () => {
const newProps: QueryBarMenuProps = {
...props,
openQueryBarMenu: true,
showFilterBar: true,
filters: filtersMock,
hiddenPanelOptions: ['pinFilter'],
};
const component = mount(wrapQueryBarMenuComponentInContext(newProps, 'kuery'));

component.find('[data-test-subj="filter-sets-applyToAllFilters"]').first().simulate('click');

await waitFor(() => {
component.update();
expect(component.find('[data-test-subj="contextMenuPanelTitleButton"]').length).toBeTruthy();
});

expect(component.find('[data-test-subj="filter-sets-pinAllFilters"]').length).toBeFalsy();
expect(component.find('[data-test-subj="filter-sets-unpinAllFilters"]').length).toBeFalsy();

expect(component.find('[data-test-subj="filter-sets-invertAllFilters"]').length).toBeTruthy();
expect(component.find('[data-test-subj="filter-sets-disableAllFilters"]').length).toBeTruthy();
expect(component.find('[data-test-subj="filter-sets-enableAllFilters"]').length).toBeTruthy();
});

it('should hide negating and enabling filter panel options', async () => {
const newProps: QueryBarMenuProps = {
...props,
openQueryBarMenu: true,
showFilterBar: true,
filters: filtersMock,
hiddenPanelOptions: ['negateFilter', 'disableFilter'],
};
const component = mount(wrapQueryBarMenuComponentInContext(newProps, 'kuery'));

component.find('[data-test-subj="filter-sets-applyToAllFilters"]').first().simulate('click');

await waitFor(() => {
component.update();
expect(component.find('[data-test-subj="contextMenuPanelTitleButton"]').length).toBeTruthy();
});

expect(component.find('[data-test-subj="filter-sets-pinAllFilters"]').length).toBeTruthy();
expect(component.find('[data-test-subj="filter-sets-unpinAllFilters"]').length).toBeTruthy();
expect(component.find('[data-test-subj="filter-sets-invertAllFilters"]').length).toBeFalsy();
expect(component.find('[data-test-subj="filter-sets-disableAllFilters"]').length).toBeFalsy();
expect(component.find('[data-test-subj="filter-sets-enableAllFilters"]').length).toBeFalsy();
});

it('should hide deleting filter panel options', async () => {
const newProps: QueryBarMenuProps = {
...props,
openQueryBarMenu: true,
showFilterBar: true,
filters: filtersMock,
hiddenPanelOptions: ['deleteFilter'],
};
const component = mount(wrapQueryBarMenuComponentInContext(newProps, 'kuery'));

expect(component.find('[data-test-subj="filter-sets-removeAllFilters"]').length).toBeFalsy();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { i18n } from '@kbn/i18n';
import type { Filter, Query } from '@kbn/es-query';
import type { DataView } from '@kbn/data-views-plugin/public';
import type { TimeRange, SavedQueryService, SavedQuery } from '@kbn/data-plugin/public';
import { QueryBarMenuPanels } from './query_bar_menu_panels';
import { QueryBarMenuPanels, QueryBarMenuPanelsProps } from './query_bar_menu_panels';
import { FilterEditorWrapper } from './filter_editor_wrapper';

export interface QueryBarMenuProps {
Expand All @@ -36,6 +36,7 @@ export interface QueryBarMenuProps {
saveAsNewQueryFormComponent?: JSX.Element;
saveFormComponent?: JSX.Element;
manageFilterSetComponent?: JSX.Element;
hiddenPanelOptions?: QueryBarMenuPanelsProps['hiddenPanelOptions'];
onFiltersUpdated?: (filters: Filter[]) => void;
filters?: Filter[];
query?: Query;
Expand All @@ -60,6 +61,7 @@ export function QueryBarMenu({
saveAsNewQueryFormComponent,
saveFormComponent,
manageFilterSetComponent,
hiddenPanelOptions,
openQueryBarMenu,
toggleFilterBarMenuPopover,
onFiltersUpdated,
Expand Down Expand Up @@ -124,6 +126,7 @@ export function QueryBarMenu({
savedQueryService,
saveAsNewQueryFormComponent,
manageFilterSetComponent,
hiddenPanelOptions,
nonKqlMode,
closePopover,
onQueryBarSubmit,
Expand Down
Loading

0 comments on commit cb83c9a

Please sign in to comment.