DataTable.utils.ts88 lines · main
| 1 | import { FilterFn } from '@tanstack/react-table' |
| 2 | import { isAfter, isBefore, isSameDay } from 'date-fns' |
| 3 | |
| 4 | import { LEVELS } from './DataTable.constants' |
| 5 | |
| 6 | export function formatCompactNumber(value: number) { |
| 7 | if (value >= 100 && value < 1000) { |
| 8 | return value.toString() // Keep the number as is if it's in the hundreds |
| 9 | } else if (value >= 1000 && value < 1000000) { |
| 10 | return (value / 1000).toFixed(1) + 'k' // Convert to 'k' for thousands |
| 11 | } else if (value >= 1000000) { |
| 12 | return (value / 1000000).toFixed(1) + 'M' // Convert to 'M' for millions |
| 13 | } else { |
| 14 | return value.toString() // Optionally handle numbers less than 100 if needed |
| 15 | } |
| 16 | } |
| 17 | |
| 18 | export function isArrayOfNumbers(arr: any): arr is number[] { |
| 19 | if (!Array.isArray(arr)) return false |
| 20 | return arr.every((item) => typeof item === 'number') |
| 21 | } |
| 22 | |
| 23 | export function isArrayOfDates(arr: any): arr is Date[] { |
| 24 | if (!Array.isArray(arr)) return false |
| 25 | return arr.every((item) => item instanceof Date) |
| 26 | } |
| 27 | |
| 28 | export function isArrayOfStrings(arr: any): arr is string[] { |
| 29 | if (!Array.isArray(arr)) return false |
| 30 | return arr.every((item) => typeof item === 'string') |
| 31 | } |
| 32 | |
| 33 | export function isArrayOfBooleans(arr: any): arr is boolean[] { |
| 34 | if (!Array.isArray(arr)) return false |
| 35 | return arr.every((item) => typeof item === 'boolean') |
| 36 | } |
| 37 | |
| 38 | export const inDateRange: FilterFn<any> = (row, columnId, value) => { |
| 39 | const date = new Date(row.getValue(columnId)) |
| 40 | const [start, end] = value as Date[] |
| 41 | |
| 42 | if (isNaN(date.getTime())) return false |
| 43 | |
| 44 | // if no end date, check if it's the same day |
| 45 | if (!end) return isSameDay(date, start) |
| 46 | |
| 47 | return isAfter(date, start) && isBefore(date, end) |
| 48 | } |
| 49 | |
| 50 | inDateRange.autoRemove = (val: any) => !Array.isArray(val) || !val.length || !isArrayOfDates(val) |
| 51 | |
| 52 | export const arrSome: FilterFn<any> = (row, columnId, filterValue) => { |
| 53 | if (!Array.isArray(filterValue)) return false |
| 54 | return filterValue.some((val) => row.getValue<unknown[]>(columnId) === val) |
| 55 | } |
| 56 | |
| 57 | arrSome.autoRemove = (val: any) => !Array.isArray(val) || !val?.length |
| 58 | |
| 59 | export function getLevelColor( |
| 60 | value: (typeof LEVELS)[number] |
| 61 | ): Record<'text' | 'bg' | 'border', string> { |
| 62 | switch (value) { |
| 63 | case 'success': |
| 64 | return { |
| 65 | text: 'text-muted', |
| 66 | bg: 'bg-muted group-data-[state=selected]/row:bg-foreground-lighter', |
| 67 | border: 'border-muted group-data-[state=selected]/row:border-foreground-lighter', |
| 68 | } |
| 69 | case 'warning': |
| 70 | return { |
| 71 | text: 'text-warning', |
| 72 | bg: 'bg-warning', |
| 73 | border: 'border-warning', |
| 74 | } |
| 75 | case 'error': |
| 76 | return { |
| 77 | text: 'text-destructive', |
| 78 | bg: 'bg-destructive', |
| 79 | border: 'border-destructive', |
| 80 | } |
| 81 | default: |
| 82 | return { |
| 83 | text: 'text-info', |
| 84 | bg: 'bg-info', |
| 85 | border: 'border-info', |
| 86 | } |
| 87 | } |
| 88 | } |