diff --git a/web/features/new-rag/__tests__/quality-evaluation-panel.spec.tsx b/web/features/new-rag/__tests__/quality-evaluation-panel.spec.tsx index 34f6bfbecf4..37776fc151b 100644 --- a/web/features/new-rag/__tests__/quality-evaluation-panel.spec.tsx +++ b/web/features/new-rag/__tests__/quality-evaluation-panel.spec.tsx @@ -179,6 +179,40 @@ describe('QualityEvaluationPanel', () => { ).toBeEnabled() }) + it('shows evaluation creation time as a relative list label', async () => { + const now = Date.parse(completedRun.created_at) + 2 * 60 * 60 * 1000 + const dateNowSpy = vi.spyOn(Date, 'now').mockReturnValue(now) + serviceMock.listReplays.mockResolvedValue({ + data: [ + { ...completedRun, created_at: new Date(now).toISOString(), id: 'run-now' }, + completedRun, + ], + next_cursor: null, + }) + + renderPanel() + + expect(await screen.findByText('dataset.newKnowledge.retrievalTest.justNow')).toBeVisible() + expect(await screen.findByText('2 hours ago')).toBeVisible() + dateNowSpy.mockRestore() + }) + + it('separates the report date and time with a middle dot', async () => { + const user = userEvent.setup() + const createdAt = new Date(completedRun.created_at) + const expected = `${new Intl.DateTimeFormat(undefined, { dateStyle: 'medium' }).format(createdAt)} · ${new Intl.DateTimeFormat(undefined, { timeStyle: 'short' }).format(createdAt)}` + serviceMock.listReplays.mockResolvedValue({ data: [completedRun], next_cursor: null }) + + renderPanel() + await user.click( + await screen.findByRole('button', { + name: 'dataset.newKnowledge.qualityPage.evaluation.viewReport', + }), + ) + + expect(await screen.findByText(expected)).toBeVisible() + }) + it('opens evaluation settings in an accessible centered modal', async () => { const user = userEvent.setup() renderPanel() diff --git a/web/features/new-rag/quality/quality-evaluation-panel.tsx b/web/features/new-rag/quality/quality-evaluation-panel.tsx index eca1a2fae3d..2e0d630d1fc 100644 --- a/web/features/new-rag/quality/quality-evaluation-panel.tsx +++ b/web/features/new-rag/quality/quality-evaluation-panel.tsx @@ -23,6 +23,7 @@ import { useTranslation } from 'react-i18next' import Loading from '@/app/components/base/loading' import { consoleQuery } from '@/service/client' import { RetrievalModeSegmentedControl } from '../components/retrieval-mode-segmented-control' +import { formatQualityEvaluationCreatedAt, formatQualityReportCreatedAt } from './quality-model' type ReplayState = KnowledgeFsQualityReplayResponse['state'] @@ -160,10 +161,7 @@ function EvaluationReport({

- {new Intl.DateTimeFormat(undefined, { - dateStyle: 'medium', - timeStyle: 'short', - }).format(new Date(run.created_at))} + {formatQualityReportCreatedAt(run.created_at)}

@@ -527,10 +525,10 @@ export function QualityEvaluationPanel({ className="grid h-12 min-w-185 grid-cols-[150px_110px_140px_160px_110px_1fr] items-center gap-3 border-t border-divider-subtle" > - {new Intl.DateTimeFormat(undefined, { - dateStyle: 'short', - timeStyle: 'short', - }).format(new Date(run.created_at))} + {formatQualityEvaluationCreatedAt( + run.created_at, + t(($) => $['newKnowledge.retrievalTest.justNow']), + )} diff --git a/web/features/new-rag/quality/quality-model.ts b/web/features/new-rag/quality/quality-model.ts index 3379ce37230..c139757f623 100644 --- a/web/features/new-rag/quality/quality-model.ts +++ b/web/features/new-rag/quality/quality-model.ts @@ -36,3 +36,21 @@ export function formatQualityUpdatedAt(value: string) { if (elapsedDays < 7) return relativeTime.format(-elapsedDays, 'day') return new Intl.DateTimeFormat(undefined, { day: 'numeric', month: 'short' }).format(time) } + +export function formatQualityEvaluationCreatedAt(value: string, justNow: string) { + const elapsedMinutes = Math.max(0, (Date.now() - new Date(value).getTime()) / 60_000) + if (elapsedMinutes < 1) return justNow + if (elapsedMinutes < 60) + return new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' }).format( + -Math.floor(elapsedMinutes), + 'minute', + ) + return formatQualityUpdatedAt(value) +} + +export function formatQualityReportCreatedAt(value: string) { + const time = new Date(value) + const date = new Intl.DateTimeFormat(undefined, { dateStyle: 'medium' }).format(time) + const formattedTime = new Intl.DateTimeFormat(undefined, { timeStyle: 'short' }).format(time) + return `${date} · ${formattedTime}` +}