Feat/spoolman qol - #295
Conversation
There was a problem hiding this comment.
What's good
- The spool lists show a "No spools found" message instead of a blank panel, with the active material filter in the text.
setFilternow assigns_material_filterbeforereset(), a real fix: the old order fetched with the previous filter.SpoolmanPagecan create a manufacturer, and the new relay resolves end to end.- Lot, weight and location stay disabled until a filament is picked, matching the submit gating already there.
reset()sets real defaults instead of"---", plus small cleanups likenot x == y->x != y.
1. filamentTab.py:642: the empty-state label is hidden above two early returns, so it never shows on the failure paths
on_spools_received hides the label, then returns on result["error"] and on a non-list response. Those are exactly the cases where the list ends up empty, so the user gets a blank panel with no message:
def on_spools_received(self, result: dict) -> None:
self._spool_load_widget.hide()
self._spool_list_view.show()
self.reset_spool_info()
if result.get("error") is not None:
self._no_spools_label.setText("Could not reach Spoolman")
self._no_spools_label.show()
return2. addFilamentPage.py:280: mousePressEvent is monkey-patched onto a QLabel instance
This is now the only way to open the wheel (_color_field.clicked.connect was removed and _color_field is a plain QLabel). The patch swallows the event, gives no press feedback, and is invisible to anyone reading the class. BlocksLabel already has a clicked signal:
self._color_swatch = BlocksLabel(left_frame)
self._color_swatch.clicked.connect(self._open_color_wheel)3. addFilamentPage.py:150: _set_color returns silently on a malformed hex
The caller can't tell the value was rejected, and _color_hex keeps the previous colour while the swatch and label stay stale:
hex_text = hex_str.strip().lstrip("#")
if len(hex_text) != 6 or not QtGui.QColor(f"#{hex_text}").isValid():
logging.warning("ignoring invalid colour hex: %r", hex_str)
return4. addFilamentPage.py:197: request_filament_body is created inside _on_sub
It has no __init__ declaration, so a manufacturer result that arrives without a matching submit raises AttributeError inside a slot (:206), which PyQt turns into qFatal(). A second
result re-emits the previous body with a new vendor_id. Pre-existing on devlive from SpoolmanPage.
# __init__
self.request_filament_body: dict | None = None
# on_add_manufacturer_result
if self.request_filament_body is None:
return
body, self.request_filament_body = self.request_filament_body, None
body["vendor_id"] = vendor_id
self.request_add_filament.emit(body)5. addFilamentPage.py:209 and :81: both error branches are bare ...
A rejected vendor or filament leaves the page sitting there with no message andiled, so the user taps again and creates a duplicate:
else:
self.failed.emit(str(result["error"]))6. addSpoolPage.py:94 / spoolmanPage.py:201: the action rows became leading-ss missed
" New Filament" / " Add Spool" are matched by exact text, so any trim in the model or delegate turns the row into a dead tap. filamentTab.py:657 still adds "+ Add Spool", so the two
spool lists now disagree. A flag on the item is safer than matching text:
@dataclass
class ListItem:
...
is_action: bool = False
if item.is_action:
self.open_add_filament.emit()
return7. addFilamentPage.py:175: _on_submit has no guard on the required name
The button is always enabled and an empty name just omits the key, so the POST goes out malformed and lands in the silent error branch from item 5:
if not name:
return
body["name"] = name**8. addFilamentPage.py:269: _color_field is fed HTML but relies on QLabel'
It works today because mightBeRichText() sees the markup, but it's one string edit away from rendering raw <span> tags:
self._color_field.setTextFormat(QtCore.Qt.TextFormat.RichText)9. spoolmanPage.py:243: inconsistent empty-state wording
The two other sites put the active filter in the message, this one shows the static "No spools found" set at build time:
self._no_spools_label.setText(
f'No spools found for "{self._material_filter}"' if self._material_filter e
)
self._no_spools_label.show()10. addFilamentPage.py:196: a repeat vendor name creates a duplicate Spoolman vendor
The vendor create is unconditional, so typing an existing manufacturer adds a sme. Look it up first and only create on a miss:
# resolve first, create only on miss
self.request_find_manufacturer.emit({"name": vendor_text})
Description
BlocksScreen/lib/panels/filamentTab.py
BlocksScreen/lib/panels/widgets/addFilamentPage.py
BlocksScreen/lib/panels/widgets/addSpoolPage.py
BlocksScreen/lib/panels/widgets/spoolmanPage.py