https://dev.kronoz.win/r/marzneshin.git
1import {
2 ColumnDef,
3 flexRender,
4} from "@tanstack/react-table";
5import {
6 Table,
7 TableBody,
8 TableCell,
9 TableHead,
10 TableHeader,
11 TableRow,
12 Skeleton
13} from "@marzneshin/common/components";
14import { useTranslation } from "react-i18next";
15import { useEntityTableContext } from "@marzneshin/libs/entity-table/contexts";
16import { type FC } from "react";
17
18interface DataTableProps<TData, TValue> {
19 columns: ColumnDef<TData, TValue>[]
20 onRowClick?: (object: TData) => void
21}
22
23const Headers = () => {
24 const { table } = useEntityTableContext();
25 return (
26 table.getHeaderGroups().map(headerGroup => (
27 <TableRow key={headerGroup.id}>
28 {headerGroup.headers.map(header => (
29 <TableHead key={header.id}>
30 {!header.isPlaceholder && flexRender(header.column.columnDef.header, header.getContext())}
31 </TableHead>
32 ))}
33 </TableRow>
34 ))
35 )
36};
37
38const Rows: FC<Readonly<DataTableProps<any, any>>> = ({
39 columns,
40 onRowClick
41}) => {
42 const { table } = useEntityTableContext();
43 const { t } = useTranslation();
44
45 return (table.getRowModel().rows?.length ? (
46 table.getRowModel().rows.map(row => (
47 <TableRow
48 key={row.id}
49 data-state={row.getIsSelected() ? "selected" : undefined}
50 data-testid="entity-table-row"
51 onClick={() => onRowClick?.(row.original)}
52 >
53 {row.getVisibleCells().map(cell => (
54 <TableCell key={cell.id}>
55 {flexRender(cell.column.columnDef.cell, cell.getContext())}
56 </TableCell>
57 ))}
58 </TableRow>
59 ))
60 ) : (
61 <TableRow>
62 <TableCell colSpan={columns.length} className="h-24 text-center">
63 {t('table.no-result')}
64 </TableCell>
65 </TableRow>
66 ))
67};
68
69const Loading = () => (
70 <>
71 {Array.from({ length: 5 }).map((_, rowIndex) => (
72 <TableRow key={`skeleton-row-${rowIndex}`} className="w-full">
73 <TableCell className="h-12">
74 <Skeleton className="w-full h-full" />
75 </TableCell>
76 <TableCell className="h-12">
77 <Skeleton className="w-full h-full" />
78 </TableCell>
79 <TableCell className="h-12">
80 <Skeleton className="w-full h-full" />
81 </TableCell>
82 <TableCell className="h-12">
83 <Skeleton className="w-full h-full" />
84 </TableCell>
85 <TableCell className="h-12">
86 <Skeleton className="w-full h-full" />
87 </TableCell>
88 </TableRow>
89 ))}
90 </>
91);
92
93export function EntityDataTable<TData, TValue>({
94 columns,
95 onRowClick,
96}: Readonly<DataTableProps<TData, TValue>>) {
97 const { isLoading } = useEntityTableContext();
98
99 return (
100 <Table className="w-full">
101 <TableHeader> <Headers /> </TableHeader>
102 <TableBody>
103 {isLoading ? <Loading /> : <Rows onRowClick={onRowClick} columns={columns} />}
104 </TableBody>
105 </Table>
106 );
107}