UNPKG

@deephaven/js-plugin-ag-grid

Version:
103 lines 5.5 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { useApi } from '@deephaven/jsapi-bootstrap'; import Log from '@deephaven/log'; import { createFormatterFromSettings } from '@deephaven/jsapi-utils'; import { AgGridReact } from 'ag-grid-react'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { AgGridFormatter, getAutoGroupColumnDef, getColumnDefs, getSideBar, isPivotTable, isTable, toGroupKeyString, TREE_NODE_KEY, } from '../utils'; import { DeephavenViewportDatasource } from '../datasources'; const log = Log.module('@deephaven/js-plugin-ag-grid/AgGridView'); /** * AgGrid view that uses the Server-Side Row Model and a Deephaven table as a data source to display * in AG Grid, with support for value formatting, sorting, and basic filtering operations. */ export function AgGridView({ table, settings, agGridProps, }) { const dh = useApi(); const gridApiRef = useRef(null); const autoSizedColumnsRef = useRef(new Set()); const [isVisible, setIsVisible] = useState(false); const [isFirstDataRendered, setIsFirstDataRendered] = useState(false); log.debug('AgGridView rendering', table); /** Map from Deephaven Table Columns to AG Grid ColDefs */ const colDefs = useMemo(() => getColumnDefs(table), [table]); /** Create the ViewportDatasource to pass in to AG Grid based on the Deephaven Table */ const datasource = useMemo(() => new DeephavenViewportDatasource(dh, table), [dh, table]); // Create the formatter used to format cell values, currently just a // wrapper around jsapi-utils Formatter, but more functionality could be added. const formatter = useMemo(() => new AgGridFormatter(createFormatterFromSettings(dh, settings)), [dh, settings]); const autoGroupColumnDef = useMemo(() => getAutoGroupColumnDef(datasource), [datasource]); const sideBar = useMemo(() => getSideBar(table), [table]); // Workaround to auto-size columns based on their contents, as ag-grid ignores virtual columns // that are not visible in the viewport const autoSizeAllColumns = () => { var _a, _b; const gridApi = gridApiRef.current; if (!gridApi) return; const allColumnIds = [ ...((_a = gridApi.getColumns()) !== null && _a !== void 0 ? _a : []), ...((_b = gridApi.getPivotResultColumns()) !== null && _b !== void 0 ? _b : []), ].map(c => c.getColId()); // Only auto-size columns that haven't been auto-sized yet const columnsToAutoSize = allColumnIds.filter(colId => !autoSizedColumnsRef.current.has(colId)); log.debug2('autoSizeAllColumns resizing', columnsToAutoSize); if (columnsToAutoSize.length > 0) { gridApi.autoSizeColumns(columnsToAutoSize); columnsToAutoSize.forEach(colId => autoSizedColumnsRef.current.add(colId)); } // Remove any columns that are no longer present in the grid from the auto-sized set autoSizedColumnsRef.current.forEach(colId => { if (!allColumnIds.includes(colId)) { autoSizedColumnsRef.current.delete(colId); } }); }; const handleGridReady = useCallback((event) => { log.debug('handleGridReady', event); datasource.setGridApi(event.api); gridApiRef.current = event.api; }, [datasource]); const handleFirstDataRendered = (event) => { log.debug('handleFirstDataRendered', event); setIsFirstDataRendered(true); }; const handleGridSizeChanged = (event) => { log.debug('handleGridSizeChanged', event); setIsVisible(event.clientHeight > 0 && event.clientWidth > 0); }; useEffect(() => { if (isVisible && isFirstDataRendered) { autoSizeAllColumns(); } }, [isVisible, isFirstDataRendered]); const getRowId = useCallback((params) => { const { data } = params; if (data == null) { log.error('getRowId called with null data', params); throw new Error('getRowId called with null data'); } if (isPivotTable(table)) { const groupKeys = []; for (let i = 0; i < table.rowSources.length; i += 1) { const rowSource = table.rowSources[i]; if (data[rowSource.name] != null) { groupKeys.push(String(data[rowSource.name])); } } return toGroupKeyString(groupKeys); } const treeNode = data === null || data === void 0 ? void 0 : data[TREE_NODE_KEY]; if (treeNode == null) { log.error('getRowId called with missing tree node info', params); throw new Error('Tree node info missing from row data'); } return `${treeNode.index}`; }, [table]); return (_jsx(AgGridReact // eslint-disable-next-line react/jsx-props-no-spreading , Object.assign({}, agGridProps, { onGridReady: handleGridReady, onFirstDataRendered: handleFirstDataRendered, onGridSizeChanged: handleGridSizeChanged, autoGroupColumnDef: autoGroupColumnDef, columnDefs: colDefs, dataTypeDefinitions: formatter.cellDataTypeDefinitions, viewportDatasource: datasource, rowModelType: "viewport", // With a regular table, the row IDs are just the row indices, so we don't need to specify getRowId getRowId: isTable(table) ? undefined : getRowId, sideBar: sideBar }))); } export default AgGridView; //# sourceMappingURL=AgGridView.js.map