fix(#145): deep-link notifications; show createdAt in recent docs
- Notification widget builds full link with ?commentId= and &annotationId= params, matching the bell notification behaviour - Recent docs widget shows createdAt (upload date) instead of documentDate (the date on the original document) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,8 @@ type NotificationDTO = {
|
|||||||
id: string;
|
id: string;
|
||||||
type: 'REPLY' | 'MENTION';
|
type: 'REPLY' | 'MENTION';
|
||||||
documentId?: string;
|
documentId?: string;
|
||||||
|
referenceId?: string;
|
||||||
|
annotationId?: string;
|
||||||
read: boolean;
|
read: boolean;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
actorName?: string;
|
actorName?: string;
|
||||||
@@ -26,7 +28,9 @@ let { mentions }: Props = $props();
|
|||||||
<div class="flex items-center gap-3 border-b border-line py-2 last:border-0">
|
<div class="flex items-center gap-3 border-b border-line py-2 last:border-0">
|
||||||
{#if mention.documentId}
|
{#if mention.documentId}
|
||||||
<a
|
<a
|
||||||
href="/documents/{mention.documentId}"
|
href={mention.annotationId
|
||||||
|
? `/documents/${mention.documentId}?commentId=${mention.referenceId}&annotationId=${mention.annotationId}`
|
||||||
|
: `/documents/${mention.documentId}?commentId=${mention.referenceId}`}
|
||||||
class="font-serif text-sm text-ink hover:text-ink-2"
|
class="font-serif text-sm text-ink hover:text-ink-2"
|
||||||
>
|
>
|
||||||
{mention.actorName ?? ''}
|
{mention.actorName ?? ''}
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ type NotificationDTO = {
|
|||||||
id: string;
|
id: string;
|
||||||
type: 'REPLY' | 'MENTION';
|
type: 'REPLY' | 'MENTION';
|
||||||
documentId?: string;
|
documentId?: string;
|
||||||
|
referenceId?: string;
|
||||||
|
annotationId?: string;
|
||||||
read: boolean;
|
read: boolean;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
actorName?: string;
|
actorName?: string;
|
||||||
@@ -20,6 +22,7 @@ function makeMention(overrides: Partial<NotificationDTO> = {}): NotificationDTO
|
|||||||
id: 'notif-1',
|
id: 'notif-1',
|
||||||
type: 'MENTION',
|
type: 'MENTION',
|
||||||
documentId: 'doc-abc',
|
documentId: 'doc-abc',
|
||||||
|
referenceId: 'comment-xyz',
|
||||||
read: false,
|
read: false,
|
||||||
createdAt: '2026-01-15T10:00:00Z',
|
createdAt: '2026-01-15T10:00:00Z',
|
||||||
actorName: 'Anna Schmidt',
|
actorName: 'Anna Schmidt',
|
||||||
@@ -40,15 +43,22 @@ describe('DashboardMentions', () => {
|
|||||||
await expect.element(widget).toBeInTheDocument();
|
await expect.element(widget).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders one row per mention with link to document', async () => {
|
it('builds link with commentId param when no annotationId', async () => {
|
||||||
const mentions = [
|
render(DashboardMentions, {
|
||||||
makeMention({ id: 'n1', documentId: 'doc-1', actorName: 'Anna' }),
|
mentions: [makeMention({ documentId: 'doc-1', referenceId: 'cmt-1' })]
|
||||||
makeMention({ id: 'n2', documentId: 'doc-2', actorName: 'Bob' })
|
});
|
||||||
];
|
const link = page.getByRole('link');
|
||||||
render(DashboardMentions, { mentions });
|
await expect.element(link).toHaveAttribute('href', '/documents/doc-1?commentId=cmt-1');
|
||||||
const links = page.getByRole('link');
|
});
|
||||||
await expect.element(links.nth(0)).toHaveAttribute('href', '/documents/doc-1');
|
|
||||||
await expect.element(links.nth(1)).toHaveAttribute('href', '/documents/doc-2');
|
it('builds link with commentId and annotationId when annotationId is present', async () => {
|
||||||
|
render(DashboardMentions, {
|
||||||
|
mentions: [makeMention({ documentId: 'doc-2', referenceId: 'cmt-2', annotationId: 'ann-9' })]
|
||||||
|
});
|
||||||
|
const link = page.getByRole('link');
|
||||||
|
await expect
|
||||||
|
.element(link)
|
||||||
|
.toHaveAttribute('href', '/documents/doc-2?commentId=cmt-2&annotationId=ann-9');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows actor name in each row', async () => {
|
it('shows actor name in each row', async () => {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { getLocale } from '$lib/paraglide/runtime.js';
|
|||||||
type Document = {
|
type Document = {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
documentDate?: string;
|
createdAt?: string;
|
||||||
sender?: { id: string; firstName: string; lastName: string };
|
sender?: { id: string; firstName: string; lastName: string };
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ function formatDate(dateStr: string): string {
|
|||||||
day: 'numeric',
|
day: 'numeric',
|
||||||
month: 'long',
|
month: 'long',
|
||||||
year: 'numeric'
|
year: 'numeric'
|
||||||
}).format(new Date(dateStr + 'T12:00:00'));
|
}).format(new Date(dateStr));
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -37,12 +37,12 @@ function formatDate(dateStr: string): string {
|
|||||||
>
|
>
|
||||||
{doc.title}
|
{doc.title}
|
||||||
</a>
|
</a>
|
||||||
{#if doc.documentDate}
|
{#if doc.createdAt}
|
||||||
<span
|
<span
|
||||||
data-testid="doc-date-{doc.id}"
|
data-testid="doc-date-{doc.id}"
|
||||||
class="ml-2 shrink-0 font-sans text-xs text-gray-400"
|
class="ml-2 shrink-0 font-sans text-xs text-gray-400"
|
||||||
>
|
>
|
||||||
{formatDate(doc.documentDate)}
|
{formatDate(doc.createdAt)}
|
||||||
</span>
|
</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ afterEach(cleanup);
|
|||||||
type Document = {
|
type Document = {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
documentDate?: string;
|
createdAt?: string;
|
||||||
sender?: { id: string; firstName: string; lastName: string };
|
sender?: { id: string; firstName: string; lastName: string };
|
||||||
};
|
};
|
||||||
|
|
||||||
function makeDoc(id: string, title: string, date?: string): Document {
|
function makeDoc(id: string, title: string, createdAt?: string): Document {
|
||||||
return { id, title, documentDate: date };
|
return { id, title, createdAt };
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('DashboardRecentDocuments', () => {
|
describe('DashboardRecentDocuments', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user