diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.test.tsx index 8e7fb9e310f664..73842e6cae114e 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.test.tsx @@ -14,16 +14,21 @@ import { FilterPopover } from './filter_popover'; import { LabelInput } from '../shared_components'; import { QueryStringInput } from '@kbn/unified-search-plugin/public'; import { QueryInput } from '@kbn/visualization-ui-components'; +import { Query } from '@kbn/es-query'; -jest.mock('.', () => ({ - isQueryValid: () => true, - defaultLabel: 'label', -})); +jest.mock('.', () => ({})); + +jest.mock('@kbn/visualization-ui-components', () => { + const original = jest.requireActual('@kbn/visualization-ui-components'); + + return { + ...original, + isQueryValid: jest.fn((q: Query) => (q.query === 'bytes >= 1 and' ? false : true)), + }; +}); jest.mock('@kbn/unified-search-plugin/public', () => ({ - QueryStringInput: () => { - return 'QueryStringInput'; - }, + QueryStringInput: () => 'QueryStringInput', })); describe('filter popover', () => { @@ -118,6 +123,16 @@ describe('filter popover', () => { }); }); + it('should not call setFilter if QueryInput value is not valid', () => { + const setFilter = jest.fn(); + const instance = shallow(); + instance.find(QueryInput).prop('onChange')!({ + query: 'bytes >= 1 and', + language: 'kuery', + }); + expect(setFilter).not.toHaveBeenCalled(); + }); + it('should call setFilter when modifying LabelInput', () => { const setFilter = jest.fn(); const instance = shallow(); diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.tsx index 35327fb91b6781..1f3f5ba94e63bc 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/filters/filter_popover.tsx @@ -7,7 +7,7 @@ import './filter_popover.scss'; -import React from 'react'; +import React, { useState } from 'react'; import { EuiPopover, EuiSpacer } from '@elastic/eui'; import type { Query } from '@kbn/es-query'; // Need to keep it separate to make it work Jest mocks in dimension_panel tests @@ -36,9 +36,18 @@ export const FilterPopover = ({ triggerClose: () => void; }) => { const inputRef = React.useRef(); + const [localFilter, setLocalFilter] = useState(() => filter); - const setFilterLabel = (label: string) => setFilter({ ...filter, label }); - const setFilterQuery = (input: Query) => setFilter({ ...filter, input }); + const setFilterLabel = (label: string) => { + setLocalFilter({ ...localFilter, label }); + setFilter({ ...filter, label }); + }; + const setFilterQuery = (input: Query) => { + setLocalFilter({ ...localFilter, input }); + if (isQueryValid(input, indexPattern)) { + setFilter({ ...filter, input }); + } + }; const getPlaceholder = (query: Query['query']) => { if (query === '') { @@ -49,6 +58,10 @@ export const FilterPopover = ({ return String(query); } }; + const closePopover = () => { + setLocalFilter({ ...localFilter, input: filter.input }); + triggerClose(); + }; return (