mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-18 21:47:39 +02:00
fix(filament): don't dispatch an unresolved AMS mapping to the external spool (#2589)
A P1S queue row with use_ams=true but ams_mapping=[-1] was silently printed with no AMS, starting against the empty external feed and pausing with a runout. Two faults combined: - start_print treated -1 (unresolved) the same as >=254 (explicit external) when deciding to force use_ams=False. Only genuine external now downgrades; -1 never does. - The scheduler trusted a stored [-1] as "already resolved" and passed it through. It now recomputes from live AMS trays whenever the stored mapping is entirely unresolved, and clears it if nothing matches rather than sending a doomed command. Frontend: the Print dialog no longer serializes an all-[-1] mapping while the printer status is still loading (the hook returns no mapping), and submit waits for AMS status with a "Waiting for AMS status" notice. Tests: new backend + frontend regression coverage; corrected one existing test that pinned the old [-1] -> use_ams=False behavior.
This commit is contained in:
@@ -372,7 +372,7 @@ export function PrintModal({
|
||||
});
|
||||
|
||||
// Only fetch printer status when single printer selected (for filament mapping)
|
||||
const { data: printerStatus } = useQuery({
|
||||
const { data: printerStatus, isLoading: printerStatusLoading } = useQuery({
|
||||
queryKey: ['printer-status', effectivePrinterId],
|
||||
queryFn: () => api.getPrinterStatus(effectivePrinterId!),
|
||||
enabled: !!effectivePrinterId,
|
||||
@@ -1100,6 +1100,12 @@ export function PrintModal({
|
||||
// the rest — the banner above says which state we are in.
|
||||
if (perPlateReqsPending || perPlateReqsFailed) return false;
|
||||
|
||||
// A single-printer AMS job must wait for the printer's live status before it
|
||||
// can resolve the filament mapping. Submitting mid-load matched against zero
|
||||
// known trays and serialized an all-[-1] mapping, which dispatched the print
|
||||
// to the empty external feed (#2589).
|
||||
if (assignmentMode === 'printer' && selectedPrinters.length === 1 && printerStatusLoading) return false;
|
||||
|
||||
return true;
|
||||
}, [
|
||||
selectedPrinters.length,
|
||||
@@ -1111,6 +1117,7 @@ export function PrintModal({
|
||||
isPending,
|
||||
perPlateReqsPending,
|
||||
perPlateReqsFailed,
|
||||
printerStatusLoading,
|
||||
]);
|
||||
|
||||
// Quantity only applies for single-printer or model-based assignment (not multi-printer)
|
||||
@@ -1482,6 +1489,17 @@ export function PrintModal({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Waiting for the printer's AMS status: submitting now would map
|
||||
against zero known trays and dispatch to the empty external feed (#2589). */}
|
||||
{assignmentMode === 'printer' && selectedPrinters.length === 1 && printerStatusLoading && (
|
||||
<div className="mb-4 p-3 bg-blue-100 dark:bg-blue-500/20 border border-blue-500/50 rounded-lg text-sm text-blue-700 dark:text-blue-400 flex items-center gap-2">
|
||||
<Loader2 className="w-4 h-4 animate-spin" />
|
||||
{t('printModal.waitingForAmsStatus', {
|
||||
printer: printers?.find((p) => p.id === effectivePrinterId)?.name ?? '',
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Actions */}
|
||||
<div className="flex gap-3 pt-2">
|
||||
<Button type="button" variant="secondary" onClick={onClose} className="flex-1" disabled={isSubmitting}>
|
||||
|
||||
Reference in New Issue
Block a user