feat: Add quick wins batch (#42, #43, #25, #35, #20, #36, #39)
Some checks failed
CI / style (push) Has been cancelled
CI / build-client (push) Has been cancelled
CI / build-amd64 (push) Has been cancelled
CI / build-tester (push) Has been cancelled
CI / test (cockroachdb) (push) Has been cancelled
CI / test (mariadb) (push) Has been cancelled
CI / test (postgres) (push) Has been cancelled
CI / test (sqlite) (push) Has been cancelled
CI / build-arm64 (push) Has been cancelled
CI / build-armv7 (push) Has been cancelled
CI / publish-images (push) Has been cancelled
CI / publish-release (push) Has been cancelled

- #42: Allow spools heavier than theoretical max (remove weight clamps)
- #43: Show filament custom fields on spool detail page
- #25: Sort spools by custom fields and remaining weight
- #35: Global search box for spool list
- #20: Gallery view for spools (color grid with progress bars)
- #36: Spool-level color override with ColorPicker
- #39: Cost analytics endpoint, total spent & avg cost/kg stats
- Fix: Filament select refresh after inline creation
- Fix: Parse temperatures from filament comments

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-22 23:09:42 -06:00
parent 5f66302e73
commit 801d3da02a
18 changed files with 524 additions and 45 deletions

View File

@@ -317,6 +317,12 @@ class Spool(BaseModel):
description=("Extra weight to account for, such as DryPods, custom spool holders, etc."),
examples=[50],
)
color_hex: Optional[str] = Field(
default=None,
max_length=8,
description="Spool-level color override (hex code without #). Overrides the filament color if set.",
examples=["FF0000"],
)
used_weight: float = Field(
ge=0,
description="Consumed weight of filament from the spool in grams.",
@@ -381,14 +387,14 @@ class Spool(BaseModel):
remaining_length: Optional[float] = None
if item.initial_weight is not None:
remaining_weight = max(item.initial_weight - item.used_weight, 0)
remaining_weight = item.initial_weight - item.used_weight
remaining_length = length_from_weight(
weight=remaining_weight,
density=filament.density,
diameter=filament.diameter,
)
elif filament.weight is not None:
remaining_weight = max(filament.weight - item.used_weight, 0)
remaining_weight = filament.weight - item.used_weight
remaining_length = length_from_weight(
weight=remaining_weight,
density=filament.density,