mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-05 13:41:36 +02:00
- New RenameModal component with validation - Backend endpoint supports filename updates (rejects path separators) - Context menu "Rename" option in grid and list views - Inline rename button in list view actions - Add Print button to multi-selection toolbar: - Appears when exactly one sliced file is selected - Opens full PrintModal with plate selection and options - Add to Queue button now uses Clock icon for clarity - Improve mobile/PWA accessibility: - Three-dot menu button always visible on mobile (md:opacity-0) - Selection checkbox always visible on touch devices - Better experience for PWA users on tablets and phones Closes #94
238 lines
5.2 KiB
Python
238 lines
5.2 KiB
Python
"""Pydantic schemas for library (File Manager) functionality."""
|
|
|
|
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
# ============ Folder Schemas ============
|
|
|
|
|
|
class FolderCreate(BaseModel):
|
|
"""Schema for creating a new folder."""
|
|
|
|
name: str = Field(..., min_length=1, max_length=255)
|
|
parent_id: int | None = None
|
|
project_id: int | None = None
|
|
archive_id: int | None = None
|
|
|
|
|
|
class FolderUpdate(BaseModel):
|
|
"""Schema for updating a folder."""
|
|
|
|
name: str | None = Field(None, min_length=1, max_length=255)
|
|
parent_id: int | None = None
|
|
project_id: int | None = None # 0 to unlink
|
|
archive_id: int | None = None # 0 to unlink
|
|
|
|
|
|
class FolderResponse(BaseModel):
|
|
"""Schema for folder response."""
|
|
|
|
id: int
|
|
name: str
|
|
parent_id: int | None
|
|
project_id: int | None = None
|
|
archive_id: int | None = None
|
|
project_name: str | None = None
|
|
archive_name: str | None = None
|
|
file_count: int = 0 # Computed field
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class FolderTreeItem(BaseModel):
|
|
"""Schema for folder tree item (includes children)."""
|
|
|
|
id: int
|
|
name: str
|
|
parent_id: int | None
|
|
project_id: int | None = None
|
|
archive_id: int | None = None
|
|
project_name: str | None = None
|
|
archive_name: str | None = None
|
|
file_count: int = 0
|
|
children: list["FolderTreeItem"] = []
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# ============ File Schemas ============
|
|
|
|
|
|
class FileCreate(BaseModel):
|
|
"""Schema for creating a file entry (internal use after upload)."""
|
|
|
|
filename: str
|
|
file_path: str
|
|
file_type: str
|
|
file_size: int
|
|
file_hash: str | None = None
|
|
thumbnail_path: str | None = None
|
|
metadata: dict | None = None
|
|
folder_id: int | None = None
|
|
project_id: int | None = None
|
|
|
|
|
|
class FileUpdate(BaseModel):
|
|
"""Schema for updating a file."""
|
|
|
|
filename: str | None = Field(None, min_length=1, max_length=255)
|
|
folder_id: int | None = None
|
|
project_id: int | None = None
|
|
notes: str | None = None
|
|
|
|
|
|
class FileDuplicate(BaseModel):
|
|
"""Reference to a duplicate file."""
|
|
|
|
id: int
|
|
filename: str
|
|
folder_id: int | None
|
|
folder_name: str | None
|
|
created_at: datetime
|
|
|
|
|
|
class FileResponse(BaseModel):
|
|
"""Schema for file response."""
|
|
|
|
id: int
|
|
folder_id: int | None
|
|
folder_name: str | None = None
|
|
project_id: int | None
|
|
project_name: str | None = None
|
|
|
|
filename: str
|
|
file_path: str
|
|
file_type: str
|
|
file_size: int
|
|
file_hash: str | None
|
|
thumbnail_path: str | None
|
|
|
|
metadata: dict | None
|
|
|
|
print_count: int
|
|
last_printed_at: datetime | None
|
|
|
|
notes: str | None
|
|
|
|
# Duplicate detection
|
|
duplicates: list[FileDuplicate] | None = None
|
|
duplicate_count: int = 0
|
|
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class FileListResponse(BaseModel):
|
|
"""Schema for file list item (lighter than full response)."""
|
|
|
|
id: int
|
|
folder_id: int | None
|
|
filename: str
|
|
file_type: str
|
|
file_size: int
|
|
thumbnail_path: str | None
|
|
print_count: int
|
|
duplicate_count: int = 0
|
|
created_at: datetime
|
|
|
|
# Key metadata fields for display
|
|
print_name: str | None = None
|
|
print_time_seconds: int | None = None
|
|
filament_used_grams: float | None = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class FileMoveRequest(BaseModel):
|
|
"""Schema for moving files to a folder."""
|
|
|
|
file_ids: list[int]
|
|
folder_id: int | None = None # None = move to root
|
|
|
|
|
|
class FilePrintRequest(BaseModel):
|
|
"""Schema for printing a file from the library.
|
|
|
|
Note: printer_id is passed as a query parameter, not in the body.
|
|
"""
|
|
|
|
# Print options (same as archive reprint)
|
|
plate_id: int | None = None
|
|
ams_mapping: list[int] | None = None
|
|
bed_levelling: bool = True
|
|
flow_cali: bool = False
|
|
vibration_cali: bool = True
|
|
layer_inspect: bool = False
|
|
timelapse: bool = False
|
|
use_ams: bool = True
|
|
|
|
|
|
class FileUploadResponse(BaseModel):
|
|
"""Schema for file upload response."""
|
|
|
|
id: int
|
|
filename: str
|
|
file_type: str
|
|
file_size: int
|
|
thumbnail_path: str | None
|
|
duplicate_of: int | None = None # ID of existing file with same hash
|
|
metadata: dict | None = None
|
|
|
|
|
|
# ============ Bulk Operations ============
|
|
|
|
|
|
class BulkDeleteRequest(BaseModel):
|
|
"""Schema for bulk delete operations."""
|
|
|
|
file_ids: list[int] = []
|
|
folder_ids: list[int] = []
|
|
|
|
|
|
class BulkDeleteResponse(BaseModel):
|
|
"""Schema for bulk delete response."""
|
|
|
|
deleted_files: int
|
|
deleted_folders: int
|
|
|
|
|
|
# ============ Queue Operations ============
|
|
|
|
|
|
class AddToQueueRequest(BaseModel):
|
|
"""Schema for adding library files to the print queue."""
|
|
|
|
file_ids: list[int] = Field(..., min_length=1)
|
|
|
|
|
|
class AddToQueueResult(BaseModel):
|
|
"""Result for a single file added to queue."""
|
|
|
|
file_id: int
|
|
filename: str
|
|
queue_item_id: int
|
|
|
|
|
|
class AddToQueueError(BaseModel):
|
|
"""Error for a file that couldn't be added to queue."""
|
|
|
|
file_id: int
|
|
filename: str
|
|
error: str
|
|
|
|
|
|
class AddToQueueResponse(BaseModel):
|
|
"""Schema for add-to-queue response."""
|
|
|
|
added: list[AddToQueueResult]
|
|
errors: list[AddToQueueError]
|