diff --git a/src/plugins/expressions/common/util/tables_adapter.ts b/src/plugins/expressions/common/util/tables_adapter.ts index 890c5601d117a..1feba80b4c43d 100644 --- a/src/plugins/expressions/common/util/tables_adapter.ts +++ b/src/plugins/expressions/common/util/tables_adapter.ts @@ -7,7 +7,7 @@ */ import { EventEmitter } from 'events'; -import { Datatable } from '../expression_types/specs'; +import type { Datatable } from '../expression_types/specs'; export class TablesAdapter extends EventEmitter { private _tables: { [key: string]: Datatable } = {}; @@ -17,6 +17,11 @@ export class TablesAdapter extends EventEmitter { this.emit('change', this.tables); } + public reset() { + this._tables = {}; + this.emit('change', this.tables); + } + public get tables() { return this._tables; } diff --git a/x-pack/plugins/lens/common/expressions/datatable/datatable_fn.ts b/x-pack/plugins/lens/common/expressions/datatable/datatable_fn.ts index 9d9e666e12762..41bf51764b539 100644 --- a/x-pack/plugins/lens/common/expressions/datatable/datatable_fn.ts +++ b/x-pack/plugins/lens/common/expressions/datatable/datatable_fn.ts @@ -15,6 +15,7 @@ import type { ExecutionContext, } from '../../../../../../src/plugins/expressions'; import type { DatatableExpressionFunction } from './types'; +import { logDataTable } from '../expressions_utils'; function isRange(meta: { params?: { id?: string } } | undefined) { return meta?.params?.id === 'range'; @@ -25,6 +26,10 @@ export const datatableFn = getFormatFactory: (context: ExecutionContext) => FormatFactory | Promise ): DatatableExpressionFunction['fn'] => async (data, args, context) => { + if (context?.inspectorAdapters?.tables) { + logDataTable(context.inspectorAdapters.tables, data.tables); + } + let untransposedData: LensMultiTable | undefined; // do the sorting at this level to propagate it also at CSV download const [firstTable] = Object.values(data.tables); diff --git a/x-pack/plugins/lens/common/expressions/expressions_utils.ts b/x-pack/plugins/lens/common/expressions/expressions_utils.ts new file mode 100644 index 0000000000000..795b23e26e830 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/expressions_utils.ts @@ -0,0 +1,16 @@ +/* + * 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 type { TablesAdapter } from '../../../../../src/plugins/expressions'; +import type { Datatable } from '../../../../../src/plugins/expressions'; + +export const logDataTable = ( + tableAdapter: TablesAdapter, + datatables: Record = {} +) => { + Object.entries(datatables).forEach(([key, table]) => tableAdapter.logDatatable(key, table)); +}; diff --git a/x-pack/plugins/lens/common/expressions/merge_tables/index.ts b/x-pack/plugins/lens/common/expressions/merge_tables/index.ts index 7ede2236e8b07..2bf955d9e3ed3 100644 --- a/x-pack/plugins/lens/common/expressions/merge_tables/index.ts +++ b/x-pack/plugins/lens/common/expressions/merge_tables/index.ts @@ -50,14 +50,16 @@ export const mergeTables: ExpressionFunctionDefinition< inputTypes: ['kibana_context', 'null'], fn(input, { layerIds, tables }, context) { const resultTables: Record = {}; + + if (context.inspectorAdapters?.tables) { + context.inspectorAdapters.tables.reset(); + context.inspectorAdapters.tables.allowCsvExport = true; + } + tables.forEach((table, index) => { resultTables[layerIds[index]] = table; - // adapter is always defined at that point because we make sure by the beginning of the function - if (context?.inspectorAdapters?.tables) { - context.inspectorAdapters.tables.allowCsvExport = true; - context.inspectorAdapters.tables.logDatatable(layerIds[index], table); - } }); + return { type: 'lens_multitable', tables: resultTables, diff --git a/x-pack/plugins/lens/common/expressions/merge_tables/merge_tables.test.ts b/x-pack/plugins/lens/common/expressions/merge_tables/merge_tables.test.ts index cd4fc5ed945d4..1642f5520c340 100644 --- a/x-pack/plugins/lens/common/expressions/merge_tables/merge_tables.test.ts +++ b/x-pack/plugins/lens/common/expressions/merge_tables/merge_tables.test.ts @@ -54,17 +54,17 @@ describe('lens_merge_tables', () => { }); }); - it('should store the current tables in the tables inspector', () => { - const adapters: DefaultInspectorAdapters = { + it('should reset the current tables in the tables inspector', () => { + const adapters = { tables: new TablesAdapter(), - requests: {} as never, - expression: {} as never, - }; + } as DefaultInspectorAdapters; + + const resetSpy = jest.spyOn(adapters.tables, 'reset'); + mergeTables.fn(null, { layerIds: ['first', 'second'], tables: [sampleTable1, sampleTable2] }, { inspectorAdapters: adapters, } as ExecutionContext); - expect(adapters.tables!.tables.first).toBe(sampleTable1); - expect(adapters.tables!.tables.second).toBe(sampleTable2); + expect(resetSpy).toHaveBeenCalled(); }); it('should pass the date range along', () => { diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/xy_chart.ts b/x-pack/plugins/lens/common/expressions/xy_chart/xy_chart.ts index d3fb2fe7a6917..481494d52966f 100644 --- a/x-pack/plugins/lens/common/expressions/xy_chart/xy_chart.ts +++ b/x-pack/plugins/lens/common/expressions/xy_chart/xy_chart.ts @@ -10,6 +10,7 @@ import type { ExpressionValueSearchContext } from '../../../../../../src/plugins import type { LensMultiTable } from '../../types'; import type { XYArgs } from './xy_args'; import { fittingFunctionDefinitions } from './fitting_function'; +import { logDataTable } from '../expressions_utils'; export interface XYChartProps { data: LensMultiTable; @@ -157,6 +158,9 @@ export const xyChart: ExpressionFunctionDefinition< }, }, fn(data: LensMultiTable, args: XYArgs, handlers) { + if (handlers?.inspectorAdapters?.tables) { + logDataTable(handlers.inspectorAdapters.tables, data.tables); + } return { type: 'render', as: 'lens_xy_chart_renderer', diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx index 7359f7cdc185b..c3854f1a67809 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx @@ -410,7 +410,7 @@ describe('workspace_panel', () => { first: mockDatasource.publicAPIMock, }; mockDatasource.toExpression.mockReturnValue('datasource'); - mockDatasource.getLayers.mockReturnValue(['first']); + mockDatasource.getLayers.mockReturnValue(['table1']); const mounted = await mountWithProvider( ); @@ -455,6 +459,7 @@ export const VisualizationWrapper = ({ ExpressionRendererComponent, application, activeDatasourceId, + datasourceMap, }: { expression: string | null | undefined; framePublicAPI: FramePublicAPI; @@ -473,6 +478,7 @@ export const VisualizationWrapper = ({ ExpressionRendererComponent: ReactExpressionRendererType; application: ApplicationStart; activeDatasourceId: string | null; + datasourceMap: DatasourceMap; }) => { const context = useLensSelector(selectExecutionContext); const searchContext: ExecutionContextSearch = useMemo( @@ -487,16 +493,26 @@ export const VisualizationWrapper = ({ [context] ); const searchSessionId = useLensSelector(selectSearchSessionId); - + const datasourceLayers = useLensSelector((state) => selectDatasourceLayers(state, datasourceMap)); const dispatchLens = useLensDispatch(); + const [defaultLayerId] = Object.keys(datasourceLayers); const onData$ = useCallback( (data: unknown, adapters?: Partial) => { if (adapters && adapters.tables) { - dispatchLens(onActiveDataChange({ ...adapters.tables.tables })); + dispatchLens( + onActiveDataChange( + Object.entries(adapters.tables?.tables).reduce>( + (acc, [key, value], index, tables) => ({ + [tables.length === 1 ? defaultLayerId : key]: value, + }), + {} + ) + ) + ); } }, - [dispatchLens] + [defaultLayerId, dispatchLens] ); function renderFixAction(