import React from 'react'; import { Avatar, Brand, Breadcrumb, BreadcrumbItem, Button, ButtonVariant, Divider, Dropdown, DropdownItem, DropdownList, EmptyState, EmptyStateActions, EmptyStateBody, EmptyStateIcon, EmptyStateHeader, EmptyStateFooter, EmptyStateVariant, MenuToggle, Nav, NavItem, NavList, NotificationBadge, NotificationDrawer, NotificationDrawerBody, NotificationDrawerGroup, NotificationDrawerGroupList, NotificationDrawerHeader, NotificationDrawerList, NotificationDrawerListItem, NotificationDrawerListItemBody, NotificationDrawerListItemHeader, Page, PageSection, PageSectionVariants, PageSidebar, PageSidebarBody, SkipToContent, TextContent, Text, PageToggleButton, Masthead, MastheadMain, MastheadToggle, MastheadContent, MastheadBrand, Toolbar, ToolbarItem, ToolbarGroup, ToolbarContent } from '@patternfly/react-core'; import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon'; import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon'; import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon'; import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon'; import QuestionCircleIcon from '@patternfly/react-icons/dist/esm/icons/question-circle-icon'; import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon'; import imgAvatar from '@patternfly/react-core/src/components/assets/avatarImg.svg'; import pfLogo from '@patternfly/react-core/src/demos/assets/pf-logo.svg'; export const NotificationDrawerGrouped: React.FunctionComponent = () => { const drawerRef = React.useRef(null); const [isDropdownOpen, setIsDropdownOpen] = React.useState(false); const [isKebabDropdownOpen, setIsKebabDropdownOpen] = React.useState(false); const [isDrawerExpanded, setIsDrawerExpanded] = React.useState(false); const [firstDrawerGroupExpanded, setFirstDrawerGroupExpanded] = React.useState(false); const [secondDrawerGroupExpanded, setSecondDrawerGroupExpanded] = React.useState(true); const [thirdDrawerGroupExpanded, setThirdDrawerGroupExpanded] = React.useState(false); interface UnreadMap { [groupName: string]: { [notificationId: string]: boolean; } | null; } const [activeItem, setActiveItem] = React.useState(0); const [isUnreadMap, setIsUnreadMap] = React.useState({ 'group-1': { 'notification-5': true, 'notification-6': true }, 'group-2': { 'notification-9': true, 'notification-10': true }, 'group-3': null }); const [shouldShowNotifications, setShouldShowNotifications] = React.useState(true); interface ActionsMenu { [toggleId: string]: boolean; } const [isActionsMenuOpen, setIsActionsMenuOpen] = React.useState({}); const onNavSelect = ( _event: React.FormEvent, selectedItem: { groupId: number | string; itemId: number | string; to: string; } ) => setActiveItem(selectedItem.itemId); const onDropdownToggle = () => setIsDropdownOpen((prevState) => !prevState); const onDropdownSelect = () => setIsDropdownOpen(false); const onKebabDropdownToggle = () => setIsKebabDropdownOpen((prevState) => !prevState); const onKebabDropdownSelect = () => setIsKebabDropdownOpen(false); const onCloseNotificationDrawer = (_event: any) => setIsDrawerExpanded((prevState) => !prevState); const onToggle = (id: string) => { setIsActionsMenuOpen({ [id]: !isActionsMenuOpen[id] }); }; const closeActionsMenu = () => setIsActionsMenuOpen({}); const onListItemClick = (groupId: string, id: string) => { if (isUnreadMap === null) { return; } if (!isUnreadMap[groupId]) { setIsUnreadMap({ ...isUnreadMap, [groupId]: { [id]: false } }); } else { setIsUnreadMap({ ...isUnreadMap, [groupId]: { ...isUnreadMap[groupId], [id]: false } }); } }; const isUnread = (groupId: string, id: string) => isUnreadMap && isUnreadMap[groupId] !== null && isUnreadMap[groupId][id]; const getNumberUnread = (groupId: string | null) => { if (!isUnreadMap) { return 0; } if (groupId) { const group = isUnreadMap[groupId]; if (!group) { return 0; } return Object.values(group).reduce((count, value) => (value ? count + 1 : count), 0); } return Object.keys(isUnreadMap).reduce((count, groupId) => { const group = isUnreadMap[groupId]; if (!group) { return count; } return Object.values(group).reduce((groupCount, value) => (value ? groupCount + 1 : groupCount), count); }, 0); }; const markAllRead = () => setIsUnreadMap(null); const showNotifications = (showNotifications: boolean) => { setIsUnreadMap(null); setShouldShowNotifications(showNotifications); }; const toggleFirstDrawer = (_event: any, value: boolean | ((prevState: boolean) => boolean)) => { setFirstDrawerGroupExpanded(value); }; const toggleSecondDrawer = (_event: any, value: boolean | ((prevState: boolean) => boolean)) => { setSecondDrawerGroupExpanded(value); }; const toggleThirdDrawer = (_event: any, value: boolean | ((prevState: boolean) => boolean)) => { setThirdDrawerGroupExpanded(value); }; const focusDrawer = (_event: any) => { if (drawerRef.current === null) { return; } // Prevent the NotificationDrawer from receiving focus if a drawer group item is opened if (!document.activeElement?.closest(`.${drawerRef.current.className}`)) { const firstTabbableItem = drawerRef.current.querySelector('a, button') as | HTMLAnchorElement | HTMLButtonElement | null; firstTabbableItem?.focus(); } }; const PageNav = ( ); const kebabDropdownItems = ( <> Settings Help ); const userDropdownItems = ( <> My profile User management Logout ); const headerToolbar = ( onCloseNotificationDrawer(event)} aria-label="Notifications" isExpanded={isDrawerExpanded} > ); const Header = ( {headerToolbar} ); const Sidebar = ( {PageNav} ); const pageId = 'main-content-page-layout-default-nav'; const PageSkipToContent = Skip to content; const PageBreadcrumb = ( Section home Section title Section title Section landing ); const notificationDrawerActions = ( <> Mark all read showNotifications(false)}> Clear all showNotifications(true)}> Unclear last Settings ); const notificationDrawerDropdownItems = ( <> ev.preventDefault()} > Link Action Disabled Link ); const notificationDrawer = ( !isOpen && closeActionsMenu()} popperProps={{ position: 'right' }} toggle={(toggleRef: React.RefObject) => ( onToggle('toggle-id-0')} isExpanded={isActionsMenuOpen['toggle-id-0'] || false} > )} > {notificationDrawerActions} {shouldShowNotifications && ( onListItemClick('group-1', 'notification-5')} isRead={!isUnread('group-1', 'notification-5')} > !isOpen && closeActionsMenu()} popperProps={{ position: 'right' }} toggle={(toggleRef: React.RefObject) => ( onToggle('toggle-id-5')} isExpanded={isActionsMenuOpen['toggle-id-5'] || false} > )} > {notificationDrawerDropdownItems} This is an info notification description. onListItemClick('group-1', 'notification-6')} isRead={!isUnread('group-1', 'notification-6')} > !isOpen && closeActionsMenu()} popperProps={{ position: 'right' }} toggle={(toggleRef: React.RefObject) => ( onToggle('toggle-id-6')} isExpanded={isActionsMenuOpen['toggle-id-6'] || false} > )} > {notificationDrawerDropdownItems} This is a danger notification description. This is a long description to show how the title will wrap if it is long and wraps to multiple lines. onListItemClick('group-1', 'notification-7')} isRead={!isUnread('group-1', 'notification-7')} > !isOpen && closeActionsMenu()} popperProps={{ position: 'right' }} toggle={(toggleRef: React.RefObject) => ( onToggle('toggle-id-7')} isExpanded={isActionsMenuOpen['toggle-id-7'] || false} > )} > {notificationDrawerDropdownItems} This is a warning notification description. onListItemClick('group-1', 'notification-8')} isRead={!isUnread('group-1', 'notification-8')} > !isOpen && closeActionsMenu()} popperProps={{ position: 'right' }} toggle={(toggleRef: React.RefObject) => ( onToggle('toggle-id-8')} isExpanded={isActionsMenuOpen['toggle-id-8'] || false} > )} > {notificationDrawerDropdownItems} This is a success notification description. onListItemClick('group-2', 'notification-9')} isRead={!isUnread('group-2', 'notification-9')} > !isOpen && closeActionsMenu()} popperProps={{ position: 'right' }} toggle={(toggleRef: React.RefObject) => ( onToggle('toggle-id-9')} isExpanded={isActionsMenuOpen['toggle-id-9'] || false} > )} > {notificationDrawerDropdownItems} This is an info notification description. onListItemClick('group-2', 'notification-10')} isRead={!isUnread('group-2', 'notification-10')} > !isOpen && closeActionsMenu()} popperProps={{ position: 'right' }} toggle={(toggleRef: React.RefObject) => ( onToggle('toggle-id-10')} isExpanded={isActionsMenuOpen['toggle-id-10'] || false} > )} > {notificationDrawerDropdownItems} This is a danger notification description. This is a long description to show how the title will wrap if it is long and wraps to multiple lines. onListItemClick('group-2', 'notification-11')} isRead={!isUnread('group-2', 'notification-11')} > !isOpen && closeActionsMenu()} popperProps={{ position: 'right' }} toggle={(toggleRef: React.RefObject) => ( onToggle('toggle-id-11')} isExpanded={isActionsMenuOpen['toggle-id-11'] || false} > )} > {notificationDrawerDropdownItems} This is a warning notification description. onListItemClick('group-2', 'notification-12')} isRead={!isUnread('group-2', 'notification-12')} > !isOpen && closeActionsMenu()} popperProps={{ position: 'right' }} toggle={(toggleRef: React.RefObject) => ( onToggle('toggle-id-12')} isExpanded={isActionsMenuOpen['toggle-id-12'] || false} > )} > {notificationDrawerDropdownItems} This is a success notification description. } /> There are currently no critical alerts firing. There may be firing alerts of other severities or silenced critical alerts however. )} {!shouldShowNotifications && ( } /> There are currently no alerts. There may be silenced critical alerts however. )} ); return ( | KeyboardEvent | React.TransitionEvent ) => focusDrawer(event)} skipToContent={PageSkipToContent} breadcrumb={PageBreadcrumb} mainContainerId={pageId} > Main title Body text should be Overpass Regular at 16px. It should have leading of 24px because
of its relative line height of 1.5.
Panel section content
); };