From d9a3d02f337f96946769b796ba249607832d6287 Mon Sep 17 00:00:00 2001 From: Nodir Date: Wed, 26 Jan 2022 20:31:18 +0500 Subject: [PATCH 01/19] feat: add open filter window --- .../data/public/ui/filter_bar/filter_bar.tsx | 35 +++++++++++++++++-- .../ui/filter_bar/filter_expression_item.tsx | 17 ++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx index 8f937d8616417..ca7d7754d48e6 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiPopover } from '@elastic/eui'; +import { EuiButtonEmpty, EuiFlexGroup, EuiFlexItem, EuiPopover, EuiButtonIcon } from '@elastic/eui'; import { groupBy, isEqual } from 'lodash'; import { FormattedMessage, InjectedIntl, injectI18n } from '@kbn/i18n-react'; import { @@ -33,6 +33,7 @@ import { SavedQueriesItem } from './saved_queries_item'; import { FilterExpressionItem } from './filter_expression_item'; import { UI_SETTINGS } from '../../../common'; +import { AddFilterModal } from '../query_string_input/add_filter_modal'; interface Props { filters: Filter[]; @@ -51,6 +52,7 @@ interface Props { const FilterBarUI = React.memo(function FilterBarUI(props: Props) { const groupRef = useRef(null); const [isAddFilterPopoverOpen, setIsAddFilterPopoverOpen] = useState(false); + const [isEditFilterPopoverOpen, setIsEditFilterPopoverOpen] = useState(false); const kibana = useKibana(); const { appName, usageCollection, uiSettings } = kibana.services; if (!uiSettings) return null; @@ -64,6 +66,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { } const onAddFilterClick = () => setIsAddFilterPopoverOpen(!isAddFilterPopoverOpen); + const onEditFilterClick = () => setIsEditFilterPopoverOpen(!isEditFilterPopoverOpen); function renderItems() { return props.filters.map((filter, i) => { @@ -106,10 +109,11 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { groupId={groupId} groupedFilters={groupedFilters} indexPatterns={props?.indexPatterns} - onClick={() => {}} + onClick={() => { }} onRemove={onRemoveFilterGroup} onUpdate={onUpdateFilterGroup} filtersGroupsCount={Object.entries(firstDepthGroupedFilters).length} + onEditFilterClick={onEditFilterClick} /> ); GroupBadge.push(badge); @@ -168,6 +172,32 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { ); } + function renderEditFilter() { + const isPinned = uiSettings!.get(UI_SETTINGS.FILTERS_PINNED_BY_DEFAULT); + const [indexPattern] = props?.indexPatterns || []; + const index = indexPattern && indexPattern.id; + const newFilter = buildEmptyFilter(isPinned, index); + + + return ( + + {isEditFilterPopoverOpen && ( + + )} + + ); + } + function onAdd(filter: Filter) { reportUiCounter?.(METRIC_TYPE.CLICK, `filter:added`); setIsAddFilterPopoverOpen(false); @@ -313,6 +343,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { {renderSelectedSavedQueries()} {props.multipleFilters.length === 0 && renderItems()} {/* {renderAddFilter()} */} + {renderEditFilter()} diff --git a/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx b/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx index 8745db2e560b0..ba09b9686717a 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx @@ -46,6 +46,7 @@ interface Props { groupId: string; filtersGroupsCount: number; onUpdate?: (filters: Filter[], groupId: string, toggleNegate: boolean) => void; + onEditFilterClick: () => void; } export const FilterExpressionItem: FC = ({ @@ -56,6 +57,7 @@ export const FilterExpressionItem: FC = ({ groupId, filtersGroupsCount, onUpdate, + onEditFilterClick }: Props) => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); function handleBadgeClick() { @@ -67,6 +69,16 @@ export const FilterExpressionItem: FC = ({ setIsPopoverOpen(!isPopoverOpen); } + function onEdit() { + // const multipleUpdatedFilters = groupedFilters?.map((filter: Filter) => { + // return { ...filter, groupId: filtersGroupsCount + 1 }; + // }); + // const finalFilters = [...multipleUpdatedFilters, ...groupedFilters]; + // onUpdate?.(finalFilters, groupId, false); + + onEditFilterClick(); + } + function onDuplicate() { const multipleUpdatedFilters = groupedFilters?.map((filter: Filter) => { return { ...filter, groupId: filtersGroupsCount + 1 }; @@ -96,7 +108,10 @@ export const FilterExpressionItem: FC = ({ defaultMessage: `Edit`, }), icon: 'pencil', - panel: 1, + onClick: () => { + setIsPopoverOpen(false); + onEdit(); + }, 'data-test-subj': 'editFilter', }, { From 0b3a746347c30c88df88defa6656f7c8e89c2b79 Mon Sep 17 00:00:00 2001 From: Nodir Date: Thu, 27 Jan 2022 21:06:17 +0500 Subject: [PATCH 02/19] feat: add show muilty filter in Add filter form --- .../data/public/ui/filter_bar/filter_bar.tsx | 4 +- .../ui/filter_bar/filter_editor/index.tsx | 2 +- .../data/public/ui/filter_bar/filter_item.tsx | 2 +- .../query_string_input/add_filter_modal.tsx | 57 +++++++++++++------ 4 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx index ca7d7754d48e6..2034ffdc109fd 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -178,13 +178,13 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { const index = indexPattern && indexPattern.id; const newFilter = buildEmptyFilter(isPinned, index); - return ( {isEditFilterPopoverOpen && ( { diff --git a/src/plugins/data/public/ui/filter_bar/filter_item.tsx b/src/plugins/data/public/ui/filter_bar/filter_item.tsx index 9e535513aa014..29841ff308a9b 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_item.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_item.tsx @@ -178,7 +178,7 @@ export function FilterItem(props: FilterItemProps) { { name: props.intl.formatMessage({ id: 'data.filter.filterBar.editFilterButtonLabel', - defaultMessage: 'Edit filter', + defaultMessage: 'Edit filter old', }), icon: 'pencil', panel: 1, diff --git a/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx b/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx index c4067bee88d64..b8c841b1de46f 100644 --- a/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx +++ b/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx @@ -15,6 +15,7 @@ import { buildCustomFilter, cleanFilter, getFilterParams, + FieldFilter, } from '@kbn/es-query'; import { EuiFormRow, @@ -44,6 +45,8 @@ import { getIndexPatternFromFilter } from '../../query'; import { getFilterableFields, getOperatorOptions, + getFieldFromFilter, + getOperatorFromFilter, } from '../filter_bar/filter_editor/lib/filter_editor_utils'; import { Operator } from '../filter_bar/filter_editor/lib/filter_operators'; @@ -53,6 +56,7 @@ import { PhrasesValuesInput } from '../filter_bar/filter_editor/phrases_values_i import { RangeValueInput } from '../filter_bar/filter_editor/range_value_input'; import { IIndexPattern, IFieldType } from '../..'; +import { filter } from '../../../../console/server/lib/spec_definitions/js/filter'; const tabs = [ { @@ -91,6 +95,7 @@ export function AddFilterModal({ onCancel, applySavedQueries, filter, + filters, indexPatterns, timeRangeForSuggestionsOverride, savedQueryManagement, @@ -101,6 +106,7 @@ export function AddFilterModal({ applySavedQueries: () => void; onCancel: () => void; filter: Filter; + filters?: Filter[]; indexPatterns: IIndexPattern[]; timeRangeForSuggestionsOverride?: boolean; savedQueryManagement?: JSX.Element; @@ -112,18 +118,37 @@ export function AddFilterModal({ const [addFilterMode, setAddFilterMode] = useState(initialAddFilterMode ?? tabs[0].type); const [customLabel, setCustomLabel] = useState(filter.meta.alias || ''); const [queryDsl, setQueryDsl] = useState(JSON.stringify(cleanFilter(filter), null, 2)); - const [localFilters, setLocalFilters] = useState([ - { - field: undefined, - operator: undefined, - value: getFilterParams(filter), - groupId: 1, - id: 0, - subGroupId: 1, - }, - ]); + const [localFilters, setLocalFilters] = useState( + convertFilterToFilterGroup(filters) + ); const [groupsCount, setGroupsCount] = useState(1); + function convertFilterToFilterGroup(convertibleFilters: Filter[] | undefined): FilterGroup[] { + if (!convertibleFilters) { + return [ + { + field: getFieldFromFilter(filter as FieldFilter, selectedIndexPattern), + operator: getOperatorFromFilter(filter), + value: getFilterParams(filter), + groupId: 1, + id: 0, + subGroupId: 1, + }, + ]; + } + + return convertibleFilters.map((convertedfilter) => { + return { + field: getFieldFromFilter(convertedfilter as FieldFilter, selectedIndexPattern), + operator: getOperatorFromFilter(convertedfilter), + value: getFilterParams(convertedfilter), + groupId: 1, + id: 0, + subGroupId: 1, + }; + }); + } + const onIndexPatternChange = ([selectedPattern]: IIndexPattern[]) => { setSelectedIndexPattern(selectedPattern); setLocalFilters([ @@ -246,11 +271,11 @@ export function AddFilterModal({ placeholder={ selectedField ? i18n.translate('data.filter.filterEditor.operatorSelectPlaceholderSelect', { - defaultMessage: 'Operator', - }) + defaultMessage: 'Operator', + }) : i18n.translate('data.filter.filterEditor.operatorSelectPlaceholderWaiting', { - defaultMessage: 'Waiting', - }) + defaultMessage: 'Waiting', + }) } options={operators} selectedOptions={selectedOperator ? [selectedOperator] : []} @@ -416,8 +441,8 @@ export function AddFilterModal({ subGroup.length > 1 && groupsCount > 1 ? 'kbnQueryBar__filterModalSubGroups' : groupsCount === 1 && subGroup.length > 1 - ? 'kbnQueryBar__filterModalGroups' - : ''; + ? 'kbnQueryBar__filterModalGroups' + : ''; return ( <>
From 731ca1335d9d413690fec0e49f7ff97d5b2dc229 Mon Sep 17 00:00:00 2001 From: Nodir Date: Fri, 28 Jan 2022 01:22:00 +0500 Subject: [PATCH 03/19] feat: expanded Filter class --- packages/kbn-es-query/src/filters/build_filters/types.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/kbn-es-query/src/filters/build_filters/types.ts b/packages/kbn-es-query/src/filters/build_filters/types.ts index d7fa064d42b24..62196c1d19994 100644 --- a/packages/kbn-es-query/src/filters/build_filters/types.ts +++ b/packages/kbn-es-query/src/filters/build_filters/types.ts @@ -75,6 +75,10 @@ export type Filter = { }; meta: FilterMeta; query?: Record; + groupId?: number; + id?: number; + relationship?: 'AND' | 'OR' | undefined; + subGroupId?: number; }; // eslint-disable-next-line From f0055d2ace863cbd523f82a400bb2047120c526c Mon Sep 17 00:00:00 2001 From: Nodir Date: Fri, 28 Jan 2022 13:45:33 +0500 Subject: [PATCH 04/19] feat: save filter with groupId, id, subGroupId, relationship properties and show new filter list after hot reset page --- .../data/public/ui/filter_bar/filter_bar.tsx | 4 +- .../query_string_input/add_filter_modal.tsx | 46 +++++++++++-------- .../data/public/ui/search_bar/search_bar.tsx | 2 +- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx index 2034ffdc109fd..cbbbf53ef3a32 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -69,7 +69,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { const onEditFilterClick = () => setIsEditFilterPopoverOpen(!isEditFilterPopoverOpen); function renderItems() { - return props.filters.map((filter, i) => { + return props.multipleFilters.map((filter, i) => { // Do not display filters from saved queries if (filter.meta.isFromSavedQuery) return null; return ( @@ -184,7 +184,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { void; onCancel: () => void; filter: Filter; - filters?: Filter[]; + multipleFilters?: Filter[]; indexPatterns: IIndexPattern[]; timeRangeForSuggestionsOverride?: boolean; savedQueryManagement?: JSX.Element; @@ -119,7 +119,7 @@ export function AddFilterModal({ const [customLabel, setCustomLabel] = useState(filter.meta.alias || ''); const [queryDsl, setQueryDsl] = useState(JSON.stringify(cleanFilter(filter), null, 2)); const [localFilters, setLocalFilters] = useState( - convertFilterToFilterGroup(filters) + convertFilterToFilterGroup(multipleFilters) ); const [groupsCount, setGroupsCount] = useState(1); @@ -127,12 +127,13 @@ export function AddFilterModal({ if (!convertibleFilters) { return [ { - field: getFieldFromFilter(filter as FieldFilter, selectedIndexPattern), - operator: getOperatorFromFilter(filter), - value: getFilterParams(filter), + field: undefined, + operator: undefined, + value: undefined, groupId: 1, id: 0, subGroupId: 1, + relationship: undefined }, ]; } @@ -142,9 +143,10 @@ export function AddFilterModal({ field: getFieldFromFilter(convertedfilter as FieldFilter, selectedIndexPattern), operator: getOperatorFromFilter(convertedfilter), value: getFilterParams(convertedfilter), - groupId: 1, - id: 0, - subGroupId: 1, + groupId: convertedfilter.groupId, + id: convertedfilter.id, + subGroupId: convertedfilter.subGroupId, + relationship: convertedfilter.relationship }; }); } @@ -395,16 +397,22 @@ export function AddFilterModal({ } else if (addFilterMode === 'quick_form' && selectedIndexPattern) { const builtFilters = localFilters.map((localFilter) => { if (localFilter.field && localFilter.operator) { - return buildFilter( - selectedIndexPattern, - localFilter.field, - localFilter.operator.type, - localFilter.operator.negate, - filter.meta.disabled ?? false, - localFilter.value ?? '', - alias, - $state.store - ); + return { + ...buildFilter( + selectedIndexPattern, + localFilter.field, + localFilter.operator.type, + localFilter.operator.negate, + filter.meta.disabled ?? false, + localFilter.value ?? '', + alias, + $state.store + ), + groupId: localFilter.groupId, + id: localFilter.id, + subGroupId: localFilter.subGroupId, + relationship: localFilter.relationship, + }; } }); if (builtFilters && builtFilters.length) { diff --git a/src/plugins/data/public/ui/search_bar/search_bar.tsx b/src/plugins/data/public/ui/search_bar/search_bar.tsx index 27631b84112df..6f5dc8cd78d97 100644 --- a/src/plugins/data/public/ui/search_bar/search_bar.tsx +++ b/src/plugins/data/public/ui/search_bar/search_bar.tsx @@ -203,7 +203,7 @@ class SearchBarUI extends Component { currentProps: this.props, selectedSavedQueries: [], finalSelectedSavedQueries: [], - multipleFilters: [], + multipleFilters: this.props.filters?.length ? [...this.props.filters] : [], query: this.props.query ? { ...this.props.query } : undefined, dateRangeFrom: get(this.props, 'dateRangeFrom', 'now-15m'), dateRangeTo: get(this.props, 'dateRangeTo', 'now'), From 42e3d052944d8757b0d33031c124a1c9da7c78e6 Mon Sep 17 00:00:00 2001 From: Nodir Date: Fri, 28 Jan 2022 19:22:19 +0500 Subject: [PATCH 05/19] feat: update build filter --- .../query_string_input/add_filter_modal.tsx | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx b/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx index 4124dc253cfc7..3139f21cf7f49 100644 --- a/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx +++ b/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx @@ -397,22 +397,16 @@ export function AddFilterModal({ } else if (addFilterMode === 'quick_form' && selectedIndexPattern) { const builtFilters = localFilters.map((localFilter) => { if (localFilter.field && localFilter.operator) { - return { - ...buildFilter( - selectedIndexPattern, - localFilter.field, - localFilter.operator.type, - localFilter.operator.negate, - filter.meta.disabled ?? false, - localFilter.value ?? '', - alias, - $state.store - ), - groupId: localFilter.groupId, - id: localFilter.id, - subGroupId: localFilter.subGroupId, - relationship: localFilter.relationship, - }; + return buildFilter( + selectedIndexPattern, + localFilter.field, + localFilter.operator.type, + localFilter.operator.negate, + filter.meta.disabled ?? false, + localFilter.value ?? '', + alias, + $state.store + ); } }); if (builtFilters && builtFilters.length) { From c6b47731f5e705f4d84f40fae0e8491cd7ec7597 Mon Sep 17 00:00:00 2001 From: Nodir Date: Fri, 28 Jan 2022 21:16:07 +0500 Subject: [PATCH 06/19] feat: added show filter only by same gropId --- src/plugins/data/public/ui/filter_bar/filter_bar.tsx | 10 ++++++++-- .../public/ui/filter_bar/filter_expression_item.tsx | 6 +++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx index cbbbf53ef3a32..409e366ec7b3c 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -53,6 +53,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { const groupRef = useRef(null); const [isAddFilterPopoverOpen, setIsAddFilterPopoverOpen] = useState(false); const [isEditFilterPopoverOpen, setIsEditFilterPopoverOpen] = useState(false); + const [editFilterGropId, setEditFilterGropId] = useState(null); const kibana = useKibana(); const { appName, usageCollection, uiSettings } = kibana.services; if (!uiSettings) return null; @@ -66,7 +67,10 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { } const onAddFilterClick = () => setIsAddFilterPopoverOpen(!isAddFilterPopoverOpen); - const onEditFilterClick = () => setIsEditFilterPopoverOpen(!isEditFilterPopoverOpen); + const onEditFilterClick = (groupId: string) => { + setEditFilterGropId(groupId); + setIsEditFilterPopoverOpen(!isEditFilterPopoverOpen); + }; function renderItems() { return props.multipleFilters.map((filter, i) => { @@ -178,13 +182,15 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { const index = indexPattern && indexPattern.id; const newFilter = buildEmptyFilter(isPinned, index); + const filteredFilter = props.multipleFilters?.filter(({ groupId }) => groupId === Number(editFilterGropId)); + return ( {isEditFilterPopoverOpen && ( void; - onEditFilterClick: () => void; + onEditFilterClick: (groupId: string) => void; } export const FilterExpressionItem: FC = ({ @@ -76,7 +76,7 @@ export const FilterExpressionItem: FC = ({ // const finalFilters = [...multipleUpdatedFilters, ...groupedFilters]; // onUpdate?.(finalFilters, groupId, false); - onEditFilterClick(); + onEditFilterClick(groupId); } function onDuplicate() { @@ -439,7 +439,7 @@ export const FilterExpressionItem: FC = ({ button={badge} panelPaddingSize="none" > - + ); }; From 9679c2710527eee7a0165757eb02bd7b496f6aa3 Mon Sep 17 00:00:00 2001 From: Nodir Date: Sun, 30 Jan 2022 16:02:39 +0500 Subject: [PATCH 07/19] feat: add delete and Apply buttons --- .../query_string_input/add_filter_modal.tsx | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx b/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx index 3139f21cf7f49..98e8b57c1a504 100644 --- a/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx +++ b/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx @@ -121,7 +121,7 @@ export function AddFilterModal({ const [localFilters, setLocalFilters] = useState( convertFilterToFilterGroup(multipleFilters) ); - const [groupsCount, setGroupsCount] = useState(1); + const [groupsCount, setGroupsCount] = useState(multipleFilters?.length >= 1 ? multipleFilters[0].groupId : 1); function convertFilterToFilterGroup(convertibleFilters: Filter[] | undefined): FilterGroup[] { if (!convertibleFilters) { @@ -421,6 +421,10 @@ export function AddFilterModal({ } }; + const onApplyChangesFilter = () => {}; + + const onDeliteFilter = () => {}; + const renderGroupedFilters = () => { const groupedFiltersNew = groupBy(localFilters, 'groupId'); const GroupComponent: JSX.Element[] = []; @@ -519,14 +523,13 @@ export function AddFilterModal({ operator: undefined, value: undefined, relationship: undefined, - groupId: - filtersOnGroup.length > 1 ? groupsCount : groupsCount + 1, + groupId: groupsCount, subGroupId, id: localFilters.length, }, ]); if (filtersOnGroup.length <= 1) { - setGroupsCount(groupsCount + 1); + setGroupsCount(groupsCount => groupsCount + 1); } }} iconType="plus" @@ -686,6 +689,20 @@ export function AddFilterModal({ })} + + + + {i18n.translate('data.filter.addFilterModal.deleteFilterBtnLabel', { + defaultMessage: 'Delete filter', + })} + + + + + + + {i18n.translate('data.filter.addFilterModal.applyChangesFilterBtnLabel', { + defaultMessage: 'Apply changes', + })} + + From 5977881089092473d1c5414a10c7bc26649a5878 Mon Sep 17 00:00:00 2001 From: Nodir Date: Sun, 30 Jan 2022 19:47:44 +0500 Subject: [PATCH 08/19] feat: add remove gilter group function --- .../data/public/ui/filter_bar/filter_bar.tsx | 24 +++++++++++++++++++ .../query_string_input/add_filter_modal.tsx | 14 +++++++---- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx index 409e366ec7b3c..239a56be87901 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -67,11 +67,34 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { } const onAddFilterClick = () => setIsAddFilterPopoverOpen(!isAddFilterPopoverOpen); + const onEditFilterClick = (groupId: string) => { setEditFilterGropId(groupId); setIsEditFilterPopoverOpen(!isEditFilterPopoverOpen); }; + const onDeleteFilterGroup = (groupId: string) => { + console.log('onDeleteFilterGroup', groupId); + const multipleFilters = [...props.multipleFilters]; + const updatedMultipleFilters = multipleFilters.filter( + (filter) => filter.groupId !== Number(groupId) + ); + const filters = [...props.filters]; + const updatedFilters: Filter[] = []; + + updatedMultipleFilters.forEach((filter) => { + filters.forEach((f) => { + if (isEqual(f.query, filter.query)) { + updatedFilters.push(f); + } + }); + }); + onFiltersUpdated(updatedFilters); + props?.onMultipleFiltersUpdated?.(updatedMultipleFilters); + + setIsEditFilterPopoverOpen(!isEditFilterPopoverOpen); + }; + function renderItems() { return props.multipleFilters.map((filter, i) => { // Do not display filters from saved queries @@ -195,6 +218,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { onSubmit={onEditFilterClick} onMultipleFiltersSubmit={onEditFilterClick} applySavedQueries={onEditFilterClick} + onRemoveFilterGroup={onDeleteFilterGroup} timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride} savedQueryManagement={undefined} initialAddFilterMode={undefined} diff --git a/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx b/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx index 98e8b57c1a504..09cd4d7de7da6 100644 --- a/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx +++ b/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx @@ -100,6 +100,7 @@ export function AddFilterModal({ timeRangeForSuggestionsOverride, savedQueryManagement, initialAddFilterMode, + onRemoveFilterGroup }: { onSubmit: (filters: Filter[]) => void; onMultipleFiltersSubmit: (filters: FilterGroup[], buildFilters: Filter[]) => void; @@ -111,6 +112,7 @@ export function AddFilterModal({ timeRangeForSuggestionsOverride?: boolean; savedQueryManagement?: JSX.Element; initialAddFilterMode?: string; + onRemoveFilterGroup: (groupId: string) => void; }) { const [selectedIndexPattern, setSelectedIndexPattern] = useState( getIndexPatternFromFilter(filter, indexPatterns) @@ -121,7 +123,7 @@ export function AddFilterModal({ const [localFilters, setLocalFilters] = useState( convertFilterToFilterGroup(multipleFilters) ); - const [groupsCount, setGroupsCount] = useState(multipleFilters?.length >= 1 ? multipleFilters[0].groupId : 1); + const [groupsCount, setGroupsCount] = useState(1); function convertFilterToFilterGroup(convertibleFilters: Filter[] | undefined): FilterGroup[] { if (!convertibleFilters) { @@ -133,7 +135,7 @@ export function AddFilterModal({ groupId: 1, id: 0, subGroupId: 1, - relationship: undefined + relationship: undefined, }, ]; } @@ -423,7 +425,9 @@ export function AddFilterModal({ const onApplyChangesFilter = () => {}; - const onDeliteFilter = () => {}; + const onDeliteFilter = () => { + onRemoveFilterGroup(multipleFilters[0]?.groupId); + }; const renderGroupedFilters = () => { const groupedFiltersNew = groupBy(localFilters, 'groupId'); @@ -523,13 +527,13 @@ export function AddFilterModal({ operator: undefined, value: undefined, relationship: undefined, - groupId: groupsCount, + groupId: filtersOnGroup.length > 1 ? groupsCount : groupsCount + 1, subGroupId, id: localFilters.length, }, ]); if (filtersOnGroup.length <= 1) { - setGroupsCount(groupsCount => groupsCount + 1); + setGroupsCount(groupsCount + 1); } }} iconType="plus" From 617fa9551e155cc8d6ba21065c9be61e4f1f8294 Mon Sep 17 00:00:00 2001 From: Nodir Date: Mon, 31 Jan 2022 10:47:59 +0500 Subject: [PATCH 09/19] feat: separated add filter and edit filter to 2 files --- .../data/public/ui/filter_bar/filter_bar.tsx | 4 +- .../query_string_input/add_filter_modal.tsx | 35 +- .../query_string_input/edit_filter_modal.tsx | 722 ++++++++++++++++++ 3 files changed, 725 insertions(+), 36 deletions(-) create mode 100644 src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx diff --git a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx index 239a56be87901..9f04d2e02d92c 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -33,7 +33,7 @@ import { SavedQueriesItem } from './saved_queries_item'; import { FilterExpressionItem } from './filter_expression_item'; import { UI_SETTINGS } from '../../../common'; -import { AddFilterModal } from '../query_string_input/add_filter_modal'; +import { EditFilterModal } from '../query_string_input/edit_filter_modal'; interface Props { filters: Filter[]; @@ -210,7 +210,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { return ( {isEditFilterPopoverOpen && ( - {}; - - const onDeliteFilter = () => { - onRemoveFilterGroup(multipleFilters[0]?.groupId); - }; - const renderGroupedFilters = () => { const groupedFiltersNew = groupBy(localFilters, 'groupId'); const GroupComponent: JSX.Element[] = []; @@ -693,20 +687,6 @@ export function AddFilterModal({ })} - - - - {i18n.translate('data.filter.addFilterModal.deleteFilterBtnLabel', { - defaultMessage: 'Delete filter', - })} - - - - - - - - {i18n.translate('data.filter.addFilterModal.applyChangesFilterBtnLabel', { - defaultMessage: 'Apply changes', - })} - - + diff --git a/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx b/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx new file mode 100644 index 0000000000000..38450e0580afa --- /dev/null +++ b/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx @@ -0,0 +1,722 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React, { useState } from 'react'; +import { groupBy } from 'lodash'; +import classNames from 'classnames'; +import { + Filter, + buildFilter, + buildCustomFilter, + cleanFilter, + getFilterParams, + FieldFilter, +} from '@kbn/es-query'; +import { + EuiFormRow, + EuiFlexGroup, + EuiFlexItem, + EuiModalFooter, + EuiButtonEmpty, + EuiButton, + EuiModal, + EuiModalHeaderTitle, + EuiModalHeader, + EuiModalBody, + EuiTabs, + EuiTab, + EuiForm, + EuiSpacer, + EuiHorizontalRule, + EuiButtonIcon, + EuiText, + EuiIcon, + EuiFieldText, +} from '@elastic/eui'; +import { XJsonLang } from '@kbn/monaco'; +import { i18n } from '@kbn/i18n'; +import { CodeEditor } from '../../../../kibana_react/public'; +import { getIndexPatternFromFilter } from '../../query'; +import { + getFilterableFields, + getOperatorOptions, + getFieldFromFilter, + getOperatorFromFilter, +} from '../filter_bar/filter_editor/lib/filter_editor_utils'; +import { Operator } from '../filter_bar/filter_editor/lib/filter_operators'; + +import { GenericComboBox } from '../filter_bar/filter_editor/generic_combo_box'; +import { PhraseValueInput } from '../filter_bar/filter_editor/phrase_value_input'; +import { PhrasesValuesInput } from '../filter_bar/filter_editor/phrases_values_input'; +import { RangeValueInput } from '../filter_bar/filter_editor/range_value_input'; + +import { IIndexPattern, IFieldType } from '../..'; +import { filter } from '../../../../console/server/lib/spec_definitions/js/filter'; + +const tabs = [ + { + type: 'quick_form', + label: i18n.translate('data.filter.filterEditor.quickFormLabel', { + defaultMessage: 'Quick form', + }), + }, + { + type: 'query_builder', + label: i18n.translate('data.filter.filterEditor.queryBuilderLabel', { + defaultMessage: 'Query builder', + }), + } +]; + +export interface FilterGroup { + field: IFieldType | undefined; + operator: Operator | undefined; + value: any; + groupId: number; + id: number; + relationship?: string; + subGroupId?: number; +} + +export function EditFilterModal({ + onSubmit, + onMultipleFiltersSubmit, + onCancel, + applySavedQueries, + filter, + multipleFilters, + indexPatterns, + timeRangeForSuggestionsOverride, + savedQueryManagement, + initialAddFilterMode, + onRemoveFilterGroup +}: { + onSubmit: (filters: Filter[]) => void; + onMultipleFiltersSubmit: (filters: FilterGroup[], buildFilters: Filter[]) => void; + applySavedQueries: () => void; + onCancel: () => void; + filter: Filter; + multipleFilters?: Filter[]; + indexPatterns: IIndexPattern[]; + timeRangeForSuggestionsOverride?: boolean; + savedQueryManagement?: JSX.Element; + initialAddFilterMode?: string; + onRemoveFilterGroup: (groupId: string) => void; +}) { + const [selectedIndexPattern, setSelectedIndexPattern] = useState( + getIndexPatternFromFilter(filter, indexPatterns) + ); + const [addFilterMode, setAddFilterMode] = useState(initialAddFilterMode ?? tabs[0].type); + const [customLabel, setCustomLabel] = useState(filter.meta.alias || ''); + const [queryDsl, setQueryDsl] = useState(JSON.stringify(cleanFilter(filter), null, 2)); + const [localFilters, setLocalFilters] = useState( + convertFilterToFilterGroup(multipleFilters) + ); + const [groupsCount, setGroupsCount] = useState(1); + + function convertFilterToFilterGroup(convertibleFilters: Filter[] | undefined): FilterGroup[] { + if (!convertibleFilters) { + return [ + { + field: undefined, + operator: undefined, + value: undefined, + groupId: 1, + id: 0, + subGroupId: 1, + relationship: undefined, + }, + ]; + } + + return convertibleFilters.map((convertedfilter) => { + return { + field: getFieldFromFilter(convertedfilter as FieldFilter, selectedIndexPattern), + operator: getOperatorFromFilter(convertedfilter), + value: getFilterParams(convertedfilter), + groupId: convertedfilter.groupId, + id: convertedfilter.id, + subGroupId: convertedfilter.subGroupId, + relationship: convertedfilter.relationship + }; + }); + } + + const onIndexPatternChange = ([selectedPattern]: IIndexPattern[]) => { + setSelectedIndexPattern(selectedPattern); + setLocalFilters([ + { field: undefined, operator: undefined, value: undefined, groupId: 1, id: 0, subGroupId: 1 }, + ]); + setGroupsCount(1); + }; + + const onFieldChange = ([field]: IFieldType[], localFilterIndex: number) => { + const index = localFilters.findIndex((f) => f.id === localFilterIndex); + const updatedLocalFilter = { ...localFilters[index], field }; + localFilters[index] = updatedLocalFilter; + setLocalFilters([...localFilters]); + }; + + const onOperatorChange = ([operator]: Operator[], localFilterIndex: number) => { + const index = localFilters.findIndex((f) => f.id === localFilterIndex); + // Only reset params when the operator type changes + const params = + localFilters[localFilterIndex].operator?.type === operator.type + ? localFilters[localFilterIndex].value + : undefined; + const updatedLocalFilter = { ...localFilters[index], operator, value: params }; + localFilters[index] = updatedLocalFilter; + setLocalFilters([...localFilters]); + }; + + const onParamsChange = (newFilterParams: any, localFilterIndex: number) => { + const index = localFilters.findIndex((f) => f.id === localFilterIndex); + const updatedLocalFilter = { ...localFilters[index], value: newFilterParams }; + localFilters[index] = updatedLocalFilter; + setLocalFilters([...localFilters]); + }; + + const renderIndexPatternInput = () => { + if ( + indexPatterns.length <= 1 && + indexPatterns.find((indexPattern) => indexPattern === selectedIndexPattern) + ) { + /** + * Don't render the index pattern selector if there's just one \ zero index patterns + * and if the index pattern the filter was LOADED with is in the indexPatterns list. + **/ + + return ''; + } + return ( + + indexPattern.title} + onChange={onIndexPatternChange} + singleSelection={{ asPlainText: true }} + isClearable={false} + data-test-subj="filterIndexPatternsSelect" + /> + + ); + }; + + const renderFieldInput = (localFilterIndex: number) => { + const fields = selectedIndexPattern ? getFilterableFields(selectedIndexPattern) : []; + const selectedField = localFilters.filter( + (localFilter) => localFilter.id === localFilterIndex + )[0]?.field; + return ( + + + field.name} + onChange={(selected: IFieldType[]) => { + onFieldChange(selected, localFilterIndex); + }} + singleSelection={{ asPlainText: true }} + isClearable={false} + data-test-subj="filterFieldSuggestionList" + /> + + + ); + }; + + const renderOperatorInput = (localFilterIndex: number) => { + const selectedField = localFilters.filter( + (localFilter) => localFilter.id === localFilterIndex + )[0]?.field; + const operators = selectedField ? getOperatorOptions(selectedField) : []; + const selectedOperator = localFilters.filter( + (localFilter) => localFilter.id === localFilterIndex + )[0]?.operator; + + return ( + + + message} + onChange={(selected: Operator[]) => { + onOperatorChange(selected, localFilterIndex); + }} + singleSelection={{ asPlainText: true }} + isClearable={false} + data-test-subj="filterOperatorList" + /> + + + ); + }; + + const renderParamsEditor = (localFilterIndex: number) => { + const selectedOperator = localFilters.filter( + (localFilter) => localFilter.id === localFilterIndex + )[0]?.operator; + const selectedField = localFilters.filter( + (localFilter) => localFilter.id === localFilterIndex + )[0]?.field; + const selectedParams = localFilters.filter( + (localFilter) => localFilter.id === localFilterIndex + )[0]?.value; + switch (selectedOperator?.type) { + case 'exists': + return ''; + case 'phrases': + return ( + { + onParamsChange(newFilterParams, localFilterIndex); + }} + timeRangeForSuggestionsOverride={timeRangeForSuggestionsOverride} + fullWidth + compressed + /> + ); + case 'range': + return ( + { + onParamsChange(newFilterParams, localFilterIndex); + }} + fullWidth + compressed + /> + ); + default: + return ( + { + onParamsChange(newFilterParams, localFilterIndex); + }} + data-test-subj="phraseValueInput" + timeRangeForSuggestionsOverride={timeRangeForSuggestionsOverride} + fullWidth + compressed + /> + ); + } + }; + + const renderCustomEditor = () => { + return ( + + + + ); + }; + + const onAddFilter = () => { + const { $state } = filter; + if (!$state || !$state.store) { + return; // typescript validation + } + const alias = customLabel || null; + if (addFilterMode === 'query_builder') { + const { index, disabled = false, negate = false } = filter.meta; + const newIndex = index || indexPatterns[0].id!; + const body = JSON.parse(queryDsl); + const builtCustomFilter = buildCustomFilter( + newIndex, + body, + disabled, + negate, + alias, + $state.store + ); + onSubmit([builtCustomFilter]); + } else if (addFilterMode === 'quick_form' && selectedIndexPattern) { + const builtFilters = localFilters.map((localFilter) => { + if (localFilter.field && localFilter.operator) { + return buildFilter( + selectedIndexPattern, + localFilter.field, + localFilter.operator.type, + localFilter.operator.negate, + filter.meta.disabled ?? false, + localFilter.value ?? '', + alias, + $state.store + ); + } + }); + if (builtFilters && builtFilters.length) { + const finalFilters = builtFilters.filter( + (value) => typeof value !== 'undefined' + ) as Filter[]; + // onSubmit(finalFilters); + onMultipleFiltersSubmit(localFilters, finalFilters); + } + } else if (addFilterMode === 'saved_filters') { + applySavedQueries(); + } + }; + + const onApplyChangesFilter = () => {}; + + const onDeliteFilter = () => { + onRemoveFilterGroup(multipleFilters[0]?.groupId); + }; + + const renderGroupedFilters = () => { + const groupedFiltersNew = groupBy(localFilters, 'groupId'); + const GroupComponent: JSX.Element[] = []; + for (const [groupId, groupedFilters] of Object.entries(groupedFiltersNew)) { + const filtersInGroup = groupedFilters.length; + const groupBySubgroups = groupBy(groupedFilters, 'subGroupId'); + const subGroups = []; + for (const [_, subGroupedFilters] of Object.entries(groupBySubgroups)) { + subGroups.push(subGroupedFilters); + } + + const temp = ( +
1 && groupsCount > 1 ? 'kbnQueryBar__filterModalGroups' : '' + )} + > + {subGroups.map((subGroup, subGroupIdx) => { + const classes = + subGroup.length > 1 && groupsCount > 1 + ? 'kbnQueryBar__filterModalSubGroups' + : groupsCount === 1 && subGroup.length > 1 + ? 'kbnQueryBar__filterModalGroups' + : ''; + return ( + <> +
+ {subGroup.map((localfilter, index) => { + return ( + <> + + + + + {renderFieldInput(localfilter.id)} + {renderOperatorInput(localfilter.id)} + + + {renderParamsEditor(localfilter.id)} + + {subGroup.length < 2 && ( + + { + const updatedLocalFilter = { ...localfilter, relationship: 'OR' }; + const idx = localFilters.findIndex( + (f) => f.id === localfilter.id && f.groupId === Number(groupId) + ); + const subGroupId = (localfilter?.subGroupId ?? 0) + 1; + if (subGroup.length < 2) { + localFilters[idx] = updatedLocalFilter; + } + setLocalFilters([ + ...localFilters, + { + field: undefined, + operator: undefined, + value: undefined, + relationship: undefined, + groupId: localfilter.groupId, + id: localFilters.length, + subGroupId, + }, + ]); + }} + iconType="returnKey" + size="s" + aria-label="Add filter group with OR" + /> + + )} + + { + const filtersOnGroup = localFilters.filter( + (f) => f.groupId === Number(groupId) + ); + const subGroupId = + filtersOnGroup.length > 2 + ? localfilter?.subGroupId ?? 0 + : (localfilter?.subGroupId ?? 0) + 1; + const updatedLocalFilter = { + ...localfilter, + relationship: 'AND', + subGroupId: filtersOnGroup.length > 1 ? subGroupId : 1, + }; + const idx = localFilters.findIndex( + (f) => f.id === localfilter.id && f.groupId === Number(groupId) + ); + localFilters[idx] = updatedLocalFilter; + setLocalFilters([ + ...localFilters, + { + field: undefined, + operator: undefined, + value: undefined, + relationship: undefined, + groupId: filtersOnGroup.length > 1 ? groupsCount : groupsCount + 1, + subGroupId, + id: localFilters.length, + }, + ]); + if (filtersOnGroup.length <= 1) { + setGroupsCount(groupsCount + 1); + } + }} + iconType="plus" + size="s" + aria-label="Add filter group with AND" + /> + + {localFilters.length > 1 && ( + + { + const currentIdx = localFilters.findIndex( + (f) => f.id === localfilter.id + ); + if (currentIdx > 0) { + localFilters[currentIdx - 1].relationship = 'AND'; + } + const updatedFilters = localFilters.filter( + (_, idx) => idx !== localfilter.id + ); + const filtersOnGroup = updatedFilters.filter( + (f) => f.groupId === Number(groupId) + ); + if (filtersOnGroup.length < 1) { + setGroupsCount(groupsCount - 1); + } + setLocalFilters(updatedFilters); + }} + iconType="trash" + size="s" + color="danger" + aria-label="Delete filter group" + /> + + )} + + {localfilter.relationship && + localfilter.relationship === 'OR' && + subGroup.length === 0 && ( + <> + + + + + + + {' '} + OR{' '} + + + + + + + + )} + + ); + })} +
+ <> + {subGroup.length > 0 && subGroupIdx !== subGroups.length - 1 && ( + <> + + + + + + + {' '} + OR{' '} + + + + + + + + )} + + + ); + })} +
+ ); + GroupComponent.push(temp); + } + return GroupComponent; + }; + + return ( + + + +

+ {i18n.translate('data.filter.editFilterModal.headerTitle', { + defaultMessage: 'Edit filter', + })} +

+
+ {renderIndexPatternInput()} +
+ + + + {tabs.map(({ label, type }) => ( + setAddFilterMode(type)} + data-test-subj={`${type}FilterMode`} + > + {label} + + ))} + + + + + + + + {addFilterMode === 'quick_form' && renderGroupedFilters()} + {addFilterMode === 'query_builder' && renderCustomEditor()} + {addFilterMode === 'saved_filters' && savedQueryManagement} + + + + + + {addFilterMode !== 'saved_filters' && ( + + + setCustomLabel(e.target.value)} + compressed + /> + + + )} + + + + + {i18n.translate('xpack.lens.palette.saveModal.cancelLabel', { + defaultMessage: 'Cancel', + })} + + + + + + {i18n.translate('data.filter.addFilterModal.deleteFilterBtnLabel', { + defaultMessage: 'Delete filter', + })} + + + + + + {i18n.translate('data.filter.addFilterModal.applyChangesFilterBtnLabel', { + defaultMessage: 'Apply changes', + })} + + + + + + +
+ ); +} From 0ff6721e035e19a113c977388aa7da6a1d5c01fd Mon Sep 17 00:00:00 2001 From: Nodir Date: Mon, 31 Jan 2022 13:27:36 +0500 Subject: [PATCH 10/19] mino: little refact --- .../query_string_input/add_filter_modal.tsx | 46 +++++-------------- .../query_string_input/edit_filter_modal.tsx | 2 +- 2 files changed, 13 insertions(+), 35 deletions(-) diff --git a/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx b/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx index 8ce3995e0cd1d..9209877cdfbe7 100644 --- a/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx +++ b/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx @@ -100,7 +100,6 @@ export function AddFilterModal({ timeRangeForSuggestionsOverride, savedQueryManagement, initialAddFilterMode, - onRemoveFilterGroup }: { onSubmit: (filters: Filter[]) => void; onMultipleFiltersSubmit: (filters: FilterGroup[], buildFilters: Filter[]) => void; @@ -112,7 +111,6 @@ export function AddFilterModal({ timeRangeForSuggestionsOverride?: boolean; savedQueryManagement?: JSX.Element; initialAddFilterMode?: string; - onRemoveFilterGroup: (groupId: string) => void; }) { const [selectedIndexPattern, setSelectedIndexPattern] = useState( getIndexPatternFromFilter(filter, indexPatterns) @@ -120,39 +118,19 @@ export function AddFilterModal({ const [addFilterMode, setAddFilterMode] = useState(initialAddFilterMode ?? tabs[0].type); const [customLabel, setCustomLabel] = useState(filter.meta.alias || ''); const [queryDsl, setQueryDsl] = useState(JSON.stringify(cleanFilter(filter), null, 2)); - const [localFilters, setLocalFilters] = useState( - convertFilterToFilterGroup(multipleFilters) - ); + const [localFilters, setLocalFilters] = useState([ + { + field: undefined, + operator: undefined, + value: undefined, + groupId: 1, + id: 0, + subGroupId: 1, + relationship: undefined, + }, + ]); const [groupsCount, setGroupsCount] = useState(1); - function convertFilterToFilterGroup(convertibleFilters: Filter[] | undefined): FilterGroup[] { - if (!convertibleFilters) { - return [ - { - field: undefined, - operator: undefined, - value: undefined, - groupId: 1, - id: 0, - subGroupId: 1, - relationship: undefined, - }, - ]; - } - - return convertibleFilters.map((convertedfilter) => { - return { - field: getFieldFromFilter(convertedfilter as FieldFilter, selectedIndexPattern), - operator: getOperatorFromFilter(convertedfilter), - value: getFilterParams(convertedfilter), - groupId: convertedfilter.groupId, - id: convertedfilter.id, - subGroupId: convertedfilter.subGroupId, - relationship: convertedfilter.relationship - }; - }); - } - const onIndexPatternChange = ([selectedPattern]: IIndexPattern[]) => { setSelectedIndexPattern(selectedPattern); setLocalFilters([ @@ -698,7 +676,7 @@ export function AddFilterModal({ defaultMessage: 'Add filter', })} - + diff --git a/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx b/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx index 38450e0580afa..96f70651730cf 100644 --- a/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx +++ b/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx @@ -94,7 +94,7 @@ export function EditFilterModal({ timeRangeForSuggestionsOverride, savedQueryManagement, initialAddFilterMode, - onRemoveFilterGroup + onRemoveFilterGroup, }: { onSubmit: (filters: Filter[]) => void; onMultipleFiltersSubmit: (filters: FilterGroup[], buildFilters: Filter[]) => void; From 43d1367f4aedc6b98dca84b18625970b2398d441 Mon Sep 17 00:00:00 2001 From: Nodir Date: Mon, 31 Jan 2022 14:24:58 +0500 Subject: [PATCH 11/19] refact: changed the logic of opening the editing window --- .../data/public/ui/filter_bar/filter_bar.tsx | 138 +----------------- .../query_string_input/add_filter_modal.tsx | 13 +- .../query_string_input/edit_filter_modal.tsx | 7 +- .../data/public/ui/search_bar/search_bar.tsx | 14 ++ 4 files changed, 24 insertions(+), 148 deletions(-) diff --git a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx index 9f04d2e02d92c..5222badf3ddcf 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -47,12 +47,13 @@ interface Props { selectedSavedQueries?: SavedQuery[]; removeSelectedSavedQuery: (savedQuery: SavedQuery) => void; onMultipleFiltersUpdated?: (filters: Filter[]) => void; + toggleEditFilterModal: (value: boolean) => void; + isEditFilterModalOpen?: boolean; + editFilterMode?: string; } const FilterBarUI = React.memo(function FilterBarUI(props: Props) { const groupRef = useRef(null); - const [isAddFilterPopoverOpen, setIsAddFilterPopoverOpen] = useState(false); - const [isEditFilterPopoverOpen, setIsEditFilterPopoverOpen] = useState(false); const [editFilterGropId, setEditFilterGropId] = useState(null); const kibana = useKibana(); const { appName, usageCollection, uiSettings } = kibana.services; @@ -66,15 +67,12 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { } } - const onAddFilterClick = () => setIsAddFilterPopoverOpen(!isAddFilterPopoverOpen); - const onEditFilterClick = (groupId: string) => { setEditFilterGropId(groupId); - setIsEditFilterPopoverOpen(!isEditFilterPopoverOpen); + props.toggleEditFilterModal?.(true); }; const onDeleteFilterGroup = (groupId: string) => { - console.log('onDeleteFilterGroup', groupId); const multipleFilters = [...props.multipleFilters]; const updatedMultipleFilters = multipleFilters.filter( (filter) => filter.groupId !== Number(groupId) @@ -92,7 +90,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { onFiltersUpdated(updatedFilters); props?.onMultipleFiltersUpdated?.(updatedMultipleFilters); - setIsEditFilterPopoverOpen(!isEditFilterPopoverOpen); + props.toggleEditFilterModal?.(false); }; function renderItems() { @@ -148,76 +146,18 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { return GroupBadge; } - function renderAddFilter() { - const isPinned = uiSettings!.get(UI_SETTINGS.FILTERS_PINNED_BY_DEFAULT); - const [indexPattern] = props.indexPatterns; - const index = indexPattern && indexPattern.id; - const newFilter = buildEmptyFilter(isPinned, index); - - const button = ( - - +{' '} - - - ); - - return ( - - setIsAddFilterPopoverOpen(false)} - anchorPosition="downLeft" - panelPaddingSize="none" - initialFocus=".filterEditor__hiddenItem" - ownFocus - repositionOnScroll - > - -
- setIsAddFilterPopoverOpen(false)} - key={JSON.stringify(newFilter)} - timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride} - /> -
-
-
-
- ); - } - function renderEditFilter() { - const isPinned = uiSettings!.get(UI_SETTINGS.FILTERS_PINNED_BY_DEFAULT); - const [indexPattern] = props?.indexPatterns || []; - const index = indexPattern && indexPattern.id; - const newFilter = buildEmptyFilter(isPinned, index); - const filteredFilter = props.multipleFilters?.filter(({ groupId }) => groupId === Number(editFilterGropId)); return ( - {isEditFilterPopoverOpen && ( + {props.isEditFilterModalOpen && ( props.toggleEditFilterModal?.(false)} + onCancel={() => props.toggleEditFilterModal?.(false)} filter={props.filters[0]} multipleFilters={filteredFilter} indexPatterns={props.indexPatterns!} - onSubmit={onEditFilterClick} - onMultipleFiltersSubmit={onEditFilterClick} - applySavedQueries={onEditFilterClick} onRemoveFilterGroup={onDeleteFilterGroup} timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride} savedQueryManagement={undefined} @@ -228,14 +168,6 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { ); } - function onAdd(filter: Filter) { - reportUiCounter?.(METRIC_TYPE.CLICK, `filter:added`); - setIsAddFilterPopoverOpen(false); - - const filters = [...props.filters, filter]; - onFiltersUpdated(filters); - } - function onRemove(i: number) { reportUiCounter?.(METRIC_TYPE.CLICK, `filter:removed`); const filters = [...props.filters]; @@ -297,47 +229,6 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { onFiltersUpdated(filters); } - // function onEnableAll() { - // reportUiCounter?.(METRIC_TYPE.CLICK, `filter:enable_all`); - // const filters = props.filters.map(enableFilter); - // onFiltersUpdated(filters); - // } - - // function onDisableAll() { - // reportUiCounter?.(METRIC_TYPE.CLICK, `filter:disable_all`); - // const filters = props.filters.map(disableFilter); - // onFiltersUpdated(filters); - // } - - // function onPinAll() { - // reportUiCounter?.(METRIC_TYPE.CLICK, `filter:pin_all`); - // const filters = props.filters.map(pinFilter); - // onFiltersUpdated(filters); - // } - - // function onUnpinAll() { - // reportUiCounter?.(METRIC_TYPE.CLICK, `filter:unpin_all`); - // const filters = props.filters.map(unpinFilter); - // onFiltersUpdated(filters); - // } - - // function onToggleAllNegated() { - // reportUiCounter?.(METRIC_TYPE.CLICK, `filter:invert_all`); - // const filters = props.filters.map(toggleFilterNegated); - // onFiltersUpdated(filters); - // } - - // function onToggleAllDisabled() { - // reportUiCounter?.(METRIC_TYPE.CLICK, `filter:toggle_all`); - // const filters = props.filters.map(toggleFilterDisabled); - // onFiltersUpdated(filters); - // } - - // function onRemoveAll() { - // reportUiCounter?.(METRIC_TYPE.CLICK, `filter:remove_all`); - // onFiltersUpdated([]); - // } - const classes = classNames('globalFilterBar', props.className); return ( @@ -347,18 +238,6 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { alignItems="flexStart" responsive={false} > - {/* - - */} - diff --git a/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx b/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx index 9209877cdfbe7..e02e734916f04 100644 --- a/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx +++ b/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx @@ -9,14 +9,7 @@ import React, { useState } from 'react'; import { groupBy } from 'lodash'; import classNames from 'classnames'; -import { - Filter, - buildFilter, - buildCustomFilter, - cleanFilter, - getFilterParams, - FieldFilter, -} from '@kbn/es-query'; +import { Filter, buildFilter, buildCustomFilter, cleanFilter } from '@kbn/es-query'; import { EuiFormRow, EuiFlexGroup, @@ -45,8 +38,6 @@ import { getIndexPatternFromFilter } from '../../query'; import { getFilterableFields, getOperatorOptions, - getFieldFromFilter, - getOperatorFromFilter, } from '../filter_bar/filter_editor/lib/filter_editor_utils'; import { Operator } from '../filter_bar/filter_editor/lib/filter_operators'; @@ -56,7 +47,6 @@ import { PhrasesValuesInput } from '../filter_bar/filter_editor/phrases_values_i import { RangeValueInput } from '../filter_bar/filter_editor/range_value_input'; import { IIndexPattern, IFieldType } from '../..'; -import { filter } from '../../../../console/server/lib/spec_definitions/js/filter'; const tabs = [ { @@ -95,7 +85,6 @@ export function AddFilterModal({ onCancel, applySavedQueries, filter, - multipleFilters, indexPatterns, timeRangeForSuggestionsOverride, savedQueryManagement, diff --git a/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx b/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx index 96f70651730cf..dedc4a2d3dde0 100644 --- a/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx +++ b/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx @@ -56,7 +56,6 @@ import { PhrasesValuesInput } from '../filter_bar/filter_editor/phrases_values_i import { RangeValueInput } from '../filter_bar/filter_editor/range_value_input'; import { IIndexPattern, IFieldType } from '../..'; -import { filter } from '../../../../console/server/lib/spec_definitions/js/filter'; const tabs = [ { @@ -84,8 +83,6 @@ export interface FilterGroup { } export function EditFilterModal({ - onSubmit, - onMultipleFiltersSubmit, onCancel, applySavedQueries, filter, @@ -96,8 +93,6 @@ export function EditFilterModal({ initialAddFilterMode, onRemoveFilterGroup, }: { - onSubmit: (filters: Filter[]) => void; - onMultipleFiltersSubmit: (filters: FilterGroup[], buildFilters: Filter[]) => void; applySavedQueries: () => void; onCancel: () => void; filter: Filter; @@ -417,7 +412,7 @@ export function EditFilterModal({ } }; - const onApplyChangesFilter = () => {}; + const onApplyChangesFilter = () => { }; const onDeliteFilter = () => { onRemoveFilterGroup(multipleFilters[0]?.groupId); diff --git a/src/plugins/data/public/ui/search_bar/search_bar.tsx b/src/plugins/data/public/ui/search_bar/search_bar.tsx index 6f5dc8cd78d97..1fd2af18fe1fa 100644 --- a/src/plugins/data/public/ui/search_bar/search_bar.tsx +++ b/src/plugins/data/public/ui/search_bar/search_bar.tsx @@ -119,7 +119,9 @@ interface State { dateRangeFrom: string; dateRangeTo: string; isAddFilterModalOpen?: boolean; + isEditFilterModalOpen?: boolean; addFilterMode?: string; + editFilterMode?: string; filtersIdsFromSavedQueries?: string[]; overrideTimeFilterModalShow: boolean; } @@ -208,7 +210,9 @@ class SearchBarUI extends Component { dateRangeFrom: get(this.props, 'dateRangeFrom', 'now-15m'), dateRangeTo: get(this.props, 'dateRangeTo', 'now'), isAddFilterModalOpen: false, + isEditFilterModalOpen: false, addFilterMode: 'quick_form', + editFilterMode: 'quick_form', filtersIdsFromSavedQueries: [], overrideTimeFilterModalShow: false, }; @@ -524,6 +528,13 @@ class SearchBarUI extends Component { }); }; + public toggleEditFilterModal = (value: boolean, editFilterMode?: string) => { + this.setState({ + isEditFilterModalOpen: value, + editFilterMode: editFilterMode || 'quick_form', + }); + }; + public toggleFilterSetPopover = (value: boolean) => { this.setState({ openFilterSetPopover: value, @@ -695,6 +706,9 @@ class SearchBarUI extends Component { removeSelectedSavedQuery={this.removeSelectedSavedQuery} onMultipleFiltersUpdated={this.onMultipleFiltersUpdated} multipleFilters={this.state.multipleFilters} + toggleEditFilterModal={this.toggleEditFilterModal} + isEditFilterModalOpen={this.state.isEditFilterModalOpen} + editFilterMode={this.state.editFilterMode} />
); From 3359e4c9fd60e9674a5898c264189a82aa8e0ef6 Mon Sep 17 00:00:00 2001 From: Nodir Date: Tue, 1 Feb 2022 00:18:20 +0500 Subject: [PATCH 12/19] fix: show all filter in Edit filter modal --- src/plugins/data/public/ui/filter_bar/filter_bar.tsx | 8 ++------ .../data/public/ui/filter_bar/filter_expression_item.tsx | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx index 5222badf3ddcf..9bdca89aa7d5f 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -54,7 +54,6 @@ interface Props { const FilterBarUI = React.memo(function FilterBarUI(props: Props) { const groupRef = useRef(null); - const [editFilterGropId, setEditFilterGropId] = useState(null); const kibana = useKibana(); const { appName, usageCollection, uiSettings } = kibana.services; if (!uiSettings) return null; @@ -67,8 +66,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { } } - const onEditFilterClick = (groupId: string) => { - setEditFilterGropId(groupId); + const onEditFilterClick = () => { props.toggleEditFilterModal?.(true); }; @@ -147,8 +145,6 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { } function renderEditFilter() { - const filteredFilter = props.multipleFilters?.filter(({ groupId }) => groupId === Number(editFilterGropId)); - return ( {props.isEditFilterModalOpen && ( @@ -156,7 +152,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { applySavedQueries={() => props.toggleEditFilterModal?.(false)} onCancel={() => props.toggleEditFilterModal?.(false)} filter={props.filters[0]} - multipleFilters={filteredFilter} + multipleFilters={props.multipleFilters} indexPatterns={props.indexPatterns!} onRemoveFilterGroup={onDeleteFilterGroup} timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride} diff --git a/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx b/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx index d80a63508fdd7..2e6e592d5b545 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx @@ -46,7 +46,7 @@ interface Props { groupId: string; filtersGroupsCount: number; onUpdate?: (filters: Filter[], groupId: string, toggleNegate: boolean) => void; - onEditFilterClick: (groupId: string) => void; + onEditFilterClick: () => void; } export const FilterExpressionItem: FC = ({ @@ -76,7 +76,7 @@ export const FilterExpressionItem: FC = ({ // const finalFilters = [...multipleUpdatedFilters, ...groupedFilters]; // onUpdate?.(finalFilters, groupId, false); - onEditFilterClick(groupId); + onEditFilterClick(); } function onDuplicate() { From 54fcee67c55ed6c30044a9266f13b5e37399a5c5 Mon Sep 17 00:00:00 2001 From: Nodir Date: Tue, 1 Feb 2022 03:05:56 +0500 Subject: [PATCH 13/19] minor: remove properties in Filter type --- packages/kbn-es-query/src/filters/build_filters/types.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/kbn-es-query/src/filters/build_filters/types.ts b/packages/kbn-es-query/src/filters/build_filters/types.ts index 62196c1d19994..d7fa064d42b24 100644 --- a/packages/kbn-es-query/src/filters/build_filters/types.ts +++ b/packages/kbn-es-query/src/filters/build_filters/types.ts @@ -75,10 +75,6 @@ export type Filter = { }; meta: FilterMeta; query?: Record; - groupId?: number; - id?: number; - relationship?: 'AND' | 'OR' | undefined; - subGroupId?: number; }; // eslint-disable-next-line From d26fd882b6ff8409cdefad1bb5a18451d8589d48 Mon Sep 17 00:00:00 2001 From: Nodir Date: Tue, 1 Feb 2022 03:08:14 +0500 Subject: [PATCH 14/19] minor: rename edit filter --- src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx b/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx index 97c560e7f7ef6..726a4bf29a43c 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_editor/index.tsx @@ -91,7 +91,7 @@ class FilterEditorUI extends Component { From 40fd46dc347f416d3127ebea4efc542aa1e93025 Mon Sep 17 00:00:00 2001 From: Nodir Date: Tue, 1 Feb 2022 13:03:51 +0500 Subject: [PATCH 15/19] feat: add Apply changes filter --- .../data/public/ui/filter_bar/filter_bar.tsx | 29 +++++++++++++++++++ .../query_string_input/edit_filter_modal.tsx | 10 +++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx index 9bdca89aa7d5f..c47a754ec94bf 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -34,6 +34,8 @@ import { FilterExpressionItem } from './filter_expression_item'; import { UI_SETTINGS } from '../../../common'; import { EditFilterModal } from '../query_string_input/edit_filter_modal'; +import { mapAndFlattenFilters } from '../../query/filter_manager/lib/map_and_flatten_filters'; +import { FilterGroup } from '../query_string_input/edit_filter_modal'; interface Props { filters: Filter[]; @@ -91,6 +93,31 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { props.toggleEditFilterModal?.(false); }; + function onAddMultipleFilters(selectedFilters: Filter[]) { + props.toggleEditFilterModal?.(false); + + const filters = [...props.filters, ...selectedFilters]; + props?.onFiltersUpdated?.(filters); + } + + function onAddMultipleFiltersANDOR(selectedFilters: FilterGroup[], buildFilters: Filter[]) { + const mappedFilters = mapAndFlattenFilters(buildFilters); + const mergedFilters = mappedFilters.map((filter, idx) => { + return { + ...filter, + groupId: selectedFilters[idx].groupId, + id: selectedFilters[idx].id, + relationship: selectedFilters[idx].relationship, + subGroupId: selectedFilters[idx].subGroupId, + }; + }); + props.toggleEditFilterModal?.(false); + props?.onMultipleFiltersUpdated?.(mergedFilters); + + const filters = [...props.filters, ...buildFilters]; + props?.onFiltersUpdated?.(filters); + } + function renderItems() { return props.multipleFilters.map((filter, i) => { // Do not display filters from saved queries @@ -149,6 +176,8 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { {props.isEditFilterModalOpen && ( props.toggleEditFilterModal?.(false)} onCancel={() => props.toggleEditFilterModal?.(false)} filter={props.filters[0]} diff --git a/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx b/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx index dedc4a2d3dde0..c3868b975f58f 100644 --- a/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx +++ b/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx @@ -83,6 +83,8 @@ export interface FilterGroup { } export function EditFilterModal({ + onSubmit, + onMultipleFiltersSubmit, onCancel, applySavedQueries, filter, @@ -93,6 +95,8 @@ export function EditFilterModal({ initialAddFilterMode, onRemoveFilterGroup, }: { + onSubmit: (filters: Filter[]) => void; + onMultipleFiltersSubmit: (filters: FilterGroup[], buildFilters: Filter[]) => void; applySavedQueries: () => void; onCancel: () => void; filter: Filter; @@ -366,7 +370,7 @@ export function EditFilterModal({ ); }; - const onAddFilter = () => { + const onUpdateFilter = () => { const { $state } = filter; if (!$state || !$state.store) { return; // typescript validation @@ -412,7 +416,9 @@ export function EditFilterModal({ } }; - const onApplyChangesFilter = () => { }; + const onApplyChangesFilter = () => { + onUpdateFilter(); + }; const onDeliteFilter = () => { onRemoveFilterGroup(multipleFilters[0]?.groupId); From a7b0b0de5002cb18f6f9aac4d44fa0a0491624ef Mon Sep 17 00:00:00 2001 From: Nodir Date: Thu, 3 Feb 2022 02:54:47 +0500 Subject: [PATCH 16/19] refact: minor changes --- src/plugins/data/public/ui/filter_bar/filter_bar.tsx | 8 ++++---- .../public/ui/filter_bar/filter_expression_item.tsx | 2 +- src/plugins/data/public/ui/filter_bar/filter_item.tsx | 2 +- .../public/ui/query_string_input/add_filter_modal.tsx | 11 ++++++----- src/plugins/data/public/ui/search_bar/search_bar.tsx | 9 --------- 5 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx index d69ec5a66e0b0..cb10a3a01fe66 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -93,7 +93,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { props?.onFiltersUpdated?.(filters); } - function onAddMultipleFiltersANDOR(selectedFilters: FilterGroup[], buildFilters: Filter[]) { + function onEditMultipleFiltersANDOR(selectedFilters: FilterGroup[], buildFilters: Filter[]) { const mappedFilters = mapAndFlattenFilters(buildFilters); const mergedFilters = mappedFilters.map((filter, idx) => { return { @@ -158,7 +158,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { groupId={groupId} groupedFilters={groupedFilters} indexPatterns={props?.indexPatterns} - onClick={() => { }} + onClick={() => {}} onRemove={onRemoveFilterGroup} onUpdate={onUpdateFilterGroup} filtersGroupsCount={Object.entries(firstDepthGroupedFilters).length} @@ -181,7 +181,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { groupId={groupId} groupedFilters={groupedByAlias[label]} indexPatterns={props?.indexPatterns} - onClick={() => { }} + onClick={() => {}} onRemove={onRemoveFilterGroup} onUpdate={onUpdateFilterGroup} filtersGroupsCount={1} @@ -200,7 +200,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { {props.isEditFilterModalOpen && ( props.toggleEditFilterModal?.(false)} onCancel={() => props.toggleEditFilterModal?.(false)} filter={props.filters[0]} diff --git a/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx b/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx index ad3d276eec403..ca551006e197b 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx @@ -474,7 +474,7 @@ export const FilterExpressionItem: FC = ({ button={badge} panelPaddingSize="none" > - + ); }; diff --git a/src/plugins/data/public/ui/filter_bar/filter_item.tsx b/src/plugins/data/public/ui/filter_bar/filter_item.tsx index 29841ff308a9b..9e535513aa014 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_item.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_item.tsx @@ -178,7 +178,7 @@ export function FilterItem(props: FilterItemProps) { { name: props.intl.formatMessage({ id: 'data.filter.filterBar.editFilterButtonLabel', - defaultMessage: 'Edit filter old', + defaultMessage: 'Edit filter', }), icon: 'pencil', panel: 1, diff --git a/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx b/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx index 2d7e22ad1959b..8f4578cceabba 100644 --- a/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx +++ b/src/plugins/data/public/ui/query_string_input/add_filter_modal.tsx @@ -245,10 +245,10 @@ export function AddFilterModal({ placeholder={ selectedField ? i18n.translate('data.filter.filterEditor.operatorSelectPlaceholderSelect', { - defaultMessage: 'Operator', + defaultMessage: 'Operator', }) : i18n.translate('data.filter.filterEditor.operatorSelectPlaceholderWaiting', { - defaultMessage: 'Waiting', + defaultMessage: 'Waiting', }) } options={operators} @@ -434,8 +434,8 @@ export function AddFilterModal({ subGroup.length > 1 && groupsCount > 1 ? 'kbnQueryBar__filterModalSubGroups' : groupsCount === 1 && subGroup.length > 1 - ? 'kbnQueryBar__filterModalGroups' - : ''; + ? 'kbnQueryBar__filterModalGroups' + : ''; return ( <>
@@ -510,7 +510,8 @@ export function AddFilterModal({ operator: undefined, value: undefined, relationship: undefined, - groupId: filtersOnGroup.length > 1 ? groupsCount : groupsCount + 1, + groupId: + filtersOnGroup.length > 1 ? groupsCount : groupsCount + 1, subGroupId, id: localFilters.length, }, diff --git a/src/plugins/data/public/ui/search_bar/search_bar.tsx b/src/plugins/data/public/ui/search_bar/search_bar.tsx index ed0908a31bcc7..dfa2660793689 100644 --- a/src/plugins/data/public/ui/search_bar/search_bar.tsx +++ b/src/plugins/data/public/ui/search_bar/search_bar.tsx @@ -625,15 +625,6 @@ class SearchBarUI extends Component { savedQueryManagement={savedQueryManagement} applySelectedSavedQueries={this.applyTimeFilterOverrideModal} fillSubmitButton={this.props.fillSubmitButton || false} - // prepend={ - // this.props.showFilterBar && this.state.query - // ? this.renderSavedQueryManagement( - // this.props.onClearSavedQuery, - // this.props.showSaveQuery, - // this.props.savedQuery - // ) - // : undefined - // } showDatePicker={this.props.showDatePicker} dateRangeFrom={this.state.dateRangeFrom} dateRangeTo={this.state.dateRangeTo} From c7504e567db7799d9cb863dfeab3d520cb8cc8c3 Mon Sep 17 00:00:00 2001 From: Nodir Date: Thu, 3 Feb 2022 12:44:31 +0500 Subject: [PATCH 17/19] fix: issue adding double NOT in condition when filter adding with IS NOT --- .../ui/filter_bar/filter_expression_item.tsx | 23 +++++++++++-------- .../query_string_input/edit_filter_modal.tsx | 4 ++-- .../query_string_input/query_bar_top_row.tsx | 11 +-------- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx b/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx index ca551006e197b..f100405f8755e 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx @@ -96,7 +96,11 @@ export const FilterExpressionItem: FC = ({ function onToggleNegated() { const isNegated = groupedFilters[0].groupNegated; const multipleUpdatedFilters = groupedFilters?.map((filter: Filter) => { - return { ...filter, groupNegated: !isNegated }; + if (filter.meta.negate) { + return { ...filter, meta: { ...filter.meta, negate: false } } + } else { + return { ...filter, groupNegated: !isNegated }; + } }); onUpdate?.(multipleUpdatedFilters, groupId, true); @@ -145,11 +149,11 @@ export const FilterExpressionItem: FC = ({ { name: groupedFilters[0].meta.disabled ? i18n.translate('data.filter.filterBar.enableFilterButtonLabel', { - defaultMessage: `Re-enable`, - }) + defaultMessage: `Re-enable`, + }) : i18n.translate('data.filter.filterBar.disableFilterButtonLabel', { - defaultMessage: `Temporarily disable`, - }), + defaultMessage: `Temporarily disable`, + }), icon: `${groupedFilters[0].meta.disabled ? 'eye' : 'eyeClosed'}`, onClick: () => { setIsPopoverOpen(false); @@ -398,8 +402,8 @@ export const FilterExpressionItem: FC = ({ const prefixText = filter.meta.negate ? ` ${i18n.translate('data.filter.filterBar.negatedFilterPrefix', { - defaultMessage: 'NOT ', - })}` + defaultMessage: 'NOT ', + })}` : ''; const prefix = filter.meta.negate && !filter.meta.disabled ? ( @@ -413,9 +417,8 @@ export const FilterExpressionItem: FC = ({ filterExpression.push(filterContent); const text = label.title; - filterText += `${filter?.meta?.key}: ${text} ${ - groupedFilters.length > 1 ? filter.relationship || '' : '' - } `; + filterText += `${filter?.meta?.key}: ${text} ${groupedFilters.length > 1 ? filter.relationship || '' : '' + } `; } if (needsParenthesis) { filterExpression.push()); diff --git a/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx b/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx index c3868b975f58f..231752081baae 100644 --- a/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx +++ b/src/plugins/data/public/ui/query_string_input/edit_filter_modal.tsx @@ -268,10 +268,10 @@ export function EditFilterModal({ placeholder={ selectedField ? i18n.translate('data.filter.filterEditor.operatorSelectPlaceholderSelect', { - defaultMessage: 'Operator', + defaultMessage: 'Operator', }) : i18n.translate('data.filter.filterEditor.operatorSelectPlaceholderWaiting', { - defaultMessage: 'Waiting', + defaultMessage: 'Waiting', }) } options={operators} diff --git a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx index d188569004225..da0d41c0c9bf7 100644 --- a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx @@ -8,7 +8,7 @@ import dateMath from '@elastic/datemath'; import classNames from 'classnames'; -import React, { useCallback, useMemo, useRef, useState, ReactNode } from 'react'; +import React, { useCallback, useMemo, useRef, useState } from 'react'; import deepEqual from 'fast-deep-equal'; import { buildEmptyFilter, Filter } from '@kbn/es-query'; import useObservable from 'react-use/lib/useObservable'; @@ -22,10 +22,8 @@ import { EuiFieldText, prettyDuration, EuiIconProps, - EuiSuperUpdateButton, OnRefreshProps, EuiButtonIcon, - EuiPopover, } from '@elastic/eui'; import { IDataPluginServices, IIndexPattern, TimeRange, TimeHistoryContract, Query } from '../..'; import { mapAndFlattenFilters } from '../../query/filter_manager/lib/map_and_flatten_filters'; @@ -36,7 +34,6 @@ import { getQueryLog } from '../../query'; import type { PersistedLog } from '../../query'; import { NoDataPopover } from './no_data_popover'; import { shallowEqual } from '../../utils/shallow_equal'; -import { SavedQuery } from '../..'; import { AddFilterModal, FilterGroup } from './add_filter_modal'; import { SavedQueryMeta } from '../saved_query_form'; @@ -382,12 +379,6 @@ export const QueryBarTopRow = React.memo( } const onAddFilterClick = () => props.toggleAddFilterModal?.(!props.isAddFilterModalOpen); - function onAdd(filter: Filter) { - props.toggleAddFilterModal?.(false); - - const filters = [...props.filters, filter]; - props?.onFiltersUpdated?.(filters); - } function onAddMultipleFilters(selectedFilters: Filter[]) { props.toggleAddFilterModal?.(false); From e7556df52a0318822b76dc3315c29aa91a0a3ab3 Mon Sep 17 00:00:00 2001 From: Nodir Date: Thu, 3 Feb 2022 13:39:45 +0500 Subject: [PATCH 18/19] fix: show edit filter modal view for filters with Label --- src/plugins/data/public/ui/filter_bar/filter_bar.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx index cb10a3a01fe66..0494c802bfa74 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -184,8 +184,12 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { onClick={() => {}} onRemove={onRemoveFilterGroup} onUpdate={onUpdateFilterGroup} + onEditFilterClick={onEditFilterClick} filtersGroupsCount={1} customLabel={label} + savedQueryService={props.savedQueryService} + onFilterSave={props.onFilterSave} + onFilterBadgeSave={props.onFilterBadgeSave} /> ); GroupBadge.push(labelBadge); From c1da476a43c04da258cfc1a973be8a81b3ab7fd8 Mon Sep 17 00:00:00 2001 From: Nodir Date: Thu, 3 Feb 2022 15:29:52 +0500 Subject: [PATCH 19/19] feat: send groupID for edit filter in badge --- .../data/public/ui/filter_bar/filter_bar.tsx | 18 ++++++++++++------ .../ui/filter_bar/filter_expression_item.tsx | 8 ++++---- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx index 0494c802bfa74..629f0b0a2ace9 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -11,7 +11,7 @@ import { groupBy, isEqual } from 'lodash'; import { InjectedIntl, injectI18n } from '@kbn/i18n-react'; import { Filter, toggleFilterNegated } from '@kbn/es-query'; import classNames from 'classnames'; -import React, { useRef } from 'react'; +import React, { useRef, useState } from 'react'; import { METRIC_TYPE } from '@kbn/analytics'; import { FilterItem } from './filter_item'; @@ -51,6 +51,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { const groupRef = useRef(null); const kibana = useKibana(); const { appName, usageCollection, uiSettings } = kibana.services; + const [groupId, setGroupId] = useState(null); if (!uiSettings) return null; const reportUiCounter = usageCollection?.reportUiCounter.bind(usageCollection, appName); @@ -61,7 +62,8 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { } } - const onEditFilterClick = () => { + const onEditFilterClick = (groupId: number) => { + setGroupId(groupId); props.toggleEditFilterModal?.(true); }; @@ -158,7 +160,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { groupId={groupId} groupedFilters={groupedFilters} indexPatterns={props?.indexPatterns} - onClick={() => {}} + onClick={() => { }} onRemove={onRemoveFilterGroup} onUpdate={onUpdateFilterGroup} filtersGroupsCount={Object.entries(firstDepthGroupedFilters).length} @@ -181,7 +183,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { groupId={groupId} groupedFilters={groupedByAlias[label]} indexPatterns={props?.indexPatterns} - onClick={() => {}} + onClick={() => { }} onRemove={onRemoveFilterGroup} onUpdate={onUpdateFilterGroup} onEditFilterClick={onEditFilterClick} @@ -199,6 +201,10 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { } function renderEditFilter() { + const currentEditFilters = props.multipleFilters.filter( + (filter) => filter.groupId == Number(groupId) + ); + return ( {props.isEditFilterModalOpen && ( @@ -207,8 +213,8 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { onMultipleFiltersSubmit={onEditMultipleFiltersANDOR} applySavedQueries={() => props.toggleEditFilterModal?.(false)} onCancel={() => props.toggleEditFilterModal?.(false)} - filter={props.filters[0]} - multipleFilters={props.multipleFilters} + filter={props.multipleFilters[0]} + multipleFilters={currentEditFilters} indexPatterns={props.indexPatterns!} onRemoveFilterGroup={onDeleteFilterGroup} timeRangeForSuggestionsOverride={props.timeRangeForSuggestionsOverride} diff --git a/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx b/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx index f100405f8755e..1956cc9459169 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_expression_item.tsx @@ -50,7 +50,7 @@ interface Props { groupId: string; filtersGroupsCount: number; onUpdate?: (filters: Filter[], groupId: string, toggleNegate: boolean) => void; - onEditFilterClick: () => void; + onEditFilterClick: (groupId: number) => void; savedQueryService?: SavedQueryService; onFilterSave?: (savedQueryMeta: SavedQueryMeta, saveAsNew?: boolean) => Promise; customLabel?: string; @@ -81,8 +81,8 @@ export const FilterExpressionItem: FC = ({ setIsPopoverOpen(!isPopoverOpen); } - function onEdit() { - onEditFilterClick(); + function onEdit(groupId: number) { + onEditFilterClick(groupId); } function onDuplicate() { @@ -120,7 +120,7 @@ export const FilterExpressionItem: FC = ({ icon: 'pencil', onClick: () => { setIsPopoverOpen(false); - onEdit(); + onEdit(groupId); }, 'data-test-subj': 'editFilter', },