From a9027ceaf7882d43b0448db60ce08c2be53a9c12 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 15 Jun 2026 22:15:24 +0200 Subject: [PATCH] fix(timeline): keep a compact letter's date unless the title embeds it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `showDate = !compact || !entry.title` dropped the date chip for ANY titled compact letter. But titles are free-form OCR/import text — a letter titled "Brief an Mutter" lost its month/day entirely, and inside an event card the band frames only the year. The chip now drops only when the formatted date actually appears in the title (e.g. "H-0023 – 6. Juli 1916"), so the row-height win holds where valid and no information is lost otherwise. The spec that asserted the date vanishes for any title is rewritten to the correct contract, plus an inverse test. Fixes review finding #4. Refs #850 Co-Authored-By: Claude Opus 4.8 --- frontend/src/lib/timeline/LetterCard.svelte | 10 ++++++---- .../lib/timeline/LetterCard.svelte.spec.ts | 20 +++++++++++++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/frontend/src/lib/timeline/LetterCard.svelte b/frontend/src/lib/timeline/LetterCard.svelte index c56b048c..1e3b334f 100644 --- a/frontend/src/lib/timeline/LetterCard.svelte +++ b/frontend/src/lib/timeline/LetterCard.svelte @@ -32,10 +32,12 @@ let { const isEventVariant = $derived(variant === 'event'); const dateLabel = $derived(timelineDateLabel(entry.eventDate, entry.precision, entry.eventDateEnd)); -// Inside an event card the year frames the time, and these archive titles already -// embed the date — so the compact in-card letter drops the redundant date chip when a -// title is present, halving the row height and killing the duplicate date (#850). -const showDate = $derived(!compact || !entry.title); +// Inside an event card the band frames the time, so a compact in-card letter drops the +// redundant date chip — but ONLY when the (free-form OCR) title actually embeds the formatted +// date, e.g. "H-0023 – 6. Juli 1916". A title without the date keeps its chip, so a letter like +// "Brief an Mutter" never loses its month/day (the band frames only the year) — #850, finding #4. +const titleEmbedsDate = $derived(!!dateLabel && !!entry.title && entry.title.includes(dateLabel)); +const showDate = $derived(!compact || !titleEmbedsDate); const sender = $derived(entry.senderName === '' ? m.timeline_unknown_person() : entry.senderName); const receiver = $derived( entry.receiverName === '' ? m.timeline_unknown_person() : entry.receiverName diff --git a/frontend/src/lib/timeline/LetterCard.svelte.spec.ts b/frontend/src/lib/timeline/LetterCard.svelte.spec.ts index f7957637..349a2e72 100644 --- a/frontend/src/lib/timeline/LetterCard.svelte.spec.ts +++ b/frontend/src/lib/timeline/LetterCard.svelte.spec.ts @@ -152,14 +152,26 @@ describe('LetterCard — event-cluster variants (#850, REQ-002)', () => { expect(document.querySelector('[data-testid="tag-chip"]')).not.toBeNull(); }); - it('drops the redundant date line in the compact variant when a title is present (#850)', () => { - // Inside an event card the year already frames the time, and these archive titles - // embed the date — so the compact in-card letter omits the date chip. - render(LetterCard, { entry: makeEntry({ title: 'H-0023 – 6. Juli 1916' }), compact: true }); + it('drops the compact date chip only when the title actually embeds the formatted date (#850)', () => { + // An archive title like "H-0023 – 6. Juli 1916" already carries the date, so inside an + // event card (where the band frames the time) the redundant chip is dropped. + const entry = makeEntry({ eventDate: '1916-07-06', precision: 'DAY' }); + const dateLabel = timelineDateLabel(entry.eventDate, entry.precision, entry.eventDateEnd); + render(LetterCard, { entry: { ...entry, title: `H-0023 – ${dateLabel}` }, compact: true }); expect(document.querySelector('[data-testid="letter-date"]')).toBeNull(); expect(document.body.textContent).toContain('Karl Raddatz'); // sender still shown }); + it('keeps the compact date chip when the title does NOT embed the date (#850, finding #4)', () => { + // Titles are free-form OCR text — a titled letter whose title carries no date must keep + // its month/day, since inside an event card the band frames only the year. + render(LetterCard, { + entry: makeEntry({ eventDate: '1916-07-06', precision: 'DAY', title: 'Brief an Mutter' }), + compact: true + }); + expect(document.querySelector('[data-testid="letter-date"]')).not.toBeNull(); + }); + it('keeps the date in the compact variant when the letter has no title (#850)', () => { render(LetterCard, { entry: makeEntry({ title: undefined }), compact: true }); expect(document.querySelector('[data-testid="letter-date"]')).not.toBeNull();