feat(ui): collapsible date filter with sort + filter toggle on person row
Some checks failed
CI / Unit & Component Tests (push) Failing after 1m13s
CI / Backend Unit Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Failing after 1m10s
CI / Backend Unit Tests (pull_request) Failing after 2m33s

Move sort button and filter toggle to the person row, matching the
document search page pattern (sort + filter + count inline). Date
range inputs are now a collapsible section behind the filter toggle,
using slide transition and the same grid layout as the document
search advanced filters. Fix date input padding (add px-3).

Refs: #179

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-06 22:34:14 +02:00
parent c4715f1637
commit c8b4bce003
4 changed files with 124 additions and 119 deletions

View File

@@ -1,14 +1,20 @@
<script lang="ts">
import PersonTypeahead from '$lib/components/PersonTypeahead.svelte';
import CorrespondentSuggestionsDropdown from './CorrespondentSuggestionsDropdown.svelte';
import { m } from '$lib/paraglide/messages.js';
interface Props {
senderId?: string;
receiverId?: string;
initialSenderName?: string;
initialReceiverName?: string;
sortDir?: string;
showAdvanced?: boolean;
documentCount?: number;
onapplyFilters: () => void;
onswapPersons: () => void;
ontoggleSort: () => void;
ontoggleAdvanced: () => void;
}
let {
@@ -16,8 +22,13 @@ let {
receiverId = $bindable(''),
initialSenderName = '',
initialReceiverName = '',
sortDir = 'DESC',
showAdvanced = false,
documentCount = 0,
onapplyFilters,
onswapPersons
onswapPersons,
ontoggleSort,
ontoggleAdvanced
}: Props = $props();
interface Correspondent {
@@ -53,6 +64,7 @@ function handleSuggestionSelect(id: string) {
}
</script>
<!-- Row 1: Person inputs -->
<div data-testid="conv-person-bar" class="flex items-end gap-4">
<!-- Person A -->
<div
@@ -127,3 +139,67 @@ function handleSuggestionSelect(id: string) {
{/if}
</div>
</div>
<!-- Row 2: Sort + Filter toggle + Count (mirrors document search bar pattern) -->
<div class="mt-4 flex items-center gap-4">
<!-- Sort button -->
<button
data-testid="conv-sort-btn"
type="button"
aria-label="Sortierung umkehren"
aria-pressed={sortDir === 'ASC'}
onclick={ontoggleSort}
class="flex items-center gap-2 border border-line bg-muted px-4 py-2.5 text-sm font-bold tracking-wide text-ink-2 uppercase transition hover:bg-muted hover:text-ink"
>
{#if sortDir === 'ASC'}
<svg
xmlns="http://www.w3.org/2000/svg"
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
class="h-4 w-4"><polyline points="18 15 12 9 6 15" /></svg
>
{m.conv_strip_sort_oldest()}
{:else}
<svg
xmlns="http://www.w3.org/2000/svg"
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
class="h-4 w-4"><polyline points="6 9 12 15 18 9" /></svg
>
{m.conv_strip_sort_newest()}
{/if}
</button>
<!-- Filter toggle button -->
<button
onclick={ontoggleAdvanced}
class="flex items-center gap-2 border border-line bg-muted px-4 py-2.5 text-sm font-bold tracking-wide text-ink-2 uppercase transition hover:bg-muted hover:text-ink"
>
<img
src="/degruyter-icons/Simple/Small-16px/SVG/Action/Chevron/Chevron-Down-SM.svg"
alt=""
aria-hidden="true"
class="h-4 w-4 transform transition-transform duration-200 {showAdvanced ? 'rotate-180' : ''}"
/>
{m.docs_btn_filter()}
</button>
<!-- Document count -->
<span data-testid="conv-strip-count" class="ml-auto text-sm font-bold text-ink-3">
{m.conv_letters_count({ count: documentCount })}
</span>
</div>