feat: category combobox list in a portal, combobox in adjustment lines and the transfers filter (#429) #471

Open
maximus wants to merge 6 commits from issue-429-category-combobox-portal into issue-372-systems-journal-first

6 commits

Author SHA1 Message Date
le king fu
14ebf0f37d docs: name the portal windows as examples, not as tested (#429)
All checks were successful
PR Check — Frontend / frontend (pull_request) Successful in 1m58s
Self-review: the Portails paragraph listed StarterAccountsModal next to
LinkTransfersModal as if both had a test of this kind; only
LinkTransfersModal has one. The other windows are named as windows the
same rule applies to.

Resolves #429

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 18:49:20 -04:00
le king fu
874563540c docs: state the exact flip rule and the portal errors (#429)
All checks were successful
PR Check — Frontend / frontend (pull_request) Successful in 1m58s
Self-review: the CHANGELOG entries said the list opens upward when the
room below is short; it does only when it also fits above (in a short
window it stays below). The Portails paragraph of architecture.md now
quotes the two errors a test meets without the mock, both reproduced
on a throwaway test: "Target container is not a DOM element" without
a DOM, "Portals are not currently supported by the server renderer"
with a DOM-like container.

Resolves #429

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 18:48:45 -04:00
le king fu
7053ae5fc6 docs: describe the category combobox in a portal and its new places (#429)
All checks were successful
PR Check — Frontend / frontend (pull_request) Successful in 1m55s
CHANGELOG (EN and FR, Changed): typing in the category of an adjustment
line and in the category filter of the "Link transfers" window, the
adjustment lines limited to the categories open to input, and the open
list no longer cut by the edge of a window or of the Transactions table.

Guide, section 7, and its in-app twin (docs.adjustments.steps, FR and
EN): type a few letters to filter the category list of a line.

architecture.md, Tests section: how a test renders a window drawn by
createPortal (identity mock, document stub), what of the combobox's
portal is pinned without a DOM (placeListbox.ts) and what is checked in
the app, and that the list no longer sits in its container's DOM.

Resolves #429

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 18:41:37 -04:00
le king fu
aa229484f6 feat: filter the transfers to link by category with a combobox (#429)
The category filter of the "Link transfers" window was a native select.
It now takes the compact CategoryCombobox, modelled on the Transactions
filter bar: "Any category" first as an extra option, active while the
filter is empty, and picking it sets the filter back to null; the list
of transactions reloads as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 18:34:52 -04:00
le king fu
619637e91b feat: pick an adjustment line's category in a combobox (#429)
Each line of the adjustment form chose its category in a native select
showing raw names. It now takes the compact CategoryCombobox of the
split window: typing filters, hierarchical order, seed names
translated. A new line still takes the first category of the list.

D2: the hook reads the Transactions list, getAllCategories (active and
open to input), instead of its own query on every active category. The
list feeds two pickers only, the form and the split window of the
Adjustments page; the detail view names a line's category from the
entries' join, so a line saved on a category hidden from input keeps
its name there and its value, its field empty until changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 18:34:49 -04:00
le king fu
3631ef0b64 feat: render the category combobox's open list in a portal (#429)
The open list of CategoryCombobox was positioned `absolute` inside its
input's container, so a scrolling ancestor clipped it: the body of the
split window, the `overflow-x-auto` wrapper of the Transactions table.
It is now rendered in a portal on document.body, `position: fixed`, at
z-[300] (above every window, the highest at z-[210]).

The pure rule lives in placeListbox.ts: under the input, as wide as it,
4 px below; above it when the room below is short of the list's 240 px
and the room above has them; below when neither side has them. The
list is placed in a layout effect before the first paint, then follows
the input on every scroll (capture phase, any scrolling container) and
resize while it is open, skipping scrolls of the list itself; the
listeners are removed with the list (followAnchor returns the cleanup).
The outside press counts the list as inside, since it no longer sits in
the container's DOM. The closed markup is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 18:34:44 -04:00