Skip to content

Commit acc2a7e

Browse files
authored
Merge pull request #2290 from dxc-technology/Mil4n0r/fix_loading_datagrid
Fix to handle loading indicators in Datagrid
2 parents 4285b64 + 08414a6 commit acc2a7e

File tree

2 files changed

+72
-51
lines changed

2 files changed

+72
-51
lines changed

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ const DxcDataGrid = ({
180180
const [rowsToRender, setRowsToRender] = useState<GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]>([...rows]);
181181
const [page, changePage] = useState(defaultPage);
182182
const [colHeight, setColHeight] = useState(36);
183-
const [loadingChildren, setLoadingChildren] = useState(false);
183+
const [loadingChildren, setLoadingChildren] = useState<(string | number)[]>([]);
184184

185185
const goToPage = (newPage: number) => {
186186
if (onPageChange) {
@@ -297,7 +297,18 @@ const DxcDataGrid = ({
297297
];
298298
}
299299
return expectedColumns;
300-
}, [selectable, expandable, columns, rowsToRender, onSelectRows, rows, summaryRow, uniqueRowId, selectedRows]);
300+
}, [
301+
selectable,
302+
expandable,
303+
columns,
304+
rowsToRender,
305+
onSelectRows,
306+
rows,
307+
summaryRow,
308+
uniqueRowId,
309+
selectedRows,
310+
loadingChildren,
311+
]);
301312
// array with the order of the columns
302313
const [columnsOrder, setColumnsOrder] = useState((): number[] => columnsToRender.map((_, index) => index));
303314
const [sortColumns, setSortColumns] = useState<readonly SortColumn[]>([]);

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

Lines changed: 59 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -138,58 +138,73 @@ export const renderHierarchyTrigger = (
138138
uniqueRowId: string,
139139
columnKey: string,
140140
setRowsToRender: (_value: SetStateAction<GridRow[] | ExpandableGridRow[] | HierarchyGridRow[]>) => void,
141-
loading?: boolean,
142-
setLoading?: (_value: SetStateAction<boolean>) => void,
141+
loadingChildren?: (string | number)[],
142+
setLoadingChildren?: (_value: SetStateAction<(string | number)[]>) => void,
143143
childrenTrigger?: (
144144
_open: boolean,
145145
_selectedRow: HierarchyGridRow
146146
) => (HierarchyGridRow[] | GridRow[]) | Promise<HierarchyGridRow[] | GridRow[]>
147147
) => {
148-
const onClick = async () => {
149-
if (loading) return; // Prevent double clicks while loading
150-
if (!triggerRow.visibleChildren) {
151-
if (childrenTrigger) {
152-
setLoading?.(true);
153-
triggerRow.loadingChildren = true;
154-
try {
155-
const dynamicChildren = await childrenTrigger(true, triggerRow);
156-
triggerRow.childRows = dynamicChildren;
157-
158-
setRowsToRender((currentRows) => {
159-
const newRowsToRender = [...currentRows];
160-
// Prevents adding children if the triggerRow has been removed
161-
if (newRowsToRender.some((row) => rowKeyGetter(row, uniqueRowId) === triggerRow[uniqueRowId])) {
162-
const rowIndex = currentRows.findIndex((row) => triggerRow === row);
163-
164-
dynamicChildren.forEach((childRow: HierarchyGridRow, index: number) => {
165-
childRow.rowLevel =
166-
triggerRow.rowLevel && typeof triggerRow.rowLevel === "number" ? triggerRow.rowLevel + 1 : 1;
167-
childRow.parentKey = rowKeyGetter(triggerRow, uniqueRowId);
168-
addRow(newRowsToRender, rowIndex + 1 + index, childRow);
169-
});
170-
}
171-
return newRowsToRender;
172-
});
173-
} catch (error) {
174-
console.error("Error loading children:", error);
175-
} finally {
176-
setLoading?.(false);
177-
}
178-
} else if (triggerRow?.childRows) {
148+
const isLoading = !!loadingChildren?.includes(rowKeyGetter(triggerRow, uniqueRowId));
149+
const expandChildren = async () => {
150+
if (childrenTrigger && !triggerRow.childRows?.length) {
151+
setLoadingChildren?.((currentLoadingChildren) => [
152+
...currentLoadingChildren,
153+
rowKeyGetter(triggerRow, uniqueRowId),
154+
]);
155+
triggerRow.loadingChildren = true;
156+
try {
157+
const dynamicChildren = await childrenTrigger(true, triggerRow);
158+
triggerRow.childRows = dynamicChildren;
159+
179160
setRowsToRender((currentRows) => {
180161
const newRowsToRender = [...currentRows];
181-
const rowIndex = currentRows.findIndex((row) => triggerRow === row);
182-
183-
triggerRow.childRows?.forEach((childRow: HierarchyGridRow, index: number) => {
184-
childRow.rowLevel =
185-
triggerRow.rowLevel && typeof triggerRow.rowLevel === "number" ? triggerRow.rowLevel + 1 : 1;
186-
childRow.parentKey = rowKeyGetter(triggerRow, uniqueRowId);
187-
addRow(newRowsToRender, rowIndex + 1 + index, childRow);
188-
});
189-
162+
if (newRowsToRender.some((row) => rowKeyGetter(row, uniqueRowId) === triggerRow[uniqueRowId])) {
163+
const rowIndex = currentRows.findIndex((row) => triggerRow === row);
164+
dynamicChildren.forEach((childRow: HierarchyGridRow, index: number) => {
165+
childRow.rowLevel =
166+
triggerRow.rowLevel && typeof triggerRow.rowLevel === "number" ? triggerRow.rowLevel + 1 : 1;
167+
childRow.parentKey = rowKeyGetter(triggerRow, uniqueRowId);
168+
addRow(newRowsToRender, rowIndex + 1 + index, childRow);
169+
});
170+
}
190171
return newRowsToRender;
191172
});
173+
} catch (e) {
174+
console.error("Error loading children:", e);
175+
} finally {
176+
setLoadingChildren?.((currentLoadingChildren) =>
177+
currentLoadingChildren.filter((key) => key !== rowKeyGetter(triggerRow, uniqueRowId))
178+
);
192179
}
180+
} else if (triggerRow?.childRows) {
181+
setRowsToRender((currentRows) => {
182+
const newRowsToRender = [...currentRows];
183+
const rowIndex = currentRows.findIndex((row) => triggerRow === row);
184+
185+
triggerRow.childRows?.forEach((childRow: HierarchyGridRow, index: number) => {
186+
childRow.rowLevel =
187+
triggerRow.rowLevel && typeof triggerRow.rowLevel === "number" ? triggerRow.rowLevel + 1 : 1;
188+
childRow.parentKey = rowKeyGetter(triggerRow, uniqueRowId);
189+
addRow(newRowsToRender, rowIndex + 1 + index, childRow);
190+
});
191+
192+
return newRowsToRender;
193+
});
194+
}
195+
};
196+
if (
197+
triggerRow.visibleChildren &&
198+
triggerRow.childRows?.length &&
199+
!rows.some((row) => row.parentKey === rowKeyGetter(triggerRow, uniqueRowId))
200+
) {
201+
expandChildren();
202+
}
203+
const onClick = async () => {
204+
if (isLoading) return; // Prevent double clicks while loading
205+
triggerRow.visibleChildren = !triggerRow.visibleChildren;
206+
if (triggerRow.visibleChildren) {
207+
await expandChildren();
193208
} else {
194209
setRowsToRender((currentRows) => {
195210
// The children of the row that is being collapsed are added to an array
@@ -221,12 +236,10 @@ export const renderHierarchyTrigger = (
221236
return newRowsToRender;
222237
});
223238
}
224-
225-
triggerRow.visibleChildren = !triggerRow.visibleChildren;
226239
};
227240
return (
228241
<button type="button" disabled={!rows.some((row) => uniqueRowId in row)} onClick={onClick}>
229-
{loading ? (
242+
{isLoading ? (
230243
<DxcSpinner mode="small" />
231244
) : (
232245
<DxcIcon icon={triggerRow.visibleChildren ? "Keyboard_Arrow_Down" : "Chevron_Right"} />
@@ -264,10 +277,7 @@ export const renderCheckbox = (
264277
onChange={(checked) => {
265278
handleCheckboxUpdate(rows, row, uniqueRowId, selectedRows, checked, onSelectRows);
266279
}}
267-
disabled={
268-
// row.loadingChildren ||
269-
!rows.some((row) => uniqueRowId in row)
270-
}
280+
disabled={!rows.some((row) => uniqueRowId in row)}
271281
/>
272282
);
273283
};

0 commit comments

Comments
 (0)