Skip to content

feat(ui): state-aware Save and Clear Filters buttons#864

Open
akira69 wants to merge 8 commits intoDonkie:masterfrom
akira69:feat/ui-button-state-upstream-split
Open

feat(ui): state-aware Save and Clear Filters buttons#864
akira69 wants to merge 8 commits intoDonkie:masterfrom
akira69:feat/ui-button-state-upstream-split

Conversation

@akira69
Copy link
Copy Markdown

@akira69 akira69 commented Feb 24, 2026

Summary

Make Save, Clear Filters, and Save Presets reflect real pending work instead of staying highlighted on unchanged state.

What Changed

  • Fixed edit-form initialization so the loaded record becomes the dirty-state baseline instead of being reapplied on every render.
  • Hardened malformed persisted UI state recovery for savedStates-*, table filters, pagination, and shown-column state.
  • Kept existing empty-string filter semantics for <empty> values when deciding whether Clear Filters should highlight.
  • Reworked spool QR preset editing so it does not mutate the persisted baseline in place, recovers from stale preset selection, and treats the auto-created empty preset as neutral until the user changes it.

Screenshots

Save button inactive when no form changes

image

Save button active after field modification

image

Clear Filters inactive with no active filters

image

Clear Filters active after applying filters

image

Save Presets inactive when no changes to existing and selected preset

image

Save Presets active after making change (in this case to preset name)

image

Testing Performed

Commands

  • cd /Users/dfinch/Code/Spoolman_Labels/worktrees/pr864/client && ./node_modules/.bin/eslint src/pages/filaments/edit.tsx src/pages/spools/edit.tsx src/pages/printing/spoolQrCodePrintingDialog.tsx src/utils/filtering.ts src/utils/saveload.ts
  • client/node_modules/.bin/prettier --check client/src/pages/filaments/edit.tsx client/src/pages/spools/edit.tsx client/src/pages/printing/spoolQrCodePrintingDialog.tsx client/src/utils/filtering.ts client/src/utils/saveload.ts
  • cd /Users/dfinch/Code/Spoolman_Labels/worktrees/pr864/client && ./node_modules/.bin/eslint src/pages/vendors/edit.tsx src/pages/filaments/edit.tsx src/pages/spools/edit.tsx src/pages/printing/printing.tsx src/pages/printing/spoolQrCodePrintingDialog.tsx
  • client/node_modules/.bin/prettier --check client/src/pages/vendors/edit.tsx client/src/pages/filaments/edit.tsx client/src/pages/spools/edit.tsx client/src/pages/printing/printing.tsx client/src/pages/printing/spoolQrCodePrintingDialog.tsx
  • cd /Users/dfinch/Code/Spoolman_Labels/worktrees/pr864/client && VITE_APIURL=/api/v1 npm run build
  • cd /Users/dfinch/Code/Spoolman_Labels/worktrees/pr864 && PATH=.venv/bin:$PATH SPOOLMAN_DIR_DATA=/tmp/spoolman_pr_864_data uv run uvicorn spoolman.main:app --host 0.0.0.0 --port 9864
  • node /tmp/pr864_retry_tests.js

Browser validation on http://localhost:9864

  • Verified Filament, Spool, Vendor, and Settings forms keep Save neutral on load, activate after a real change, and return to neutral after reverting the change.
  • Verified Filaments, Spools, and Vendors list pages keep Clear Filters neutral with no meaningful filters, highlight when meaningful filters are restored from saved state, and return to neutral after clearing.
  • Verified Vendors list still treats empty-string filters as meaningful for the existing <empty> filter semantics.
  • Poisoned saved list/table state for Filaments, Spools, and Vendors and confirmed each page still renders instead of crashing.
  • Verified Spool QR presets keep Save Presets neutral when unchanged, activate after a preset-name edit, and return to neutral after reverting.
  • Poisoned savedStates-selectedPreset and savedStates-print-useHTTPUrl and confirmed the spool print page still renders.

Test Checklist

  • Filament edit page: Save button is neutral until a field is modified
  • Filament edit page: Save button returns to neutral after reverting a field
  • Spool edit page: Save button is neutral until a field is modified
  • Spool edit page: Save button returns to neutral after reverting a field
  • Vendor edit page: Save button is neutral on initial page load
  • Vendor edit page: Save button is active after a field is modified
  • Vendor edit page: Save button returns to neutral after reverting a field
  • Settings > General page: Save button is neutral until a setting is changed
  • Settings > General page: Save button returns to neutral after reverting a setting
  • Filaments list: Clear Filters button is neutral with no meaningful filters
  • Filaments list: Clear Filters highlights after applying a meaningful filter
  • Filaments list: malformed saved filter/table state recovers without a crash
  • Spools list: Clear Filters button is neutral with no meaningful filters
  • Spools list: Clear Filters highlights after applying a meaningful filter
  • Spools list: malformed saved filter/table state recovers without a crash
  • Vendors list: Clear Filters button is neutral with no meaningful filters
  • Vendors list: Clear Filters highlights after applying a meaningful filter
  • Vendors list: malformed saved filter/table state recovers without a crash
  • Spool QR label presets: Save Presets is neutral when unchanged
  • Spool QR label presets: Save Presets is active after a meaningful preset change
  • Spool QR label presets: Save Presets returns to neutral after revert or save
  • Malformed savedStates-* localStorage recovers without a crash on affected pages

@akira69 akira69 force-pushed the feat/ui-button-state-upstream-split branch 2 times, most recently from ec6a279 to eab1f06 Compare February 24, 2026 20:30
@akira69 akira69 marked this pull request as ready for review February 24, 2026 21:52
@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
@akira69 akira69 reopened this Mar 2, 2026
@akira69 akira69 marked this pull request as draft March 14, 2026 01:43
akira69 added 6 commits March 18, 2026 22:49
- Filament/Spool/Vendor edit forms: Save button activates only when
  unsaved changes exist; neutral and disabled when form is unchanged
- Filament/Spool/Vendor list pages: Clear Filters highlights only when
  active filters would actually change results
- Spool QR label preset dialog: Save Presets highlights when local
  working copy diverges from persisted presets
…orms

Replace direct mutation of formProps.initialValues at render time with
useEffect + form.setFieldsValue(). Use dot notation for nested id access
to avoid any inference. Add explicit cast for setFieldsValue argument
to satisfy Ant Design strict form field types. Fix Prettier violations.
The live-update warning was set to true by onLiveEvent but never cleared
after the user submitted the form, leaving the alert visible permanently
even after a successful save. Clear it on submit intent; server errors
are surfaced separately by useForm.
formProps.initialValues.extra contains raw JSON-encoded strings from
the API (e.g. '"some_value"' for a string field), while form state
after setFieldsValue(ParsedExtras(...)) holds the actual parsed types
(e.g. 'some_value').

Passing raw initialValues to toComparableState caused the Save button
to appear active on first load whenever an entity had extra fields with
values, even though no changes had been made.

Fix: wrap formProps.initialValues with ParsedExtras() in the
initialComparableState useMemo in spools/edit, filaments/edit, and
vendors/edit so both sides of the dirty-state comparison use the same
parsed representation.
Add ISpoolEditForm, IFilamentEditForm, and IVendorEditForm to each model
file. These types are Omit<IParsedExtras, ...system/computed fields> plus
any form-specific ID fields (filament_id, vendor_id).

Change comparableDefaults in all three edit pages from bare 'as const'
objects to Record<keyof IEditForm, unknown>. TypeScript now enforces
completeness: adding a field to the model and edit form will produce a
compile error in comparableDefaults until the field is also listed there
with its default value. No manual tracking of field names required.
@akira69 akira69 force-pushed the feat/ui-button-state-upstream-split branch from f5d087a to 4a41aaa Compare March 19, 2026 03:49
@akira69 akira69 marked this pull request as ready for review March 19, 2026 14:42
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.

1 participant