')
- .attr('ng-controller', 'OsdTableVisController')
- .attr('ng-init', 'newScope(this)');
-
- $compile($el)($rootScope);
- }
-
- // put a response into the controller
- function attachOpenSearchResponseToScope(resp: object) {
- $rootScope.opensearchResponse = resp;
- $rootScope.$apply();
- }
-
- // remove the response from the controller
- function removeOpenSearchResponseFromScope() {
- delete $rootScope.opensearchResponse;
- $rootScope.renderComplete = () => {};
- $rootScope.$apply();
- }
-
- test('exposes #tableGroups and #hasSomeRows when a response is attached to scope', async () => {
- const vis: Vis = getRangeVis();
- initController(vis);
-
- expect(!$scope.tableGroups).toBeTruthy();
- expect(!$scope.hasSomeRows).toBeTruthy();
-
- attachOpenSearchResponseToScope(await tableAggResponse(tabifiedResponse, dimensions));
-
- expect($scope.hasSomeRows).toBeTruthy();
- expect($scope.tableGroups.tables).toBeDefined();
- expect($scope.tableGroups.tables.length).toBe(1);
- expect($scope.tableGroups.tables[0].columns.length).toBe(2);
- expect($scope.tableGroups.tables[0].rows.length).toBe(2);
- });
-
- test('clears #tableGroups and #hasSomeRows when the response is removed', async () => {
- const vis = getRangeVis();
- initController(vis);
-
- attachOpenSearchResponseToScope(await tableAggResponse(tabifiedResponse, dimensions));
- removeOpenSearchResponseFromScope();
-
- expect(!$scope.hasSomeRows).toBeTruthy();
- expect(!$scope.tableGroups).toBeTruthy();
- });
-
- test('sets the sort on the scope when it is passed as a vis param', async () => {
- const sortObj = {
- columnIndex: 1,
- direction: 'asc',
- };
- const vis = getRangeVis({ sort: sortObj });
- initController(vis);
-
- attachOpenSearchResponseToScope(await tableAggResponse(tabifiedResponse, dimensions));
-
- expect($scope.sort.columnIndex).toEqual(sortObj.columnIndex);
- expect($scope.sort.direction).toEqual(sortObj.direction);
- });
-
- test('sets #hasSomeRows properly if the table group is empty', async () => {
- const vis = getRangeVis();
- initController(vis);
-
- tabifiedResponse.rows = [];
-
- attachOpenSearchResponseToScope(await tableAggResponse(tabifiedResponse, dimensions));
-
- expect($scope.hasSomeRows).toBeFalsy();
- expect(!$scope.tableGroups).toBeTruthy();
- });
-
- test('passes partialRows:true to tabify based on the vis params', () => {
- const vis = getRangeVis({ showPartialRows: true });
- initController(vis);
-
- expect((vis.type.hierarchicalData as Function)(vis)).toEqual(true);
- });
-
- test('passes partialRows:false to tabify based on the vis params', () => {
- const vis = getRangeVis({ showPartialRows: false });
- initController(vis);
-
- expect((vis.type.hierarchicalData as Function)(vis)).toEqual(false);
- });
-});
diff --git a/src/plugins/vis_type_table/public/table_vis_fn.test.ts b/src/plugins/vis_type_table/public/table_vis_fn.test.ts
deleted file mode 100644
index f7723456b757..000000000000
--- a/src/plugins/vis_type_table/public/table_vis_fn.test.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * 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 { createTableVisFn } from './table_vis_fn';
-import { tableVisResponseHandler } from './table_vis_response_handler';
-
-import { functionWrapper } from '../../expressions/common/expression_functions/specs/tests/utils';
-
-jest.mock('./table_vis_response_handler', () => ({
- tableVisResponseHandler: jest.fn().mockReturnValue({
- tables: [{ columns: [], rows: [] }],
- }),
-}));
-
-describe('interpreter/functions#table', () => {
- const fn = functionWrapper(createTableVisFn());
- const context = {
- type: 'opensearch_dashboards_datatable',
- rows: [{ 'col-0-1': 0 }],
- columns: [{ id: 'col-0-1', name: 'Count' }],
- };
- const visConfig = {
- title: 'My Chart title',
- perPage: 10,
- showPartialRows: false,
- showMetricsAtAllLevels: false,
- sort: {
- columnIndex: null,
- direction: null,
- },
- showTotal: false,
- totalFunc: 'sum',
- dimensions: {
- metrics: [
- {
- accessor: 0,
- format: {
- id: 'number',
- },
- params: {},
- aggType: 'count',
- },
- ],
- buckets: [],
- },
- };
-
- beforeEach(() => {
- jest.clearAllMocks();
- });
-
- it('returns an object with the correct structure', async () => {
- const actual = await fn(context, { visConfig: JSON.stringify(visConfig) }, undefined);
- expect(actual).toMatchSnapshot();
- });
-
- it('calls response handler with correct values', async () => {
- await fn(context, { visConfig: JSON.stringify(visConfig) }, undefined);
- expect(tableVisResponseHandler).toHaveBeenCalledTimes(1);
- expect(tableVisResponseHandler).toHaveBeenCalledWith(context, visConfig.dimensions);
- });
-});
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 daf76580b59f..4f0fb2c0ba1f 100644
--- a/src/plugins/vis_type_table/public/table_vis_fn.ts
+++ b/src/plugins/vis_type_table/public/table_vis_fn.ts
@@ -1,31 +1,6 @@
/*
+ * Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * 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 { i18n } from '@osd/i18n';
@@ -35,7 +10,7 @@ import {
OpenSearchDashboardsDatatable,
Render,
} from '../../expressions/public';
-import { VisRenderValue } from '../../visualizations/public';
+import { TableVisConfig } from './types';
export type Input = OpenSearchDashboardsDatatable;
@@ -43,17 +18,20 @@ interface Arguments {
visConfig: string | null;
}
-interface RenderValue extends VisRenderValue {
+export interface TableVisRenderValue {
visData: TableContext;
visType: 'table';
+ visConfig: TableVisConfig;
}
-export const createTableVisFn = (): ExpressionFunctionDefinition<
+export type TableVisExpressionFunctionDefinition = ExpressionFunctionDefinition<
'opensearch_dashboards_table',
Input,
Arguments,
- Render
-> => ({
+ Render
+>;
+
+export const createTableVisFn = (): TableVisExpressionFunctionDefinition => ({
name: 'opensearch_dashboards_table',
type: 'render',
inputTypes: ['opensearch_dashboards_datatable'],
@@ -69,18 +47,15 @@ export const createTableVisFn = (): ExpressionFunctionDefinition<
},
fn(input, args) {
const visConfig = args.visConfig && JSON.parse(args.visConfig);
- const convertedData = tableVisResponseHandler(input, visConfig.dimensions);
+ const convertedData = tableVisResponseHandler(input, visConfig);
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_legacy_module.ts b/src/plugins/vis_type_table/public/table_vis_legacy_module.ts
deleted file mode 100644
index 49eed3494f92..000000000000
--- a/src/plugins/vis_type_table/public/table_vis_legacy_module.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * 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 { IModule } from 'angular';
-
-// @ts-ignore
-import { TableVisController } from './table_vis_controller.js';
-// @ts-ignore
-import { OsdAggTable } from './agg_table/agg_table';
-// @ts-ignore
-import { OsdAggTableGroup } from './agg_table/agg_table_group';
-// @ts-ignore
-import { OsdRows } from './paginated_table/rows';
-// @ts-ignore
-import { PaginatedTable } from './paginated_table/paginated_table';
-
-/** @internal */
-export const initTableVisLegacyModule = (angularIns: IModule): void => {
- angularIns
- .controller('OsdTableVisController', TableVisController)
- .directive('osdAggTable', OsdAggTable)
- .directive('osdAggTableGroup', OsdAggTableGroup)
- .directive('osdRows', OsdRows)
- .directive('paginatedTable', PaginatedTable);
-};
diff --git a/src/plugins/vis_type_table/public/table_vis_renderer.tsx b/src/plugins/vis_type_table/public/table_vis_renderer.tsx
new file mode 100644
index 000000000000..dd35d8b77f23
--- /dev/null
+++ b/src/plugins/vis_type_table/public/table_vis_renderer.tsx
@@ -0,0 +1,33 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from 'react';
+import { render, unmountComponentAtNode } from 'react-dom';
+
+import { VisualizationContainer } from '../../visualizations/public';
+import { ExpressionRenderDefinition } from '../../expressions/common/expression_renderers';
+import { TableVisRenderValue } from './table_vis_fn';
+
+export const tableVisRenderer: () => ExpressionRenderDefinition = () => ({
+ name: 'table_vis',
+ displayName: 'table visualization',
+ reuseDomNode: true,
+ render: async (domNode, { visData, visConfig }, handlers) => {
+ handlers.onDestroy(() => {
+ unmountComponentAtNode(domNode);
+ });
+
+ const showNoResult = visData.table
+ ? visData.table.rows.length === 0
+ : visData.tableGroups?.length === 0;
+
+ render(
+
+ <>> //toDo: add TableVisComponent
+ ,
+ domNode
+ );
+ },
+});
diff --git a/src/plugins/vis_type_table/public/table_vis_response_handler.ts b/src/plugins/vis_type_table/public/table_vis_response_handler.ts
index 78b2306e744b..9bb50a00dd06 100644
--- a/src/plugins/vis_type_table/public/table_vis_response_handler.ts
+++ b/src/plugins/vis_type_table/public/table_vis_response_handler.ts
@@ -28,19 +28,17 @@
* under the License.
*/
-import { Required } from '@osd/utility-types';
-
import { getFormatService } from './services';
-import { Input } from './table_vis_fn';
+import { OpenSearchDashboardsDatatable } from '../../expressions/public';
+import { TableVisConfig } from './types';
-export interface TableContext {
- tables: Array;
- direction?: 'row' | 'column';
+export interface Table {
+ columns: OpenSearchDashboardsDatatable['columns'];
+ rows: OpenSearchDashboardsDatatable['rows'];
}
export interface TableGroup {
- $parent: TableContext;
- table: Input;
+ table: OpenSearchDashboardsDatatable;
tables: Table[];
title: string;
name: string;
@@ -49,61 +47,66 @@ export interface TableGroup {
row: number;
}
-export interface Table {
- $parent?: TableGroup;
- columns: Input['columns'];
- rows: Input['rows'];
+export interface TableContext {
+ table?: Table;
+ tableGroups?: TableGroup[];
+ direction?: 'row' | 'column';
}
-export function tableVisResponseHandler(table: Input, dimensions: any): TableContext {
- const converted: TableContext = {
- tables: [],
- };
+export function tableVisResponseHandler(
+ input: OpenSearchDashboardsDatatable,
+ config: TableVisConfig
+): TableContext {
+ let table: Table | undefined;
+ const tableGroups: TableGroup[] = [];
+ let direction: TableContext['direction'];
- const split = dimensions.splitColumn || dimensions.splitRow;
+ const split = config.splitColumn || config.splitRow;
if (split) {
- converted.direction = dimensions.splitRow ? 'row' : 'column';
+ direction = config.splitRow ? 'row' : 'column';
const splitColumnIndex = split[0].accessor;
const splitColumnFormatter = getFormatService().deserialize(split[0].format);
- const splitColumn = table.columns[splitColumnIndex];
- const splitMap = {};
+ const splitColumn = input.columns[splitColumnIndex];
+ const splitMap: { [key: string]: number } = {};
let splitIndex = 0;
- table.rows.forEach((row, rowIndex) => {
+ input.rows.forEach((row, rowIndex) => {
const splitValue: any = row[splitColumn.id];
if (!splitMap.hasOwnProperty(splitValue as any)) {
(splitMap as any)[splitValue] = splitIndex++;
- const tableGroup: Required = {
- $parent: converted,
+ const tableGroup: TableGroup = {
title: `${splitColumnFormatter.convert(splitValue)}: ${splitColumn.name}`,
name: splitColumn.name,
key: splitValue,
column: splitColumnIndex,
row: rowIndex,
- table,
+ table: input,
tables: [],
};
tableGroup.tables.push({
- $parent: tableGroup,
- columns: table.columns,
+ columns: input.columns,
rows: [],
});
- converted.tables.push(tableGroup);
+ tableGroups.push(tableGroup);
}
const tableIndex = (splitMap as any)[splitValue];
- (converted.tables[tableIndex] as any).tables[0].rows.push(row);
+ (tableGroups[tableIndex] as any).tables[0].rows.push(row);
});
} else {
- converted.tables.push({
- columns: table.columns,
- rows: table.rows,
- });
+ table = {
+ columns: input.columns,
+ rows: input.rows,
+ };
}
- return converted;
+ return {
+ table,
+ tableGroups,
+ direction,
+ };
}
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 df1495a3d06b..0c27e7a8af0b 100644
--- a/src/plugins/vis_type_table/public/table_vis_type.ts
+++ b/src/plugins/vis_type_table/public/table_vis_type.ts
@@ -28,91 +28,78 @@
* under the License.
*/
-import { CoreSetup, PluginInitializerContext } from 'opensearch-dashboards/public';
import { i18n } from '@osd/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 { toExpressionAst } from './to_ast';
+import { VIS_EVENT_TO_TRIGGER } from '../../../plugins/visualizations/public';
import { TableOptions } from './components/table_vis_options_lazy';
-import { getTableVisualizationControllerClass } from './vis_controller';
-import { VIS_EVENT_TO_TRIGGER } from '../../visualizations/public';
-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];
+export const getTableVisTypeDefinition = (): BaseVisTypeOptions => ({
+ name: 'table',
+ title: i18n.translate('visTypeTable.tableVisTitle', {
+ defaultMessage: 'Data Table',
+ }),
+ icon: 'visTable',
+ description: i18n.translate('visTypeTable.tableVisDescription', {
+ defaultMessage: 'Display values in a table',
+ }),
+ toExpressionAst,
+ visConfig: {
+ defaults: {
+ perPage: 10,
+ showPartialRows: false,
+ showMetricsAtAllLevels: false,
+ showTotal: false,
+ totalFunc: 'sum',
+ percentageCol: '',
},
- visConfig: {
- defaults: {
- perPage: 10,
- showPartialRows: false,
- showMetricsAtAllLevels: false,
- sort: {
- columnIndex: null,
- direction: null,
- },
- showTotal: false,
- totalFunc: 'sum',
- percentageCol: '',
- },
- template: tableVisTemplate,
- },
- 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'],
+ },
+ ]),
+ },
+ responseHandler: tableVisResponseHandler,
+ getSupportedTriggers: () => {
+ return [VIS_EVENT_TO_TRIGGER.filter];
+ },
+ hierarchicalData: (vis) => {
+ return Boolean(vis.params.showPartialRows || vis.params.showMetricsAtAllLevels);
+ },
+});
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 000000000000..67381388d18a
--- /dev/null
+++ b/src/plugins/vis_type_table/public/to_ast.ts
@@ -0,0 +1,56 @@
+/*
+ * Copyright OpenSearch Contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { getVisSchemas, Vis } from '../../visualizations/public';
+import { buildExpression, buildExpressionFunction } from '../../expressions/public';
+import { TableVisExpressionFunctionDefinition } from './table_vis_fn';
+import { OpenSearchaggsExpressionFunctionDefinition } from '../../data/common/search/expressions';
+
+export const toExpressionAst = (vis: Vis, params: any) => {
+ const opensearchaggs = buildExpressionFunction(
+ 'opensearchaggs',
+ {
+ index: vis.data.indexPattern!.id!,
+ metricsAtAllLevels: vis.isHierarchical(),
+ partialRows: vis.params.showPartialRows || false,
+ aggConfigs: JSON.stringify(vis.data.aggs!.aggs),
+ includeFormatHints: false,
+ }
+ );
+
+ const schemas = getVisSchemas(vis, params);
+
+ const tableData = {
+ metrics: schemas.metric,
+ buckets: schemas.bucket || [],
+ splitRow: schemas.split_row,
+ splitColumn: schemas.split_column,
+ };
+
+ const tableConfig = {
+ perPage: vis.params.perPage,
+ percentageCol: vis.params.percentageCol,
+ showPartialRows: vis.params.showPartialRows,
+ showMetricsAtAllLevels: vis.params.showMetricsAtAllLevels,
+ showTotal: vis.params.showTotal,
+ totalFunc: vis.params.totalFunc,
+ };
+
+ const visConfig = {
+ ...tableConfig,
+ ...tableData,
+ };
+
+ const tableVis = buildExpressionFunction(
+ 'opensearch_dashboards_table',
+ {
+ visConfig: JSON.stringify(visConfig),
+ }
+ );
+
+ const ast = buildExpression([opensearchaggs, tableVis]);
+
+ return ast.toAst();
+};
diff --git a/src/plugins/vis_type_table/public/types.ts b/src/plugins/vis_type_table/public/types.ts
index c780ef3b5db9..fbc573409a99 100644
--- a/src/plugins/vis_type_table/public/types.ts
+++ b/src/plugins/vis_type_table/public/types.ts
@@ -28,7 +28,7 @@
* under the License.
*/
-import { SchemaConfig } from '../../visualizations/public';
+import { SchemaConfig } from 'src/plugins/visualizations/public';
export enum AggTypes {
SUM = 'sum',
@@ -38,22 +38,18 @@ export enum AggTypes {
COUNT = 'count',
}
-export interface Dimensions {
- buckets: SchemaConfig[];
+export interface TableVisConfig extends TableVisParams {
metrics: SchemaConfig[];
+ buckets: SchemaConfig[];
+ splitRow?: SchemaConfig[];
+ splitColumn?: SchemaConfig[];
}
export interface TableVisParams {
- type: 'table';
perPage: number | '';
showPartialRows: boolean;
showMetricsAtAllLevels: boolean;
- sort: {
- columnIndex: number | null;
- direction: string | null;
- };
showTotal: boolean;
totalFunc: AggTypes;
percentageCol: string;
- dimensions: Dimensions;
}
diff --git a/src/plugins/vis_type_table/public/vis_controller.ts b/src/plugins/vis_type_table/public/vis_controller.ts
deleted file mode 100644
index aa7ffb05110a..000000000000
--- a/src/plugins/vis_type_table/public/vis_controller.ts
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * The OpenSearch Contributors require contributions made to
- * this file be licensed under the Apache-2.0 license or a
- * compatible open source license.
- *
- * Any modifications Copyright OpenSearch Contributors. See
- * GitHub history for details.
- */
-
-/*
- * 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 'opensearch-dashboards/public';
-import angular, { IModule, auto, IRootScopeService, IScope, ICompileService } from 'angular';
-import $ from 'jquery';
-
-import { VisParams, ExprVis } from '../../visualizations/public';
-import { getAngularModule } from './get_inner_angular';
-import { getOpenSearchDashboardsLegacy } from './services';
-import { initTableVisLegacyModule } from './table_vis_legacy_module';
-
-const innerAngularName = 'opensearch-dashboards/table_vis';
-
-export function getTableVisualizationControllerClass(
- 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) {
- this.el = $(domeElement);
- this.vis = vis;
- }
-
- getInjector() {
- if (!this.injector) {
- const mountpoint = document.createElement('div');
- mountpoint.setAttribute('style', 'height: 100%; width: 100%;');
- this.injector = angular.bootstrap(mountpoint, [innerAngularName]);
- this.el.append(mountpoint);
- }
-
- return this.injector;
- }
-
- async initLocalAngular() {
- if (!this.tableVisModule) {
- const [coreStart] = await core.getStartServices();
- this.tableVisModule = getAngularModule(innerAngularName, coreStart, context);
- initTableVisLegacyModule(this.tableVisModule);
- }
- }
-
- async render(opensearchResponse: object, visParams: VisParams): Promise {
- getOpenSearchDashboardsLegacy().loadFontAwesome();
- await this.initLocalAngular();
-
- return new Promise(async (resolve, reject) => {
- if (!this.$rootScope) {
- const $injector = this.getInjector();
- this.$rootScope = $injector.get('$rootScope');
- this.$compile = $injector.get('$compile');
- }
- const updateScope = () => {
- if (!this.$scope) {
- 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.opensearchResponse = opensearchResponse;
-
- this.$scope.visParams = visParams;
- this.$scope.renderComplete = resolve;
- this.$scope.renderFailed = reject;
- this.$scope.resize = Date.now();
- this.$scope.$apply();
- };
-
- if (!this.$scope && this.$compile) {
- this.$scope = this.$rootScope.$new();
- this.$scope.uiState = this.vis.getUiState();
- updateScope();
- this.el
- .find('div')
- .append(this.$compile(this.vis.type.visConfig?.template ?? '')(this.$scope));
- this.$scope.$apply();
- } else {
- updateScope();
- }
- });
- }
-
- destroy() {
- if (this.$rootScope) {
- this.$rootScope.$destroy();
- this.$rootScope = null;
- }
- }
- };
-}
diff --git a/src/plugins/vis_type_table/server/index.ts b/src/plugins/vis_type_table/server/index.ts
index 5ec9b8b91c03..e0c27a37755c 100644
--- a/src/plugins/vis_type_table/server/index.ts
+++ b/src/plugins/vis_type_table/server/index.ts
@@ -34,9 +34,6 @@ import { configSchema, ConfigSchema } from '../config';
export const config: PluginConfigDescriptor = {
schema: configSchema,
- deprecations: ({ renameFromRoot }) => [
- renameFromRoot('table_vis.enabled', 'vis_type_table.enabled'),
- ],
};
export const plugin = () => ({
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 b3b4dc5e09b1..6a16b5caa15c 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,15 +12,15 @@ 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`] = `"opensearch_dashboards_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=false 1`] = `"visTable 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`] = `"opensearch_dashboards_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 showPartialRows=true and showMetricsAtAllLevels=true 1`] = `"visTable 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`] = `"opensearch_dashboards_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 1`] = `"visTable 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`] = `"opensearch_dashboards_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 with splits and buckets 1`] = `"visTable 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`] = `"opensearch_dashboards_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 table function without splits or buckets 1`] = `"visTable 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}}' "`;
diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts
index 90721f66c4af..5f240f82602c 100644
--- a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts
+++ b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts
@@ -128,84 +128,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 7a28ae7ac394..1cbb3bc38879 100644
--- a/src/plugins/visualizations/public/legacy/build_pipeline.ts
+++ b/src/plugins/visualizations/public/legacy/build_pipeline.ts
@@ -278,13 +278,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 `opensearch_dashboards_table ${prepareJson('visConfig', visConfig)}`;
- },
region_map: (params, schemas) => {
const visConfig = {
...params,
@@ -309,26 +302,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];