From df79eec5ccc71c2402a96a614d08be438835c274 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 29 Mar 2026 00:42:54 +0100 Subject: [PATCH] feat(#145): add DashboardRecentDocuments widget component Shows recently reviewed documents as a dashboard widget with formatted dates. Renders nothing when the list is empty. Co-Authored-By: Claude Sonnet 4.6 --- .../DashboardRecentDocuments.svelte | 48 ++++++++++++++++ .../DashboardRecentDocuments.svelte.spec.ts | 57 +++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 frontend/src/lib/components/DashboardRecentDocuments.svelte create mode 100644 frontend/src/lib/components/DashboardRecentDocuments.svelte.spec.ts diff --git a/frontend/src/lib/components/DashboardRecentDocuments.svelte b/frontend/src/lib/components/DashboardRecentDocuments.svelte new file mode 100644 index 00000000..cb9ed9ac --- /dev/null +++ b/frontend/src/lib/components/DashboardRecentDocuments.svelte @@ -0,0 +1,48 @@ + + +{#if recentDocs.length > 0} +
+

+ Zuletzt hinzugefügt +

+ {#each recentDocs as doc (doc.id)} +
+ + {doc.title} + + {#if doc.documentDate} + + {formatDate(doc.documentDate)} + + {/if} +
+ {/each} +
+{/if} diff --git a/frontend/src/lib/components/DashboardRecentDocuments.svelte.spec.ts b/frontend/src/lib/components/DashboardRecentDocuments.svelte.spec.ts new file mode 100644 index 00000000..74ecf14d --- /dev/null +++ b/frontend/src/lib/components/DashboardRecentDocuments.svelte.spec.ts @@ -0,0 +1,57 @@ +import { describe, it, expect, afterEach } from 'vitest'; +import { cleanup, render } from 'vitest-browser-svelte'; +import { page } from 'vitest/browser'; + +import DashboardRecentDocuments from './DashboardRecentDocuments.svelte'; + +afterEach(cleanup); + +type Document = { + id: string; + title: string; + documentDate?: string; + sender?: { id: string; firstName: string; lastName: string }; +}; + +function makeDoc(id: string, title: string, date?: string): Document { + return { id, title, documentDate: date }; +} + +describe('DashboardRecentDocuments', () => { + it('renders nothing when recentDocs is empty', async () => { + render(DashboardRecentDocuments, { recentDocs: [] }); + const widget = page.getByTestId('dashboard-recent-docs'); + await expect.element(widget).not.toBeInTheDocument(); + }); + + it('shows the widget when recentDocs are present', async () => { + render(DashboardRecentDocuments, { recentDocs: [makeDoc('d1', 'Taufschein')] }); + const widget = page.getByTestId('dashboard-recent-docs'); + await expect.element(widget).toBeInTheDocument(); + }); + + it('renders a link to /documents/{id} for each document', async () => { + const docs = [makeDoc('d1', 'Taufschein'), makeDoc('d2', 'Heiratsurkunde')]; + render(DashboardRecentDocuments, { recentDocs: docs }); + const links = page.getByRole('link'); + await expect.element(links.nth(0)).toHaveAttribute('href', '/documents/d1'); + await expect.element(links.nth(1)).toHaveAttribute('href', '/documents/d2'); + }); + + it('shows the document title in each row', async () => { + render(DashboardRecentDocuments, { + recentDocs: [makeDoc('d1', 'Sterbeurkunde 1930', '1930-05-12')] + }); + await expect.element(page.getByText('Sterbeurkunde 1930')).toBeInTheDocument(); + }); + + it('formats and displays the document date when present', async () => { + render(DashboardRecentDocuments, { recentDocs: [makeDoc('d1', 'Dok', '1945-04-20')] }); + // The date should be visible in some formatted form + const widget = page.getByTestId('dashboard-recent-docs'); + await expect.element(widget).toBeInTheDocument(); + // Just verify the date element exists (not exact format due to locale) + const dateEl = page.getByTestId('doc-date-d1'); + await expect.element(dateEl).toBeInTheDocument(); + }); +});