From 8ff00e4263e10f56eb0d8132e26183063dc37eeb Mon Sep 17 00:00:00 2001 From: Emir Karabeg Date: Fri, 4 Apr 2025 19:26:13 -0700 Subject: [PATCH] fix(notifications): dropdown logic and styling --- .../notification-dropdown-item.tsx | 39 ++--------------- .../notifications/notifications.tsx | 5 +-- sim/stores/notifications/store.ts | 43 ++++++++++++++----- 3 files changed, 38 insertions(+), 49 deletions(-) diff --git a/sim/app/w/[id]/components/control-bar/components/notification-dropdown-item/notification-dropdown-item.tsx b/sim/app/w/[id]/components/control-bar/components/notification-dropdown-item/notification-dropdown-item.tsx index 7a503340a1..c3a7f08b10 100644 --- a/sim/app/w/[id]/components/control-bar/components/notification-dropdown-item/notification-dropdown-item.tsx +++ b/sim/app/w/[id]/components/control-bar/components/notification-dropdown-item/notification-dropdown-item.tsx @@ -29,7 +29,7 @@ const NotificationColors = { console: 'text-foreground', api: 'text-[#802FFF]', marketplace: 'text-foreground', - info: 'text-blue-500', + info: 'text-foreground', } export function NotificationDropdownItem({ @@ -64,41 +64,8 @@ export function NotificationDropdownItem({ const notification = getFullNotification() if (notification) { - // For persistent notifications like API info, just re-show them - if (notification.options?.isPersistent) { - showNotification(id) - } else { - // For non-persistent notifications, we have different strategies: - - if (notification.isVisible) { - if (notification.isFading) { - // If it's currently fading, remove and re-add it to restart animation sequence - removeNotification(id) - - // Re-add with same properties but new ID - addNotification( - notification.type, - notification.message, - notification.workflowId, - notification.options - ) - } else { - // If visible but not fading, just make sure it's at the top of the stack - showNotification(id) - } - } else { - // If not visible, we re-add it instead of just showing it - // This ensures a fresh animation sequence - - // Create a new notification with same properties - addNotification( - notification.type, - notification.message, - notification.workflowId, - notification.options - ) - } - } + // Simply show the notification regardless of its current state + showNotification(id) } else { // Fallback for any case where the notification doesn't exist anymore addNotification(type, message, null, options) diff --git a/sim/app/w/[id]/components/notifications/notifications.tsx b/sim/app/w/[id]/components/notifications/notifications.tsx index f8aa9b6537..261a471e34 100644 --- a/sim/app/w/[id]/components/notifications/notifications.tsx +++ b/sim/app/w/[id]/components/notifications/notifications.tsx @@ -577,9 +577,8 @@ export function NotificationAlert({ notification, isFading, onHide }: Notificati diff --git a/sim/stores/notifications/store.ts b/sim/stores/notifications/store.ts index 0f179deda3..9b749d51bb 100644 --- a/sim/stores/notifications/store.ts +++ b/sim/stores/notifications/store.ts @@ -120,22 +120,31 @@ export const useNotificationStore = create()( const notification = state.notifications.find((n) => n.id === id) if (!notification) return { notifications: state.notifications } - // Bring the notification to the top and make it visible - const filteredNotifications = state.notifications.filter((n) => n.id !== id) - const updatedNotification = { ...notification, isVisible: true, read: false, isFading: false } - - // Put the notification at the top so it's easily visible in dropdowns - let newNotifications = [updatedNotification, ...filteredNotifications] + // Update the notification in place without changing its position + const newNotifications = state.notifications.map((n) => { + if (n.id === id) { + // Only update visibility state, preserve timestamp and position + return { + ...n, + isVisible: true, + read: false, + isFading: false + } + } + return n + }) // Check if we need to auto-fade older notifications due to the limit const workflowId = notification.workflowId; const workflowVisibleCount = get().getVisibleNotificationCount(workflowId); + let updatedNotifications = [...newNotifications]; + if (workflowVisibleCount > MAX_VISIBLE_NOTIFICATIONS) { // Find the oldest non-persistent visible notification to fade out - newNotifications = newNotifications.map((n, index) => { + updatedNotifications = updatedNotifications.map((n) => { // Don't touch the newly shown notification - if (index === 0) return n; + if (n.id === id) return n; // Only target notifications from the same workflow that are visible, not persistent, and not already fading if ( @@ -152,8 +161,22 @@ export const useNotificationStore = create()( }); } - persistNotifications(newNotifications) - return { notifications: newNotifications } + // If notification is not persistent, restart the fade timer + if (!notification.options?.isPersistent) { + setTimeout(() => { + // Start fade out animation + set((state) => { + const newNotifications = state.notifications.map((n) => + n.id === id ? { ...n, isFading: true } : n + ) + persistNotifications(newNotifications) + return { notifications: newNotifications } + }) + }, NOTIFICATION_TIMEOUT) + } + + persistNotifications(updatedNotifications) + return { notifications: updatedNotifications } }), markAsRead: (id) =>