"use client" import { ColumnDef, ColumnFiltersState, ColumnSizingState, Row, SortingState, Table, TableMeta, VisibilityState, flexRender, getCoreRowModel, getFacetedRowModel, getFacetedUniqueValues, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table" import * as React from "react" import { Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, TableBody, TableCell, Table as TableComp, TableFooter, 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" export type DataTableOps = { onAdd?: (table: Table) => void; } export type DataTableRowOps = { duplicate?(index: number, table: Table): void; remove?(index: number, table: Table): void; move?(from: number, to: number, table: Table): void; canMoveUp?(index: number, table: Table): boolean; canMoveDown?(index: number, lastIndex: number, table: Table): boolean; }; export type DataTableBulkRowOps = { duplicateSelected?: (indexes: number[], table: Table) => void; removeSelected?: (indexes: number[], table: Table) => void; moveSelectedUp?: (indexes: number[], table: Table) => void; moveSelectedDown?: (indexes: number[], table: Table) => void; }; export type DataTableMeta = TableMeta & { tableOps?: DataTableOps rowOps?: DataTableRowOps bulkOps?: DataTableBulkRowOps } export interface DataTableProps { columns: ColumnDef[] data: TData[] meta?: DataTableMeta // Configuración readOnly?: boolean enablePagination?: boolean pageSize?: number enableRowSelection?: boolean EditorComponent?: React.ComponentType<{ row: TData; index: number; onClose: () => void }> getRowId?: (row: Row, index: number) => string; } export function DataTable({ columns, data, meta, readOnly = false, enablePagination = true, pageSize = 25, enableRowSelection = false, EditorComponent, }: DataTableProps) { const { t } = useTranslation(); const [rowSelection, setRowSelection] = React.useState({}) const [sorting, setSorting] = React.useState([]) const [columnVisibility, setColumnVisibility] = React.useState({}) const [columnFilters, setColumnFilters] = React.useState([]) const [colSizes, setColSizes] = React.useState({}) const [editIndex, setEditIndex] = React.useState(null) const table = useReactTable({ data, columns, columnResizeMode: "onChange", onColumnSizingChange: setColSizes, getRowId: (row: any, i) => row.id ?? String(i), meta, state: { columnSizing: colSizes, sorting, columnVisibility, rowSelection, columnFilters, }, initialState: { pagination: { pageSize }, }, enableRowSelection, onRowSelectionChange: setRowSelection, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, onColumnVisibilityChange: setColumnVisibility, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), getPaginationRowModel: getPaginationRowModel(), getSortedRowModel: getSortedRowModel(), getFacetedRowModel: getFacetedRowModel(), getFacetedUniqueValues: getFacetedUniqueValues(), }) const handleCloseEditor = React.useCallback(() => setEditIndex(null), []) 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, i) => ( {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.datatable.empty")} )}
{enablePagination && } {EditorComponent && editIndex !== null && ( {t("components.datatable.editor.title")} {t("components.datatable.editor.subtitle")}
)}
) }