feat(documents): wire TimelineDensityFilter into /documents/+page (#385)

Mounts the timeline above the result count, hidden on mobile via
\`hidden sm:block\` (defense-in-depth — +page.ts already gates the fetch).
The component's onchange callback updates local from/to and triggers
the existing search reload, so timeline selection composes with the
SearchFilterBar's other filters via AND semantics for free.

3 new page-level integration tests cover: widget renders when density
present, hides when null, and bar click navigates with correct
from/to URL params.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-07 22:16:05 +02:00
parent d43d73f231
commit 6786c0112d
2 changed files with 58 additions and 0 deletions

View File

@@ -135,3 +135,45 @@ describe('documents page — URL building', () => {
expect(url).not.toContain('page=');
});
});
// ─── Timeline density widget wiring (#385) ────────────────────────────────────
describe('documents page — timeline density widget', () => {
it('renders the timeline widget when density data is present', async () => {
render(Page, {
data: makeData({
density: [{ month: '1915-08', count: 3 }],
minDate: '1915-08-01',
maxDate: '1915-08-31'
})
});
await expect.element(page.getByTestId('timeline-density-filter')).toBeInTheDocument();
});
it('hides the timeline widget when density is null (mobile / calendar view)', async () => {
render(Page, { data: makeData({ density: null, minDate: null, maxDate: null }) });
expect(document.querySelector('[data-testid="timeline-density-filter"]')).toBeNull();
});
it('clicking a timeline bar navigates with from/to set to that month boundary', async () => {
const { goto } = await import('$app/navigation');
vi.mocked(goto).mockClear();
render(Page, {
data: makeData({
density: [{ month: '1915-08', count: 3 }],
minDate: '1915-08-01',
maxDate: '1915-08-31'
})
});
const bar = document.querySelector('[data-testid="timeline-bar"]') as HTMLButtonElement;
bar.dispatchEvent(new MouseEvent('click', { bubbles: true }));
expect(goto).toHaveBeenCalledOnce();
const [url] = vi.mocked(goto).mock.calls[0];
expect(url).toContain('from=1915-08-01');
expect(url).toContain('to=1915-08-31');
});
});