fix(web): prevent list cell text and badge overflow (#5510)

* fix(ui): prevent table cell text overflow

- add default truncation with hover details for text cells in shared and static data tables to prevent content from spilling into adjacent columns.
- adjust API key group, model, and IP restriction columns to fix badge overlap and left alignment drift.
- reuse a shared truncated cell component and add width constraints for composite badge cells.

* fix(table): prevent badge content from overflowing columns

- make table text and badge cells shrink within constrained columns so long values truncate instead of bleeding into adjacent cells.
- add a shared BadgeCell wrapper to keep badge alignment consistent across API keys and other list pages.
- update affected list views to use constrained wrappers for group, provider, pricing, OAuth, and API info values.
This commit is contained in:
QuentinHsu
2026-06-15 14:52:57 +08:00
committed by GitHub
parent 1ac0f5807a
commit 3c1bb0a74f
20 changed files with 355 additions and 140 deletions
+10 -3
View File
@@ -32,6 +32,7 @@ import {
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip'
import { BadgeCell } from '@/components/data-table'
import { StatusBadge } from '@/components/status-badge'
import { type ApiKey } from '../types'
import { useApiKeys } from './api-keys-provider'
@@ -157,7 +158,12 @@ export function ModelLimitsCell({ apiKey }: { apiKey: ApiKey }) {
if (!apiKey.model_limits_enabled || !apiKey.model_limits) {
return (
<StatusBadge label={t('Unlimited')} variant='neutral' copyable={false} />
<StatusBadge
label={t('Unlimited')}
variant='neutral'
copyable={false}
className='-ml-1.5'
/>
)
}
@@ -165,7 +171,7 @@ export function ModelLimitsCell({ apiKey }: { apiKey: ApiKey }) {
return (
<Tooltip>
<TooltipTrigger render={<span />}>
<TooltipTrigger render={<BadgeCell />}>
<StatusBadge
label={t('{{count}} model(s)', { count: models.length })}
variant='neutral'
@@ -195,6 +201,7 @@ export function IpRestrictionsCell({ apiKey }: { apiKey: ApiKey }) {
label={t('No restriction')}
variant='neutral'
copyable={false}
className='-ml-1.5'
/>
)
}
@@ -206,7 +213,7 @@ export function IpRestrictionsCell({ apiKey }: { apiKey: ApiKey }) {
return (
<Tooltip>
<TooltipTrigger render={<span />}>
<TooltipTrigger render={<BadgeCell />}>
<StatusBadge
label={t('{{count}} IP(s)', { count: ips.length })}
variant='neutral'
@@ -29,6 +29,7 @@ import {
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip'
import { BadgeCell, TruncatedCell } from '@/components/data-table'
import { GroupBadge } from '@/components/group-badge'
import { StatusBadge } from '@/components/status-badge'
import { API_KEY_STATUSES } from '../constants'
@@ -97,9 +98,7 @@ export function useApiKeysColumns(): ColumnDef<ApiKey>[] {
accessorKey: 'name',
header: t('Name'),
cell: ({ row }) => (
<div className='max-w-[200px] truncate font-medium'>
{row.getValue('name')}
</div>
<span className='font-medium'>{row.getValue('name')}</span>
),
size: 180,
meta: { mobileTitle: true },
@@ -200,9 +199,7 @@ export function useApiKeysColumns(): ColumnDef<ApiKey>[] {
return (
<Tooltip>
<TooltipTrigger
render={
<span className='inline-flex items-center gap-1.5 text-xs' />
}
render={<BadgeCell className='gap-1.5 text-xs' />}
>
<GroupBadge group='auto' />
{apiKey.cross_group_retry && (
@@ -223,7 +220,15 @@ export function useApiKeysColumns(): ColumnDef<ApiKey>[] {
</Tooltip>
)
}
return <GroupBadge group={group} ratio={ratio} />
return (
<TruncatedCell
className='-ml-1.5'
tooltipContent={group || '-'}
tooltipClassName='break-all'
>
<GroupBadge group={group} ratio={ratio} />
</TruncatedCell>
)
},
size: 160,
meta: { mobileHidden: true },