"use client" import { ColumnDef, ColumnFiltersState, ColumnSizingState, SortingState, VisibilityState, flexRender, getCoreRowModel, getFacetedRowModel, getFacetedUniqueValues, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table" import * as React from "react" import { Dialog, DialogContent, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@repo/shadcn-ui/components' import { DataTablePagination } from './data-table-pagination.tsx' import { DataTableToolbar } from "./data-table-toolbar.tsx" import { useTranslation } from "../../locales/i18n.ts" type DataTableRowOps = { duplicate?(index: number): void; remove?(index: number): void; move?(from: number, to: number): void; canMoveUp?(index: number): boolean; canMoveDown?(index: number, lastIndex: number): boolean; }; interface DataTableProps { columns: ColumnDef[] data: TData[], meta?: Record, getRowId?: (row: TData, index: number) => string; pageSize?: number; enableRowSelection?: boolean; renderRowEditor?: (index: number, close: () => void) => React.ReactNode; // editor modal opcional. Se muestra dentro de un Dialog. } export function DataTable({ columns, data, meta, getRowId, pageSize = 25, enableRowSelection = true, renderRowEditor, }: DataTableProps) { const { t } = useTranslation(); const [rowSelection, setRowSelection] = React.useState({}); const [columnVisibility, setColumnVisibility] = React.useState({}); const [columnFilters, setColumnFilters] = React.useState([]); const [sorting, setSorting] = React.useState([]); const [colSizes, setColSizes] = React.useState({}); const [editIndex, setEditIndex] = React.useState(null); const openEditor = React.useCallback((i: number) => setEditIndex(i), []); const closeEditor = React.useCallback(() => setEditIndex(null), []); const table = useReactTable({ data, columns, columnResizeMode: "onChange", onColumnSizingChange: setColSizes, getRowId: getRowId ?? ((row: any, idx) => (row?.id ? String(row.id) : String(idx))), state: { columnSizing: colSizes, sorting, columnVisibility, rowSelection, columnFilters, }, initialState: { pagination: { pageSize } }, meta: { ...meta, openEditor }, enableRowSelection, getCoreRowModel: getCoreRowModel(), onRowSelectionChange: setRowSelection, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, onColumnVisibilityChange: setColumnVisibility, getFilteredRowModel: getFilteredRowModel(), getPaginationRowModel: getPaginationRowModel(), getSortedRowModel: getSortedRowModel(), getFacetedRowModel: getFacetedRowModel(), getFacetedUniqueValues: getFacetedUniqueValues(), }) return (
{table.getHeaderGroups().map((hg) => ( {hg.headers.map((h) => { const w = h.getSize(); // px const minW = h.column.columnDef.minSize; const maxW = h.column.columnDef.maxSize; return ( {h.isPlaceholder ? null : flexRender(h.column.columnDef.header, h.getContext())} ); })} ))} {table.getRowModel().rows.length ? ( table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => { const w = cell.column.getSize(); const minW = cell.column.columnDef.minSize; const maxW = cell.column.columnDef.maxSize; return ( {flexRender(cell.column.columnDef.cell, cell.getContext())} ); })} )) ) : ( {t("components.datatabla.empty")} )}
{!!renderRowEditor && editIndex !== null && ( (!open ? closeEditor() : null)}> {renderRowEditor(editIndex, closeEditor)} )}
); }