Commit Graph
429 Commits
Author SHA1 Message Date
maziggy c834a0bd00 Add SpoolBuddy Inventory page to kiosk UI
New page at /spoolbuddy/inventory with compact 2-column spool card grid,
  search bar, material filter chips, sort options, and tap-to-open detail
  sheet. Shows Spoolman iframe when Spoolman is enabled. Navigation item
  added between Write and Settings in the bottom bar.
2026-03-26 15:04:41 +01:00
maziggy e7c81e3f08 Fix Assign Spool modal clipping on SpoolBuddy display
CSS rules scoped via data-spoolbuddy-kiosk force the modal panel to
  90vh with flex column layout. Content area scrolls, header/footer
  pinned. Uses height (not just max-height) so flex-basis auto works
  correctly. No flash — CSS applies before paint.
2026-03-26 11:40:44 +01:00
maziggy e0f0718dfc Fix Assign Spool modal clipping on SpoolBuddy display
Used a ref callback wrapper in SpoolBuddyAmsPage to directly apply
  inline styles (max-height 90vh, flex column, scrollable content) to
  the shared AssignSpoolModal DOM elements without modifying the
  shared component.
2026-03-26 11:29:22 +01:00
maziggy d4a997db34 Fix Assign Spool modal clipping on SpoolBuddy display
Added data-spoolbuddy-kiosk attribute to the SpoolBuddy layout and
  global CSS rules that cap modals at 90vh with scrollable content on
  the small touchscreen, without modifying shared components.
2026-03-26 11:26:12 +01:00
maziggy 01af948f66 Fix Assign-to-AMS modal clipping on SpoolBuddy display
The AMS slot content area was missing overflow-y-auto, so on the
  small SpoolBuddy touchscreen the content overflowed and clipped
  instead of scrolling.
2026-03-26 11:11:18 +01:00
maziggy 6e93b9f7d1 Fix virtual keyboard overlaying input fields on SpoolBuddy settings
When the virtual keyboard opened on the SpoolBuddy device tab, the
  API token field and Save button were hidden behind the keyboard.
  The keyboard now adds bottom scroll padding and scrolls the parent
  card (not just the focused input) to the top of the visible area,
  keeping all related fields accessible.
2026-03-26 10:58:08 +01:00
maziggy 00b4386e90 Fix virtual keyboard overlaying input fields on SpoolBuddy settings
When the virtual keyboard opened on the SpoolBuddy device tab, the
  Backend URL and API Token fields were hidden behind the keyboard
  overlay. The keyboard now adds temporary bottom padding to the
  scrollable container so inputs scroll above it, and removes the
  padding on dismiss.
2026-03-26 10:54:19 +01:00
maziggy bebfc01167 Fix right-swipe still triggering browser back navigation
Non-passive touchmove listener with preventDefault() blocks Chromium's
  compositor-level back/forward swipe gesture. Once horizontal movement
  is detected, the gesture is locked and all further touchmove events
  are prevented for that swipe. Removed touch-action: pan-y which was
  insufficient on its own.
2026-03-26 10:50:10 +01:00
maziggy f6d760bb3e Add swipe-to-switch-printer and auto-navigate on tag scan
Swiping left/right on the SpoolBuddy touchscreen now cycles through
  online printers instead of triggering browser back/forward navigation.
  Uses touch-action: pan-y to suppress Chromium's native swipe history
  gesture. Auto-navigates to dashboard when a new NFC tag is detected
  on any other page, with edge detection so a persistent tag doesn't
  block manual navigation. Also wakes the screen if blanked.
2026-03-26 10:47:27 +01:00
maziggy ceb599ec00 Add swipe-to-switch-printer and auto-navigate on tag scan
Swiping left/right on the SpoolBuddy touchscreen now cycles through
  online printers instead of triggering browser navigation. Auto-navigates
  to dashboard when a new NFC tag is detected on any other page, with
  edge detection so a persistent tag doesn't block manual navigation.
2026-03-26 10:44:28 +01:00
maziggy 57a774c32f Auto-navigate SpoolBuddy to dashboard on tag scan
When an NFC tag is first detected while the UI is on a non-dashboard
  page, automatically navigate to the main dashboard. Uses edge detection
  (previous ref) so a persistently present tag doesn't block navigation
  to other pages. Also wakes the screen if the display was blanked.
2026-03-26 10:40:40 +01:00
maziggy 1c35ed94a5 Auto-navigate SpoolBuddy to dashboard on tag scan
When an NFC tag is detected while the UI is on a non-dashboard page
  (Settings, AMS, Write Tag, Calibration), automatically navigate back
  to the main dashboard to display the scanned spool. Also wakes the
  screen if the display blank timeout had kicked in.
2026-03-26 10:38:25 +01:00
maziggy 45892077ab Add material/profile mismatch warnings to SpoolBuddy Assign-to-AMS modal
The AssignToAmsModal was missing all material/profile validation guards
  that exist in the main AssignSpoolModal. Clicking an AMS slot now checks
  the spool's material and slicer profile against the target slot's current
  filament, showing a confirmation dialog on mismatch. Respects the global
  disable_filament_warnings setting. Uses existing i18n keys and ConfirmModal.
2026-03-26 09:23:42 +01:00
maziggy c52ff1dcee Add Unassign button to edit spool modal
Allows removing a spool's AMS slot assignment directly from the
  edit modal, clearing the location column in the inventory table.
2026-03-25 14:14:40 +01:00
maziggy 91320e76d3 Clear all tag fields when deleting tag from spool
Delete Tag only cleared tag_uid, leaving tray_uuid, tag_type, and
  data_origin as stale data. Now sends all four fields as null.
2026-03-25 14:06:39 +01:00
maziggy 88c0503009 Show spool notes as hover tooltip in Assign Spool modal (#793) 2026-03-25 08:55:06 +01:00
maziggy c9efa4b8bb Fix stale AMS slot data and empty slot button visibility (#784)
Some printers (e.g. H2D) only send {id, state} in incremental MQTT
  tray updates — no tray_type, tray_color, or other fields. When
  filament is unloaded (state changes from 11 to 10), the old tray
  data persisted indefinitely because the merge logic only updates
  fields present in the incoming message.

  Backend:
  - Detect tray state != 11 without tray_type in incremental updates
    and clear stale tray data (bambu_mqtt.py)
  - Expose tray `state` field via REST API and WebSocket broadcasts
    (printer.py schema, printers.py route, printer_manager.py)
  - Include AMS tray content in WebSocket dedup key so load/unload
    transitions trigger broadcasts (main.py)

  Frontend:
  - Add `state` to AMSTray interface (client.ts)
  - Show configure/assign buttons for state=10 (spool present, not
    loaded) but hide for state=9 (truly empty) on AMS/HT slots
  - Hide fill level bar on empty slots

  Tests:
  - 5 new tests covering state-based clearing, preservation, reload,
    and idempotency
2026-03-24 16:03:34 +01:00
Keybored 6e648804fc [Feature] Spoolbuddy Fixes and Improvements (#787)
[Feature] Spoolbuddy Fixes and Improvements (#787)
2026-03-24 11:56:33 +01:00
Keybored 3f7d0e2d55 Add notification for no spool assigned for active trays, improve usage tracker logic in edge cases (#789)
Add notification for no spool assigned for active trays, improve usage tracker logic in edge cases (#789)
2026-03-24 11:31:32 +01:00
maziggy 8be4bed384 Fix SpoolBuddy update UI responsiveness and stale data
Rewrote update button states: single `busy` flag stays set from click
  through to device pickup — no more gap with no feedback. Buttons hide
  while any operation is in progress. Listens for spoolbuddy-online
  WebSocket event to reload the page after daemon re-registers, ensuring
  fresh version and status. Set staleTime to 0 on update check queries.
2026-03-23 15:04:56 +01:00
maziggy 1f24bd264a Fix SpoolBuddy update UI feedback and stale query cache
- Check button now shows spinner on refetch (isFetching vs isLoading)
  - Force Update button shows spinner while triggering
  - Reduced staleTime from 4 minutes to 30 seconds so the UI picks up
    version changes after an update without a long delay
2026-03-23 14:48:10 +01:00
maziggy 511ece791a Fix SpoolBuddy update check comparing against GitHub releases instead of backend version
The SpoolBuddy daemon update endpoint fetched GitHub releases and compared
  them against device.firmware_version, which always showed "up to date"
  because the comparison source was wrong. Now compares directly against
  APP_VERSION from the running backend, so a daemon at 0.2.3b1 correctly
  sees 0.2.3 as an available update.
2026-03-23 12:05:20 +01:00
maziggy 40f0405ea0 Revert "Feature/multiple switches per prtinter (#786)"
This reverts commit 9e81f246d8.
2026-03-23 10:11:56 +01:00
ManuelW 9e81f246d8 Feature/multiple switches per prtinter (#786)
Feature/multiple switches per prtinter (#786)
2026-03-23 10:09:14 +01:00
maziggy 311a14e7ec Improve SpoolBuddy update UX: auto-check and remove beta toggle
The SpoolBuddy layout now auto-checks for daemon updates every 5
  minutes and shows "Update available: v{version}" in the status bar.
  Removed the beta toggle since SpoolBuddy follows Bambuddy's release
  channel. The daemon version is now read from backend APP_VERSION
  instead of a stale hardcoded string.
2026-03-22 13:15:44 +01:00
maziggy d6e883652d Misc Spoolbuddy frontend fixes 2026-03-22 11:34:21 +01:00
maziggy 1b3faca4c7 Add checkboxes to select plates to queue (#777)
Multi-plate 3MF files now support selecting a subset of plates to queue
  via checkboxes, instead of the binary "one plate" or "all plates" toggle.
  In add-to-queue mode, each plate gets a checkbox for multi-select with a
  Select All / Deselect All toggle. Reprint and edit modes remain single-select.
2026-03-22 07:51:47 +01:00
maziggy 7b88b50d27 Fix AMS slot search still showing wrong preset for PLA Silk (#681)
The saved preset bypassed the search filter entirely, so when a slot's
  DB mapping was stale (e.g. previously Matte, now physically Silk), the
  old preset always appeared regardless of search query. Remove the search
  bypass — saved/current presets still bypass the printer model filter but
  must match the search text like all other presets.
2026-03-21 14:08:30 +01:00
Thomas Rambach 2cac7d0172 Feature: Admin Set Default Nav-Menu Order (#761)
Feature: Admin Set Default Nav-Menu Order (#761)
2026-03-21 09:30:18 +01:00
maziggy dc4d77b93a [Feature] Redesign bug report debug log capture flow
Replace fixed 30-second debug log collection with an interactive
  3-step flow: start logging, reproduce the issue, stop & submit.
  Users now control timing instead of racing a countdown.

  Backend: split _collect_debug_logs() into POST /start-logging and
  POST /stop-logging endpoints; add debug_logs field to submit request.
  Frontend: 3-step progress indicator with elapsed timer, pulsing
  active state, and 5-minute auto-stop. Updated all 7 locale files.
2026-03-20 14:18:24 +01:00
mrtncode 7e0f52ebb0 Improve Home Assistant notifications (#750)
Improve Home Assistant notifications (#750)
2026-03-20 11:10:43 +01:00
maziggy c5a0651172 Fix AMS slot search showing unrelated filament profiles (#681)
When searching for a non-existent profile in the AMS slot config modal,
  presets matching the current slot's tray_info_idx bypassed the search
  filter, showing e.g. all "Generic PLA" variants instead of no results.
  Narrow the search bypass to only the exact saved preset — the broader
  trayIdx match still bypasses the model filter as intended.
2026-03-19 08:29:03 +01:00
maziggy dcdebef9a8 [Fix] Spool assignment UI shows wrong filament preset name (#681)
After assigning a spool to an AMS slot, the Bambuddy UI could show the
  wrong filament preset (e.g. "Bambu PLA Matte" instead of "Bambu PLA
  Silk") even though the printer was configured correctly.

  Two bugs:
  1. AssignSpoolModal (PrintersPage hover card path) never saved the slot
     preset mapping to the DB, so the display fell back to the old/stale
     mapping from a previous manual configuration.
  2. AssignToAmsModal (SpoolBuddy path) constructed the preset name from
     spool.material + spool.subtype ("PLA Silk") instead of using the
     authoritative spool.slicer_filament_name ("Bambu PLA Silk").

  Fix: the backend now saves the slot preset mapping in assign_spool()
  after successful MQTT configuration, using slicer_filament_name as the
  display name. This covers both frontend paths and ensures the correct
  name is always stored.
2026-03-18 08:12:08 +01:00
maziggy 6be5fa6632 [Fix] Camera window overlapping modals (#738)
Floating camera viewer used z-50, same as all modals, causing it to
  render on top of dialogs like Assign Spool. Lowered to z-40 so modals
  always stack above the camera window.
2026-03-17 16:40:16 +01:00
maziggy 4f617c21e1 [Fix] X1C Virtual Printer not accepting sends (#735)
X1C and X1 virtual printers used legacy SSDP model codes
  (3DPrinter-X1-Carbon, 3DPrinter-X1) that BambuStudio doesn't
  recognize, causing "incompatible printer preset" errors when
  sending prints. Changed to the correct codes (BL-P001, BL-P002)
  that real printers report via SSDP.

  Also fixed proxy mode auto-inherit storing printer display names
  (e.g. "X1C") instead of SSDP codes, by adding a resolution layer
  that maps display names to model codes.

  DB migration auto-converts existing VPs on startup.
2026-03-17 16:25:31 +01:00
maziggy fe3c1983af Add camera image rotation option (#672)
Per-printer camera rotation (0°/90°/180°/270°) for cameras mounted
  in portrait or upside-down. CSS rotation for live views, Pillow
  rotation for notification snapshots. Setting visible in external
  camera config when enabled.
2026-03-17 13:59:01 +01:00
maziggy a4006408a2 Fix white filament color swatches invisible in light theme (#726)
Changed filament color circle borders from border-white/20 to
  border-black/20 across all views so white spools are distinguishable
  against light backgrounds.
2026-03-17 13:08:04 +01:00
maziggy 11610a5b48 Compact assign spool modal grid layout (#725)
- Change spool list from vertical to 3-column grid (2-col on small screens)
  - Widen modal from max-w-md to max-w-2xl
  - Increase scroll area from max-h-64 to max-h-96
  - Show compact cards with name, color dot, and remaining/total weight
2026-03-17 12:40:38 +01:00
maziggy 7ab9b3e39f Fix mobile sidebar scroll, lint errors, and add tests for (#724)
- Fix mobile sidebar not scrollable when nav items exceed viewport
2026-03-17 12:31:11 +01:00
Thomas Rambach 9562d66b6b Feature: Advanced Authentication User Email Notifications (#693)
Feature: Advanced Authentication User Email Notifications (#693)
2026-03-17 12:01:18 +01:00
Dakota G ac7cfe2930 [Fix]: Send Bambu RFID Tags to Spoolman, Allow Unlink in Manual Mode, Stop Location Clearing for Generic Spools (#719)
[Fix]: Send Bambu RFID Tags to Spoolman, Allow Unlink in Manual Mode, Stop Location Clearing for Generic Spools (#719)
2026-03-16 15:45:06 +01:00
Keybored 3ca91eb6d1 [Feature] Add material mismatch and insufficient filament checks (#720)
[Feature] Add material mismatch and insufficient filament checks (#720)
2026-03-16 15:30:36 +01:00
maziggy b889de91ba Allow spool assignment to empty AMS slots and fix profile label (#717)
Previously the "Assign Spool" button only appeared on configured slots,
  forcing users to manually configure first — redundant since assignment
  auto-configures the slot. Now shows on empty slots too. Also fixed the
  AMS hover card showing generic material type instead of the spool's
  slicer preset name after assignment.
2026-03-16 09:24:04 +01:00
maziggy fa6edfbcde Fix stored XSS vulnerabilities and unauthenticated auth toggle
- Sanitize project notes with DOMPurify before rendering via
    dangerouslySetInnerHTML (ProjectDetailPage.tsx)
  - Replace hand-rolled HTML sanitizer with DOMPurify in ProjectPageModal
    to prevent attribute injection via crafted 3MF href values
  - Block /api/v1/auth/setup when auth is already enabled to prevent
    unauthenticated clients from disabling authentication remotely
2026-03-15 15:31:49 +01:00
maziggy bbc5ccb982 Library Upload Doesn't Show New File Until Page Reload ([#704](https://github.com/maziggy/bambuddy/issues/704)) — After uploading a file in the Library file manager, the file list didn't update until the user reloaded the browser. The upload endpoint used db.flush() instead of db.commit(), so the new row was only written to the database *after* the response was sent to the client. The frontend immediately refetched the file list upon receiving the response, but a new database session couldn't see the uncommitted row — resulting in stale data. Fixed by committing before the response is returned. Also fixed the same race condition in folder create, folder update, and file update endpoints. Reported by @shadowjig.
Printer File Manager Doesn't Auto-Refresh ([#704](https://github.com/maziggy/bambuddy/issues/704)) — The printer file manager (SD card browser) only fetched the file list once when opened. Files uploaded from BambuStudio/OrcaSlicer while the modal was open wouldn't appear until the user clicked the refresh button or reopened the modal. Now auto-refreshes every 30 seconds while open. Reported by @shadowjig.

Database Connection Pool Exhaustion Under Load ([#704](https://github.com/maziggy/bambuddy/issues/704)) — Background tasks (print scheduler FTP uploads, camera captures, notification sends, timelapse stitching) held database sessions open during slow network I/O, consuming connection pool slots for seconds at a time. With the default pool of 15 connections (size 5 + overflow 10), concurrent operations during print start/complete events could exhaust the pool, causing `QueuePool limit reached` errors and `greenlet_spawn` failures in RFID spool auto-assignment. Doubled the pool to 30 connections (size 10 + overflow 20). Reported by @shadowjig.
2026-03-15 09:15:18 +01:00
Dakota G 30b34bc255 [Fix]: Changes SMTP testing to use saved settings in the database (#710)
[Fix]: Changes SMTP testing to use saved settings in the database (#710)
2026-03-15 09:13:47 +01:00
Dakota G 47afcec1c5 [Fix]: Allow SMTP to be configured before Advanced Authentication is enabled (#700)
[Fix]: Allow SMTP to be configured before Advanced Authentication is enabled (#700)
2026-03-14 11:34:34 +01:00
maziggy 5a4a2260b1 Fix PA-CF/PA12-CF/PAHT-CF type matching and force color match click target (#688)
Bambu Lab firmware treats PA-CF, PA12-CF, and PAHT-CF as interchangeable,
  but the print scheduler and filament override UI used exact string matching.
  A 3MF requiring PA-CF wouldn't match PA12-CF in the AMS, leaving the
  override dropdown disabled and preventing scheduler assignment.

  Add a filament type equivalence system (both backend and frontend) so
  these PA variants are treated as compatible in scheduler assignment,
  AMS slot matching, force color match validation, and the override dropdown.

  Also fix the "Force color match" checkbox click target being too wide
  (entire row instead of just the checkbox/label) by changing flex to
  inline-flex on the label element.
2026-03-13 12:56:31 +01:00
maziggy cfec18eca4 Fix floating camera drag/resize not working on iOS/iPadOS (#687)
The embedded camera viewer only handled mouse events (mousedown,
  mousemove, mouseup) for window dragging and resizing. On iOS/iPadOS,
  touch input doesn't trigger mouse events, so the camera window
  couldn't be repositioned — touch just scrolled the page underneath.

  Add touch event handlers (touchstart, touchmove, touchend, touchcancel)
  alongside mouse handlers for both the header drag handle and the
  bottom-right resize handle. Uses preventDefault on touchmove to
  prevent page scrolling during drag.
2026-03-13 12:44:51 +01:00
maziggy adb0500e67 Fix AMS fill level showing 0% for non-Viewer users (#676)
When inventory spool assignments had stale weight_used values, the fill
  level fallback chain (Spoolman → Inventory → AMS remain) used nullish
  coalescing (??), which doesn't fall through on 0. A stale inventory
  fill of 0% permanently shadowed the correct real-time AMS remain value.
  Viewer users were unaffected because their group lacked the
  inventory:view_assignments permission, so the query never fired.

  Now when inventory says 0% but AMS hardware reports positive remain,
  the inventory value is bypassed in favor of the live AMS data.
2026-03-13 11:21:37 +01:00