From dcd108ae54a455cd9ff2ddfc2424c66241607153 Mon Sep 17 00:00:00 2001 From: Alexey Antonov Date: Thu, 3 Mar 2022 18:09:11 +0300 Subject: [PATCH 1/6] [Lens] Duplicated datatable available as inspector data for Heatmap chart Close: #123176 --- .../expressions/common/util/tables_adapter.ts | 5 +++++ .../common/expressions/datatable/datatable_fn.ts | 5 +++++ .../lens/common/expressions/expressions_utils.ts | 13 +++++++++++++ .../lens/common/expressions/merge_tables/index.ts | 9 ++++----- .../lens/common/expressions/xy_chart/xy_chart.ts | 4 ++++ 5 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 x-pack/plugins/lens/common/expressions/expressions_utils.ts diff --git a/src/plugins/expressions/common/util/tables_adapter.ts b/src/plugins/expressions/common/util/tables_adapter.ts index 890c5601d117a..cebce4d401e77 100644 --- a/src/plugins/expressions/common/util/tables_adapter.ts +++ b/src/plugins/expressions/common/util/tables_adapter.ts @@ -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..f7ee187263ebe 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, Object.values(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..ef8804fe1bdb9 --- /dev/null +++ b/x-pack/plugins/lens/common/expressions/expressions_utils.ts @@ -0,0 +1,13 @@ +/* + * 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: Datatable[]) => { + datatables.forEach((table, index) => tableAdapter.logDatatable(index.toString(), 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..f03334fd45c29 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,13 @@ export const mergeTables: ExpressionFunctionDefinition< inputTypes: ['kibana_context', 'null'], fn(input, { layerIds, tables }, context) { const resultTables: Record = {}; + + context.inspectorAdapters?.tables?.reset(); + 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/xy_chart/xy_chart.ts b/x-pack/plugins/lens/common/expressions/xy_chart/xy_chart.ts index d3fb2fe7a6917..6fb9b0cef4ebf 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, Object.values(data.tables)); + } return { type: 'render', as: 'lens_xy_chart_renderer', From 94cb3b60d8d9dc9b9b116d917d3af334b988910c Mon Sep 17 00:00:00 2001 From: Alexey Antonov Date: Thu, 10 Mar 2022 19:27:31 +0500 Subject: [PATCH 2/6] update workspace_panel --- .../expressions/datatable/datatable_fn.ts | 2 +- .../common/expressions/expressions_utils.ts | 7 +++-- .../common/expressions/xy_chart/xy_chart.ts | 2 +- .../workspace_panel/workspace_panel.tsx | 28 +++++++++++++++---- 4 files changed, 29 insertions(+), 10 deletions(-) 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 f7ee187263ebe..41bf51764b539 100644 --- a/x-pack/plugins/lens/common/expressions/datatable/datatable_fn.ts +++ b/x-pack/plugins/lens/common/expressions/datatable/datatable_fn.ts @@ -27,7 +27,7 @@ export const datatableFn = ): DatatableExpressionFunction['fn'] => async (data, args, context) => { if (context?.inspectorAdapters?.tables) { - logDataTable(context?.inspectorAdapters?.tables, Object.values(data.tables)); + logDataTable(context.inspectorAdapters.tables, data.tables); } let untransposedData: LensMultiTable | undefined; diff --git a/x-pack/plugins/lens/common/expressions/expressions_utils.ts b/x-pack/plugins/lens/common/expressions/expressions_utils.ts index ef8804fe1bdb9..795b23e26e830 100644 --- a/x-pack/plugins/lens/common/expressions/expressions_utils.ts +++ b/x-pack/plugins/lens/common/expressions/expressions_utils.ts @@ -8,6 +8,9 @@ import type { TablesAdapter } from '../../../../../src/plugins/expressions'; import type { Datatable } from '../../../../../src/plugins/expressions'; -export const logDataTable = (tableAdapter: TablesAdapter, datatables: Datatable[]) => { - datatables.forEach((table, index) => tableAdapter.logDatatable(index.toString(), table)); +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/xy_chart/xy_chart.ts b/x-pack/plugins/lens/common/expressions/xy_chart/xy_chart.ts index 6fb9b0cef4ebf..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 @@ -159,7 +159,7 @@ export const xyChart: ExpressionFunctionDefinition< }, fn(data: LensMultiTable, args: XYArgs, handlers) { if (handlers?.inspectorAdapters?.tables) { - logDataTable(handlers?.inspectorAdapters?.tables, Object.values(data.tables)); + logDataTable(handlers.inspectorAdapters.tables, data.tables); } return { type: 'render', diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx index 81fef751ae46a..f95312615c722 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx @@ -52,7 +52,6 @@ import { getUnknownVisualizationTypeError, } from '../../error_helper'; import { getMissingIndexPattern, validateDatasourceAndVisualization } from '../state_helpers'; -import { DefaultInspectorAdapters } from '../../../../../../../src/plugins/expressions/common'; import { onActiveDataChange, useLensDispatch, @@ -68,10 +67,12 @@ import { selectSearchSessionId, selectAutoApplyEnabled, selectTriggerApplyChanges, + selectDatasourceLayers, } from '../../../state_management'; import type { LensInspector } from '../../../lens_inspector_service'; import { inferTimeField } from '../../../utils'; import { setChangesApplied } from '../../../state_management/lens_slice'; +import type { Datatable } from '../../../../../../../src/plugins/expressions/public'; export interface WorkspacePanelProps { visualizationMap: VisualizationMap; @@ -381,6 +382,7 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({ if (localState.expressionToRender === null) { return renderEmptyWorkspace(); } + return ( ); @@ -455,6 +458,7 @@ export const VisualizationWrapper = ({ ExpressionRendererComponent, application, activeDatasourceId, + datasourceMap, }: { expression: string | null | undefined; framePublicAPI: FramePublicAPI; @@ -473,6 +477,7 @@ export const VisualizationWrapper = ({ ExpressionRendererComponent: ReactExpressionRendererType; application: ApplicationStart; activeDatasourceId: string | null; + datasourceMap: DatasourceMap; }) => { const context = useLensSelector(selectExecutionContext); const searchContext: ExecutionContextSearch = useMemo( @@ -487,16 +492,27 @@ export const VisualizationWrapper = ({ [context] ); const searchSessionId = useLensSelector(selectSearchSessionId); - + const datasourceLayers = useLensSelector((state) => selectDatasourceLayers(state, datasourceMap)); const dispatchLens = useLensDispatch(); const onData$ = useCallback( - (data: unknown, adapters?: Partial) => { - if (adapters && adapters.tables) { - dispatchLens(onActiveDataChange({ ...adapters.tables.tables })); + (data) => { + let tables: Record = {}; + if (data?.value?.data) { + switch (data.value.data.type) { + case 'datatable': + const [layerId] = Object.keys(datasourceLayers); + tables[layerId] = { ...data.value.data }; + break; + case 'lens_multitable': + tables = { ...data.value.data.tables }; + break; + } } + + dispatchLens(onActiveDataChange(tables)); }, - [dispatchLens] + [datasourceLayers, dispatchLens] ); function renderFixAction( From cf4cb838c40a9cc2fbaa53a46cae3b13e962327f Mon Sep 17 00:00:00 2001 From: Alexey Antonov Date: Thu, 10 Mar 2022 22:28:05 +0500 Subject: [PATCH 3/6] revert allowCsvExport --- src/plugins/expressions/common/util/tables_adapter.ts | 2 +- x-pack/plugins/lens/common/expressions/merge_tables/index.ts | 5 ++++- .../editor_frame/workspace_panel/workspace_panel.tsx | 5 ++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/plugins/expressions/common/util/tables_adapter.ts b/src/plugins/expressions/common/util/tables_adapter.ts index cebce4d401e77..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 } = {}; 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 f03334fd45c29..2bf955d9e3ed3 100644 --- a/x-pack/plugins/lens/common/expressions/merge_tables/index.ts +++ b/x-pack/plugins/lens/common/expressions/merge_tables/index.ts @@ -51,7 +51,10 @@ export const mergeTables: ExpressionFunctionDefinition< fn(input, { layerIds, tables }, context) { const resultTables: Record = {}; - context.inspectorAdapters?.tables?.reset(); + if (context.inspectorAdapters?.tables) { + context.inspectorAdapters.tables.reset(); + context.inspectorAdapters.tables.allowCsvExport = true; + } tables.forEach((table, index) => { resultTables[layerIds[index]] = table; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx index f95312615c722..bb9fbace86477 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx @@ -497,8 +497,8 @@ export const VisualizationWrapper = ({ const onData$ = useCallback( (data) => { - let tables: Record = {}; if (data?.value?.data) { + let tables: Record = {}; switch (data.value.data.type) { case 'datatable': const [layerId] = Object.keys(datasourceLayers); @@ -508,9 +508,8 @@ export const VisualizationWrapper = ({ tables = { ...data.value.data.tables }; break; } + dispatchLens(onActiveDataChange(tables)); } - - dispatchLens(onActiveDataChange(tables)); }, [datasourceLayers, dispatchLens] ); From 2f8ce6f5585100c698f568075a0ab10dfa9304aa Mon Sep 17 00:00:00 2001 From: Alexey Antonov Date: Fri, 11 Mar 2022 18:03:56 +0500 Subject: [PATCH 4/6] fix CI --- .../merge_tables/merge_tables.test.ts | 14 +++++----- .../workspace_panel/workspace_panel.tsx | 28 ++++++++++--------- 2 files changed, 22 insertions(+), 20 deletions(-) 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/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx index bb9fbace86477..6da602313c031 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx @@ -52,6 +52,7 @@ import { getUnknownVisualizationTypeError, } from '../../error_helper'; import { getMissingIndexPattern, validateDatasourceAndVisualization } from '../state_helpers'; +import type { DefaultInspectorAdapters } from '../../../../../../../src/plugins/expressions/common'; import { onActiveDataChange, useLensDispatch, @@ -496,19 +497,20 @@ export const VisualizationWrapper = ({ const dispatchLens = useLensDispatch(); const onData$ = useCallback( - (data) => { - if (data?.value?.data) { - let tables: Record = {}; - switch (data.value.data.type) { - case 'datatable': - const [layerId] = Object.keys(datasourceLayers); - tables[layerId] = { ...data.value.data }; - break; - case 'lens_multitable': - tables = { ...data.value.data.tables }; - break; - } - dispatchLens(onActiveDataChange(tables)); + (data: unknown, adapters?: Partial) => { + if (adapters && adapters.tables) { + const [defaultLayerId] = Object.keys(datasourceLayers); + + dispatchLens( + onActiveDataChange( + Object.entries(adapters.tables?.tables).reduce>( + (acc, [key, value]) => ({ + [key === 'default' ? defaultLayerId : key]: value, + }), + {} + ) + ) + ); } }, [datasourceLayers, dispatchLens] From 36a4e916d0c6809ec820da5e1786fcaba9f685e5 Mon Sep 17 00:00:00 2001 From: Alexey Antonov Date: Mon, 14 Mar 2022 14:54:19 +0500 Subject: [PATCH 5/6] fix PR comments --- .../editor_frame/workspace_panel/workspace_panel.test.tsx | 2 +- .../editor_frame/workspace_panel/workspace_panel.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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( >( - (acc, [key, value]) => ({ - [key === 'default' ? defaultLayerId : key]: value, + (acc, [key, value], index, tables) => ({ + [tables.length === 1 ? defaultLayerId : key]: value, }), {} ) From ed6967fccd5d97aa5aaa9a0568d39e696d882606 Mon Sep 17 00:00:00 2001 From: Alexey Antonov Date: Wed, 16 Mar 2022 11:42:16 +0500 Subject: [PATCH 6/6] apply pr comments --- .../editor_frame/workspace_panel/workspace_panel.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx index 31b8354a18188..5ca1084d7f507 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx @@ -495,12 +495,11 @@ export const VisualizationWrapper = ({ 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) { - const [defaultLayerId] = Object.keys(datasourceLayers); - dispatchLens( onActiveDataChange( Object.entries(adapters.tables?.tables).reduce>( @@ -513,7 +512,7 @@ export const VisualizationWrapper = ({ ); } }, - [datasourceLayers, dispatchLens] + [defaultLayerId, dispatchLens] ); function renderFixAction(