gitscope
← marzneshin / v0.4.0 / dashboard/src/components/data-table/table.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/components/data-table/table.tsx · TypeScript
Blame Raw
  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 "./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}