refactor(ui): migrate Scenarios page to consistency baseline (ui-consistency ticket 05)

FormDrawer with footer submit at width 720 (keeps Monaco room),
submitting guard, 20-row conditional pagination, Empty locale,
unified delete Popconfirm wording. Preview/template Modals kept as
read-only surfaces.
This commit is contained in:
sinohqb 2026-08-05 20:23:46 +08:00
parent f1316578fe
commit 1588972a8e
2 changed files with 31 additions and 23 deletions

View File

@ -5,9 +5,9 @@
**Blocked by:** 04
**Acceptance criteria:**
- [ ] 创建/编辑入口统一(表单 Drawer 或保留 Monaco 全屏编辑——以现有主模式为准,但容器样式对齐标准
- [ ] 删除有 Popconfirm模板相关交互不变
- [ ] 空态 Empty、20 行分页阈值
- [ ] 现状 Modal 与 Drawer 混用处收敛(保留 Monaco 场景所需的 Modal
- [ ] `tsc --noEmit` 通过
- [x] 创建/编辑入口统一 FormDrawerwidth 720 保留 Monaco 编辑空间
- [x] 删除有 Popconfirm模板相关交互不变
- [x] 空态 Empty、20 行分页阈值
- [x] Modal 仅保留预览与模板选择(只读/选择型),编辑表单收敛为 FormDrawer
- [x] `tsc --noEmit` 通过
- [ ] t480 走查:场景 CRUD + 编辑 + 校验 golden path

View File

@ -1,6 +1,6 @@
import { useEffect, useState } from 'react'
import {
Button, Card, Drawer, Form, Input, message, Modal, Popconfirm,
Button, Card, Empty, Form, Input, message, Modal, Popconfirm,
Select, Space, Table, Tag, Tooltip,
} from 'antd'
import {
@ -9,6 +9,7 @@ import {
} from '@ant-design/icons'
import Editor from '@monaco-editor/react'
import { modelConfigsApi, scenariosApi, type Scenario } from '../api'
import FormDrawer from '../components/FormDrawer'
import PageWrapper from '../components/PageWrapper'
import { useResource } from '../hooks/useResource'
import { colors } from '../tokens'
@ -50,6 +51,7 @@ export default function ScenariosPage() {
const [previewOpen, setPreviewOpen] = useState(false)
const [previewData, setPreviewData] = useState<any>(null)
const [editingScenario, setEditingScenario] = useState<Scenario | null>(null)
const [submitting, setSubmitting] = useState(false)
const [casesJson, setCasesJson] = useState(YAML_TEMPLATE)
const [modelBindings, setModelBindings] = useState<Record<string, string>>({})
const [form] = Form.useForm()
@ -138,11 +140,21 @@ export default function ScenariosPage() {
}
if (editingScenario) {
setSubmitting(true)
try {
await scenariosApi.update(editingScenario.id, payload)
message.success('更新成功')
} finally {
setSubmitting(false)
}
} else {
setSubmitting(true)
try {
await scenariosApi.create(payload)
message.success('创建成功')
} finally {
setSubmitting(false)
}
}
setDrawerOpen(false)
reload()
@ -180,7 +192,7 @@ export default function ScenariosPage() {
<Tooltip title="编辑">
<Button size="small" type="text" icon={<EditOutlined />} onClick={() => openEdit(record)} />
</Tooltip>
<Popconfirm title="确认删除?" onConfirm={() => handleDelete(record.id)}>
<Popconfirm title="删除该评测场景" onConfirm={() => handleDelete(record.id)}>
<Tooltip title="删除">
<Button size="small" type="text" danger icon={<DeleteOutlined />} />
</Tooltip>
@ -217,29 +229,25 @@ export default function ScenariosPage() {
</Space>
}
>
{/* 表格区 — 撑满剩余高度 */}
<div style={{ flex: 1, minHeight: 0, overflow: 'hidden' }}>
<div style={{ height: '100%', overflowY: 'auto', padding: '0 16px 16px' }}>
<Table
dataSource={scenarios ?? []}
columns={columns}
rowKey="id"
loading={loading}
pagination={{ pageSize: 15, showSizeChanger: true, showTotal: (t) => `${t}` }}
scroll={{ y: 'calc(100vh - 200px)' }}
style={{ height: '100%' }}
pagination={(scenarios?.length ?? 0) > 20 ? { pageSize: 20, showTotal: (t) => `${t}` } : false}
locale={{ emptyText: <Empty description="还没有评测场景" /> }}
/>
</div>
<Drawer
<FormDrawer
title={editingScenario ? `编辑评测场景(当前 v${editingScenario.version ?? 1}` : '新增评测场景'}
open={drawerOpen}
onClose={() => setDrawerOpen(false)}
onSubmit={handleSubmit}
submitting={submitting}
okText={editingScenario ? '更新' : '创建'}
width={720}
extra={
<Button type="primary" onClick={handleSubmit}>
{editingScenario ? '更新' : '创建'}
</Button>
}
>
<Form form={form} layout="vertical">
<Form.Item name="name" label="名称" rules={[{ required: true, message: '请输入场景名称' }]}>
@ -309,7 +317,7 @@ export default function ScenariosPage() {
}}
/>
</div>
</Drawer>
</FormDrawer>
<Modal
title={`场景预览: ${previewData?.name || ''}${previewData?.version != null ? `v${previewData.version}` : ''}`}