import clsx from 'clsx'; import { Menu, MenuButton, MenuList, MenuLink as ReachMenuLink, } from '@reach/menu-button'; import { UISrefProps, useSref } from '@uirouter/react'; import Moment from 'moment'; import { useStore } from 'zustand'; import { AlertCircle, Bell, CheckCircle, Trash2 } from 'lucide-react'; import { AutomationTestingProps } from '@/types'; import { useUser } from '@/react/hooks/useUser'; import { ToastNotification } from '@/react/portainer/notifications/types'; import { Icon } from '@@/Icon'; import { Link } from '@@/Link'; import { Button } from '@@/buttons'; import { notificationsStore } from '../../portainer/notifications/notifications-store'; import headerStyles from './HeaderTitle.module.css'; import notificationStyles from './NotificationsMenu.module.css'; export function NotificationsMenu() { const notificationsStoreState = useStore(notificationsStore); const { removeNotification } = notificationsStoreState; const { clearUserNotifications } = notificationsStoreState; const { user } = useUser(); const userNotifications: ToastNotification[] = useStore( notificationsStore, (state) => state.userNotifications[user.Id] ); const reducedNotifications = userNotifications?.slice(0, 50); return (
0 ? notificationStyles.badge : '' } />

Notifications

{reducedNotifications?.length > 0 && ( )}
{reducedNotifications?.length > 0 ? ( <>
{reducedNotifications.map((notification) => ( onDelete(notification.id)} /> ))}
View all notifications
) : (

You have no notifications yet.

)}
); function onDelete(notificationId: string) { removeNotification(user.Id, notificationId); } function onClear() { clearUserNotifications(user.Id); } } interface MenuLinkProps extends AutomationTestingProps, UISrefProps { notification: ToastNotification; onDelete: () => void; } function MenuLink({ to, params, notification, onDelete }: MenuLinkProps) { const anchorProps = useSref(to, params); return (
{notification.type === 'success' ? ( ) : ( )}

{notification.title}

{notification.details}

{formatTime(notification.timeStamp)}

); } function formatTime(timeCreated: Date) { const timeStamp = new Date(timeCreated).valueOf().toString(); const diff = Math.floor((Date.now() - parseInt(timeStamp, 10)) / 1000); if (diff <= 86400) { let interval = Math.floor(diff / 3600); if (interval >= 1) { return `${interval} hours ago`; } interval = Math.floor(diff / 60); if (interval >= 1) { return `${interval} min ago`; } } if (diff > 86400) { const formatDate = Moment(timeCreated).format('YYYY-MM-DD h:mm:ss'); return formatDate; } return 'Just now'; }