feat(conversations): swap button, year dividers, summary bar, new-doc link #43

Merged
marcel merged 11 commits from feat/conversation-page-improvements into main 2026-03-20 21:35:23 +01:00
Owner

Closes #30, #31, #32, #33

Summary

  • Swap button (#32) — exchanges sender and receiver, re-fetches immediately; placed between the two person fields; hidden (invisible) when either field is empty to avoid layout shift
  • Year dividers (#30) — horizontal rule with the year label appears between chat bubbles whenever the year changes
  • Summary bar (#31) — shows document count and year range (e.g. "12 Dokumente · 1940 – 1965") above the chat timeline
  • New-document link (#33) — "Neues Dokument" link above the timeline, pre-fills senderId + receiverId in the new-document form; hidden for read-only users
  • Prefill sender/receiver from URL params — the new-document page reads senderId/receiverId from URL search params and pre-selects them in the form
  • Component tests for all new conversations features and the URL-param prefill on the new-document page

Test plan

  • npm run test — 129 frontend tests pass
  • npm run lint && npm run check — no errors
  • Manual: open /conversations, select two persons → summary bar, year dividers, swap button, and new-doc link all appear correctly
Closes #30, #31, #32, #33 ## Summary - **Swap button** (#32) — exchanges sender and receiver, re-fetches immediately; placed between the two person fields; hidden (invisible) when either field is empty to avoid layout shift - **Year dividers** (#30) — horizontal rule with the year label appears between chat bubbles whenever the year changes - **Summary bar** (#31) — shows document count and year range (e.g. "12 Dokumente · 1940 – 1965") above the chat timeline - **New-document link** (#33) — "Neues Dokument" link above the timeline, pre-fills `senderId` + `receiverId` in the new-document form; hidden for read-only users - **Prefill sender/receiver from URL params** — the new-document page reads `senderId`/`receiverId` from URL search params and pre-selects them in the form - Component tests for all new conversations features and the URL-param prefill on the new-document page ## Test plan - [ ] `npm run test` — 129 frontend tests pass - [ ] `npm run lint && npm run check` — no errors - [ ] Manual: open `/conversations`, select two persons → summary bar, year dividers, swap button, and new-doc link all appear correctly
marcel added 11 commits 2026-03-20 21:33:38 +01:00
Adds a button between the two person typeaheads that swaps sender and
receiver, then reloads the conversation view.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shows a summary line above the conversation listing with total document
count and the year span, e.g. "4 Dokumente · 1923–1965".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Renders a horizontal rule with the year label between consecutive
documents that belong to different years.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a link next to the summary that navigates to the new-document form
with senderId and receiverId pre-filled from the current conversation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On desktop the button sits between the two typeaheads as an icon-only
button (icon rotated 90° to point left/right) aligned to the input
baseline. On mobile it renders full-width with the label text between
the stacked fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The link navigates to a page that requires WRITE_ALL. Guard it with
data.canWrite (supplied by the layout) so read-only users never see a
link that leads to a 403.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The guard was lost when the button was moved into the grid between the
two person inputs. Without it the button rendered even when no persons
were selected, breaking the UX and the E2E assertion.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers: empty state, swap button (visible/hidden, goto called with
swapped params), summary content, year dividers, and new document link
visibility gated by canWrite.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When navigating from the conversations page via the 'New document in this
correspondence' link, the senderId and receiverId query params are now read
in the server load, resolved to person names, and used to pre-populate the
sender typeahead and receiver multi-select on the form.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fix(conversations): keep swap button in DOM to prevent grid column width shift
All checks were successful
CI / Unit & Component Tests (push) Successful in 1m56s
CI / Backend Unit Tests (push) Successful in 1m53s
CI / E2E Tests (push) Successful in 16m37s
CI / Unit & Component Tests (pull_request) Successful in 2m2s
CI / Backend Unit Tests (pull_request) Successful in 2m2s
CI / E2E Tests (pull_request) Successful in 16m55s
513a7290b0
The swap button was conditionally removed from the DOM with {#if}, which
caused the receiver input to collapse into the narrow auto column of the
grid-cols-[1fr_auto_1fr] layout on desktop when no persons were selected.

The button is now always rendered. On desktop it becomes invisible
(visibility:hidden) when no persons are selected, preserving the middle
column width so both 1fr columns stay equal. On mobile it remains hidden
(display:none) via the hidden class so no empty gap appears between the
stacked inputs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
marcel merged commit 513a7290b0 into main 2026-03-20 21:35:23 +01:00
marcel deleted branch feat/conversation-page-improvements 2026-03-20 21:35:25 +01:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: marcel/familienarchiv#43