|
|
|
import {
|
|
|
|
AttachmentAggregations,
|
|
|
|
BooleanAggregations,
|
|
|
|
type ColumnType,
|
|
|
|
CommonAggregations,
|
|
|
|
DateAggregations,
|
|
|
|
UITypes,
|
|
|
|
dateFormats,
|
|
|
|
timeFormats,
|
|
|
|
} from 'nocodb-sdk'
|
|
|
|
import dayjs from 'dayjs'
|
|
|
|
|
|
|
|
const getDateValue = (modelValue: string | null | number, col: ColumnType, isSystemCol?: boolean) => {
|
|
|
|
const dateFormat = !isSystemCol ? parseProp(col.meta)?.date_format ?? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'
|
|
|
|
if (!modelValue || !dayjs(modelValue).isValid()) {
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
return dayjs(/^\d+$/.test(String(modelValue)) ? +modelValue : modelValue).format(dateFormat)
|
|
|
|
}
|
|
|
|
|
|
|
|
const roundTo = (num: unknown, precision = 1) => {
|
|
|
|
if (!num || Number.isNaN(num)) return num
|
|
|
|
const factor = 10 ** precision
|
|
|
|
return Math.round(+num * factor) / factor
|
|
|
|
}
|
|
|
|
|
|
|
|
const getDateTimeValue = (modelValue: string | null, col: ColumnType, isXcdbBase?: boolean) => {
|
|
|
|
if (!modelValue || !dayjs(modelValue).isValid()) {
|
|
|
|
return ''
|
|
|
|
}
|
|
|
|
|
|
|
|
const dateFormat = parseProp(col?.meta)?.date_format ?? dateFormats[0]
|
|
|
|
const timeFormat = parseProp(col?.meta)?.time_format ?? timeFormats[0]
|
|
|
|
const dateTimeFormat = `${dateFormat} ${timeFormat}`
|
|
|
|
|
|
|
|
if (!isXcdbBase) {
|
|
|
|
return dayjs(/^\d+$/.test(modelValue) ? +modelValue : modelValue, dateTimeFormat).format(dateTimeFormat)
|
|
|
|
}
|
|
|
|
|
|
|
|
return dayjs(modelValue).utc().local().format(dateTimeFormat)
|
|
|
|
}
|
|
|
|
|
|
|
|
const getCurrencyValue = (modelValue: string | number | null | undefined, col: ColumnType): string => {
|
|
|
|
const currencyMeta = {
|
|
|
|
currency_locale: 'en-US',
|
|
|
|
currency_code: 'USD',
|
|
|
|
...parseProp(col.meta),
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
if (modelValue === null || modelValue === undefined || Number.isNaN(modelValue)) {
|
|
|
|
return modelValue === null || modelValue === undefined ? '' : (modelValue as string)
|
|
|
|
}
|
|
|
|
return new Intl.NumberFormat(currencyMeta.currency_locale || 'en-US', {
|
|
|
|
style: 'currency',
|
|
|
|
currency: currencyMeta.currency_code || 'USD',
|
|
|
|
}).format(+modelValue)
|
|
|
|
} catch (e) {
|
|
|
|
return modelValue as string
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function formatBytes(bytes, decimals = 2, base = 1000) {
|
|
|
|
if (bytes === 0) return '0 Bytes'
|
|
|
|
|
|
|
|
const k = base
|
|
|
|
const dm = Math.max(0, decimals)
|
|
|
|
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
|
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
|
|
|
|
|
|
|
return `${(bytes / k ** i).toFixed(dm)} ${sizes[i]}`
|
|
|
|
}
|
|
|
|
|
|
|
|
const formatAggregation = (aggregation: any, value: any, column: ColumnType) => {
|
|
|
|
if ([DateAggregations.EarliestDate, DateAggregations.LatestDate].includes(aggregation)) {
|
|
|
|
if (column.uidt === UITypes.DateTime) {
|
|
|
|
return getDateTimeValue(value, column)
|
|
|
|
} else if (column.uidt === UITypes.Date) {
|
|
|
|
return getDateValue(value, column)
|
|
|
|
}
|
|
|
|
return getDateTimeValue(value, column)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
[
|
|
|
|
CommonAggregations.PercentEmpty,
|
|
|
|
CommonAggregations.PercentFilled,
|
|
|
|
CommonAggregations.PercentUnique,
|
|
|
|
BooleanAggregations.PercentChecked,
|
|
|
|
BooleanAggregations.PercentUnchecked,
|
|
|
|
].includes(aggregation)
|
|
|
|
) {
|
|
|
|
return `${roundTo(value, 1) ?? 0}%`
|
|
|
|
}
|
|
|
|
|
|
|
|
if ([DateAggregations.MonthRange, DateAggregations.DateRange].includes(aggregation)) {
|
|
|
|
return aggregation === DateAggregations.DateRange ? `${value ?? 0} days` : `${value ?? 0} months`
|
|
|
|
}
|
|
|
|
|
|
|
|
if (
|
|
|
|
[
|
|
|
|
CommonAggregations.Count,
|
|
|
|
CommonAggregations.CountEmpty,
|
|
|
|
CommonAggregations.CountFilled,
|
|
|
|
CommonAggregations.CountUnique,
|
|
|
|
].includes(aggregation)
|
|
|
|
) {
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
|
|
|
|
if ([AttachmentAggregations.AttachmentSize].includes(aggregation)) {
|
|
|
|
return formatBytes(value ?? 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (column.uidt === UITypes.Currency) {
|
|
|
|
return getCurrencyValue(value, column)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (column.uidt === UITypes.Percent) {
|
|
|
|
return `${roundTo(value, 1)}%`
|
|
|
|
}
|
|
|
|
|
|
|
|
if (column.uidt === UITypes.Duration) {
|
|
|
|
return convertMS2Duration(value, parseProp(column.meta)?.duration || 0)
|
|
|
|
}
|
|
|
|
if (typeof value === 'number') {
|
|
|
|
return roundTo(value, 1) ?? '∞'
|
|
|
|
}
|
|
|
|
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
|
|
|
|
export { formatAggregation }
|