| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- 'use client';
- import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table.js';
- import { DataTablePagination } from '@/framework/internal/data-table/data-table-pagination.js';
- import { DataTableViewOptions } from '@/framework/internal/data-table/data-table-view-options.js';
- import {
- ColumnDef,
- flexRender,
- getCoreRowModel,
- getPaginationRowModel,
- PaginationState,
- VisibilityState,
- SortingState,
- Table as TableType,
- useReactTable,
- ColumnFilter,
- ColumnFiltersState,
- } from '@tanstack/react-table';
- import React, { useEffect } from 'react';
- interface DataTableProps<TData, TValue> {
- columns: ColumnDef<TData, TValue>[];
- data: TData[];
- totalItems: number;
- page?: number;
- itemsPerPage?: number;
- sorting?: SortingState;
- columnFilters?: ColumnFiltersState;
- onPageChange?: (table: TableType<TData>, page: number, itemsPerPage: number) => void;
- onSortChange?: (table: TableType<TData>, sorting: SortingState) => void;
- onFilterChange?: (table: TableType<TData>, columnFilters: ColumnFilter[]) => void;
- defaultColumnVisibility?: VisibilityState;
- }
- export function DataTable<TData, TValue>({
- columns,
- data,
- totalItems,
- page,
- itemsPerPage,
- sorting: sortingInitialState,
- columnFilters: filtersInitialState,
- onPageChange,
- onSortChange,
- onFilterChange,
- defaultColumnVisibility,
- }: DataTableProps<TData, TValue>) {
- const [sorting, setSorting] = React.useState<SortingState>(sortingInitialState || []);
- const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>(filtersInitialState || []);
- const [pagination, setPagination] = React.useState<PaginationState>({
- pageIndex: (page ?? 1) - 1,
- pageSize: itemsPerPage ?? 10,
- });
- const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>(
- defaultColumnVisibility ?? {},
- );
- const table = useReactTable({
- data,
- columns,
- getCoreRowModel: getCoreRowModel(),
- getPaginationRowModel: getPaginationRowModel(),
- manualPagination: true,
- manualSorting: true,
- manualFiltering: true,
- rowCount: totalItems,
- onPaginationChange: setPagination,
- onSortingChange: setSorting,
- onColumnVisibilityChange: setColumnVisibility,
- onColumnFiltersChange: setColumnFilters,
- state: {
- pagination,
- sorting,
- columnVisibility,
- columnFilters,
- },
- });
- useEffect(() => {
- onPageChange?.(table, pagination.pageIndex + 1, pagination.pageSize);
- }, [pagination]);
- useEffect(() => {
- onSortChange?.(table, sorting);
- }, [sorting]);
- useEffect(() => {
- onFilterChange?.(table, columnFilters);
- }, [columnFilters]);
- return (
- <>
- <DataTableViewOptions table={table} />
- <div className="rounded-md border my-2">
- <Table>
- <TableHeader>
- {table.getHeaderGroups().map(headerGroup => (
- <TableRow key={headerGroup.id}>
- {headerGroup.headers.map(header => {
- return (
- <TableHead key={header.id}>
- {header.isPlaceholder
- ? null
- : flexRender(
- header.column.columnDef.header,
- header.getContext(),
- )}
- </TableHead>
- );
- })}
- </TableRow>
- ))}
- </TableHeader>
- <TableBody>
- {table.getRowModel().rows?.length ? (
- table.getRowModel().rows.map(row => (
- <TableRow key={row.id} data-state={row.getIsSelected() && 'selected'}>
- {row.getVisibleCells().map(cell => (
- <TableCell key={cell.id}>
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
- </TableCell>
- ))}
- </TableRow>
- ))
- ) : (
- <TableRow>
- <TableCell colSpan={columns.length} className="h-24 text-center">
- No results.
- </TableCell>
- </TableRow>
- )}
- </TableBody>
- </Table>
- </div>
- <DataTablePagination table={table} />
- </>
- );
- }
|