Files
supabase/apps/studio/components/ui/DataTable/DataTable.utils.ts
kemal.earth 7e717fb7bc fix(studio): selected status bg colour unified logs (#46152)
## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Small visual gremlin where the status dot was blending in with the
selected state background colour. See image below.

Appreciate there's probably another PR to go in with the row select
before this goes in.

| Before | After |
|--------|--------|
| <img width="97" height="84" alt="Screenshot 2026-05-20 at 09 34 10"
src="https://github.com/user-attachments/assets/7f21d415-e551-4686-a7e8-a6c7260ecab3"
/> | <img width="173" height="67" alt="Screenshot 2026-05-20 at 12 51
14"
src="https://github.com/user-attachments/assets/439b4c73-bd82-4bca-9d93-69c833da60bc"
/> |




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Style**
* Updated visual styling for successful rows in data tables to use the
selected-row variant, improving highlight consistency for
selected/successful rows.

* **Refactor**
* Standardized row class composition so each table row reliably includes
the base row grouping class alongside any custom row classes from table
metadata, reducing UI regressions and improving consistency.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46152?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-05-20 20:42:16 +07:00

89 lines
2.7 KiB
TypeScript

import { FilterFn } from '@tanstack/react-table'
import { isAfter, isBefore, isSameDay } from 'date-fns'
import { LEVELS } from './DataTable.constants'
export function formatCompactNumber(value: number) {
if (value >= 100 && value < 1000) {
return value.toString() // Keep the number as is if it's in the hundreds
} else if (value >= 1000 && value < 1000000) {
return (value / 1000).toFixed(1) + 'k' // Convert to 'k' for thousands
} else if (value >= 1000000) {
return (value / 1000000).toFixed(1) + 'M' // Convert to 'M' for millions
} else {
return value.toString() // Optionally handle numbers less than 100 if needed
}
}
export function isArrayOfNumbers(arr: any): arr is number[] {
if (!Array.isArray(arr)) return false
return arr.every((item) => typeof item === 'number')
}
export function isArrayOfDates(arr: any): arr is Date[] {
if (!Array.isArray(arr)) return false
return arr.every((item) => item instanceof Date)
}
export function isArrayOfStrings(arr: any): arr is string[] {
if (!Array.isArray(arr)) return false
return arr.every((item) => typeof item === 'string')
}
export function isArrayOfBooleans(arr: any): arr is boolean[] {
if (!Array.isArray(arr)) return false
return arr.every((item) => typeof item === 'boolean')
}
export const inDateRange: FilterFn<any> = (row, columnId, value) => {
const date = new Date(row.getValue(columnId))
const [start, end] = value as Date[]
if (isNaN(date.getTime())) return false
// if no end date, check if it's the same day
if (!end) return isSameDay(date, start)
return isAfter(date, start) && isBefore(date, end)
}
inDateRange.autoRemove = (val: any) => !Array.isArray(val) || !val.length || !isArrayOfDates(val)
export const arrSome: FilterFn<any> = (row, columnId, filterValue) => {
if (!Array.isArray(filterValue)) return false
return filterValue.some((val) => row.getValue<unknown[]>(columnId) === val)
}
arrSome.autoRemove = (val: any) => !Array.isArray(val) || !val?.length
export function getLevelColor(
value: (typeof LEVELS)[number]
): Record<'text' | 'bg' | 'border', string> {
switch (value) {
case 'success':
return {
text: 'text-muted',
bg: 'bg-muted group-data-[state=selected]/row:bg-foreground-lighter',
border: 'border-muted group-data-[state=selected]/row:border-foreground-lighter',
}
case 'warning':
return {
text: 'text-warning',
bg: 'bg-warning',
border: 'border-warning',
}
case 'error':
return {
text: 'text-destructive',
bg: 'bg-destructive',
border: 'border-destructive',
}
default:
return {
text: 'text-info',
bg: 'bg-info',
border: 'border-info',
}
}
}