Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DataGrid] Refactor row state propagation #15627

Merged
merged 60 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
45f52f9
experimental fix for row state propagation
lauri865 Nov 27, 2024
7d6833c
rebase fix tests
lauri865 Nov 28, 2024
e73f872
fix tests
lauri865 Nov 28, 2024
9b63559
update api
lauri865 Nov 28, 2024
28ed635
fix e2e
lauri865 Nov 28, 2024
b3d87f7
refactor getCellParams into two methods
lauri865 Dec 2, 2024
a1db0cb
rebuild api
lauri865 Dec 2, 2024
9295e5d
refactor: selector with argument
romgrk Dec 10, 2024
cbd3793
refactor: remove EMPTY_CELL_PARAMS
romgrk Dec 10, 2024
72507ac
perf: avoid spread operator
romgrk Dec 10, 2024
d02033b
manual rebase
lauri865 Dec 19, 2024
33cc4c9
improve editing state selectors and separation between row and column…
lauri865 Dec 19, 2024
76d22ae
remove checkbox shallowcompare as it's incompatible with v8 selectors
lauri865 Dec 19, 2024
1f95e27
fix
lauri865 Dec 19, 2024
f89f70e
fix2
lauri865 Dec 19, 2024
28373b7
Merge branch 'master' into fix-grid-row-state-propagation
lauri865 Dec 20, 2024
8c3d5cb
use normal selector for DetailPanelToggleCell
lauri865 Dec 20, 2024
1b60107
fix private api being exported
lauri865 Dec 21, 2024
d84764d
Merge branch 'master' into fix-grid-row-state-propagation
lauri865 Dec 21, 2024
ce54c27
export type
lauri865 Dec 21, 2024
c61278c
fix column pinning state propagation
lauri865 Dec 21, 2024
e3eb6dd
rehydrate columns only when outerwidth changes (instead of inner)
lauri865 Dec 21, 2024
c22c4d9
fix resize / column hydration
lauri865 Dec 22, 2024
2810949
rehydrate columns on resize only if there are flex columns present
lauri865 Dec 22, 2024
1417385
fix
lauri865 Dec 22, 2024
4e14aa7
test fix
lauri865 Dec 22, 2024
b705c62
fix tests
lauri865 Dec 22, 2024
c5160ea
breaking fix: `viewportInnerWidth` should include `pinnedColumns`
lauri865 Dec 22, 2024
7ec0af7
cleanup
lauri865 Dec 22, 2024
fa8f8cf
Merge branch 'master' into fix-grid-row-state-propagation
lauri865 Dec 23, 2024
9d9278e
Merge branch 'master' into fix-grid-row-state-propagation
lauri865 Jan 14, 2025
c1d7023
Merge branch 'master' into fix-grid-row-state-propagation
lauri865 Jan 15, 2025
5f190d6
lint
lauri865 Jan 15, 2025
cb16f18
ci
lauri865 Jan 15, 2025
07d71b7
fix scroll logic
lauri865 Jan 15, 2025
e046e93
fix row spanning
lauri865 Jan 15, 2025
0ef9310
Merge remote-tracking branch 'upstream/master' into fix-grid-row-stat…
lauri865 Jan 16, 2025
0eaafcb
fix subpixel inconsistencies
lauri865 Jan 17, 2025
6a7383e
Merge remote-tracking branch 'upstream/master' into fix-grid-row-stat…
lauri865 Jan 17, 2025
0334141
fix deleting rows
lauri865 Jan 20, 2025
0d99303
reduce the use of useGridVisibleRows on root level
lauri865 Jan 20, 2025
a6af9ee
fix lazy loading
lauri865 Jan 20, 2025
c4c84f7
Merge remote-tracking branch 'upstream/master' into fix-grid-row-stat…
lauri865 Jan 20, 2025
9edcaeb
perf: use memoized selector for pinned rows enrichment
lauri865 Jan 20, 2025
fbd581a
use concat instead of spread
lauri865 Jan 20, 2025
d07e4ad
fix listView state propagation
lauri865 Jan 20, 2025
ced72c5
fix restore focus on row removal
lauri865 Jan 20, 2025
9d5c737
use rowId as index for rowIdToIndexMap
lauri865 Jan 21, 2025
009c3e5
Merge branch 'master' into fix-grid-row-state-propagation
lauri865 Jan 21, 2025
9e7486e
fix test calling `getRowIndexRelativeToVisibleRows` with incorrect ids
lauri865 Jan 21, 2025
4745a67
potential fix for flaky test
lauri865 Jan 21, 2025
0b383e7
actual fix for flaky test
lauri865 Jan 21, 2025
2a6c1dc
revert rowSpanning related change
lauri865 Jan 22, 2025
93d11d0
`getInitialRangeToProcess`
lauri865 Jan 22, 2025
da83729
refactor: rootDimensions => dimensions
romgrk Jan 24, 2025
cf2915f
refactor: gridIsRowReorderingEnabledSelector => isRowReorderingEnable…
romgrk Jan 24, 2025
654335c
refactor: Object.keys() => isObjectEmpty()
romgrk Jan 24, 2025
eff59c2
Merge branch 'master' into fix-grid-row-state-propagation
romgrk Jan 24, 2025
bbab47f
perf: remove object allocation
romgrk Jan 24, 2025
581119f
fix autoresize with pinned columns
lauri865 Jan 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions docs/data/data-grid/master-detail/FullWidthDetailPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@ import {
} from '@mui/x-data-grid-generator';

const getDetailPanelWidth = (gridDimensions) => {
return (
gridDimensions.viewportInnerSize.width +
gridDimensions.leftPinnedWidth +
gridDimensions.rightPinnedWidth
);
return gridDimensions.viewportInnerSize.width;
};

function DetailPanelContent({ row: rowProp }) {
Expand Down
6 changes: 1 addition & 5 deletions docs/data/data-grid/master-detail/FullWidthDetailPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,7 @@ import {
} from '@mui/x-data-grid-generator';

const getDetailPanelWidth = (gridDimensions: GridDimensions) => {
return (
gridDimensions.viewportInnerSize.width +
gridDimensions.leftPinnedWidth +
gridDimensions.rightPinnedWidth
);
return gridDimensions.viewportInnerSize.width;
};

function DetailPanelContent({ row: rowProp }: { row: Customer }) {
Expand Down
14 changes: 13 additions & 1 deletion docs/pages/x/api/data-grid/selectors.json
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@
"description": "",
"supportsApiRef": false
},
{
"name": "gridEditCellStateSelector",
"returnType": "GridEditCellProps<any>",
"description": "",
"supportsApiRef": true
},
{
"name": "gridEditRowsStateSelector",
"returnType": "GridEditingState",
Expand Down Expand Up @@ -403,6 +409,12 @@
"description": "",
"supportsApiRef": true
},
{
"name": "gridRowIsEditingSelector",
"returnType": "boolean",
"description": "",
"supportsApiRef": true
},
{
"name": "gridRowMaximumTreeDepthSelector",
"returnType": "number",
Expand Down Expand Up @@ -554,7 +566,7 @@
},
{
"name": "gridVisibleRowsSelector",
"returnType": "{ rows: GridRowEntry<GridValidRowModel>[]; range: { firstRowIndex: number; lastRowIndex: number } | null; rowToIndexMap: Map<GridValidRowModel, number> }",
"returnType": "{ rows: GridRowEntry<GridValidRowModel>[]; range: { firstRowIndex: number; lastRowIndex: number } | null; rowIdToIndexMap: Map<GridRowId, number> }",
"category": "Pagination",
"description": "Get the rows, range and rowIndex lookup map after filtering and sorting.\nDoes not contain the collapsed children.",
"supportsApiRef": true
Expand Down
2 changes: 1 addition & 1 deletion docs/translations/api-docs/data-grid/grid-api.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"getAllGroupDetails": { "description": "Returns the column group lookup." },
"getAllRowIds": { "description": "Gets the list of row ids." },
"getCellElement": {
"description": "Gets the underlying DOM element for a cell at the given <code>id</code> and <code>field</code>."
"description": "Gets the <a href=\"/x/api/data-grid/grid-cell-params/\">GridCellParams</a> object that is passed as argument in events."
},
"getCellMode": { "description": "Gets the mode of a cell." },
"getCellParams": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ export const useGridAggregationPreProcessors = (

rulesOnLastColumnHydration.current = aggregationRules;

apiRef.current.caches.aggregation.rulesOnLastColumnHydration = aggregationRules;

return columnsState;
},
[apiRef, props.aggregationFunctions, props.disableAggregation, props.unstable_dataSource],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,18 @@ describe('<DataGridPremium /> - Data source aggregation', () => {

it('should show aggregation option in the column menu', async () => {
const { user } = render(<TestDataSourceAggregation />);
await waitFor(() => {
expect(getRowsSpy.callCount).to.be.greaterThan(0);
});
await user.click(within(getColumnHeaderCell(0)).getByLabelText('Menu'));
expect(screen.queryByLabelText('Aggregation')).not.to.equal(null);
});

it('should not show aggregation option in the column menu when no aggregation function is defined', async () => {
const { user } = render(<TestDataSourceAggregation aggregationFunctions={{}} />);
await waitFor(() => {
expect(getRowsSpy.callCount).to.be.greaterThan(0);
});
await user.click(within(getColumnHeaderCell(0)).getByLabelText('Menu'));
expect(screen.queryByLabelText('Aggregation')).to.equal(null);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import composeClasses from '@mui/utils/composeClasses';
import { getDataGridUtilityClass, useGridSelector, GridRenderCellParams } from '@mui/x-data-grid';
import {
getDataGridUtilityClass,
useGridSelector,
GridRenderCellParams,
GridRowId,
} from '@mui/x-data-grid';
import { createSelector } from '@mui/x-data-grid/internals';
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
import { useGridApiContext } from '../hooks/utils/useGridApiContext';
import { DataGridProProcessedProps } from '../models/dataGridProProps';
import { gridDetailPanelExpandedRowsContentCacheSelector } from '../hooks/features/detailPanel/gridDetailPanelSelector';
import {
gridDetailPanelExpandedRowIdsSelector,
gridDetailPanelExpandedRowsContentCacheSelector,
} from '../hooks/features/detailPanel/gridDetailPanelSelector';
import { GridApiPro } from '../models';

type OwnerState = { classes: DataGridProProcessedProps['classes']; isExpanded: boolean };

Expand All @@ -19,8 +29,17 @@ const useUtilityClasses = (ownerState: OwnerState) => {
return composeClasses(slots, getDataGridUtilityClass, classes);
};

const isExpandedSelector = createSelector(
gridDetailPanelExpandedRowIdsSelector,
(expandedRowIds, rowId: GridRowId) => {
return expandedRowIds.has(rowId);
},
);

function GridDetailPanelToggleCell(props: GridRenderCellParams) {
const { id, value: isExpanded } = props;
const { id, row, api } = props;
const rowId = api.getRowId(row);
const isExpanded = useGridSelector({ current: api as GridApiPro }, isExpandedSelector, rowId);

const rootProps = useGridRootProps();
const apiRef = useGridApiContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ export const useGridColumnPinning = (
const setPinnedColumns = React.useCallback<GridColumnPinningApi['setPinnedColumns']>(
(newPinnedColumns) => {
setState(apiRef, newPinnedColumns);
apiRef.current.forceUpdate();
apiRef.current.requestPipeProcessorsApplication('hydrateColumns');
},
[apiRef],
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import * as React from 'react';
import { RefObject } from '@mui/x-internals/types';
import {
GridPinnedColumnFields,
GridPipeProcessor,
gridPinnedColumnsSelector,
useGridRegisterPipeProcessor,
eslintUseValue,
gridVisiblePinnedColumnDefinitionsSelector,
} from '@mui/x-data-grid/internals';
import { DataGridProProcessedProps } from '../../../models/dataGridProProps';
Expand All @@ -17,19 +14,10 @@ export const useGridColumnPinningPreProcessors = (
) => {
const { disableColumnPinning } = props;

let pinnedColumns: GridPinnedColumnFields | null;
if (apiRef.current.state.columns) {
pinnedColumns = gridPinnedColumnsSelector(apiRef.current.state);
} else {
pinnedColumns = null;
}

const prevAllPinnedColumns = React.useRef<string[]>([]);

const reorderPinnedColumns = React.useCallback<GridPipeProcessor<'hydrateColumns'>>(
(columnsState) => {
eslintUseValue(pinnedColumns);

if (columnsState.orderedFields.length === 0 || disableColumnPinning) {
return columnsState;
}
Expand Down Expand Up @@ -132,7 +120,7 @@ export const useGridColumnPinningPreProcessors = (
orderedFields: [...leftPinnedColumns, ...centerColumns, ...rightPinnedColumns],
};
},
[apiRef, disableColumnPinning, pinnedColumns],
[apiRef, disableColumnPinning],
);

useGridRegisterPipeProcessor(apiRef, 'hydrateColumns', reorderPinnedColumns);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,13 +235,13 @@ export const useGridDataSourceLazyLoader = (
const newLoadingTrigger =
rowCount === -1 ? LoadingTrigger.SCROLL_END : LoadingTrigger.VIEWPORT;

if (loadingTrigger.current !== newLoadingTrigger) {
loadingTrigger.current = newLoadingTrigger;
}

if (loadingTrigger.current !== null) {
ensureValidRowCount(loadingTrigger.current, newLoadingTrigger);
}

if (loadingTrigger.current !== newLoadingTrigger) {
loadingTrigger.current = newLoadingTrigger;
}
},
[ensureValidRowCount],
);
Expand Down
50 changes: 33 additions & 17 deletions packages/x-data-grid/src/components/GridRow.tsx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It also seems like the below code doesn't seem to serve any function, as it always returns 0 for cellOffset, at least after the state propagation has been fixed.

This element is necessary for virtualization to work:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, makes total sense. Thanks! 🙏

Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import clsx from 'clsx';
import { unstable_useForkRef as useForkRef } from '@mui/utils';
import { fastMemo } from '@mui/x-internals/fastMemo';
import { forwardRef } from '@mui/x-internals/forwardRef';
import { isObjectEmpty } from '@mui/x-internals/isObjectEmpty';
import { GridRowEventLookup } from '../models/events';
import { GridRowId, GridRowModel } from '../models/gridRows';
import { GridEditModes, GridRowModes, GridCellModes } from '../models/gridEditRowModel';
import { GridEditModes, GridCellModes } from '../models/gridEditRowModel';
import { gridClasses } from '../constants/gridClasses';
import { composeGridClasses } from '../utils/composeGridClasses';
import { useGridRootProps } from '../hooks/utils/useGridRootProps';
Expand All @@ -24,11 +25,26 @@ import { GRID_ACTIONS_COLUMN_TYPE } from '../colDef/gridActionsColDef';
import { GRID_DETAIL_PANEL_TOGGLE_FIELD, PinnedColumnPosition } from '../internals/constants';
import { gridSortModelSelector } from '../hooks/features/sorting/gridSortingSelector';
import { gridRowMaximumTreeDepthSelector } from '../hooks/features/rows/gridRowsSelector';
import { gridEditRowsStateSelector } from '../hooks/features/editing/gridEditingSelectors';
import {
gridEditRowsStateSelector,
gridRowIsEditingSelector,
} from '../hooks/features/editing/gridEditingSelectors';
import { GridScrollbarFillerCell as ScrollbarFiller } from './GridScrollbarFillerCell';
import { getPinnedCellOffset } from '../internals/utils/getPinnedCellOffset';
import { useGridConfiguration } from '../hooks/utils/useGridConfiguration';
import { useGridPrivateApiContext } from '../hooks/utils/useGridPrivateApiContext';
import { createSelector } from '../utils/createSelector';

const isRowReorderingEnabledSelector = createSelector(
gridEditRowsStateSelector,
(editRows, rowReordering: boolean) => {
if (!rowReordering) {
return false;
}
const isEditingRows = !isObjectEmpty(editRows);
return !isEditingRows;
},
);

export interface GridRowProps extends React.HTMLAttributes<HTMLDivElement> {
row: GridRowModel;
Expand Down Expand Up @@ -104,10 +120,15 @@ const GridRow = forwardRef<HTMLDivElement, GridRowProps>(function GridRow(props,
const sortModel = useGridSelector(apiRef, gridSortModelSelector);
const treeDepth = useGridSelector(apiRef, gridRowMaximumTreeDepthSelector);
const columnPositions = useGridSelector(apiRef, gridColumnPositionsSelector);
const editRowsState = useGridSelector(apiRef, gridEditRowsStateSelector);
const rowReordering = (rootProps as any).rowReordering as boolean;
const isRowReorderingEnabled = useGridSelector(
apiRef,
isRowReorderingEnabledSelector,
rowReordering,
);
const handleRef = useForkRef(ref, refProp);
const rowNode = apiRef.current.getRowNode(rowId);
const editing = apiRef.current.getRowMode(rowId) === GridRowModes.Edit;
const editing = useGridSelector(apiRef, gridRowIsEditingSelector, rowId);
const editable = rootProps.editMode === GridEditModes.Row;
const hasFocusCell = focusedColumnIndex !== undefined;
const hasVirtualFocusCellLeft =
Expand Down Expand Up @@ -216,8 +237,6 @@ const GridRow = forwardRef<HTMLDivElement, GridRowProps>(function GridRow(props,

const { slots, slotProps, disableColumnReorder } = rootProps;

const rowReordering = (rootProps as any).rowReordering as boolean;

const heightEntry = useGridSelector(
apiRef,
() => ({ ...apiRef.current.getRowHeightEntry(rowId) }),
Expand Down Expand Up @@ -275,6 +294,11 @@ const GridRow = forwardRef<HTMLDivElement, GridRowProps>(function GridRow(props,
rowClassNames.push(rootProps.getRowClassName(rowParams));
}

/* Start of rendering */
if (!rowNode) {
return null;
}

const getCell = (
column: GridStateColDef,
indexInSection: number,
Expand Down Expand Up @@ -316,15 +340,12 @@ const GridRow = forwardRef<HTMLDivElement, GridRowProps>(function GridRow(props,
);
}

const editCellState = editRowsState[rowId]?.[column.field] ?? null;

// when the cell is a reorder cell we are not allowing to reorder the col
// fixes https://github.com/mui/mui-x/issues/11126
const isReorderCell = column.field === '__reorder__';
const isEditingRows = Object.keys(editRowsState).length > 0;

const canReorderColumn = !(disableColumnReorder || column.disableReorder);
const canReorderRow = rowReordering && !sortModel.length && treeDepth <= 1 && !isEditingRows;
const canReorderRow = isRowReorderingEnabled && !sortModel.length && treeDepth <= 1;

const disableDragEvents = !(canReorderColumn || (isReorderCell && canReorderRow));

Expand All @@ -349,23 +370,18 @@ const GridRow = forwardRef<HTMLDivElement, GridRowProps>(function GridRow(props,
colIndex={indexRelativeToAllColumns}
colSpan={colSpan}
disableDragEvents={disableDragEvents}
editCellState={editCellState}
isNotVisible={cellIsNotVisible}
pinnedOffset={pinnedOffset}
pinnedPosition={pinnedPosition}
showLeftBorder={showLeftBorder}
showRightBorder={showRightBorder}
row={row}
rowNode={rowNode}
{...slotProps?.cell}
/>
);
};

/* Start of rendering */

if (!rowNode) {
return null;
}

const leftCells = pinnedColumns.left.map((column, i) => {
const indexRelativeToAllColumns = i;
return getCell(
Expand Down
Loading
Loading