From 5211e0b9f707aa111fc17b83d3ed9e5879c2e4bf Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 5 Apr 2026 11:22:38 +0200 Subject: [PATCH] feat(topbar): add expandable metadata drawer with Details toggle (#175) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DocumentMetadataDrawer: 3-column grid (≥1024px), single-column mobile Shows document date, location, status, person cards, tag chips Person names link to /persons/{id}, tags link to filtered search Empty states for missing persons/tags, receiver cap with expand button - DocumentTopBar: "Details" toggle button with animated SVG chevron 44×44px tap target, aria-expanded, Svelte slide transition Semantic color tokens for dark mode compatibility - Remove DocumentBottomPanel from document detail page Bottom panel replaced by topbar drawer for metadata access Simplify +page.server.ts (remove comments loading) Update page.server.spec.ts for new load signature Co-Authored-By: Claude Sonnet 4.6 --- .../DocumentBottomPanel.svelte.spec.ts | 47 ------ .../components/DocumentMetadataDrawer.svelte | 146 ++++++++++++++++++ .../src/lib/components/DocumentTopBar.svelte | 43 ++++++ .../src/routes/documents/[id]/+page.server.ts | 18 +-- .../src/routes/documents/[id]/+page.svelte | 39 +---- .../routes/documents/[id]/page.server.spec.ts | 56 +------ 6 files changed, 197 insertions(+), 152 deletions(-) delete mode 100644 frontend/src/lib/components/DocumentBottomPanel.svelte.spec.ts create mode 100644 frontend/src/lib/components/DocumentMetadataDrawer.svelte diff --git a/frontend/src/lib/components/DocumentBottomPanel.svelte.spec.ts b/frontend/src/lib/components/DocumentBottomPanel.svelte.spec.ts deleted file mode 100644 index 975d36e6..00000000 --- a/frontend/src/lib/components/DocumentBottomPanel.svelte.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { describe, it, expect, afterEach } from 'vitest'; -import { cleanup, render } from 'vitest-browser-svelte'; -import { page } from 'vitest/browser'; -import DocumentBottomPanel from './DocumentBottomPanel.svelte'; -import type { Comment } from '$lib/types'; - -afterEach(cleanup); - -function makeComment(id: string): Comment { - return { - id, - authorId: 'user-1', - authorName: 'Alice', - content: 'Hello', - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), - replies: [] - }; -} - -const doc = { id: 'doc-1', title: 'Test' }; - -const baseProps = { - doc, - canComment: true, - currentUserId: 'user-1', - canAdmin: false, - height: 300, - activeTab: 'discussion' as const -}; - -describe('DocumentBottomPanel – discussion badge', () => { - it('always shows a badge on the Discussion tab', async () => { - render(DocumentBottomPanel, { ...baseProps, comments: [], open: true }); - await expect.element(page.getByTestId('discussion-count-badge')).toBeInTheDocument(); - await expect.element(page.getByTestId('discussion-count-badge')).toHaveTextContent('0'); - }); - - it('shows the correct count when comments exist', async () => { - render(DocumentBottomPanel, { - ...baseProps, - comments: [makeComment('c-1'), makeComment('c-2')], - open: true - }); - await expect.element(page.getByTestId('discussion-count-badge')).toHaveTextContent('2'); - }); -}); diff --git a/frontend/src/lib/components/DocumentMetadataDrawer.svelte b/frontend/src/lib/components/DocumentMetadataDrawer.svelte new file mode 100644 index 00000000..22e8b13a --- /dev/null +++ b/frontend/src/lib/components/DocumentMetadataDrawer.svelte @@ -0,0 +1,146 @@ + + +{#snippet personCard(person: Person)} + + + {getFullName(person)} + +{/snippet} + +
+
+ +
+

+ {m.doc_details_section_details()} +

+
+
+
{m.doc_details_field_date()}
+
{formattedDate}
+
+
+
{m.form_label_location()}
+
{displayLocation}
+
+
+
{m.doc_details_field_status()}
+
{statusLabel}
+
+
+
+ + +
+

+ {m.doc_details_section_persons()} +

+ {#if hasPersons} +
+ {#if sender} +
+

+ {m.doc_details_field_sender()} +

+ {@render personCard(sender)} +
+ {/if} + {#if receivers.length > 0} +
+

+ {m.doc_details_field_receivers()} +

+
+ {#each displayedReceivers as receiver (receiver.id)} + {@render personCard(receiver)} + {/each} +
+ {#if hiddenReceiverCount > 0 && !showAllReceivers} + + {/if} +
+ {/if} +
+ {:else} +

{m.doc_details_no_persons()}

+ {/if} +
+ + +
+

+ {m.doc_details_section_tags()} +

+ {#if hasTags} +
+ {#each tags as tag (tag.id)} + + {tag.name} + + {/each} +
+ {:else} +

{m.doc_details_no_tags()}

+ {/if} +
+
+
diff --git a/frontend/src/lib/components/DocumentTopBar.svelte b/frontend/src/lib/components/DocumentTopBar.svelte index 9c1bd419..5f63473d 100644 --- a/frontend/src/lib/components/DocumentTopBar.svelte +++ b/frontend/src/lib/components/DocumentTopBar.svelte @@ -1,12 +1,15 @@