✨ feat: Add model performance metrics to dashboard
Add a shared `performance-metrics` feature module for perf metric APIs, DTOs, and formatting, then surface global 24h model performance on the dashboard with cards and a top-model table. Reuse the shared metrics module from pricing model details, remove duplicated perf API/formatting code from pricing, and add localized labels for the new dashboard performance UI.
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { useMemo, useState } from 'react'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { ChevronLeft, ChevronRight } from 'lucide-react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { getPerfMetricsSummary } from '../api'
|
||||
import { getPerfMetricsSummary } from '@/features/performance-metrics/api'
|
||||
import { DEFAULT_PRICING_PAGE_SIZE, DEFAULT_TOKEN_UNIT } from '../constants'
|
||||
import type { PricingModel, TokenUnit } from '../types'
|
||||
import { ModelCard } from './model-card'
|
||||
@@ -24,22 +24,19 @@ export function ModelCardGrid(props: ModelCardGridProps) {
|
||||
const pageSize = DEFAULT_PRICING_PAGE_SIZE
|
||||
const tokenUnit = props.tokenUnit ?? DEFAULT_TOKEN_UNIT
|
||||
const totalPages = Math.max(1, Math.ceil(props.models.length / pageSize))
|
||||
const currentPage = Math.min(page, totalPages)
|
||||
|
||||
const perfQuery = useQuery({
|
||||
queryKey: ['perf-metrics-summary'],
|
||||
queryKey: ['perf-metrics-summary', 24],
|
||||
queryFn: () => getPerfMetricsSummary(24),
|
||||
staleTime: 60 * 1000,
|
||||
retry: false,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
setPage(1)
|
||||
}, [props.models])
|
||||
|
||||
const pagedModels = useMemo(() => {
|
||||
const start = (page - 1) * pageSize
|
||||
const start = (currentPage - 1) * pageSize
|
||||
return props.models.slice(start, start + pageSize)
|
||||
}, [page, pageSize, props.models])
|
||||
}, [currentPage, pageSize, props.models])
|
||||
|
||||
const perfMap = useMemo(() => {
|
||||
const map = new Map<string, ModelPerfBadgeData>()
|
||||
@@ -76,7 +73,7 @@ export function ModelCardGrid(props: ModelCardGridProps) {
|
||||
<div className='text-muted-foreground flex flex-col items-center justify-between gap-3 border-t px-4 py-3 text-sm sm:flex-row'>
|
||||
<p className='text-muted-foreground'>
|
||||
{t('Page {{current}} of {{total}}', {
|
||||
current: page,
|
||||
current: currentPage,
|
||||
total: totalPages,
|
||||
})}
|
||||
</p>
|
||||
@@ -86,7 +83,7 @@ export function ModelCardGrid(props: ModelCardGridProps) {
|
||||
variant='outline'
|
||||
size='sm'
|
||||
onClick={() => setPage((current) => Math.max(1, current - 1))}
|
||||
disabled={page <= 1}
|
||||
disabled={currentPage <= 1}
|
||||
className='gap-1.5'
|
||||
>
|
||||
<ChevronLeft className='size-4' />
|
||||
@@ -99,7 +96,7 @@ export function ModelCardGrid(props: ModelCardGridProps) {
|
||||
onClick={() =>
|
||||
setPage((current) => Math.min(totalPages, current + 1))
|
||||
}
|
||||
disabled={page >= totalPages}
|
||||
disabled={currentPage >= totalPages}
|
||||
className='gap-1.5'
|
||||
>
|
||||
{t('Next')}
|
||||
|
||||
Reference in New Issue
Block a user