refactor(ui): Improve usage log filter responsiveness and mobile UX

Refactor the usage log filter toolbar into a shared reusable component for common, drawing, and task logs. Optimize desktop filters with a responsive grid, move secondary filters into a mobile drawer, standardize filter typography, remove redundant filter icons, and add the missing i18n translations for the new drawer description.
This commit is contained in:
t0ng7u
2026-05-25 05:35:44 +08:00
parent b302be30e3
commit 583da45296
79 changed files with 1879 additions and 1262 deletions
@@ -35,7 +35,7 @@ import {
formatQuota as formatQuotaValue,
} from '@/lib/format'
import { getLobeIcon } from '@/lib/lobe-icon'
import { cn, truncateText } from '@/lib/utils'
import { truncateText } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import {
@@ -47,11 +47,8 @@ import {
import { ConfirmDialog } from '@/components/confirm-dialog'
import { DataTableColumnHeader } from '@/components/data-table/column-header'
import { GroupBadge } from '@/components/group-badge'
import {
StatusBadge,
dotColorMap,
textColorMap,
} from '@/components/status-badge'
import { StatusBadge, StatusBadgeList } from '@/components/status-badge'
import { TableId } from '@/components/table-id'
import { TruncatedText } from '@/components/truncated-text'
import { getCodexUsage } from '../api'
import { CHANNEL_STATUS_CONFIG, MODEL_FETCHABLE_TYPES } from '../constants'
@@ -107,25 +104,12 @@ function renderLimitedItems(
items: React.ReactNode[],
maxDisplay: number = 2
): React.ReactNode {
if (items.length === 0)
return <span className='text-muted-foreground text-xs'>-</span>
const displayed = items.slice(0, maxDisplay)
const remaining = items.length - maxDisplay
return (
<div className='flex max-w-full items-center gap-1 overflow-hidden'>
{displayed}
{remaining > 0 && (
<StatusBadge
label={`+${remaining}`}
variant='neutral'
size='sm'
copyable={false}
className='flex-shrink-0'
/>
)}
</div>
<StatusBadgeList
items={items}
max={maxDisplay}
renderItem={(item) => item}
/>
)
}
@@ -361,47 +345,50 @@ function BalanceCell({ channel }: { channel: Channel }) {
return (
<TooltipProvider>
<div className='flex items-center gap-1.5 text-xs font-medium'>
<span
className={cn(
'size-1.5 shrink-0 rounded-full',
dotColorMap[isUpdating ? 'neutral' : variant]
)}
aria-hidden='true'
/>
<div className='flex items-center gap-1'>
<Tooltip>
<TooltipTrigger
render={<span className='text-muted-foreground cursor-help' />}
>
{usedDisplay}
</TooltipTrigger>
render={
<StatusBadge
label={usedDisplay}
variant='neutral'
size='sm'
copyable={false}
className='cursor-help'
/>
}
/>
<TooltipContent>
<p>
{t('Used:')} {usedDisplay}
</p>
</TooltipContent>
</Tooltip>
<span className='text-muted-foreground/30'>·</span>
<Tooltip>
<TooltipTrigger
render={
<span
className={cn(
'cursor-pointer transition-opacity hover:opacity-70',
<StatusBadge
label={
isUpdating
? t('Updating...')
: channel.type === 57
? t('Account Info')
: remainingDisplay
}
variant={
channel.type === 57
? 'text-primary'
: textColorMap[isUpdating ? 'neutral' : variant]
)}
? 'info'
: isUpdating
? 'neutral'
: variant
}
size='sm'
copyable={false}
className='cursor-pointer'
onClick={handleClickUpdate}
/>
}
>
{isUpdating
? 'Updating...'
: channel.type === 57
? t('Account Info')
: remainingDisplay}
</TooltipTrigger>
/>
<TooltipContent>
<p>
{channel.type === 57
@@ -491,15 +478,7 @@ export function useChannelsColumns(): ColumnDef<Channel>[] {
),
cell: ({ row }) => {
const id = row.getValue('id') as number
return (
<StatusBadge
label={String(id)}
variant='neutral'
copyText={String(id)}
size='sm'
className='font-mono'
/>
)
return <TableId value={id} />
},
size: 80,
},
@@ -695,8 +674,13 @@ export function useChannelsColumns(): ColumnDef<Channel>[] {
/>
}
>
<span className='text-muted-foreground/30'>·</span>
<span className={cn(textColorMap.purple)}>IO.NET</span>
<StatusBadge
label='IO.NET'
variant='purple'
size='sm'
copyable={false}
className='cursor-pointer'
/>
</TooltipTrigger>
<TooltipContent side='top'>
<div className='max-w-xs space-y-1'>
@@ -747,7 +731,6 @@ export function useChannelsColumns(): ColumnDef<Channel>[] {
<StatusBadge
label={`Active (${childrenCount})`}
variant='success'
showDot
size='sm'
copyable={false}
/>
@@ -806,7 +789,6 @@ export function useChannelsColumns(): ColumnDef<Channel>[] {
<StatusBadge
label={label}
variant={config.variant}
showDot={config.showDot}
size='sm'
copyable={false}
/>
@@ -835,7 +817,6 @@ export function useChannelsColumns(): ColumnDef<Channel>[] {
<StatusBadge
label={label}
variant={config.variant}
showDot={config.showDot}
size='sm'
copyable={false}
/>