feat: documents page polish — no Close row on a document, Category first, categories fold #17
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/document-ui-polish"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Three small UI improvements to the Documents page, from the owner's read.
What changes
h3 > button[aria-expanded]), witharia-controlsset while the category is open and a keyboard focus ring.Side fix: the list column's scroll box clipped focus rings at its edges (the rows' rings too, not just the new toggles). It now has a 4px inline padding, given back by a negative margin, so the rings show in full and the list doesn't move.
ADR / docs
docs/stories/documents.md: a checked item for folding, plus acceptance criteria for the field order and for folds vs. the filter.Tests
DocumentsPageTests: the document tests now leave through the breadcrumb, with an assertion that the editor has no Close. The label order isCategory, Title, Description, Body, and the old.editor__barchecks read the Category select instead.A_category_folds_under_its_name_keeps_its_count_and_a_filter_shows_every_match(fold/unfold, count, description folds, nothing journaled, filter override and return, fold survives remount) andA_new_document_unfolds_its_category.Browser check
I ran the seeded app (
TSUMUGI_SEED_DEV_DATA=true) and drove it with a Playwright script, in light and dark themes:Category, Title, Description, Body, with no Close link and no badge.🤖 Generated with Claude Code
Summary
Summary
Coverage
Tsumugi.BlazorAdapter - 96.9%
Tsumugi.Domain - 99.3%
Tsumugi.Infrastructure - 97.1%
A55E0373ED22DC58420DBB40F103A46B68DC4D9CE5A49E00B__Pattern_0
on
tion
n
Tsumugi.Kernel - 90.9%
Tsumugi.Server - 100%
Tsumugi.UseCases - 98%
🔮 fufu~ Jibril reviewed your code!
Ohh, what a lovely little polish PR~ Three owner's-read improvements, and each one carried through state, reducer, markup, CSS, ADR, stories AND tests — the fold even survives a section trip and refuses to be lied to by the filter. I read the full diff, every changed file whole, traced the siblings, and ran the suite with my own hands. And then… I found one small thing hiding in the one file this PR didn't touch. You'll fix it in one line, won't you? ♡
Verdict: ⛔ I can't let this pass~ ♡
⛔ These need fixing before I'm satisfied~
tests/Tsumugi.BlazorAdapter.Tests/DocumentsReducersTests.cs:42-69 — the new action is missing from the staleness sweep. The file's own summary promises it: "every answer names its story, and one for a story the panel has left is dropped" — and
Every_answer_for_a_story_the_panel_has_left_is_droppedmechanically pins that guard for all 17 pre-existing slice actions, includingSetDocumentsFilter(the new action's nearest sibling).SetCategoryCollapsed— the 18th action, added by this PR — has no line there. I didn't take that on faith; I probed it:OnSetCategoryCollapsed(DocumentsReducers.cs:31-34) → the full adapter suite stays green, 213/213. The branch is exercised by nothing.OnSetFilter→ the sweep test goes red, exactly as designed.SetCollapseddispatches with the component's liveStoryId, so the mismatch arm is unconstructible from the UI. Only the sweep can hold it.The pattern in this very repo is new slice action → new line in the sweep (every action before this one has one). A late
SetCategoryCollapsedfrom a story the panel has left would currently fold a category in the wrong story's list — the exact stale-answer bug class the file exists to kill.Fix, one line among its siblings:
💡 Little ideas (non-blocking)~
Collapsedforever (until the story switch resets the slice). Unobservable today — the view can't render what it doesn't hold, and an undo that resurrects the category just finds it still folded, which is arguably faithful view state. Pure observation, no action needed ♪✅ What I liked~
A_new_document_unfolds_its_categoryis a real pin, not a tautology. The fold/unfold/count/description-folds/nothing-journaled/filter-override/folds-return/filter-clear/remount-persistence chain in the CI big test is genuinely thorough~Disclosure— I checked! Disclosure is browser-owned<details>with collapsed-by-default state; it cannot hold slice-owned fold state that survives a section trip. Choosing the WAI-ARIA accordion pattern (h3 > button[aria-expanded]) and omittingaria-controlswhen the body isn't rendered was the right call, not a DRY miss.SelectMany(...).FirstOrDefault(...)rewrite is better than the old per-category scan-then-rescan. Cheeky little improvement smuggled in with a parameter removal~font: inherit+letter-spacing: inheritso the button truly is the heading,prefers-reduced-motion, tabular-nums on the count, and the padding-inline-given-back-by-margin trick for the clipped focus rings — with a comment explaining why.editor__barretired cleanly (CategoryEditor keeps its own in its own scoped css — verified no orphan), andFiledUnderreadingoption[selected]matches Select's actual rendering.Local, at
c361b57: build 0 warnings (as errors) 0 errors after initializing both submodules; full suite 417/417 (Domain 37 + UseCases 12 + Adapter 213 + Integration 155 — matches your table exactly); clone restored pristine post-probes. Mutation probes: A (unfold removed) red on its own test; B (new guard removed) green-on-mutant across all 213 — the blocker above; C (sibling guard removed, control) red on the sweep.Fufu~ one line, scarlet. Add it, and this folds open beautifully~ ♡
Automated review by Jibril · 2026-09-23
CI/CD: absent for head SHA
c361b57· Local checks: build 0w/0e, 417/417, 3 mutation probesAddressed in
88650e4.⛔ Staleness sweep.
SetCategoryCollapsednow has its line inEvery_answer_for_a_story_the_panel_has_left_is_dropped, next toSetDocumentsFilter. I re-ran your probe B: with the guard removed fromOnSetCategoryCollapsed, the sweep goes red (1 failed, 7 passed inDocumentsReducersTests). With the guard restored, it's green again.Also:
Opening_another_story_clears_the_slice_at_once_and_a_refresh_keeps_itnow checksCollapsedtoo. A refresh keeps the folds; another story starts with none. That pins ADR 0027's "another story starts with every category open", which nothing covered before.💡 Stale ids in
Collapsed: agreed, and left as is. Nothing can see them, and a category restored by undo comes back folded the way it was, which is the honest view state. The set is cleared on every story switch.Adapter suite: 213/213.
🔮 fufu~ Jibril reviewed your code!
One line, just as promised~ Well — one line plus a bonus pin you didn't owe me! I pulled the increment, read the diff, rebuilt everything with my own hands, and re-ran the probe myself, because a girl doesn't take "the sweep goes red" on faith, no matter how nicely it's worded~ ♡
Verdict: ✅ Looks good to me~
The round-1 blocker — closed and probe-verified
Every_answer_for_a_story_the_panel_has_left_is_droppednow has itsSetCategoryCollapsedline. I stripped the staleness guard fromOnSetCategoryCollapsed(DocumentsReducers.cs:30-33) on the head tree, rebuilt, and ran the suite: the sweep goes red, 1 failed / 212 passed — the exact result you reported in your reply, reproduced mechanically. The 18th action is now held by the same invariant as its 17 siblings. The stale-answer arm can't rot silently anymore~The bonus — and I probed that too~
Opening_another_story_clears_the_slice_at_once_and_a_refresh_keeps_itgrewAssert.Equal([lore.Id], refreshed.Collapsed)andAssert.Empty(other.Collapsed), pinning ADR 0027's "another story starts with every category open" — which truly nothing covered before. I probed this one as well: mutatingOnLoad's other-story arm to carryCollapsedover → red on exactly that test. Both new assertions are directional pins, not tautologies. You didn't have to do that, and you did it anyway~✅ What I liked~
Local, at
88650e4: build 0 warnings (as errors) 0 errors after initializing both submodules; full suite 417/417 (Domain 37 + UseCases 12 + Adapter 213 + Integration 155); clone restored pristine post-probes (git status clean, reducer hash matches head, suite re-verified green on the restored tree).Fufu~ every round of this PR was a pleasure. Fold it into main~ ♡
Automated review by Jibril · 2026-09-23
CI/CD: coverage comment stale for head SHA
88650e4(rev #1 coversc361b57; workflow runs tests before coverage) · Local checks: build 0w/0e, 417/417, 2 mutation probes