fix(assign-spool): refresh printer status after assignment so card updates without manual Force-refresh (#1414 follow-up)

Reporter (@snozzlebert on A1 mini external slot) saw the
  Filament page Location column update correctly after Assign
  Spool, but the Printer card kept showing "Empty slot" until
  they manually pressed Force-refresh. MQTT command was going
  through fine; gap was client-side.

  AssignSpoolModal's two onSuccess callbacks invalidated the
  inventory / slot-assignment queries but never invalidated
  ['printerStatus', printerId] and never issued a pushall. For
  Bambu RFID-tagged spools the printer echoes the new tray_type
  on its own; for non-RFID spools and A1 mini external slots
  the firmware doesn't volunteer that state change.

  Added nudgePrinterRepublish() helper called from both onSuccess
  paths: api.refreshPrinterStatus(printerId) to issue the pushall
  (same call the Force-refresh button uses) plus invalidate
  printerStatus so the refetch lands. Refresh failures are
  swallowed — the assignment itself succeeded; a stale-cache
  nudge that didn't go through shouldn't surface as "assign
  failed". Same pattern as ConfigureAmsSlotModal since #1235,
  with the extra pushall because assign-spool affects firmware-
  side state.
This commit is contained in:
maziggy
2026-05-19 11:41:53 +02:00
parent 9c934c905d
commit 9bcaafbc1a
5 changed files with 123 additions and 67 deletions
@@ -113,6 +113,20 @@ export function AssignSpoolModal({ isOpen, onClose, printerId, amsId, trayId, tr
);
}, [allSpoolmanAssignments, printerId, amsId, trayId]);
// #1414: nudge the printer to republish its state after we assign a
// spool. The backend assign-spool path already issues an MQTT command,
// but firmware (especially A1 mini external slots and any non-RFID
// assignment) doesn't always echo the new tray state back on its own,
// so the printer card sits on stale data and the user has to press
// Force-refresh to see the assignment. Calling /refresh-status forces
// a pushall the way the Force-refresh button does. Failures are
// intentionally swallowed — the assignment itself succeeded; if the
// refresh is offline the next poll / websocket update will catch up.
const nudgePrinterRepublish = () => {
api.refreshPrinterStatus(printerId).catch(() => {});
queryClient.invalidateQueries({ queryKey: ['printerStatus', printerId] });
};
const assignMutation = useMutation({
mutationFn: (spoolId: number) =>
api.assignSpool({ spool_id: spoolId, printer_id: printerId, ams_id: amsId, tray_id: trayId }),
@@ -126,6 +140,7 @@ export function AssignSpoolModal({ isOpen, onClose, printerId, amsId, trayId, tr
return filtered;
});
queryClient.invalidateQueries({ queryKey: ['spool-assignments'] });
nudgePrinterRepublish();
showToast(t('inventory.assignSuccess'), 'success');
setShowMismatchConfirm(false);
setPendingAssignId(null);
@@ -148,6 +163,7 @@ export function AssignSpoolModal({ isOpen, onClose, printerId, amsId, trayId, tr
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['spoolman-inventory-spools'] });
queryClient.invalidateQueries({ queryKey: ['spoolman-slot-assignments'] });
nudgePrinterRepublish();
showToast(t('inventory.assignSuccess'), 'success');
onClose();
},