Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions packages/lib/src/data-grid/DataGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ const DxcDataGrid = ({
const [rowsToRender, setRowsToRender] = useState<GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]>([...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) {
Expand Down Expand Up @@ -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<readonly SortColumn[]>([]);
Expand Down
108 changes: 59 additions & 49 deletions packages/lib/src/data-grid/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,58 +138,73 @@ export const renderHierarchyTrigger = (
uniqueRowId: string,
columnKey: string,
setRowsToRender: (_value: SetStateAction<GridRow[] | ExpandableGridRow[] | HierarchyGridRow[]>) => void,
loading?: boolean,
setLoading?: (_value: SetStateAction<boolean>) => void,
loadingChildren?: (string | number)[],
setLoadingChildren?: (_value: SetStateAction<(string | number)[]>) => void,
childrenTrigger?: (
_open: boolean,
_selectedRow: HierarchyGridRow
) => (HierarchyGridRow[] | GridRow[]) | Promise<HierarchyGridRow[] | GridRow[]>
) => {
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
Expand Down Expand Up @@ -221,12 +236,10 @@ export const renderHierarchyTrigger = (
return newRowsToRender;
});
}

triggerRow.visibleChildren = !triggerRow.visibleChildren;
};
return (
<button type="button" disabled={!rows.some((row) => uniqueRowId in row)} onClick={onClick}>
{loading ? (
{isLoading ? (
<DxcSpinner mode="small" />
) : (
<DxcIcon icon={triggerRow.visibleChildren ? "Keyboard_Arrow_Down" : "Chevron_Right"} />
Expand Down Expand Up @@ -264,10 +277,7 @@ export const renderCheckbox = (
onChange={(checked) => {
handleCheckboxUpdate(rows, row, uniqueRowId, selectedRows, checked, onSelectRows);
}}
disabled={
// row.loadingChildren ||
!rows.some((row) => uniqueRowId in row)
}
disabled={!rows.some((row) => uniqueRowId in row)}
/>
);
};
Expand Down