import { useMemo, useState } from "react"; import { type ColumnDef, type OnChangeFn, type SortingState, type Updater, type VisibilityState, getCoreRowModel, getSortedRowModel, useReactTable, } from "@tanstack/react-table"; import { type BoardGroupRead } from "@/api/generated/model"; import { DataTable, type DataTableEmptyState, } from "@/components/tables/DataTable"; import { dateCell, linkifyCell } from "@/components/tables/cell-formatters"; type BoardGroupsTableProps = { groups: BoardGroupRead[]; isLoading?: boolean; sorting?: SortingState; onSortingChange?: OnChangeFn; stickyHeader?: boolean; showActions?: boolean; hiddenColumns?: string[]; columnOrder?: string[]; disableSorting?: boolean; onDelete?: (group: BoardGroupRead) => void; emptyMessage?: string; emptyState?: Omit & { icon?: DataTableEmptyState["icon"]; }; }; const DEFAULT_EMPTY_ICON = ( ); export function BoardGroupsTable({ groups, isLoading = false, sorting, onSortingChange, stickyHeader = false, showActions = true, hiddenColumns, columnOrder, disableSorting = false, onDelete, emptyMessage = "No groups found.", emptyState, }: BoardGroupsTableProps) { const [internalSorting, setInternalSorting] = useState([ { id: "name", desc: false }, ]); const resolvedSorting = sorting ?? internalSorting; const handleSortingChange: OnChangeFn = onSortingChange ?? ((updater: Updater) => { setInternalSorting(updater); }); const columnVisibility = useMemo( () => Object.fromEntries( (hiddenColumns ?? []).map((columnId) => [columnId, false]), ), [hiddenColumns], ); const columns = useMemo[]>(() => { const baseColumns: ColumnDef[] = [ { accessorKey: "name", header: "Group", cell: ({ row }) => linkifyCell({ href: `/board-groups/${row.original.id}`, label: row.original.name, subtitle: row.original.description ?? "No description", subtitleClassName: row.original.description ? "mt-1 line-clamp-2 text-xs text-slate-500" : "mt-1 text-xs text-slate-400", }), }, { accessorKey: "updated_at", header: "Updated", cell: ({ row }) => dateCell(row.original.updated_at), }, ]; return baseColumns; }, []); // eslint-disable-next-line react-hooks/incompatible-library const table = useReactTable({ data: groups, columns, enableSorting: !disableSorting, state: { ...(!disableSorting ? { sorting: resolvedSorting } : {}), ...(columnOrder ? { columnOrder } : {}), columnVisibility, }, ...(disableSorting ? {} : { onSortingChange: handleSortingChange }), getCoreRowModel: getCoreRowModel(), ...(disableSorting ? {} : { getSortedRowModel: getSortedRowModel() }), }); return ( `/board-groups/${group.id}/edit`, onDelete, } : undefined } emptyState={ emptyState ? { icon: emptyState.icon ?? DEFAULT_EMPTY_ICON, title: emptyState.title, description: emptyState.description, actionHref: emptyState.actionHref, actionLabel: emptyState.actionLabel, } : undefined } /> ); }