From 0da34d06694710b255c27a2b820f08de7be032c2 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 23 Apr 2026 21:06:16 +0200 Subject: [PATCH] i18n(briefwechsel): ThumbnailRow direction label via Paraglide Adds row_direction_sent / row_direction_received keys across the three locale files (de: Gesendet/Empfangen, en: Sent/Received, es: Enviada/Recibida) and routes ThumbnailRow's directionLabel through Paraglide. An English or Spanish screen-reader user now hears "Sent:" / "Enviada:" in their language, matching the DistributionBar i18n pass. Refs #305 Fixes @leonievoss round-2 follow-up from PR review Co-Authored-By: Claude Sonnet 4.6 --- frontend/messages/de.json | 2 ++ frontend/messages/en.json | 2 ++ frontend/messages/es.json | 2 ++ frontend/src/lib/components/ThumbnailRow.svelte | 3 ++- .../src/lib/components/ThumbnailRow.svelte.spec.ts | 10 +++++++--- 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/frontend/messages/de.json b/frontend/messages/de.json index 9f8c71b8..f74c749a 100644 --- a/frontend/messages/de.json +++ b/frontend/messages/de.json @@ -167,6 +167,8 @@ "conv_no_party": "—", "dist_bar_segment": "{count} von {name}", "dist_bar_aria": "Briefverteilung in diesem Zeitraum: {outCount} von {senderName}, {inCount} von {receiverName}", + "row_direction_sent": "Gesendet", + "row_direction_received": "Empfangen", "admin_heading": "Admin Dashboard", "admin_tab_users": "Benutzer", "admin_tab_groups": "Gruppen", diff --git a/frontend/messages/en.json b/frontend/messages/en.json index f93f2a4e..0ff58ce2 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -167,6 +167,8 @@ "conv_no_party": "—", "dist_bar_segment": "{count} from {name}", "dist_bar_aria": "Letter distribution in this period: {outCount} from {senderName}, {inCount} from {receiverName}", + "row_direction_sent": "Sent", + "row_direction_received": "Received", "admin_heading": "Admin Dashboard", "admin_tab_users": "Users", "admin_tab_groups": "Groups", diff --git a/frontend/messages/es.json b/frontend/messages/es.json index 7d976d46..f968bbde 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -167,6 +167,8 @@ "conv_no_party": "—", "dist_bar_segment": "{count} de {name}", "dist_bar_aria": "Distribución de cartas en este período: {outCount} de {senderName}, {inCount} de {receiverName}", + "row_direction_sent": "Enviada", + "row_direction_received": "Recibida", "admin_heading": "Panel de administración", "admin_tab_users": "Usuarios", "admin_tab_groups": "Grupos", diff --git a/frontend/src/lib/components/ThumbnailRow.svelte b/frontend/src/lib/components/ThumbnailRow.svelte index f605b0c4..7fb2eba0 100644 --- a/frontend/src/lib/components/ThumbnailRow.svelte +++ b/frontend/src/lib/components/ThumbnailRow.svelte @@ -3,6 +3,7 @@ import ConversationThumbnail from '$lib/components/ConversationThumbnail.svelte' import TagChipList from '$lib/components/TagChipList.svelte'; import { formatDate } from '$lib/utils/date'; import { relativeYearsDe } from '$lib/relativeTime'; +import * as m from '$lib/paraglide/messages.js'; type Person = { id: string; firstName?: string | null; lastName: string; displayName: string }; type Tag = { id: string; name: string }; @@ -47,7 +48,7 @@ const otherPartyName = $derived( const relativeYearLabel = $derived( doc.documentDate ? relativeYearsDe(new Date(doc.documentDate + 'T12:00:00'), now) : '' ); -const directionLabel = $derived(isOut ? 'Gesendet' : 'Empfangen'); +const directionLabel = $derived(isOut ? m.row_direction_sent() : m.row_direction_received()); const ariaLabel = $derived( `${directionLabel}: ${title}${doc.documentDate ? `, ${formatDate(doc.documentDate)}` : ''}` ); diff --git a/frontend/src/lib/components/ThumbnailRow.svelte.spec.ts b/frontend/src/lib/components/ThumbnailRow.svelte.spec.ts index 9c41fc65..e62b45ea 100644 --- a/frontend/src/lib/components/ThumbnailRow.svelte.spec.ts +++ b/frontend/src/lib/components/ThumbnailRow.svelte.spec.ts @@ -1,5 +1,6 @@ import { describe, it, expect, afterEach } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; +import * as m from '$lib/paraglide/messages.js'; import ThumbnailRow from './ThumbnailRow.svelte'; @@ -151,12 +152,14 @@ describe('ThumbnailRow', () => { const link = document.querySelector('a[href="/documents/d1"]') as HTMLElement; const label = link.getAttribute('aria-label') ?? ''; - expect(label).toMatch(/^Gesendet:/); + // Direction label routes through Paraglide so EN / ES users don't hear + // "Gesendet" in their screen reader. + expect(label.startsWith(`${m.row_direction_sent()}:`)).toBe(true); expect(label).toContain('Liebe Anna'); expect(label).toMatch(/1950/); }); - it('aria-label begins with "Empfangen:" for incoming letters', () => { + it('aria-label leads with the received direction label for incoming letters', () => { render(ThumbnailRow, { doc: baseDoc, isOut: false, @@ -165,7 +168,8 @@ describe('ThumbnailRow', () => { }); const link = document.querySelector('a[href="/documents/d1"]') as HTMLElement; - expect(link.getAttribute('aria-label') ?? '').toMatch(/^Empfangen:/); + const label = link.getAttribute('aria-label') ?? ''; + expect(label.startsWith(`${m.row_direction_received()}:`)).toBe(true); }); it('does not inject raw HTML when summary contains markup (XSS regression)', () => {