From 3df1fa86ae1dfa02e7acd5848f861b8d4379d12e Mon Sep 17 00:00:00 2001 From: Sergej-Vlasov <37613182+Sergej-Vlasov@users.noreply.github.com> Date: Thu, 16 Jan 2025 14:43:46 +0000 Subject: [PATCH] setDashboardPanelContext: Allow to add filters from the table with the same key (#99004) * always add filters for elastic seach ds when filtering table value * simplify update filter logic and restore behaviour from old arch * remove unnecessary modifications * adjust namig --- .../scene/setDashboardPanelContext.test.ts | 13 +++++--- .../scene/setDashboardPanelContext.ts | 32 +++++++++---------- 2 files changed, 25 insertions(+), 20 deletions(-) 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]); }