diff --git a/web/src/lib/components/notifications/NotificationBell.stories.svelte b/web/src/lib/components/notifications/NotificationBell.stories.svelte new file mode 100644 index 000000000..149a32150 --- /dev/null +++ b/web/src/lib/components/notifications/NotificationBell.stories.svelte @@ -0,0 +1,38 @@ + + + + + + + + + + + { + const canvas = within(canvasElement); + await userEvent.click(canvas.getByRole("button", { name: /notifications/i })); + await waitFor(() => expect(canvas.getByRole("link", { name: /view all/i })).toBeVisible()); + }} +/> diff --git a/web/src/lib/components/notifications/NotificationBell.svelte b/web/src/lib/components/notifications/NotificationBell.svelte new file mode 100644 index 000000000..d63c3df53 --- /dev/null +++ b/web/src/lib/components/notifications/NotificationBell.svelte @@ -0,0 +1,148 @@ + + +{#snippet count()} + {#if unreadCount > 0} + + {/if} +{/snippet} + + +
+
+ + diff --git a/web/src/lib/components/notifications/NotificationItem.svelte b/web/src/lib/components/notifications/NotificationItem.svelte index 6954b05f4..6bb0005a4 100644 --- a/web/src/lib/components/notifications/NotificationItem.svelte +++ b/web/src/lib/components/notifications/NotificationItem.svelte @@ -13,7 +13,7 @@ target: "text-foreground-default", meta: "relative row-start-1 flex items-center justify-end", time: "typography-paragraph-small whitespace-nowrap text-foreground-subtle", - toggle: "absolute inset-0 hidden items-center justify-end text-foreground-placeholder hover:text-foreground-muted md:group-hover/notification:flex hover:cursor-pointer", + toggle: "absolute inset-0 hidden items-center justify-end text-foreground-placeholder hover:cursor-pointer hover:text-foreground-muted md:group-hover/notification:flex", number: "col-start-1 row-start-2 text-left typography-paragraph-small text-foreground-muted", title: "col-start-2 row-start-2 truncate typography-paragraph-small text-foreground-muted" }, @@ -65,9 +65,17 @@ event.stopPropagation(); onToggleRead?.(notification.id, !notification.read); }; + + // client-side navigation leaves a popover open, so a row inside the topbar + // dropdown has to dismiss it on the way out + const open = (event: MouseEvent & { currentTarget: HTMLAnchorElement }) => { + onToggleRead?.(notification.id, true); + const popover = event.currentTarget.closest("[popover]"); + if (popover instanceof HTMLElement) popover.hidePopover(); + }; - onToggleRead?.(notification.id, true)}> +