diff --git a/public/app/features/dashboard-scene/scene/setDashboardPanelContext.test.ts b/public/app/features/dashboard-scene/scene/setDashboardPanelContext.test.ts index 36eb42d3a05..d246ddcccd4 100644 --- a/public/app/features/dashboard-scene/scene/setDashboardPanelContext.test.ts +++ b/public/app/features/dashboard-scene/scene/setDashboardPanelContext.test.ts @@ -130,11 +130,16 @@ describe('setDashboardPanelContext', () => { it('Should add new filter set', () => { const { scene, context } = buildTestScene({}); - context.onAddAdHocFilter!({ key: 'hello', value: 'world', operator: '=' }); + context.onAddAdHocFilter!({ key: 'hello', value: 'world', operator: '!=' }); + context.onAddAdHocFilter!({ key: 'hello', value: 'world2', operator: '!=' }); const variable = getAdHocFilterVariableFor(scene, { uid: 'my-ds-uid' }); - expect(variable.state.filters).toEqual([{ key: 'hello', value: 'world', operator: '=' }]); + expect(variable.state.filters).toEqual([ + { key: 'hello', value: 'world', operator: '!=' }, + { key: 'hello', value: 'world2', operator: '!=' }, + , + ]); }); it('Should update and add filter to existing set', () => { @@ -149,9 +154,9 @@ describe('setDashboardPanelContext', () => { expect(variable.state.filters.length).toBe(2); // Can update existing filter value without adding a new filter - context.onAddAdHocFilter!({ key: 'hello', value: 'world2', operator: '=' }); + context.onAddAdHocFilter!({ key: 'hello', value: 'world', operator: '!=' }); // Verify existing filter value updated - expect(variable.state.filters[1].value).toBe('world2'); + expect(variable.state.filters[1].operator).toBe('!='); }); }); }); diff --git a/public/app/features/dashboard-scene/scene/setDashboardPanelContext.ts b/public/app/features/dashboard-scene/scene/setDashboardPanelContext.ts index 00150b02a0a..4b141354801 100644 --- a/public/app/features/dashboard-scene/scene/setDashboardPanelContext.ts +++ b/public/app/features/dashboard-scene/scene/setDashboardPanelContext.ts @@ -175,23 +175,23 @@ export function getAdHocFilterVariableFor(scene: DashboardScene, ds: DataSourceR } function updateAdHocFilterVariable(filterVar: AdHocFiltersVariable, newFilter: AdHocFilterItem) { - // Check if we need to update an existing filter - for (const filter of filterVar.state.filters) { - if (filter.key === newFilter.key) { - filterVar.setState({ - filters: filterVar.state.filters.map((f) => { - if (f.key === newFilter.key) { - return newFilter; - } - return f; - }), - }); - return; - } + // This function handles 'Filter for value' and 'Filter out value' from table cell + // We are allowing to add filters with the same key because elastic search ds supports that + + // Update is only required when we change operator and keep key and value the same + // key1 = value1 -> key1 != value1 + const filterToReplaceIndex = filterVar.state.filters.findIndex( + (filter) => + filter.key === newFilter.key && filter.value === newFilter.value && filter.operator !== newFilter.operator + ); + + if (filterToReplaceIndex >= 0) { + const updatedFilters = filterVar.state.filters.slice(); + updatedFilters.splice(filterToReplaceIndex, 1, newFilter); + filterVar.updateFilters(updatedFilters); + return; } // Add new filter - filterVar.setState({ - filters: [...filterVar.state.filters, newFilter], - }); + filterVar.updateFilters([...filterVar.state.filters, newFilter]); }