diff --git a/frontend/src/lib/components/PersonMultiSelect.svelte b/frontend/src/lib/components/PersonMultiSelect.svelte index cffbf38f..c98ba5ab 100644 --- a/frontend/src/lib/components/PersonMultiSelect.svelte +++ b/frontend/src/lib/components/PersonMultiSelect.svelte @@ -1,15 +1,20 @@ - + {#each selectedPersons as person} @@ -69,7 +74,7 @@ {person.firstName} {person.lastName} - - {/each} +
+ +
+ + {#each tags as tag, i} + + {tag} + + + {/each} - -
- handleInput()} - on:blur={() => setTimeout(() => (showSuggestions = false), 200)} - placeholder={tags.length === 0 - ? allowCreation - ? 'Schlagworte hinzufügen...' - : 'Nach Schlagworten filtern...' - : ''} - class="w-full h-full border-none p-1 focus:ring-0 text-sm bg-transparent outline-none" - /> + +
+ fetchSuggestions(inputVal)} + onkeydown={handleKeydown} + onfocus={() => fetchSuggestions(inputVal)} + placeholder={tags.length === 0 + ? allowCreation + ? 'Schlagworte hinzufügen...' + : 'Nach Schlagworten filtern...' + : ''} + class="w-full h-full border-none p-1 focus:ring-0 text-sm bg-transparent outline-none" + /> - - {#if showSuggestions && suggestions.length > 0} -
    - {#each suggestions as suggestion, i} -
  • addTag(suggestion)} - on:keydown={(e) => e.key === 'Enter' && addTag(suggestion)} - > - {suggestion} -
  • - {/each} -
- {/if} -
-
- {#if allowCreation} -

Enter drücken um Schlagwort zu erstellen.

- {/if} + + {#if showSuggestions && suggestions.length > 0} +
    + {#each suggestions as suggestion, i} +
  • addTag(suggestion)} + onkeydown={(e) => e.key === 'Enter' && addTag(suggestion)} + > + {suggestion} +
  • + {/each} +
+ {/if} +
+
+ {#if allowCreation} +

Enter drücken um Schlagwort zu erstellen.

+ {/if} diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index 50dc8338..d019a23d 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -2,116 +2,112 @@ import './layout.css'; import { enhance } from '$app/forms'; import { page } from '$app/state'; - $: user = page.data.user; - $: isAdmin = user?.groups.some(g => g.permissions.includes("ADMIN")) + + let { children } = $props(); + + const isAdmin = $derived(page.data.user?.groups.some((g: { permissions: string[] }) => g.permissions.includes('ADMIN')));
- - - {#if !page.url.pathname.startsWith('/login')} -
-
-
- + {#if !page.url.pathname.startsWith('/login')} +
+
+
- - - -
-
- -
-
-
-
-
- {/if} + +
+
+ +
+
+
+
+
+ {/if} -
- -
+
+ {@render children()} +
diff --git a/frontend/src/routes/+page.svelte b/frontend/src/routes/+page.svelte index ceae8171..f1ea2f67 100644 --- a/frontend/src/routes/+page.svelte +++ b/frontend/src/routes/+page.svelte @@ -3,21 +3,19 @@ import PersonTypeahead from '$lib/components/PersonTypeahead.svelte'; import { goto } from '$app/navigation'; import TagInput from '$lib/components/TagInput.svelte'; import { slide } from 'svelte/transition'; +import { untrack } from 'svelte'; -export let data; +let { data } = $props(); -// Local state variables -let q = data.filters?.q || ''; -let from = data.filters?.from || ''; -let to = data.filters?.to || ''; -let senderId = data.filters?.senderId || ''; -let receiverId = data.filters?.receiverId || ''; -let tagNames = data.filters?.tags || []; +let q = $state(untrack(() => data.filters?.q || '')); +let from = $state(untrack(() => data.filters?.from || '')); +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 || [])); -// Debounce Timer -let searchTimer: any; - -let showAdvanced = false; +let searchTimer: ReturnType; +let showAdvanced = $state(false); function triggerSearch() { const params = new URLSearchParams(); @@ -42,27 +40,24 @@ function handleTextSearch() { }, 500); } -let previousTags = tagNames.join(','); -$: { - const currentTags = tagNames.join(','); - if (currentTags !== previousTags) { - previousTags = currentTags; +// Trigger search when tags change +let prevTagStr = untrack(() => tagNames.join(',')); +$effect(() => { + const cur = tagNames.join(','); + if (cur !== prevTagStr) { + prevTagStr = cur; triggerSearch(); } -} +}); -function toggleAdvanced() { - showAdvanced = !showAdvanced; -} - -// Sync with server data (e.g. after reset) -$: { +// Sync local state with server data after navigation +$effect(() => { q = data.filters?.q || ''; from = data.filters?.from || ''; to = data.filters?.to || ''; senderId = data.filters?.senderId || ''; receiverId = data.filters?.receiverId || ''; -} +}); @@ -76,7 +71,7 @@ $: { @@ -94,7 +89,7 @@ $: { @@ -384,7 +378,7 @@ $: { Versuchen Sie, die Filter anzupassen oder den Suchbegriff zu ändern.

(activeTab = 'users')}>Benutzer (activeTab = 'groups')}>Gruppen (activeTab = 'tags')}>Schlagworte @@ -106,7 +105,6 @@ {user.username} - - {:else if activeTab === 'tags'} -

Schlagworte

@@ -332,9 +324,9 @@ >
@@ -106,7 +87,7 @@ id="dateFrom" type="date" bind:value={fromDate} - on:change={() => applyFilters()} + onchange={() => applyFilters()} class="block w-full border-gray-300 shadow-sm focus:border-brand-navy focus:ring-brand-navy text-sm py-2.5" /> @@ -122,7 +103,7 @@ id="dateTo" type="date" bind:value={toDate} - on:change={() => applyFilters()} + onchange={() => applyFilters()} class="block w-full border-gray-300 shadow-sm focus:border-brand-navy focus:ring-brand-navy text-sm py-2.5" /> @@ -130,7 +111,7 @@
- {:else if documents.length === 0} + {:else if data.documents.length === 0}
@@ -178,18 +159,15 @@
{:else} -
-
-
- {#each documents as doc} + {#each data.documents as doc} {@const isRight = doc.sender?.id === senderId} @@ -200,7 +178,7 @@ ? 'flex-row-reverse' : 'flex-row'}" > - +