diff --git a/web/app/components/evaluation/components/layout/pipeline-evaluation.tsx b/web/app/components/evaluation/components/layout/pipeline-evaluation.tsx
index 73ba754f28..c605c53e17 100644
--- a/web/app/components/evaluation/components/layout/pipeline-evaluation.tsx
+++ b/web/app/components/evaluation/components/layout/pipeline-evaluation.tsx
@@ -1,190 +1,19 @@
'use client'
-import type { EvaluationResourceProps, MetricOption } from '../../types'
-import { useEffect, useMemo, useRef, useState } from 'react'
+import type { EvaluationResourceProps } from '../../types'
+import { useEffect, useMemo, useRef } from 'react'
import { useTranslation } from 'react-i18next'
-import Badge from '@/app/components/base/badge'
import Button from '@/app/components/base/button'
-import Checkbox from '@/app/components/base/checkbox'
-import Input from '@/app/components/base/input'
import { toast } from '@/app/components/base/ui/toast'
-import { Tooltip, TooltipContent, TooltipTrigger } from '@/app/components/base/ui/tooltip'
import { useDocLink } from '@/context/i18n'
-import { cn } from '@/utils/classnames'
import { getEvaluationMockConfig } from '../../mock'
import { isEvaluationRunnable, useEvaluationResource, useEvaluationStore } from '../../store'
import JudgeModelSelector from '../judge-model-selector'
+import PipelineHistoryTable from '../pipeline/pipeline-history-table'
+import PipelineMetricItem from '../pipeline/pipeline-metric-item'
+import PipelineResultsPanel from '../pipeline/pipeline-results-panel'
import SectionHeader, { InlineSectionHeader } from '../section-header'
-type PipelineMetricItemProps = {
- metric: MetricOption
- selected: boolean
- onToggle: () => void
- disabledCondition: boolean
-}
-
-const PipelineMetricItem = ({
- metric,
- selected,
- onToggle,
- disabledCondition,
-}: PipelineMetricItemProps) => {
- return (
-
-
-
-
-
- )
-}
-
-const PipelineHistoryTable = ({
- resourceType,
- resourceId,
-}: EvaluationResourceProps) => {
- const { t } = useTranslation('evaluation')
- const resource = useEvaluationResource(resourceType, resourceId)
- const [query, setQuery] = useState('')
- const statusLabels = {
- running: t('batch.status.running'),
- success: t('batch.status.success'),
- failed: t('batch.status.failed'),
- }
-
- const filteredRecords = useMemo(() => {
- const keyword = query.trim().toLowerCase()
- if (!keyword)
- return resource.batchRecords
-
- return resource.batchRecords.filter(record =>
- record.fileName.toLowerCase().includes(keyword)
- || record.summary.toLowerCase().includes(keyword),
- )
- }, [query, resource.batchRecords])
-
- return (
-
-
-
{t('history.title')}
-
- setQuery(event.target.value)}
- />
-
-
-
-
-
-
-
- {t('history.columns.time')}
-
-
-
{t('history.columns.creator')}
-
{t('history.columns.version')}
-
{t('history.columns.status')}
-
-
-
-
- {filteredRecords.length > 0 && (
-
- {filteredRecords.map(record => (
-
-
{record.startedAt}
-
{t('history.creatorYou')}
-
{t('history.latestVersion')}
-
-
- {record.status === 'running'
- ? (
-
-
- {statusLabels.running}
-
- )
- : statusLabels[record.status]}
-
-
-
-
-
-
- ))}
-
- )}
-
- {filteredRecords.length === 0 && (
-
-
-
{t('history.empty')}
-
- )}
-
-
-
-
- )
-}
-
-const PipelineResultsPanel = () => {
- const { t } = useTranslation('evaluation')
-
- return (
-
-
-
-
{t('results.empty')}
-
-
- )
-}
-
const PipelineEvaluation = ({
resourceType,
resourceId,
diff --git a/web/app/components/evaluation/components/pipeline/pipeline-history-table.tsx b/web/app/components/evaluation/components/pipeline/pipeline-history-table.tsx
new file mode 100644
index 0000000000..51769d5d75
--- /dev/null
+++ b/web/app/components/evaluation/components/pipeline/pipeline-history-table.tsx
@@ -0,0 +1,117 @@
+'use client'
+
+import type { EvaluationResourceProps } from '../../types'
+import { useMemo, useState } from 'react'
+import { useTranslation } from 'react-i18next'
+import Badge from '@/app/components/base/badge'
+import Input from '@/app/components/base/input'
+import { cn } from '@/utils/classnames'
+import { useEvaluationResource } from '../../store'
+
+const PipelineHistoryTable = ({
+ resourceType,
+ resourceId,
+}: EvaluationResourceProps) => {
+ const { t } = useTranslation('evaluation')
+ const resource = useEvaluationResource(resourceType, resourceId)
+ const [query, setQuery] = useState('')
+ const statusLabels = {
+ running: t('batch.status.running'),
+ success: t('batch.status.success'),
+ failed: t('batch.status.failed'),
+ }
+
+ const filteredRecords = useMemo(() => {
+ const keyword = query.trim().toLowerCase()
+ if (!keyword)
+ return resource.batchRecords
+
+ return resource.batchRecords.filter(record =>
+ record.fileName.toLowerCase().includes(keyword)
+ || record.summary.toLowerCase().includes(keyword),
+ )
+ }, [query, resource.batchRecords])
+
+ return (
+
+
+
{t('history.title')}
+
+ setQuery(event.target.value)}
+ />
+
+
+
+
+
+
+
+ {t('history.columns.time')}
+
+
+
{t('history.columns.creator')}
+
{t('history.columns.version')}
+
{t('history.columns.status')}
+
+
+
+
+ {filteredRecords.length > 0 && (
+
+ {filteredRecords.map(record => (
+
+
{record.startedAt}
+
{t('history.creatorYou')}
+
{t('history.latestVersion')}
+
+
+ {record.status === 'running'
+ ? (
+
+
+ {statusLabels.running}
+
+ )
+ : statusLabels[record.status]}
+
+
+
+
+
+
+ ))}
+
+ )}
+
+ {filteredRecords.length === 0 && (
+
+
+
{t('history.empty')}
+
+ )}
+
+
+
+
+ )
+}
+
+export default PipelineHistoryTable
diff --git a/web/app/components/evaluation/components/pipeline/pipeline-metric-item.tsx b/web/app/components/evaluation/components/pipeline/pipeline-metric-item.tsx
new file mode 100644
index 0000000000..14c4a3c726
--- /dev/null
+++ b/web/app/components/evaluation/components/pipeline/pipeline-metric-item.tsx
@@ -0,0 +1,58 @@
+'use client'
+
+import type { MetricOption } from '../../types'
+import Checkbox from '@/app/components/base/checkbox'
+import { Tooltip, TooltipContent, TooltipTrigger } from '@/app/components/base/ui/tooltip'
+import { cn } from '@/utils/classnames'
+
+type PipelineMetricItemProps = {
+ metric: MetricOption
+ selected: boolean
+ onToggle: () => void
+ disabledCondition: boolean
+}
+
+const PipelineMetricItem = ({
+ metric,
+ selected,
+ onToggle,
+ disabledCondition,
+}: PipelineMetricItemProps) => {
+ return (
+
+
+
+
+
+ )
+}
+
+export default PipelineMetricItem
diff --git a/web/app/components/evaluation/components/pipeline/pipeline-results-panel.tsx b/web/app/components/evaluation/components/pipeline/pipeline-results-panel.tsx
new file mode 100644
index 0000000000..3e7286adbf
--- /dev/null
+++ b/web/app/components/evaluation/components/pipeline/pipeline-results-panel.tsx
@@ -0,0 +1,18 @@
+'use client'
+
+import { useTranslation } from 'react-i18next'
+
+const PipelineResultsPanel = () => {
+ const { t } = useTranslation('evaluation')
+
+ return (
+
+
+
+
{t('results.empty')}
+
+
+ )
+}
+
+export default PipelineResultsPanel