diff --git a/docs/data/data-grid/recipes-row-grouping/RowGroupingChildRowCount.js b/docs/data/data-grid/recipes-row-grouping/RowGroupingChildRowCount.js new file mode 100644 index 0000000000000..837ea2546b6bb --- /dev/null +++ b/docs/data/data-grid/recipes-row-grouping/RowGroupingChildRowCount.js @@ -0,0 +1,55 @@ +import * as React from 'react'; +import { + DataGridPremium, + useGridApiRef, + useGridSelector, + useKeepGroupedColumnsHidden, + useGridApiContext, + gridFilteredDescendantRowCountSelector, +} from '@mui/x-data-grid-premium'; +import { useMovieData } from '@mui/x-data-grid-generator'; +import { Box } from '@mui/material'; + +function CustomFooterRowCount(props) { + const { visibleRowCount: topLevelRowCount } = props; + const apiRef = useGridApiContext(); + const descendantRowCount = useGridSelector( + apiRef, + gridFilteredDescendantRowCountSelector, + ); + + return ( + + {descendantRowCount} row{descendantRowCount > 1 ? 's' : ''} in{' '} + {topLevelRowCount} group + {topLevelRowCount > 1 ? 's' : ''} + + ); +} + +export default function RowGroupingChildRowCount() { + const data = useMovieData(); + const apiRef = useGridApiRef(); + + const initialState = useKeepGroupedColumnsHidden({ + apiRef, + initialState: { + rowGrouping: { + model: ['company'], + }, + }, + }); + + return ( +
+ +
+ ); +} diff --git a/docs/data/data-grid/recipes-row-grouping/RowGroupingChildRowCount.tsx b/docs/data/data-grid/recipes-row-grouping/RowGroupingChildRowCount.tsx new file mode 100644 index 0000000000000..514aa8358b3cc --- /dev/null +++ b/docs/data/data-grid/recipes-row-grouping/RowGroupingChildRowCount.tsx @@ -0,0 +1,56 @@ +import * as React from 'react'; +import { + DataGridPremium, + GridRowCountProps, + useGridApiRef, + useGridSelector, + useKeepGroupedColumnsHidden, + useGridApiContext, + gridFilteredDescendantRowCountSelector, +} from '@mui/x-data-grid-premium'; +import { useMovieData } from '@mui/x-data-grid-generator'; +import { Box } from '@mui/material'; + +function CustomFooterRowCount(props: GridRowCountProps) { + const { visibleRowCount: topLevelRowCount } = props; + const apiRef = useGridApiContext(); + const descendantRowCount = useGridSelector( + apiRef, + gridFilteredDescendantRowCountSelector, + ); + + return ( + + {descendantRowCount} row{descendantRowCount > 1 ? 's' : ''} in{' '} + {topLevelRowCount} group + {topLevelRowCount > 1 ? 's' : ''} + + ); +} + +export default function RowGroupingChildRowCount() { + const data = useMovieData(); + const apiRef = useGridApiRef(); + + const initialState = useKeepGroupedColumnsHidden({ + apiRef, + initialState: { + rowGrouping: { + model: ['company'], + }, + }, + }); + + return ( +
+ +
+ ); +} diff --git a/docs/data/data-grid/recipes-row-grouping/RowGroupingChildRowCount.tsx.preview b/docs/data/data-grid/recipes-row-grouping/RowGroupingChildRowCount.tsx.preview new file mode 100644 index 0000000000000..f9d69b63cb0ae --- /dev/null +++ b/docs/data/data-grid/recipes-row-grouping/RowGroupingChildRowCount.tsx.preview @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/docs/data/data-grid/recipes-row-grouping/recipes-row-grouping.md b/docs/data/data-grid/recipes-row-grouping/recipes-row-grouping.md index 014bbd94411a6..90067a6eb2715 100644 --- a/docs/data/data-grid/recipes-row-grouping/recipes-row-grouping.md +++ b/docs/data/data-grid/recipes-row-grouping/recipes-row-grouping.md @@ -25,3 +25,11 @@ By default, the row grouping column uses `sortComparator` of the grouping column To sort the row groups by the number of child rows, you can override it using `groupingColDef.sortComparator`: {{"demo": "RowGroupingSortByChildRows.js", "bg": "inline", "defaultCodeOpen": false}} + +## Dispaying child row count in footer + +By default, the row count in the footer is the number of top level rows that are visible after filtering. + +In the demo below, a `CustomFooterRowCount` component is added to the `footerRowCount` slot. This component uses the `gridFilteredDescendantRowCountSelector` to get the number of child rows and display it alongside the number of groups. + +{{"demo": "RowGroupingChildRowCount.js", "bg": "inline", "defaultCodeOpen": false}} diff --git a/docs/pages/x/api/data-grid/selectors.json b/docs/pages/x/api/data-grid/selectors.json index 10cb5c8c44395..ad0e4aefd23db 100644 --- a/docs/pages/x/api/data-grid/selectors.json +++ b/docs/pages/x/api/data-grid/selectors.json @@ -194,6 +194,20 @@ "description": "Get the filterable columns as a lookup (an object containing the field for keys and the definition for values).", "supportsApiRef": true }, + { + "name": "gridFilteredDescendantRowCountSelector", + "returnType": "number", + "category": "Filtering", + "description": "Get the amount of descendant rows accessible after the filtering process.", + "supportsApiRef": true + }, + { + "name": "gridFilteredRowCountSelector", + "returnType": "number", + "category": "Filtering", + "description": "Get the amount of rows accessible after the filtering process.\nIncludes top level and descendant rows.", + "supportsApiRef": true + }, { "name": "gridFilteredSortedRowEntriesSelector", "returnType": "GridRowEntry[]", diff --git a/packages/x-data-grid/src/hooks/features/filter/gridFilterSelector.ts b/packages/x-data-grid/src/hooks/features/filter/gridFilterSelector.ts index 40fa6d9c6a3bd..9d376a2321f23 100644 --- a/packages/x-data-grid/src/hooks/features/filter/gridFilterSelector.ts +++ b/packages/x-data-grid/src/hooks/features/filter/gridFilterSelector.ts @@ -131,6 +131,26 @@ export const gridFilteredTopLevelRowCountSelector = createSelector( (visibleSortedTopLevelRows) => visibleSortedTopLevelRows.length, ); +/** + * Get the amount of rows accessible after the filtering process. + * Includes top level and descendant rows. + * @category Filtering + */ +export const gridFilteredRowCountSelector = createSelector( + gridFilteredSortedRowEntriesSelector, + (filteredSortedRowEntries) => filteredSortedRowEntries.length, +); + +/** + * Get the amount of descendant rows accessible after the filtering process. + * @category Filtering + */ +export const gridFilteredDescendantRowCountSelector = createSelector( + gridFilteredRowCountSelector, + gridFilteredTopLevelRowCountSelector, + (totalRowCount, topLevelRowCount) => totalRowCount - topLevelRowCount, +); + /** * @category Filtering * @ignore - do not document. diff --git a/scripts/x-data-grid-premium.exports.json b/scripts/x-data-grid-premium.exports.json index 12f86b8d61963..6ef4a77490067 100644 --- a/scripts/x-data-grid-premium.exports.json +++ b/scripts/x-data-grid-premium.exports.json @@ -324,6 +324,8 @@ { "name": "GridFilterAltIcon", "kind": "Variable" }, { "name": "GridFilterApi", "kind": "Interface" }, { "name": "gridFilteredDescendantCountLookupSelector", "kind": "Variable" }, + { "name": "gridFilteredDescendantRowCountSelector", "kind": "Variable" }, + { "name": "gridFilteredRowCountSelector", "kind": "Variable" }, { "name": "gridFilteredRowsLookupSelector", "kind": "Variable" }, { "name": "gridFilteredSortedRowEntriesSelector", "kind": "Variable" }, { "name": "gridFilteredSortedRowIdsSelector", "kind": "Variable" }, diff --git a/scripts/x-data-grid-pro.exports.json b/scripts/x-data-grid-pro.exports.json index 22f8ca72e6d0d..8d972b055ecc6 100644 --- a/scripts/x-data-grid-pro.exports.json +++ b/scripts/x-data-grid-pro.exports.json @@ -293,6 +293,8 @@ { "name": "GridFilterAltIcon", "kind": "Variable" }, { "name": "GridFilterApi", "kind": "Interface" }, { "name": "gridFilteredDescendantCountLookupSelector", "kind": "Variable" }, + { "name": "gridFilteredDescendantRowCountSelector", "kind": "Variable" }, + { "name": "gridFilteredRowCountSelector", "kind": "Variable" }, { "name": "gridFilteredRowsLookupSelector", "kind": "Variable" }, { "name": "gridFilteredSortedRowEntriesSelector", "kind": "Variable" }, { "name": "gridFilteredSortedRowIdsSelector", "kind": "Variable" }, diff --git a/scripts/x-data-grid.exports.json b/scripts/x-data-grid.exports.json index ec3c2edb53e86..3d911f1ed3776 100644 --- a/scripts/x-data-grid.exports.json +++ b/scripts/x-data-grid.exports.json @@ -263,6 +263,8 @@ { "name": "GridFilterAltIcon", "kind": "Variable" }, { "name": "GridFilterApi", "kind": "Interface" }, { "name": "gridFilteredDescendantCountLookupSelector", "kind": "Variable" }, + { "name": "gridFilteredDescendantRowCountSelector", "kind": "Variable" }, + { "name": "gridFilteredRowCountSelector", "kind": "Variable" }, { "name": "gridFilteredRowsLookupSelector", "kind": "Variable" }, { "name": "gridFilteredSortedRowEntriesSelector", "kind": "Variable" }, { "name": "gridFilteredSortedRowIdsSelector", "kind": "Variable" },