Browse Source

fix(slice-modal): disable Slice button until preview slice resolves

  Until the preview slice / embedded-metadata read returns the per-plate
  filament list, the modal renders a synthetic single-slot fallback so
  the auto-pick has something to bind against. That made the Slice button
  enabled the moment the modal opened, even before the slicer had told us
  which AMS slots the plate actually consumes — clicking would dispatch
  against opaque defaults.

  Add filamentReqsQuery.isSuccess to the isReady chain so the button
  stays disabled while the preview slice is in flight (or before the
  backend's /filament-requirements call settles for sliced files) and
  flips to enabled the moment the real slot list lands and auto-pick
  fills it.
maziggy 3 weeks ago
parent
commit
a64cfbbd36

+ 2 - 1
frontend/src/__tests__/components/SliceModal.test.tsx

@@ -138,7 +138,8 @@ describe('SliceModal', () => {
     expect(selects[1].value).toBe('local:2');
     expect(selects[2].value).toBe('local:3');
 
-    // Slice button is enabled because all three slots auto-defaulted.
+    // Slice button is enabled because all three slots auto-defaulted and
+    // the preview-slice query has resolved (mock returns immediately).
     const sliceBtn = screen.getByRole('button', { name: /^Slice$/ });
     expect((sliceBtn as HTMLButtonElement).disabled).toBe(false);
   });

+ 11 - 5
frontend/src/components/SliceModal.tsx

@@ -407,14 +407,20 @@ export function SliceModal({ source, onClose }: SliceModalProps) {
     !!printerProfileName &&
     !printerProfileName.toLowerCase().includes(sourcePrinterModel.toLowerCase());
 
-  // Slice button stays disabled while the printer mismatch warning is
-  // visible: clicking it would silently fall back to embedded settings and
-  // produce a wrong-printer file, the exact UX bug the warning is here to
-  // prevent. Only re-enable when the user picks a matching profile (or
-  // cloud preset whose name we can't parse).
+  // Slice button stays disabled until *all* of these hold:
+  //   - the preview slice / embedded-metadata read has succeeded so we know
+  //     the per-plate filament slot list is final
+  //     (filamentReqsQuery.isSuccess). Without this gate the synthetic
+  //     single-slot fallback would auto-enable the button on opaque
+  //     defaults, before the slicer has even returned the real slot map.
+  //   - printer + process picked, every filament slot has a profile (the
+  //     auto-pick fills these once filamentSlots arrives)
+  //   - no printer-mismatch warning is up (clicking would silently fall
+  //     back to embedded settings and produce a wrong-printer file)
   const isReady =
     printerPreset != null &&
     processPreset != null &&
+    filamentReqsQuery.isSuccess &&
     filamentPresets.length > 0 &&
     filamentPresets.every((r) => r != null) &&
     !printerMismatch;

File diff suppressed because it is too large
+ 0 - 0
static/assets/index-B--K0Euf.js


+ 1 - 1
static/index.html

@@ -26,7 +26,7 @@
 
     <!-- Splash screens for iOS -->
     <link rel="apple-touch-startup-image" href="./img/android-chrome-512x512.png" />
-    <script type="module" crossorigin src="./assets/index-B2mJSviN.js"></script>
+    <script type="module" crossorigin src="./assets/index-B--K0Euf.js"></script>
     <link rel="stylesheet" crossorigin href="./assets/index-CzFVl3Rw.css">
   </head>
   <body>

Some files were not shown because too many files changed in this diff