From 74ab7e922eea971524324f484d7e3af09163c529 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Fri, 28 Oct 2022 17:57:38 +0300 Subject: [PATCH 1/7] Fixed way of expression building at Lens datatable. --- .../lens/common/expressions/collapse/index.ts | 2 + .../expressions/datatable/datatable_column.ts | 7 +- .../common/expressions/datatable/index.ts | 2 +- .../datatable/visualization.test.tsx | 16 +- .../datatable/visualization.tsx | 190 +++++++++--------- 5 files changed, 104 insertions(+), 113 deletions(-) diff --git a/x-pack/plugins/lens/common/expressions/collapse/index.ts b/x-pack/plugins/lens/common/expressions/collapse/index.ts index 43874859411fc..2b1e89af08bd4 100644 --- a/x-pack/plugins/lens/common/expressions/collapse/index.ts +++ b/x-pack/plugins/lens/common/expressions/collapse/index.ts @@ -16,6 +16,8 @@ export interface CollapseArgs { fn: CollapseFunction[]; } +export type { CollapseExpressionFunction }; + /** * Collapses multiple rows into a single row using the specified function. * diff --git a/x-pack/plugins/lens/common/expressions/datatable/datatable_column.ts b/x-pack/plugins/lens/common/expressions/datatable/datatable_column.ts index f955cc1dfa2cb..16e76d3baf2e4 100644 --- a/x-pack/plugins/lens/common/expressions/datatable/datatable_column.ts +++ b/x-pack/plugins/lens/common/expressions/datatable/datatable_column.ts @@ -48,13 +48,14 @@ export interface ColumnState { } export type DatatableColumnResult = ColumnState & { type: 'lens_datatable_column' }; - -export const datatableColumn: ExpressionFunctionDefinition< +export type DatatableColumnFunction = ExpressionFunctionDefinition< 'lens_datatable_column', null, ColumnState & { sortingHint?: SortingHint }, DatatableColumnResult -> = { +>; + +export const datatableColumn: DatatableColumnFunction = { name: 'lens_datatable_column', aliases: [], type: 'lens_datatable_column', diff --git a/x-pack/plugins/lens/common/expressions/datatable/index.ts b/x-pack/plugins/lens/common/expressions/datatable/index.ts index 2fa0312360297..7003fd8d486b8 100644 --- a/x-pack/plugins/lens/common/expressions/datatable/index.ts +++ b/x-pack/plugins/lens/common/expressions/datatable/index.ts @@ -8,4 +8,4 @@ export * from './datatable_column'; export * from './datatable'; -export type { DatatableProps } from './types'; +export type { DatatableProps, DatatableExpressionFunction } from './types'; diff --git a/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx b/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx index e6683aee13499..a6a894e370ff6 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx @@ -550,22 +550,16 @@ describe('Datatable Visualization', () => { expect(columnArgs[0].arguments).toEqual( expect.objectContaining({ columnId: ['c'], - hidden: [], - width: [], - isTransposed: [], + palette: [expect.objectContaining({})], transposable: [true], - alignment: [], colorMode: ['none'], }) ); expect(columnArgs[1].arguments).toEqual( expect.objectContaining({ columnId: ['b'], - hidden: [], - width: [], - isTransposed: [], + palette: [expect.objectContaining({})], transposable: [true], - alignment: [], colorMode: ['none'], }) ); @@ -592,14 +586,16 @@ describe('Datatable Visualization', () => { }); it('sets pagination based on state', () => { - expect(getDatatableExpressionArgs({ ...defaultExpressionTableState }).pageSize).toEqual([]); + expect(getDatatableExpressionArgs({ ...defaultExpressionTableState }).pageSize).toEqual( + undefined + ); expect( getDatatableExpressionArgs({ ...defaultExpressionTableState, paging: { size: 20, enabled: false }, }).pageSize - ).toEqual([]); + ).toEqual(undefined); expect( getDatatableExpressionArgs({ diff --git a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx index 60de4d4d1148c..986b6da0908b6 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { render } from 'react-dom'; -import { Ast, AstFunction } from '@kbn/interpreter'; +import { Ast } from '@kbn/interpreter'; import { I18nProvider } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { PaletteRegistry, CUSTOM_PALETTE } from '@kbn/coloring'; @@ -16,6 +16,7 @@ import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public'; import { IconChartDatatable } from '@kbn/chart-icons'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; +import { buildExpression, buildExpressionFunction } from '@kbn/expressions-plugin/common'; import type { FormBasedPersistedState } from '../../datasources/form_based/types'; import type { SuggestionRequest, @@ -27,8 +28,17 @@ import type { import { TableDimensionEditor } from './components/dimension_editor'; import { TableDimensionEditorAdditionalSection } from './components/dimension_editor_addtional_section'; import type { LayerType } from '../../../common'; +import type { + DatatableColumnFunction, + DatatableExpressionFunction, +} from '../../../common/expressions/datatable'; import { getDefaultSummaryLabel } from '../../../common/expressions/datatable/summary'; -import type { ColumnState, SortingState, PagingState } from '../../../common/expressions'; +import { + ColumnState, + SortingState, + PagingState, + CollapseExpressionFunction, +} from '../../../common/expressions'; import { DataTableToolbar } from './components/toolbar'; export interface DatatableVisualizationState { @@ -398,107 +408,89 @@ export const getDatatableVisualization = ({ const datasourceExpression = datasourceExpressionsByLayers[state.layerId]; + const notCollapseFns = columns.filter((c) => !c.collapseFn); + + const columnFns = notCollapseFns.map((column) => { + const paletteParams = { + ...column.palette?.params, + // rewrite colors and stops as two distinct arguments + colors: (column.palette?.params?.stops || []).map(({ color }) => color), + stops: + column.palette?.params?.name === 'custom' + ? (column.palette?.params?.stops || []).map(({ stop }) => stop) + : [], + reverse: false, // managed at UI level + }; + const sortingHint = datasource!.getOperationForColumnId(column.columnId)!.sortingHint; + + const hasNoSummaryRow = column.summaryRow == null || column.summaryRow === 'none'; + + const canColor = datasource!.getOperationForColumnId(column.columnId)?.dataType === 'number'; + + const datatableColumnFn = buildExpressionFunction( + 'lens_datatable_column', + { + columnId: column.columnId, + hidden: column.hidden, + oneClickFilter: column.oneClickFilter, + width: column.width, + isTransposed: column.isTransposed, + transposable: !datasource!.getOperationForColumnId(column.columnId)?.isBucketed, + alignment: column.alignment, + colorMode: canColor && column.colorMode ? column.colorMode : 'none', + palette: paletteService.get(CUSTOM_PALETTE).toExpression(paletteParams), + summaryRow: hasNoSummaryRow ? undefined : column.summaryRow!, + summaryLabel: hasNoSummaryRow + ? undefined + : column.summaryLabel ?? getDefaultSummaryLabel(column.summaryRow!), + sortingHint, + } + ); + + return datatableColumnFn; + }); + + const datatableFn = buildExpressionFunction('lens_datatable', { + title: title || '', + description: description || '', + sortingColumnId: state.sorting?.columnId || '', + sortingDirection: state.sorting?.direction || 'none', + fitRowToContent: state.rowHeight === 'auto', + headerRowHeight: state.headerRowHeight ?? 'single', + rowHeightLines: + !state.rowHeight || state.rowHeight === 'single' ? 1 : state.rowHeightLines ?? 2, + headerRowHeightLines: + !state.headerRowHeight || state.headerRowHeight === 'single' + ? 1 + : state.headerRowHeightLines ?? 2, + pageSize: state.paging?.enabled ? state.paging.size : undefined, + columns: columnFns.length ? buildExpression(columnFns) : [], + }); + + const collapseFnCols = columns.filter((c) => c.collapseFn); + const collapseFns = collapseFnCols.map((column) => { + const collapseFn = buildExpressionFunction('lens_collapse', { + by: columns + .filter( + (col) => + col.columnId !== column.columnId && + datasource!.getOperationForColumnId(col.columnId)?.isBucketed + ) + .map((col) => col.columnId), + metric: columns + .filter((col) => !datasource!.getOperationForColumnId(col.columnId)?.isBucketed) + .map((col) => col.columnId), + fn: [column.collapseFn!], + }); + return collapseFn; + }); + return { type: 'expression', chain: [ ...(datasourceExpression?.chain ?? []), - ...columns - .filter((c) => c.collapseFn) - .map((c) => { - return { - type: 'function', - function: 'lens_collapse', - arguments: { - by: columns - .filter( - (col) => - col.columnId !== c.columnId && - datasource!.getOperationForColumnId(col.columnId)?.isBucketed - ) - .map((col) => col.columnId), - metric: columns - .filter((col) => !datasource!.getOperationForColumnId(col.columnId)?.isBucketed) - .map((col) => col.columnId), - fn: [c.collapseFn!], - }, - } as AstFunction; - }), - { - type: 'function', - function: 'lens_datatable', - arguments: { - title: [title || ''], - description: [description || ''], - columns: columns - .filter((c) => !c.collapseFn) - .map((column) => { - const paletteParams = { - ...column.palette?.params, - // rewrite colors and stops as two distinct arguments - colors: (column.palette?.params?.stops || []).map(({ color }) => color), - stops: - column.palette?.params?.name === 'custom' - ? (column.palette?.params?.stops || []).map(({ stop }) => stop) - : [], - reverse: false, // managed at UI level - }; - const sortingHint = datasource!.getOperationForColumnId( - column.columnId - )!.sortingHint; - - const hasNoSummaryRow = column.summaryRow == null || column.summaryRow === 'none'; - - const canColor = - datasource!.getOperationForColumnId(column.columnId)?.dataType === 'number'; - - return { - type: 'expression', - chain: [ - { - type: 'function', - function: 'lens_datatable_column', - arguments: { - columnId: [column.columnId], - hidden: typeof column.hidden === 'undefined' ? [] : [column.hidden], - oneClickFilter: - typeof column.oneClickFilter === 'undefined' - ? [] - : [column.oneClickFilter], - width: typeof column.width === 'undefined' ? [] : [column.width], - isTransposed: - typeof column.isTransposed === 'undefined' ? [] : [column.isTransposed], - transposable: [ - !datasource!.getOperationForColumnId(column.columnId)?.isBucketed, - ], - alignment: - typeof column.alignment === 'undefined' ? [] : [column.alignment], - colorMode: [canColor && column.colorMode ? column.colorMode : 'none'], - palette: [paletteService.get(CUSTOM_PALETTE).toExpression(paletteParams)], - summaryRow: hasNoSummaryRow ? [] : [column.summaryRow!], - summaryLabel: hasNoSummaryRow - ? [] - : [column.summaryLabel ?? getDefaultSummaryLabel(column.summaryRow!)], - sortingHint: sortingHint ? [sortingHint] : [], - }, - }, - ], - }; - }), - sortingColumnId: [state.sorting?.columnId || ''], - sortingDirection: [state.sorting?.direction || 'none'], - fitRowToContent: [state.rowHeight === 'auto'], - headerRowHeight: [state.headerRowHeight ?? 'single'], - rowHeightLines: [ - !state.rowHeight || state.rowHeight === 'single' ? 1 : state.rowHeightLines ?? 2, - ], - headerRowHeightLines: [ - !state.headerRowHeight || state.headerRowHeight === 'single' - ? 1 - : state.headerRowHeightLines ?? 2, - ], - pageSize: state.paging?.enabled ? [state.paging.size] : [], - }, - }, + ...collapseFns.map((fn) => fn.toAst()), + datatableFn.toAst(), ], }; }, From 30e39b6adb775a23c91d5cfab06fcb00171907d2 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 31 Oct 2022 12:20:51 +0200 Subject: [PATCH 2/7] CollapseFn type safety added. --- .../lens/common/expressions/collapse/index.ts | 2 + .../datatable/visualization.tsx | 51 ++++++++++--------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/lens/common/expressions/collapse/index.ts b/x-pack/plugins/lens/common/expressions/collapse/index.ts index 43874859411fc..238d704dd97fc 100644 --- a/x-pack/plugins/lens/common/expressions/collapse/index.ts +++ b/x-pack/plugins/lens/common/expressions/collapse/index.ts @@ -68,3 +68,5 @@ export const collapse: CollapseExpressionFunction = { return collapseFn(...args); }, }; + +export { CollapseExpressionFunction }; diff --git a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx index 60de4d4d1148c..43fb956c48503 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { render } from 'react-dom'; -import { Ast, AstFunction } from '@kbn/interpreter'; +import { Ast } from '@kbn/interpreter'; import { I18nProvider } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { PaletteRegistry, CUSTOM_PALETTE } from '@kbn/coloring'; @@ -16,6 +16,7 @@ import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public'; import { IconChartDatatable } from '@kbn/chart-icons'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; +import { buildExpressionFunction } from '@kbn/expressions-plugin/common'; import type { FormBasedPersistedState } from '../../datasources/form_based/types'; import type { SuggestionRequest, @@ -28,7 +29,12 @@ import { TableDimensionEditor } from './components/dimension_editor'; import { TableDimensionEditorAdditionalSection } from './components/dimension_editor_addtional_section'; import type { LayerType } from '../../../common'; import { getDefaultSummaryLabel } from '../../../common/expressions/datatable/summary'; -import type { ColumnState, SortingState, PagingState } from '../../../common/expressions'; +import type { + ColumnState, + SortingState, + PagingState, + CollapseExpressionFunction, +} from '../../../common/expressions'; import { DataTableToolbar } from './components/toolbar'; export interface DatatableVisualizationState { @@ -398,31 +404,30 @@ export const getDatatableVisualization = ({ const datasourceExpression = datasourceExpressionsByLayers[state.layerId]; + const lensCollapseFns = columns + .filter((c) => c.collapseFn) + .map((c) => { + const fn = buildExpressionFunction('lens_collapse', { + by: columns + .filter( + (col) => + col.columnId !== c.columnId && + datasource!.getOperationForColumnId(col.columnId)?.isBucketed + ) + .map((col) => col.columnId), + metric: columns + .filter((col) => !datasource!.getOperationForColumnId(col.columnId)?.isBucketed) + .map((col) => col.columnId), + fn: [c.collapseFn!], + }); + return fn.toAst(); + }); + return { type: 'expression', chain: [ ...(datasourceExpression?.chain ?? []), - ...columns - .filter((c) => c.collapseFn) - .map((c) => { - return { - type: 'function', - function: 'lens_collapse', - arguments: { - by: columns - .filter( - (col) => - col.columnId !== c.columnId && - datasource!.getOperationForColumnId(col.columnId)?.isBucketed - ) - .map((col) => col.columnId), - metric: columns - .filter((col) => !datasource!.getOperationForColumnId(col.columnId)?.isBucketed) - .map((col) => col.columnId), - fn: [c.collapseFn!], - }, - } as AstFunction; - }), + ...lensCollapseFns, { type: 'function', function: 'lens_datatable', From caa729d39a2503f736921e73409ce964e516d342 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 31 Oct 2022 12:41:59 +0200 Subject: [PATCH 3/7] Removed duplicated export. --- x-pack/plugins/lens/common/expressions/collapse/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/x-pack/plugins/lens/common/expressions/collapse/index.ts b/x-pack/plugins/lens/common/expressions/collapse/index.ts index e92c21590a844..2b1e89af08bd4 100644 --- a/x-pack/plugins/lens/common/expressions/collapse/index.ts +++ b/x-pack/plugins/lens/common/expressions/collapse/index.ts @@ -70,5 +70,3 @@ export const collapse: CollapseExpressionFunction = { return collapseFn(...args); }, }; - -export { CollapseExpressionFunction }; From e6f63367f66fd7458cb251d4393ce07b20381a86 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 31 Oct 2022 12:50:42 +0200 Subject: [PATCH 4/7] Small refactoring --- .../public/visualizations/datatable/visualization.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx index 43fb956c48503..004ff8bf6590f 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx @@ -406,8 +406,8 @@ export const getDatatableVisualization = ({ const lensCollapseFns = columns .filter((c) => c.collapseFn) - .map((c) => { - const fn = buildExpressionFunction('lens_collapse', { + .map((c) => + buildExpressionFunction('lens_collapse', { by: columns .filter( (col) => @@ -419,9 +419,8 @@ export const getDatatableVisualization = ({ .filter((col) => !datasource!.getOperationForColumnId(col.columnId)?.isBucketed) .map((col) => col.columnId), fn: [c.collapseFn!], - }); - return fn.toAst(); - }); + }).toAst() + ); return { type: 'expression', From a6820067a051179b2b91445f4abada6b237a04e5 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 31 Oct 2022 13:04:01 +0200 Subject: [PATCH 5/7] Added datatableColumnFn expression. --- .../datatable/visualization.tsx | 55 ++++++++----------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx index 004ff8bf6590f..8fcca74a54182 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx @@ -16,7 +16,7 @@ import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; import { VIS_EVENT_TO_TRIGGER } from '@kbn/visualizations-plugin/public'; import { IconChartDatatable } from '@kbn/chart-icons'; import { LayerTypes } from '@kbn/expression-xy-plugin/public'; -import { buildExpressionFunction } from '@kbn/expressions-plugin/common'; +import { buildExpression, buildExpressionFunction } from '@kbn/expressions-plugin/common'; import type { FormBasedPersistedState } from '../../datasources/form_based/types'; import type { SuggestionRequest, @@ -34,6 +34,7 @@ import type { SortingState, PagingState, CollapseExpressionFunction, + DatatableColumnFunction, } from '../../../common/expressions'; import { DataTableToolbar } from './components/toolbar'; @@ -455,38 +456,26 @@ export const getDatatableVisualization = ({ const canColor = datasource!.getOperationForColumnId(column.columnId)?.dataType === 'number'; - return { - type: 'expression', - chain: [ - { - type: 'function', - function: 'lens_datatable_column', - arguments: { - columnId: [column.columnId], - hidden: typeof column.hidden === 'undefined' ? [] : [column.hidden], - oneClickFilter: - typeof column.oneClickFilter === 'undefined' - ? [] - : [column.oneClickFilter], - width: typeof column.width === 'undefined' ? [] : [column.width], - isTransposed: - typeof column.isTransposed === 'undefined' ? [] : [column.isTransposed], - transposable: [ - !datasource!.getOperationForColumnId(column.columnId)?.isBucketed, - ], - alignment: - typeof column.alignment === 'undefined' ? [] : [column.alignment], - colorMode: [canColor && column.colorMode ? column.colorMode : 'none'], - palette: [paletteService.get(CUSTOM_PALETTE).toExpression(paletteParams)], - summaryRow: hasNoSummaryRow ? [] : [column.summaryRow!], - summaryLabel: hasNoSummaryRow - ? [] - : [column.summaryLabel ?? getDefaultSummaryLabel(column.summaryRow!)], - sortingHint: sortingHint ? [sortingHint] : [], - }, - }, - ], - }; + const datatableColumnFn = buildExpressionFunction( + 'lens_datatable_column', + { + columnId: column.columnId, + hidden: column.hidden, + oneClickFilter: column.oneClickFilter, + width: column.width, + isTransposed: column.isTransposed, + transposable: !datasource!.getOperationForColumnId(column.columnId)?.isBucketed, + alignment: column.alignment, + colorMode: canColor && column.colorMode ? column.colorMode : 'none', + palette: paletteService.get(CUSTOM_PALETTE).toExpression(paletteParams), + summaryRow: hasNoSummaryRow ? undefined : column.summaryRow!, + summaryLabel: hasNoSummaryRow + ? undefined + : column.summaryLabel ?? getDefaultSummaryLabel(column.summaryRow!), + sortingHint, + } + ); + return buildExpression([datatableColumnFn]).toAst(); }), sortingColumnId: [state.sorting?.columnId || ''], sortingDirection: [state.sorting?.direction || 'none'], From 63bd9ba50b108cef69af82ebae8cc176066f1036 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Mon, 31 Oct 2022 13:13:39 +0200 Subject: [PATCH 6/7] Added type safety for datatable fn. --- .../datatable/visualization.tsx | 129 ++++++++---------- 1 file changed, 60 insertions(+), 69 deletions(-) diff --git a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx index 8fcca74a54182..ccfaff17a8ecb 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx @@ -35,6 +35,7 @@ import type { PagingState, CollapseExpressionFunction, DatatableColumnFunction, + DatatableExpressionFunction, } from '../../../common/expressions'; import { DataTableToolbar } from './components/toolbar'; @@ -405,7 +406,7 @@ export const getDatatableVisualization = ({ const datasourceExpression = datasourceExpressionsByLayers[state.layerId]; - const lensCollapseFns = columns + const lensCollapseFnAsts = columns .filter((c) => c.collapseFn) .map((c) => buildExpressionFunction('lens_collapse', { @@ -423,76 +424,66 @@ export const getDatatableVisualization = ({ }).toAst() ); + const datatableFnAst = buildExpressionFunction('lens_datatable', { + title: title || '', + description: description || '', + columns: columns + .filter((c) => !c.collapseFn) + .map((column) => { + const paletteParams = { + ...column.palette?.params, + // rewrite colors and stops as two distinct arguments + colors: (column.palette?.params?.stops || []).map(({ color }) => color), + stops: + column.palette?.params?.name === 'custom' + ? (column.palette?.params?.stops || []).map(({ stop }) => stop) + : [], + reverse: false, // managed at UI level + }; + const sortingHint = datasource!.getOperationForColumnId(column.columnId)!.sortingHint; + + const hasNoSummaryRow = column.summaryRow == null || column.summaryRow === 'none'; + + const canColor = + datasource!.getOperationForColumnId(column.columnId)?.dataType === 'number'; + + const datatableColumnFn = buildExpressionFunction( + 'lens_datatable_column', + { + columnId: column.columnId, + hidden: column.hidden, + oneClickFilter: column.oneClickFilter, + width: column.width, + isTransposed: column.isTransposed, + transposable: !datasource!.getOperationForColumnId(column.columnId)?.isBucketed, + alignment: column.alignment, + colorMode: canColor && column.colorMode ? column.colorMode : 'none', + palette: paletteService.get(CUSTOM_PALETTE).toExpression(paletteParams), + summaryRow: hasNoSummaryRow ? undefined : column.summaryRow!, + summaryLabel: hasNoSummaryRow + ? undefined + : column.summaryLabel ?? getDefaultSummaryLabel(column.summaryRow!), + sortingHint, + } + ); + return buildExpression([datatableColumnFn]).toAst(); + }), + sortingColumnId: state.sorting?.columnId || '', + sortingDirection: state.sorting?.direction || 'none', + fitRowToContent: state.rowHeight === 'auto', + headerRowHeight: state.headerRowHeight ?? 'single', + rowHeightLines: + !state.rowHeight || state.rowHeight === 'single' ? 1 : state.rowHeightLines ?? 2, + headerRowHeightLines: + !state.headerRowHeight || state.headerRowHeight === 'single' + ? 1 + : state.headerRowHeightLines ?? 2, + pageSize: state.paging?.enabled ? state.paging.size : undefined, + }).toAst(); + return { type: 'expression', - chain: [ - ...(datasourceExpression?.chain ?? []), - ...lensCollapseFns, - { - type: 'function', - function: 'lens_datatable', - arguments: { - title: [title || ''], - description: [description || ''], - columns: columns - .filter((c) => !c.collapseFn) - .map((column) => { - const paletteParams = { - ...column.palette?.params, - // rewrite colors and stops as two distinct arguments - colors: (column.palette?.params?.stops || []).map(({ color }) => color), - stops: - column.palette?.params?.name === 'custom' - ? (column.palette?.params?.stops || []).map(({ stop }) => stop) - : [], - reverse: false, // managed at UI level - }; - const sortingHint = datasource!.getOperationForColumnId( - column.columnId - )!.sortingHint; - - const hasNoSummaryRow = column.summaryRow == null || column.summaryRow === 'none'; - - const canColor = - datasource!.getOperationForColumnId(column.columnId)?.dataType === 'number'; - - const datatableColumnFn = buildExpressionFunction( - 'lens_datatable_column', - { - columnId: column.columnId, - hidden: column.hidden, - oneClickFilter: column.oneClickFilter, - width: column.width, - isTransposed: column.isTransposed, - transposable: !datasource!.getOperationForColumnId(column.columnId)?.isBucketed, - alignment: column.alignment, - colorMode: canColor && column.colorMode ? column.colorMode : 'none', - palette: paletteService.get(CUSTOM_PALETTE).toExpression(paletteParams), - summaryRow: hasNoSummaryRow ? undefined : column.summaryRow!, - summaryLabel: hasNoSummaryRow - ? undefined - : column.summaryLabel ?? getDefaultSummaryLabel(column.summaryRow!), - sortingHint, - } - ); - return buildExpression([datatableColumnFn]).toAst(); - }), - sortingColumnId: [state.sorting?.columnId || ''], - sortingDirection: [state.sorting?.direction || 'none'], - fitRowToContent: [state.rowHeight === 'auto'], - headerRowHeight: [state.headerRowHeight ?? 'single'], - rowHeightLines: [ - !state.rowHeight || state.rowHeight === 'single' ? 1 : state.rowHeightLines ?? 2, - ], - headerRowHeightLines: [ - !state.headerRowHeight || state.headerRowHeight === 'single' - ? 1 - : state.headerRowHeightLines ?? 2, - ], - pageSize: state.paging?.enabled ? [state.paging.size] : [], - }, - }, - ], + chain: [...(datasourceExpression?.chain ?? []), ...lensCollapseFnAsts, datatableFnAst], }; }, From 92e7c6abee4c34d3b8854d76b83fb6edcb684b69 Mon Sep 17 00:00:00 2001 From: Yaroslav Kuznietsov Date: Tue, 1 Nov 2022 09:25:11 +0200 Subject: [PATCH 7/7] Update x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx Co-authored-by: Andrew Tate --- .../lens/public/visualizations/datatable/visualization.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx b/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx index a6a894e370ff6..a38d669d73cd5 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx @@ -550,7 +550,7 @@ describe('Datatable Visualization', () => { expect(columnArgs[0].arguments).toEqual( expect.objectContaining({ columnId: ['c'], - palette: [expect.objectContaining({})], + palette: [expect.any(Object)], transposable: [true], colorMode: ['none'], })