'use client' import type { WebhookDeliveryEntry } from '@admin/actions/webhooks' import type { ColumnDef } from '@tanstack/react-table' import { DataGrid, DataGridBody, DataGridCell, DataGridHead, DataGridHeader, DataGridRow } from '@admin/components/shared/data-table/data-grid' import { DataTablePagination } from '@admin/components/shared/data-table/data-table-pagination' import { useTableUtils } from '@admin/hooks/use-table-utils' import { useWebhookDeliveries } from '@admin/hooks/use-webhooks' import { cn } from '@admin/utils/shared/cn' import { flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table' import { GripVertical } from 'lucide-react' import { parseAsInteger, parseAsString, useQueryStates } from 'nuqs' interface WebhooksLogsTableProps extends React.HTMLAttributes { columns: ColumnDef[] search?: string status?: string endpoint?: string createdAtFrom?: string createdAtTo?: string } export function WebhooksLogsTable({ columns, search, status, endpoint, createdAtFrom, createdAtTo, className }: WebhooksLogsTableProps) { const defaultPageSize = 20 const [{ page: pageIndex, size: pageSize, sort: sortField, dir: sortDir }, setTableQuery] = useQueryStates({ page: parseAsInteger.withDefault(0), size: parseAsInteger.withDefault(defaultPageSize), sort: parseAsString.withDefault(''), dir: parseAsString.withDefault('') }) const safePageIndex = Number.isFinite(pageIndex) && pageIndex > 0 ? pageIndex : 0 const safePageSize = pageSize === -1 || (Number.isFinite(pageSize) && pageSize > 0) ? pageSize : defaultPageSize const { data, error, isPending } = useWebhookDeliveries( search, status, endpoint, createdAtFrom, createdAtTo, safePageIndex, safePageSize, sortField || undefined, (sortDir as 'asc' | 'desc') || undefined ) const tableData = data?.deliveries ?? [] const totalRows = data?.total ?? 0 const effectivePageSize = safePageSize === -1 ? totalRows : safePageSize const pageCount = effectivePageSize > 0 ? Math.ceil(totalRows / effectivePageSize) : 1 const shouldShowPagination = totalRows > defaultPageSize const { columnSizing, handleColumnSizingChange, handlePaginationChange, handleSortingChange, hoveredColumnId, registerTable, resetColumnSizingToContainer, setHoveredColumnId, sorting, tableContainerRef } = useTableUtils({ data: tableData, pageIndex: safePageIndex, pageSize: effectivePageSize, setPageIndex: (nextPageIndex) => setTableQuery({ page: nextPageIndex }), setSortingParams: ({ pageIndex: nextPageIndex, sortDir: nextSortDir, sortField: nextSortField }) => setTableQuery({ page: nextPageIndex, sort: nextSortField, dir: nextSortDir }), sortField, sortDir }) const table = useReactTable({ data: tableData, columns, columnResizeMode: 'onChange', defaultColumn: { minSize: 48, size: 220 }, getCoreRowModel: getCoreRowModel(), manualPagination: true, manualSorting: true, pageCount, rowCount: totalRows, onSortingChange: handleSortingChange, onColumnSizingChange: handleColumnSizingChange, onPaginationChange: handlePaginationChange, state: { sorting, columnSizing, pagination: { pageIndex: safePageIndex, pageSize: effectivePageSize } } }) registerTable(table) const gridTemplateColumns = table .getVisibleLeafColumns() .map((column) => `${column.getSize()}px`) .join(' ') return (
{table.getHeaderGroups().map((headerGroup) => ( {headerGroup.headers.map((header, headerIndex) => { const resizeLabel = typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : header.column.id const nextHeader = headerGroup.headers[headerIndex + 1] const canResizeColumn = header.column.getCanResize() && nextHeader?.column.getCanResize() === true return ( setHoveredColumnId(header.column.id)} onMouseLeave={() => setHoveredColumnId((current) => current === header.column.id ? null : current ) } > {header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext())} {canResizeColumn ? ( ) : null} ) })} ))} {isPending ? (
Loading deliveries…
) : error ? (
Failed to load deliveries. Refresh to try again.
) : table.getRowModel().rows?.length ? ( table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( setHoveredColumnId(cell.column.id)} onMouseLeave={() => setHoveredColumnId((current) => (current === cell.column.id ? null : current)) } > {flexRender(cell.column.columnDef.cell, cell.getContext())} ))} )) ) : ( No deliveries found. )}
{shouldShowPagination ? ( setTableQuery({ page: nextPageIndex })} setPageSize={(nextPageSize) => setTableQuery({ page: 0, size: nextPageSize })} /> ) : null}
) }