UNPKG

tubular-common

Version:

Tubular Common Models and Data Transformer

116 lines (95 loc) 4.13 kB
import { ColumnDataType, type ColumnModel, parseDateColumnValue } from './Models'; export const parsePayload = (row: Record<string, unknown>, columns: ColumnModel[]): Record<string, unknown> => columns.reduce((obj: Record<string, unknown>, column: ColumnModel, key: number) => { obj[column.name] = row[key] || row[column.name]; return obj; }, {}); export const getColumnAlign = (column: ColumnModel): 'inherit' | 'left' | 'center' | 'right' | 'justify' => { switch (column.dataType) { case ColumnDataType.Numeric: return 'right'; case ColumnDataType.Boolean: return 'center'; default: return 'inherit'; } }; const getRealCellValue = (column: ColumnModel, value: unknown, isHeader = false): string => { if (isHeader) return String(value); switch (column.dataType) { case ColumnDataType.Date: case ColumnDataType.DateTime: case ColumnDataType.DateTimeUtc: return value ? parseDateColumnValue(column, String(value)) : ''; case ColumnDataType.Boolean: return value === true ? 'Yes' : 'No'; default: return String(value ?? ''); } }; const getCellValue = (column: ColumnModel, row: unknown, isHeader) => column.isComputed ? column.getComputedStringValue(column, row, isHeader) : getRealCellValue(column, row[column.name], isHeader); const processRow = (row: unknown, columns: ColumnModel[], isHeader: boolean): string => { const finalVal = columns.reduce<string>((prev: string, currentColumn: ColumnModel) => { const result = `"${getCellValue(currentColumn, row, isHeader).replace(/"/g, '""')}"`; return `${prev}${result},`; }, ''); return `${finalVal.replace(/(^,)|(,$)/g, '')}\n`; }; const visibleColumns = (c: ColumnModel) => (c.visible && c.exportable) || (c.isComputed && !c.getComputedStringValue); export const getCsv = (gridResult: unknown[], columns: ColumnModel[]): string => { const exportableColumns = columns.filter(visibleColumns); const headers = processRow( exportableColumns .map((x) => ({ [x.name]: x.label })) // biome-ignore lint/performance/noAccumulatingSpread: <explanation> .reduce((prev, current) => ({ ...prev, ...current }), {}), exportableColumns, true, ); return gridResult.reduce( (prev, row) => String(prev) + processRow(row, exportableColumns, false), headers, ) as string; }; export const getHtml = (gridResult: unknown[], columns: ColumnModel[]): string => { const exportableColumns = columns.filter(visibleColumns); const headers = exportableColumns.reduce((prev, el) => `${prev}<th>${el.label || el.name}</th>`, ''); return `<table class="table table-bordered table-striped"><thead><tr>${headers}</tr></thead><tbody>${ gridResult.reduce( (prevRow, row) => `${prevRow}<tr>${exportableColumns.reduce( (prev, currentColumn) => `${prev}<td>${getCellValue(currentColumn, row, false)}</td>`, '', )}</tr>`, '', ) as string }</tbody></table>`; }; export const getPages = (currentPage: number, totalRows: number, rowsPerPage: number): number[] => { const pages: number[] = []; // Default page limits const totalPages = Math.ceil(totalRows / rowsPerPage); let startPage = 1; let endPage = totalPages; const maxSize = 6; const isMaxSized = maxSize < totalPages; // recompute if maxSize if (isMaxSized) { // Current page is displayed in the middle of the visible ones startPage = Math.max(currentPage - Math.floor(maxSize / 2), 1); endPage = startPage + maxSize - 1; // Adjust if limit is exceeded if (endPage > totalPages) { endPage = totalPages; startPage = endPage - maxSize + 1; } } // Add page number links for (let num = startPage; num <= endPage; num++) { pages.push(num - 1); } return pages; };