Skip to content

feat(printing): filament label printing foundation - #846

Closed
akira69 wants to merge 11 commits into
Donkie:masterfrom
akira69:feat/filament-aml-printing
Closed

feat(printing): filament label printing foundation#846
akira69 wants to merge 11 commits into
Donkie:masterfrom
akira69:feat/filament-aml-printing

Conversation

@akira69

@akira69 akira69 commented Feb 12, 2026

Copy link
Copy Markdown
Contributor

Summary

filament label printing foundation

Provides a means to print labels for Filaments, not just spools. This is useful for labeling test coupons/filament color swatches that are not spool connected.

Print filaments

Note, further, earlier additional functionality that used to be inside this PR is moved to other PRs to limit scope and simplify review.

Code Quality Compliance ✅

Per https://github.com/Donkie/Spoolman/wiki/Contribute#style

  • ESLint (frontend) ✓
  • Prettier (frontend) ✓
  • Ruff (backend) ✓
  • Pre-commit hooks validated ✓

Included

  • Filament label printing entry points from filament list/show
  • Dedicated filament printing page + selection modal
  • Filament QR-code printing dialog and filament-specific print preset plumbing (print_presets_filament)
  • Spool presets remain on print_presets in this PR
  • Shared print dialog wiring for filament printing
  • Filament selector performance fix for large datasets (server pagination in selector table)
  • Clarified print page headers to show context (filament vs spool)
  • Filament pre-print selection UX now mirrors the same general selection-step pattern used by the spool-side selection UX PR (feat(printing/ui): Spool Print selection page UX Improvement #869):
    • backend-backed ?search= param across the full filament dataset (vendor name, name, material, article number, ID)
    • viewport-fill table height
    • visible pagination controls
    • bulk selection tied to visible rows
  • Changelog entry for printing updates

Latest Fixes

  • The filament selector now uses a single debounced ?search= API call for full-dataset search, consistent with the spool selector pattern in feat(printing/ui): Spool Print selection page UX Improvement #869. Searching for a vendor or material is no longer limited to the currently visible page.
  • The filament API endpoint now exposes a unified search query parameter (matching the spool API), backed by the existing _build_search_filters() helper.
  • Filament QR print dialogs now handle older or manually edited base_url settings without crashing when that value was stored as a plain string.

Code Quality Improvements 🔧

Performance Optimizations Applied:

  • Added useCallback memoization to selectUnselectFiltered, handleSelectItem, handlePageChange, and handlePageSizeChange callbacks in filamentSelectModal.tsx
  • Prevents unnecessary re-renders of child components (Table pagination, checkboxes, buttons)
  • Stable function references now persist across renders, improving React.memo effectiveness for downstream components

Backend Refactoring:

  • Extracted search filter logic from filament.find() to dedicated _build_search_filters() helper function
  • Reduced cyclomatic complexity and improves code maintainability
  • Dedicated helper clarifies search term parsing logic (exact match vs fuzzy matching)
  • Added unified ?search= query parameter to the filament list API endpoint

React Immutability Fixes Applied:

  • Replaced prop mutations with spread copies in qrCodePrintingDialog.tsx (×5 sites), filamentQrCodePrintingDialog.tsx (×3 sites), spoolQrCodePrintingDialog.tsx (×3 sites)
  • Pattern: curPreset.field = value; updateCurrentPreset(curPreset)updateCurrentPreset({ ...curPreset, field: value })
  • Nested-object sites use double-spread: { ...curPreset, subObj: { ...curPreset.subObj, key: value } }

Selection Performance Fix (spoolSelectModal):

  • Replaced O(n) selectedItems.includes(id) calls (once per row per render) with O(1) selectedSet.has(id) via useMemo(() => new Set(selectedItems), [selectedItems])

Related

Scope Boundary

  • Feature requests addressed:
    • Filament label printing foundation (parity with spool label printing flow)
    • Filament print entry points from filament list/show pages
  • Feature request links:
  • Deliberately excluded from this PR:
    • Separate export flows/pages (filament/spool labels export UX): #869
    • AML ZIP/template export follow-ups: #860
    • General search/index/performance/table UX improvements: #861, #862
    • Cross spool/filament preset sharing; preset storage remains intentionally separate in this PR
    • Export flows (AML/PNG/ZIP), filename templates, and broader print/export selector UX (moved to follow-up PRs)

Database Impact

  • None (this PR does not introduce schema/index/data migrations).

Relationship / Merge Notes

  • This PR is the filament printing foundation base.
  • #860 is stacked on top of #846.
  • #857 is stacked on top of #860.
  • #872 is stacked on top of #857.
  • #869 remains intentionally independent and improves the spool-side pre-print selection UX.
  • #846 and #869 now use parallel selection-step UX patterns, both using a single debounced ?search= API call for full-dataset search.
  • Until both are merged, any shared selection UX changes must be mirrored/rebased deliberately between the two branches.
  • #869 does not replace this PR; it brings spool selection UX up to the same general level as the filament-side selection flow here.
  • #846 does not depend on #862.

Compatibility pre-patch (d65860a) for combined-branch merges:

Test Checklist

Verified locally on March 27, 2026 via Playwright against the PR app at http://localhost:9846.

  • Filament list page has Print entry point accessible
  • Filament show page has Print entry point accessible
  • Filament search works for vendor/material names across full dataset (single ?search= API call)
  • QR codes generate correctly for filament labels
  • Print presets (filament-specific) save and restore correctly
  • Dialog handles older base_url settings without crashing
  • Print page headers display "Filament" context correctly
  • Bulk selection in filament selector works and mirrors spool patterns
  • Filament selector pagination responds smoothly with callback memoization
  • Button clicks and interactions remain responsive
  • No console warnings related to prop changes or re-renders

@akira69

akira69 commented Feb 13, 2026

Copy link
Copy Markdown
Contributor Author

@Donkie , at all interested in implementing these features? do you have the time to consider it? Or did you find any other maintainers to consider it? Thanks for any feedback.

@Donkie

Donkie commented Feb 13, 2026

Copy link
Copy Markdown
Owner

Thanks for the contribution! I will take a look within a couple of days hopefully.

@AIT-OLPE

Copy link
Copy Markdown

This feature would be great as many has requested the filament QR code generation. +1 from me

jpapiez added a commit to OlyForge3D/Spoolman that referenced this pull request Feb 14, 2026
jpapiez added a commit to OlyForge3D/Spoolman that referenced this pull request Feb 14, 2026
- Remove unused sqlalchemy imports from migrations
- Move AsyncSession to TYPE_CHECKING block
- Use removeprefix() instead of ternary
- Rename loop variable to avoid overwrite warning
- Fix extra blank lines in env.py
@akira69
akira69 force-pushed the feat/filament-aml-printing branch from f2e6da9 to e1ab3be Compare February 24, 2026 04:42
@akira69 akira69 changed the title feat: filament labels + export/print flows + AML feat(printing): filament label printing foundation Feb 24, 2026
@akira69
akira69 marked this pull request as draft February 24, 2026 04:48
@akira69
akira69 force-pushed the feat/filament-aml-printing branch from e1ab3be to 2c8a20f Compare February 24, 2026 05:17
@akira69
akira69 marked this pull request as ready for review February 26, 2026 01:02
@akira69
akira69 marked this pull request as draft February 26, 2026 16:47
@akira69
akira69 marked this pull request as ready for review February 26, 2026 17:12
@akira69 akira69 closed this Mar 2, 2026
- Extract _build_search_filters() helper to reduce McCabe complexity
- Reduces find() complexity from 13 → ~8 (under 10 limit)
- Reduces branch count from 13 → acceptable levels
- Resolves Ruff linting errors C901 + PLR0912
- Pure refactoring: behavior unchanged
- Also fixes Prettier formatting on filamentSelectModal and qrCodePrintingDialog
@akira69
akira69 force-pushed the feat/filament-aml-printing branch from 16ca9a4 to 8420604 Compare March 16, 2026 19:54
akira69 added 3 commits March 16, 2026 21:33
- Wrap selectUnselectFiltered, handleSelectItem callbacks in useCallback
- Wrap handlePageChange, handlePageSizeChange, applySearchFilter in useCallback
- Reduces unnecessary re-renders of child components (pagination, checkboxes, buttons)
- Stable function references now persist across renders
…ack PR773)

- Fetch extra field definitions once at endpoint entry instead of per-request
- Eliminates redundant database calls for extra field validation
- Applies feedback from PR 773: 'get_extra_fields only needs to be run max at once per call'
- Affected endpoints: create/update for filament, spool, and vendor resources
- Reduces API layer complexity and improves performance
- Add ?search= query param to filament API endpoint (mirrors spool API)
- Simplify filamentSelectModal from 4-field parallel fetch loop to single
  debounced ?search= call – consistent with spoolSelectModal pattern
- Remove getAPIURL import, allSearchResults state, isSearching state,
  localSearchTerm, and multi-field fetch loop (~50 LOC removed)
@akira69
akira69 force-pushed the feat/filament-aml-printing branch from e2388ac to 85fd256 Compare March 17, 2026 13:15
akira69 added 2 commits March 17, 2026 17:01
- onPrint made optional (was required)
- Added optional onExport callback + Export Labels button (conditional)
- Added optional initialSelectedIds for URL-parameter pre-selection
- Initialize selectedItems state from initialSelectedIds ?? []
- Added printing.qrcode.exportButton locale key
…n checks

- qrCodePrintingDialog: 5 sites (nested printSettings + 4 scalar fields)
- filamentQrCodePrintingDialog: 3 sites (labelSettings, name triple-spread, template)
- spoolQrCodePrintingDialog: 3 sites (same pattern as filament dialog)
- spoolSelectModal: add useMemo Set for O(1) isAllFilteredSelected checks
@NPutting

Copy link
Copy Markdown

@akira69 Is this just waiting on Donkie to approve?

@akira69

akira69 commented Mar 30, 2026

Copy link
Copy Markdown
Contributor Author

@akira69 Is this just waiting on Donkie to approve?

Pretty much, I've just recently did some more testing and tweaked accordingly, but confirmation/review/test from anyone else is appreciated

@AIT-OLPE

Copy link
Copy Markdown

Would you mind creating a release on your repo so we can test/use it until it gets merged into Spoolman?
I would love to try it out.

@akira69

akira69 commented Mar 30, 2026

Copy link
Copy Markdown
Contributor Author

Would you mind creating a release on your repo so we can test/use it until it gets merged into Spoolman? I would love to try it out.

@AIT-OLPE : done:
https://github.com/akira69/Spoolman_Labels/releases/tag/v0.9.0-filament-labels
--> though note I didn't test this specifically - hope it works, no reason it shouldn't
i'll try to make some releases for the other PRs too.

@AIT-OLPE

Copy link
Copy Markdown

Thanks, I built the docker image and started it which works, however I can't seem to find the button to print filament labels at all. Do I need to enable it somewhere? Ive tried both with my production database and a new test database same issue.

@akira69

akira69 commented Mar 31, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, I built the docker image and started it which works, however I can't seem to find the button to print filament labels at all. Do I need to enable it somewhere? Ive tried both with my production database and a new test database same issue.

I must have made a mistake in what I selected to release.
@AIT-OLPE
and yep, confirmed
fixed in this new release. the commit count matches PR846 upstream and there is 0 diff. I did build the PR846. I don't have the time right now to directly build this release, but will try that when I get time.
https://github.com/akira69/Spoolman_Labels/releases/tag/v0.9.1-pr846-exact

sherrmann added a commit to sherrmann/Spoolman-NG that referenced this pull request Jun 29, 2026
* Add filament label printing foundation

Ports upstream Donkie#846: extends the QR/label printing system to filaments
(filament select modal, filament QR/label print dialogs, and a filament
printing page) alongside the existing spool printing, with supporting settings
and API/query changes. Ruff-formatted to the fork's style.

Verified: eslint, prettier, client build (tsc + vite), ruff, and a backend
import smoke test.

Ported from upstream Donkie#846 by @akira69.

Co-authored-by: akira69 <akira69@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JqPtZvXQkraNt9ttEhLsBt

* Address label-printing review nits (memo, fetch error handling, print guard)

- filamentSelectModal: memoize dataSource so the selectUnselectFiltered useCallback (deps
  [dataSource]) is actually stable instead of rebuilt every render.
- useGetFilamentsByIds: check res.ok before parsing so a 404/500 for a stale filament id surfaces
  as a real error instead of being parsed as an IFilament.
- filaments/show print button: disable it (and omit the href) until the record has loaded, so it
  can't build "...?filaments=undefined" during the initial load.

Deferred (with reason): consolidating database/filament._build_search_filters into the shared
utils helpers — the new multi-field/empty-term behavior intentionally differs, so consolidation is
a judgment call best left to the owner. The qrCodeScanner URL regexes are unchanged — they only ever
navigate to local routes (no open redirect) and the nested-path match supports base-path deployments.

Verified: tsc, eslint, prettier, build all pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: akira69 <akira69@users.noreply.github.com>
@Donkie

Donkie commented Aug 8, 2026

Copy link
Copy Markdown
Owner

This is now available in the new client

@Donkie Donkie closed this Aug 8, 2026
jpapiez added a commit to OlyForge3D/Spoolman that referenced this pull request Aug 18, 2026
spoolman/import_externaldb.py has never been reachable. Its only function,
import_external_filaments, has no callers, no route, no poe task and no entry
point -- searching the whole history for the name turns up only the commit that
added it (05a4898), which brought it across while merging upstream PR Donkie#846
without the wiring that would have invoked it. So it has been dead since the day
it landed, and no behaviour changes by deleting it.

It is also no longer the way to do this. Upstream now exposes the external
database through /external/filament, /external/material and
/external/filament/search, and client_v2 creates filaments from those directly,
so a server-side bulk importer is not the direction this is going.

Verified: ruff clean, the app imports and registers its routes unchanged, and
the unit tests pass.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ability to print QR-codes for Filament aswell as Spool

4 participants