From b125472de53068f56b10598fc8ee030097af4288 Mon Sep 17 00:00:00 2001 From: Daniil Suleiman <31325372+sulemanof@users.noreply.github.com> Date: Mon, 12 Oct 2020 12:06:33 +0300 Subject: [PATCH] Table visualization renderer (#79455) * Implement toExpressionAst fn * Implement table vis renderer, move legacy codebase * Update legacy paths * Update types * Fix filtering * Update styles * Remove legacy tests * Update docs * Update tests * Fix tests Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- ...sions-public.iinterpreterrenderhandlers.md | 1 + ...blic.iinterpreterrenderhandlers.uistate.md | 11 ++ ...sions-server.iinterpreterrenderhandlers.md | 1 + ...rver.iinterpreterrenderhandlers.uistate.md | 11 ++ .../common/expression_renderers/types.ts | 3 + src/plugins/expressions/public/public.api.md | 3 + src/plugins/expressions/server/server.api.md | 3 + .../__snapshots__/table_vis_fn.test.ts.snap | 5 +- .../public/__snapshots__/to_ast.test.ts.snap | 74 +++++++++ src/plugins/vis_type_table/public/index.ts | 1 - .../public/{ => legacy}/_table_vis.scss | 4 +- .../{ => legacy}/agg_table/_agg_table.scss | 0 .../public/{ => legacy}/agg_table/_index.scss | 0 .../{ => legacy}/agg_table/agg_table.html | 0 .../{ => legacy}/agg_table/agg_table.js | 4 +- .../{ => legacy}/agg_table/agg_table.test.js | 16 +- .../agg_table/agg_table_group.html | 0 .../{ => legacy}/agg_table/agg_table_group.js | 0 .../agg_table/agg_table_group.test.js | 10 +- .../{ => legacy}/agg_table/tabified_data.js | 0 .../public/{ => legacy}/get_inner_angular.ts | 2 +- .../public/{ => legacy}/index.scss | 0 .../{ => legacy}/paginated_table/_index.scss | 0 .../paginated_table/_table_cell_filter.scss | 0 .../paginated_table/paginated_table.html | 0 .../paginated_table/paginated_table.js | 0 .../paginated_table/paginated_table.test.ts | 6 +- .../{ => legacy}/paginated_table/rows.js | 21 +-- .../paginated_table/table_cell_filter.html | 0 .../public/{ => legacy}/table_vis.html | 2 +- .../{ => legacy}/table_vis_controller.js | 0 .../{ => legacy}/table_vis_controller.test.ts | 25 +-- .../{ => legacy}/table_vis_legacy_module.ts | 0 .../legacy/table_vis_legacy_renderer.tsx | 53 +++++++ .../public/{ => legacy}/vis_controller.ts | 49 +++--- src/plugins/vis_type_table/public/plugin.ts | 19 +-- src/plugins/vis_type_table/public/services.ts | 5 - .../vis_type_table/public/table_vis_fn.ts | 23 ++- .../vis_type_table/public/table_vis_type.ts | 145 ++++++++---------- .../vis_type_table/public/to_ast.test.ts | 79 ++++++++++ src/plugins/vis_type_table/public/to_ast.ts | 74 +++++++++ src/plugins/vis_type_table/public/types.ts | 5 +- .../__snapshots__/build_pipeline.test.ts.snap | 10 -- .../public/legacy/build_pipeline.test.ts | 78 ---------- .../public/legacy/build_pipeline.ts | 33 +--- 45 files changed, 474 insertions(+), 302 deletions(-) create mode 100644 docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.uistate.md create mode 100644 docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.uistate.md create mode 100644 src/plugins/vis_type_table/public/__snapshots__/to_ast.test.ts.snap rename src/plugins/vis_type_table/public/{ => legacy}/_table_vis.scss (91%) rename src/plugins/vis_type_table/public/{ => legacy}/agg_table/_agg_table.scss (100%) rename src/plugins/vis_type_table/public/{ => legacy}/agg_table/_index.scss (100%) rename src/plugins/vis_type_table/public/{ => legacy}/agg_table/agg_table.html (100%) rename src/plugins/vis_type_table/public/{ => legacy}/agg_table/agg_table.js (99%) rename src/plugins/vis_type_table/public/{ => legacy}/agg_table/agg_table.test.js (97%) rename src/plugins/vis_type_table/public/{ => legacy}/agg_table/agg_table_group.html (100%) rename src/plugins/vis_type_table/public/{ => legacy}/agg_table/agg_table_group.js (100%) rename src/plugins/vis_type_table/public/{ => legacy}/agg_table/agg_table_group.test.js (92%) rename src/plugins/vis_type_table/public/{ => legacy}/agg_table/tabified_data.js (100%) rename src/plugins/vis_type_table/public/{ => legacy}/get_inner_angular.ts (98%) rename src/plugins/vis_type_table/public/{ => legacy}/index.scss (100%) rename src/plugins/vis_type_table/public/{ => legacy}/paginated_table/_index.scss (100%) rename src/plugins/vis_type_table/public/{ => legacy}/paginated_table/_table_cell_filter.scss (100%) rename src/plugins/vis_type_table/public/{ => legacy}/paginated_table/paginated_table.html (100%) rename src/plugins/vis_type_table/public/{ => legacy}/paginated_table/paginated_table.js (100%) rename src/plugins/vis_type_table/public/{ => legacy}/paginated_table/paginated_table.test.ts (98%) rename src/plugins/vis_type_table/public/{ => legacy}/paginated_table/rows.js (91%) rename src/plugins/vis_type_table/public/{ => legacy}/paginated_table/table_cell_filter.html (100%) rename src/plugins/vis_type_table/public/{ => legacy}/table_vis.html (96%) rename src/plugins/vis_type_table/public/{ => legacy}/table_vis_controller.js (100%) rename src/plugins/vis_type_table/public/{ => legacy}/table_vis_controller.test.ts (89%) rename src/plugins/vis_type_table/public/{ => legacy}/table_vis_legacy_module.ts (100%) create mode 100644 src/plugins/vis_type_table/public/legacy/table_vis_legacy_renderer.tsx rename src/plugins/vis_type_table/public/{ => legacy}/vis_controller.ts (68%) create mode 100644 src/plugins/vis_type_table/public/to_ast.test.ts create mode 100644 src/plugins/vis_type_table/public/to_ast.ts diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md index 9dbd18ae687b46..ab0273be714022 100644 --- a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md @@ -18,5 +18,6 @@ export interface IInterpreterRenderHandlers | [event](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.event.md) | (event: any) => void | | | [onDestroy](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.ondestroy.md) | (fn: () => void) => void | | | [reload](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.reload.md) | () => void | | +| [uiState](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.uistate.md) | PersistedState | | | [update](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.update.md) | (params: any) => void | | diff --git a/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.uistate.md b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.uistate.md new file mode 100644 index 00000000000000..8d74c8e555fee6 --- /dev/null +++ b/docs/development/plugins/expressions/public/kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.uistate.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-public](./kibana-plugin-plugins-expressions-public.md) > [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.md) > [uiState](./kibana-plugin-plugins-expressions-public.iinterpreterrenderhandlers.uistate.md) + +## IInterpreterRenderHandlers.uiState property + +Signature: + +```typescript +uiState?: PersistedState; +``` diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md index cbaffa04bae8ff..ccf6271f712b94 100644 --- a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md @@ -18,5 +18,6 @@ export interface IInterpreterRenderHandlers | [event](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.event.md) | (event: any) => void | | | [onDestroy](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.ondestroy.md) | (fn: () => void) => void | | | [reload](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.reload.md) | () => void | | +| [uiState](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.uistate.md) | PersistedState | | | [update](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.update.md) | (params: any) => void | | diff --git a/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.uistate.md b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.uistate.md new file mode 100644 index 00000000000000..b09433c6454adb --- /dev/null +++ b/docs/development/plugins/expressions/server/kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.uistate.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-expressions-server](./kibana-plugin-plugins-expressions-server.md) > [IInterpreterRenderHandlers](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.md) > [uiState](./kibana-plugin-plugins-expressions-server.iinterpreterrenderhandlers.uistate.md) + +## IInterpreterRenderHandlers.uiState property + +Signature: + +```typescript +uiState?: PersistedState; +``` diff --git a/src/plugins/expressions/common/expression_renderers/types.ts b/src/plugins/expressions/common/expression_renderers/types.ts index b760e7b32a7d2b..0ea3d72e756092 100644 --- a/src/plugins/expressions/common/expression_renderers/types.ts +++ b/src/plugins/expressions/common/expression_renderers/types.ts @@ -17,6 +17,8 @@ * under the License. */ +import { PersistedState } from 'src/plugins/visualizations/public'; + export interface ExpressionRenderDefinition { /** * Technical name of the renderer, used as ID to identify renderer in @@ -68,4 +70,5 @@ export interface IInterpreterRenderHandlers { reload: () => void; update: (params: any) => void; event: (event: any) => void; + uiState?: PersistedState; } diff --git a/src/plugins/expressions/public/public.api.md b/src/plugins/expressions/public/public.api.md index 5c0fd8ab1a5729..763147df6d922d 100644 --- a/src/plugins/expressions/public/public.api.md +++ b/src/plugins/expressions/public/public.api.md @@ -11,6 +11,7 @@ import { EnvironmentMode } from '@kbn/config'; import { EventEmitter } from 'events'; import { Observable } from 'rxjs'; import { PackageInfo } from '@kbn/config'; +import { PersistedState } from 'src/plugins/visualizations/public'; import { Plugin as Plugin_2 } from 'src/core/public'; import { PluginInitializerContext as PluginInitializerContext_2 } from 'src/core/public'; import React from 'react'; @@ -883,6 +884,8 @@ export interface IInterpreterRenderHandlers { // (undocumented) reload: () => void; // (undocumented) + uiState?: PersistedState; + // (undocumented) update: (params: any) => void; } diff --git a/src/plugins/expressions/server/server.api.md b/src/plugins/expressions/server/server.api.md index d8872ee4160174..8266789664d444 100644 --- a/src/plugins/expressions/server/server.api.md +++ b/src/plugins/expressions/server/server.api.md @@ -9,6 +9,7 @@ import { CoreStart } from 'src/core/server'; import { Ensure } from '@kbn/utility-types'; import { EventEmitter } from 'events'; import { Observable } from 'rxjs'; +import { PersistedState } from 'src/plugins/visualizations/public'; import { Plugin as Plugin_2 } from 'src/core/server'; import { PluginInitializerContext } from 'src/core/server'; import { UnwrapPromiseOrReturn } from '@kbn/utility-types'; @@ -717,6 +718,8 @@ export interface IInterpreterRenderHandlers { // (undocumented) reload: () => void; // (undocumented) + uiState?: PersistedState; + // (undocumented) update: (params: any) => void; } diff --git a/src/plugins/vis_type_table/public/__snapshots__/table_vis_fn.test.ts.snap b/src/plugins/vis_type_table/public/__snapshots__/table_vis_fn.test.ts.snap index dc6571de969f02..a32609c2e3d342 100644 --- a/src/plugins/vis_type_table/public/__snapshots__/table_vis_fn.test.ts.snap +++ b/src/plugins/vis_type_table/public/__snapshots__/table_vis_fn.test.ts.snap @@ -2,12 +2,9 @@ exports[`interpreter/functions#table returns an object with the correct structure 1`] = ` Object { - "as": "visualization", + "as": "table_vis", "type": "render", "value": Object { - "params": Object { - "listenOnChange": true, - }, "visConfig": Object { "dimensions": Object { "buckets": Array [], diff --git a/src/plugins/vis_type_table/public/__snapshots__/to_ast.test.ts.snap b/src/plugins/vis_type_table/public/__snapshots__/to_ast.test.ts.snap new file mode 100644 index 00000000000000..d2298e6fb3eb57 --- /dev/null +++ b/src/plugins/vis_type_table/public/__snapshots__/to_ast.test.ts.snap @@ -0,0 +1,74 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`table vis toExpressionAst function should match snapshot based on params & dimensions 1`] = ` +Object { + "chain": Array [ + Object { + "arguments": Object { + "aggConfigs": Array [ + "[]", + ], + "includeFormatHints": Array [ + false, + ], + "index": Array [ + "123", + ], + "metricsAtAllLevels": Array [ + false, + ], + "partialRows": Array [ + true, + ], + }, + "function": "esaggs", + "type": "function", + }, + Object { + "arguments": Object { + "visConfig": Array [ + "{\\"perPage\\":20,\\"percentageCol\\":\\"Count\\",\\"showMetricsAtAllLevels\\":true,\\"showPartialRows\\":true,\\"showTotal\\":true,\\"sort\\":{\\"columnIndex\\":null,\\"direction\\":null},\\"totalFunc\\":\\"sum\\",\\"dimensions\\":{\\"metrics\\":[{\\"accessor\\":1,\\"format\\":{\\"id\\":\\"number\\"},\\"params\\":{},\\"label\\":\\"Count\\",\\"aggType\\":\\"count\\"}],\\"buckets\\":[{\\"accessor\\":0,\\"format\\":{\\"id\\":\\"date\\",\\"params\\":{\\"pattern\\":\\"YYYY-MM-DD HH:mm\\"}},\\"params\\":{},\\"label\\":\\"order_date per 3 hours\\",\\"aggType\\":\\"date_histogram\\"}]}}", + ], + }, + "function": "kibana_table", + "type": "function", + }, + ], + "type": "expression", +} +`; + +exports[`table vis toExpressionAst function should match snapshot without params 1`] = ` +Object { + "chain": Array [ + Object { + "arguments": Object { + "aggConfigs": Array [ + "[]", + ], + "includeFormatHints": Array [ + false, + ], + "index": Array [ + "123", + ], + "metricsAtAllLevels": Array [ + false, + ], + }, + "function": "esaggs", + "type": "function", + }, + Object { + "arguments": Object { + "visConfig": Array [ + "{\\"showLabel\\":false,\\"dimensions\\":{\\"metrics\\":[{\\"accessor\\":1,\\"format\\":{\\"id\\":\\"number\\"},\\"params\\":{},\\"label\\":\\"Count\\",\\"aggType\\":\\"count\\"}],\\"buckets\\":[{\\"accessor\\":0,\\"format\\":{\\"id\\":\\"date\\",\\"params\\":{\\"pattern\\":\\"YYYY-MM-DD HH:mm\\"}},\\"params\\":{},\\"label\\":\\"order_date per 3 hours\\",\\"aggType\\":\\"date_histogram\\"}]}}", + ], + }, + "function": "kibana_table", + "type": "function", + }, + ], + "type": "expression", +} +`; diff --git a/src/plugins/vis_type_table/public/index.ts b/src/plugins/vis_type_table/public/index.ts index 5621fdb0947724..6493c967165dbb 100644 --- a/src/plugins/vis_type_table/public/index.ts +++ b/src/plugins/vis_type_table/public/index.ts @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ -import './index.scss'; import { PluginInitializerContext } from 'kibana/public'; import { TableVisPlugin as Plugin } from './plugin'; diff --git a/src/plugins/vis_type_table/public/_table_vis.scss b/src/plugins/vis_type_table/public/legacy/_table_vis.scss similarity index 91% rename from src/plugins/vis_type_table/public/_table_vis.scss rename to src/plugins/vis_type_table/public/legacy/_table_vis.scss index 8a36b9818c2a3b..fa12ef9a1cf39e 100644 --- a/src/plugins/vis_type_table/public/_table_vis.scss +++ b/src/plugins/vis_type_table/public/legacy/_table_vis.scss @@ -4,8 +4,10 @@ .table-vis { display: flex; flex-direction: column; - flex: 1 0 100%; + flex: 1 1 0; overflow: auto; + + @include euiScrollBar; } .table-vis-container { diff --git a/src/plugins/vis_type_table/public/agg_table/_agg_table.scss b/src/plugins/vis_type_table/public/legacy/agg_table/_agg_table.scss similarity index 100% rename from src/plugins/vis_type_table/public/agg_table/_agg_table.scss rename to src/plugins/vis_type_table/public/legacy/agg_table/_agg_table.scss diff --git a/src/plugins/vis_type_table/public/agg_table/_index.scss b/src/plugins/vis_type_table/public/legacy/agg_table/_index.scss similarity index 100% rename from src/plugins/vis_type_table/public/agg_table/_index.scss rename to src/plugins/vis_type_table/public/legacy/agg_table/_index.scss diff --git a/src/plugins/vis_type_table/public/agg_table/agg_table.html b/src/plugins/vis_type_table/public/legacy/agg_table/agg_table.html similarity index 100% rename from src/plugins/vis_type_table/public/agg_table/agg_table.html rename to src/plugins/vis_type_table/public/legacy/agg_table/agg_table.html diff --git a/src/plugins/vis_type_table/public/agg_table/agg_table.js b/src/plugins/vis_type_table/public/legacy/agg_table/agg_table.js similarity index 99% rename from src/plugins/vis_type_table/public/agg_table/agg_table.js rename to src/plugins/vis_type_table/public/legacy/agg_table/agg_table.js index 1e98a06c2a6a99..a9ec431e9d940e 100644 --- a/src/plugins/vis_type_table/public/agg_table/agg_table.js +++ b/src/plugins/vis_type_table/public/legacy/agg_table/agg_table.js @@ -17,9 +17,9 @@ * under the License. */ import _ from 'lodash'; -import { CSV_SEPARATOR_SETTING, CSV_QUOTE_VALUES_SETTING } from '../../../share/public'; +import { CSV_SEPARATOR_SETTING, CSV_QUOTE_VALUES_SETTING } from '../../../../share/public'; import aggTableTemplate from './agg_table.html'; -import { getFormatService } from '../services'; +import { getFormatService } from '../../services'; import { i18n } from '@kbn/i18n'; export function KbnAggTable(config, RecursionHelper) { diff --git a/src/plugins/vis_type_table/public/agg_table/agg_table.test.js b/src/plugins/vis_type_table/public/legacy/agg_table/agg_table.test.js similarity index 97% rename from src/plugins/vis_type_table/public/agg_table/agg_table.test.js rename to src/plugins/vis_type_table/public/legacy/agg_table/agg_table.test.js index 29a10151a9418b..c93fb4f8bd5684 100644 --- a/src/plugins/vis_type_table/public/agg_table/agg_table.test.js +++ b/src/plugins/vis_type_table/public/legacy/agg_table/agg_table.test.js @@ -24,14 +24,14 @@ import 'angular-mocks'; import sinon from 'sinon'; import { round } from 'lodash'; -import { getFieldFormatsRegistry } from '../../../data/public/test_utils'; -import { coreMock } from '../../../../core/public/mocks'; -import { initAngularBootstrap } from '../../../kibana_legacy/public'; -import { setUiSettings } from '../../../data/public/services'; -import { UI_SETTINGS } from '../../../data/public/'; -import { CSV_SEPARATOR_SETTING, CSV_QUOTE_VALUES_SETTING } from '../../../share/public'; - -import { setFormatService } from '../services'; +import { getFieldFormatsRegistry } from '../../../../data/public/test_utils'; +import { coreMock } from '../../../../../core/public/mocks'; +import { initAngularBootstrap } from '../../../../kibana_legacy/public'; +import { setUiSettings } from '../../../../data/public/services'; +import { UI_SETTINGS } from '../../../../data/public/'; +import { CSV_SEPARATOR_SETTING, CSV_QUOTE_VALUES_SETTING } from '../../../../share/public'; + +import { setFormatService } from '../../services'; import { getInnerAngular } from '../get_inner_angular'; import { initTableVisLegacyModule } from '../table_vis_legacy_module'; import { tabifiedData } from './tabified_data'; diff --git a/src/plugins/vis_type_table/public/agg_table/agg_table_group.html b/src/plugins/vis_type_table/public/legacy/agg_table/agg_table_group.html similarity index 100% rename from src/plugins/vis_type_table/public/agg_table/agg_table_group.html rename to src/plugins/vis_type_table/public/legacy/agg_table/agg_table_group.html diff --git a/src/plugins/vis_type_table/public/agg_table/agg_table_group.js b/src/plugins/vis_type_table/public/legacy/agg_table/agg_table_group.js similarity index 100% rename from src/plugins/vis_type_table/public/agg_table/agg_table_group.js rename to src/plugins/vis_type_table/public/legacy/agg_table/agg_table_group.js diff --git a/src/plugins/vis_type_table/public/agg_table/agg_table_group.test.js b/src/plugins/vis_type_table/public/legacy/agg_table/agg_table_group.test.js similarity index 92% rename from src/plugins/vis_type_table/public/agg_table/agg_table_group.test.js rename to src/plugins/vis_type_table/public/legacy/agg_table/agg_table_group.test.js index 04cf624331d819..833f51b446ac18 100644 --- a/src/plugins/vis_type_table/public/agg_table/agg_table_group.test.js +++ b/src/plugins/vis_type_table/public/legacy/agg_table/agg_table_group.test.js @@ -22,11 +22,11 @@ import angular from 'angular'; import 'angular-mocks'; import expect from '@kbn/expect'; -import { getFieldFormatsRegistry } from '../../../data/public/test_utils'; -import { coreMock } from '../../../../core/public/mocks'; -import { initAngularBootstrap } from '../../../kibana_legacy/public'; -import { setUiSettings } from '../../../data/public/services'; -import { setFormatService } from '../services'; +import { getFieldFormatsRegistry } from '../../../../data/public/test_utils'; +import { coreMock } from '../../../../../core/public/mocks'; +import { initAngularBootstrap } from '../../../../kibana_legacy/public'; +import { setUiSettings } from '../../../../data/public/services'; +import { setFormatService } from '../../services'; import { getInnerAngular } from '../get_inner_angular'; import { initTableVisLegacyModule } from '../table_vis_legacy_module'; import { tabifiedData } from './tabified_data'; diff --git a/src/plugins/vis_type_table/public/agg_table/tabified_data.js b/src/plugins/vis_type_table/public/legacy/agg_table/tabified_data.js similarity index 100% rename from src/plugins/vis_type_table/public/agg_table/tabified_data.js rename to src/plugins/vis_type_table/public/legacy/agg_table/tabified_data.js diff --git a/src/plugins/vis_type_table/public/get_inner_angular.ts b/src/plugins/vis_type_table/public/legacy/get_inner_angular.ts similarity index 98% rename from src/plugins/vis_type_table/public/get_inner_angular.ts rename to src/plugins/vis_type_table/public/legacy/get_inner_angular.ts index 4e4269a1f44f47..f3d88a2a217b3c 100644 --- a/src/plugins/vis_type_table/public/get_inner_angular.ts +++ b/src/plugins/vis_type_table/public/legacy/get_inner_angular.ts @@ -33,7 +33,7 @@ import { PrivateProvider, watchMultiDecorator, KbnAccessibleClickProvider, -} from '../../kibana_legacy/public'; +} from '../../../kibana_legacy/public'; initAngularBootstrap(); diff --git a/src/plugins/vis_type_table/public/index.scss b/src/plugins/vis_type_table/public/legacy/index.scss similarity index 100% rename from src/plugins/vis_type_table/public/index.scss rename to src/plugins/vis_type_table/public/legacy/index.scss diff --git a/src/plugins/vis_type_table/public/paginated_table/_index.scss b/src/plugins/vis_type_table/public/legacy/paginated_table/_index.scss similarity index 100% rename from src/plugins/vis_type_table/public/paginated_table/_index.scss rename to src/plugins/vis_type_table/public/legacy/paginated_table/_index.scss diff --git a/src/plugins/vis_type_table/public/paginated_table/_table_cell_filter.scss b/src/plugins/vis_type_table/public/legacy/paginated_table/_table_cell_filter.scss similarity index 100% rename from src/plugins/vis_type_table/public/paginated_table/_table_cell_filter.scss rename to src/plugins/vis_type_table/public/legacy/paginated_table/_table_cell_filter.scss diff --git a/src/plugins/vis_type_table/public/paginated_table/paginated_table.html b/src/plugins/vis_type_table/public/legacy/paginated_table/paginated_table.html similarity index 100% rename from src/plugins/vis_type_table/public/paginated_table/paginated_table.html rename to src/plugins/vis_type_table/public/legacy/paginated_table/paginated_table.html diff --git a/src/plugins/vis_type_table/public/paginated_table/paginated_table.js b/src/plugins/vis_type_table/public/legacy/paginated_table/paginated_table.js similarity index 100% rename from src/plugins/vis_type_table/public/paginated_table/paginated_table.js rename to src/plugins/vis_type_table/public/legacy/paginated_table/paginated_table.js diff --git a/src/plugins/vis_type_table/public/paginated_table/paginated_table.test.ts b/src/plugins/vis_type_table/public/legacy/paginated_table/paginated_table.test.ts similarity index 98% rename from src/plugins/vis_type_table/public/paginated_table/paginated_table.test.ts rename to src/plugins/vis_type_table/public/legacy/paginated_table/paginated_table.test.ts index de253f26ff9e71..3bc5f79557041a 100644 --- a/src/plugins/vis_type_table/public/paginated_table/paginated_table.test.ts +++ b/src/plugins/vis_type_table/public/legacy/paginated_table/paginated_table.test.ts @@ -25,11 +25,7 @@ import 'angular-mocks'; import { getAngularModule } from '../get_inner_angular'; import { initTableVisLegacyModule } from '../table_vis_legacy_module'; -import { coreMock } from '../../../../core/public/mocks'; - -jest.mock('../../../kibana_legacy/public/angular/angular_config', () => ({ - configureAppAngularModule: () => {}, -})); +import { coreMock } from '../../../../../core/public/mocks'; interface Sort { columnIndex: number; diff --git a/src/plugins/vis_type_table/public/paginated_table/rows.js b/src/plugins/vis_type_table/public/legacy/paginated_table/rows.js similarity index 91% rename from src/plugins/vis_type_table/public/paginated_table/rows.js rename to src/plugins/vis_type_table/public/legacy/paginated_table/rows.js index d8f01a10c63fa7..54e754adcc1708 100644 --- a/src/plugins/vis_type_table/public/paginated_table/rows.js +++ b/src/plugins/vis_type_table/public/legacy/paginated_table/rows.js @@ -44,15 +44,18 @@ export function KbnRows($compile) { } $scope.filter({ - data: [ - { - table: $scope.table, - row: $scope.rows.findIndex((r) => r === row), - column: $scope.table.columns.findIndex((c) => c.id === column.id), - value, - }, - ], - negate, + name: 'filterBucket', + data: { + data: [ + { + table: $scope.table, + row: $scope.rows.findIndex((r) => r === row), + column: $scope.table.columns.findIndex((c) => c.id === column.id), + value, + }, + ], + negate, + }, }); }; diff --git a/src/plugins/vis_type_table/public/paginated_table/table_cell_filter.html b/src/plugins/vis_type_table/public/legacy/paginated_table/table_cell_filter.html similarity index 100% rename from src/plugins/vis_type_table/public/paginated_table/table_cell_filter.html rename to src/plugins/vis_type_table/public/legacy/paginated_table/table_cell_filter.html diff --git a/src/plugins/vis_type_table/public/table_vis.html b/src/plugins/vis_type_table/public/legacy/table_vis.html similarity index 96% rename from src/plugins/vis_type_table/public/table_vis.html rename to src/plugins/vis_type_table/public/legacy/table_vis.html index f721b670400d66..c469cd250755cc 100644 --- a/src/plugins/vis_type_table/public/table_vis.html +++ b/src/plugins/vis_type_table/public/legacy/table_vis.html @@ -15,7 +15,7 @@
({ - configureAppAngularModule: () => {}, -})); - interface TableVisScope extends IScope { [key: string]: any; } @@ -112,10 +107,6 @@ describe('Table Vis - Controller', () => { coreMock.createSetup() ); }); - const tableVisTypeDefinition = getTableVisTypeDefinition( - coreMock.createSetup(), - coreMock.createPluginInitializerContext() - ); function getRangeVis(params?: object) { return ({ diff --git a/src/plugins/vis_type_table/public/table_vis_legacy_module.ts b/src/plugins/vis_type_table/public/legacy/table_vis_legacy_module.ts similarity index 100% rename from src/plugins/vis_type_table/public/table_vis_legacy_module.ts rename to src/plugins/vis_type_table/public/legacy/table_vis_legacy_module.ts diff --git a/src/plugins/vis_type_table/public/legacy/table_vis_legacy_renderer.tsx b/src/plugins/vis_type_table/public/legacy/table_vis_legacy_renderer.tsx new file mode 100644 index 00000000000000..ab633bd5137bae --- /dev/null +++ b/src/plugins/vis_type_table/public/legacy/table_vis_legacy_renderer.tsx @@ -0,0 +1,53 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { CoreSetup, PluginInitializerContext } from 'kibana/public'; +import { ExpressionRenderDefinition } from 'src/plugins/expressions'; +import { TablePluginStartDependencies } from '../plugin'; +import { TableVisRenderValue } from '../table_vis_fn'; +import { TableVisLegacyController } from './vis_controller'; + +const tableVisRegistry = new Map(); + +export const getTableVisLegacyRenderer: ( + core: CoreSetup, + context: PluginInitializerContext +) => ExpressionRenderDefinition = (core, context) => ({ + name: 'table_vis', + reuseDomNode: true, + render: async (domNode, config, handlers) => { + let registeredController = tableVisRegistry.get(domNode); + + if (!registeredController) { + const { getTableVisualizationControllerClass } = await import('./vis_controller'); + + const Controller = getTableVisualizationControllerClass(core, context); + registeredController = new Controller(domNode); + tableVisRegistry.set(domNode, registeredController); + + handlers.onDestroy(() => { + registeredController?.destroy(); + tableVisRegistry.delete(domNode); + }); + } + + await registeredController.render(config.visData, config.visConfig, handlers); + handlers.done(); + }, +}); diff --git a/src/plugins/vis_type_table/public/vis_controller.ts b/src/plugins/vis_type_table/public/legacy/vis_controller.ts similarity index 68% rename from src/plugins/vis_type_table/public/vis_controller.ts rename to src/plugins/vis_type_table/public/legacy/vis_controller.ts index 1781808660260e..eff8e34f3e7785 100644 --- a/src/plugins/vis_type_table/public/vis_controller.ts +++ b/src/plugins/vis_type_table/public/legacy/vis_controller.ts @@ -20,35 +20,43 @@ import { CoreSetup, PluginInitializerContext } from 'kibana/public'; import angular, { IModule, auto, IRootScopeService, IScope, ICompileService } from 'angular'; import $ from 'jquery'; -import { VisParams, ExprVis } from '../../visualizations/public'; +import './index.scss'; + +import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; import { getAngularModule } from './get_inner_angular'; -import { getKibanaLegacy } from './services'; import { initTableVisLegacyModule } from './table_vis_legacy_module'; +// @ts-ignore +import tableVisTemplate from './table_vis.html'; +import { TablePluginStartDependencies } from '../plugin'; +import { TableVisConfig } from '../types'; +import { TableContext } from '../table_vis_response_handler'; const innerAngularName = 'kibana/table_vis'; +export type TableVisLegacyController = InstanceType< + ReturnType +>; + export function getTableVisualizationControllerClass( - core: CoreSetup, + core: CoreSetup, context: PluginInitializerContext ) { return class TableVisualizationController { private tableVisModule: IModule | undefined; private injector: auto.IInjectorService | undefined; el: JQuery; - vis: ExprVis; $rootScope: IRootScopeService | null = null; $scope: (IScope & { [key: string]: any }) | undefined; $compile: ICompileService | undefined; - constructor(domeElement: Element, vis: ExprVis) { + constructor(domeElement: Element) { this.el = $(domeElement); - this.vis = vis; } getInjector() { if (!this.injector) { const mountpoint = document.createElement('div'); - mountpoint.setAttribute('style', 'height: 100%; width: 100%;'); + mountpoint.className = 'visualization'; this.injector = angular.bootstrap(mountpoint, [innerAngularName]); this.el.append(mountpoint); } @@ -58,14 +66,18 @@ export function getTableVisualizationControllerClass( async initLocalAngular() { if (!this.tableVisModule) { - const [coreStart] = await core.getStartServices(); + const [coreStart, { kibanaLegacy }] = await core.getStartServices(); this.tableVisModule = getAngularModule(innerAngularName, coreStart, context); initTableVisLegacyModule(this.tableVisModule); + kibanaLegacy.loadFontAwesome(); } } - async render(esResponse: object, visParams: VisParams): Promise { - getKibanaLegacy().loadFontAwesome(); + async render( + esResponse: TableContext, + visParams: TableVisConfig, + handlers: IInterpreterRenderHandlers + ): Promise { await this.initLocalAngular(); return new Promise(async (resolve, reject) => { @@ -79,16 +91,6 @@ export function getTableVisualizationControllerClass( return; } - // How things get into this $scope? - // To inject variables into this $scope there's the following pipeline of stuff to check: - // - visualize_embeddable => that's what the editor creates to wrap this Angular component - // - build_pipeline => it serialize all the params into an Angular template compiled on the fly - // - table_vis_fn => unserialize the params and prepare them for the final React/Angular bridge - // - visualization_renderer => creates the wrapper component for this controller and passes the params - // - // In case some prop is missing check into the top of the chain if they are available and check - // the list above that it is passing through - this.$scope.vis = this.vis; this.$scope.visState = { params: visParams, title: visParams.title }; this.$scope.esResponse = esResponse; @@ -101,11 +103,10 @@ export function getTableVisualizationControllerClass( if (!this.$scope && this.$compile) { this.$scope = this.$rootScope.$new(); - this.$scope.uiState = this.vis.getUiState(); + this.$scope.uiState = handlers.uiState; + this.$scope.filter = handlers.event; updateScope(); - this.el - .find('div') - .append(this.$compile(this.vis.type.visConfig?.template ?? '')(this.$scope)); + this.el.find('div').append(this.$compile(tableVisTemplate)(this.$scope)); this.$scope.$apply(); } else { updateScope(); diff --git a/src/plugins/vis_type_table/public/plugin.ts b/src/plugins/vis_type_table/public/plugin.ts index 28f823df79d919..35ef5fc831cb78 100644 --- a/src/plugins/vis_type_table/public/plugin.ts +++ b/src/plugins/vis_type_table/public/plugin.ts @@ -21,10 +21,11 @@ import { Plugin as ExpressionsPublicPlugin } from '../../expressions/public'; import { VisualizationsSetup } from '../../visualizations/public'; import { createTableVisFn } from './table_vis_fn'; -import { getTableVisTypeDefinition } from './table_vis_type'; +import { tableVisTypeDefinition } from './table_vis_type'; import { DataPublicPluginStart } from '../../data/public'; -import { setFormatService, setKibanaLegacy } from './services'; +import { setFormatService } from './services'; import { KibanaLegacyStart } from '../../kibana_legacy/public'; +import { getTableVisLegacyRenderer } from './legacy/table_vis_legacy_renderer'; /** @internal */ export interface TablePluginSetupDependencies { @@ -39,7 +40,9 @@ export interface TablePluginStartDependencies { } /** @internal */ -export class TableVisPlugin implements Plugin, void> { +export class TableVisPlugin + implements + Plugin, void, TablePluginSetupDependencies, TablePluginStartDependencies> { initializerContext: PluginInitializerContext; createBaseVisualization: any; @@ -48,17 +51,15 @@ export class TableVisPlugin implements Plugin, void> { } public async setup( - core: CoreSetup, + core: CoreSetup, { expressions, visualizations }: TablePluginSetupDependencies ) { expressions.registerFunction(createTableVisFn); - visualizations.createBaseVisualization( - getTableVisTypeDefinition(core, this.initializerContext) - ); + expressions.registerRenderer(getTableVisLegacyRenderer(core, this.initializerContext)); + visualizations.createBaseVisualization(tableVisTypeDefinition); } - public start(core: CoreStart, { data, kibanaLegacy }: TablePluginStartDependencies) { + public start(core: CoreStart, { data }: TablePluginStartDependencies) { setFormatService(data.fieldFormats); - setKibanaLegacy(kibanaLegacy); } } diff --git a/src/plugins/vis_type_table/public/services.ts b/src/plugins/vis_type_table/public/services.ts index b4f996f078f6be..3aaffe75e27f14 100644 --- a/src/plugins/vis_type_table/public/services.ts +++ b/src/plugins/vis_type_table/public/services.ts @@ -19,12 +19,7 @@ import { createGetterSetter } from '../../kibana_utils/public'; import { DataPublicPluginStart } from '../../data/public'; -import { KibanaLegacyStart } from '../../kibana_legacy/public'; export const [getFormatService, setFormatService] = createGetterSetter< DataPublicPluginStart['fieldFormats'] >('table data.fieldFormats'); - -export const [getKibanaLegacy, setKibanaLegacy] = createGetterSetter( - 'table kibanaLegacy' -); diff --git a/src/plugins/vis_type_table/public/table_vis_fn.ts b/src/plugins/vis_type_table/public/table_vis_fn.ts index 9739a7a284e6cf..2e446ba4e4fcf0 100644 --- a/src/plugins/vis_type_table/public/table_vis_fn.ts +++ b/src/plugins/vis_type_table/public/table_vis_fn.ts @@ -20,6 +20,7 @@ import { i18n } from '@kbn/i18n'; import { tableVisResponseHandler, TableContext } from './table_vis_response_handler'; import { ExpressionFunctionDefinition, KibanaDatatable, Render } from '../../expressions/public'; +import { TableVisConfig } from './types'; export type Input = KibanaDatatable; @@ -27,23 +28,20 @@ interface Arguments { visConfig: string | null; } -type VisParams = Required; - -interface RenderValue { +export interface TableVisRenderValue { visData: TableContext; visType: 'table'; - visConfig: VisParams; - params: { - listenOnChange: boolean; - }; + visConfig: TableVisConfig; } -export const createTableVisFn = (): ExpressionFunctionDefinition< +export type TableExpressionFunctionDefinition = ExpressionFunctionDefinition< 'kibana_table', Input, Arguments, - Render -> => ({ + Render +>; + +export const createTableVisFn = (): TableExpressionFunctionDefinition => ({ name: 'kibana_table', type: 'render', inputTypes: ['kibana_datatable'], @@ -63,14 +61,11 @@ export const createTableVisFn = (): ExpressionFunctionDefinition< return { type: 'render', - as: 'visualization', + as: 'table_vis', value: { visData: convertedData, visType: 'table', visConfig, - params: { - listenOnChange: true, - }, }, }; }, diff --git a/src/plugins/vis_type_table/public/table_vis_type.ts b/src/plugins/vis_type_table/public/table_vis_type.ts index 95f4f06ee6111c..bfc7abac02895a 100644 --- a/src/plugins/vis_type_table/public/table_vis_type.ts +++ b/src/plugins/vis_type_table/public/table_vis_type.ts @@ -16,91 +16,82 @@ * specific language governing permissions and limitations * under the License. */ -import { CoreSetup, PluginInitializerContext } from 'kibana/public'; import { i18n } from '@kbn/i18n'; import { AggGroupNames } from '../../data/public'; import { Schemas } from '../../vis_default_editor/public'; import { BaseVisTypeOptions } from '../../visualizations/public'; -import { tableVisResponseHandler } from './table_vis_response_handler'; -// @ts-ignore -import tableVisTemplate from './table_vis.html'; + import { TableOptions } from './components/table_vis_options_lazy'; -import { getTableVisualizationControllerClass } from './vis_controller'; import { VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public'; +import { toExpressionAst } from './to_ast'; +import { TableVisParams } from './types'; -export function getTableVisTypeDefinition( - core: CoreSetup, - context: PluginInitializerContext -): BaseVisTypeOptions { - return { - name: 'table', - title: i18n.translate('visTypeTable.tableVisTitle', { - defaultMessage: 'Data Table', - }), - icon: 'visTable', - description: i18n.translate('visTypeTable.tableVisDescription', { - defaultMessage: 'Display values in a table', - }), - visualization: getTableVisualizationControllerClass(core, context), - getSupportedTriggers: () => { - return [VIS_EVENT_TO_TRIGGER.filter]; - }, - visConfig: { - defaults: { - perPage: 10, - showPartialRows: false, - showMetricsAtAllLevels: false, - sort: { - columnIndex: null, - direction: null, - }, - showTotal: false, - totalFunc: 'sum', - percentageCol: '', +export const tableVisTypeDefinition: BaseVisTypeOptions = { + name: 'table', + title: i18n.translate('visTypeTable.tableVisTitle', { + defaultMessage: 'Data Table', + }), + icon: 'visTable', + description: i18n.translate('visTypeTable.tableVisDescription', { + defaultMessage: 'Display values in a table', + }), + getSupportedTriggers: () => { + return [VIS_EVENT_TO_TRIGGER.filter]; + }, + visConfig: { + defaults: { + perPage: 10, + showPartialRows: false, + showMetricsAtAllLevels: false, + sort: { + columnIndex: null, + direction: null, }, - template: tableVisTemplate, + showTotal: false, + totalFunc: 'sum', + percentageCol: '', }, - editorConfig: { - optionsTemplate: TableOptions, - schemas: new Schemas([ - { - group: AggGroupNames.Metrics, - name: 'metric', - title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.metricTitle', { - defaultMessage: 'Metric', - }), - aggFilter: ['!geo_centroid', '!geo_bounds'], - aggSettings: { - top_hits: { - allowStrings: true, - }, + }, + editorConfig: { + optionsTemplate: TableOptions, + schemas: new Schemas([ + { + group: AggGroupNames.Metrics, + name: 'metric', + title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.metricTitle', { + defaultMessage: 'Metric', + }), + aggFilter: ['!geo_centroid', '!geo_bounds'], + aggSettings: { + top_hits: { + allowStrings: true, }, - min: 1, - defaults: [{ type: 'count', schema: 'metric' }], - }, - { - group: AggGroupNames.Buckets, - name: 'bucket', - title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.bucketTitle', { - defaultMessage: 'Split rows', - }), - aggFilter: ['!filter'], - }, - { - group: AggGroupNames.Buckets, - name: 'split', - title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.splitTitle', { - defaultMessage: 'Split table', - }), - min: 0, - max: 1, - aggFilter: ['!filter'], }, - ]), - }, - responseHandler: tableVisResponseHandler, - hierarchicalData: (vis) => { - return Boolean(vis.params.showPartialRows || vis.params.showMetricsAtAllLevels); - }, - }; -} + min: 1, + defaults: [{ type: 'count', schema: 'metric' }], + }, + { + group: AggGroupNames.Buckets, + name: 'bucket', + title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.bucketTitle', { + defaultMessage: 'Split rows', + }), + aggFilter: ['!filter'], + }, + { + group: AggGroupNames.Buckets, + name: 'split', + title: i18n.translate('visTypeTable.tableVisEditorConfig.schemas.splitTitle', { + defaultMessage: 'Split table', + }), + min: 0, + max: 1, + aggFilter: ['!filter'], + }, + ]), + }, + toExpressionAst, + hierarchicalData: (vis) => { + return Boolean(vis.params.showPartialRows || vis.params.showMetricsAtAllLevels); + }, +}; diff --git a/src/plugins/vis_type_table/public/to_ast.test.ts b/src/plugins/vis_type_table/public/to_ast.test.ts new file mode 100644 index 00000000000000..045b5814944b02 --- /dev/null +++ b/src/plugins/vis_type_table/public/to_ast.test.ts @@ -0,0 +1,79 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { Vis } from 'src/plugins/visualizations/public'; +import { toExpressionAst } from './to_ast'; +import { AggTypes, TableVisParams } from './types'; + +const mockSchemas = { + metric: [{ accessor: 1, format: { id: 'number' }, params: {}, label: 'Count', aggType: 'count' }], + bucket: [ + { + accessor: 0, + format: { id: 'date', params: { pattern: 'YYYY-MM-DD HH:mm' } }, + params: {}, + label: 'order_date per 3 hours', + aggType: 'date_histogram', + }, + ], +}; + +jest.mock('../../visualizations/public', () => ({ + getVisSchemas: () => mockSchemas, +})); + +describe('table vis toExpressionAst function', () => { + let vis: Vis; + + beforeEach(() => { + vis = { + isHierarchical: () => false, + type: {}, + params: { + showLabel: false, + }, + data: { + indexPattern: { id: '123' }, + aggs: { + getResponseAggs: () => [], + aggs: [], + }, + }, + } as any; + }); + + it('should match snapshot without params', () => { + const actual = toExpressionAst(vis, {} as any); + expect(actual).toMatchSnapshot(); + }); + + it('should match snapshot based on params & dimensions', () => { + vis.params = { + perPage: 20, + percentageCol: 'Count', + showMetricsAtAllLevels: true, + showPartialRows: true, + showTotal: true, + sort: { columnIndex: null, direction: null }, + totalFunc: AggTypes.SUM, + }; + const actual = toExpressionAst(vis, {} as any); + expect(actual).toMatchSnapshot(); + }); +}); diff --git a/src/plugins/vis_type_table/public/to_ast.ts b/src/plugins/vis_type_table/public/to_ast.ts new file mode 100644 index 00000000000000..449e2dde7f7c96 --- /dev/null +++ b/src/plugins/vis_type_table/public/to_ast.ts @@ -0,0 +1,74 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { EsaggsExpressionFunctionDefinition } from '../../data/common/search/expressions'; +import { buildExpression, buildExpressionFunction } from '../../expressions/public'; +import { getVisSchemas, Vis, BuildPipelineParams } from '../../visualizations/public'; +import { TableExpressionFunctionDefinition } from './table_vis_fn'; +import { TableVisConfig, TableVisParams } from './types'; + +const buildTableVisConfig = ( + schemas: ReturnType, + visParams: TableVisParams +) => { + const visConfig = {} as any; + const metrics = schemas.metric; + const buckets = schemas.bucket || []; + visConfig.dimensions = { + metrics, + buckets, + splitRow: schemas.split_row, + splitColumn: schemas.split_column, + }; + + if (visParams.showPartialRows && !visParams.showMetricsAtAllLevels) { + // Handle case where user wants to see partial rows but not metrics at all levels. + // This requires calculating how many metrics will come back in the tabified response, + // and removing all metrics from the dimensions except the last set. + const metricsPerBucket = metrics.length / buckets.length; + visConfig.dimensions.metrics.splice(0, metricsPerBucket * buckets.length - metricsPerBucket); + } + return visConfig; +}; + +export const toExpressionAst = (vis: Vis, params: BuildPipelineParams) => { + const esaggs = buildExpressionFunction('esaggs', { + index: vis.data.indexPattern!.id!, + metricsAtAllLevels: vis.isHierarchical(), + partialRows: vis.params.showPartialRows, + aggConfigs: JSON.stringify(vis.data.aggs!.aggs), + includeFormatHints: false, + }); + + const schemas = getVisSchemas(vis, params); + + const visConfig: TableVisConfig = { + ...vis.params, + ...buildTableVisConfig(schemas, vis.params), + title: vis.title, + }; + + const table = buildExpressionFunction('kibana_table', { + visConfig: JSON.stringify(visConfig), + }); + + const ast = buildExpression([esaggs, table]); + + return ast.toAst(); +}; diff --git a/src/plugins/vis_type_table/public/types.ts b/src/plugins/vis_type_table/public/types.ts index 39023d1305cb63..c0a995ad5da699 100644 --- a/src/plugins/vis_type_table/public/types.ts +++ b/src/plugins/vis_type_table/public/types.ts @@ -33,7 +33,6 @@ export interface Dimensions { } export interface TableVisParams { - type: 'table'; perPage: number | ''; showPartialRows: boolean; showMetricsAtAllLevels: boolean; @@ -44,5 +43,9 @@ export interface TableVisParams { showTotal: boolean; totalFunc: AggTypes; percentageCol: string; +} + +export interface TableVisConfig extends TableVisParams { + title: string; dimensions: Dimensions; } diff --git a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap index c0c37e2262f9c6..cbdecd4aac747a 100644 --- a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap +++ b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap @@ -12,16 +12,6 @@ exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunct exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles region_map function without buckets 1`] = `"regionmap visConfig='{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"}}' "`; -exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles table function with showPartialRows=true and showMetricsAtAllLevels=false 1`] = `"kibana_table visConfig='{\\"showMetricsAtAllLevels\\":false,\\"showPartialRows\\":true,\\"dimensions\\":{\\"metrics\\":[{\\"accessor\\":4,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},{\\"accessor\\":5,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"}],\\"buckets\\":[0,3]}}' "`; - -exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles table function with showPartialRows=true and showMetricsAtAllLevels=true 1`] = `"kibana_table visConfig='{\\"showMetricsAtAllLevels\\":true,\\"showPartialRows\\":true,\\"dimensions\\":{\\"metrics\\":[{\\"accessor\\":1,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},{\\"accessor\\":2,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},{\\"accessor\\":4,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},{\\"accessor\\":5,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"}],\\"buckets\\":[0,3]}}' "`; - -exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles table function with splits 1`] = `"kibana_table visConfig='{\\"foo\\":\\"bar\\",\\"dimensions\\":{\\"metrics\\":[{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"}],\\"buckets\\":[],\\"splitRow\\":[1,2]}}' "`; - -exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles table function with splits and buckets 1`] = `"kibana_table visConfig='{\\"foo\\":\\"bar\\",\\"dimensions\\":{\\"metrics\\":[{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},{\\"accessor\\":1,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"}],\\"buckets\\":[3],\\"splitRow\\":[2,4]}}' "`; - -exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles table function without splits or buckets 1`] = `"kibana_table visConfig='{\\"foo\\":\\"bar\\",\\"dimensions\\":{\\"metrics\\":[{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},{\\"accessor\\":1,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"}],\\"buckets\\":[]}}' "`; - exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles tile_map function 1`] = `"tilemap visConfig='{\\"metric\\":{},\\"dimensions\\":{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},\\"geohash\\":1,\\"geocentroid\\":3}}' "`; exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles vega function 1`] = `"vega spec='this is a test' "`; diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts index a1fea45f517816..c744043ed155b0 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts @@ -117,84 +117,6 @@ describe('visualize loader pipeline helpers: build pipeline', () => { expect(actual).toMatchSnapshot(); }); - describe('handles table function', () => { - it('without splits or buckets', () => { - const params = { foo: 'bar' }; - const schemas = { - ...schemasDef, - metric: [ - { ...schemaConfig, accessor: 0 }, - { ...schemaConfig, accessor: 1 }, - ], - }; - const actual = buildPipelineVisFunction.table(params, schemas, uiState); - expect(actual).toMatchSnapshot(); - }); - - it('with splits', () => { - const params = { foo: 'bar' }; - const schemas = { - ...schemasDef, - split_row: [1, 2], - }; - const actual = buildPipelineVisFunction.table(params, schemas, uiState); - expect(actual).toMatchSnapshot(); - }); - - it('with splits and buckets', () => { - const params = { foo: 'bar' }; - const schemas = { - ...schemasDef, - metric: [ - { ...schemaConfig, accessor: 0 }, - { ...schemaConfig, accessor: 1 }, - ], - split_row: [2, 4], - bucket: [3], - }; - const actual = buildPipelineVisFunction.table(params, schemas, uiState); - expect(actual).toMatchSnapshot(); - }); - - it('with showPartialRows=true and showMetricsAtAllLevels=true', () => { - const params = { - showMetricsAtAllLevels: true, - showPartialRows: true, - }; - const schemas = { - ...schemasDef, - metric: [ - { ...schemaConfig, accessor: 1 }, - { ...schemaConfig, accessor: 2 }, - { ...schemaConfig, accessor: 4 }, - { ...schemaConfig, accessor: 5 }, - ], - bucket: [0, 3], - }; - const actual = buildPipelineVisFunction.table(params, schemas, uiState); - expect(actual).toMatchSnapshot(); - }); - - it('with showPartialRows=true and showMetricsAtAllLevels=false', () => { - const params = { - showMetricsAtAllLevels: false, - showPartialRows: true, - }; - const schemas = { - ...schemasDef, - metric: [ - { ...schemaConfig, accessor: 1 }, - { ...schemaConfig, accessor: 2 }, - { ...schemaConfig, accessor: 4 }, - { ...schemaConfig, accessor: 5 }, - ], - bucket: [0, 3], - }; - const actual = buildPipelineVisFunction.table(params, schemas, uiState); - expect(actual).toMatchSnapshot(); - }); - }); - describe('handles region_map function', () => { it('without buckets', () => { const params = { metric: {} }; diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.ts b/src/plugins/visualizations/public/legacy/build_pipeline.ts index 9f6a4d55532928..eb431212166a3a 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.ts @@ -39,14 +39,14 @@ export interface SchemaConfig { export interface Schemas { metric: SchemaConfig[]; - bucket?: any[]; + bucket?: SchemaConfig[]; geo_centroid?: any[]; group?: any[]; params?: any[]; radius?: any[]; segment?: any[]; - split_column?: any[]; - split_row?: any[]; + split_column?: SchemaConfig[]; + split_row?: SchemaConfig[]; width?: any[]; // catch all for schema name [key: string]: any[] | undefined; @@ -267,13 +267,6 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = { const paramsArray = [paramsJson, uiStateJson].filter((param) => Boolean(param)); return `tsvb ${paramsArray.join(' ')}`; }, - table: (params, schemas) => { - const visConfig = { - ...params, - ...buildVisConfig.table(schemas, params), - }; - return `kibana_table ${prepareJson('visConfig', visConfig)}`; - }, region_map: (params, schemas) => { const visConfig = { ...params, @@ -298,26 +291,6 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = { }; const buildVisConfig: BuildVisConfigFunction = { - table: (schemas, visParams = {}) => { - const visConfig = {} as any; - const metrics = schemas.metric; - const buckets = schemas.bucket || []; - visConfig.dimensions = { - metrics, - buckets, - splitRow: schemas.split_row, - splitColumn: schemas.split_column, - }; - - if (visParams.showMetricsAtAllLevels === false && visParams.showPartialRows === true) { - // Handle case where user wants to see partial rows but not metrics at all levels. - // This requires calculating how many metrics will come back in the tabified response, - // and removing all metrics from the dimensions except the last set. - const metricsPerBucket = metrics.length / buckets.length; - visConfig.dimensions.metrics.splice(0, metricsPerBucket * buckets.length - metricsPerBucket); - } - return visConfig; - }, region_map: (schemas) => { const visConfig = {} as any; visConfig.metric = schemas.metric[0];