Job list: sort by status/priority/age, hide old finished jobs by default
Sort order: printing → queued → rest, then priority desc, then created_at asc. Finished jobs (done/failed/cancelled) older than 24h are hidden by default; a footer note shows the count with a 'Show all' link (?show_all=1). Filter params (bracket_id, q) are preserved on the show-all link. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,12 @@
|
|||||||
import os
|
import os
|
||||||
import uuid as _uuid
|
import uuid as _uuid
|
||||||
|
from datetime import datetime, timedelta
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends, File, Form, Request, UploadFile
|
from fastapi import APIRouter, Depends, File, Form, Request, UploadFile
|
||||||
from fastapi.responses import HTMLResponse, RedirectResponse
|
from fastapi.responses import HTMLResponse, RedirectResponse
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
from sqlalchemy import or_
|
from sqlalchemy import case, or_
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from starlette.status import HTTP_303_SEE_OTHER
|
from starlette.status import HTTP_303_SEE_OTHER
|
||||||
|
|
||||||
@@ -127,7 +128,7 @@ def create_printer_type(
|
|||||||
# ── Jobs ───────────────────────────────────────────────────────────────────────
|
# ── Jobs ───────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@router.get("/jobs", response_class=HTMLResponse)
|
@router.get("/jobs", response_class=HTMLResponse)
|
||||||
def jobs_page(request: Request, q: str = "", bracket_id: str = "", db: Session = Depends(get_db)):
|
def jobs_page(request: Request, q: str = "", bracket_id: str = "", show_all: str = "", db: Session = Depends(get_db)):
|
||||||
query = db.query(PrintJob)
|
query = db.query(PrintJob)
|
||||||
if q:
|
if q:
|
||||||
like = f"%{q}%"
|
like = f"%{q}%"
|
||||||
@@ -138,11 +139,35 @@ def jobs_page(request: Request, q: str = "", bracket_id: str = "", db: Session =
|
|||||||
if bracket_id:
|
if bracket_id:
|
||||||
query = query.filter(PrintJob.bracket_id == int(bracket_id))
|
query = query.filter(PrintJob.bracket_id == int(bracket_id))
|
||||||
active_bracket = db.query(JobBracket).filter(JobBracket.id == int(bracket_id)).first()
|
active_bracket = db.query(JobBracket).filter(JobBracket.id == int(bracket_id)).first()
|
||||||
|
|
||||||
|
# Hide finished jobs older than 24h unless show_all
|
||||||
|
finished = [JobStatus.done, JobStatus.failed, JobStatus.cancelled]
|
||||||
|
cutoff = datetime.now() - timedelta(hours=24)
|
||||||
|
hidden_count = 0
|
||||||
|
if not show_all:
|
||||||
|
hidden_count = query.filter(
|
||||||
|
PrintJob.status.in_(finished), PrintJob.created_at < cutoff
|
||||||
|
).count()
|
||||||
|
query = query.filter(
|
||||||
|
or_(~PrintJob.status.in_(finished), PrintJob.created_at >= cutoff)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Sort: printing → queued → rest, then priority, then oldest first
|
||||||
|
status_order = case(
|
||||||
|
(PrintJob.status == JobStatus.printing, 0),
|
||||||
|
(PrintJob.status == JobStatus.queued, 1),
|
||||||
|
else_=2,
|
||||||
|
)
|
||||||
|
jobs = query.order_by(status_order, PrintJob.priority.desc(), PrintJob.created_at.asc()).all()
|
||||||
|
|
||||||
return templates.TemplateResponse("jobs.html", {
|
return templates.TemplateResponse("jobs.html", {
|
||||||
"request": request,
|
"request": request,
|
||||||
"active": "jobs",
|
"active": "jobs",
|
||||||
"jobs": query.order_by(PrintJob.priority.desc(), PrintJob.created_at.desc()).all(),
|
"jobs": jobs,
|
||||||
"q": q,
|
"q": q,
|
||||||
|
"bracket_id": bracket_id,
|
||||||
|
"show_all": bool(show_all),
|
||||||
|
"hidden_count": hidden_count,
|
||||||
"active_bracket": active_bracket,
|
"active_bracket": active_bracket,
|
||||||
"printers": db.query(Printer).order_by(Printer.name).all(),
|
"printers": db.query(Printer).order_by(Printer.name).all(),
|
||||||
"brackets": db.query(JobBracket).order_by(JobBracket.name).all(),
|
"brackets": db.query(JobBracket).order_by(JobBracket.name).all(),
|
||||||
|
|||||||
@@ -93,6 +93,16 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% if hidden_count %}
|
||||||
|
{% set sep = '&' if (q or bracket_id) else '?' %}
|
||||||
|
{% set show_all_url = '/jobs?show_all=1' ~ ('&bracket_id=' ~ bracket_id if bracket_id else '') ~ ('&q=' ~ q if q else '') %}
|
||||||
|
<p class="text-secondary small mt-3 mb-0">
|
||||||
|
<i class="bi bi-archive me-1"></i>
|
||||||
|
{{ hidden_count }} finished job{{ 's' if hidden_count != 1 else '' }} older than 24 h hidden.
|
||||||
|
<a href="{{ show_all_url }}" class="text-secondary">Show all</a>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{# ── Add Job Modal ── #}
|
{# ── Add Job Modal ── #}
|
||||||
<div class="modal fade" id="addJobModal" tabindex="-1">
|
<div class="modal fade" id="addJobModal" tabindex="-1">
|
||||||
<div class="modal-dialog modal-lg">
|
<div class="modal-dialog modal-lg">
|
||||||
|
|||||||
Reference in New Issue
Block a user