import type { Transaction } from "@olenbetong/appframe-updater"; import { useMemo } from "react"; import { calculateColumnWidths, createTransactionColumns, DEFAULT_TABLE_SEPARATOR, type EditorTransactionRow, formatRowLines, mapTransactionsToRows, } from "./tableFormatting.js"; import { CURSOR_PREFIX_WIDTH, HEADER_PREFIX } from "./useVirtualScrolling.js"; export interface TransactionsTableLayoutOptions { displayTransactions: Transaction[]; showErrorColumn: boolean; tableWidth: number; } export interface TransactionsTableLayoutResult { columns: ReturnType; rows: EditorTransactionRow[]; widths: number[]; tableContentWidth: number; lineWidth: number; header: string; divider: string; } export function useTransactionsTableLayout({ displayTransactions, showErrorColumn, tableWidth, }: TransactionsTableLayoutOptions): TransactionsTableLayoutResult { let columns = useMemo(() => createTransactionColumns(showErrorColumn), [showErrorColumn]); let rows = useMemo( () => mapTransactionsToRows(displayTransactions, showErrorColumn), [displayTransactions, showErrorColumn], ); let widths = useMemo( () => calculateColumnWidths({ columns, rows, totalWidth: tableWidth, separator: DEFAULT_TABLE_SEPARATOR, }), [columns, rows, tableWidth], ); let tableSeparatorWidth = useMemo(() => DEFAULT_TABLE_SEPARATOR.length * Math.max(columns.length - 1, 0), [columns]); let tableContentWidth = useMemo( () => widths.reduce((sum, width) => sum + width, 0) + tableSeparatorWidth, [tableSeparatorWidth, widths], ); let lineWidth = useMemo(() => CURSOR_PREFIX_WIDTH + tableContentWidth, [tableContentWidth]); let headerRow = useMemo( () => Object.fromEntries(columns.map((column) => [column.key, column.header])) as unknown as EditorTransactionRow, [columns], ); let headerLines = useMemo( () => formatRowLines({ row: headerRow, columns, widths, separator: DEFAULT_TABLE_SEPARATOR }), [columns, headerRow, widths], ); let header = useMemo( () => `${HEADER_PREFIX}${(headerLines[0] ?? "").padEnd(tableContentWidth, " ")}`, [headerLines, tableContentWidth], ); let divider = useMemo(() => { let separator = "─".repeat(DEFAULT_TABLE_SEPARATOR.length); let content = columns.map((_, index) => "─".repeat(widths[index])).join(separator); return `${HEADER_PREFIX}${content.padEnd(tableContentWidth, " ")}`; }, [columns, tableContentWidth, widths]); return { columns, rows, widths, tableContentWidth, lineWidth, header, divider }; }