import { useLocal } from "@/utils/use-local"; import { FC, useEffect } from "react"; import DataGrid, { ColumnOrColumnGroup, Row, SortColumn, } from "react-data-grid"; import "react-data-grid/lib/styles.css"; import { Skeleton } from "../ui/skeleton"; type OnRowClick = { row: any; rows: any[]; idx: any; event: React.MouseEvent; }; export const Table: FC<{ columns: () => Promise[]>; on_load: () => Promise; child: any; PassProp: any; row_click: (arg: OnRowClick) => void; }> = ({ columns, on_load, child, PassProp, row_click }) => { const local = useLocal({ loading: false, data: undefined as unknown as any[], columns: [] as ColumnOrColumnGroup[], }); useEffect(() => { local.loading = true; columns().then((col) => { local.columns = col.map((e) => ({ ...e, resizable: true, renderCell(props) { return ( {child} ); }, })); if (!!local.data) { local.loading = false; } local.render(); }); }, [columns]); useEffect(() => { local.loading = true; on_load().then((data) => { local.data = data; local.loading = false; local.render(); }); }, [on_load]); return ( ); }; const TableInternal: FC<{ columns: ColumnOrColumnGroup[]; data?: any[]; render: () => void; row_click: (arg: OnRowClick) => void; }> = ({ columns, data, render, row_click }) => { const local = useLocal({ width: 0, height: 0, rob: new ResizeObserver(([e]) => { local.height = e.contentRect.height; local.width = e.contentRect.width; local.render(); }), el: null as any, sort: [] as SortColumn[], }); useEffect(() => { return () => { local.rob.disconnect(); }; }, []); const sort = local.sort; let sorted = data; if (sort.length > 0 && data) { sorted = data.sort((a, b) => { const va = a[sort[0].columnKey]; const vb = b[sort[0].columnKey]; if (typeof va === "string" && typeof vb === "string") { if (sort[0].direction === "ASC") { return va.localeCompare(vb); } else { return vb.localeCompare(va); } } return 0; }); } return (
{ if (!local.el && el) { local.el = el; local.rob.observe(el); } }} > { local.sort = []; if (col) { if (sort.length > 0) { const first = sort[0]; if (first && first.columnKey === col.columnKey) { local.sort.push({ columnKey: col.columnKey, direction: first.direction === "ASC" ? "DESC" : "ASC", }); render(); return; } } local.sort.push(col); } render(); }} className="fill-grid rdg-light" renderers={ typeof data === "undefined" ? undefined : { renderRow(key, props) { return ( { if (typeof row_click === "function") { row_click({ event: ev, idx: props.rowIdx, row: props.row, rows: data, }); } }} /> ); }, noRowsFallback: (
No Data
), } } style={{ height: typeof data === "undefined" ? 50 : local.height, width: local.width, }} rows={data || []} /> {typeof data === "undefined" && (
)}
); };