mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-20 17:50:12 +02:00
change(workflow): default Plate-Clear Confirmation to off on fresh installs
New users repeatedly reported queued prints "not starting" because the confirmation prompt was waiting on an ack they didn't know existed. Flip the default in the settings schema and in the frontend fallbacks so a missing/unset value reads as disabled. Existing installs keep their saved preference.
This commit is contained in:
@@ -58,7 +58,7 @@ describe('PrinterQueueWidget - Clear Plate', () => {
|
||||
|
||||
describe('clear plate button visibility', () => {
|
||||
it('shows clear plate button when printer state is FINISH', async () => {
|
||||
render(<PrinterQueueWidget printerId={1} printerState="FINISH" awaitingPlateClear={true} />);
|
||||
render(<PrinterQueueWidget printerId={1} printerState="FINISH" awaitingPlateClear={true} requirePlateClear={true} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Clear Plate & Start Next')).toBeInTheDocument();
|
||||
@@ -66,7 +66,7 @@ describe('PrinterQueueWidget - Clear Plate', () => {
|
||||
});
|
||||
|
||||
it('shows clear plate button when printer state is FAILED', async () => {
|
||||
render(<PrinterQueueWidget printerId={1} printerState="FAILED" awaitingPlateClear={true} />);
|
||||
render(<PrinterQueueWidget printerId={1} printerState="FAILED" awaitingPlateClear={true} requirePlateClear={true} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Clear Plate & Start Next')).toBeInTheDocument();
|
||||
@@ -128,7 +128,7 @@ describe('PrinterQueueWidget - Clear Plate', () => {
|
||||
// still awaiting plate-clear ack. The prompt must still show — the ack state, not
|
||||
// the reported printer state, is the authoritative signal.
|
||||
it('shows clear plate button in IDLE state when awaitingPlateClear is true (#961)', async () => {
|
||||
render(<PrinterQueueWidget printerId={1} printerState="IDLE" awaitingPlateClear={true} />);
|
||||
render(<PrinterQueueWidget printerId={1} printerState="IDLE" awaitingPlateClear={true} requirePlateClear={true} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Clear Plate & Start Next')).toBeInTheDocument();
|
||||
@@ -137,7 +137,7 @@ describe('PrinterQueueWidget - Clear Plate', () => {
|
||||
|
||||
it('shows clear plate button with no printerState when awaitingPlateClear is true', async () => {
|
||||
// State may be null briefly after a reconnect; the widget must still gate on the flag.
|
||||
render(<PrinterQueueWidget printerId={1} awaitingPlateClear={true} />);
|
||||
render(<PrinterQueueWidget printerId={1} awaitingPlateClear={true} requirePlateClear={true} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Clear Plate & Start Next')).toBeInTheDocument();
|
||||
@@ -166,7 +166,7 @@ describe('PrinterQueueWidget - Clear Plate', () => {
|
||||
describe('clear plate action', () => {
|
||||
it('shows confirmation state after clicking clear plate', async () => {
|
||||
const user = userEvent.setup();
|
||||
render(<PrinterQueueWidget printerId={1} printerState="FINISH" awaitingPlateClear={true} />);
|
||||
render(<PrinterQueueWidget printerId={1} printerState="FINISH" awaitingPlateClear={true} requirePlateClear={true} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Clear Plate & Start Next')).toBeInTheDocument();
|
||||
@@ -192,7 +192,7 @@ describe('PrinterQueueWidget - Clear Plate', () => {
|
||||
);
|
||||
|
||||
const user = userEvent.setup();
|
||||
render(<PrinterQueueWidget printerId={1} printerState="FAILED" awaitingPlateClear={true} />);
|
||||
render(<PrinterQueueWidget printerId={1} printerState="FAILED" awaitingPlateClear={true} requirePlateClear={true} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Clear Plate & Start Next')).toBeInTheDocument();
|
||||
@@ -264,6 +264,7 @@ describe('PrinterQueueWidget - Clear Plate', () => {
|
||||
printerId={1}
|
||||
printerState="FINISH"
|
||||
awaitingPlateClear={true}
|
||||
requirePlateClear={true}
|
||||
loadedFilamentTypes={new Set(['PLA', 'PETG'])}
|
||||
/>
|
||||
);
|
||||
@@ -281,6 +282,7 @@ describe('PrinterQueueWidget - Clear Plate', () => {
|
||||
printerId={1}
|
||||
printerState="FINISH"
|
||||
awaitingPlateClear={true}
|
||||
requirePlateClear={true}
|
||||
loadedFilamentTypes={new Set(['PLA'])}
|
||||
/>
|
||||
);
|
||||
@@ -297,7 +299,7 @@ describe('PrinterQueueWidget - Clear Plate', () => {
|
||||
);
|
||||
|
||||
render(
|
||||
<PrinterQueueWidget printerId={1} printerState="FINISH" awaitingPlateClear={true} />
|
||||
<PrinterQueueWidget printerId={1} printerState="FINISH" awaitingPlateClear={true} requirePlateClear={true} />
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
@@ -378,6 +380,7 @@ describe('PrinterQueueWidget - Clear Plate', () => {
|
||||
printerId={1}
|
||||
printerState="FINISH"
|
||||
awaitingPlateClear={true}
|
||||
requirePlateClear={true}
|
||||
loadedFilamentTypes={new Set(['PETG'])}
|
||||
/>
|
||||
);
|
||||
@@ -437,6 +440,7 @@ describe('PrinterQueueWidget - Clear Plate', () => {
|
||||
printerId={1}
|
||||
printerState="FINISH"
|
||||
awaitingPlateClear={true}
|
||||
requirePlateClear={true}
|
||||
loadedFilamentTypes={new Set(['PETG'])}
|
||||
loadedFilaments={new Set(['PETG:ffffff'])}
|
||||
/>
|
||||
@@ -591,12 +595,15 @@ describe('PrinterQueueWidget - Clear Plate', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('shows clear plate button when requirePlateClear is not provided (defaults to true)', async () => {
|
||||
it('shows passive link when requirePlateClear is not provided (defaults to false)', async () => {
|
||||
render(<PrinterQueueWidget printerId={1} printerState="FINISH" awaitingPlateClear={true} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Clear Plate & Start Next')).toBeInTheDocument();
|
||||
const link = screen.getByRole('link');
|
||||
expect(link).toHaveAttribute('href', '/queue');
|
||||
});
|
||||
|
||||
expect(screen.queryByText('Clear Plate & Start Next')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('still shows next item info in passive link when requirePlateClear is false', async () => {
|
||||
@@ -637,7 +644,7 @@ describe('PrinterQueueWidget - Clear Plate', () => {
|
||||
http.get('/api/v1/queue/', () => HttpResponse.json(mixedItems)),
|
||||
);
|
||||
|
||||
render(<PrinterQueueWidget printerId={1} printerState="FINISH" awaitingPlateClear={true} />);
|
||||
render(<PrinterQueueWidget printerId={1} printerState="FINISH" awaitingPlateClear={true} requirePlateClear={true} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Clear Plate & Start Next')).toBeInTheDocument();
|
||||
|
||||
@@ -20,7 +20,7 @@ interface PrinterQueueWidgetProps {
|
||||
loadedFilaments?: Set<string>; // "TYPE:rrggbb" pairs for filament override color matching
|
||||
}
|
||||
|
||||
export function PrinterQueueWidget({ printerId, printerModel, awaitingPlateClear, requirePlateClear = true, loadedFilamentTypes, loadedFilaments }: PrinterQueueWidgetProps) {
|
||||
export function PrinterQueueWidget({ printerId, printerModel, awaitingPlateClear, requirePlateClear = false, loadedFilamentTypes, loadedFilaments }: PrinterQueueWidgetProps) {
|
||||
const { t } = useTranslation();
|
||||
const queryClient = useQueryClient();
|
||||
const { showToast } = useToast();
|
||||
|
||||
@@ -1279,7 +1279,7 @@ function PrinterCard({
|
||||
onOpenEmbeddedCamera,
|
||||
checkPrinterFirmware = true,
|
||||
dryingPresets = DRYING_PRESETS,
|
||||
requirePlateClear = true,
|
||||
requirePlateClear = false,
|
||||
selectionMode = false,
|
||||
isSelected = false,
|
||||
onToggleSelect,
|
||||
@@ -6360,7 +6360,7 @@ export function PrintersPage() {
|
||||
onOpenEmbeddedCamera={(id, name) => setEmbeddedCameraPrinters(prev => new Map(prev).set(id, { id, name }))}
|
||||
checkPrinterFirmware={settings?.check_printer_firmware !== false}
|
||||
dryingPresets={effectiveDryingPresets}
|
||||
requirePlateClear={settings?.require_plate_clear !== false}
|
||||
requirePlateClear={settings?.require_plate_clear === true}
|
||||
selectionMode={selectionMode}
|
||||
isSelected={selectedPrinterIds.has(printer.id)}
|
||||
onToggleSelect={toggleSelect}
|
||||
@@ -6399,7 +6399,7 @@ export function PrintersPage() {
|
||||
onOpenEmbeddedCamera={(id, name) => setEmbeddedCameraPrinters(prev => new Map(prev).set(id, { id, name }))}
|
||||
checkPrinterFirmware={settings?.check_printer_firmware !== false}
|
||||
dryingPresets={effectiveDryingPresets}
|
||||
requirePlateClear={settings?.require_plate_clear !== false}
|
||||
requirePlateClear={settings?.require_plate_clear === true}
|
||||
selectionMode={selectionMode}
|
||||
isSelected={selectedPrinterIds.has(printer.id)}
|
||||
onToggleSelect={toggleSelect}
|
||||
|
||||
@@ -889,7 +889,7 @@ export function SettingsPage() {
|
||||
(settings.default_timelapse ?? false) !== (localSettings.default_timelapse ?? false) ||
|
||||
(settings.stagger_group_size ?? 2) !== (localSettings.stagger_group_size ?? 2) ||
|
||||
(settings.stagger_interval_minutes ?? 5) !== (localSettings.stagger_interval_minutes ?? 5) ||
|
||||
(settings.require_plate_clear ?? true) !== (localSettings.require_plate_clear ?? true);
|
||||
(settings.require_plate_clear ?? false) !== (localSettings.require_plate_clear ?? false);
|
||||
|
||||
if (!hasChanges) {
|
||||
return;
|
||||
@@ -3730,7 +3730,7 @@ export function SettingsPage() {
|
||||
<label className="relative inline-flex items-center cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={localSettings.require_plate_clear ?? true}
|
||||
checked={localSettings.require_plate_clear ?? false}
|
||||
onChange={(e) => updateSetting('require_plate_clear', e.target.checked)}
|
||||
className="sr-only peer"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user