From 78fdb01ec1913b053297e8a31c2c5e5457aff639 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 6 Apr 2026 13:58:53 +0200 Subject: [PATCH] feat(search): wire sort/dir/tagQ state into page.svelte and URL params Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/routes/+page.svelte | 12 ++++++++++++ frontend/src/routes/page.svelte.spec.ts | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index cff0779d..3583e9bc 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -19,6 +19,9 @@ let to = $state(untrack(() => data.filters?.to || '')); let senderId = $state(untrack(() => data.filters?.senderId || '')); let receiverId = $state(untrack(() => data.filters?.receiverId || '')); let tagNames = $state(untrack(() => data.filters?.tags || [])); +let sort = $state(untrack(() => data.filters?.sort || 'DATE')); +let dir = $state(untrack(() => data.filters?.dir || 'desc')); +let tagQ = $state(untrack(() => data.filters?.tagQ || '')); const hasAdvancedFilters = (filters: typeof data.filters) => (filters?.tags?.length ?? 0) > 0 || @@ -39,6 +42,9 @@ function triggerSearch() { if (senderId) params.set('senderId', senderId); if (receiverId) params.set('receiverId', receiverId); if (tagNames) tagNames.forEach((tag) => params.append('tag', tag)); + if (sort) params.set('sort', sort); + if (dir) params.set('dir', dir); + if (tagQ) params.set('tagQ', tagQ); goto(`/?${params.toString()}`, { keepFocus: true, noScroll: true }); } @@ -66,6 +72,9 @@ $effect(() => { senderId = data.filters?.senderId || ''; receiverId = data.filters?.receiverId || ''; tagNames = data.filters?.tags || []; + sort = data.filters?.sort || 'DATE'; + dir = data.filters?.dir || 'desc'; + tagQ = data.filters?.tagQ || ''; if (hasAdvancedFilters(data.filters)) showAdvanced = true; }); @@ -88,6 +97,9 @@ const showRightColumn = $derived(data.canWrite || (data.incompleteDocs?.length ? bind:receiverId={receiverId} bind:tagNames={tagNames} bind:showAdvanced={showAdvanced} + bind:sort={sort} + bind:dir={dir} + bind:tagQ={tagQ} initialSenderName={data.initialValues?.senderName} initialReceiverName={data.initialValues?.receiverName} onSearch={handleTextSearch} diff --git a/frontend/src/routes/page.svelte.spec.ts b/frontend/src/routes/page.svelte.spec.ts index a8c31e67..856b8c66 100644 --- a/frontend/src/routes/page.svelte.spec.ts +++ b/frontend/src/routes/page.svelte.spec.ts @@ -239,3 +239,27 @@ describe('Home page – error state', () => { await page.screenshot({ path: 'test-results/screenshots/home-error.png' }); }); }); + +// ─── Sort controls ──────────────────────────────────────────────────────────── + +describe('Home page – sort controls', () => { + it('pre-fills sort from filters.sort', async () => { + const data = { + ...emptyData, + filters: { ...emptyData.filters, sort: 'TITLE', dir: 'asc', tagQ: '' } + }; + render(Page, { data }); + const select = page.getByRole('combobox'); + await expect.element(select).toHaveValue('TITLE'); + }); + + it('renders direction toggle with asc indicator when dir is asc', async () => { + const data = { + ...emptyData, + filters: { ...emptyData.filters, sort: 'DATE', dir: 'asc', tagQ: '' } + }; + render(Page, { data }); + const btn = page.getByRole('button', { name: /aufsteigend/i }); + await expect.element(btn).toBeInTheDocument(); + }); +});