Skip to content

Commit

Permalink
final memoized virtualization
Browse files Browse the repository at this point in the history
useMemoed components; used padding instead of getTotalSize;
  • Loading branch information
MarceloRobert committed Oct 30, 2024
1 parent cfb603a commit 7595b5a
Showing 1 changed file with 60 additions and 36 deletions.
96 changes: 60 additions & 36 deletions dashboard/src/pages/TreeDetails/Tabs/Tests/IndividualTestsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
import { useVirtualizer } from '@tanstack/react-virtual';
import { useMemo, useRef, useState } from 'react';

import { Link, LinkProps } from '@tanstack/react-router';

import { TIndividualTest } from '@/types/general';

import { TooltipDateTime } from '@/components/TooltipDateTime';
Expand Down Expand Up @@ -159,57 +161,79 @@ export function IndividualTestsTable({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [groupHeaders, sorting]);

const { rows } = table.getRowModel();
const { rows } = useMemo(() => {
return table.getRowModel();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [table, sorting]);

const parentRef = useRef<HTMLDivElement>(null);
const virtualizer = useVirtualizer({
count: rows.length,
// eslint-disable-next-line no-magic-numbers
estimateSize: () => 60, //estimate row height for accurate scrollbar dragging
estimateSize: () => 60,
getScrollElement: () => parentRef.current,
overscan: 10,
overscan: 5,
});
const virtualItems = virtualizer.getVirtualItems();

const { pTop: paddingTop, pBottom: paddingBottom } = useMemo(() => {
const pTop = virtualItems?.length > 0 ? virtualItems?.[0]?.start || 0 : 0;
const pBottom =
virtualItems?.length > 0
? virtualizer.getTotalSize() - (virtualItems?.at(-1)?.end || 0)
: 0;
return { pTop, pBottom };
}, [virtualItems, virtualizer]);

const tableRows = useMemo((): JSX.Element[] => {
return virtualItems.map(virtualRow => {
const row = rows[virtualRow.index] as Row<TIndividualTest>;
const linkProps: LinkProps = {
to: '/tree/$treeId/test/$testId',
params: {
testId: row.original.id,
},
search: s => s,
};
return (
<TableRow key={row.id} className="border-b-0 hover:bg-lightBlue">
{row.getVisibleCells().map(cell => {
return (
<TableCell
key={cell.id}
className="max-w-32 overflow-clip text-ellipsis text-nowrap"
>
<Link {...linkProps}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</Link>
</TableCell>
);
})}
</TableRow>
);
});
}, [rows, virtualItems]);

return (
<div
ref={parentRef}
style={{ height: '300px', overflow: 'auto', maxWidth: '100%' }}
>
<div
className="rounded-lg border-x border-t border-darkGray bg-white text-sm text-black"
style={{ height: `${virtualizer.getTotalSize()}px` }}
>
<div className="rounded-lg border-x border-t border-darkGray bg-white text-sm text-black">
<table className="w-full">
<DumbTableHeader>{tableHeaders}</DumbTableHeader>
<TableBody>
{virtualizer.getVirtualItems().map((virtualRow, index) => {
const row = rows[virtualRow.index] as Row<TIndividualTest>;
return (
<TableRow
key={row.id}
className="cursor-pointer hover:bg-lightBlue"
style={{
height: `${virtualRow.size}px`,
transform: `translateY(${
virtualRow.start - index * virtualRow.size
}px)`,
}}
>
{row.getVisibleCells().map(cell => {
return (
<TableCell
key={cell.id}
className="max-w-32 overflow-clip text-nowrap"
>
{flexRender(
cell.column.columnDef.cell,
cell.getContext(),
)}
</TableCell>
);
})}
</TableRow>
);
})}
{paddingTop > 0 && (
<tr>
<td style={{ height: paddingTop }}></td>
</tr>
)}
{tableRows}
{paddingBottom > 0 && (
<tr>
<td style={{ height: paddingBottom }}></td>
</tr>
)}
</TableBody>
</table>
</div>
Expand Down

0 comments on commit 7595b5a

Please sign in to comment.