From 520a0071176abdcd83c82767c88ff8bf4cc9aabb Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 11 Feb 2025 06:37:39 +1100 Subject: [PATCH] [9.0] [Lens] Fix `activeData` in multi-layer config (#208571) (#210436) # Backport This will backport the following commits from `main` to `9.0`: - [[Lens] Fix `activeData` in multi-layer config (#208571)](https://github.com/elastic/kibana/pull/208571) ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) Co-authored-by: Nick Partridge --- .../lens_configuration_flyout.tsx | 32 +++++++----- .../workspace_panel/workspace_panel.tsx | 11 +---- .../state_management/shared_logic.test.ts | 49 +++++++++++++++++++ .../public/state_management/shared_logic.ts | 15 ++++++ 4 files changed, 85 insertions(+), 22 deletions(-) create mode 100644 x-pack/platform/plugins/shared/lens/public/state_management/shared_logic.test.ts diff --git a/x-pack/platform/plugins/shared/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx b/x-pack/platform/plugins/shared/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx index 8bdff81f37142..0f362d10050ad 100644 --- a/x-pack/platform/plugins/shared/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx +++ b/x-pack/platform/plugins/shared/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx @@ -21,7 +21,6 @@ import { keys, } from '@elastic/eui'; import { euiThemeVars } from '@kbn/ui-theme'; -import type { Datatable } from '@kbn/expressions-plugin/public'; import { getAggregateQueryMode, isOfAggregateQueryType, @@ -55,6 +54,7 @@ import { trackSaveUiCounterEvents } from '../../../lens_ui_telemetry'; import { ESQLDataGridAccordion } from './esql_data_grid_accordion'; import { isApiESQLVariablesCompatible } from '../../../react_embeddable/types'; import { useESQLVariables } from './use_esql_variables'; +import { getActiveDataFromDatatable } from '../../../state_management/shared_logic'; export function LensEditConfigurationFlyout({ attributes, @@ -138,23 +138,29 @@ export function LensEditConfigurationFlyout({ if (isDataLoading) { return; } - const activeData: Record = {}; - const adaptersTables = previousAdapters.current?.tables?.tables; - const [table] = Object.values(adaptersTables || {}); - if (table) { - // there are cases where a query can return a big amount of columns - // at this case we don't suggest all columns in a table but the first - // MAX_NUM_OF_COLUMNS - setSuggestsLimitedColumns(table.columns.length >= MAX_NUM_OF_COLUMNS); - layers.forEach((layer) => { - activeData[layer] = table; - }); + const [defaultLayerId] = Object.keys(framePublicAPI.datasourceLayers); + const activeData = getActiveDataFromDatatable( + defaultLayerId, + previousAdapters.current?.tables?.tables + ); + + layers.forEach((layer) => { + const table = activeData[layer]; + + if (table) { + // there are cases where a query can return a big amount of columns + // at this case we don't suggest all columns in a table but the first `MAX_NUM_OF_COLUMNS` + setSuggestsLimitedColumns(table.columns.length >= MAX_NUM_OF_COLUMNS); + } + }); + + if (Object.keys(activeData).length > 0) { dispatch(onActiveDataChange({ activeData })); } }); return () => s?.unsubscribe(); - }, [dispatch, dataLoading$, layers]); + }, [dispatch, dataLoading$, layers, framePublicAPI.datasourceLayers]); const attributesChanged: boolean = useMemo(() => { const previousAttrs = previousAttributes.current; diff --git a/x-pack/platform/plugins/shared/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx b/x-pack/platform/plugins/shared/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx index 31228d8bb1da8..a9552c1399558 100644 --- a/x-pack/platform/plugins/shared/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx +++ b/x-pack/platform/plugins/shared/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx @@ -23,7 +23,6 @@ import type { import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public'; import type { DefaultInspectorAdapters } from '@kbn/expressions-plugin/common'; -import type { Datatable } from '@kbn/expressions-plugin/public'; import { DropIllustration } from '@kbn/chart-icons'; import { useDragDropContext, DragDropIdentifier, Droppable } from '@kbn/dom-drag-drop'; import { reportPerformanceMetricEvent } from '@kbn/ebt-tools'; @@ -81,6 +80,7 @@ import { } from '../../../utils'; import { setChangesApplied } from '../../../state_management/lens_slice'; import { WorkspaceErrors } from './workspace_errors'; +import { getActiveDataFromDatatable } from '../../../state_management/shared_logic'; export interface WorkspacePanelProps { visualizationMap: VisualizationMap; @@ -282,14 +282,7 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({ if (adapters && adapters.tables) { dispatchLens( onActiveDataChange({ - activeData: Object.entries(adapters.tables?.tables).reduce>( - (acc, [key, value], _index, tables) => { - const id = tables.length === 1 ? defaultLayerId : key; - acc[id] = value as Datatable; - return acc; - }, - {} - ), + activeData: getActiveDataFromDatatable(defaultLayerId, adapters.tables?.tables), }) ); } diff --git a/x-pack/platform/plugins/shared/lens/public/state_management/shared_logic.test.ts b/x-pack/platform/plugins/shared/lens/public/state_management/shared_logic.test.ts new file mode 100644 index 0000000000000..fa24426c82917 --- /dev/null +++ b/x-pack/platform/plugins/shared/lens/public/state_management/shared_logic.test.ts @@ -0,0 +1,49 @@ +/* + * 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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Datatable } from '@kbn/expressions-plugin/common'; +import { getActiveDataFromDatatable } from './shared_logic'; + +describe('lens shared logic', () => { + describe('#getActiveDataFromDatatable', () => { + const defaultLayerId = 'default-layer'; + const firstTable: Datatable = { + type: 'datatable', + columns: [], + rows: [], + }; + const secondTable: Datatable = { + type: 'datatable', + columns: [], + rows: [], + }; + + it('should return {} for empty datatable', () => { + expect(getActiveDataFromDatatable(defaultLayerId, undefined)).toEqual({}); + }); + + it('should return multiple tables', () => { + const datatables: Record = { + first: firstTable, + second: secondTable, + }; + expect(getActiveDataFromDatatable(defaultLayerId, datatables)).toEqual({ + first: firstTable, + second: secondTable, + }); + }); + + it('should return since table with default layer id', () => { + const datatables: Record = { + first: firstTable, + }; + expect(getActiveDataFromDatatable(defaultLayerId, datatables)).toEqual({ + [defaultLayerId]: firstTable, + }); + }); + }); +}); diff --git a/x-pack/platform/plugins/shared/lens/public/state_management/shared_logic.ts b/x-pack/platform/plugins/shared/lens/public/state_management/shared_logic.ts index 4e24d9f3fdaa0..1be2200f69f9a 100644 --- a/x-pack/platform/plugins/shared/lens/public/state_management/shared_logic.ts +++ b/x-pack/platform/plugins/shared/lens/public/state_management/shared_logic.ts @@ -9,6 +9,7 @@ import type { SavedObjectReference } from '@kbn/core-saved-objects-api-server'; import { DataViewSpec, DataViewPersistableStateService } from '@kbn/data-views-plugin/common'; import { AggregateQuery, Query, Filter } from '@kbn/es-query'; import { FilterManager } from '@kbn/data-plugin/public'; +import { Datatable } from '@kbn/expressions-plugin/common'; import { DOC_TYPE, INDEX_PATTERN_TYPE } from '../../common/constants'; import { VisualizationState, DatasourceStates } from '.'; import { LensDocument } from '../persistence'; @@ -122,3 +123,17 @@ export function mergeToNewDoc( }, }; } + +export function getActiveDataFromDatatable( + defaultLayerId: string, + tables: Record = {} +) { + return Object.entries(tables).reduce>( + (acc, [key, value], _index, { length }) => { + const id = length === 1 ? defaultLayerId : key; + acc[id] = value as Datatable; + return acc; + }, + {} + ); +}