import type { TFunction } from 'i18next' import type { FC } from 'react' import type { SQLiteValue } from '../../hooks/use-sqlite-database' import * as React from 'react' import { useMemo } from 'react' import { useTranslation } from 'react-i18next' import { cn } from '@/utils/classnames' type DataTableProps = { columns: string[] values: SQLiteValue[][] } const MAX_CELL_LENGTH = 120 const formatValue = (value: SQLiteValue, t: TFunction<'workflow'>): string => { if (value === null) return t('skillSidebar.sqlitePreview.nullValue') if (value instanceof Uint8Array) return t('skillSidebar.sqlitePreview.blobValue', { size: value.byteLength }) if (typeof value === 'bigint') return value.toString() return String(value) } const truncateValue = (value: string): string => { if (value.length <= MAX_CELL_LENGTH) return value return `${value.slice(0, MAX_CELL_LENGTH)}...` } const DataTable: FC = ({ columns, values }) => { const { t } = useTranslation('workflow') const keyColumnIndex = useMemo(() => { const candidates = new Set(['id', 'rowid', 'uuid']) return columns.findIndex(column => candidates.has(column.toLowerCase())) }, [columns]) const rows = useMemo(() => { return values.map((row) => { const rowKey = keyColumnIndex >= 0 ? String(row[keyColumnIndex] ?? '') : row.map((value) => { if (value instanceof Uint8Array) return `blob:${value.byteLength}` return String(value ?? '') }).join('|') const cells = row.map((value) => { const rawValue = formatValue(value, t) return { rawValue, displayValue: truncateValue(rawValue), isNull: value === null, } }) return { key: rowKey, cells, } }) }, [keyColumnIndex, t, values]) return ( {columns.map(column => ( ))} {rows.map(row => ( {row.cells.map((cell, cellIndex) => ( ))} ))}
{column}
{cell.displayValue}
) } export default React.memo(DataTable)