♻️ refactor(web): consolidate design-system primitives and responsive data views

This commit is contained in:
t0ng7u
2026-07-11 05:13:16 +08:00
parent 262ab93123
commit 0918bdb49a
451 changed files with 7295 additions and 7693 deletions
@@ -22,7 +22,7 @@ import { Music } from 'lucide-react'
import { useState, useMemo } from 'react'
import { useTranslation } from 'react-i18next'
import { StatusBadge } from '@/components/status-badge'
import { CopyableStatusBadge, StatusBadge } from '@/components/status-badge'
import { Avatar, AvatarFallback } from '@/components/ui/avatar'
import { getUserAvatarFallback, getUserAvatarStyle } from '@/lib/avatar'
import { formatTimestampToDate } from '@/lib/format'
@@ -102,11 +102,11 @@ export function useTaskLogsColumns(isAdmin: boolean): ColumnDef<TaskLog>[] {
return (
<div className='flex min-w-0 flex-col gap-0.5'>
<span className='truncate text-xs tabular-nums'>
<span className='text-xs tabular-nums'>
{formatTimestampToDate(submitTime, 'seconds')}
</span>
{log.finish_time ? (
<span className='text-muted-foreground/60 truncate text-xs tabular-nums'>
<span className='text-muted-foreground/60 text-xs tabular-nums'>
{formatTimestampToDate(log.finish_time, 'seconds')}
</span>
) : (
@@ -116,6 +116,11 @@ export function useTaskLogsColumns(isAdmin: boolean): ColumnDef<TaskLog>[] {
)
},
size: 180,
meta: {
cardRole: 'primary',
cardOrder: 10,
contentMode: 'full',
},
},
]
@@ -153,12 +158,17 @@ export function useTaskLogsColumns(isAdmin: boolean): ColumnDef<TaskLog>[] {
{sensitiveVisible ? getUserAvatarFallback(displayName) : '•'}
</AvatarFallback>
</Avatar>
<span className='text-muted-foreground truncate text-sm hover:underline'>
<span className='text-muted-foreground text-sm [overflow-wrap:anywhere] break-words hover:underline'>
{sensitiveVisible ? displayName : '••••'}
</span>
</button>
)
},
meta: {
cardRole: 'primary',
cardOrder: 30,
contentMode: 'wrap',
},
})
}
@@ -174,20 +184,25 @@ export function useTaskLogsColumns(isAdmin: boolean): ColumnDef<TaskLog>[] {
}
return (
<div className='flex max-w-[170px] flex-col gap-0.5'>
<StatusBadge
label={taskId}
copyText={taskId}
<CopyableStatusBadge
value={taskId}
variant='neutral'
size='sm'
className='border-border/60 bg-muted/30 text-foreground max-w-full truncate rounded-md border px-1.5 py-0.5 font-mono'
/>
<span className='text-muted-foreground/60 truncate text-xs'>
className='h-auto max-w-full overflow-visible font-mono [overflow-wrap:anywhere] whitespace-normal [&_[data-slot=status-badge-label]]:overflow-visible [&_[data-slot=status-badge-label]]:text-clip [&_[data-slot=status-badge-label]]:whitespace-normal'
>
{taskId}
</CopyableStatusBadge>
<span className='text-muted-foreground/60 text-xs [overflow-wrap:anywhere] break-words'>
{t(log.platform)} · {t(taskActionMapper.getLabel(log.action))}
</span>
</div>
)
},
meta: { mobileTitle: true },
meta: {
cardRole: 'title',
cardSpan: 2,
contentMode: 'full',
},
},
createDurationColumn<TaskLog>({
submitTimeKey: 'submit_time',
@@ -202,14 +217,15 @@ export function useTaskLogsColumns(isAdmin: boolean): ColumnDef<TaskLog>[] {
cell: ({ row }) => {
const status = row.getValue('status') as string
return (
<StatusBadge
label={t(taskStatusMapper.getLabel(status, status || 'Submitting'))}
variant={taskStatusMapper.getVariant(status)}
size='sm'
copyable={false}
/>
<StatusBadge variant={taskStatusMapper.getVariant(status)} size='sm'>
{t(taskStatusMapper.getLabel(status, status || 'Submitting'))}
</StatusBadge>
)
},
meta: {
cardRole: 'badge',
contentMode: 'full',
},
},
createProgressColumn<TaskLog>({ headerLabel: t('Progress') }),
{
@@ -272,7 +288,7 @@ export function useTaskLogsColumns(isAdmin: boolean): ColumnDef<TaskLog>[] {
onClick={() => setDialogOpen(true)}
title={t('Click to view full error message')}
>
<span className='truncate leading-snug text-red-600 group-hover:underline dark:text-red-400'>
<span className='text-destructive truncate leading-snug group-hover:underline'>
{failReason}
</span>
</button>
@@ -286,6 +302,12 @@ export function useTaskLogsColumns(isAdmin: boolean): ColumnDef<TaskLog>[] {
},
size: 200,
maxSize: 220,
meta: {
cardRole: 'secondary',
cardOrder: 20,
cardSpan: 2,
contentMode: 'summary',
},
}
)