* feat(transactions): cascade parent/subcategory checkboxes in the category filter
Checking a parent category in the transaction filter sidebar now auto-checks
its subcategories, and vice versa. Unchecking a single subcategory also
unchecks the parent so the submitted filter never silently includes a
category the user just deselected — Transaction::Search#apply_category_filter
includes every subcategory whenever a parent name is present, with no way to
exclude one individually, so the parent checkbox must reflect exactly what
gets submitted.
Also fixes the "swipe-to-categorize" pill picker (transactions/categorizes/show.html.erb),
which was still a flat alphabetical list with no parent/child indication —
now grouped and labeled consistently with the rest of the app (PR #2845, #3292).
Adds an :indeterminate style for .checkbox--light (only .checkbox--dark had one).
Closes discussion #3149.
This code was written by Claude Code (Anthropic).
* fix(transactions): preserve parent-only category filters on reopen
connect() derived each checkbox's parent/child state independently from
server-rendered checked attributes, so a parent-only filter (e.g. an
incoming link naming only the parent category) rendered the parent
checked with its children unchecked — syncParentState() then read that
as "some children unchecked" and cleared the parent, silently dropping
the filter on the next Apply. Cascade checked parents to their children
before deriving parent state so the picker matches the active query.
Also makes the internal helper methods private per review feedback.
* fix(transactions): eager-load category parent, fix categorize-pill filter text
Addresses PR #3356 review from jjmata:
- Current.family.categories.alphabetically caused an N+1 (SELECT per
parent) via display_name_with_parent in the categorize-wizard pill
loop. Added .includes(:parent) at all three call sites.
- data-filter-name still used the bare category name while the pill
label showed "Parent > Child" for subcategories, so searching by the
visible parent prefix found nothing. Both now share one computed
label.
---------
Co-authored-by: Gerald <248542187+gfr-free@users.noreply.github.com>