diff --git a/comps/custom/Detail.tsx b/comps/custom/Detail.tsx index c12976a..f113b33 100755 --- a/comps/custom/Detail.tsx +++ b/comps/custom/Detail.tsx @@ -138,9 +138,12 @@ export const Detail: FC<{ if (mode === "standard") { return ( -
-
{label}
-
+
+
{label}
+
-
+
{label}
-
{label}
-
+
{label}
+
{}; +import { useLocal } from "@/utils/use-local"; +import { FC, useEffect } from "react"; +import DataGrid, { ColumnOrColumnGroup, SortColumn } from "react-data-grid"; +import "react-data-grid/lib/styles.css"; +import { Skeleton } from "../ui/skeleton"; + +export const Table: FC<{ + columns: () => Promise[]>; + on_load: () => Promise; + child: any; + PassProp: any; +}> = ({ columns, on_load, child, PassProp }) => { + 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; +}> = ({ columns, data, render }) => { + 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 + : { + noRowsFallback: ( +
+
+ + + + +
No Data
+
+
+ ), + } + } + style={{ + height: typeof data === "undefined" ? 50 : local.height, + width: local.width, + }} + rows={data || []} + /> + {typeof data === "undefined" && ( +
+ + +
+ )} +
+ ); +};