diff --git a/apps/website/screens/components/data-grid/code/DataGridCodePage.tsx b/apps/website/screens/components/data-grid/code/DataGridCodePage.tsx index 8a9d45911..50569816f 100644 --- a/apps/website/screens/components/data-grid/code/DataGridCodePage.tsx +++ b/apps/website/screens/components/data-grid/code/DataGridCodePage.tsx @@ -33,6 +33,10 @@ const GridRowTypeString = `{ const HierarchyGridRowTypeString = `GridRow & { childRows?: HierarchyGridRow[] | GridRow[]; + childrenTrigger?: ( + open: boolean, + triggerRow: HierarchyGridRow + ) => (HierarchyGridRow[] | GridRow[]) | Promise; }`; const ExpandableGridRowTypeString = `GridRow & { @@ -116,26 +120,11 @@ const sections = [ - + defaultPage - - rows - - - GridRow[] | HierarchyGridRow[] | ExpandableGridRow[] -

Each one of them being in order:

-

- {GridRowTypeString} -

-

- {HierarchyGridRowTypeString} -

-

- {ExpandableGridRowTypeString} -

- - - List of rows that will be rendered in each cell based on the key in each column. + number + Default page in which the datagrid is rendered. - @@ -147,32 +136,45 @@ const sections = [ - - selectable + itemsPerPage - boolean + number - Whether the rows are selectable or not. - - + Number of items per page. + 5 - selectedRows + itemsPerPageFunction - {`Set`} + {`(value: number) => void`} - Set of selected rows. This prop is mandatory if selectable is set to true. The{" "} - uniqueRowId key will be used to identify the each row. + This function will be called when the user selects an item per page option. The value selected will be + passed as a parameter. - - onSelectRows + itemsPerPageOptions - {`(selectedRows: Set) => void`} + number[] + + An array of numbers representing the items per page options. + - + + + + + + childrenTrigger + - Function called whenever the selected values changes. This prop is mandatory if selectable is - set to true.The uniqueRowId key will be used to identify the rows. + {`(open: boolean, triggerRow: HierarchyGridRow) => HierarchyGridRow[] | Promise`} + + + Function called whenever a cell with children (HierarchyGridRow) is expanded. Returns the + children array. - @@ -184,6 +186,25 @@ const sections = [ Function called whenever a cell is edited. - + + onPageChange + + {`(page: number) => void`} + + Function called whenever the current page is changed. + - + + + onSelectRows + + {`(selectedRows: Set) => void`} + + + Function called whenever the selected values changes. This prop is mandatory if selectable is + set to true.The uniqueRowId key will be used to identify the rows. + + - + onSort @@ -196,90 +217,89 @@ const sections = [ - - uniqueRowId - string + + rows - This prop indicates the unique key that can be used to identify each row. The value of that key can be - either a number or a string. This prop is mandatory if selectable is set to true,{" "} - expandable is set to true or rows is of type HierarchyGridRow[]. + GridRow[] | HierarchyGridRow[] | ExpandableGridRow[] +

Each one of them being in order:

+

+ {GridRowTypeString} +

+

+ {HierarchyGridRowTypeString} +

+

+ {ExpandableGridRowTypeString} +

- - - - - summaryRow - GridRow + List of rows that will be rendered in each cell based on the key in each column. - Extra row that will be always visible. - - showPaginator + selectable boolean - If true, paginator will be displayed. - false + Whether the rows are selectable or not. + - - defaultPage + selectedRows - number + {`Set`} + + + Set of selected rows. This prop is mandatory if selectable is set to true. The{" "} + uniqueRowId key will be used to identify the each row. - Default page in which the datagrid is rendered. - - itemsPerPage + showGoToPage - number + boolean - Number of items per page. - 5 + If true, a select component for navigation between pages will be displayed. + true - itemsPerPageOptions + showPaginator - number[] + boolean - An array of numbers representing the items per page options. - - + If true, paginator will be displayed. + false - itemsPerPageFunction - - {`(value: number) => void`} - + summaryRow - This function will be called when the user selects an item per page option. The value selected will be - passed as a parameter. + GridRow + Extra row that will be always visible. - - onPageChange + totalItems - {`(page: number) => void`} + number - Function called whenever the current page is changed. + Number of total items. - - showGoToPage + uniqueRowId - boolean + string - If true, a select component for navigation between pages will be displayed. - true - - - totalItems - number + This prop indicates the unique key that can be used to identify each row. The value of that key can be + either a number or a string. This prop is mandatory if selectable is set to true,{" "} + expandable is set to true or rows is of type HierarchyGridRow[]. - Number of total items. - diff --git a/packages/lib/src/data-grid/DataGrid.stories.tsx b/packages/lib/src/data-grid/DataGrid.stories.tsx index ea4a0728f..cef1b41bd 100644 --- a/packages/lib/src/data-grid/DataGrid.stories.tsx +++ b/packages/lib/src/data-grid/DataGrid.stories.tsx @@ -2,7 +2,7 @@ import Title from "../../.storybook/components/Title"; import ExampleContainer from "../../.storybook/components/ExampleContainer"; import DxcDataGrid from "./DataGrid"; import DxcContainer from "../container/Container"; -import { GridColumn, HierarchyGridRow } from "./types"; +import { GridColumn, GridRow, HierarchyGridRow } from "./types"; import { isValidElement, useState } from "react"; import { disabledRules } from "../../test/accessibility/rules/specific/data-grid/disabledRules"; import preview from "../../.storybook/preview"; @@ -325,7 +325,7 @@ const childcolumns: GridColumn[] = [ }, ]; -const childRows: HierarchyGridRow[] = [ +const childRows = [ { name: "Root Node 1", value: "1", @@ -444,7 +444,59 @@ const childRows: HierarchyGridRow[] = [ }, ] as HierarchyGridRow[]; -const childRowsPaginated: HierarchyGridRow[] = [ +const childrenTrigger = (open: boolean, triggerRow: HierarchyGridRow) => { + if (open) { + return new Promise((resolve) => { + setTimeout(() => { + resolve([ + { + name: `${triggerRow.name} Child 1`, + value: triggerRow.value, + id: `${triggerRow.id}-child-1`, + childrenTrigger, + }, + { + name: `${triggerRow.name} Child 2`, + value: triggerRow.value, + id: `${triggerRow.id}-child-2`, + childrenTrigger, + }, + ] as unknown as HierarchyGridRow[]); + }, 5000); + }); + } else { + return [] as HierarchyGridRow[]; + } +}; + +const childRowsLazy = [ + { + name: "Root Node 1 Lazy", + value: "1", + id: "lazy-a", + childrenTrigger, + }, + { + name: "Root Node 2 Lazy", + value: "2", + id: "lazy-b", + childrenTrigger, + }, + { + name: "Root Node 3 Lazy", + value: "3", + id: "lazy-c", + childrenTrigger, + }, + { + name: "Root Node 4 Lazy", + value: "4", + id: "lazy-d", + childrenTrigger, + }, +] as unknown as HierarchyGridRow[]; + +const childRowsPaginated = [ { name: "Paginated Node 1", value: "1", @@ -728,6 +780,17 @@ const DataGridControlled = () => { onSelectRows={setSelectedChildRows} /> + + + <DxcDataGrid + columns={childcolumns} + rows={childRowsLazy} + uniqueRowId="id" + selectable + selectedRows={selectedRows} + onSelectRows={setSelectedRows} + /> + </ExampleContainer> <ExampleContainer> <Title title="Empty Data Grid" theme="light" level={4} /> <DxcDataGrid @@ -997,6 +1060,15 @@ export const Chromatic: Story = { export const Controlled: Story = { render: DataGridControlled, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + await userEvent.click(canvas.getByText("Root Node 1 Lazy")); + await userEvent.click(canvas.getByText("Root Node 2 Lazy")); + // await userEvent.click(canvas.getByText("Root Node 1 Lazy Child 1")); + // await userEvent.click(canvas.getByText("Root Node 1 Lazy Child 2")); + // await userEvent.click(canvas.getByText("Root Node 2 Lazy Child 1")); + // await userEvent.click(canvas.getByText("Root Node 2 Lazy Child 2")); + }, }; export const CustomSort: Story = { diff --git a/packages/lib/src/data-grid/DataGrid.test.tsx b/packages/lib/src/data-grid/DataGrid.test.tsx index d421b7b27..fd871fdbd 100644 --- a/packages/lib/src/data-grid/DataGrid.test.tsx +++ b/packages/lib/src/data-grid/DataGrid.test.tsx @@ -1,6 +1,6 @@ import { fireEvent, render, waitFor } from "@testing-library/react"; import DxcDataGrid from "./DataGrid"; -import { GridColumn } from "./types"; +import { GridColumn, HierarchyGridRow } from "./types"; Object.defineProperty(window, "getComputedStyle", { value: () => ({ @@ -205,6 +205,42 @@ const hierarchyRows: HierarchyGridRow[] = [ }, ] as HierarchyGridRow[]; +const loadedChildrenMock = [ + { id: "child-1", name: "Child 1", value: "Child 1" }, + { id: "child-2", name: "Child 2", value: "Child 2" }, +]; + +const childrenTriggerMock = jest.fn().mockResolvedValue(loadedChildrenMock); + +const hierarchyRowsLazy: HierarchyGridRow[] = [ + { + name: "Root Node 1 Lazy", + value: "1", + id: "lazy-a", + childrenTrigger: childrenTriggerMock, + }, + { + name: "Root Node 2 Lazy", + value: "2", + id: "lazy-b", + }, + { + name: "Root Node 3 Lazy", + value: "3", + id: "lazy-c", + }, + { + name: "Root Node 4 Lazy", + value: "4", + id: "lazy-d", + }, + { + name: "Root Node 5 Lazy", + value: "5", + id: "lazy-e", + }, +] as HierarchyGridRow[]; + describe("Data grid component tests", () => { beforeAll(() => { (global as any).CSS = { @@ -237,6 +273,30 @@ describe("Data grid component tests", () => { expect(rows.length).toBe(5); }); + test("Triggers childrenTrigger when expanding hierarchy row", async () => { + const onSelectRows = jest.fn(); + const selectedRows = new Set<number | string>(); + + const { getAllByRole } = render( + <DxcDataGrid + columns={columns} + rows={hierarchyRowsLazy} + uniqueRowId="id" + selectable + onSelectRows={onSelectRows} + selectedRows={selectedRows} + /> + ); + + expect(getAllByRole("row").length).toBe(5); + + const buttons = getAllByRole("button"); + + buttons[0] && fireEvent.click(buttons[0]); + + expect(childrenTriggerMock).toHaveBeenCalledWith(true, expect.objectContaining({ id: "lazy-a" })); + }); + test("Renders column headers", () => { const { getByText } = render(<DxcDataGrid columns={columns} rows={expandableRows} />); expect(getByText("ID")).toBeTruthy(); diff --git a/packages/lib/src/data-grid/DataGrid.tsx b/packages/lib/src/data-grid/DataGrid.tsx index e3fcb59e0..6902e3283 100644 --- a/packages/lib/src/data-grid/DataGrid.tsx +++ b/packages/lib/src/data-grid/DataGrid.tsx @@ -1,4 +1,4 @@ -import { useEffect, useMemo, useState } from "react"; +import { useEffect, useMemo, useState, ReactNode } from "react"; import DataGrid, { SortColumn } from "react-data-grid"; import styled from "@emotion/styled"; import DataGridPropsType, { HierarchyGridRow, GridRow, ExpandableGridRow } from "./types"; @@ -217,7 +217,7 @@ const DxcDataGrid = ({ renderCell({ row }) { if (row.isExpandedChildContent) { // if it is expanded content - return row.expandedChildContent || null; + return (row.expandedChildContent as ReactNode) || null; } // if row has expandable content return ( @@ -230,23 +230,38 @@ const DxcDataGrid = ({ ...expectedColumns, ]; } - if (!expandable && rows.some((row) => Array.isArray(row.childRows) && row.childRows.length > 0) && uniqueRowId) { + const rowHasHierarchy = (row: GridRow | HierarchyGridRow): row is HierarchyGridRow => { + return ( + (Array.isArray(row.childRows) && row.childRows.length > 0) || + typeof (row as HierarchyGridRow).childrenTrigger === "function" + ); + }; + if (!expandable && rows.some((row) => rowHasHierarchy(row)) && uniqueRowId) { // only the first column will be clickable and will expand the rows const firstColumnKey = expectedColumns[0]?.key; if (firstColumnKey) { expectedColumns[0] = { ...expectedColumns[0]!, renderCell({ row }) { - if ((row as HierarchyGridRow).childRows?.length) { + if (rowHasHierarchy(row)) { return ( <HierarchyContainer level={typeof row.rowLevel === "number" ? row.rowLevel : 0}> - {renderHierarchyTrigger(rowsToRender, row, uniqueRowId, firstColumnKey, setRowsToRender)} + {renderHierarchyTrigger( + rowsToRender, + row, + uniqueRowId, + firstColumnKey, + setRowsToRender, + row.childrenTrigger + // TODO: remove + // selectedRows + )} </HierarchyContainer> ); } return ( <HierarchyContainer level={typeof row.rowLevel === "number" ? row.rowLevel : 0} className="ellipsis-cell"> - {row[firstColumnKey]} + {row[firstColumnKey] as ReactNode} </HierarchyContainer> ); }, diff --git a/packages/lib/src/data-grid/types.ts b/packages/lib/src/data-grid/types.ts index 5a6161fc0..d657fa786 100644 --- a/packages/lib/src/data-grid/types.ts +++ b/packages/lib/src/data-grid/types.ts @@ -48,7 +48,30 @@ export type GridRow = { }; export type HierarchyGridRow = GridRow & { + /** + * Array of child rows nested under this row, enabling hierarchical (tree-like) structures. + * These child rows will be displayed when the parent row is expanded. + */ childRows?: HierarchyGridRow[] | GridRow[]; + /** + * Function called whenever a cell with children is expanded or collapsed. Returns the children array + */ + childrenTrigger?: ( + open?: boolean, + triggerRow?: HierarchyGridRow + ) => (HierarchyGridRow[] | GridRow[]) | Promise<HierarchyGridRow[] | GridRow[]>; + /** + * Indicates the level of nesting for this row in the hierarchy. + */ + rowLevel?: number; + /** + * Reference to the parent row's unique identifier. + */ + parentKey?: string | number; + /** + * Indicates whether child rows are currently visible. + */ + visibleChildren?: boolean; }; export type ExpandableGridRow = GridRow & { diff --git a/packages/lib/src/data-grid/utils.tsx b/packages/lib/src/data-grid/utils.tsx index 22ea80024..ef5233cae 100644 --- a/packages/lib/src/data-grid/utils.tsx +++ b/packages/lib/src/data-grid/utils.tsx @@ -1,13 +1,13 @@ // TODO: Remove eslint disable /* eslint-disable no-param-reassign */ -import { ReactNode, SetStateAction } from "react"; +import { ReactNode, SetStateAction, useState } from "react"; import { Column, RenderSortStatusProps, SortColumn, textEditor } from "react-data-grid"; import DxcActionIcon from "../action-icon/ActionIcon"; import DxcCheckbox from "../checkbox/Checkbox"; -import { DeepPartial, HalstackProvider } from "../HalstackContext"; import DxcIcon from "../icon/Icon"; import { GridColumn, HierarchyGridRow, GridRow, ExpandableGridRow } from "./types"; +import DxcSpinner from "../spinner/Spinner"; /** * Converts grid columns into react-data-grid column format. @@ -122,6 +122,8 @@ export const renderExpandableTrigger = ( /> ); +// TODO: REMOVE COMMENTED CODE (LEAVING IT JUST IN CASE IT IS NEEDED WHILE REVIEWING) + /** * Renders a trigger for hierarchical row expansion in the grid. * @param {HierarchyGridRow[]} rows - List of all hierarchy grid rows. @@ -129,6 +131,8 @@ export const renderExpandableTrigger = ( * @param {string} uniqueRowId - Unique identifier for each row. * @param {string} columnKey - Key of the column that displays the hierarchy trigger. * @param {Function} setRowsToRender - Function to update the rows being rendered. + * @param {Function} childrenTrigger - Function called whenever a cell with children is expanded or collapsed. Returns the children array +// * @param {Set<string | number>} selectedRows - Set containing the IDs of selected rows. * @returns {JSX.Element} Button that toggles visibility of child rows. */ export const renderHierarchyTrigger = ( @@ -136,27 +140,75 @@ export const renderHierarchyTrigger = ( triggerRow: HierarchyGridRow, uniqueRowId: string, columnKey: string, - setRowsToRender: (_value: SetStateAction<GridRow[] | ExpandableGridRow[] | HierarchyGridRow[]>) => void -) => ( - <button - type="button" - disabled={!rows.some((row) => uniqueRowId in row)} - onClick={() => { - let newRowsToRender = [...rows]; - if (!triggerRow.visibleChildren) { - const rowIndex = rows.findIndex((rowToRender) => triggerRow === rowToRender); - 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); + setRowsToRender: (_value: SetStateAction<GridRow[] | ExpandableGridRow[] | HierarchyGridRow[]>) => void, + childrenTrigger?: ( + _open: boolean, + _selectedRow: HierarchyGridRow + ) => (HierarchyGridRow[] | GridRow[]) | Promise<HierarchyGridRow[] | GridRow[]>, + // selectedRows?: Set<string | number> +) => { + const [loading, setLoading] = useState(false); + const onClick = async () => { + if (loading) return; // Prevent double clicks while loading + setLoading(true); + + if (!triggerRow.visibleChildren) { + if (childrenTrigger) { + try { + const dynamicChildren = await childrenTrigger(true, triggerRow); + triggerRow.childRows = dynamicChildren; + + // TODO: REMOVED, NOW THE LOGIC IS HANDLED INSIDE RENDERCHECKBOX + // TODO: I HAVE LEFT IT FOR NOW BECAUSE I AM WORRIED ABOUT THE BEHAVIOR + // TODO: WHEN THERE ARE MULTIPLE HIERARCHY LEVELS EXPANDED AT ONCE + // TODO (AS RENDERCHECKBOX ONLY CHECKS DIRECT PARENT, AND HAVING A RECURSIVE CHECK + // TODO: SEEMS OVERKILL) + // + // if (selectedRows?.has(rowKeyGetter(triggerRow, uniqueRowId))) { + // dynamicChildren.forEach((child) => { + // selectedRows.add(rowKeyGetter(child, uniqueRowId)); + // }); + // } + + setRowsToRender((currentRows) => { + const newRowsToRender = [...currentRows]; + 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); + } + } 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; }); - } else { + } + } else { + setRowsToRender((currentRows) => { // 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) ); // The children are checked if any of them has any other children of their own + const rowsToCheck = [...rowsToRemove]; while (rowsToCheck.length > 0) { const currentRow = rowsToCheck.pop(); @@ -165,7 +217,8 @@ export const renderHierarchyTrigger = ( rowsToRemove.push(...childRows); rowsToCheck.push(...childRows); } - newRowsToRender = rows.filter( + + const newRowsToRender = currentRows.filter( (row) => !rowsToRemove .map((rowToRemove) => { @@ -176,22 +229,55 @@ export const renderHierarchyTrigger = ( }) .includes(rowKeyGetter(row, uniqueRowId)) ); + + return newRowsToRender; + }); + + if (childrenTrigger) { + try { + const dynamicChildren = await childrenTrigger(false, triggerRow); + if (dynamicChildren.length > 0) { + const parentKey = rowKeyGetter(triggerRow, uniqueRowId); + const enrichedChildren = dynamicChildren.map((child) => ({ + ...child, + parentKey, + })); + + setRowsToRender((prevRows) => { + const index = prevRows.findIndex((row) => rowKeyGetter(row, uniqueRowId) === parentKey); + const before = prevRows.slice(0, index + 1); + const after = prevRows.slice(index + 1); + + return [...before, ...enrichedChildren, ...after]; + }); + } + } catch (error) { + console.error("Error loading children:", error); + } } - triggerRow.visibleChildren = !triggerRow.visibleChildren; - setRowsToRender(newRowsToRender); - }} - > - <DxcIcon icon={triggerRow.visibleChildren ? "Keyboard_Arrow_Down" : "Chevron_Right"} /> - <span className="ellipsis-cell">{triggerRow[columnKey]}</span> - </button> -); + } + + triggerRow.visibleChildren = !triggerRow.visibleChildren; + setLoading(false); + }; + return ( + <button type="button" disabled={!rows.some((row) => uniqueRowId in row)} onClick={onClick}> + {loading ? ( + <DxcSpinner mode="small" /> + ) : ( + <DxcIcon icon={triggerRow.visibleChildren ? "Keyboard_Arrow_Down" : "Chevron_Right"} /> + )} + <span className="ellipsis-cell">{triggerRow[columnKey]}</span> + </button> + ); +}; /** * Renders a checkbox for row selection. * @param {GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]} rows - Array of rows that are currently displayed. * @param {GridRow | HierarchyGridRow | ExpandableGridRow} row - Row object to render the checkbox for. * @param {string} uniqueRowId - The key used to uniquely identify each row. - * @param {Set<string | number>} selectedRows - Set containing the IDs of selected rows. + * @param {Set<string | number>} selectedRows - Set of selected rows. * @param {Function} onSelectRows - Callback function that triggers when rows are selected/deselected. * @returns {JSX.Element} Checkbox for selecting the row. */ @@ -201,33 +287,35 @@ export const renderCheckbox = ( uniqueRowId: string, selectedRows: Set<string | number>, onSelectRows: (_selected: Set<string | number>) => void -) => ( - <DxcCheckbox - checked={selectedRows.has(rowKeyGetter(row, uniqueRowId))} - onChange={(checked) => { - const selected = new Set(selectedRows); - if (checked) { - selected.add(rowKeyGetter(row, uniqueRowId)); - } else { - selected.delete(rowKeyGetter(row, uniqueRowId)); - } - if (row.childRows && Array.isArray(row.childRows)) { - getChildrenSelection(row.childRows, uniqueRowId, selected, checked); - } - if (row.parentKey) { - getParentSelectedState(rows, row.parentKey, uniqueRowId, selected, checked); - } - onSelectRows(selected); - }} - disabled={!rows.some((row) => uniqueRowId in row)} - /> -); +) => { + return ( + <DxcCheckbox + checked={selectedRows.has(rowKeyGetter(row, uniqueRowId)) || selectedRows.has(row.parentKey as string | number)} + onChange={(checked) => { + const selected = new Set(selectedRows); + if (checked) { + selected.add(rowKeyGetter(row, uniqueRowId)); + } else { + selected.delete(rowKeyGetter(row, uniqueRowId)); + } + if (row.childRows && Array.isArray(row.childRows)) { + getChildrenSelection(row.childRows, uniqueRowId, selected, checked); + } + if (row.parentKey) { + getParentSelectedState(rows, row.parentKey, uniqueRowId, selected, checked); + } + onSelectRows(selected); + }} + disabled={!rows.some((row) => uniqueRowId in row)} + /> + ); +}; /** * Renders a header checkbox that controls the selection of all rows. * @param {GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]} rows - Array of rows that are currently displayed. * @param {string} uniqueRowId - The key used to uniquely identify each row. - * @param {Set<string | number>} selectedRows - Set containing the IDs of selected rows. + * @param {Set<string | number>} selectedRows - Set of selected rows. * @param {Function} onSelectRows - Callback function that triggers when rows are selected/deselected. * @returns {JSX.Element} Checkbox for the header checkbox. */ @@ -454,13 +542,13 @@ export const rowFinderBasedOnId = ( * Recursively selects or deselects children rows based on the checked state. * @param {HierarchyGridRow[]} rowList - List of child rows that need to be checked/unchecked. * @param {string} uniqueRowId - Key used to uniquely identify each row. - * @param {Set<ReactNode>} selectedRows - Set of selected rows. + * @param {Set<string | number>} selectedRows - Set of selected rows. * @param {boolean} checked - Boolean indicating whether the rows should be selected (true) or deselected (false). */ export const getChildrenSelection = ( rowList: HierarchyGridRow[], uniqueRowId: string, - selectedRows: Set<ReactNode>, + selectedRows: Set<string | number>, checked: boolean ) => { rowList.forEach((row) => { @@ -482,14 +570,14 @@ export const getChildrenSelection = ( * @param {ReactNode} uniqueRowKeyValue Unique value of the selected row * @param {ReactNode} parentKeyValue Unique value of the parent Row * @param {string} uniqueRowId Key where the unique value is located - * @param {Set<ReactNode>} changedRows + * @param {Set<string | number>} selectedRows - Set of selected rows. * @param {boolean} checkedStateToMatch */ export const getParentSelectedState = ( rowList: HierarchyGridRow[], parentKeyValue: ReactNode, uniqueRowId: string, - selectedRows: Set<ReactNode>, + selectedRows: Set<string | number>, checkedStateToMatch: boolean ) => { if (!rowList.some((row) => uniqueRowId in row)) {