{
+ 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}
+
+ {badge}
+
+ {/if}
+{/snippet}
+
+
+
+
+ {@render count()}
+
+
+
+
+
+ {@render count()}
+
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)}>
+