import React, { useEffect } from 'react'; import { Button, EmptyState, EmptyStateBody, EmptyStateHeader, EmptyStateIcon, NotificationBadge, NotificationBadgeVariant, NotificationDrawer, NotificationDrawerBody, NotificationDrawerHeader, NotificationDrawerList, NotificationDrawerListItem, NotificationDrawerListItemBody, NotificationDrawerListItemHeader, PageSection, PageSectionVariants, TextContent, Text, EmptyStateVariant, NumberInput, Alert, AlertProps, AlertGroup, AlertActionCloseButton, ToolbarItem, Dropdown, DropdownList, DropdownItem, MenuToggle, MenuToggleElement } from '@breakaway/preact-core'; import SearchIcon from '@patternfly/react-icons/dist/js/icons/search-icon'; import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon'; import DashboardWrapper from '../DashboardWrapper'; import DashboardHeader from '../DashboardHeader'; interface NotificationProps { title: string; srTitle: string; variant: 'default' | 'success' | 'danger' | 'warning' | 'info'; key: React.Key; timestamp: string; description: string; isNotificationRead: boolean; } export const AlertGroupToastWithNotificationDrawer: React.FunctionComponent = () => { const maxDisplayedAlerts = 3; const minAlerts = 0; const maxAlerts = 100; const alertTimeout = 8000; const [isDrawerExpanded, setDrawerExpanded] = React.useState(false); const [openDropdownKey, setOpenDropdownKey] = React.useState(null); const [overflowMessage, setOverflowMessage] = React.useState(''); const [maxDisplayed, setMaxDisplayed] = React.useState(maxDisplayedAlerts); const [alerts, setAlerts] = React.useState[]>([]); const [notifications, setNotifications] = React.useState([]); useEffect(() => { setOverflowMessage(buildOverflowMessage()); }, [maxDisplayed, notifications, alerts]); const addNewNotification = (variant: NotificationProps['variant']) => { const variantFormatted = variant.charAt(0).toUpperCase() + variant.slice(1); const title = variantFormatted + ' alert notification'; const srTitle = variantFormatted + ' alert'; const description = variantFormatted + ' alert notification description'; const key = getUniqueId(); const timestamp = getTimeCreated(); setNotifications((prevNotifications) => [ { title, srTitle, variant, key, timestamp, description, isNotificationRead: false }, ...prevNotifications ]); if (!isDrawerExpanded) { setAlerts((prevAlerts) => [ removeAlert(key)} isLiveRegion actionClose={ removeAlert(key)} /> } key={key} id={key.toString()} >

{description}

, ...prevAlerts ]); } }; const removeNotification = (key: React.Key) => { setNotifications((prevNotifications) => prevNotifications.filter((notification) => notification.key !== key)); }; const removeAllNotifications = () => { setNotifications([]); }; const isNotificationRead = (key: React.Key) => notifications.find((notification) => notification.key === key)?.isNotificationRead; const markNotificationRead = (key: React.Key) => { setNotifications((prevNotifications) => prevNotifications.map((notification) => notification.key === key ? { ...notification, isNotificationRead: true } : notification ) ); }; const markAllNotificationsRead = () => { setNotifications((prevNotifications) => prevNotifications.map((notification) => ({ ...notification, isNotificationRead: true })) ); }; const getUnreadNotificationsNumber = () => notifications.filter((notification) => notification.isNotificationRead === false).length; const containsUnreadAlertNotification = () => notifications.filter( (notification) => notification.isNotificationRead === false && notification.variant === 'danger' ).length > 0; const getNotificationBadgeVariant = () => { if (getUnreadNotificationsNumber() === 0) { return NotificationBadgeVariant.read; } if (containsUnreadAlertNotification()) { return NotificationBadgeVariant.attention; } return NotificationBadgeVariant.unread; }; const onNotificationBadgeClick = () => { removeAllAlerts(); setDrawerExpanded(!isDrawerExpanded); }; const onDropdownToggle = (id: React.Key) => { if (id && openDropdownKey !== id) { setOpenDropdownKey(id); return; } setOpenDropdownKey(null); }; const onDropdownSelect = () => { setOpenDropdownKey(null); }; const buildOverflowMessage = () => { const overflow = alerts.length - maxDisplayed; if (overflow > 0 && maxDisplayed > 0) { return `View ${overflow} more notification(s) in notification drawer`; } return ''; }; const getUniqueId = () => new Date().getTime(); const getTimeCreated = () => { const dateCreated = new Date(); return ( dateCreated.toDateString() + ' at ' + ('00' + dateCreated.getHours().toString()).slice(-2) + ':' + ('00' + dateCreated.getMinutes().toString()).slice(-2) ); }; const removeAlert = (key: React.Key) => { setAlerts((prevAlerts) => prevAlerts.filter((alert) => alert.props.id !== key.toString())); }; const removeAllAlerts = () => { setAlerts([]); }; const onAlertGroupOverflowClick = () => { removeAllAlerts(); setDrawerExpanded(true); }; const onMaxDisplayedAlertsMinus = () => { setMaxDisplayed(normalizeAlertsNumber(maxDisplayed - 1)); }; const onMaxDisplayedAlertsChange = (event: any) => { setMaxDisplayed(normalizeAlertsNumber(Number(event.target.value))); }; const onMaxDisplayedAlertsPlus = () => { setMaxDisplayed(normalizeAlertsNumber(maxDisplayed + 1)); }; const normalizeAlertsNumber = (value: number) => Math.max(Math.min(value, maxAlerts), minAlerts); const alertButtonStyle = { marginRight: '8px', marginTop: '8px' }; const notificationBadge = ( ); const notificationDrawerActions = ( <> Mark all read Clear all ); const notificationDrawerDropdownItems = (key: React.Key) => [ markNotificationRead(key)}> Mark as read , removeNotification(key)}> Clear ]; const notificationDrawer = ( setDrawerExpanded(false)}> !isOpen && setOpenDropdownKey(null)} toggle={(toggleRef: React.Ref) => ( onDropdownToggle('dropdown-toggle-id-0')} aria-label="Notification drawer actions" > )} > {notificationDrawerActions} {notifications.length !== 0 && ( {notifications.map(({ key, variant, title, srTitle, description, timestamp }, index) => ( markNotificationRead(key)} > !isOpen && setOpenDropdownKey(null)} toggle={(toggleRef: React.Ref) => ( onDropdownToggle(key)} aria-label={`Notification ${index + 1} actions`} > )} > {notificationDrawerDropdownItems(key)} {description} ))} )} {notifications.length === 0 && ( } /> There are currently no notifications. )} ); return ( } mainContainerId="main-content-page-layout-default-nav" notificationDrawer={notificationDrawer} isNotificationDrawerExpanded={isDrawerExpanded} > Alert Group with Notification Drawer demo New alerts can be added with buttons below. Each alert has a timeout of 7 seconds, however, even after the timeout expires, all alerts are still visible in the notification drawer. By default, only 3 alerts are displayed. The rest can be accessed in the notification drawer after clicking on the bell icon in the header or by clicking on the overflow message.


Max displayed alerts The maximum number of displayed alerts can be set below.
{alerts.slice(0, maxDisplayed)}
); };