Add printer types with bed volume + add-printer UI

- PrinterType model: name, bed_x_mm/y/z, linked to Printer via type_id
- Migration 0002: creates printer_types, adds type_id to printers, drops model
- /printer-types page: table + Add Type modal form
- /printers page: Add Printer modal with type dropdown (disabled if no types)
- API: GET/POST/DELETE /api/printer-types

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Martin Hohenberg
2026-06-18 21:46:26 +02:00
parent 5fb15b36bf
commit 750edbbcec
9 changed files with 309 additions and 12 deletions

View File

@@ -0,0 +1,39 @@
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel
from sqlalchemy.orm import Session
from app.db import get_db
from app.models.printer_type import PrinterType
router = APIRouter(prefix="/printer-types", tags=["printer-types"])
class PrinterTypeCreate(BaseModel):
name: str
bed_x_mm: int
bed_y_mm: int
bed_z_mm: int
@router.get("/")
def list_printer_types(db: Session = Depends(get_db)):
return [t.to_dict() for t in db.query(PrinterType).order_by(PrinterType.name).all()]
@router.post("/")
def create_printer_type(data: PrinterTypeCreate, db: Session = Depends(get_db)):
pt = PrinterType(**data.model_dump())
db.add(pt)
db.commit()
db.refresh(pt)
return pt.to_dict()
@router.delete("/{type_id}")
def delete_printer_type(type_id: int, db: Session = Depends(get_db)):
pt = db.query(PrinterType).filter(PrinterType.id == type_id).first()
if not pt:
raise HTTPException(status_code=404, detail="Printer type not found")
db.delete(pt)
db.commit()
return {"ok": True}

View File

@@ -1,12 +1,14 @@
from fastapi import APIRouter, Depends, Request
from fastapi.responses import HTMLResponse
from fastapi import APIRouter, Depends, Form, Request
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
from starlette.status import HTTP_303_SEE_OTHER
from app.db import get_db
from app.models.filament import Filament
from app.models.print_job import JobStatus, PrintJob
from app.models.printer import Printer, PrinterStatus
from app.models.printer_type import PrinterType
from app.models.pricing import PricingConfig
from app.models.todo import Todo
@@ -37,9 +39,50 @@ def printers_page(request: Request, db: Session = Depends(get_db)):
"request": request,
"active": "printers",
"printers": db.query(Printer).order_by(Printer.name).all(),
"printer_types": db.query(PrinterType).order_by(PrinterType.name).all(),
})
@router.post("/printers")
def create_printer(
name: str = Form(...),
location: str = Form(""),
type_id: str = Form(""),
db: Session = Depends(get_db),
):
printer = Printer(
name=name.strip(),
location=location.strip() or None,
type_id=int(type_id) if type_id else None,
)
db.add(printer)
db.commit()
return RedirectResponse(url="/printers", status_code=HTTP_303_SEE_OTHER)
@router.get("/printer-types", response_class=HTMLResponse)
def printer_types_page(request: Request, db: Session = Depends(get_db)):
return templates.TemplateResponse("printer_types.html", {
"request": request,
"active": "printers",
"printer_types": db.query(PrinterType).order_by(PrinterType.name).all(),
})
@router.post("/printer-types")
def create_printer_type(
name: str = Form(...),
bed_x_mm: int = Form(...),
bed_y_mm: int = Form(...),
bed_z_mm: int = Form(...),
db: Session = Depends(get_db),
):
pt = PrinterType(name=name.strip(), bed_x_mm=bed_x_mm, bed_y_mm=bed_y_mm, bed_z_mm=bed_z_mm)
db.add(pt)
db.commit()
return RedirectResponse(url="/printer-types", status_code=HTTP_303_SEE_OTHER)
@router.get("/jobs", response_class=HTMLResponse)
def jobs_page(request: Request, db: Session = Depends(get_db)):
return templates.TemplateResponse("jobs.html", {