feat(documents): timeline density refetches when other filters change (#385)

The +page.ts client-side load now forwards the active /documents URL
filters (q, senderId, receiverId, tag, tagQ, status, tagOp) to
/api/documents/density so the bars recompute when the user narrows the
search. Date bounds (from/to) are deliberately omitted — the chart is
the surface for picking those.

- New `DensityFilters` type and `buildDensityUrl(filters)` helper.
- `fetchDensity` accepts a filter snapshot (defaulting to {} for
  back-compat in tests).
- 6 new unit tests cover URL building, multi-tag repetition, AND/OR
  forwarding, the explicit-no-from/to invariant, and filter-aware fetch.
- Generated API types refreshed against the new backend signature.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-07 23:10:12 +02:00
parent e92e9e452e
commit 76023a99ed
4 changed files with 108 additions and 8 deletions

View File

@@ -1,10 +1,23 @@
import { browser } from '$app/environment';
import { fetchDensity } from '$lib/document/timeline';
import { fetchDensity, type DensityFilters } from '$lib/document/timeline';
import type { PageLoad } from './$types';
export const load: PageLoad = async ({ url, fetch, data }) => {
const view = url.searchParams.get('view');
const isDesktop = browser && window.matchMedia('(min-width: 640px)').matches;
const density = await fetchDensity(fetch, view, isDesktop);
// Forward active filters (excluding from/to) so the chart matches the list.
const tagOp = url.searchParams.get('tagOp');
const filters: DensityFilters = {
q: url.searchParams.get('q') ?? undefined,
senderId: url.searchParams.get('senderId') ?? undefined,
receiverId: url.searchParams.get('receiverId') ?? undefined,
tags: url.searchParams.getAll('tag'),
tagQ: url.searchParams.get('tagQ') ?? undefined,
status: url.searchParams.get('status') ?? undefined,
tagOp: tagOp === 'OR' ? 'OR' : 'AND'
};
const density = await fetchDensity(fetch, view, isDesktop, filters);
return { ...data, ...density };
};