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 6dca323cec2b2..fa487be48b846 100644 --- a/src/plugins/data/public/ui/filter_bar/filter_bar.tsx +++ b/src/plugins/data/public/ui/filter_bar/filter_bar.tsx @@ -11,21 +11,20 @@ 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, useState } from 'react'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; import { METRIC_TYPE } from '@kbn/analytics'; import { FilterItem } from './filter_item'; import { useKibana } from '../../../../kibana_react/public'; -import { IDataPluginServices, IIndexPattern } from '../..'; +import { IDataPluginServices, IIndexPattern, SavedQueryService } from '../..'; import type { SavedQuery } from '../../query'; import { SavedQueriesItem } from './saved_queries_item'; import { FilterExpressionItem } from './filter_expression_item'; -import { EditFilterModal } from '../query_string_input/edit_filter_modal'; +import { EditFilterModal, FilterGroup } 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'; import { SavedQueryMeta } from '../saved_query_form'; -import { SavedQueryService } from '../..'; +import { QUERY_BUILDER } from '../query_string_input/add_filter_modal'; interface Props { filters: Filter[]; @@ -51,7 +50,60 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { const groupRef = useRef(null); const kibana = useKibana(); const { appName, usageCollection, uiSettings } = kibana.services; - const [groupIds, setGroupIds] = useState<[] | undefined>(undefined); + const [groupIds, setGroupIds] = useState([]); + // we need this to disable quick_form tab for editing saved filters + const [selectedSavedFiltersGroupIds, setSelectedSavedFiltersGroupIds] = useState([]); + + const getInitForField = useCallback((multipleFilters: any[], field: string, minValue: number) => { + return multipleFilters.length + ? Math.max.apply( + Math, + multipleFilters.map((f) => f[field]) + ) + 1 + : minValue; + }, []); + + const sortFiltersByGroupId = useCallback((multipleFilters: Filter[]) => { + // when user adds new filters in edit modal they should appear near of editing filter + let gId: number = 0; + let reserveGroupId: number; // for cases where multiple filters have same groupId + return multipleFilters.map((filter, idx) => { + if (filter.groupId !== reserveGroupId) { + reserveGroupId = filter.groupId; + gId++; + } + return { + ...filter, + groupId: gId, + id: idx, + }; + }); + }, []); + + useEffect(() => { + const savedFiltersGroupIds: number[] = []; + let groupId = getInitForField(props.multipleFilters, 'groupId', 1); + let id = getInitForField(props.multipleFilters, 'id', 0); + + const groupsFromSavedFilters: Filter[] = []; + props.selectedSavedQueries?.map((savedQuery) => { + savedQuery.attributes.filters?.map((f) => { + savedFiltersGroupIds.push(groupId); + groupsFromSavedFilters.push({ + ...f, + groupId, + id, + subgroupId: 1, + relationship: undefined, + }); + groupId++; + id++; + }); + }); + setSelectedSavedFiltersGroupIds(savedFiltersGroupIds); + props?.onMultipleFiltersUpdated?.([...props.multipleFilters, ...groupsFromSavedFilters]); + }, [props.selectedSavedQueries]); + if (!uiSettings) return null; const reportUiCounter = usageCollection?.reportUiCounter.bind(usageCollection, appName); @@ -90,18 +142,50 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { props.toggleEditFilterModal?.(false); }; - function onAddMultipleFilters(selectedFilters: Filter[]) { - props.toggleEditFilterModal?.(false); + function onEditMultipleFilters(selectedFilters: Filter[]) { + const editedFilters = props.multipleFilters.filter((f) => groupIds.includes(f.groupId)); + const oldFilters = props.filters.filter( + (filter) => !editedFilters.find((editedFilter) => isEqual(filter.query, editedFilter.query)) + ); + const updatedFilters = [...oldFilters, ...selectedFilters]; + props?.onFiltersUpdated?.(updatedFilters); + + const editedFilterGroupId = groupIds[0]; + const multipleFilters = [...props.multipleFilters]; + const idxEditedFilterInMultiple = props.multipleFilters.findIndex( + (f) => Number(f.groupId) === Number(editedFilterGroupId) + ); + const initGroupId = getInitForField(props.multipleFilters, 'groupId', 1); + const initId = getInitForField(props.multipleFilters, 'id', 0); + const newMultipleFilters = selectedFilters.map((filter, idx) => { + return { + ...filter, + groupId: initGroupId + idx, + id: initId + idx, + relationship: 'AND', + subGroupId: 1, + }; + }); - const filters = [...props.filters, ...selectedFilters]; - props?.onFiltersUpdated?.(filters); + multipleFilters.splice(idxEditedFilterInMultiple, groupIds.length, ...newMultipleFilters); + const updatedMultipleFilters = sortFiltersByGroupId(multipleFilters); + + props?.onMultipleFiltersUpdated?.(updatedMultipleFilters); + props.toggleEditFilterModal?.(false); } function onEditMultipleFiltersANDOR( selectedFilters: FilterGroup[], buildFilters: Filter[], - groupCount: number + groupCount: number = 0 ) { + const editedFilters = props.multipleFilters.filter((f) => groupIds.includes(f.groupId)); + const oldFilters = props.filters.filter( + (filter) => !editedFilters.find((editedFilter) => isEqual(filter.query, editedFilter.query)) + ); + const updatedFilters = [...oldFilters, ...buildFilters]; + props?.onFiltersUpdated?.(updatedFilters); + const mappedFilters = mapAndFlattenFilters(buildFilters); const mergedFilters = mappedFilters.map((filter, idx) => { return { @@ -110,54 +194,19 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { id: selectedFilters[idx].id, relationship: selectedFilters[idx].relationship, subGroupId: selectedFilters[idx].subGroupId, - groupCount + groupCount, }; }); const multipleFilters = [...props.multipleFilters]; - const newMultipleFilters = multipleFilters.filter( - (filter) => !groupIds.includes(filter.groupId) + const indexOfCurFilter = multipleFilters.findIndex( + (f) => Number(f.groupId) === Number(groupIds[0]) ); + multipleFilters.splice(indexOfCurFilter, groupIds.length, ...mergedFilters); + const updatedMultipleFilters = sortFiltersByGroupId(multipleFilters); - const filtersNew = newMultipleFilters.concat(mergedFilters); - - // const indexOfCurFilter = multipleFilters.findIndex( - // (f) => Number(f.groupId) === Number(groupId) - // ); - - // multipleFilters.splice(indexOfCurFilter, 1, ...mergedFilters); - - // when user adds new filters in edit modal they should appear near of editing filter - // let gId: number = 0; - // let reserveGroupId: number; - // const updatedMultipleFilters = multipleFilters.map((filter, idx) => { - // if (filter.groupId !== reserveGroupId) { - // reserveGroupId = filter.groupId; - // gId++; - // } - // return { - // ...filter, - // groupId: gId, - // id: idx, - // }; - // }); - - props?.onMultipleFiltersUpdated?.(filtersNew); - - const filters = [...props.filters, ...buildFilters]; - const updatedFilters: Filter[] = []; - - filtersNew.forEach((filter) => { - filters.forEach((f) => { - if (isEqual(f.query, filter.query)) { - updatedFilters.push(f); - } - }); - }); - - props?.onFiltersUpdated?.(updatedFilters); - + props?.onMultipleFiltersUpdated?.(updatedMultipleFilters); props.toggleEditFilterModal?.(false); } @@ -248,22 +297,37 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { } function renderEditFilter() { - let currentEditFilters = []; + const currentEditFilters: Filter[] = []; groupIds?.forEach((groupId) => { - const filteredFilters = props.multipleFilters.filter(filter => filter.groupId === groupId); + const filteredFilters = props.multipleFilters.filter((filter) => filter.groupId === groupId); currentEditFilters.push(...filteredFilters); }); + const saerchedFilters: Filter[] = []; + + currentEditFilters.forEach((filter) => { + props.filters.forEach((f) => { + if (isEqual(f.query, filter.query)) { + saerchedFilters.push(f); + } + }); + }); + + const queryBuilderTab = QUERY_BUILDER; + const tabs = selectedSavedFiltersGroupIds.some((g) => groupIds.includes(g)) + ? [queryBuilderTab] + : undefined; + return ( {props.isEditFilterModalOpen && ( props.toggleEditFilterModal?.(false)} onCancel={() => props.toggleEditFilterModal?.(false)} - filter={currentEditFilters[0]} + filter={saerchedFilters[0]} currentEditFilters={currentEditFilters} + filters={saerchedFilters} multipleFilters={props.multipleFilters} indexPatterns={props.indexPatterns!} onRemoveFilterGroup={onDeleteFilterGroup} @@ -271,6 +335,8 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { initialAddFilterMode={undefined} saveFilters={props.onFilterSave} savedQueryService={props.savedQueryService} + tabs={tabs} + initialLabel={saerchedFilters[0].meta.alias!} /> )} @@ -365,7 +431,7 @@ const FilterBarUI = React.memo(function FilterBarUI(props: Props) { tabIndex={-1} > {renderMultipleFilters()} - {renderSelectedSavedQueries()} + {/*{renderSelectedSavedQueries()}*/} {props.multipleFilters.length === 0 && renderItems()} {renderEditFilter()} 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 8ee0ef6c4ef28..9c75d12644ab2 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 @@ -48,26 +48,31 @@ import { SavedQueryMeta } from '../saved_query_form'; import { IIndexPattern, IFieldType } from '../..'; -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', - }), - }, - { - type: 'saved_filters', - label: i18n.translate('data.filter.filterEditor.savedFiltersLabel', { - defaultMessage: 'Saved filters', - }), - }, -]; +export interface ITab { + type: string; + label: string; +} + +export const QUICK_FORM: ITab = { + type: 'quick_form', + label: i18n.translate('data.filter.filterEditor.quickFormLabel', { + defaultMessage: 'Quick form', + }), +}; +export const QUERY_BUILDER: ITab = { + type: 'query_builder', + label: i18n.translate('data.filter.filterEditor.queryBuilderLabel', { + defaultMessage: 'Query builder', + }), +}; +export const SAVED_FILTERS: ITab = { + type: 'saved_filters', + label: i18n.translate('data.filter.filterEditor.savedFiltersLabel', { + defaultMessage: 'Saved filters', + }), +}; + +const tabs: ITab[] = [QUICK_FORM, QUERY_BUILDER, SAVED_FILTERS]; export interface FilterGroup { field: IFieldType | undefined; @@ -77,7 +82,6 @@ export interface FilterGroup { id: number; relationship?: string; subGroupId?: number; - groupsCount?: number; } export function AddFilterModal({ @@ -95,11 +99,7 @@ export function AddFilterModal({ savedQueryService, }: { onSubmit: (filters: Filter[]) => void; - onMultipleFiltersSubmit: ( - filters: FilterGroup[], - buildFilters: Filter[], - groupsCount: number - ) => void; + onMultipleFiltersSubmit: (filters: FilterGroup[], buildFilters: Filter[]) => void; applySavedQueries: () => void; onCancel: () => void; filter: Filter; @@ -114,7 +114,9 @@ export function AddFilterModal({ const [selectedIndexPattern, setSelectedIndexPattern] = useState( getIndexPatternFromFilter(filter, indexPatterns) ); - const [addFilterMode, setAddFilterMode] = useState(initialAddFilterMode ?? tabs[0].type); + const [addFilterMode, setAddFilterMode] = useState( + initialAddFilterMode ?? QUICK_FORM.type + ); const [customLabel, setCustomLabel] = useState(filter.meta.alias || ''); const [queryDsl, setQueryDsl] = useState(JSON.stringify(cleanFilter(filter), null, 2)); const [groupsCount, setGroupsCount] = useState(1); @@ -141,7 +143,6 @@ export function AddFilterModal({ : 0, subGroupId: 1, relationship: undefined, - groupsCount, }, ]); @@ -182,7 +183,6 @@ export function AddFilterModal({ ) + 1 : 0, subGroupId: 1, - groupsCount, }, ]); setGroupsCount(1); @@ -413,29 +413,31 @@ export function AddFilterModal({ return; } - if (addFilterMode === 'query_builder') { + if (addFilterMode === QUERY_BUILDER.type) { const { index, disabled = false, negate = false } = filter.meta; const newIndex = index || indexPatterns[0].id!; + let builtCustomFilter = []; const body = JSON.parse(queryDsl); - const builtCustomFilter = buildCustomFilter( - newIndex, - body, - disabled, - negate, - alias, - $state.store - ); - onSubmit([builtCustomFilter]); + if (Array.isArray(body)) { + builtCustomFilter = body.map((query) => + buildCustomFilter(newIndex, query, disabled, negate, alias, $state.store) + ); + } else { + builtCustomFilter = [ + buildCustomFilter(newIndex, body, disabled, negate, alias, $state.store), + ]; + } + onSubmit(builtCustomFilter); if (alias) { saveFilters({ title: customLabel, description: '', shouldIncludeFilters: false, shouldIncludeTimefilter: false, - filters: [builtCustomFilter], + filters: builtCustomFilter, }); } - } else if (addFilterMode === 'quick_form' && selectedIndexPattern) { + } else if (addFilterMode === QUICK_FORM.type && selectedIndexPattern) { const builtFilters = localFilters.map((localFilter) => { if (localFilter.field && localFilter.operator) { return buildFilter( @@ -456,7 +458,7 @@ export function AddFilterModal({ ) as Filter[]; // onSubmit(finalFilters); - onMultipleFiltersSubmit(localFilters, finalFilters, groupsCount); + onMultipleFiltersSubmit(localFilters, finalFilters); if (alias) { saveFilters({ title: customLabel, @@ -467,7 +469,7 @@ export function AddFilterModal({ }); } } - } else if (addFilterMode === 'saved_filters') { + } else if (addFilterMode === SAVED_FILTERS.type) { applySavedQueries(); } }; @@ -546,7 +548,6 @@ export function AddFilterModal({ groupId: localfilter.groupId, id: Number(multipleFilters?.length) + localFilters.length, subGroupId, - groupsCount, }, ]); }} @@ -589,7 +590,6 @@ export function AddFilterModal({ ? localFilters[localFilters.length - 1].groupId : localFilters[localFilters.length - 1].groupId + 1, subGroupId, - groupsCount, id: Number(multipleFilters?.length) + localFilters.length, }, ]); @@ -691,7 +691,12 @@ export function AddFilterModal({ }; return ( - +

@@ -721,14 +726,14 @@ export function AddFilterModal({ - {addFilterMode === 'quick_form' && renderGroupedFilters()} - {addFilterMode === 'query_builder' && renderCustomEditor()} - {addFilterMode === 'saved_filters' && savedQueryManagement} + {addFilterMode === QUICK_FORM.type && renderGroupedFilters()} + {addFilterMode === QUERY_BUILDER.type && renderCustomEditor()} + {addFilterMode === SAVED_FILTERS.type && savedQueryManagement} - {addFilterMode !== 'saved_filters' && ( + {addFilterMode !== SAVED_FILTERS.type && ( void; onMultipleFiltersSubmit: ( @@ -105,7 +96,6 @@ export function EditFilterModal({ buildFilters: Filter[], groupCount: number ) => void; - applySavedQueries: () => void; onCancel: () => void; filter: Filter; multipleFilters?: Filter[]; @@ -116,17 +106,47 @@ export function EditFilterModal({ onRemoveFilterGroup: () => void; saveFilters: (savedQueryMeta: SavedQueryMeta, saveAsNew?: boolean) => Promise; savedQueryService: SavedQueryService; + filters: Filter[]; + tabs?: ITab[]; + initialLabel?: string; }) { 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(currentEditFilters?.map(filter => cleanFilter(filter)), null, 2)); + const [addFilterMode, setAddFilterMode] = useState( + initialAddFilterMode ?? QUICK_FORM.type + ); + const [customLabel, setCustomLabel] = useState(initialLabel || ''); + const [queryDsl, setQueryDsl] = useState( + JSON.stringify( + // { + // query: { + // bool: buildQueryFromFilters(filters, selectedIndexPattern), + // }, + // }, + filters.map((filter) => cleanFilter(filter)), + null, + 2 + ) + ); const [localFilters, setLocalFilters] = useState( - convertFilterToFilterGroup(currentEditFilters) + tabs.includes(QUICK_FORM) + ? convertFilterToFilterGroup(currentEditFilters) + : [ + { + field: undefined, + operator: undefined, + value: undefined, + groupId: 1, + id: 0, + subGroupId: 1, + relationship: undefined, + }, + ] + ); + const [groupsCount, setGroupsCount] = useState( + (new Set(localFilters.map(filter => filter.groupId))).size ); - const [groupsCount, setGroupsCount] = useState(currentEditFilters[currentEditFilters?.length - 1].groupCount ?? 0); const [savedQueries, setSavedQueries] = useState([]); const [submitDisabled, setSubmitDisabled] = useState(false); @@ -150,7 +170,6 @@ export function EditFilterModal({ id: 0, subGroupId: 1, relationship: undefined, - groupsCount }, ]; } @@ -164,7 +183,6 @@ export function EditFilterModal({ id: convertedfilter.id, subGroupId: convertedfilter.subGroupId, relationship: convertedfilter.relationship, - groupsCount: convertedfilter.groupsCount }; }); } @@ -239,29 +257,31 @@ export function EditFilterModal({ return ''; } return ( - - indexPattern.title} - onChange={onIndexPatternChange} - singleSelection={{ asPlainText: true }} - isClearable={false} - data-test-subj="filterIndexPatternsSelect" - /> - + > + indexPattern.title} + onChange={onIndexPatternChange} + singleSelection={{ asPlainText: true }} + isClearable={false} + data-test-subj="filterIndexPatternsSelect" + /> + + ) ); }; @@ -421,12 +441,12 @@ export function EditFilterModal({ shouldIncludeTimefilter: false, filters, }; - if (!filter.meta.alias) { + if (!initialLabel) { // if our filters had not alias before then we save them as new fiterSet saveFilters(queryMetaObj, true); } else { const curQuery = savedQueries.find( - (existingQuery) => existingQuery.attributes.title === filter.meta.alias + (existingQuery) => existingQuery.attributes.title === initialLabel ); saveFilters( { @@ -444,28 +464,30 @@ export function EditFilterModal({ return; // typescript validation } const alias = customLabel || null; - if (alias && !filter.meta.alias && isLabelDuplicated()) { + if (alias && !initialLabel && isLabelDuplicated()) { setSubmitDisabled(true); return; } - if (addFilterMode === 'query_builder') { + if (addFilterMode === QUERY_BUILDER.type) { 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]); + let builtCustomFilter = []; + if (Array.isArray(JSON.parse(queryDsl))) { + builtCustomFilter = JSON.parse(queryDsl).map((query) => + buildCustomFilter(newIndex, query, disabled, negate, alias, $state.store) + ); + } else { + const body = JSON.parse(queryDsl); + builtCustomFilter = [ + buildCustomFilter(newIndex, body, disabled, negate, alias, $state.store), + ]; + } + onSubmit(builtCustomFilter); if (alias) { - onSubmitWithLabel([builtCustomFilter]); + onSubmitWithLabel(builtCustomFilter); } - } else if (addFilterMode === 'quick_form' && selectedIndexPattern) { + } else if (addFilterMode === QUICK_FORM.type && selectedIndexPattern) { const builtFilters = localFilters.map((localFilter) => { if (localFilter.field && localFilter.operator) { return buildFilter( @@ -489,8 +511,6 @@ export function EditFilterModal({ onSubmitWithLabel(finalFilters); } } - } else if (addFilterMode === 'saved_filters') { - applySavedQueries(); } }; @@ -774,8 +794,8 @@ export function EditFilterModal({ - {addFilterMode === 'quick_form' && renderGroupedFilters()} - {addFilterMode === 'query_builder' && renderCustomEditor()} + {addFilterMode === QUICK_FORM.type && renderGroupedFilters()} + {addFilterMode === QUERY_BUILDER.type && renderCustomEditor()} 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 19425ba77e9c9..02648d0e3dcc3 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 @@ -392,30 +392,45 @@ export const QueryBarTopRow = React.memo( const onAddFilterClick = () => props.toggleAddFilterModal?.(!props.isAddFilterModalOpen); function onAddMultipleFilters(selectedFilters: Filter[]) { - props.toggleAddFilterModal?.(false); - const filters = [...props.filters, ...selectedFilters]; props?.onFiltersUpdated?.(filters); + + const maxGroupId = props.multipleFilters.length + ? Math.max.apply( + Math, + props.multipleFilters.map((f) => f.groupId) + ) + : 0; + const maxId = props.multipleFilters.length + ? Math.max.apply( + Math, + props.multipleFilters.map((f) => f.id) + ) + : -1; + const multipleFilters = [ + ...props.multipleFilters, + ...selectedFilters.map((filter, idx) => ({ + ...filter, + groupId: maxGroupId + 1 + idx, + id: maxId + 1 + idx, + subGroupId: 1, + relationship: undefined, + groupsCount: 0, + })), + ]; + props?.onMultipleFiltersUpdated?.(multipleFilters); + props.toggleAddFilterModal?.(false); } - function onAddMultipleFiltersANDOR( - selectedFilters: FilterGroup[], - buildFilters: Filter[], - groupCount: number - ) { - let mergedFilters = []; + function onAddMultipleFiltersANDOR(selectedFilters: FilterGroup[], buildFilters: Filter[]) { const mappedFilters = mapAndFlattenFilters(buildFilters); - - mergedFilters = mappedFilters.map((filter, idx) => { - let groupId = selectedFilters[idx].groupId; - let id = selectedFilters[idx].id; + const mergedFilters = mappedFilters.map((filter, idx) => { return { ...filter, - groupId, - id, + groupId: selectedFilters[idx].groupId, + id: selectedFilters[idx].id, relationship: selectedFilters[idx].relationship, subGroupId: selectedFilters[idx].subGroupId, - groupCount: selectedFilters[idx].groupsCount, }; }); 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 394584bc98b5a..ae8a87ee7fec8 100644 --- a/src/plugins/data/public/ui/search_bar/search_bar.tsx +++ b/src/plugins/data/public/ui/search_bar/search_bar.tsx @@ -204,7 +204,18 @@ class SearchBarUI extends Component { currentProps: this.props, selectedSavedQueries: [], finalSelectedSavedQueries: [], - multipleFilters: this.props.filters?.length ? [...this.props.filters] : [], + multipleFilters: this.props.filters?.length + ? [ + ...this.props.filters.map((filter: Filter, idx: number) => ({ + ...filter, + groupId: idx + 1, + id: idx, + subGroupId: 1, + relationship: undefined, + groupsCount: 1, + })), + ] + : [], query: this.props.query ? { ...this.props.query } : undefined, dateRangeFrom: get(this.props, 'dateRangeFrom', 'now-15m'), dateRangeTo: get(this.props, 'dateRangeTo', 'now'), @@ -478,7 +489,18 @@ class SearchBarUI extends Component { }, }); - this.props?.onFiltersUpdated?.(filters!); + // remove filters from state if it is included in selected saved filters + const existingFiltersWithoutDuplicate = this.props.filters?.filter( + (existingFilter) => + !filters.find((savedFilter) => isEqual(savedFilter.query, existingFilter.query)) + ); + const existingMFiltersWithoutDuplicate = this.state.multipleFilters?.filter( + (existingFilter) => + !filters.find((savedFilter) => isEqual(savedFilter.query, existingFilter.query)) + ); + + this.setState({ multipleFilters: existingMFiltersWithoutDuplicate }); + this.props?.onFiltersUpdated?.([...existingFiltersWithoutDuplicate!, ...filters!]); }; public applySelectedQuery = (selectedSavedQuery: SavedQuery) => { @@ -730,7 +752,6 @@ class SearchBarUI extends Component { editFilterMode={this.state.editFilterMode} savedQueryService={this.savedQueryService} onFilterSave={(savedQueryMeta: SavedQueryMeta, saveAsNew = false) => { - console.log(this.state.query); return this.onSave(savedQueryMeta, saveAsNew, { language: this.state.query!.language, query: '',