diff --git a/internal/db/queries.go b/internal/db/queries.go index 5328b8a..f64a98f 100644 --- a/internal/db/queries.go +++ b/internal/db/queries.go @@ -79,6 +79,33 @@ func GetPendingJobs() ([]Job, error) { return jobs, nil } +func GetJobsPaginated(limit, offset int) ([]Job, int, error) { + var total int + if err := DB.QueryRow(`SELECT COUNT(*) FROM jobs`).Scan(&total); err != nil { + return nil, 0, err + } + + rows, err := DB.Query(`SELECT id, file_path, media_type, status, priority, original_size, target_resolution, ffmpeg_flags, error_message, created_at, updated_at FROM jobs ORDER BY priority DESC, created_at ASC LIMIT ? OFFSET ?`, limit, offset) + if err != nil { + return nil, 0, err + } + defer rows.Close() + + var jobs []Job + for rows.Next() { + var j Job + var targetRes, ffmpegFlags, errMsg sql.NullString + if err := rows.Scan(&j.ID, &j.FilePath, &j.MediaType, &j.Status, &j.Priority, &j.OriginalSize, &targetRes, &ffmpegFlags, &errMsg, &j.CreatedAt, &j.UpdatedAt); err != nil { + return nil, 0, err + } + if targetRes.Valid { j.TargetResolution = targetRes.String } + if ffmpegFlags.Valid { j.FFmpegFlags = ffmpegFlags.String } + if errMsg.Valid { j.ErrorMessage = errMsg.String } + jobs = append(jobs, j) + } + return jobs, total, nil +} + func UpdateJobStatus(id int, status, errMsg string) error { _, err := DB.Exec(`UPDATE jobs SET status = ?, error_message = ? WHERE id = ?`, status, nullStr(errMsg), id) return err diff --git a/internal/web/api.go b/internal/web/api.go index 93e1b4e..0b44e45 100644 --- a/internal/web/api.go +++ b/internal/web/api.go @@ -10,13 +10,42 @@ import ( ) func (s *Server) handleGetQueue(w http.ResponseWriter, r *http.Request) { - jobs, err := db.GetPendingJobs() + limitStr := r.URL.Query().Get("limit") + pageStr := r.URL.Query().Get("page") + + limit := 10 + if l, err := strconv.Atoi(limitStr); err == nil && l > 0 { + limit = l + } + + page := 1 + if p, err := strconv.Atoi(pageStr); err == nil && p > 0 { + page = p + } + + offset := (page - 1) * limit + + jobs, total, err := db.GetJobsPaginated(limit, offset) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } + + totalPages := (total + limit - 1) / limit + if totalPages == 0 { + totalPages = 1 + } + + response := map[string]interface{}{ + "jobs": jobs, + "total": total, + "page": page, + "totalPages": totalPages, + "limit": limit, + } + w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(jobs) + json.NewEncoder(w).Encode(response) } func (s *Server) handleBumpJob(w http.ResponseWriter, r *http.Request) { diff --git a/web/templates/dashboard.html b/web/templates/dashboard.html index dffd923..51649e0 100644 --- a/web/templates/dashboard.html +++ b/web/templates/dashboard.html @@ -33,15 +33,50 @@ +