Skip to content

Commit e7da1f7

Browse files
authored
Merge pull request #2238 from dxc-technology/Mil4n0r/datagrid-state-fix
Fix for `DxcDatagrid` state maintenance using hierarchy + selectable rows
2 parents 4e0937f + 10c2806 commit e7da1f7

File tree

3 files changed

+51
-41
lines changed

3 files changed

+51
-41
lines changed

apps/website/screens/components/data-grid/code/examples/hierarchicalSelectable.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { DxcDataGrid, DxcInset } from "@dxc-technology/halstack-react";
22
import { useState } from "react";
33

44
const code = `() => {
5-
const columns = [
5+
const [columns] = useState([
66
{
77
key: "name",
88
label: "Label",
@@ -14,9 +14,9 @@ const code = `() => {
1414
alignment: "right",
1515
summaryKey: "total"
1616
},
17-
];
18-
19-
const rows = [
17+
]);
18+
19+
const [rows] = useState([
2020
{
2121
name: "Root Node 1",
2222
value: "1",
@@ -75,7 +75,7 @@ const code = `() => {
7575
},
7676
],
7777
},
78-
];
78+
]);
7979
8080
const [selectedRows, setSelectedRows] = useState(new Set());
8181
return (

packages/lib/src/data-grid/DataGrid.tsx

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
getPaginatedNodes,
1919
getMinItemsPerPageIndex,
2020
getMaxItemsPerPageIndex,
21+
expandRow,
2122
} from "./utils";
2223
import DxcPaginator from "../paginator/Paginator";
2324
import { DxcActionsCell } from "../table/Table";
@@ -171,7 +172,7 @@ const DxcDataGrid = ({
171172
totalItems,
172173
defaultPage = 1,
173174
}: DataGridPropsType): JSX.Element => {
174-
const [rowsToRender, setRowsToRender] = useState<GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]>(rows);
175+
const [rowsToRender, setRowsToRender] = useState<GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]>([...rows]);
175176
const [page, changePage] = useState(defaultPage);
176177
const [colHeight, setColHeight] = useState(36);
177178

@@ -292,20 +293,14 @@ const DxcDataGrid = ({
292293
useEffect(() => {
293294
const finalRows = [...rows];
294295
if (expandable) {
295-
rows.forEach((row, index) => {
296-
if (
297-
row.contentIsExpanded &&
298-
!rows.some((row) => row[uniqueRowId] === `${rowKeyGetter(row, uniqueRowId)}_expanded`)
299-
) {
300-
addRow(finalRows, index + 1, {
301-
isExpandedChildContent: row.contentIsExpanded,
302-
[uniqueRowId]: `${rowKeyGetter(row, uniqueRowId)}_expanded`,
303-
expandedChildContent: row.expandedContent,
304-
triggerRowKey: rowKeyGetter(row, uniqueRowId),
305-
expandedContentHeight: row.expandedContentHeight,
306-
});
307-
}
308-
});
296+
finalRows
297+
.filter((row) => {
298+
const rowId = rowKeyGetter(row, uniqueRowId);
299+
return row.contentIsExpanded && !rows.some((r) => r[uniqueRowId] === `${rowId}_expanded`);
300+
})
301+
.forEach((row) => {
302+
expandRow(row, finalRows, uniqueRowId);
303+
});
309304
}
310305
setRowsToRender(finalRows);
311306
}, [rows]);

packages/lib/src/data-grid/utils.tsx

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,35 @@ export const renderSortStatus = ({ sortDirection }: RenderSortStatusProps) => (
5959
</div>
6060
);
6161

62+
/**
63+
* Expands a given row by inserting a new child row with the expanded content.
64+
* @param {ExpandableGridRow} row - The row object to expand.
65+
* @param {ExpandableGridRow[]} rows - The current list of all rows (as rendered).
66+
* @param {string} uniqueRowId - Unique identifier key used for each row.
67+
*/
68+
export const expandRow = (row: ExpandableGridRow, rows: ExpandableGridRow[], uniqueRowId: string) => {
69+
const rowIndex = rows.findIndex((r) => r === row);
70+
addRow(rows, rowIndex + 1, {
71+
isExpandedChildContent: true,
72+
[uniqueRowId]: `${rowKeyGetter(row, uniqueRowId)}_expanded`,
73+
expandedChildContent: row.expandedContent,
74+
triggerRowKey: rowKeyGetter(row, uniqueRowId),
75+
expandedContentHeight: row.expandedContentHeight,
76+
});
77+
};
78+
79+
/**
80+
* Collapses a given row by removing its expanded child row.
81+
* @param {ExpandableGridRow} row - The row object to collapse.
82+
* @param {ExpandableGridRow[]} rows - The current list of all rows (as rendered).
83+
*/
84+
export const collapseRow = (row: ExpandableGridRow, rows: ExpandableGridRow[]) => {
85+
const rowIndex = rows.findIndex((r) => r === row);
86+
const newRows = [...rows];
87+
deleteRow(newRows, rowIndex + 1);
88+
return newRows;
89+
};
90+
6291
/**
6392
* Renders an expandable trigger icon that toggles row expansion.
6493
* @param {ExpandableGridRow} row - Row object that can be expanded or collapsed.
@@ -80,25 +109,13 @@ export const renderExpandableTrigger = (
80109
onClick={() => {
81110
row.contentIsExpanded = !row.contentIsExpanded;
82111
if (row.contentIsExpanded) {
83-
const rowIndex = rows.findIndex((rowToRender) => row === rowToRender);
84112
setRowsToRender((currentRows) => {
85-
const newRows = [...currentRows];
86-
addRow(newRows, rowIndex + 1, {
87-
isExpandedChildContent: row.contentIsExpanded,
88-
[uniqueRowId]: `${rowKeyGetter(row, uniqueRowId)}_expanded`,
89-
expandedChildContent: row.expandedContent,
90-
triggerRowKey: rowKeyGetter(row, uniqueRowId),
91-
expandedContentHeight: row.expandedContentHeight,
92-
});
93-
return newRows;
113+
const finalRows = [...currentRows];
114+
expandRow(row, finalRows, uniqueRowId);
115+
return finalRows;
94116
});
95117
} else {
96-
const rowIndex = rows.findIndex((rowToRender) => row === rowToRender);
97-
setRowsToRender((currentRows) => {
98-
const newRows = [...currentRows];
99-
deleteRow(newRows, rowIndex + 1);
100-
return newRows;
101-
});
118+
setRowsToRender((currentRows) => collapseRow(row, [...currentRows]));
102119
}
103120
}}
104121
disabled={!rows.some((row) => uniqueRowId in row)}
@@ -136,11 +153,9 @@ export const renderHierarchyTrigger = (
136153
});
137154
} else {
138155
// The children of the row that is being collapsed are added to an array
139-
const rowsToRemove: HierarchyGridRow[] = [
140-
...rows.filter(
141-
(rowToRender) => rowToRender.parentKey && rowToRender.parentKey === rowKeyGetter(triggerRow, uniqueRowId)
142-
),
143-
];
156+
const rowsToRemove: HierarchyGridRow[] = rows.filter(
157+
(rowToRender) => rowToRender.parentKey && rowToRender.parentKey === rowKeyGetter(triggerRow, uniqueRowId)
158+
);
144159
// The children are checked if any of them has any other children of their own
145160
const rowsToCheck = [...rowsToRemove];
146161
while (rowsToCheck.length > 0) {

0 commit comments

Comments
 (0)