From 7dd05c88b3ce300a1b00f6cd84e934dadf0c918c Mon Sep 17 00:00:00 2001 From: 7MIMIRA <7mimira@gmail.com> Date: Tue, 4 Nov 2025 14:22:14 -0500 Subject: [PATCH 01/10] Set column headers in table view as resizeable --- .../src/components/table-view/document-table-view.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/compass-crud/src/components/table-view/document-table-view.tsx b/packages/compass-crud/src/components/table-view/document-table-view.tsx index 4f957b248f3..179e5464fdb 100644 --- a/packages/compass-crud/src/components/table-view/document-table-view.tsx +++ b/packages/compass-crud/src/components/table-view/document-table-view.tsx @@ -845,6 +845,7 @@ class DocumentTableView extends React.Component { tz: this.props.tz, darkMode: this.props.darkMode, }, + resizable: true, }; }; From 4cc8c83d02aa23131ce07e02e38cb38d473e314e Mon Sep 17 00:00:00 2001 From: 7MIMIRA <7mimira@gmail.com> Date: Wed, 5 Nov 2025 00:42:58 -0500 Subject: [PATCH 02/10] Persist column width changes between table data refreshes (queries, refresh button) --- .../src/components/document-list.tsx | 13 ++++++- .../table-view/document-table-view.tsx | 38 +++++++++++++++++++ .../compass-crud/src/stores/grid-store.ts | 3 ++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/packages/compass-crud/src/components/document-list.tsx b/packages/compass-crud/src/components/document-list.tsx index e034a0e3f27..ac2fd7d4b1b 100644 --- a/packages/compass-crud/src/components/document-list.tsx +++ b/packages/compass-crud/src/components/document-list.tsx @@ -1,4 +1,10 @@ -import React, { useCallback, useLayoutEffect, useMemo, useRef } from 'react'; +import React, { + useCallback, + useLayoutEffect, + useMemo, + useRef, + useState, +} from 'react'; import { ObjectId } from 'bson'; import { Button, @@ -39,6 +45,7 @@ import { } from '@mongodb-js/compass-query-bar'; import { usePreferences } from 'compass-preferences-model/provider'; import { useAssistantActions } from '@mongodb-js/compass-assistant'; +import type { GridColumnState } from '../stores/grid-store'; // Table has its own scrollable container. const tableStyles = css({ @@ -317,6 +324,8 @@ const DocumentList: React.FunctionComponent = (props) => { updateMaxDocumentsPerPage, } = props; + const [gridColumnState, setGridColumnState] = useState({}); + const onOpenInsert = useCallback( (key: 'insert-document' | 'import-file') => { if (key === 'insert-document') { @@ -480,6 +489,8 @@ const DocumentList: React.FunctionComponent = (props) => { initialScrollTop={currentViewInitialScrollTop} scrollableContainerRef={scrollRef} scrollTriggerRef={scrollTriggerRef} + gridColumnState={gridColumnState} + setGridColumnState={setGridColumnState} /> ); } diff --git a/packages/compass-crud/src/components/table-view/document-table-view.tsx b/packages/compass-crud/src/components/table-view/document-table-view.tsx index 179e5464fdb..842640767f7 100644 --- a/packages/compass-crud/src/components/table-view/document-table-view.tsx +++ b/packages/compass-crud/src/components/table-view/document-table-view.tsx @@ -27,6 +27,7 @@ import type { GridActions, GridStoreTriggerParams, TableHeaderType, + GridColumnState, } from '../../stores/grid-store'; import type { CellDoubleClickedEvent, @@ -37,6 +38,7 @@ import type { GridReadyEvent, RowNode, ValueGetterParams, + ColumnResizedEvent, } from 'ag-grid-community'; const MIXED = 'Mixed' as const; @@ -70,6 +72,8 @@ export type DocumentTableViewProps = { tz: string; className?: string; darkMode?: boolean; + gridColumnState: GridColumnState; + setGridColumnState: React.Dispatch>; }; export type GridContext = { @@ -148,6 +152,7 @@ class DocumentTableView extends React.Component { const fid = data.isFooter ? '1' : '0'; return String(data.hadronDocument.getStringId()) + fid; }, + onColumnResized: this.onColumnResized.bind(this), }; this.collection = mongodbns(props.ns).collection; @@ -169,6 +174,8 @@ class DocumentTableView extends React.Component { } componentDidUpdate(prevProps: DocumentTableViewProps) { + this.setGridColumns(); + this.handleBreadcrumbChange(); // @note: Durran: Since all the values are getting passed down as props now @@ -211,6 +218,26 @@ class DocumentTableView extends React.Component { this.addFooter(event.node, event.data, 'editing'); } + /** + * Callback for when a column's width is changed + * + * @param {Object} event + * finished {Boolean} - indicates the end of a stream of column resize events + */ + onColumnResized(event: ColumnResizedEvent) { + if (event.finished) { + // Delete the existing entry so that the logic ran during componentDidUpdate + // doesn't use the previously existing entry before the current grid column + // update to gridColumnState is made + delete this.props.gridColumnState[this.collection]; + + this.props.setGridColumnState({ + ...this.props.gridColumnState, + [this.collection]: this.columnApi.getColumnState(), + }); + } + } + /** * Add a row to the table that represents the update/cancel footer for the * row directly above. The row will be a full-width row that has the same @@ -587,6 +614,17 @@ class DocumentTableView extends React.Component { } } + /** + * When the component is updated, handle setting updated column widths + */ + setGridColumns() { + if (!this.props.gridColumnState[this.collection] || !this.columnApi) { + return; + } + + this.columnApi.setColumnState(this.props.gridColumnState[this.collection]); + } + /** * When the component is updated, handle any changes to the paths. */ diff --git a/packages/compass-crud/src/stores/grid-store.ts b/packages/compass-crud/src/stores/grid-store.ts index cf2075d78f6..3a932e77cb9 100644 --- a/packages/compass-crud/src/stores/grid-store.ts +++ b/packages/compass-crud/src/stores/grid-store.ts @@ -6,6 +6,7 @@ import type { TypeCastTypes } from 'hadron-type-checker'; import TypeChecker from 'hadron-type-checker'; import { BaseRefluxStore } from './base-reflux-store'; import type { BSONObject } from './crud-store'; +import type { ColumnState } from 'ag-grid-community'; export type TableHeaderType = TypeCastTypes | 'Mixed'; @@ -53,6 +54,8 @@ export type GridStoreTriggerParams = { }; }; +export type GridColumnState = Record; + const MIXED = 'Mixed'; class GridStoreImpl From 107aacd90b110d36c84896ceb940377a5edf0c9f Mon Sep 17 00:00:00 2001 From: 7MIMIRA <7mimira@gmail.com> Date: Thu, 6 Nov 2025 15:51:16 -0500 Subject: [PATCH 03/10] Persist column width data when switching between tabs --- .../components/collection-tab-provider.tsx | 6 ++++- packages/compass-collection/src/index.ts | 5 +++- .../src/components/document-list.tsx | 17 +++++++++---- .../table-view/document-table-view.tsx | 25 +++++++++---------- .../compass-crud/src/stores/grid-store.ts | 3 --- 5 files changed, 33 insertions(+), 23 deletions(-) diff --git a/packages/compass-collection/src/components/collection-tab-provider.tsx b/packages/compass-collection/src/components/collection-tab-provider.tsx index 531e5c9fbf9..574ac45b18a 100644 --- a/packages/compass-collection/src/components/collection-tab-provider.tsx +++ b/packages/compass-collection/src/components/collection-tab-provider.tsx @@ -2,27 +2,31 @@ import React, { useContext, useRef } from 'react'; import type { CollectionTabPluginMetadata } from '../modules/collection-tab'; import type { CompassPluginComponent } from '@mongodb-js/compass-app-registry'; import type { CollectionSubtab } from '@mongodb-js/compass-workspaces'; +import type { ColumnState } from 'ag-grid-community'; export interface CollectionTabPlugin { name: CollectionSubtab; provider: CompassPluginComponent; content: React.FunctionComponent; header: React.FunctionComponent; + tableColumnStateData: Record; } type CollectionTabComponentsProviderValue = { tabs: CollectionTabPlugin[]; modals: CollectionTabPlugin['content'][]; queryBar: CollectionTabPlugin['content']; + tableColumnData: CollectionTabPlugin['tableColumnStateData']; }; const defaultComponents: CollectionTabComponentsProviderValue = { tabs: [], modals: [], queryBar: (() => null) as any, + tableColumnData: {}, }; -const CollectionTabComponentsContext = +export const CollectionTabComponentsContext = React.createContext(defaultComponents); export const CollectionTabsProvider: React.FunctionComponent< diff --git a/packages/compass-collection/src/index.ts b/packages/compass-collection/src/index.ts index 05a1680409b..229a3a7419b 100644 --- a/packages/compass-collection/src/index.ts +++ b/packages/compass-collection/src/index.ts @@ -46,4 +46,7 @@ export const WorkspaceTab: WorkspacePlugin = { }; export type { CollectionTabPluginMetadata } from './modules/collection-tab'; -export { CollectionTabsProvider } from './components/collection-tab-provider'; +export { + CollectionTabsProvider, + CollectionTabComponentsContext, +} from './components/collection-tab-provider'; diff --git a/packages/compass-crud/src/components/document-list.tsx b/packages/compass-crud/src/components/document-list.tsx index ac2fd7d4b1b..ffd1de45234 100644 --- a/packages/compass-crud/src/components/document-list.tsx +++ b/packages/compass-crud/src/components/document-list.tsx @@ -4,6 +4,7 @@ import React, { useMemo, useRef, useState, + useContext, } from 'react'; import { ObjectId } from 'bson'; import { @@ -38,14 +39,17 @@ import { import type { CrudStore, BSONObject, DocumentView } from '../stores/crud-store'; import { getToolbarSignal } from '../utils/toolbar-signal'; import BulkDeleteModal from './bulk-delete-modal'; -import { useTabState } from '@mongodb-js/compass-workspaces/provider'; +import { + useTabState, + useWorkspaceTabId, +} from '@mongodb-js/compass-workspaces/provider'; import { useIsLastAppliedQueryOutdated, useLastAppliedQuery, } from '@mongodb-js/compass-query-bar'; import { usePreferences } from 'compass-preferences-model/provider'; import { useAssistantActions } from '@mongodb-js/compass-assistant'; -import type { GridColumnState } from '../stores/grid-store'; +import { CollectionTabComponentsContext } from '@mongodb-js/compass-collection'; // Table has its own scrollable container. const tableStyles = css({ @@ -324,7 +328,10 @@ const DocumentList: React.FunctionComponent = (props) => { updateMaxDocumentsPerPage, } = props; - const [gridColumnState, setGridColumnState] = useState({}); + const tableColumnData = useContext( + CollectionTabComponentsContext + ).tableColumnData; + const workspaceTabId = useWorkspaceTabId(); const onOpenInsert = useCallback( (key: 'insert-document' | 'import-file') => { @@ -489,8 +496,8 @@ const DocumentList: React.FunctionComponent = (props) => { initialScrollTop={currentViewInitialScrollTop} scrollableContainerRef={scrollRef} scrollTriggerRef={scrollTriggerRef} - gridColumnState={gridColumnState} - setGridColumnState={setGridColumnState} + workspaceTabId={workspaceTabId} + tableColumnData={tableColumnData} /> ); } diff --git a/packages/compass-crud/src/components/table-view/document-table-view.tsx b/packages/compass-crud/src/components/table-view/document-table-view.tsx index 842640767f7..714f8f0f756 100644 --- a/packages/compass-crud/src/components/table-view/document-table-view.tsx +++ b/packages/compass-crud/src/components/table-view/document-table-view.tsx @@ -32,6 +32,7 @@ import type { import type { CellDoubleClickedEvent, ColDef, + ColumnState, ColumnApi, GridApi, GridCellDef, @@ -72,8 +73,7 @@ export type DocumentTableViewProps = { tz: string; className?: string; darkMode?: boolean; - gridColumnState: GridColumnState; - setGridColumnState: React.Dispatch>; + tableColumnData: Record; }; export type GridContext = { @@ -226,15 +226,8 @@ class DocumentTableView extends React.Component { */ onColumnResized(event: ColumnResizedEvent) { if (event.finished) { - // Delete the existing entry so that the logic ran during componentDidUpdate - // doesn't use the previously existing entry before the current grid column - // update to gridColumnState is made - delete this.props.gridColumnState[this.collection]; - - this.props.setGridColumnState({ - ...this.props.gridColumnState, - [this.collection]: this.columnApi.getColumnState(), - }); + this.props.tableColumnData[this.props.workspaceTabId] = + this.columnApi.getColumnState(); } } @@ -614,15 +607,21 @@ class DocumentTableView extends React.Component { } } + // TODO: Determine when setGridColumns can be ran so that column widths are set at first "paint" /** * When the component is updated, handle setting updated column widths */ setGridColumns() { - if (!this.props.gridColumnState[this.collection] || !this.columnApi) { + if ( + !this.props.tableColumnData?.[this.props.workspaceTabId] || + !this.columnApi + ) { return; } - this.columnApi.setColumnState(this.props.gridColumnState[this.collection]); + this.columnApi.setColumnState( + this.props.tableColumnData[this.props.workspaceTabId] + ); } /** diff --git a/packages/compass-crud/src/stores/grid-store.ts b/packages/compass-crud/src/stores/grid-store.ts index 3a932e77cb9..cf2075d78f6 100644 --- a/packages/compass-crud/src/stores/grid-store.ts +++ b/packages/compass-crud/src/stores/grid-store.ts @@ -6,7 +6,6 @@ import type { TypeCastTypes } from 'hadron-type-checker'; import TypeChecker from 'hadron-type-checker'; import { BaseRefluxStore } from './base-reflux-store'; import type { BSONObject } from './crud-store'; -import type { ColumnState } from 'ag-grid-community'; export type TableHeaderType = TypeCastTypes | 'Mixed'; @@ -54,8 +53,6 @@ export type GridStoreTriggerParams = { }; }; -export type GridColumnState = Record; - const MIXED = 'Mixed'; class GridStoreImpl From 3ef14b4b39c1d0a10372990082a34132eb9c1a3d Mon Sep 17 00:00:00 2001 From: 7MIMIRA <7mimira@gmail.com> Date: Fri, 7 Nov 2025 04:42:48 -0500 Subject: [PATCH 04/10] Update implementation to address visual bug Previous implementation would cause the columns to first render with default widths and then immediately update to previously set widths whenever the view was refreshed or when the user switched between tabs --- .../src/components/document-list.tsx | 17 +++++---- .../table-view/document-table-view.tsx | 38 +++++++++---------- 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/packages/compass-crud/src/components/document-list.tsx b/packages/compass-crud/src/components/document-list.tsx index ffd1de45234..338d0d2dfd6 100644 --- a/packages/compass-crud/src/components/document-list.tsx +++ b/packages/compass-crud/src/components/document-list.tsx @@ -3,7 +3,6 @@ import React, { useLayoutEffect, useMemo, useRef, - useState, useContext, } from 'react'; import { ObjectId } from 'bson'; @@ -166,6 +165,12 @@ const DocumentViewComponent: React.FunctionComponent< return null; } + const tableColumnData = useContext( + CollectionTabComponentsContext + ).tableColumnData; + const workspaceTabId = useWorkspaceTabId(); + const columnDefs = tableColumnData[workspaceTabId] || null; + if (props.view === 'List') { return ( ); @@ -328,11 +336,6 @@ const DocumentList: React.FunctionComponent = (props) => { updateMaxDocumentsPerPage, } = props; - const tableColumnData = useContext( - CollectionTabComponentsContext - ).tableColumnData; - const workspaceTabId = useWorkspaceTabId(); - const onOpenInsert = useCallback( (key: 'insert-document' | 'import-file') => { if (key === 'insert-document') { @@ -496,8 +499,6 @@ const DocumentList: React.FunctionComponent = (props) => { initialScrollTop={currentViewInitialScrollTop} scrollableContainerRef={scrollRef} scrollTriggerRef={scrollTriggerRef} - workspaceTabId={workspaceTabId} - tableColumnData={tableColumnData} /> ); } diff --git a/packages/compass-crud/src/components/table-view/document-table-view.tsx b/packages/compass-crud/src/components/table-view/document-table-view.tsx index 714f8f0f756..b6719755073 100644 --- a/packages/compass-crud/src/components/table-view/document-table-view.tsx +++ b/packages/compass-crud/src/components/table-view/document-table-view.tsx @@ -74,6 +74,7 @@ export type DocumentTableViewProps = { className?: string; darkMode?: boolean; tableColumnData: Record; + columnDefs: ColDef[] | null; }; export type GridContext = { @@ -134,6 +135,7 @@ class DocumentTableView extends React.Component { } return params.nextCellDef; }, + columnDefs: this.props.columnDefs, }, onGridReady: this.onGridReady.bind(this), isFullWidthCell: function (rowNode) { @@ -174,8 +176,6 @@ class DocumentTableView extends React.Component { } componentDidUpdate(prevProps: DocumentTableViewProps) { - this.setGridColumns(); - this.handleBreadcrumbChange(); // @note: Durran: Since all the values are getting passed down as props now @@ -226,8 +226,21 @@ class DocumentTableView extends React.Component { */ onColumnResized(event: ColumnResizedEvent) { if (event.finished) { - this.props.tableColumnData[this.props.workspaceTabId] = - this.columnApi.getColumnState(); + const columnDefs = this.columnApi.columnController.columnDefs; + const columnState = this.columnApi.getColumnState(); + + const columnWidths = columnState.reduce((acc, curr) => { + acc[curr.colId] = curr.width; + return acc; + }, {}); + + for (const columnDef of columnDefs) { + if (columnWidths[columnDef.colId] !== undefined) { + columnDef.width = columnWidths[columnDef.colId]; + } + } + + this.props.tableColumnData[this.props.workspaceTabId] = columnDefs; } } @@ -607,23 +620,6 @@ class DocumentTableView extends React.Component { } } - // TODO: Determine when setGridColumns can be ran so that column widths are set at first "paint" - /** - * When the component is updated, handle setting updated column widths - */ - setGridColumns() { - if ( - !this.props.tableColumnData?.[this.props.workspaceTabId] || - !this.columnApi - ) { - return; - } - - this.columnApi.setColumnState( - this.props.tableColumnData[this.props.workspaceTabId] - ); - } - /** * When the component is updated, handle any changes to the paths. */ From da6585242bc5973dc214d276b1d89bb6617414d8 Mon Sep 17 00:00:00 2001 From: 7MIMIRA <7mimira@gmail.com> Date: Mon, 10 Nov 2025 02:45:42 -0500 Subject: [PATCH 05/10] Scope tableData to each tab so we don't have to manage shared state where ColDefs are stored for each tab --- .../components/collection-tab-provider.tsx | 6 +----- packages/compass-collection/src/index.ts | 5 +---- .../src/components/document-list.tsx | 13 ++++-------- .../table-view/document-table-view.tsx | 7 +++---- .../workspace-tab-context-provider.tsx | 2 +- .../workspace-tab-state-provider.tsx | 20 ++++++++++++++++++- packages/compass-workspaces/src/provider.tsx | 2 ++ .../src/stores/workspaces.ts | 5 +++++ 8 files changed, 36 insertions(+), 24 deletions(-) diff --git a/packages/compass-collection/src/components/collection-tab-provider.tsx b/packages/compass-collection/src/components/collection-tab-provider.tsx index 574ac45b18a..531e5c9fbf9 100644 --- a/packages/compass-collection/src/components/collection-tab-provider.tsx +++ b/packages/compass-collection/src/components/collection-tab-provider.tsx @@ -2,31 +2,27 @@ import React, { useContext, useRef } from 'react'; import type { CollectionTabPluginMetadata } from '../modules/collection-tab'; import type { CompassPluginComponent } from '@mongodb-js/compass-app-registry'; import type { CollectionSubtab } from '@mongodb-js/compass-workspaces'; -import type { ColumnState } from 'ag-grid-community'; export interface CollectionTabPlugin { name: CollectionSubtab; provider: CompassPluginComponent; content: React.FunctionComponent; header: React.FunctionComponent; - tableColumnStateData: Record; } type CollectionTabComponentsProviderValue = { tabs: CollectionTabPlugin[]; modals: CollectionTabPlugin['content'][]; queryBar: CollectionTabPlugin['content']; - tableColumnData: CollectionTabPlugin['tableColumnStateData']; }; const defaultComponents: CollectionTabComponentsProviderValue = { tabs: [], modals: [], queryBar: (() => null) as any, - tableColumnData: {}, }; -export const CollectionTabComponentsContext = +const CollectionTabComponentsContext = React.createContext(defaultComponents); export const CollectionTabsProvider: React.FunctionComponent< diff --git a/packages/compass-collection/src/index.ts b/packages/compass-collection/src/index.ts index 229a3a7419b..05a1680409b 100644 --- a/packages/compass-collection/src/index.ts +++ b/packages/compass-collection/src/index.ts @@ -46,7 +46,4 @@ export const WorkspaceTab: WorkspacePlugin = { }; export type { CollectionTabPluginMetadata } from './modules/collection-tab'; -export { - CollectionTabsProvider, - CollectionTabComponentsContext, -} from './components/collection-tab-provider'; +export { CollectionTabsProvider } from './components/collection-tab-provider'; diff --git a/packages/compass-crud/src/components/document-list.tsx b/packages/compass-crud/src/components/document-list.tsx index 338d0d2dfd6..1ee84a0e89d 100644 --- a/packages/compass-crud/src/components/document-list.tsx +++ b/packages/compass-crud/src/components/document-list.tsx @@ -40,7 +40,7 @@ import { getToolbarSignal } from '../utils/toolbar-signal'; import BulkDeleteModal from './bulk-delete-modal'; import { useTabState, - useWorkspaceTabId, + useWorkspaceTabTableData, } from '@mongodb-js/compass-workspaces/provider'; import { useIsLastAppliedQueryOutdated, @@ -48,7 +48,6 @@ import { } from '@mongodb-js/compass-query-bar'; import { usePreferences } from 'compass-preferences-model/provider'; import { useAssistantActions } from '@mongodb-js/compass-assistant'; -import { CollectionTabComponentsContext } from '@mongodb-js/compass-collection'; // Table has its own scrollable container. const tableStyles = css({ @@ -165,11 +164,8 @@ const DocumentViewComponent: React.FunctionComponent< return null; } - const tableColumnData = useContext( - CollectionTabComponentsContext - ).tableColumnData; - const workspaceTabId = useWorkspaceTabId(); - const columnDefs = tableColumnData[workspaceTabId] || null; + const tableData = useWorkspaceTabTableData(); + const columnDefs = tableData.columnDefs.length ? tableData.columnDefs : null; if (props.view === 'List') { return ( @@ -195,8 +191,7 @@ const DocumentViewComponent: React.FunctionComponent< key={props.darkMode ? 'dark' : 'light'} {...props} className={tableStyles} - tableColumnData={tableColumnData} - workspaceTabId={workspaceTabId} + tableData={tableData} columnDefs={columnDefs} /> diff --git a/packages/compass-crud/src/components/table-view/document-table-view.tsx b/packages/compass-crud/src/components/table-view/document-table-view.tsx index b6719755073..fdca51d163f 100644 --- a/packages/compass-crud/src/components/table-view/document-table-view.tsx +++ b/packages/compass-crud/src/components/table-view/document-table-view.tsx @@ -27,12 +27,10 @@ import type { GridActions, GridStoreTriggerParams, TableHeaderType, - GridColumnState, } from '../../stores/grid-store'; import type { CellDoubleClickedEvent, ColDef, - ColumnState, ColumnApi, GridApi, GridCellDef, @@ -41,6 +39,7 @@ import type { ValueGetterParams, ColumnResizedEvent, } from 'ag-grid-community'; +import type { TableDataObject } from '@mongodb-js/compass-workspaces/provider'; const MIXED = 'Mixed' as const; @@ -73,7 +72,7 @@ export type DocumentTableViewProps = { tz: string; className?: string; darkMode?: boolean; - tableColumnData: Record; + tableData: TableDataObject; columnDefs: ColDef[] | null; }; @@ -240,7 +239,7 @@ class DocumentTableView extends React.Component { } } - this.props.tableColumnData[this.props.workspaceTabId] = columnDefs; + this.props.tableData.columnDefs = columnDefs; } } diff --git a/packages/compass-workspaces/src/components/workspace-tab-context-provider.tsx b/packages/compass-workspaces/src/components/workspace-tab-context-provider.tsx index a416e46c680..13329e650d9 100644 --- a/packages/compass-workspaces/src/components/workspace-tab-context-provider.tsx +++ b/packages/compass-workspaces/src/components/workspace-tab-context-provider.tsx @@ -149,7 +149,7 @@ const WorkspaceTabContextProvider: React.FunctionComponent< } return ( - + >; +export type TableDataObject = { + columnDefs: ColDef[]; +}; + const SET_STATE = 'compass-workspaces/workspace-tab-state-provider/SET_STATE'; const CLEANUP_TAB_STATE = @@ -67,6 +72,11 @@ export const TabStateStoreContext = React.createContext< ); const WorkspaceTabIdContext = React.createContext(null); +const WorkspaceTabTableColumnDefsContext = React.createContext( + { + columnDefs: [], + } +); /** * Exported for testing purposes only @@ -82,14 +92,18 @@ export const TabStoreProvider: React.FunctionComponent = ({ children }) => { export const WorkspaceTabStateProvider = ({ id, + tableData, children, }: { id: string; + tableData: TableDataObject; children: React.ReactChild; }) => { return ( - {children} + + {children} + ); }; @@ -107,6 +121,10 @@ export function useWorkspaceTabId() { return tabId; } +export function useWorkspaceTabTableData() { + return useContext(WorkspaceTabTableColumnDefsContext); +} + const useStore: () => TabStateStore = createStoreHook(TabStateStoreContext); const useSelector: TypedUseSelectorHook = diff --git a/packages/compass-workspaces/src/provider.tsx b/packages/compass-workspaces/src/provider.tsx index aa311c736c1..ea95b14a0f0 100644 --- a/packages/compass-workspaces/src/provider.tsx +++ b/packages/compass-workspaces/src/provider.tsx @@ -383,6 +383,8 @@ export { useWorkspacePlugins } from './components/workspaces-provider'; export { useWorkspaceTabId, useTabState, + useWorkspaceTabTableData, + TableDataObject, } from './components/workspace-tab-state-provider'; export { useOnTabClose, diff --git a/packages/compass-workspaces/src/stores/workspaces.ts b/packages/compass-workspaces/src/stores/workspaces.ts index 9d588d1ead8..954bbdc267e 100644 --- a/packages/compass-workspaces/src/stores/workspaces.ts +++ b/packages/compass-workspaces/src/stores/workspaces.ts @@ -210,10 +210,15 @@ export const getInitialTabState = ( const subTab = initialSubtab ?? (isAggregationsSubtab ? 'Aggregations' : 'Documents'); + const tableData = { + columnDefs: [], + }; + return { id: tabId, subTab, ...rest, + tableData, }; } return { id: tabId, ...workspace }; From 26194e4855f6585708c85cd31cdde2a32ea17a9e Mon Sep 17 00:00:00 2001 From: 7MIMIRA <7mimira@gmail.com> Date: Sun, 16 Nov 2025 04:30:39 -0500 Subject: [PATCH 06/10] Update implementation to persist previously adjusted column widths when projections are used and then removed --- .../src/components/document-list.tsx | 2 -- .../table-view/document-table-view.tsx | 18 +++--------------- .../workspace-tab-state-provider.tsx | 5 ++--- packages/compass-workspaces/src/provider.tsx | 2 +- .../src/stores/workspaces.ts | 2 +- 5 files changed, 7 insertions(+), 22 deletions(-) diff --git a/packages/compass-crud/src/components/document-list.tsx b/packages/compass-crud/src/components/document-list.tsx index 1ee84a0e89d..5d6de4e5cce 100644 --- a/packages/compass-crud/src/components/document-list.tsx +++ b/packages/compass-crud/src/components/document-list.tsx @@ -165,7 +165,6 @@ const DocumentViewComponent: React.FunctionComponent< } const tableData = useWorkspaceTabTableData(); - const columnDefs = tableData.columnDefs.length ? tableData.columnDefs : null; if (props.view === 'List') { return ( @@ -192,7 +191,6 @@ const DocumentViewComponent: React.FunctionComponent< {...props} className={tableStyles} tableData={tableData} - columnDefs={columnDefs} /> ); diff --git a/packages/compass-crud/src/components/table-view/document-table-view.tsx b/packages/compass-crud/src/components/table-view/document-table-view.tsx index fdca51d163f..3bf5c25e349 100644 --- a/packages/compass-crud/src/components/table-view/document-table-view.tsx +++ b/packages/compass-crud/src/components/table-view/document-table-view.tsx @@ -73,7 +73,6 @@ export type DocumentTableViewProps = { className?: string; darkMode?: boolean; tableData: TableDataObject; - columnDefs: ColDef[] | null; }; export type GridContext = { @@ -134,7 +133,6 @@ class DocumentTableView extends React.Component { } return params.nextCellDef; }, - columnDefs: this.props.columnDefs, }, onGridReady: this.onGridReady.bind(this), isFullWidthCell: function (rowNode) { @@ -225,21 +223,10 @@ class DocumentTableView extends React.Component { */ onColumnResized(event: ColumnResizedEvent) { if (event.finished) { - const columnDefs = this.columnApi.columnController.columnDefs; const columnState = this.columnApi.getColumnState(); - - const columnWidths = columnState.reduce((acc, curr) => { - acc[curr.colId] = curr.width; - return acc; - }, {}); - - for (const columnDef of columnDefs) { - if (columnWidths[columnDef.colId] !== undefined) { - columnDef.width = columnWidths[columnDef.colId]; - } + for (const column of columnState) { + this.props.tableData.columnWidths[column.colId] = column.width; } - - this.props.tableData.columnDefs = columnDefs; } } @@ -878,6 +865,7 @@ class DocumentTableView extends React.Component { darkMode: this.props.darkMode, }, resizable: true, + width: this.props.tableData.columnWidths[String(path[path.length - 1])], }; }; diff --git a/packages/compass-workspaces/src/components/workspace-tab-state-provider.tsx b/packages/compass-workspaces/src/components/workspace-tab-state-provider.tsx index 62db6424490..6ac78a579a6 100644 --- a/packages/compass-workspaces/src/components/workspace-tab-state-provider.tsx +++ b/packages/compass-workspaces/src/components/workspace-tab-state-provider.tsx @@ -9,12 +9,11 @@ import type { ReactReduxContextValue, TypedUseSelectorHook } from 'react-redux'; import { Provider, createSelectorHook, createStoreHook } from 'react-redux'; import type { AnyAction } from 'redux'; import { createStore } from 'redux'; -import { ColDef } from 'ag-grid-community'; type TabState = Record>; export type TableDataObject = { - columnDefs: ColDef[]; + columnWidths: Record; }; const SET_STATE = 'compass-workspaces/workspace-tab-state-provider/SET_STATE'; @@ -74,7 +73,7 @@ export const TabStateStoreContext = React.createContext< const WorkspaceTabIdContext = React.createContext(null); const WorkspaceTabTableColumnDefsContext = React.createContext( { - columnDefs: [], + columnWidths: {}, } ); diff --git a/packages/compass-workspaces/src/provider.tsx b/packages/compass-workspaces/src/provider.tsx index ea95b14a0f0..e0c7428884f 100644 --- a/packages/compass-workspaces/src/provider.tsx +++ b/packages/compass-workspaces/src/provider.tsx @@ -379,12 +379,12 @@ export const workspacesServiceLocator = createServiceLocator( 'workspacesServiceLocator' ); +export type { TableDataObject } from './components/workspace-tab-state-provider'; export { useWorkspacePlugins } from './components/workspaces-provider'; export { useWorkspaceTabId, useTabState, useWorkspaceTabTableData, - TableDataObject, } from './components/workspace-tab-state-provider'; export { useOnTabClose, diff --git a/packages/compass-workspaces/src/stores/workspaces.ts b/packages/compass-workspaces/src/stores/workspaces.ts index 954bbdc267e..f931d93aaad 100644 --- a/packages/compass-workspaces/src/stores/workspaces.ts +++ b/packages/compass-workspaces/src/stores/workspaces.ts @@ -211,7 +211,7 @@ export const getInitialTabState = ( initialSubtab ?? (isAggregationsSubtab ? 'Aggregations' : 'Documents'); const tableData = { - columnDefs: [], + columnWidths: {}, }; return { From 2021e77e2f4fd97eefbc203afe6ec90f0fbd59d0 Mon Sep 17 00:00:00 2001 From: 7MIMIRA <7mimira@gmail.com> Date: Mon, 17 Nov 2025 03:37:35 -0500 Subject: [PATCH 07/10] Add test --- .../src/components/document-list.tsx | 8 +-- .../table-view/document-table-view.spec.tsx | 68 +++++++++++++++++++ .../table-view/document-table-view.tsx | 2 +- .../workspace-tab-state-provider.tsx | 14 ++-- 4 files changed, 76 insertions(+), 16 deletions(-) create mode 100644 packages/compass-crud/src/components/table-view/document-table-view.spec.tsx diff --git a/packages/compass-crud/src/components/document-list.tsx b/packages/compass-crud/src/components/document-list.tsx index 5d6de4e5cce..fc8bca1098c 100644 --- a/packages/compass-crud/src/components/document-list.tsx +++ b/packages/compass-crud/src/components/document-list.tsx @@ -1,10 +1,4 @@ -import React, { - useCallback, - useLayoutEffect, - useMemo, - useRef, - useContext, -} from 'react'; +import React, { useCallback, useLayoutEffect, useMemo, useRef } from 'react'; import { ObjectId } from 'bson'; import { Button, diff --git a/packages/compass-crud/src/components/table-view/document-table-view.spec.tsx b/packages/compass-crud/src/components/table-view/document-table-view.spec.tsx new file mode 100644 index 00000000000..655fc32b67f --- /dev/null +++ b/packages/compass-crud/src/components/table-view/document-table-view.spec.tsx @@ -0,0 +1,68 @@ +import React from 'react'; +import { mount } from 'enzyme'; +import type { ReactWrapper } from 'enzyme'; +import HadronDocument from 'hadron-document'; +import { expect } from 'chai'; +import sinon from 'sinon'; + +import DocumentTableView, { + DocumentTableView as RawDocumentTableView, +} from './document-table-view'; + +describe('', function () { + describe('#render', function () { + context('when the documents have objects for ids', function () { + const docs = [{ _id: '6909a21e9e548506e786c1e5', name: 'test-1' }]; + const hadronDocs = docs.map((doc) => new HadronDocument(doc)); + + let component: ReactWrapper; + beforeEach(function () { + component = mount( + + ); + }); + + afterEach(function () { + component?.unmount(); + }); + + it('columnWidths data gets applied to relevant grid column', async function () { + // Ensure we wait for GridReadyEvent so columnApi is set + await new Promise(setImmediate); + + const instance = component.find(RawDocumentTableView).instance(); + expect(instance).to.not.be.undefined; + + const columnState = instance.columnApi.getColumnState(); + const nameCol = columnState.find((column) => column.colId === 'name'); + const idCol = columnState.find((column) => column.colId === '_id'); + + expect(nameCol.width).to.equal(1337); + expect(idCol.width).to.equal(200); // Default width is 200 + }); + }); + }); +}); diff --git a/packages/compass-crud/src/components/table-view/document-table-view.tsx b/packages/compass-crud/src/components/table-view/document-table-view.tsx index 3bf5c25e349..e0fd7108f26 100644 --- a/packages/compass-crud/src/components/table-view/document-table-view.tsx +++ b/packages/compass-crud/src/components/table-view/document-table-view.tsx @@ -91,7 +91,7 @@ export type GridContext = { /** * Represents the table view of the documents tab. */ -class DocumentTableView extends React.Component { +export class DocumentTableView extends React.Component { AGGrid: React.ReactElement; collection: string; topLevel: boolean; diff --git a/packages/compass-workspaces/src/components/workspace-tab-state-provider.tsx b/packages/compass-workspaces/src/components/workspace-tab-state-provider.tsx index 6ac78a579a6..7ad72b4a288 100644 --- a/packages/compass-workspaces/src/components/workspace-tab-state-provider.tsx +++ b/packages/compass-workspaces/src/components/workspace-tab-state-provider.tsx @@ -71,11 +71,9 @@ export const TabStateStoreContext = React.createContext< ); const WorkspaceTabIdContext = React.createContext(null); -const WorkspaceTabTableColumnDefsContext = React.createContext( - { - columnWidths: {}, - } -); +const WorkspaceTabTableDataContext = React.createContext({ + columnWidths: {}, +}); /** * Exported for testing purposes only @@ -100,9 +98,9 @@ export const WorkspaceTabStateProvider = ({ }) => { return ( - + {children} - + ); }; @@ -121,7 +119,7 @@ export function useWorkspaceTabId() { } export function useWorkspaceTabTableData() { - return useContext(WorkspaceTabTableColumnDefsContext); + return useContext(WorkspaceTabTableDataContext); } const useStore: () => TabStateStore = createStoreHook(TabStateStoreContext); From 24f08bcdb3ac7d28180d3b49e496ae448573aef9 Mon Sep 17 00:00:00 2001 From: Jose Lopez <63031501+7MIMIRA@users.noreply.github.com> Date: Mon, 17 Nov 2025 05:07:02 -0500 Subject: [PATCH 08/10] Update packages/compass-crud/src/components/table-view/document-table-view.spec.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../src/components/table-view/document-table-view.spec.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compass-crud/src/components/table-view/document-table-view.spec.tsx b/packages/compass-crud/src/components/table-view/document-table-view.spec.tsx index 655fc32b67f..8ff3405751f 100644 --- a/packages/compass-crud/src/components/table-view/document-table-view.spec.tsx +++ b/packages/compass-crud/src/components/table-view/document-table-view.spec.tsx @@ -49,7 +49,7 @@ describe('', function () { component?.unmount(); }); - it('columnWidths data gets applied to relevant grid column', async function () { + it('columnWidths data is applied to the relevant grid column', async function () { // Ensure we wait for GridReadyEvent so columnApi is set await new Promise(setImmediate); From 7240a65fbea18e7472e21211266cfb41f393a3f3 Mon Sep 17 00:00:00 2001 From: 7MIMIRA <7mimira@gmail.com> Date: Tue, 18 Nov 2025 05:36:11 -0500 Subject: [PATCH 09/10] Use existing useTabState hook --- .../src/components/document-list.tsx | 25 +++++++++++++------ .../table-view/document-table-view.spec.tsx | 6 ++--- .../table-view/document-table-view.tsx | 19 ++++++++++---- .../workspace-tab-context-provider.tsx | 2 +- .../workspace-tab-state-provider.tsx | 17 +------------ packages/compass-workspaces/src/provider.tsx | 2 -- .../src/stores/workspaces.ts | 5 ---- 7 files changed, 36 insertions(+), 40 deletions(-) diff --git a/packages/compass-crud/src/components/document-list.tsx b/packages/compass-crud/src/components/document-list.tsx index fc8bca1098c..9fad7ddf7cf 100644 --- a/packages/compass-crud/src/components/document-list.tsx +++ b/packages/compass-crud/src/components/document-list.tsx @@ -32,10 +32,7 @@ import { import type { CrudStore, BSONObject, DocumentView } from '../stores/crud-store'; import { getToolbarSignal } from '../utils/toolbar-signal'; import BulkDeleteModal from './bulk-delete-modal'; -import { - useTabState, - useWorkspaceTabTableData, -} from '@mongodb-js/compass-workspaces/provider'; +import { useTabState } from '@mongodb-js/compass-workspaces/provider'; import { useIsLastAppliedQueryOutdated, useLastAppliedQuery, @@ -147,19 +144,25 @@ const DocumentViewComponent: React.FunctionComponent< initialScrollTop?: number; scrollTriggerRef?: React.Ref; scrollableContainerRef?: React.Ref; + columnWidths: Record; + setColumnWidths: ( + newState: + | Record + | ((prev: Record) => Record) + ) => void; } > = ({ initialScrollTop, scrollTriggerRef, scrollableContainerRef, + columnWidths, + setColumnWidths, ...props }) => { if (props.docs?.length === 0) { return null; } - const tableData = useWorkspaceTabTableData(); - if (props.view === 'List') { return ( ); @@ -424,6 +428,11 @@ const DocumentList: React.FunctionComponent = (props) => { ] ); + const [columnWidths, setColumnWidths] = useTabState>( + 'columnWidths', + {} + ); + const renderContent = useCallback( (scrollTriggerRef: React.Ref) => { let content = null; @@ -486,6 +495,8 @@ const DocumentList: React.FunctionComponent = (props) => { initialScrollTop={currentViewInitialScrollTop} scrollableContainerRef={scrollRef} scrollTriggerRef={scrollTriggerRef} + columnWidths={columnWidths} + setColumnWidths={setColumnWidths} /> ); } diff --git a/packages/compass-crud/src/components/table-view/document-table-view.spec.tsx b/packages/compass-crud/src/components/table-view/document-table-view.spec.tsx index 8ff3405751f..3682ad1805b 100644 --- a/packages/compass-crud/src/components/table-view/document-table-view.spec.tsx +++ b/packages/compass-crud/src/components/table-view/document-table-view.spec.tsx @@ -35,10 +35,8 @@ describe('', function () { }, }} resetColumns={sinon.spy()} - tableData={{ - columnWidths: { - name: 1337, - }, + columnWidths={{ + name: 1337, }} start={1} /> diff --git a/packages/compass-crud/src/components/table-view/document-table-view.tsx b/packages/compass-crud/src/components/table-view/document-table-view.tsx index e0fd7108f26..cff39c3f672 100644 --- a/packages/compass-crud/src/components/table-view/document-table-view.tsx +++ b/packages/compass-crud/src/components/table-view/document-table-view.tsx @@ -39,7 +39,6 @@ import type { ValueGetterParams, ColumnResizedEvent, } from 'ag-grid-community'; -import type { TableDataObject } from '@mongodb-js/compass-workspaces/provider'; const MIXED = 'Mixed' as const; @@ -72,7 +71,12 @@ export type DocumentTableViewProps = { tz: string; className?: string; darkMode?: boolean; - tableData: TableDataObject; + columnWidths: Record; + setColumnWidths: ( + newState: + | Record + | ((prev: Record) => Record) + ) => void; }; export type GridContext = { @@ -223,10 +227,15 @@ export class DocumentTableView extends React.Component { */ onColumnResized(event: ColumnResizedEvent) { if (event.finished) { - const columnState = this.columnApi.getColumnState(); + const columnState = this.columnApi?.getColumnState() || []; + const currentColumnWidths: Record = {}; for (const column of columnState) { - this.props.tableData.columnWidths[column.colId] = column.width; + if (column.width) currentColumnWidths[column.colId] = column.width; } + this.props.setColumnWidths((prev) => ({ + ...prev, + ...currentColumnWidths, + })); } } @@ -865,7 +874,7 @@ export class DocumentTableView extends React.Component { darkMode: this.props.darkMode, }, resizable: true, - width: this.props.tableData.columnWidths[String(path[path.length - 1])], + width: this.props.columnWidths[String(path[path.length - 1])], }; }; diff --git a/packages/compass-workspaces/src/components/workspace-tab-context-provider.tsx b/packages/compass-workspaces/src/components/workspace-tab-context-provider.tsx index 13329e650d9..a416e46c680 100644 --- a/packages/compass-workspaces/src/components/workspace-tab-context-provider.tsx +++ b/packages/compass-workspaces/src/components/workspace-tab-context-provider.tsx @@ -149,7 +149,7 @@ const WorkspaceTabContextProvider: React.FunctionComponent< } return ( - + >; -export type TableDataObject = { - columnWidths: Record; -}; - const SET_STATE = 'compass-workspaces/workspace-tab-state-provider/SET_STATE'; const CLEANUP_TAB_STATE = @@ -71,9 +67,6 @@ export const TabStateStoreContext = React.createContext< ); const WorkspaceTabIdContext = React.createContext(null); -const WorkspaceTabTableDataContext = React.createContext({ - columnWidths: {}, -}); /** * Exported for testing purposes only @@ -89,18 +82,14 @@ export const TabStoreProvider: React.FunctionComponent = ({ children }) => { export const WorkspaceTabStateProvider = ({ id, - tableData, children, }: { id: string; - tableData: TableDataObject; children: React.ReactChild; }) => { return ( - - {children} - + {children} ); }; @@ -118,10 +107,6 @@ export function useWorkspaceTabId() { return tabId; } -export function useWorkspaceTabTableData() { - return useContext(WorkspaceTabTableDataContext); -} - const useStore: () => TabStateStore = createStoreHook(TabStateStoreContext); const useSelector: TypedUseSelectorHook = diff --git a/packages/compass-workspaces/src/provider.tsx b/packages/compass-workspaces/src/provider.tsx index e0c7428884f..aa311c736c1 100644 --- a/packages/compass-workspaces/src/provider.tsx +++ b/packages/compass-workspaces/src/provider.tsx @@ -379,12 +379,10 @@ export const workspacesServiceLocator = createServiceLocator( 'workspacesServiceLocator' ); -export type { TableDataObject } from './components/workspace-tab-state-provider'; export { useWorkspacePlugins } from './components/workspaces-provider'; export { useWorkspaceTabId, useTabState, - useWorkspaceTabTableData, } from './components/workspace-tab-state-provider'; export { useOnTabClose, diff --git a/packages/compass-workspaces/src/stores/workspaces.ts b/packages/compass-workspaces/src/stores/workspaces.ts index f931d93aaad..9d588d1ead8 100644 --- a/packages/compass-workspaces/src/stores/workspaces.ts +++ b/packages/compass-workspaces/src/stores/workspaces.ts @@ -210,15 +210,10 @@ export const getInitialTabState = ( const subTab = initialSubtab ?? (isAggregationsSubtab ? 'Aggregations' : 'Documents'); - const tableData = { - columnWidths: {}, - }; - return { id: tabId, subTab, ...rest, - tableData, }; } return { id: tabId, ...workspace }; From 3273d6c2f8cdf392b86a1f78c8e6392401bf7d95 Mon Sep 17 00:00:00 2001 From: 7MIMIRA <7mimira@gmail.com> Date: Wed, 19 Nov 2025 13:37:12 -0500 Subject: [PATCH 10/10] Update implementation to follow established conventions --- .../src/components/document-list.tsx | 19 +++++++++++-------- .../table-view/document-table-view.tsx | 11 ++--------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/packages/compass-crud/src/components/document-list.tsx b/packages/compass-crud/src/components/document-list.tsx index 87224de587d..6d847994e64 100644 --- a/packages/compass-crud/src/components/document-list.tsx +++ b/packages/compass-crud/src/components/document-list.tsx @@ -146,18 +146,14 @@ const DocumentViewComponent: React.FunctionComponent< scrollTriggerRef?: React.Ref; scrollableContainerRef?: React.Ref; columnWidths: Record; - setColumnWidths: ( - newState: - | Record - | ((prev: Record) => Record) - ) => void; + onColumnWidthChange: (newColumnWidths: Record) => void; } > = ({ initialScrollTop, scrollTriggerRef, scrollableContainerRef, columnWidths, - setColumnWidths, + onColumnWidthChange, ...props }) => { if (props.docs?.length === 0) { @@ -189,7 +185,7 @@ const DocumentViewComponent: React.FunctionComponent< {...props} className={tableStyles} columnWidths={columnWidths} - setColumnWidths={setColumnWidths} + onColumnWidthChange={onColumnWidthChange} /> ); @@ -435,6 +431,13 @@ const DocumentList: React.FunctionComponent = (props) => { {} ); + const onColumnWidthChange = useCallback((newColumnWidths) => { + setColumnWidths({ + ...columnWidths, + ...newColumnWidths, + }); + }, []); + const renderContent = useCallback( (scrollTriggerRef: React.Ref) => { let content = null; @@ -498,7 +501,7 @@ const DocumentList: React.FunctionComponent = (props) => { scrollableContainerRef={scrollRef} scrollTriggerRef={scrollTriggerRef} columnWidths={columnWidths} - setColumnWidths={setColumnWidths} + onColumnWidthChange={onColumnWidthChange} /> ); } diff --git a/packages/compass-crud/src/components/table-view/document-table-view.tsx b/packages/compass-crud/src/components/table-view/document-table-view.tsx index cff39c3f672..798bfdd5ce3 100644 --- a/packages/compass-crud/src/components/table-view/document-table-view.tsx +++ b/packages/compass-crud/src/components/table-view/document-table-view.tsx @@ -72,11 +72,7 @@ export type DocumentTableViewProps = { className?: string; darkMode?: boolean; columnWidths: Record; - setColumnWidths: ( - newState: - | Record - | ((prev: Record) => Record) - ) => void; + onColumnWidthChange: (newColumnWidths: Record) => void; }; export type GridContext = { @@ -232,10 +228,7 @@ export class DocumentTableView extends React.Component { for (const column of columnState) { if (column.width) currentColumnWidths[column.colId] = column.width; } - this.props.setColumnWidths((prev) => ({ - ...prev, - ...currentColumnWidths, - })); + this.props.onColumnWidthChange(currentColumnWidths); } }