mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-09 07:25:44 +02:00
Hide unnecessary target model selector on "Any" tab (#528)
When scheduling a print to "Any {model}", a redundant "Target Model"
dropdown appeared even though the G-code is already sliced for a
specific printer model. Changing it would lead to print failures.
Hide the dropdown when slicedForModel is known — the tab label already
communicates the target. The dropdown still appears as a fallback for
legacy files without model metadata.
This commit is contained in:
@@ -5,6 +5,7 @@ All notable changes to Bambuddy will be documented in this file.
|
||||
## [0.2.1] - Unreleased
|
||||
|
||||
### Fixed
|
||||
- **Unnecessary Target Model Selector on "Any" Tab** ([#528](https://github.com/maziggy/bambuddy/issues/528)) — When scheduling a print to "Any {model}", a redundant "Target Model" dropdown appeared even though the G-code is already sliced for a specific printer model. Changing the target model would lead to print failures. The dropdown is now hidden when the sliced model is known (the tab label already shows "Any {model}"). It still appears as a fallback for legacy files without model metadata.
|
||||
- **"Clear Plate & Start Next" Button Shown on Printers Without Correct Filament** ([#527](https://github.com/maziggy/bambuddy/issues/527)) — When a print job was queued for "any printer" of a model (e.g., "any H2S"), the "Clear Plate & Start Next" button appeared on ALL printers of that model, including those without the required filament loaded. Clicking it on a printer without the right filament would start a print that fails. The `PrinterQueueWidget` now filters queue items by filament compatibility — it checks the printer's loaded filament types (from AMS and external spools) against the queue item's `required_filament_types` and only shows items the printer can actually print. If no compatible items exist, the widget is hidden.
|
||||
- **Manual Spool Weight Overwritten by AMS Auto-Sync** ([#525](https://github.com/maziggy/bambuddy/issues/525)) — When a user manually entered a spool weight (via UI or API), the value was overwritten by the automatic AMS remain% sync that runs on every MQTT update. The AMS remain% is integer-only (~10g resolution for 1kg spool) and can't match precise manual entries. Added a `weight_locked` flag that is automatically set when `weight_used` is explicitly updated via the API. Locked spools are skipped by both the automatic AMS remain% sync and the manual force-sync endpoint. The usage tracker (3MF/gcode delta tracking) is unaffected. Users can re-enable AMS sync by setting `weight_locked: false`.
|
||||
- **Inconsistent Print Cost on Reprints** ([#505](https://github.com/maziggy/bambuddy/issues/505)) — Reprinting the same model produced different costs each time (e.g., £0.77, £1.54, £2.03 for the same print). Three independent code paths wrote to `archive.cost` with conflicting strategies: the usage tracker summed ALL historical `SpoolUsageHistory` rows for the archive (including rows from previous reprints), and a separate `add_reprint_cost` method added yet another full print's cost on top. Removed the redundant `add_reprint_cost` path entirely and changed the usage tracker to compute cost only from the current print session's results instead of querying all historical rows. `archive.cost` now always reflects the cost of a single print.
|
||||
|
||||
@@ -51,7 +51,7 @@ def event_loop():
|
||||
loop = asyncio.get_event_loop_policy().new_event_loop()
|
||||
yield loop
|
||||
# Drain pending callbacks so aiosqlite threads can finish before loop closes
|
||||
loop.run_until_complete(asyncio.sleep(0.05))
|
||||
loop.run_until_complete(asyncio.sleep(0.1))
|
||||
loop.close()
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ async def test_engine():
|
||||
# Allow aiosqlite's background thread to finish processing the close
|
||||
# response before the per-function event loop shuts down, preventing
|
||||
# "RuntimeError: Event loop is closed" in call_soon_threadsafe.
|
||||
await asyncio.sleep(0.05)
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
||||
@@ -389,28 +389,30 @@ export function PrinterSelector({
|
||||
{/* Model selection and location filter (when in model mode) */}
|
||||
{assignmentMode === 'model' && modelAssignmentAvailable && (
|
||||
<div className="space-y-3 mb-4">
|
||||
{/* Model selector */}
|
||||
<div>
|
||||
<label className="block text-xs text-bambu-gray mb-1">Target Model</label>
|
||||
<select
|
||||
value={targetModel || ''}
|
||||
onChange={(e) => {
|
||||
onTargetModelChange!(e.target.value || null);
|
||||
// Clear location when model changes
|
||||
if (onTargetLocationChange) {
|
||||
onTargetLocationChange(null);
|
||||
}
|
||||
}}
|
||||
className="w-full px-3 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white focus:border-bambu-green focus:outline-none text-sm"
|
||||
>
|
||||
<option value="">Select a model...</option>
|
||||
{uniqueModels.map((model) => (
|
||||
<option key={model} value={model}>
|
||||
{model}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
{/* Model selector — only show when sliced model is unknown */}
|
||||
{!slicedForModel && (
|
||||
<div>
|
||||
<label className="block text-xs text-bambu-gray mb-1">Target Model</label>
|
||||
<select
|
||||
value={targetModel || ''}
|
||||
onChange={(e) => {
|
||||
onTargetModelChange!(e.target.value || null);
|
||||
// Clear location when model changes
|
||||
if (onTargetLocationChange) {
|
||||
onTargetLocationChange(null);
|
||||
}
|
||||
}}
|
||||
className="w-full px-3 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white focus:border-bambu-green focus:outline-none text-sm"
|
||||
>
|
||||
<option value="">Select a model...</option>
|
||||
{uniqueModels.map((model) => (
|
||||
<option key={model} value={model}>
|
||||
{model}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Location filter (only show when target model is selected and locations exist) */}
|
||||
{targetModel && uniqueLocations.length > 0 && onTargetLocationChange && (
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -23,7 +23,7 @@
|
||||
|
||||
<!-- Splash screens for iOS -->
|
||||
<link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
|
||||
<script type="module" crossorigin src="/assets/index-D6vc8KCS.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-BXXkRrQK.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-1Ts9jjQl.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in New Issue
Block a user