diff --git a/src/plugins/data/public/query/filter_manager/filter_manager.test.ts b/src/plugins/data/public/query/filter_manager/filter_manager.test.ts index 7857e2989bda65..3f31749ee71f34 100644 --- a/src/plugins/data/public/query/filter_manager/filter_manager.test.ts +++ b/src/plugins/data/public/query/filter_manager/filter_manager.test.ts @@ -170,6 +170,32 @@ describe('filter_manager', () => { expect(fetchStub).toBeCalledTimes(0); expect(updateStub).toBeCalledTimes(1); }); + + test('should merge multiple conflicting app filters', async function() { + filterManager.addFilters(readyFilters, true); + const appFilter1 = _.cloneDeep(readyFilters[1]); + appFilter1.meta.negate = true; + appFilter1.$state = { + store: esFilters.FilterStateStore.APP_STATE, + }; + const appFilter2 = _.cloneDeep(readyFilters[2]); + appFilter2.meta.negate = true; + appFilter2.$state = { + store: esFilters.FilterStateStore.APP_STATE, + }; + + const globalFilters = filterManager.getFilters(); + filterManager.setFilters([...globalFilters, appFilter1, appFilter2]); + + // global filters are taking precedence over same app filters when setting + const res = filterManager.getFilters(); + expect(res).toHaveLength(3); + expect( + res.filter(function(filter) { + return filter.$state && filter.$state.store === esFilters.FilterStateStore.GLOBAL_STATE; + }).length + ).toBe(3); + }); }); describe('add filters', () => { diff --git a/src/plugins/data/public/query/filter_manager/filter_manager.ts b/src/plugins/data/public/query/filter_manager/filter_manager.ts index f7d0dddd5bf039..18bb619f6a1370 100644 --- a/src/plugins/data/public/query/filter_manager/filter_manager.ts +++ b/src/plugins/data/public/query/filter_manager/filter_manager.ts @@ -45,20 +45,23 @@ export class FilterManager { const appFilters = partitionedFilters.appFilters; // existing globalFilters should be mutated by appFilters + // ignore original appFilters which are already inside globalFilters + const cleanedAppFilters: esFilters.Filter[] = []; _.each(appFilters, function(filter, i) { const match = _.find(globalFilters, function(globalFilter) { return compareFilters(globalFilter, filter); }); - // no match, do nothing - if (!match) return; + // no match, do continue with app filter + if (!match) { + return cleanedAppFilters.push(filter); + } - // matching filter in globalState, update global and remove from appState + // matching filter in globalState, update global and don't add from appState _.assign(match.meta, filter.meta); - appFilters.splice(i, 1); }); - return FilterManager.mergeFilters(appFilters, globalFilters); + return FilterManager.mergeFilters(cleanedAppFilters, globalFilters); } private static mergeFilters(