/* * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ import React, { useState, useMemo, useCallback, useRef, useEffect } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; // ag-data-grid import { AgGridReact } from 'ag-grid-react'; import 'ag-grid-community/dist/styles/ag-grid.css'; import 'ag-grid-community/dist/styles/ag-theme-alpine.css'; // grid elements import { CustomOverlay, RowConfigType, GridHeader } from './data_table_header'; import { GridFooter } from './data_table_footer'; // constants import { COLUMN_DEFAULT_MIN_WIDTH, HEADER_HEIGHT } from '../../../../../common/constants/explorer'; import { IVisualizationContainerProps, IField } from '../../../../../common/types/explorer'; import 'ag-grid-community/dist/styles/ag-theme-alpine-dark.css'; // styles import './data_table.scss'; const doubleValueGetter = (params) => { return params.data[params.column.colId]; }; export const DataTable = ({ visualizations, layout, config }: any) => { const { data: { explorer: { explorerData: { jsonData = [], schema = [] }, }, userConfigs: { dataConfig: { chartStyles = {} } = {} } = {}, } = {}, }: IVisualizationContainerProps = visualizations; const enablePagination = typeof chartStyles.enablePagination !== 'undefined' ? chartStyles.enablePagination : visualizations.vis.enablepagination; const showTableHeader = typeof chartStyles.showTableHeader !== 'undefined' ? chartStyles.showTableHeader : visualizations.vis.showtableheader; const colunmFilter = typeof chartStyles.colunmFilter !== 'undefined' ? chartStyles.colunmFilter : visualizations.vis.colunmfilter; const columnAlignment = chartStyles.columnAlignment || visualizations.vis.columnalignment; const columnWidth = typeof chartStyles.columnWidth !== 'undefined' ? chartStyles.columnWidth : visualizations.vis.columnwidth; useEffect(() => { document.addEventListener('keydown', hideGridFullScreenHandler); return () => { document.removeEventListener('keydown', hideGridFullScreenHandler); }; }, []); // rows and columns const rawData = [...jsonData]; const columns = useMemo( () => schema.map((field: IField) => { return { lockVisible: true, columnsMenuParams: { suppressColumnFilter: true, suppressColumnSelectAll: true, suppressColumnExpandAll: true, }, headerName: field.name, field: field.name, colId: field.name, ...(field.type === 'double' && { valueGetter: doubleValueGetter, }), }; }), [schema] ); // ag-grid-react bindings const gridRef = useRef(); const gridRefFullScreen = useRef(); const [pageSize, setPageSize] = useState(10); const [columnVisibility, setColumnVisibility] = useState([]); const [isFullScreen, setIsFullScreen] = useState(false); const [selectedRowDensity, setSelectedRowDensity] = useState({ icon: 'tableDensityCompact', height: 35, selected: true, }); // pagination const [activePage, setActivePage] = useState(0); const pageCount = Math.ceil(rawData.length / pageSize); const defaultColDef = useMemo(() => { return { sortable: true, resizable: true, filter: colunmFilter, flex: 1, suppressMenu: false, minWidth: COLUMN_DEFAULT_MIN_WIDTH, headerHeight: 400, type: columnAlignment, }; }, [colunmFilter, columnAlignment]); useEffect(() => { if (!chartStyles.columnWidth) { gridRef?.current?.api?.sizeColumnsToFit(); } else { columns.forEach((col: any) => gridRef?.current?.columnApi?.setColumnWidth(col.field, Number(columnWidth)) ); } }, [columnWidth, columns]); const onPageSizeChanged = useCallback( (val: number) => { setPageSize(val); gridRef.current.api.paginationSetPageSize(val); setActivePage(0); gridRef.current.api.paginationGoToPage(0); if (isFullScreen) { gridRefFullScreen.current.api.paginationSetPageSize(val); gridRefFullScreen.current.api.paginationGoToPage(0); } }, [isFullScreen] ); const selectDensityHandler = useCallback((value: RowConfigType) => { setSelectedRowDensity({ ...value }); gridRef.current.api.forEachNode((rowNode) => { if (rowNode.data) { rowNode.setRowHeight(value.height); } }); gridRef.current.api.onRowHeightChanged(); }, []); const columnVisiblityHandler = useCallback((visible: boolean, field: string) => { const isExisting = columnVisibility.findIndex((column) => column === field); if (visible) { if (isExisting > -1) { columnVisibility.splice(isExisting, 1); gridRef?.current?.columnApi?.setColumnsVisible([field], true); } } else { columnVisibility.push(field); gridRef?.current?.columnApi?.setColumnsVisible([field], false); } setColumnVisibility([...columnVisibility]); }, []); const goToPage = ({ selected }: { selected: number }) => { setActivePage(selected); gridRef.current.api.paginationGoToPage(selected); if (isFullScreen) { gridRefFullScreen.current.api.paginationGoToPage(selected); } }; const setIsFullScreenHandler = (val: boolean) => { setIsFullScreen(val); }; const hideGridFullScreenHandler = (e: any) => { if (e.key === 'Escape') { setIsFullScreen(false); } }; return ( <> {showTableHeader && ( )} { gridRef?.current?.api.setHeaderHeight(HEADER_HEIGHT); }} suppressFieldDotNotation // added for key contains dot operator /> {enablePagination && ( )} {isFullScreen && ( { gridRefFullScreen?.current?.api.setHeaderHeight(HEADER_HEIGHT); }} // added for key contains dot operator suppressFieldDotNotation /> )} ); };