feat(web): judgement model selector

This commit is contained in:
JzoNg 2026-03-30 14:03:37 +08:00
parent 0642475b85
commit 1660067d6e
4 changed files with 41 additions and 41 deletions

View File

@ -31,7 +31,7 @@ const SectionHeader = ({
return (
<div className={cn('flex flex-wrap items-start justify-between gap-3', className)}>
<div>
<div className={cn('text-text-primary system-md-semibold', titleClassName)}>{title}</div>
<div className={cn('text-text-primary system-xl-semibold', titleClassName)}>{title}</div>
{description && <div className={cn('mt-1 text-text-tertiary system-sm-regular', descriptionClassName)}>{description}</div>}
</div>
{action}
@ -58,7 +58,7 @@ export const InlineSectionHeader = ({
className="flex h-4 w-4 items-center justify-center text-text-quaternary transition-colors hover:text-text-tertiary"
aria-label={title}
>
<span aria-hidden="true" className="i-ri-information-line h-3.5 w-3.5" />
<span aria-hidden="true" className="i-ri-question-line h-3.5 w-3.5" />
</button>
)}
/>

View File

@ -27,7 +27,7 @@ const Evaluation = ({
return (
<div className="flex h-full min-h-0 flex-col bg-background-default xl:flex-row">
<div className="min-h-0 flex-1 overflow-y-auto">
<div className="mx-auto flex min-h-full max-w-[748px] flex-col px-6 py-4">
<div className="flex min-h-full max-w-[748px] flex-col px-6 py-4">
<SectionHeader
title={t('title')}
description={(

View File

@ -1,8 +1,9 @@
import type { Snippet } from '@/types/snippet'
import type { SnippetDetailPayload } from '@/models/snippet'
import { render, screen } from '@testing-library/react'
import SnippetEvaluationPage from '../snippet-evaluation-page'
const mockUseSnippetApiDetail = vi.fn()
const mockGetSnippetDetailMock = vi.fn()
const mockSetAppSidebarExpand = vi.fn()
vi.mock('@/service/use-snippets', async (importOriginal) => {
@ -33,6 +34,10 @@ vi.mock('@/next/navigation', () => ({
}),
}))
vi.mock('@/service/use-snippets.mock', () => ({
getSnippetDetailMock: (snippetId: string) => mockGetSnippetDetailMock(snippetId),
}))
vi.mock('@/hooks/use-breakpoints', () => ({
default: () => 'desktop',
MediaType: { mobile: 'mobile', desktop: 'desktop' },
@ -69,38 +74,49 @@ vi.mock('@/app/components/evaluation', () => ({
default: ({ resourceId }: { resourceId: string }) => <div data-testid="evaluation">{resourceId}</div>,
}))
const mockSnippetApiDetail: Snippet = {
id: 'snippet-1',
name: 'Tone Rewriter',
description: 'A static snippet mock.',
type: 'node',
is_published: false,
version: 'draft',
use_count: 19,
icon_info: {
icon_type: 'emoji',
const mockSnippetDetail: SnippetDetailPayload = {
snippet: {
id: 'snippet-1',
name: 'Tone Rewriter',
description: 'A static snippet mock.',
author: 'Evan',
updatedAt: '2024-03-24',
usage: '19',
icon: '🪄',
icon_background: '#E0EAFF',
iconBackground: '#E0EAFF',
},
graph: {
nodes: [],
edges: [],
viewport: {
x: 0,
y: 0,
zoom: 1,
},
},
inputFields: [],
uiMeta: {
inputFieldCount: 0,
checklistCount: 0,
autoSavedAt: '2024-03-24 12:00',
},
input_fields: [],
created_at: 1_711_609_600,
updated_at: 1_711_616_800,
author: 'Evan',
}
describe('SnippetEvaluationPage', () => {
beforeEach(() => {
vi.clearAllMocks()
mockUseSnippetApiDetail.mockReturnValue({
data: mockSnippetApiDetail,
data: undefined,
isLoading: false,
})
mockGetSnippetDetailMock.mockReturnValue(mockSnippetDetail)
})
it('should fetch evaluation route data independently from snippet init', () => {
it('should render evaluation with mock snippet detail data', () => {
render(<SnippetEvaluationPage snippetId="snippet-1" />)
expect(mockUseSnippetApiDetail).toHaveBeenCalledWith('snippet-1')
expect(mockGetSnippetDetailMock).toHaveBeenCalledWith('snippet-1')
expect(mockUseSnippetApiDetail).not.toHaveBeenCalled()
expect(screen.getByTestId('app-sidebar')).toBeInTheDocument()
expect(screen.getByTestId('evaluation')).toHaveTextContent('snippet-1')
})

View File

@ -1,9 +1,7 @@
'use client'
import { useMemo } from 'react'
import Loading from '@/app/components/base/loading'
import Evaluation from '@/app/components/evaluation'
import { buildSnippetDetailPayload, useSnippetApiDetail } from '@/service/use-snippets'
import { getSnippetDetailMock } from '@/service/use-snippets.mock'
import SnippetLayout from './components/snippet-layout'
@ -12,25 +10,11 @@ type SnippetEvaluationPageProps = {
}
const SnippetEvaluationPage = ({ snippetId }: SnippetEvaluationPageProps) => {
const snippetApiDetail = useSnippetApiDetail(snippetId)
const mockSnippet = useMemo(() => getSnippetDetailMock(snippetId)?.snippet, [snippetId])
const snippet = useMemo(() => {
if (snippetApiDetail.data)
return buildSnippetDetailPayload(snippetApiDetail.data).snippet
const snippet = mockSnippet
if (!snippetApiDetail.isLoading)
return mockSnippet
return undefined
}, [mockSnippet, snippetApiDetail.data, snippetApiDetail.isLoading])
if (!snippet || snippetApiDetail.isLoading) {
return (
<div className="flex h-full items-center justify-center bg-background-body">
<Loading />
</div>
)
}
if (!snippet)
return null
return (
<SnippetLayout