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:
parent
f1316578fe
commit
1588972a8e
@ -5,9 +5,9 @@
|
|||||||
**Blocked by:** 04
|
**Blocked by:** 04
|
||||||
|
|
||||||
**Acceptance criteria:**
|
**Acceptance criteria:**
|
||||||
- [ ] 创建/编辑入口统一(表单 Drawer 或保留 Monaco 全屏编辑——以现有主模式为准,但容器样式对齐标准)
|
- [x] 创建/编辑入口统一 FormDrawer(width 720 保留 Monaco 编辑空间)
|
||||||
- [ ] 删除有 Popconfirm;模板相关交互不变
|
- [x] 删除有 Popconfirm;模板相关交互不变
|
||||||
- [ ] 空态 Empty、20 行分页阈值
|
- [x] 空态 Empty、20 行分页阈值
|
||||||
- [ ] 现状 Modal 与 Drawer 混用处收敛(保留 Monaco 场景所需的 Modal)
|
- [x] Modal 仅保留预览与模板选择(只读/选择型),编辑表单收敛为 FormDrawer
|
||||||
- [ ] `tsc --noEmit` 通过
|
- [x] `tsc --noEmit` 通过
|
||||||
- [ ] t480 走查:场景 CRUD + 编辑 + 校验 golden path
|
- [ ] t480 走查:场景 CRUD + 编辑 + 校验 golden path
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import {
|
import {
|
||||||
Button, Card, Drawer, Form, Input, message, Modal, Popconfirm,
|
Button, Card, Empty, Form, Input, message, Modal, Popconfirm,
|
||||||
Select, Space, Table, Tag, Tooltip,
|
Select, Space, Table, Tag, Tooltip,
|
||||||
} from 'antd'
|
} from 'antd'
|
||||||
import {
|
import {
|
||||||
@ -9,6 +9,7 @@ import {
|
|||||||
} from '@ant-design/icons'
|
} from '@ant-design/icons'
|
||||||
import Editor from '@monaco-editor/react'
|
import Editor from '@monaco-editor/react'
|
||||||
import { modelConfigsApi, scenariosApi, type Scenario } from '../api'
|
import { modelConfigsApi, scenariosApi, type Scenario } from '../api'
|
||||||
|
import FormDrawer from '../components/FormDrawer'
|
||||||
import PageWrapper from '../components/PageWrapper'
|
import PageWrapper from '../components/PageWrapper'
|
||||||
import { useResource } from '../hooks/useResource'
|
import { useResource } from '../hooks/useResource'
|
||||||
import { colors } from '../tokens'
|
import { colors } from '../tokens'
|
||||||
@ -50,6 +51,7 @@ export default function ScenariosPage() {
|
|||||||
const [previewOpen, setPreviewOpen] = useState(false)
|
const [previewOpen, setPreviewOpen] = useState(false)
|
||||||
const [previewData, setPreviewData] = useState<any>(null)
|
const [previewData, setPreviewData] = useState<any>(null)
|
||||||
const [editingScenario, setEditingScenario] = useState<Scenario | null>(null)
|
const [editingScenario, setEditingScenario] = useState<Scenario | null>(null)
|
||||||
|
const [submitting, setSubmitting] = useState(false)
|
||||||
const [casesJson, setCasesJson] = useState(YAML_TEMPLATE)
|
const [casesJson, setCasesJson] = useState(YAML_TEMPLATE)
|
||||||
const [modelBindings, setModelBindings] = useState<Record<string, string>>({})
|
const [modelBindings, setModelBindings] = useState<Record<string, string>>({})
|
||||||
const [form] = Form.useForm()
|
const [form] = Form.useForm()
|
||||||
@ -138,11 +140,21 @@ export default function ScenariosPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (editingScenario) {
|
if (editingScenario) {
|
||||||
await scenariosApi.update(editingScenario.id, payload)
|
setSubmitting(true)
|
||||||
message.success('更新成功')
|
try {
|
||||||
|
await scenariosApi.update(editingScenario.id, payload)
|
||||||
|
message.success('更新成功')
|
||||||
|
} finally {
|
||||||
|
setSubmitting(false)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
await scenariosApi.create(payload)
|
setSubmitting(true)
|
||||||
message.success('创建成功')
|
try {
|
||||||
|
await scenariosApi.create(payload)
|
||||||
|
message.success('创建成功')
|
||||||
|
} finally {
|
||||||
|
setSubmitting(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setDrawerOpen(false)
|
setDrawerOpen(false)
|
||||||
reload()
|
reload()
|
||||||
@ -180,7 +192,7 @@ export default function ScenariosPage() {
|
|||||||
<Tooltip title="编辑">
|
<Tooltip title="编辑">
|
||||||
<Button size="small" type="text" icon={<EditOutlined />} onClick={() => openEdit(record)} />
|
<Button size="small" type="text" icon={<EditOutlined />} onClick={() => openEdit(record)} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Popconfirm title="确认删除?" onConfirm={() => handleDelete(record.id)}>
|
<Popconfirm title="删除该评测场景?" onConfirm={() => handleDelete(record.id)}>
|
||||||
<Tooltip title="删除">
|
<Tooltip title="删除">
|
||||||
<Button size="small" type="text" danger icon={<DeleteOutlined />} />
|
<Button size="small" type="text" danger icon={<DeleteOutlined />} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -217,29 +229,25 @@ export default function ScenariosPage() {
|
|||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{/* 表格区 — 撑满剩余高度 */}
|
<div style={{ height: '100%', overflowY: 'auto', padding: '0 16px 16px' }}>
|
||||||
<div style={{ flex: 1, minHeight: 0, overflow: 'hidden' }}>
|
|
||||||
<Table
|
<Table
|
||||||
dataSource={scenarios ?? []}
|
dataSource={scenarios ?? []}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
loading={loading}
|
loading={loading}
|
||||||
pagination={{ pageSize: 15, showSizeChanger: true, showTotal: (t) => `共 ${t} 个` }}
|
pagination={(scenarios?.length ?? 0) > 20 ? { pageSize: 20, showTotal: (t) => `共 ${t} 个` } : false}
|
||||||
scroll={{ y: 'calc(100vh - 200px)' }}
|
locale={{ emptyText: <Empty description="还没有评测场景" /> }}
|
||||||
style={{ height: '100%' }}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Drawer
|
<FormDrawer
|
||||||
title={editingScenario ? `编辑评测场景(当前 v${editingScenario.version ?? 1})` : '新增评测场景'}
|
title={editingScenario ? `编辑评测场景(当前 v${editingScenario.version ?? 1})` : '新增评测场景'}
|
||||||
open={drawerOpen}
|
open={drawerOpen}
|
||||||
onClose={() => setDrawerOpen(false)}
|
onClose={() => setDrawerOpen(false)}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
submitting={submitting}
|
||||||
|
okText={editingScenario ? '更新' : '创建'}
|
||||||
width={720}
|
width={720}
|
||||||
extra={
|
|
||||||
<Button type="primary" onClick={handleSubmit}>
|
|
||||||
{editingScenario ? '更新' : '创建'}
|
|
||||||
</Button>
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
<Form form={form} layout="vertical">
|
<Form form={form} layout="vertical">
|
||||||
<Form.Item name="name" label="名称" rules={[{ required: true, message: '请输入场景名称' }]}>
|
<Form.Item name="name" label="名称" rules={[{ required: true, message: '请输入场景名称' }]}>
|
||||||
@ -309,7 +317,7 @@ export default function ScenariosPage() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Drawer>
|
</FormDrawer>
|
||||||
|
|
||||||
<Modal
|
<Modal
|
||||||
title={`场景预览: ${previewData?.name || ''}${previewData?.version != null ? `(v${previewData.version})` : ''}`}
|
title={`场景预览: ${previewData?.name || ''}${previewData?.version != null ? `(v${previewData.version})` : ''}`}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user