1import {
2 ColumnDef,
3 ColumnFiltersState,
4 OnChangeFn,
5 RowSelectionState,
6 SortingState,
7 VisibilityState,
8 flexRender,
9 getCoreRowModel,
10 getFilteredRowModel,
11 getPaginationRowModel,
12 getSortedRowModel,
13 useReactTable,
14} from "@tanstack/react-table"
15
16import {
17 Button,
18 Input,
19 Table,
20 TableBody,
21 TableCell,
22 TableHead,
23 TableHeader,
24 TableRow,
25} from "@marzneshin/components"
26
27import { useTranslation } from "react-i18next"
28import { DataTablePagination } from "./table-pagination"
29import { useState } from "react"
30import { DataTableViewOptions } from "./table-view-option"
31
32interface DataTableProps<TData, TValue> {
33 columns: ColumnDef<TData, TValue>[]
34 data: TData[]
35 filteredColumn: string
36 onCreate?: () => void
37 onOpen?: (object: TData) => void
38 setSelectedRow?: OnChangeFn<RowSelectionState> | undefined
39 selectedRow?: RowSelectionState | undefined
40}
41
42export function DataTable<TData, TValue>({
43 columns,
44 data,
45 onCreate,
46 onOpen,
47 filteredColumn,
48 selectedRow,
49 setSelectedRow,
50}: DataTableProps<TData, TValue>) {
51 const [sorting, setSorting] = useState<SortingState>([])
52 const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>(
53 []
54 )
55 const [columnVisibility, setColumnVisibility] =
56 useState<VisibilityState>({})
57 const table = useReactTable({
58 data,
59 columns,
60 onSortingChange: setSorting,
61 onColumnFiltersChange: setColumnFilters,
62 getCoreRowModel: getCoreRowModel(),
63 getPaginationRowModel: getPaginationRowModel(),
64 getSortedRowModel: getSortedRowModel(),
65 getFilteredRowModel: getFilteredRowModel(),
66 onColumnVisibilityChange: setColumnVisibility,
67 onRowSelectionChange: setSelectedRow,
68 state: {
69 sorting,
70 columnFilters,
71 columnVisibility,
72 rowSelection: selectedRow !== undefined ? selectedRow : {},
73 },
74 })
75 const { t } = useTranslation();
76 return (
77 <div>
78 <div className="flex items-center py-4">
79 <Input
80 placeholder={t('table.filter-placeholder', { name: filteredColumn })}
81 value={(table.getColumn(filteredColumn)?.getFilterValue() as string) ?? ""}
82 onChange={(event) =>
83 table.getColumn(filteredColumn)?.setFilterValue(event.target.value)
84 }
85 className="max-w-sm"
86 />
87 <DataTableViewOptions table={table} />
88 {onCreate && (<Button onClick={onCreate}>{t('create')}</Button>)}
89 </div>
90 <div className="rounded-md border">
91 <Table>
92 <TableHeader>
93 {table.getHeaderGroups().map((headerGroup) => (
94 <TableRow key={headerGroup.id}>
95 {headerGroup.headers.map((header) => {
96 return (
97 <TableHead key={header.id}>
98 {header.isPlaceholder
99 ? null
100 : flexRender(
101 header.column.columnDef.header,
102 header.getContext()
103 )}
104 </TableHead>
105 )
106 })}
107 </TableRow>
108 ))}
109 </TableHeader>
110 <TableBody>
111 {table.getRowModel().rows?.length ? (
112 table.getRowModel().rows.map((row) => (
113 <TableRow
114 key={row.id}
115 data-state={row.getIsSelected() && "selected"}
116 onClick={() => onOpen !== undefined && onOpen(row.original)}
117 >
118 {row.getVisibleCells().map((cell) => (
119 <TableCell key={cell.id}>
120 {flexRender(cell.column.columnDef.cell, cell.getContext())}
121 </TableCell>
122 ))}
123 </TableRow>
124 ))
125 ) : (
126 <TableRow>
127 <TableCell colSpan={columns.length} className="h-24 text-center">
128 {t('table.no-result')}
129 </TableCell>
130 </TableRow>
131 )}
132 </TableBody>
133 </Table>
134 <DataTablePagination table={table} />
135 </div>
136 </div>
137 )
138}