Skip to content

Commit

Permalink
[DataGridPremium] Automatic parents and children selection (#13757)
Browse files Browse the repository at this point in the history
Signed-off-by: Bilal Shafi <[email protected]>
Co-authored-by: José Rodolfo Freitas <[email protected]>
Co-authored-by: Andrew Cherniavskii <[email protected]>
  • Loading branch information
3 people authored Oct 4, 2024
1 parent c39b734 commit 978a438
Show file tree
Hide file tree
Showing 22 changed files with 1,380 additions and 59 deletions.
72 changes: 72 additions & 0 deletions docs/data/data-grid/row-grouping/RowGroupingPropagateSelection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import * as React from 'react';
import {
DataGridPremium,
useGridApiRef,
useKeepGroupedColumnsHidden,
} from '@mui/x-data-grid-premium';
import { useMovieData } from '@mui/x-data-grid-generator';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import Stack from '@mui/material/Stack';

export default function RowGroupingPropagateSelection() {
const data = useMovieData();
const apiRef = useGridApiRef();
const [rowSelectionPropagation, setRowSelectionPropagation] = React.useState({
parents: true,
descendants: true,
});

const initialState = useKeepGroupedColumnsHidden({
apiRef,
initialState: {
rowGrouping: {
model: ['company', 'director'],
},
},
});

return (
<div style={{ width: '100%' }}>
<Stack direction="row" spacing={2}>
<FormControlLabel
control={
<Checkbox
checked={rowSelectionPropagation.descendants}
onChange={(event) =>
setRowSelectionPropagation((prev) => ({
...prev,
descendants: event.target.checked,
}))
}
/>
}
label="Auto select descendants"
/>
<FormControlLabel
control={
<Checkbox
checked={rowSelectionPropagation.parents}
onChange={(event) =>
setRowSelectionPropagation((prev) => ({
...prev,
parents: event.target.checked,
}))
}
/>
}
label="Auto select parents"
/>
</Stack>
<div style={{ height: 400 }}>
<DataGridPremium
{...data}
apiRef={apiRef}
initialState={initialState}
checkboxSelection
rowSelectionPropagation={rowSelectionPropagation}
/>
</div>
</div>
);
}
74 changes: 74 additions & 0 deletions docs/data/data-grid/row-grouping/RowGroupingPropagateSelection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import * as React from 'react';
import {
DataGridPremium,
useGridApiRef,
useKeepGroupedColumnsHidden,
GridRowSelectionPropagation,
} from '@mui/x-data-grid-premium';
import { useMovieData } from '@mui/x-data-grid-generator';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import Stack from '@mui/material/Stack';

export default function RowGroupingPropagateSelection() {
const data = useMovieData();
const apiRef = useGridApiRef();
const [rowSelectionPropagation, setRowSelectionPropagation] =
React.useState<GridRowSelectionPropagation>({
parents: true,
descendants: true,
});

const initialState = useKeepGroupedColumnsHidden({
apiRef,
initialState: {
rowGrouping: {
model: ['company', 'director'],
},
},
});

return (
<div style={{ width: '100%' }}>
<Stack direction="row" spacing={2}>
<FormControlLabel
control={
<Checkbox
checked={rowSelectionPropagation.descendants}
onChange={(event) =>
setRowSelectionPropagation((prev) => ({
...prev,
descendants: event.target.checked,
}))
}
/>
}
label="Auto select descendants"
/>
<FormControlLabel
control={
<Checkbox
checked={rowSelectionPropagation.parents}
onChange={(event) =>
setRowSelectionPropagation((prev) => ({
...prev,
parents: event.target.checked,
}))
}
/>
}
label="Auto select parents"
/>
</Stack>
<div style={{ height: 400 }}>
<DataGridPremium
{...data}
apiRef={apiRef}
initialState={initialState}
checkboxSelection
rowSelectionPropagation={rowSelectionPropagation}
/>
</div>
</div>
);
}
44 changes: 44 additions & 0 deletions docs/data/data-grid/row-grouping/row-grouping.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,50 @@ In the example below:
If you are dynamically switching the `leafField` or `mainGroupingCriteria`, the sorting and filtering models will not be cleaned up automatically, and the sorting/filtering will not be re-applied.
:::

## Automatic parents and children selection

By default, selecting a parent row does not select its children.
You can override this behavior by using the `rowSelectionPropagation` prop.

Here's how it's structured:

```ts
type GridRowSelectionPropagation = {
descendants?: boolean; // default: false
parents?: boolean; // default: false
};
```

When `rowSelectionPropagation.descendants` is set to `true`.

- Selecting a parent would auto-select all its filtered descendants.
- Deselecting a parent row would auto-deselect all its filtered descendants.

When `rowSelectionPropagation.parents` is set to `true`.

- Selecting all the filtered descendants of a parent would auto-select the parent.
- Deselecting a descendant of a selected parent would auto-deselect the parent.

The example below demonstrates the usage of the `rowSelectionPropagation` prop.

{{"demo": "RowGroupingPropagateSelection.js", "bg": "inline", "defaultCodeOpen": false}}

:::info
The row selection propagation also affects the "Select all" checkbox like any other group checkbox.
:::

:::info
The selected rows that do not pass the filtering criteria are automatically deselected when the filter is applied. Row selection propagation is not applied to the unfiltered rows.
:::

:::warning
If `props.disableMultipleRowSelection` is set to `true`, the row selection propagation doesn't apply.
:::

:::warning
Row selection propagation is a client-side feature and is not supported with the [server-side data source](/x/react-data-grid/server-side-data/).
:::

## Get the rows in a group

You can use the `apiRef.current.getRowGroupChildren` method to get the id of all rows contained in a group.
Expand Down
4 changes: 4 additions & 0 deletions docs/data/data-grid/tree-data/tree-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ If you want to access the grouping column field, for instance, to use it with co

Same behavior as for the [Row grouping](/x/react-data-grid/row-grouping/#group-expansion).

## Automatic parents and children selection

Same behavior as for the [Row grouping](/x/react-data-grid/row-grouping/#automatic-parents-and-children-selection).

## Gaps in the tree

If some entries are missing to build the full tree, the `DataGridPro` will automatically create rows to fill those gaps.
Expand Down
4 changes: 4 additions & 0 deletions docs/pages/x/api/data-grid/data-grid-premium.json
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,10 @@
"description": "Array&lt;number<br>&#124;&nbsp;string&gt;<br>&#124;&nbsp;number<br>&#124;&nbsp;string"
}
},
"rowSelectionPropagation": {
"type": { "name": "shape", "description": "{ descendants?: bool, parents?: bool }" },
"default": "{ parents: false, descendants: false }"
},
"rowsLoadingMode": {
"type": { "name": "enum", "description": "'client'<br>&#124;&nbsp;'server'" }
},
Expand Down
4 changes: 4 additions & 0 deletions docs/pages/x/api/data-grid/data-grid-pro.json
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,10 @@
"description": "Array&lt;number<br>&#124;&nbsp;string&gt;<br>&#124;&nbsp;number<br>&#124;&nbsp;string"
}
},
"rowSelectionPropagation": {
"type": { "name": "shape", "description": "{ descendants?: bool, parents?: bool }" },
"default": "{ parents: false, descendants: false }"
},
"rowsLoadingMode": {
"type": { "name": "enum", "description": "'client'<br>&#124;&nbsp;'server'" }
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@
"groupingColDef": { "description": "The grouping column used by the tree data." },
"headerFilterHeight": { "description": "Override the height of the header filters." },
"headerFilters": {
"description": "If <code>true</code>, enables the data grid filtering on header feature."
"description": "If <code>true</code>, the header filters feature is enabled."
},
"hideFooter": { "description": "If <code>true</code>, the footer component is hidden." },
"hideFooterPagination": {
Expand Down Expand Up @@ -610,6 +610,9 @@
"rows": { "description": "Set of rows of type GridRowsProp." },
"rowSelection": { "description": "If <code>false</code>, the row selection mode is disabled." },
"rowSelectionModel": { "description": "Sets the row selection model of the Data Grid." },
"rowSelectionPropagation": {
"description": "When <code>rowSelectionPropagation.descendants</code> is set to <code>true</code>. - Selecting a parent will auto-select all its filtered descendants. - Deselecting a parent will auto-deselect all its filtered descendants.<br>When <code>rowSelectionPropagation.parents=true</code> - Selecting all descendants of a parent would auto-select it. - Deselecting a descendant of a selected parent would deselect the parent.<br>Works with tree data and row grouping on the client-side only."
},
"rowsLoadingMode": {
"description": "Loading rows can be processed on the server or client-side. Set it to &#39;client&#39; if you would like enable infnite loading. Set it to &#39;server&#39; if you would like to enable lazy loading. * @default &quot;client&quot;"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
"groupingColDef": { "description": "The grouping column used by the tree data." },
"headerFilterHeight": { "description": "Override the height of the header filters." },
"headerFilters": {
"description": "If <code>true</code>, enables the data grid filtering on header feature."
"description": "If <code>true</code>, the header filters feature is enabled."
},
"hideFooter": { "description": "If <code>true</code>, the footer component is hidden." },
"hideFooterPagination": {
Expand Down Expand Up @@ -552,6 +552,9 @@
"rows": { "description": "Set of rows of type GridRowsProp." },
"rowSelection": { "description": "If <code>false</code>, the row selection mode is disabled." },
"rowSelectionModel": { "description": "Sets the row selection model of the Data Grid." },
"rowSelectionPropagation": {
"description": "When <code>rowSelectionPropagation.descendants</code> is set to <code>true</code>. - Selecting a parent will auto-select all its filtered descendants. - Deselecting a parent will auto-deselect all its filtered descendants.<br>When <code>rowSelectionPropagation.parents=true</code> - Selecting all descendants of a parent would auto-select it. - Deselecting a descendant of a selected parent would deselect the parent.<br>Works with tree data and row grouping on the client-side only."
},
"rowsLoadingMode": {
"description": "Loading rows can be processed on the server or client-side. Set it to &#39;client&#39; if you would like enable infnite loading. Set it to &#39;server&#39; if you would like to enable lazy loading. * @default &quot;client&quot;"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ DataGridPremiumRaw.propTypes = {
*/
headerFilterHeight: PropTypes.number,
/**
* If `true`, enables the data grid filtering on header feature.
* If `true`, the header filters feature is enabled.
* @default false
*/
headerFilters: PropTypes.bool,
Expand Down Expand Up @@ -985,6 +985,22 @@ DataGridPremiumRaw.propTypes = {
PropTypes.number,
PropTypes.string,
]),
/**
* When `rowSelectionPropagation.descendants` is set to `true`.
* - Selecting a parent will auto-select all its filtered descendants.
* - Deselecting a parent will auto-deselect all its filtered descendants.
*
* When `rowSelectionPropagation.parents=true`
* - Selecting all descendants of a parent would auto-select it.
* - Deselecting a descendant of a selected parent would deselect the parent.
*
* Works with tree data and row grouping on the client-side only.
* @default { parents: false, descendants: false }
*/
rowSelectionPropagation: PropTypes.shape({
descendants: PropTypes.bool,
parents: PropTypes.bool,
}),
/**
* Loading rows can be processed on the server or client-side.
* Set it to 'client' if you would like enable infnite loading.
Expand Down
Loading

0 comments on commit 978a438

Please sign in to comment.