Skip to content

Commit

Permalink
FEAT: virtualization of data
Browse files Browse the repository at this point in the history
  • Loading branch information
silvareal committed Nov 25, 2022
1 parent 0a49dc7 commit 06f4d33
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 93 deletions.
139 changes: 93 additions & 46 deletions web/src/common/Table.css
Original file line number Diff line number Diff line change
@@ -1,81 +1,128 @@
/* .StandardTable [data-sticky-td] {
position: sticky;
} */

.StandardTable {
max-height: calc(100vh - 280px);
.Table__container {
min-height: 300px;
max-height: calc(100vh - 250px);
overflow: auto;
position: relative;
width: 100%;
background-color: inherit;
}
.Table {

width: 100%;

.StandardTable__row {
@apply border-b border-solid border-gray-200;
/* width: 100%; */
background: inherit;
}

.StandardTable__row:last-child {
border-bottom: 0;
.Table__table {
min-width: 100%;
background: inherit;
/* text-indent: 0; */
/* border-color: inherit; */
border-collapse: collapse;
}

.StandardTable__row:last-child .StandardTable__cell {
/* border-bottom: 0; */
.Table__table__header {
top: 0;
}

.StandardTable__cell {
@apply px-2 py-2 overflow-hidden flex items-center;
/* border-bottom: 1px solid theme("colors.primary.main"); */
min-width: 0;
.Table__pagination {
justify-content: flex-end;
bottom: 0;
}

.StandardTable__cell:first-child {
@apply pl-4;
.Table__table__header,
.Table__table__footer {
font-weight: bold;
}

.StandardTable__cell:last-child {
@apply pr-4;
.Table__table__header,
/* .Table__table__footer, */
.Table__pagination {
position: sticky;
z-index: 10;
}

[data-sticky-td] {
/* @apply bg-primary-shade4; */
.Table__table__header__row,
.Table__table__body__row,
.Table__table__footer__row {
border-bottom: 1px solid lightgray;
}

.StandardTable__header {
@apply rounded-xl font-bold;
position: sticky;
top: 0;
z-index: 4;
.Table__table__header__row--relative,
.Table__table__body__row--relative,
.Table__table__footer__row--relative {
display: flex;
min-width: 100%;
}

.StandardTable__header__row {
@apply bg-secondary-light text-secondary-contrastText h-12;
.Table__table__header__row--absolute,
.Table__table__body__row--absolute,
.Table__table__footer__row--absolute {
display: flex;
position: relative;
height: 40px;
}

.StandardTable__header__row__cell {
.Table__table__header__row__cell,
.Table__table__body__row__cell,
.Table__table__footer__row__cell {
position: relative;
background-color: white;
padding: 8px;
/* height: 48px; */
text-align: left;
}

.StandardTable__body {
.Table__table__header__row__cell--relative,
.Table__table__body__row__cell--relative,
.Table__table__footer__row__cell--relative {
flex: 1 0 auto;
}

.StandardTable__body__row {
.Table__table__header__row__cell--absolute,
.Table__table__body__row__cell--absolute,
.Table__table__footer__row__cell--absolute {
position: absolute;
height: 40px;
}

.StandardTable__body__row__cell {
.Table__loading,
.Table__empty,
.Table__error {
display: flex;
justify-content: center;
padding: 16px;
}

.StandardTable__pagination {
.Table__loading,
.Table__empty,
.Table__error,
.Table__pagination {
position: sticky;
bottom: 0;
left: 0;
right: 0;
z-index: 4;
display: flex;
justify-content: flex-end;
background-color: inherit;
}

.StandardTable__pagination__item {
background-color: inherit;
/* border-top: 1px solid theme("colors.secondary.main"); */
.Table__resizer {
position: absolute;
right: 0;
top: 0;
height: 100%;
width: 5px;
background: rgba(0, 0, 0, 0.5);
cursor: col-resize;
user-select: none;
touch-action: none;
}

.Table__resizer.Table__resizing {
background: blue;
opacity: 1;
}

@media (hover: hover) {
.Table__resizer {
opacity: 0;
}

*:hover > .Table__resizer {
opacity: 1;
}
}
57 changes: 47 additions & 10 deletions web/src/common/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import {
import clsx from "clsx";
import TablePagination from "./TablePagination";
import "./Table.css";
import { ReactNode } from "react";
import React, { ReactNode, Ref } from "react";

interface TableProps {
variant: "default" | "absolute" | "relative";
instance: TanTable<any>;
classes: {
classes?: {
[P in
| "root"
| "row"
Expand All @@ -33,6 +33,8 @@ interface TableProps {
| "footer"]: string;
};
flexRender: Function;
virtualizationInstance: any;
virtualization: boolean;
onReload: () => void;
Root: any;
RootProps: (instance: TanTable<any>, props: TableProps) => any;
Expand Down Expand Up @@ -139,17 +141,22 @@ interface TableProps {
*
* @param {TableProps} props
*/
function Table(props: any) {
return props.renderRoot(props.instance, props);
}
const Table = React.forwardRef((props: any, ref: Ref<HTMLDivElement>) => {
return (
<div ref={ref} className="Table__container">
{props.renderRoot(props.instance, props)}
</div>
);
});

/**
* @type {TableProps}
*/
Table.defaultProps = {
header: true,
footer: false,
pagination: true,
pagination: false,
virtualization: false,
flexRender,
renderRoot,
renderTable,
Expand Down Expand Up @@ -405,6 +412,14 @@ function renderBody(instance: TanTable<any>, props: TableProps) {
// const isRelative = props.variant === "relative";
const Body = props.Body || isDefault ? "tbody" : "div";
const BodyProps = props.BodyProps?.(instance, props);
const { rows } = instance.getRowModel();
console.log("rows.length", rows);
const { virtualItems: virtualRows, totalSize } = props.virtualizationInstance;
const paddingTop = virtualRows.length > 0 ? virtualRows?.[0]?.start || 0 : 0;
const paddingBottom =
virtualRows.length > 0
? totalSize - (virtualRows?.[virtualRows.length - 1]?.end || 0)
: 0;

return (
<Body
Expand All @@ -417,10 +432,32 @@ function renderBody(instance: TanTable<any>, props: TableProps) {
),
}}
>
{BodyProps?.children ||
instance
.getPaginationRowModel()
.rows.map((bodyRow) => props.renderBodyRow(bodyRow, instance, props))}
<>
{props.virtualization ? (
<>
{paddingTop > 0 && (
<tr>
<td style={{ height: `${paddingTop}px` }} />
</tr>
)}
{virtualRows.map((virtualRow: any) =>
props.renderBodyRow(rows[virtualRow.index], instance, props)
)}
{paddingBottom > 0 && (
<tr>
<td style={{ height: `${paddingBottom}px` }} />
</tr>
)}
</>
) : (
BodyProps?.children ||
instance
.getPaginationRowModel()
.rows.map((bodyRow) =>
props.renderBodyRow(bodyRow, instance, props)
)
)}
</>
</Body>
);
}
Expand Down
13 changes: 1 addition & 12 deletions web/src/common/useTable.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
useReactTable,
getPaginationRowModel,
TableOptions,
getCoreRowModel,
} from "@tanstack/react-table";
import { useReactTable, TableOptions } from "@tanstack/react-table";

/**
*
Expand All @@ -12,15 +7,9 @@ import {
*/
function useTable(options: TableOptions<any>) {
return useReactTable({
// getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
debugTable: true,
...options,
data: options.data || [],
// defaultColumn: {
// // cell: (info) => <Typography>{info.getValue()}</Typography>,
// ...options?.defaultColumn,
// },
});
}

Expand Down
47 changes: 22 additions & 25 deletions web/src/server/ServerDetailServicesTabPanelProcess.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getCoreRowModel } from "@tanstack/react-table";
import { useVirtual } from "react-virtual";
import Table from "common/Table";
import useTable from "common/useTable";
import React from "react";
Expand All @@ -19,37 +20,33 @@ export default function ServerDetailServicesTabPanelProcess(
props: ServerDetailServicesTabPanelProcessType
) {
const tableInstance = useTable({
getCoreRowModel: getCoreRowModel(),
initialState: { pagination: { pageSize: 30 } },
columns,
data,
columns,
getCoreRowModel: getCoreRowModel(),
});

const tableContainerRef = React.useRef<HTMLDivElement>(null);

const { rows } = tableInstance.getRowModel();

const rowVirtualizer = useVirtual({
parentRef: tableContainerRef,
size: rows.length,
overscan: 10,
});

return (
<div>
<Table instance={tableInstance} />
</div>
<Table
ref={tableContainerRef}
variant="default"
virtualization
instance={tableInstance}
virtualizationInstance={rowVirtualizer}
/>
);
}

const columns = [
// {
// header: "Name",
// footer: (props) => props.column.id,
// columns: [
// {
// accessorKey: "firstname",
// cell: (info) => info.getValue(),
// footer: (props) => props.column.id
// },
// {
// accessorFn: (row) => row.lastName,
// id: "lastname",
// cell: (info) => info.getValue(),
// header: () => <span>Last Name</span>,
// footer: (props) => props.column.id
// }
// ]
// },
{
header: "First Name",
accessorKey: "firstname",
Expand All @@ -68,7 +65,7 @@ const columns = [
},
];

const data = Array(100).fill({
const data = Array(1000).fill({
firstname: "Joseph",
lastname: "Edache",
message: "Hello",
Expand Down

0 comments on commit 06f4d33

Please sign in to comment.