import { type ColumnDef, flexRender, getCoreRowModel, useReactTable, } from "@tanstack/react-table"; import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell, } from "@/components/ui/table"; import { Card, CardHeader, CardTitle, CardDescription, CardContent, } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { type Audits } from "@/types/audit"; import { AuditFilterBar } from "@/components/filters/audit-filter-bar"; import { AuditDetailDialog } from "@/components/dialogs/audit-detail-dialog"; interface AuditListTemplateProps { // data items: Audits[]; total: number; columns: ColumnDef[]; isLoading: boolean; isFetching: boolean; // pagination pageNumber: number; pageSize: number; pageCount: number; onPreviousPage: () => void; onNextPage: () => void; canPreviousPage: boolean; canNextPage: boolean; // filter username: string | null; action: string | null; from: string | null; to: string | null; onUsernameChange: (v: string | null) => void; onActionChange: (v: string | null) => void; onFromChange: (v: string | null) => void; onToChange: (v: string | null) => void; onSearch: () => void; onReset: () => void; // detail dialog selectedAudit: Audits | null; onRowClick: (audit: Audits) => void; onDialogClose: () => void; } export function AuditListTemplate({ items, total, columns, isLoading, isFetching, pageNumber, pageSize, pageCount, onPreviousPage, onNextPage, canPreviousPage, canNextPage, username, action, from, to, onUsernameChange, onActionChange, onFromChange, onToChange, onSearch, onReset, selectedAudit, onRowClick, onDialogClose, }: AuditListTemplateProps) { const table = useReactTable({ data: items, columns, state: { pagination: { pageIndex: Math.max(0, pageNumber - 1), pageSize }, }, pageCount, manualPagination: true, onPaginationChange: (updater) => { const next = typeof updater === "function" ? updater({ pageIndex: Math.max(0, pageNumber - 1), pageSize }) : updater; const newPage = (next.pageIndex ?? 0) + 1; if (newPage > pageNumber) onNextPage(); else if (newPage < pageNumber) onPreviousPage(); }, getCoreRowModel: getCoreRowModel(), }); return (

Nhật ký hoạt động

Xem nhật ký audit hệ thống

Danh sách audit Lọc theo người dùng, loại, hành động và khoảng thời gian. Nhấn vào dòng để xem chi tiết.
{table.getHeaderGroups().map((hg) => ( {hg.headers.map((header) => ( {flexRender( header.column.columnDef.header, header.getContext() )} ))} ))} {isLoading || isFetching ? ( Đang tải... ) : table.getRowModel().rows.length === 0 ? ( Không có dữ liệu ) : ( table.getRowModel().rows.map((row) => ( onRowClick(row.original)} > {row.getVisibleCells().map((cell) => ( {cell.column.columnDef.cell ? flexRender( cell.column.columnDef.cell, cell.getContext() ) : String(cell.getValue() ?? "")} ))} )) )}
Hiển thị {items.length} / {total} mục
{pageNumber} / {pageCount}
); }