Files
tusk/src/components/table-viewer/PaginationControls.tsx
A.Shakhmatov 9b9d2cee94 feat: add table data viewer, structure inspector, and export
Add TableDataView with pagination, filtering, and inline editing,
TableStructure with columns/constraints/indexes tabs,
PaginationControls, and ExportDialog for CSV/JSON export.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 19:06:54 +03:00

106 lines
2.8 KiB
TypeScript

import { Button } from "@/components/ui/button";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import {
ChevronsLeft,
ChevronLeft,
ChevronRight,
ChevronsRight,
} from "lucide-react";
interface Props {
page: number;
pageSize: number;
totalRows: number;
onPageChange: (page: number) => void;
onPageSizeChange: (size: number) => void;
}
export function PaginationControls({
page,
pageSize,
totalRows,
onPageChange,
onPageSizeChange,
}: Props) {
const totalPages = Math.max(1, Math.ceil(totalRows / pageSize));
const from = (page - 1) * pageSize + 1;
const to = Math.min(page * pageSize, totalRows);
return (
<div className="flex items-center justify-between border-t px-3 py-1.5">
<span className="text-xs text-muted-foreground">
Showing {totalRows > 0 ? from.toLocaleString() : 0}-
{to.toLocaleString()} of {totalRows.toLocaleString()}
</span>
<div className="flex items-center gap-2">
<Select
value={String(pageSize)}
onValueChange={(v) => onPageSizeChange(Number(v))}
>
<SelectTrigger className="h-6 w-[70px] text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
{[25, 50, 100, 500].map((size) => (
<SelectItem key={size} value={String(size)}>
{size}
</SelectItem>
))}
</SelectContent>
</Select>
<div className="flex items-center gap-0.5">
<Button
variant="ghost"
size="icon"
className="h-6 w-6"
onClick={() => onPageChange(1)}
disabled={page <= 1}
>
<ChevronsLeft className="h-3.5 w-3.5" />
</Button>
<Button
variant="ghost"
size="icon"
className="h-6 w-6"
onClick={() => onPageChange(page - 1)}
disabled={page <= 1}
>
<ChevronLeft className="h-3.5 w-3.5" />
</Button>
<span className="px-2 text-xs text-muted-foreground">
{page} / {totalPages}
</span>
<Button
variant="ghost"
size="icon"
className="h-6 w-6"
onClick={() => onPageChange(page + 1)}
disabled={page >= totalPages}
>
<ChevronRight className="h-3.5 w-3.5" />
</Button>
<Button
variant="ghost"
size="icon"
className="h-6 w-6"
onClick={() => onPageChange(totalPages)}
disabled={page >= totalPages}
>
<ChevronsRight className="h-3.5 w-3.5" />
</Button>
</div>
</div>
</div>
);
}