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: (
+
+ ),
+ }
+ }
+ style={{
+ height: typeof data === "undefined" ? 50 : local.height,
+ width: local.width,
+ }}
+ rows={data || []}
+ />
+ {typeof data === "undefined" && (
+
+
+
+
+ )}
+
+ );
+};