"use client"; import { getSnRowNumber } from "@/shared/lib/row-number"; import { useMemo, type ReactNode } from "react"; import { getCoreRowModel, useReactTable, type ColumnDef, type PaginationState, } from "@tanstack/react-table"; import { StandardDataTable, type ScrollMode, type UiHeadProps, } from "@common/business_components"; type ExmnStandardDataTableProps> = { rows: T[]; headlist: UiHeadProps[]; title: ReactNode; total: number; page: number; pageSize: number; onPageChange: (page: number) => void; actions?: ReactNode; loading?: boolean; scrollMode?: ScrollMode; minTableWidth?: string; clickableHeadIds?: string[]; onCellClick?: (row: T, rowIndex: number, headId: string) => void; onRowClick?: (row: T, rowIndex: number) => void; rowId?: (row: T, rowIndex: number) => string; }; const ROW_NUMBER_IDS = new Set(["no", "rowNo", "rowNumber"]); const EXMN_TABLE_HEADER_HEIGHT_REM = 5.6; const EXMN_TABLE_HEADER_CLASS = "[&_thead_th]:!h-[5.6rem]"; const formatValue = (value: unknown) => { if (value === null || value === undefined || value === "") return "-"; return typeof value === "number" ? value.toLocaleString("ko-KR") : String(value); }; /** 조사관리 표를 CS 목록 규격과 페이지 연속 오름차순 순번으로 연결한다. */ export function ExmnStandardDataTable>({ rows, headlist, title, total, page, pageSize, onPageChange, actions, loading = false, scrollMode = "none", minTableWidth = "100%", clickableHeadIds = [], onCellClick, onRowClick, rowId, }: ExmnStandardDataTableProps) { const columns = useMemo[]>( () => headlist.map((head) => ({ id: head.id, accessorFn: (row) => row[head.id], header: ROW_NUMBER_IDS.has(head.id) ? "순번" : head.title, cell: ({ row, getValue }) => { const value = ROW_NUMBER_IDS.has(head.id) ? getSnRowNumber({ total, rowIndex: row.index, pageIndex: page - 1, pageSize, }) : formatValue(getValue()); const clickable = Boolean(onCellClick) && clickableHeadIds.includes(head.id); return clickable ? ( ) : ( value ); }, meta: { align: head.align === "left" || head.align === "right" ? head.align : "center", }, })), [clickableHeadIds, headlist, onCellClick, page, pageSize, total], ); const pagination: PaginationState = { pageIndex: Math.max(page - 1, 0), pageSize, }; const table = useReactTable({ data: rows, columns, state: { pagination }, rowCount: total, manualPagination: true, getCoreRowModel: getCoreRowModel(), getRowId: (row, index) => rowId?.(row, index) ?? String(index), onPaginationChange: (updater) => { const next = typeof updater === "function" ? updater(pagination) : updater; if (next.pageIndex !== pagination.pageIndex) { onPageChange(next.pageIndex + 1); } }, }); return ( onRowClick(row, rows.indexOf(row)) : undefined } /> ); } export { EXMN_TABLE_HEADER_CLASS, EXMN_TABLE_HEADER_HEIGHT_REM }; export type { ExmnStandardDataTableProps };