feat(ui): state-aware Save and Clear Filters buttons#864
Open
akira69 wants to merge 8 commits intoDonkie:masterfrom
Open
feat(ui): state-aware Save and Clear Filters buttons#864akira69 wants to merge 8 commits intoDonkie:masterfrom
akira69 wants to merge 8 commits intoDonkie:masterfrom
Conversation
3 tasks
ec6a279 to
eab1f06
Compare
- 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.
f5d087a to
4a41aaa
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Make Save, Clear Filters, and Save Presets reflect real pending work instead of staying highlighted on unchanged state.
What Changed
savedStates-*, table filters, pagination, and shown-column state.<empty>values when deciding whetherClear Filtersshould highlight.Screenshots
Save button inactive when no form changes
Save button active after field modification
Clear Filters inactive with no active filters
Clear Filters active after applying filters
Save Presets inactive when no changes to existing and selected preset
Save Presets active after making change (in this case to preset name)
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.tsclient/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.tscd /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.tsxclient/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.tsxcd /Users/dfinch/Code/Spoolman_Labels/worktrees/pr864/client && VITE_APIURL=/api/v1 npm run buildcd /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 9864node /tmp/pr864_retry_tests.jsBrowser validation on
http://localhost:9864Clear Filtersneutral with no meaningful filters, highlight when meaningful filters are restored from saved state, and return to neutral after clearing.<empty>filter semantics.Save Presetsneutral when unchanged, activate after a preset-name edit, and return to neutral after reverting.savedStates-selectedPresetandsavedStates-print-useHTTPUrland confirmed the spool print page still renders.Test Checklist
savedStates-*localStorage recovers without a crash on affected pages