From abba85a451cfd1b71ec4e8d6e1f1a0e62a1c3640 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 16 Apr 2026 16:25:27 +0200 Subject: [PATCH] feat(#221): wire tagOp URL param from server to SearchFilterBar Reads ?tagOp=OR from URL in +page.server.ts, passes it to the backend search endpoint, and surfaces it via the filters return. +page.svelte initialises tagOperator state from filters, writes it back to the URL in triggerSearch(), and binds it to SearchFilterBar. Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/routes/+page.server.ts | 6 ++++-- frontend/src/routes/+page.svelte | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/frontend/src/routes/+page.server.ts b/frontend/src/routes/+page.server.ts index 6a430477..258c8213 100644 --- a/frontend/src/routes/+page.server.ts +++ b/frontend/src/routes/+page.server.ts @@ -29,6 +29,7 @@ export async function load({ url, fetch }) { ? (rawDir as ValidDir) : 'desc'; const tagQ = url.searchParams.get('tagQ') || ''; + const tagOp = url.searchParams.get('tagOp') === 'OR' ? 'OR' : 'AND'; const isDashboard = !q && !from && !to && !senderId && !receiverId && !tags.length && !tagQ; @@ -48,6 +49,7 @@ export async function load({ url, fetch }) { receiverId: receiverId || undefined, tag: tags.length ? tags : undefined, tagQ: tagQ || undefined, + tagOp: tagOp === 'OR' ? 'OR' : undefined, sort, dir: dir || undefined } @@ -147,7 +149,7 @@ export async function load({ url, fetch }) { senderName: senderObj?.displayName ?? '', receiverName: receiverObj?.displayName ?? '' }, - filters: { q, from, to, senderId, receiverId, tags, sort, dir, tagQ }, + filters: { q, from, to, senderId, receiverId, tags, sort, dir, tagQ, tagOp }, error: null as string | null }; } catch (e) { @@ -166,7 +168,7 @@ export async function load({ url, fetch }) { readyDocs: [], weeklyStats: null, initialValues: { senderName: '', receiverName: '' }, - filters: { q, from, to, senderId, receiverId, tags, sort, dir, tagQ }, + filters: { q, from, to, senderId, receiverId, tags, sort, dir, tagQ, tagOp }, error: 'Daten konnten nicht geladen werden.' as string | null }; } diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index 1ca31d88..801b2280 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -26,6 +26,9 @@ let tagNames = $state<{ name: string; id?: string; color?: string; parentId?: st let sort = $state(untrack(() => data.filters?.sort || 'DATE')); let dir = $state(untrack(() => data.filters?.dir || 'desc')); let tagQ = $state(untrack(() => data.filters?.tagQ || '')); +let tagOperator = $state<'AND' | 'OR'>( + untrack(() => (data.filters?.tagOp as 'AND' | 'OR') || 'AND') +); const hasAdvancedFilters = (filters: typeof data.filters) => (filters?.tags?.length ?? 0) > 0 || @@ -49,6 +52,7 @@ function triggerSearch() { if (sort) params.set('sort', sort); if (dir) params.set('dir', dir); if (tagQ) params.set('tagQ', tagQ); + if (tagOperator === 'OR') params.set('tagOp', 'OR'); goto(`/?${params.toString()}`, { keepFocus: true, noScroll: true }); } @@ -79,6 +83,7 @@ $effect(() => { sort = data.filters?.sort || 'DATE'; dir = data.filters?.dir || 'desc'; tagQ = data.filters?.tagQ || ''; + tagOperator = (data.filters?.tagOp as 'AND' | 'OR') || 'AND'; if (hasAdvancedFilters(data.filters)) showAdvanced = true; }); @@ -104,6 +109,7 @@ const showRightColumn = $derived(data.canWrite || (data.incompleteDocs?.length ? bind:sort={sort} bind:dir={dir} bind:tagQ={tagQ} + bind:tagOperator={tagOperator} initialSenderName={data.initialValues?.senderName} initialReceiverName={data.initialValues?.receiverName} isLoading={navigating.to !== null}