diff --git a/frontend/src/routes/zeitstrahl/+page.svelte b/frontend/src/routes/zeitstrahl/+page.svelte index 73ecb287..7126a5ba 100644 --- a/frontend/src/routes/zeitstrahl/+page.svelte +++ b/frontend/src/routes/zeitstrahl/+page.svelte @@ -8,14 +8,11 @@ import type { PageData } from './$types'; let { data }: { data: PageData } = $props(); -const meta = $derived(timelineMeta(data.timeline)); const hasContent = $derived(data.timeline.years.length > 0 || data.timeline.undated.length > 0); // Layer-filter state (#780). Layer hiding is client-side only — the whole // timeline is loaded once by #779's SSR load and we derive a filtered view of -// it here; there is no goto, no URL param, and no extra fetch. Known limitation -// (D1): the meta-line counts above stay on the unfiltered timeline, so they -// include entries the active toggles hide. +// it here; there is no goto, no URL param, and no extra fetch. let personalOn = $state(true); let historicalOn = $state(true); let lettersOn = $state(true); @@ -27,6 +24,11 @@ const filteredEmpty = $derived( filteredTimeline.years.length === 0 && filteredTimeline.undated.length === 0 ); +// Meta-line figures track the *filtered* view, so the header counts always +// match what is actually on screen once layers are toggled off (#780 — this +// closes the prior D1 limitation, where the counts stayed on the full timeline). +const meta = $derived(timelineMeta(filteredTimeline)); + function resetFilters() { personalOn = true; historicalOn = true; diff --git a/frontend/src/routes/zeitstrahl/page.svelte.spec.ts b/frontend/src/routes/zeitstrahl/page.svelte.spec.ts index d3c03ce3..3266c171 100644 --- a/frontend/src/routes/zeitstrahl/page.svelte.spec.ts +++ b/frontend/src/routes/zeitstrahl/page.svelte.spec.ts @@ -196,4 +196,20 @@ describe('/zeitstrahl layer filter (#780)', () => { await page.getByTestId('timeline-filter-empty-reset').click(); await expect.element(page.getByText('Brief Eins')).toBeVisible(); }); + + it('recomputes the meta-line counts from the filtered view, so a hidden layer drops out of the totals (#780, resolves D1)', async () => { + render(Page, { data: pageData(mixed()) }); + const meta = page.getByTestId('timeline-meta'); + // all layers on → the one letter and the two events are counted + await expect.element(meta).toHaveTextContent(m.timeline_letters_count_singular()); + await expect.element(meta).toHaveTextContent(m.timeline_events_count({ count: 2 })); + + await openBar(); + await page.getByTestId('timeline-filter-letters').click(); + + // the hidden letter leaves the count instead of lingering as "1 Brief"; + // the event total is untouched + await expect.element(meta).not.toHaveTextContent(m.timeline_letters_count_singular()); + await expect.element(meta).toHaveTextContent(m.timeline_events_count({ count: 2 })); + }); });