From 2c16598a3680956fd374859b0cb1f449cef03c3e Mon Sep 17 00:00:00 2001 From: Anan Zhuang Date: Thu, 22 Sep 2022 12:22:24 -0700 Subject: [PATCH] [Table Visualization] add a plain datagrid component (#2390) implement a plain OuiDataGrid component use the basic pagenation, sort and format. Partially resolve: https://github.com/opensearch-project/OpenSearch-Dashboards/issues/2305 Signed-off-by: Anan Zhuang Signed-off-by: Anan Zhuang --- .../vis_type_table/opensearch_dashboards.json | 1 + .../public/components/table_vis_app.tsx | 45 +++++++++++++ .../public/components/table_vis_component.tsx | 64 +++++++++++++++++++ src/plugins/vis_type_table/public/plugin.ts | 18 ++++-- .../public/table_vis_renderer.tsx | 8 ++- yarn.lock | 16 ++--- 6 files changed, 137 insertions(+), 15 deletions(-) create mode 100644 src/plugins/vis_type_table/public/components/table_vis_app.tsx create mode 100644 src/plugins/vis_type_table/public/components/table_vis_component.tsx diff --git a/src/plugins/vis_type_table/opensearch_dashboards.json b/src/plugins/vis_type_table/opensearch_dashboards.json index 97a7d4c753d0..5ba8545250e0 100644 --- a/src/plugins/vis_type_table/opensearch_dashboards.json +++ b/src/plugins/vis_type_table/opensearch_dashboards.json @@ -10,6 +10,7 @@ ], "requiredBundles": [ "opensearchDashboardsUtils", + "opensearchDashboardsReact", "charts", "visDefaultEditor" ] diff --git a/src/plugins/vis_type_table/public/components/table_vis_app.tsx b/src/plugins/vis_type_table/public/components/table_vis_app.tsx new file mode 100644 index 000000000000..6498abe1fb2f --- /dev/null +++ b/src/plugins/vis_type_table/public/components/table_vis_app.tsx @@ -0,0 +1,45 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { CoreStart } from 'opensearch-dashboards/public'; +import { I18nProvider } from '@osd/i18n/react'; +import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; +import { OpenSearchDashboardsContextProvider } from '../../../opensearch_dashboards_react/public'; + +import { TableContext } from '../table_vis_response_handler'; +import { TableVisConfig } from '../types'; +import { TableVisComponent } from './table_vis_component'; + +interface TableVisAppProps { + visData: TableContext; + visConfig: TableVisConfig; + handlers: IInterpreterRenderHandlers; +} + +export const TableVisApp = ({ + services, + visData: { table, tableGroups, direction }, + visConfig, + handlers, +}: TableVisAppProps & { services: CoreStart }) => { + return ( + + +
+ {table ? ( + + ) : ( + <> + )} +
+
+
+ ); +}; + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { TableVisApp as default }; diff --git a/src/plugins/vis_type_table/public/components/table_vis_component.tsx b/src/plugins/vis_type_table/public/components/table_vis_component.tsx new file mode 100644 index 000000000000..de0074beac38 --- /dev/null +++ b/src/plugins/vis_type_table/public/components/table_vis_component.tsx @@ -0,0 +1,64 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React, { useState, useCallback, useMemo } from 'react'; +import { EuiDataGridProps, EuiDataGrid } from '@elastic/eui'; + +import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; +import { Table } from '../table_vis_response_handler'; +import { TableVisConfig } from '../types'; + +interface TableVisComponentProps { + table: Table; + visConfig: TableVisConfig; + handlers: IInterpreterRenderHandlers; +} + +export const TableVisComponent = ({ table, visConfig, handlers }: TableVisComponentProps) => { + const { rows, columns } = table; + const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 5 }); + const onChangeItemsPerPage = useCallback( + (pageSize) => setPagination((p) => ({ ...p, pageSize, pageIndex: 0 })), + [setPagination] + ); + + const onChangePage = useCallback((pageIndex) => setPagination((p) => ({ ...p, pageIndex })), [ + setPagination, + ]); + + // toDo: it is a sample renderCellValue to render a data grid component + // will check on it and it might be replaced + const renderCellValue = useMemo(() => { + return (({ rowIndex, columnId }) => { + let adjustedRowIndex = rowIndex; + + // If we are doing the pagination (instead of leaving that to the grid) + // then the row index must be adjusted as `data` has already been pruned to the page size + adjustedRowIndex = rowIndex - pagination.pageIndex * pagination.pageSize; + + return rows.hasOwnProperty(adjustedRowIndex) + ? rows[adjustedRowIndex][columnId] || null + : null; + }) as EuiDataGridProps['renderCellValue']; + }, [rows, pagination.pageIndex, pagination.pageSize]); + + return ( + id), + setVisibleColumns: () => {}, + }} + rowCount={rows.length} + renderCellValue={renderCellValue} + pagination={{ + ...pagination, + onChangeItemsPerPage, + onChangePage, + }} + /> + ); +}; diff --git a/src/plugins/vis_type_table/public/plugin.ts b/src/plugins/vis_type_table/public/plugin.ts index ce0852a9ba7d..c5648f75d4fb 100644 --- a/src/plugins/vis_type_table/public/plugin.ts +++ b/src/plugins/vis_type_table/public/plugin.ts @@ -17,7 +17,7 @@ import { getTableVisTypeDefinition } from './table_vis_type'; import { DataPublicPluginStart } from '../../data/public'; import { setFormatService } from './services'; import { ConfigSchema } from '../config'; -import { tableVisRenderer } from './table_vis_renderer'; +import { getTableVisRenderer } from './table_vis_renderer'; /** @internal */ export interface TableVisPluginSetupDependencies { @@ -30,6 +30,16 @@ export interface TableVisPluginStartDependencies { data: DataPublicPluginStart; } +const setupTableVis = async ( + core: CoreSetup, + { expressions, visualizations }: TableVisPluginSetupDependencies +) => { + const [coreStart] = await core.getStartServices(); + expressions.registerFunction(createTableVisFn); + expressions.registerRenderer(getTableVisRenderer(coreStart)); + visualizations.createBaseVisualization(getTableVisTypeDefinition()); +}; + /** @internal */ export class TableVisPlugin implements Plugin { initializerContext: PluginInitializerContext; @@ -38,10 +48,8 @@ export class TableVisPlugin implements Plugin { this.initializerContext = initializerContext; } - public setup(core: CoreSetup, { expressions, visualizations }: TableVisPluginSetupDependencies) { - expressions.registerFunction(createTableVisFn); - expressions.registerRenderer(tableVisRenderer); - visualizations.createBaseVisualization(getTableVisTypeDefinition()); + public async setup(core: CoreSetup, dependencies: TableVisPluginSetupDependencies) { + setupTableVis(core, dependencies); } public start(core: CoreStart, { data }: TableVisPluginStartDependencies) { diff --git a/src/plugins/vis_type_table/public/table_vis_renderer.tsx b/src/plugins/vis_type_table/public/table_vis_renderer.tsx index dd35d8b77f23..a717d38e04b2 100644 --- a/src/plugins/vis_type_table/public/table_vis_renderer.tsx +++ b/src/plugins/vis_type_table/public/table_vis_renderer.tsx @@ -6,11 +6,15 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; +import { CoreStart } from 'opensearch-dashboards/public'; import { VisualizationContainer } from '../../visualizations/public'; import { ExpressionRenderDefinition } from '../../expressions/common/expression_renderers'; import { TableVisRenderValue } from './table_vis_fn'; +import { TableVisApp } from './components/table_vis_app'; -export const tableVisRenderer: () => ExpressionRenderDefinition = () => ({ +export const getTableVisRenderer: ( + core: CoreStart +) => ExpressionRenderDefinition = (core) => ({ name: 'table_vis', displayName: 'table visualization', reuseDomNode: true, @@ -25,7 +29,7 @@ export const tableVisRenderer: () => ExpressionRenderDefinition - <> //toDo: add TableVisComponent + , domNode ); diff --git a/yarn.lock b/yarn.lock index 6ec85a1424f5..e1ff92cb3069 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11640,10 +11640,10 @@ leaflet-responsive-popup@0.6.4: resolved "https://registry.yarnpkg.com/leaflet-responsive-popup/-/leaflet-responsive-popup-0.6.4.tgz#b93d9368ef9f96d6dc911cf5b96d90e08601c6b3" integrity sha512-2D8G9aQA6NHkulDBPN9kqbUCkCpWQQ6dF0xFL11AuEIWIbsL4UC/ZPP5m8GYM0dpU6YTlmyyCh1Tz+cls5Q4dg== -"leaflet-vega@npm:@amoo-miki/leaflet-vega@0.8.7": - version "0.8.7" - resolved "https://registry.yarnpkg.com/@amoo-miki/leaflet-vega/-/leaflet-vega-0.8.7.tgz#8faca1b4b8e2ef7d48667ac6faad9204f4da7153" - integrity sha512-T4M5yziwj3Fi9Adsbce+cdWqPjON0BRwEjwqLlPMoirU1vhifA6YKrlZkVzJrK0IIm+hdfMCLkBz33gD8fdxzQ== +"leaflet-vega@npm:@amoo-miki/leaflet-vega@0.8.8": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@amoo-miki/leaflet-vega/-/leaflet-vega-0.8.8.tgz#675abf37d72fbea859755e982f4fd19dea776557" + integrity sha512-W2gGgFDxzy/XUx+fQJfz0NYVXsKl7V+G6QywiMcOV5NEodDId9c60up7NNf+cfM7ggpo+5BuLqrKmosuGO1CsA== dependencies: vega-spec-injector "^0.0.2" @@ -18000,10 +18000,10 @@ vega-hierarchy@~4.1.0: vega-dataflow "^5.7.3" vega-util "^1.15.2" -"vega-interpreter@npm:@amoo-miki/vega-forced-csp-compliant-interpreter@1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@amoo-miki/vega-forced-csp-compliant-interpreter/-/vega-forced-csp-compliant-interpreter-1.0.5.tgz#49970be9b00ca7e45ced0617fbf373c77a28aab4" - integrity sha512-lfeU77lVoUbSCC6N1ywdKg+I6K08xpkd82TLon+LebtKyC8aLCe7P5Dd/89zAPyFwRyobKftHu8z0xpV7R7a4Q== +"vega-interpreter@npm:@amoo-miki/vega-forced-csp-compliant-interpreter@1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@amoo-miki/vega-forced-csp-compliant-interpreter/-/vega-forced-csp-compliant-interpreter-1.0.6.tgz#5cffdf12b7fe12dc936194edd9e8519506c38716" + integrity sha512-9S5nTTVd8JVKobcWp5iwirIeePiamwH1J9uSZPuG5kcF0TUBvGu++ERKjNdst5Qck7e4R6/7vjx2wVf58XUarg== vega-label@~1.2.0: version "1.2.0"