diff --git a/packages/lib/src/data-grid/DataGrid.tsx b/packages/lib/src/data-grid/DataGrid.tsx index ddaecb5cd..ace21c1f1 100644 --- a/packages/lib/src/data-grid/DataGrid.tsx +++ b/packages/lib/src/data-grid/DataGrid.tsx @@ -180,7 +180,7 @@ const DxcDataGrid = ({ const [rowsToRender, setRowsToRender] = useState([...rows]); const [page, changePage] = useState(defaultPage); const [colHeight, setColHeight] = useState(36); - const [loadingChildren, setLoadingChildren] = useState(false); + const [loadingChildren, setLoadingChildren] = useState<(string | number)[]>([]); const goToPage = (newPage: number) => { if (onPageChange) { @@ -297,7 +297,18 @@ const DxcDataGrid = ({ ]; } return expectedColumns; - }, [selectable, expandable, columns, rowsToRender, onSelectRows, rows, summaryRow, uniqueRowId, selectedRows]); + }, [ + selectable, + expandable, + columns, + rowsToRender, + onSelectRows, + rows, + summaryRow, + uniqueRowId, + selectedRows, + loadingChildren, + ]); // array with the order of the columns const [columnsOrder, setColumnsOrder] = useState((): number[] => columnsToRender.map((_, index) => index)); const [sortColumns, setSortColumns] = useState([]); diff --git a/packages/lib/src/data-grid/utils.tsx b/packages/lib/src/data-grid/utils.tsx index c60e08f19..55fa64b92 100644 --- a/packages/lib/src/data-grid/utils.tsx +++ b/packages/lib/src/data-grid/utils.tsx @@ -138,58 +138,73 @@ export const renderHierarchyTrigger = ( uniqueRowId: string, columnKey: string, setRowsToRender: (_value: SetStateAction) => void, - loading?: boolean, - setLoading?: (_value: SetStateAction) => void, + loadingChildren?: (string | number)[], + setLoadingChildren?: (_value: SetStateAction<(string | number)[]>) => void, childrenTrigger?: ( _open: boolean, _selectedRow: HierarchyGridRow ) => (HierarchyGridRow[] | GridRow[]) | Promise ) => { - const onClick = async () => { - if (loading) return; // Prevent double clicks while loading - if (!triggerRow.visibleChildren) { - if (childrenTrigger) { - setLoading?.(true); - triggerRow.loadingChildren = true; - try { - const dynamicChildren = await childrenTrigger(true, triggerRow); - triggerRow.childRows = dynamicChildren; - - setRowsToRender((currentRows) => { - const newRowsToRender = [...currentRows]; - // Prevents adding children if the triggerRow has been removed - if (newRowsToRender.some((row) => rowKeyGetter(row, uniqueRowId) === triggerRow[uniqueRowId])) { - const rowIndex = currentRows.findIndex((row) => triggerRow === row); - - dynamicChildren.forEach((childRow: HierarchyGridRow, index: number) => { - childRow.rowLevel = - triggerRow.rowLevel && typeof triggerRow.rowLevel === "number" ? triggerRow.rowLevel + 1 : 1; - childRow.parentKey = rowKeyGetter(triggerRow, uniqueRowId); - addRow(newRowsToRender, rowIndex + 1 + index, childRow); - }); - } - return newRowsToRender; - }); - } catch (error) { - console.error("Error loading children:", error); - } finally { - setLoading?.(false); - } - } else if (triggerRow?.childRows) { + const isLoading = !!loadingChildren?.includes(rowKeyGetter(triggerRow, uniqueRowId)); + const expandChildren = async () => { + if (childrenTrigger && !triggerRow.childRows?.length) { + setLoadingChildren?.((currentLoadingChildren) => [ + ...currentLoadingChildren, + rowKeyGetter(triggerRow, uniqueRowId), + ]); + triggerRow.loadingChildren = true; + try { + const dynamicChildren = await childrenTrigger(true, triggerRow); + triggerRow.childRows = dynamicChildren; + setRowsToRender((currentRows) => { const newRowsToRender = [...currentRows]; - const rowIndex = currentRows.findIndex((row) => triggerRow === row); - - triggerRow.childRows?.forEach((childRow: HierarchyGridRow, index: number) => { - childRow.rowLevel = - triggerRow.rowLevel && typeof triggerRow.rowLevel === "number" ? triggerRow.rowLevel + 1 : 1; - childRow.parentKey = rowKeyGetter(triggerRow, uniqueRowId); - addRow(newRowsToRender, rowIndex + 1 + index, childRow); - }); - + if (newRowsToRender.some((row) => rowKeyGetter(row, uniqueRowId) === triggerRow[uniqueRowId])) { + const rowIndex = currentRows.findIndex((row) => triggerRow === row); + dynamicChildren.forEach((childRow: HierarchyGridRow, index: number) => { + childRow.rowLevel = + triggerRow.rowLevel && typeof triggerRow.rowLevel === "number" ? triggerRow.rowLevel + 1 : 1; + childRow.parentKey = rowKeyGetter(triggerRow, uniqueRowId); + addRow(newRowsToRender, rowIndex + 1 + index, childRow); + }); + } return newRowsToRender; }); + } catch (e) { + console.error("Error loading children:", e); + } finally { + setLoadingChildren?.((currentLoadingChildren) => + currentLoadingChildren.filter((key) => key !== rowKeyGetter(triggerRow, uniqueRowId)) + ); } + } else if (triggerRow?.childRows) { + setRowsToRender((currentRows) => { + const newRowsToRender = [...currentRows]; + const rowIndex = currentRows.findIndex((row) => triggerRow === row); + + triggerRow.childRows?.forEach((childRow: HierarchyGridRow, index: number) => { + childRow.rowLevel = + triggerRow.rowLevel && typeof triggerRow.rowLevel === "number" ? triggerRow.rowLevel + 1 : 1; + childRow.parentKey = rowKeyGetter(triggerRow, uniqueRowId); + addRow(newRowsToRender, rowIndex + 1 + index, childRow); + }); + + return newRowsToRender; + }); + } + }; + if ( + triggerRow.visibleChildren && + triggerRow.childRows?.length && + !rows.some((row) => row.parentKey === rowKeyGetter(triggerRow, uniqueRowId)) + ) { + expandChildren(); + } + const onClick = async () => { + if (isLoading) return; // Prevent double clicks while loading + triggerRow.visibleChildren = !triggerRow.visibleChildren; + if (triggerRow.visibleChildren) { + await expandChildren(); } else { setRowsToRender((currentRows) => { // The children of the row that is being collapsed are added to an array @@ -221,12 +236,10 @@ export const renderHierarchyTrigger = ( return newRowsToRender; }); } - - triggerRow.visibleChildren = !triggerRow.visibleChildren; }; return (