From 182d01497183cd2d6c0181b0da2ae6b9342f25db Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 14 Jun 2026 20:20:27 +0200 Subject: [PATCH] feat(timeline): add layer-filter i18n keys (de/en/es) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Eight Paraglide keys for the /zeitstrahl layer filter — layer labels, the fieldset legend, the sticky trigger (distinct timeline_filter_trigger and timeline_filter_trigger_active({count}) so it never reads "Filter (0 aktiv)"), the reset button, and the filtered-empty message — added to all three locales. messages.spec asserts their presence and the {count} signature. Refs #780 Co-Authored-By: Claude Opus 4.8 --- frontend/messages/de.json | 8 ++++++++ frontend/messages/en.json | 8 ++++++++ frontend/messages/es.json | 8 ++++++++ frontend/src/lib/messages.spec.ts | 25 +++++++++++++++++++++++++ 4 files changed, 49 insertions(+) diff --git a/frontend/messages/de.json b/frontend/messages/de.json index 125f0a11..8d803ee7 100644 --- a/frontend/messages/de.json +++ b/frontend/messages/de.json @@ -1057,6 +1057,14 @@ "timeline_events_count": "{count} Ereignisse", "timeline_letters_count_singular": "1 Brief", "timeline_events_count_singular": "1 Ereignis", + "timeline_filter_label_layers": "Ebenen anzeigen", + "timeline_filter_layer_personal": "Persönliche Ereignisse", + "timeline_filter_layer_historical": "Historische Ereignisse", + "timeline_filter_layer_letters": "Briefe", + "timeline_filter_trigger": "Filter", + "timeline_filter_trigger_active": "Filter ({count} aktiv)", + "timeline_filter_reset": "Filter zurücksetzen", + "timeline_filter_empty_state": "Keine Einträge entsprechen diesen Filtern.", "event_editor_new_title": "Neues Ereignis", "event_editor_edit_title": "Ereignis bearbeiten", "event_editor_section_when": "Wann", diff --git a/frontend/messages/en.json b/frontend/messages/en.json index 9ff1000e..8cedb0ea 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -1057,6 +1057,14 @@ "timeline_events_count": "{count} events", "timeline_letters_count_singular": "1 letter", "timeline_events_count_singular": "1 event", + "timeline_filter_label_layers": "Show layers", + "timeline_filter_layer_personal": "Personal events", + "timeline_filter_layer_historical": "Historical events", + "timeline_filter_layer_letters": "Letters", + "timeline_filter_trigger": "Filter", + "timeline_filter_trigger_active": "Filter ({count} active)", + "timeline_filter_reset": "Reset filters", + "timeline_filter_empty_state": "No entries match these filters.", "event_editor_new_title": "New event", "event_editor_edit_title": "Edit event", "event_editor_section_when": "When", diff --git a/frontend/messages/es.json b/frontend/messages/es.json index 2cd4548c..f03a1cbd 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -1057,6 +1057,14 @@ "timeline_events_count": "{count} eventos", "timeline_letters_count_singular": "1 carta", "timeline_events_count_singular": "1 evento", + "timeline_filter_label_layers": "Mostrar capas", + "timeline_filter_layer_personal": "Eventos personales", + "timeline_filter_layer_historical": "Eventos históricos", + "timeline_filter_layer_letters": "Cartas", + "timeline_filter_trigger": "Filtro", + "timeline_filter_trigger_active": "Filtro ({count} activos)", + "timeline_filter_reset": "Restablecer filtros", + "timeline_filter_empty_state": "Ninguna entrada coincide con estos filtros.", "event_editor_new_title": "Nuevo evento", "event_editor_edit_title": "Editar evento", "event_editor_section_when": "Cuándo", diff --git a/frontend/src/lib/messages.spec.ts b/frontend/src/lib/messages.spec.ts index 542a0d50..b3866877 100644 --- a/frontend/src/lib/messages.spec.ts +++ b/frontend/src/lib/messages.spec.ts @@ -98,4 +98,29 @@ describe('message key parity', () => { expect(en).toMatchObject({ timeline_tag_chip_label: 'Topic' }); expect(es).toMatchObject({ timeline_tag_chip_label: 'Tema' }); }); + + // #780 REQ-010: the layer-filter strings are Paraglide keys in every locale. + // timeline_filter_trigger (0 active) and timeline_filter_trigger_active ({count}, + // ≥1 active) are distinct keys so the trigger never reads "Filter (0 aktiv)". + it('zeitstrahl layer-filter keys are present in all locales (#780 REQ-010)', () => { + const requiredKeys = [ + 'timeline_filter_label_layers', + 'timeline_filter_layer_personal', + 'timeline_filter_layer_historical', + 'timeline_filter_layer_letters', + 'timeline_filter_trigger', + 'timeline_filter_trigger_active', + 'timeline_filter_reset', + 'timeline_filter_empty_state' + ]; + for (const key of requiredKeys) { + expect(de, `missing key in de: ${key}`).toHaveProperty(key); + expect(en, `missing key in en: ${key}`).toHaveProperty(key); + expect(es, `missing key in es: ${key}`).toHaveProperty(key); + } + // the active-count key carries the established {count} placeholder + expect(de.timeline_filter_trigger_active).toContain('{count}'); + expect(en.timeline_filter_trigger_active).toContain('{count}'); + expect(es.timeline_filter_trigger_active).toContain('{count}'); + }); });