diff --git a/frontend/components/TableContainer/DataTable/DataTable.tsx b/frontend/components/TableContainer/DataTable/DataTable.tsx index 49e34060c9..40b40dc0eb 100644 --- a/frontend/components/TableContainer/DataTable/DataTable.tsx +++ b/frontend/components/TableContainer/DataTable/DataTable.tsx @@ -81,6 +81,10 @@ interface IDataTableProps { setExportRows?: (rows: Row[]) => void; onClearSelection?: () => void; suppressHeaderActions?: boolean; + /** Optional override for react-table's row ID derivation. + * Note: avoid index-only row IDs in server-side paginated or selectable tables, + * as IDs would collide across pages. */ + getRowId?: (row: any, index: number) => string; } interface IHeaderGroup extends HeaderGroup { @@ -128,6 +132,7 @@ const DataTable = ({ setExportRows, onClearSelection = noop, suppressHeaderActions, + getRowId: getRowIdProp, }: IDataTableProps): JSX.Element => { // used to track the initial mount of the component. const isInitialRender = useRef(true); @@ -181,8 +186,10 @@ const DataTable = ({ columns, data, // Use a stable row ID when available (row.id), otherwise fall back to the index-based ID (default of react-table) - getRowId: (row: any, index: number) => - row && row.id != null ? String(row.id) : String(index), + getRowId: + getRowIdProp ?? + ((row: any, index: number) => + row && row.id != null ? String(row.id) : String(index)), initialState: { sortBy: initialSortBy, pageIndex: defaultPageIndex, diff --git a/frontend/components/TableContainer/TableContainer.tsx b/frontend/components/TableContainer/TableContainer.tsx index aa8979adf1..ad6da7c6e7 100644 --- a/frontend/components/TableContainer/TableContainer.tsx +++ b/frontend/components/TableContainer/TableContainer.tsx @@ -122,6 +122,7 @@ interface ITableContainerProps { onClearSelection?: () => void; /** don't show the Clear selection button and selected item count when items are selected */ suppressHeaderActions?: boolean; + getRowId?: (row: any, index: number) => string; } const baseClass = "table-container"; @@ -184,6 +185,7 @@ const TableContainer = ({ persistSelectedRows, onClearSelection = noop, suppressHeaderActions, + getRowId, }: ITableContainerProps) => { const isControlledSearchQuery = controlledSearchQuery !== undefined; const [searchQuery, setSearchQuery] = useState(defaultSearchQuery); @@ -578,6 +580,7 @@ const TableContainer = ({ setExportRows={setExportRows} onClearSelection={onClearSelection} suppressHeaderActions={suppressHeaderActions} + getRowId={getRowId} persistSelectedRows={persistSelectedRows} hideFooter={hideFooter} /> diff --git a/frontend/pages/hosts/details/HostQueryReport/HQRTable/HQRTable.tsx b/frontend/pages/hosts/details/HostQueryReport/HQRTable/HQRTable.tsx index 1fd1c602e8..c7090efb81 100644 --- a/frontend/pages/hosts/details/HostQueryReport/HQRTable/HQRTable.tsx +++ b/frontend/pages/hosts/details/HostQueryReport/HQRTable/HQRTable.tsx @@ -211,6 +211,7 @@ const HQRTable = ({ emptyComponent={() => null} defaultSortHeader={columnConfigs[0].id} defaultSortDirection="asc" + getRowId={(_row, index) => String(index)} /> )} diff --git a/frontend/pages/queries/details/components/QueryReport/QueryReport.tsx b/frontend/pages/queries/details/components/QueryReport/QueryReport.tsx index f3e0ee8509..8ded5041ea 100644 --- a/frontend/pages/queries/details/components/QueryReport/QueryReport.tsx +++ b/frontend/pages/queries/details/components/QueryReport/QueryReport.tsx @@ -150,6 +150,7 @@ const QueryReport = ({ customControl={() => renderTableButtons()} setExportRows={setFilteredResults} renderCount={renderResultsCount} + getRowId={(_row, index) => String(index)} /> ); diff --git a/frontend/pages/queries/edit/components/QueryResults/QueryResults.tsx b/frontend/pages/queries/edit/components/QueryResults/QueryResults.tsx index b764bce7c4..cdb12dfa41 100644 --- a/frontend/pages/queries/edit/components/QueryResults/QueryResults.tsx +++ b/frontend/pages/queries/edit/components/QueryResults/QueryResults.tsx @@ -234,6 +234,7 @@ const QueryResults = ({ tableType === "results" ? setFilteredResults : setFilteredErrors } renderCount={() => renderCount(tableType)} + getRowId={(_row, index) => String(index)} /> );