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 { useEffect, useState } from 'react'; import { useStore } from 'zustand'; 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] ); if (userNotifications && userNotifications.length > 1) { userNotifications.sort( (a, b) => new Date(b.timeStamp).getTime() - new Date(a.timeStamp).getTime() ); } const [badge, setBadge] = useState(false); useEffect(() => { if (userNotifications?.length > 0) { setBadge(true); } else { setBadge(false); } }, [userNotifications]); return (

Notifications

{userNotifications?.length > 0 && ( )}
{userNotifications?.length > 0 ? ( <>
{userNotifications.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'; }