add column template

This commit is contained in:
2024-07-11 22:57:50 +02:00
parent c827329cdd
commit e907291f06
4 changed files with 73 additions and 30 deletions

BIN
api/bun.lockb Normal file → Executable file

Binary file not shown.

BIN
frontend/bun.lockb Normal file → Executable file

Binary file not shown.

View File

@@ -1,36 +1,71 @@
import {
Button,
DataTablePagination,
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuTrigger,
ScrollArea,
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui";
import { cn, isImageUrl, isUrl } from "@/lib/utils"; import { cn, isImageUrl, isUrl } from "@/lib/utils";
import { useTableColumnsQuery, useTableDataQuery } from "@/services/db"; import { useTableColumnsQuery, useTableDataQuery } from "@/services/db";
import { useSettingsStore } from "@/state"; import { useSettingsStore } from "@/state";
import { import type { SortingState, VisibilityState } from "@tanstack/react-table";
type ColumnDef, import { Rows3 } from "lucide-react";
type OnChangeFn,
type PaginationState,
type SortingState,
type VisibilityState,
flexRender,
getCoreRowModel,
useReactTable,
} from "@tanstack/react-table";
import { ArrowUp, Rows3 } from "lucide-react";
import { Column } from "primereact/column"; import { Column } from "primereact/column";
import { DataTable } from "primereact/datatable"; import { DataTable } from "primereact/datatable";
import { usePassThrough } from "primereact/passthrough"; import { useState } from "react";
import { useMemo, useState } from "react";
const columnTemplate =
({
columnName,
formatDates,
showImagesPreview,
udt_name,
data_type,
}: {
columnName: string;
formatDates: boolean;
showImagesPreview: boolean;
udt_name: string;
data_type: string;
}) =>
(item: Record<string, any>) => {
const value = item[columnName] as any;
let finalValue = value;
if (
formatDates &&
["timestamp", "datetime"].includes(udt_name.toLowerCase())
) {
finalValue = new Date(value as string).toLocaleString();
}
if (showImagesPreview && typeof value === "string" && isUrl(value)) {
const isImage = isImageUrl(value);
return (
<a
href={value}
target={"_blank"}
className={cn("hover:underline")}
rel="noreferrer"
>
<div className={"flex items-center justify-between break-all gap-4"}>
{value}
{isImage && (
<img
src={value}
alt={"preview"}
className="size-20 object-cover"
/>
)}
</div>
</a>
);
}
return (
<div
className={cn(
"break-all",
["integer", "int", "tinyint", "double"].includes(data_type) &&
"text-right",
)}
>
{finalValue}
</div>
);
};
export const DataTablePrime = ({ export const DataTablePrime = ({
tableName, tableName,
dbName, dbName,
@@ -53,7 +88,7 @@ export const DataTablePrime = ({
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({}); const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
const { data: columns } = useTableColumnsQuery({ dbName, tableName }); const { data: columns } = useTableColumnsQuery({ dbName, tableName });
const { data } = useTableDataQuery({ const { data, isFetching } = useTableDataQuery({
tableName, tableName,
dbName, dbName,
perPage: pageSize, perPage: pageSize,
@@ -96,12 +131,20 @@ export const DataTablePrime = ({
tableStyle={{ minWidth: "100%" }} tableStyle={{ minWidth: "100%" }}
scrollable scrollable
scrollHeight="flex" scrollHeight="flex"
loading={isFetching}
> >
{columns?.map((col) => ( {columns?.map((col) => (
<Column <Column
key={col.column_name} key={col.column_name}
field={col.column_name} field={col.column_name}
header={col.column_name} header={col.column_name}
body={columnTemplate({
columnName: col.column_name,
formatDates,
showImagesPreview,
udt_name: col.udt_name,
data_type: col.data_type,
})}
/> />
))} ))}
</DataTable> </DataTable>

View File

@@ -24,7 +24,7 @@ export const datatable: DataTablePassThroughOptions = {
className: cn( className: cn(
"fixed w-full h-full t-0 l-0 bg-gray-100/40", "fixed w-full h-full t-0 l-0 bg-gray-100/40",
"transition duration-200", "transition duration-200",
"absolute flex items-center justify-center z-2", "absolute flex items-center justify-center z-10",
"dark:bg-gray-950/40", // Dark Mode "dark:bg-gray-950/40", // Dark Mode
), ),
}, },