Refine Integration #13
|
@ -1,4 +1,4 @@
|
||||||
import { useState } from "react";
|
import { useMemo} from "react";
|
||||||
import { BaseRecord } from "@refinedev/core";
|
import { BaseRecord } from "@refinedev/core";
|
||||||
import { useTable } from "@refinedev/react-table";
|
import { useTable } from "@refinedev/react-table";
|
||||||
import {
|
import {
|
||||||
|
@ -14,6 +14,7 @@ import {
|
||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "./ui/table"
|
} from "./ui/table"
|
||||||
|
import { Skeleton } from "./ui/skeleton";
|
||||||
import { DataTablePagination } from "./table-pagination"
|
import { DataTablePagination } from "./table-pagination"
|
||||||
|
|
||||||
interface DataTableProps<TData extends BaseRecord = BaseRecord, TValue = unknown> {
|
interface DataTableProps<TData extends BaseRecord = BaseRecord, TValue = unknown> {
|
||||||
|
@ -21,22 +22,31 @@ interface DataTableProps<TData extends BaseRecord = BaseRecord, TValue = unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DataTable<TData extends BaseRecord, TValue>({
|
export function DataTable<TData extends BaseRecord, TValue>({
|
||||||
columns
|
columns,
|
||||||
}: DataTableProps<TData, TValue>) {
|
}: DataTableProps<TData, TValue>) {
|
||||||
const [hoveredRowId, setHoveredRowId] = useState<string>("");
|
|
||||||
|
|
||||||
const table = useTable({
|
const table = useTable({
|
||||||
columns,
|
columns,
|
||||||
meta: {
|
|
||||||
hoveredRowId,
|
|
||||||
},
|
|
||||||
refineCoreProps: {
|
refineCoreProps: {
|
||||||
resource: "files"
|
resource: "files"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const loadingRows = useMemo(() => Array(4).fill({}).map(() => ({
|
||||||
|
getIsSelected: () => false,
|
||||||
|
getVisibleCells: () => columns.map(() => ({
|
||||||
|
column: {
|
||||||
|
columnDef: {
|
||||||
|
cell: <Skeleton className="h-4 w-full bg-primary-1/30" />,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getContext: () => null
|
||||||
|
})),
|
||||||
|
})), [])
|
||||||
|
|
||||||
|
const rows = table.refineCore.tableQueryResult.isLoading ? loadingRows : table.getRowModel().rows
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="rounded-lg">
|
<>
|
||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
{table.getHeaderGroups().map((headerGroup) => (
|
||||||
|
@ -57,15 +67,12 @@ export function DataTable<TData extends BaseRecord, TValue>({
|
||||||
))}
|
))}
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{table.getRowModel().rows?.length ? (
|
{rows.length ? (
|
||||||
table.getRowModel().rows.map((row) => (
|
rows.map((row) => (
|
||||||
<TableRow
|
<TableRow
|
||||||
key={row.id}
|
key={row.id}
|
||||||
data-state={row.getIsSelected() && "selected"}
|
data-state={row.getIsSelected() && "selected"}
|
||||||
onMouseEnter={() => {
|
className="group"
|
||||||
console.log(hoveredRowId, row.id);
|
|
||||||
setHoveredRowId(row.id)
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{row.getVisibleCells().map((cell) => (
|
{row.getVisibleCells().map((cell) => (
|
||||||
<TableCell key={cell.id}>
|
<TableCell key={cell.id}>
|
||||||
|
@ -84,6 +91,6 @@ export function DataTable<TData extends BaseRecord, TValue>({
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
<DataTablePagination table={table} />
|
<DataTablePagination table={table} />
|
||||||
</div>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { cn } from "~/utils"
|
||||||
|
|
||||||
|
function Skeleton({
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: React.HTMLAttributes<HTMLDivElement>) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn("animate-pulse rounded-md bg-primary/10", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Skeleton }
|
|
@ -3,6 +3,7 @@ import type { ColumnDef, RowData } from "@tanstack/react-table";
|
||||||
import { FileIcon, MoreIcon } from "~/components/icons";
|
import { FileIcon, MoreIcon } from "~/components/icons";
|
||||||
import { Checkbox } from "~/components/ui/checkbox";
|
import { Checkbox } from "~/components/ui/checkbox";
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "~/components/ui/dropdown-menu";
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "~/components/ui/dropdown-menu";
|
||||||
|
import { cn } from "~/utils";
|
||||||
|
|
||||||
// This type is used to define the shape of our data.
|
// This type is used to define the shape of our data.
|
||||||
// You can use a Zod schema here if you want.
|
// You can use a Zod schema here if you want.
|
||||||
|
@ -66,12 +67,13 @@ export const columns: ColumnDef<File>[] = [
|
||||||
accessorKey: "createdOn",
|
accessorKey: "createdOn",
|
||||||
size: 200,
|
size: 200,
|
||||||
header: "Created On",
|
header: "Created On",
|
||||||
cell: ({ row, table }) => (
|
cell: ({ row }) => (
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
{row.getValue("createdOn")}
|
{row.getValue("createdOn")}
|
||||||
{(row.getIsSelected() || table.options.meta?.hoveredRowId === row.id) && (
|
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger>
|
<DropdownMenuTrigger className={
|
||||||
|
cn("hidden group-hover:block data-[state=open]:block", row.getIsSelected() && "block")
|
||||||
|
}>
|
||||||
<MoreIcon />
|
<MoreIcon />
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="end">
|
<DropdownMenuContent align="end">
|
||||||
|
@ -88,7 +90,6 @@ export const columns: ColumnDef<File>[] = [
|
||||||
</DropdownMenuGroup>
|
</DropdownMenuGroup>
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue