|
|
@@ -2,6 +2,9 @@ import { useState, useEffect, useRef, useCallback, memo } from 'react'
|
|
|
import api, { TrainingJob, ModelInfo, DatasetInfo } from '../api/client'
|
|
|
import { wsManager } from '../api/websocket'
|
|
|
import { Train } from 'lucide-react'
|
|
|
+import { Pagination } from '../components/Pagination'
|
|
|
+
|
|
|
+const JOBS_PER_PAGE = 10
|
|
|
|
|
|
const MODEL_TYPES = [
|
|
|
{ value: 'text', label: '文本 (LLaMA/Qwen)' },
|
|
|
@@ -334,6 +337,7 @@ export function Training() {
|
|
|
const [numGpus, setNumGpus] = useState(1)
|
|
|
|
|
|
const [jobs, setJobs] = useState<TrainingJob[]>([])
|
|
|
+ const [jobPage, setJobPage] = useState(1)
|
|
|
const [loading, setLoading] = useState(false)
|
|
|
const [submitting, setSubmitting] = useState(false)
|
|
|
const [createError, setCreateError] = useState('')
|
|
|
@@ -449,6 +453,15 @@ export function Training() {
|
|
|
}
|
|
|
}, [])
|
|
|
|
|
|
+ // 页码自动校正
|
|
|
+ const totalJobPages = Math.max(1, Math.ceil(jobs.length / JOBS_PER_PAGE))
|
|
|
+ useEffect(() => {
|
|
|
+ if (jobPage > totalJobPages) setJobPage(totalJobPages)
|
|
|
+ }, [jobPage, totalJobPages])
|
|
|
+
|
|
|
+ // 当前页的 jobs
|
|
|
+ const pagedJobs = jobs.slice((jobPage - 1) * JOBS_PER_PAGE, jobPage * JOBS_PER_PAGE)
|
|
|
+
|
|
|
const handleCreate = () => {
|
|
|
if (!modelId.trim() || !datasetId.trim()) return
|
|
|
setSubmitting(true)
|
|
|
@@ -477,6 +490,7 @@ export function Training() {
|
|
|
setModelId('')
|
|
|
setDatasetId('')
|
|
|
setJobs(prev => prev.filter(j => j.id !== tempId))
|
|
|
+ setJobPage(1)
|
|
|
fetchJobs()
|
|
|
fetchOptions()
|
|
|
})
|
|
|
@@ -636,6 +650,7 @@ export function Training() {
|
|
|
)}
|
|
|
|
|
|
{!loading && jobs.length > 0 && (
|
|
|
+ <>
|
|
|
<div style={{
|
|
|
background: '#fff', borderRadius: 10, overflow: 'hidden',
|
|
|
boxShadow: '0 1px 3px rgba(0,0,0,0.06)', border: '1px solid rgba(0,0,0,0.04)',
|
|
|
@@ -654,12 +669,19 @@ export function Training() {
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody>
|
|
|
- {jobs.map(j => (
|
|
|
+ {pagedJobs.map(j => (
|
|
|
<JobRow key={j.id} j={j} onCancel={handleCancel} datasets={datasets} />
|
|
|
))}
|
|
|
</tbody>
|
|
|
</table>
|
|
|
</div>
|
|
|
+ <Pagination
|
|
|
+ page={jobPage}
|
|
|
+ totalPages={totalJobPages}
|
|
|
+ total={jobs.length}
|
|
|
+ onChange={setJobPage}
|
|
|
+ />
|
|
|
+ </>
|
|
|
)}
|
|
|
</div>
|
|
|
</div>
|