diff --git a/apps/website/screens/components/data-grid/code/examples/hierarchicalSelectable.ts b/apps/website/screens/components/data-grid/code/examples/hierarchicalSelectable.ts index 47de08593..8847aa7dd 100644 --- a/apps/website/screens/components/data-grid/code/examples/hierarchicalSelectable.ts +++ b/apps/website/screens/components/data-grid/code/examples/hierarchicalSelectable.ts @@ -2,7 +2,7 @@ import { DxcDataGrid, DxcInset } from "@dxc-technology/halstack-react"; import { useState } from "react"; const code = `() => { - const columns = [ + const [columns] = useState([ { key: "name", label: "Label", @@ -14,9 +14,9 @@ const code = `() => { alignment: "right", summaryKey: "total" }, - ]; - - const rows = [ + ]); + + const [rows] = useState([ { name: "Root Node 1", value: "1", @@ -75,7 +75,7 @@ const code = `() => { }, ], }, - ]; + ]); const [selectedRows, setSelectedRows] = useState(new Set()); return ( diff --git a/packages/lib/src/data-grid/DataGrid.tsx b/packages/lib/src/data-grid/DataGrid.tsx index 7a3b208fb..c836af1ae 100644 --- a/packages/lib/src/data-grid/DataGrid.tsx +++ b/packages/lib/src/data-grid/DataGrid.tsx @@ -18,6 +18,7 @@ import { getPaginatedNodes, getMinItemsPerPageIndex, getMaxItemsPerPageIndex, + expandRow, } from "./utils"; import DxcPaginator from "../paginator/Paginator"; import { DxcActionsCell } from "../table/Table"; @@ -171,7 +172,7 @@ const DxcDataGrid = ({ totalItems, defaultPage = 1, }: DataGridPropsType): JSX.Element => { - const [rowsToRender, setRowsToRender] = useState(rows); + const [rowsToRender, setRowsToRender] = useState([...rows]); const [page, changePage] = useState(defaultPage); const [colHeight, setColHeight] = useState(36); @@ -292,20 +293,14 @@ const DxcDataGrid = ({ useEffect(() => { const finalRows = [...rows]; if (expandable) { - rows.forEach((row, index) => { - if ( - row.contentIsExpanded && - !rows.some((row) => row[uniqueRowId] === `${rowKeyGetter(row, uniqueRowId)}_expanded`) - ) { - addRow(finalRows, index + 1, { - isExpandedChildContent: row.contentIsExpanded, - [uniqueRowId]: `${rowKeyGetter(row, uniqueRowId)}_expanded`, - expandedChildContent: row.expandedContent, - triggerRowKey: rowKeyGetter(row, uniqueRowId), - expandedContentHeight: row.expandedContentHeight, - }); - } - }); + finalRows + .filter((row) => { + const rowId = rowKeyGetter(row, uniqueRowId); + return row.contentIsExpanded && !rows.some((r) => r[uniqueRowId] === `${rowId}_expanded`); + }) + .forEach((row) => { + expandRow(row, finalRows, uniqueRowId); + }); } setRowsToRender(finalRows); }, [rows]); diff --git a/packages/lib/src/data-grid/utils.tsx b/packages/lib/src/data-grid/utils.tsx index 0aa8f13a2..22ea80024 100644 --- a/packages/lib/src/data-grid/utils.tsx +++ b/packages/lib/src/data-grid/utils.tsx @@ -59,6 +59,35 @@ export const renderSortStatus = ({ sortDirection }: RenderSortStatusProps) => ( ); +/** + * Expands a given row by inserting a new child row with the expanded content. + * @param {ExpandableGridRow} row - The row object to expand. + * @param {ExpandableGridRow[]} rows - The current list of all rows (as rendered). + * @param {string} uniqueRowId - Unique identifier key used for each row. + */ +export const expandRow = (row: ExpandableGridRow, rows: ExpandableGridRow[], uniqueRowId: string) => { + const rowIndex = rows.findIndex((r) => r === row); + addRow(rows, rowIndex + 1, { + isExpandedChildContent: true, + [uniqueRowId]: `${rowKeyGetter(row, uniqueRowId)}_expanded`, + expandedChildContent: row.expandedContent, + triggerRowKey: rowKeyGetter(row, uniqueRowId), + expandedContentHeight: row.expandedContentHeight, + }); +}; + +/** + * Collapses a given row by removing its expanded child row. + * @param {ExpandableGridRow} row - The row object to collapse. + * @param {ExpandableGridRow[]} rows - The current list of all rows (as rendered). + */ +export const collapseRow = (row: ExpandableGridRow, rows: ExpandableGridRow[]) => { + const rowIndex = rows.findIndex((r) => r === row); + const newRows = [...rows]; + deleteRow(newRows, rowIndex + 1); + return newRows; +}; + /** * Renders an expandable trigger icon that toggles row expansion. * @param {ExpandableGridRow} row - Row object that can be expanded or collapsed. @@ -80,25 +109,13 @@ export const renderExpandableTrigger = ( onClick={() => { row.contentIsExpanded = !row.contentIsExpanded; if (row.contentIsExpanded) { - const rowIndex = rows.findIndex((rowToRender) => row === rowToRender); setRowsToRender((currentRows) => { - const newRows = [...currentRows]; - addRow(newRows, rowIndex + 1, { - isExpandedChildContent: row.contentIsExpanded, - [uniqueRowId]: `${rowKeyGetter(row, uniqueRowId)}_expanded`, - expandedChildContent: row.expandedContent, - triggerRowKey: rowKeyGetter(row, uniqueRowId), - expandedContentHeight: row.expandedContentHeight, - }); - return newRows; + const finalRows = [...currentRows]; + expandRow(row, finalRows, uniqueRowId); + return finalRows; }); } else { - const rowIndex = rows.findIndex((rowToRender) => row === rowToRender); - setRowsToRender((currentRows) => { - const newRows = [...currentRows]; - deleteRow(newRows, rowIndex + 1); - return newRows; - }); + setRowsToRender((currentRows) => collapseRow(row, [...currentRows])); } }} disabled={!rows.some((row) => uniqueRowId in row)} @@ -136,11 +153,9 @@ export const renderHierarchyTrigger = ( }); } else { // The children of the row that is being collapsed are added to an array - const rowsToRemove: HierarchyGridRow[] = [ - ...rows.filter( - (rowToRender) => rowToRender.parentKey && rowToRender.parentKey === rowKeyGetter(triggerRow, uniqueRowId) - ), - ]; + const rowsToRemove: HierarchyGridRow[] = rows.filter( + (rowToRender) => rowToRender.parentKey && rowToRender.parentKey === rowKeyGetter(triggerRow, uniqueRowId) + ); // The children are checked if any of them has any other children of their own const rowsToCheck = [...rowsToRemove]; while (rowsToCheck.length > 0) {