diff --git a/site/src/api/api.ts b/site/src/api/api.ts index 0959a5c79124e..b042735357ab0 100644 --- a/site/src/api/api.ts +++ b/site/src/api/api.ts @@ -2434,9 +2434,13 @@ class ApiMethods { return res.data; }; - getInboxNotifications = async () => { + getInboxNotifications = async (startingBeforeId?: string) => { + const params = new URLSearchParams(); + if (startingBeforeId) { + params.append("starting_before", startingBeforeId); + } const res = await this.axios.get( - "/api/v2/notifications/inbox", + `/api/v2/notifications/inbox?${params.toString()}`, ); return res.data; }; diff --git a/site/src/components/ScrollArea/ScrollArea.tsx b/site/src/components/ScrollArea/ScrollArea.tsx index d4544a0ca2d33..2c3b2f3255755 100644 --- a/site/src/components/ScrollArea/ScrollArea.tsx +++ b/site/src/components/ScrollArea/ScrollArea.tsx @@ -18,7 +18,7 @@ export const ScrollArea = React.forwardRef< {children} - + )); diff --git a/site/src/modules/notifications/NotificationsInbox/InboxPopover.tsx b/site/src/modules/notifications/NotificationsInbox/InboxPopover.tsx index 7651a83ebed66..3a5cd92248b91 100644 --- a/site/src/modules/notifications/NotificationsInbox/InboxPopover.tsx +++ b/site/src/modules/notifications/NotificationsInbox/InboxPopover.tsx @@ -19,9 +19,12 @@ type InboxPopoverProps = { notifications: readonly InboxNotification[] | undefined; unreadCount: number; error: unknown; + isLoadingMoreNotifications: boolean; + hasMoreNotifications: boolean; onRetry: () => void; onMarkAllAsRead: () => void; onMarkNotificationAsRead: (notificationId: string) => void; + onLoadMoreNotifications: () => void; defaultOpen?: boolean; }; @@ -30,9 +33,12 @@ export const InboxPopover: FC = ({ unreadCount, notifications, error, + isLoadingMoreNotifications, + hasMoreNotifications, onRetry, onMarkAllAsRead, onMarkNotificationAsRead, + onLoadMoreNotifications, }) => { const [isOpen, setIsOpen] = useState(defaultOpen); @@ -41,12 +47,21 @@ export const InboxPopover: FC = ({ - + {/* * data-radix-scroll-area-viewport is used to set the max-height of the ScrollArea * https://github.com/shadcn-ui/ui/issues/542#issuecomment-2339361283 */} - + [data-radix-scroll-area-viewport]]:max-h-[var(--max-height)]", + ])} + >
= ({ onMarkNotificationAsRead={onMarkNotificationAsRead} /> ))} + {hasMoreNotifications && ( + + )}
) : (
diff --git a/site/src/modules/notifications/NotificationsInbox/NotificationsInbox.tsx b/site/src/modules/notifications/NotificationsInbox/NotificationsInbox.tsx index bee4d7482b6ce..78d119a7e371f 100644 --- a/site/src/modules/notifications/NotificationsInbox/NotificationsInbox.tsx +++ b/site/src/modules/notifications/NotificationsInbox/NotificationsInbox.tsx @@ -1,4 +1,4 @@ -import { API, watchInboxNotifications } from "api/api"; +import { watchInboxNotifications } from "api/api"; import { getErrorDetail, getErrorMessage } from "api/errors"; import type { ListInboxNotificationsResponse, @@ -11,10 +11,13 @@ import { useMutation, useQuery, useQueryClient } from "react-query"; import { InboxPopover } from "./InboxPopover"; const NOTIFICATIONS_QUERY_KEY = ["notifications"]; +const NOTIFICATIONS_LIMIT = 25; // This is hard set in the API type NotificationsInboxProps = { defaultOpen?: boolean; - fetchNotifications: () => Promise; + fetchNotifications: ( + startingBeforeId?: string, + ) => Promise; markAllAsRead: () => Promise; markNotificationAsRead: ( notificationId: string, @@ -30,12 +33,12 @@ export const NotificationsInbox: FC = ({ const queryClient = useQueryClient(); const { - data: res, + data: inboxRes, error, refetch, } = useQuery({ queryKey: NOTIFICATIONS_QUERY_KEY, - queryFn: fetchNotifications, + queryFn: () => fetchNotifications(), }); const updateNotificationsCache = useEffectEvent( @@ -75,6 +78,32 @@ export const NotificationsInbox: FC = ({ }; }, [updateNotificationsCache]); + const { + mutate: loadMoreNotifications, + isLoading: isLoadingMoreNotifications, + } = useMutation({ + mutationFn: async () => { + if (!inboxRes || inboxRes.notifications.length === 0) { + return; + } + const lastNotification = + inboxRes.notifications[inboxRes.notifications.length - 1]; + const newRes = await fetchNotifications(lastNotification.id); + updateNotificationsCache((prev) => { + return { + unread_count: newRes.unread_count, + notifications: [...prev.notifications, ...newRes.notifications], + }; + }); + }, + onError: (error) => { + displayError( + getErrorMessage(error, "Error loading more notifications"), + getErrorDetail(error), + ); + }, + }); + const markAllAsReadMutation = useMutation({ mutationFn: markAllAsRead, onSuccess: () => { @@ -122,12 +151,17 @@ export const NotificationsInbox: FC = ({ return ( ); }; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy