Skip to content
This repository has been archived by the owner on Aug 18, 2020. It is now read-only.

Commit

Permalink
Merge pull request #306 from Tripwire/feat/notification
Browse files Browse the repository at this point in the history
feat(notification): initial version of Notification Component
  • Loading branch information
ggascoigne authored Oct 17, 2018
2 parents a1aba3b + 53fc514 commit e778a9f
Show file tree
Hide file tree
Showing 14 changed files with 836 additions and 74 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
90 changes: 90 additions & 0 deletions src/components/Notification/Notification.examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#### Notification Menu

```js
const notifications1 = [];

let notifications = [
{id:1, type:'error',
title:'First Notification',
description:'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus nulla arcu, elementum in nibh eu, volutpat interdum lorem. Suspendisse congue consequat congue. Vestibulum iaculis, ipsum sed semper semper, leo velit varius quam, eget tincidunt augue nunc at turpis.',
timeStamp:'Just now',
isMsgRead:false},
{id:2,
type:'success',
title:'Second Notification',
description:'Curabitur congue ligula sit amet lacus gravida lacinia. Curabitur id orci vel ligula ultricies sollicitudin. Nullam vel neque commodo, rutrum diam sed, cursus ex.',
timeStamp:'Just now',
isMsgRead:false},
{id:3,
type:'info',
title:'Third Notification',
description:'Nulla accumsan, augue sit amet maximus hendrerit, nisl erat pharetra erat, vitae lacinia quam velit tincidunt turpis. Phasellus sagittis, libero vel ullamcorper laoreet, lorem libero scelerisque nisl, nec suscipit metus lacus sit amet justo.',
timeStamp:'Just now',
isMsgRead:false},
{id:4,
type:'warning',
title:'Fourth Notification',
description:'Pellentesque eget posuere turpis.',
timeStamp:'Just now',
isMsgRead:true},
{id:5,
type:'error',
title:'Fifth Notification',
description:'Integer enim tellus, molestie quis magna scelerisque, commodo malesuada erat. Cras sodales dolor enim.',
timeStamp:'Just now',
isMsgRead:false},
{id:6,
type:'error',
title:'Six Notification',
description:'Fusce ac ornare nulla, ut faucibus nunc.',
timeStamp:'Just now',
isMsgRead:false},
{id:7,
type:'info',
title:'Seven Notification',
description:'Curabitur semper tincidunt augue non faucibus. Nullam in dui pellentesque, tempor urna non, tincidunt arcu.',
timeStamp:'Just now',
isMsgRead:false},
{id:8,
type:'warning',
title:'Eighth Notification',
description:'Quisque sagittis metus ac mattis maximus. Curabitur quis lorem et diam sodales cursus.',
timeStamp:'Just now',
isMsgRead:true}
];

initialState = {
selectedNotification: undefined,
notifications: notifications
};

<div className='notifcationexample' style={{textAlign: 'right'}}>
<Notification
notifications={state.notifications}
selectedNotification={state.selectedNotification}
onNotificationClicked={notification => {
const clickedBack = (typeof notification == 'undefined')
if (!clickedBack) {
const notificationIdx = notifications.findIndex( (item) => {
return item.id === notification.id
})
notifications[notificationIdx].isMsgRead = true
}
setState({ selectedNotification: notification, notifications: notifications})
}
}
onClearAll={() => {
setState({ selectedNotification: undefined, notifications: []})
}
}
onClearNotification={notification => {
const notificationIdx = notifications.findIndex( (item) => {
return item.id === notification.id
})
delete notifications[notificationIdx]
setState({ selectedNotification: undefined, notifications: notifications})
}
}
/>
</div>
```
72 changes: 72 additions & 0 deletions src/components/Notification/Notification.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import '../../styles/components/notification.css'
import React from 'react'
import { Popup } from 'semantic-ui-react'
import NotificationBadge from './NotificationBadge'
import NotificationTray from './NotificationTray'
import NotificationHeader from './NotificationHeader'
import NotificationBody from './NotificationBody'
import NotificationFooter from './NotificationFooter'
import NotificationEmpty from './NotificationEmpty'

const Notification = props => {
const {
children,
notifications,
onNotificationClicked,
onClearNotification,
onClearAll,
selectedNotification,
...rest
} = props

const notificationCount = notifications.length

const badge = (
<Notification.Badge
key={'badge'}
size='small'
notificationCount={notificationCount}
/>
)
const tray = (
<Notification.Tray key={'tray'}>
<Notification.Header
title={'NOTIFICATIONS'}
selectedNotification={selectedNotification}
notificationCount={notificationCount}
onNotificationClicked={onNotificationClicked}
/>
<Notification.Body
selectedNotification={selectedNotification}
notifications={notifications}
onNotificationClicked={onNotificationClicked}
onClearNotification={onClearNotification}
/>
<Notification.Footer
onClearAll={onClearAll}
selectedNotification={selectedNotification}
empty={!notificationCount}
/>
</Notification.Tray>
)

return (
<Popup
trigger={badge}
content={tray}
on='click'
position='bottom center'
className={'notificationPopup'}
{...rest}
/>
)
}

Notification.Badge = NotificationBadge
Notification.Tray = NotificationTray
Notification.Header = NotificationHeader
Notification.Body = NotificationBody
Notification.Footer = NotificationFooter
Notification.Empty = NotificationEmpty

export default Notification
24 changes: 24 additions & 0 deletions src/components/Notification/NotificationBadge.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react'
import { Icon } from 'semantic-ui-react'
import PropTypes from 'prop-types'

const NotificationBadge = props => {
const { size, notificationCount, ...rest } = props

return (
<span className={`notificationIcon ${size}`} {...rest}>
<Icon name='bell outline' size={size} />
<span className={`notificationCount ${size}`}>{notificationCount}</span>
</span>
)
}

NotificationBadge.defaultProps = {
notificationCount: 0
}

NotificationBadge.propTypes = {
notificationCount: PropTypes.number
}

export default NotificationBadge
60 changes: 60 additions & 0 deletions src/components/Notification/NotificationBody.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react'
import NotificationMessage from './NotificationMessage'
import NotificationEmpty from './NotificationEmpty'
import NotificationDetail from './NotificationDetail'

const NotificationBody = props => {
function getNotification (notification, dataFor) {
if (dataFor === 'notificationList') {
return (
<NotificationMessage
key={notification.id}
notification={notification}
onNotificationClicked={onNotificationClicked}
onClearNotification={onClearNotification}
/>
)
} else {
return (
<NotificationDetail
notification={notification}
onClearNotification={onClearNotification}
/>
)
}
}
function getNotificationContent () {
if (props.selectedNotification) {
return getNotification(props.selectedNotification, 'detailedNotification')
}
if (notificationsLength > 0) {
return notifications.map(notification => {
return getNotification(notification, 'notificationList')
})
} else {
return <NotificationEmpty />
}
}

const {
children,
notifications,
onNotificationClicked,
onClearNotification,
...rest
} = props
const notificationsLength = notifications.length
const notificationContent = getNotificationContent()

return (
<div className='notificationBody' {...rest}>
{notificationContent}
</div>
)
}

NotificationBody.defaultProps = {}

NotificationBody.propTypes = {}

export default NotificationBody
48 changes: 48 additions & 0 deletions src/components/Notification/NotificationDetail.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react'
import Flexbox from 'flexbox-react'
import { Icon } from 'semantic-ui-react'
import { getAlertIconClassName } from '../../util/getAlertIconClassName'

const NotificationDetail = props => {
const { notification, onClearNotification, ...rest } = props
const { id, type, title, description, timeStamp } = notification
const icon = getAlertIconClassName(type)

function handleClearClicked (e, notification) {
onClearNotification(notification)
e.stopPropagation()
}

return (
<Flexbox
id={id}
flexDirection='column'
flexGrow={1}
className={'column detailView notification_detail'}
{...rest}
>
<Flexbox title={title}>
<Icon className={`notificationIcon ${type} ${icon}`} />
<Flexbox flexDirection='column' className={`notificationContent`}>
<div className='notificationTitle'>{title}</div>
<div className='notificationTime'>{timeStamp}</div>
<div className='notificationDesc '>{description}</div>
<div className='notificationActions'>
<a
className='notificationClear'
onClick={e => handleClearClicked(e, notification)}
>
Clear
</a>
</div>
</Flexbox>
</Flexbox>
</Flexbox>
)
}

NotificationDetail.defaultProps = {}

NotificationDetail.propTypes = {}

export default NotificationDetail
28 changes: 28 additions & 0 deletions src/components/Notification/NotificationEmpty.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import { Icon } from 'semantic-ui-react'

const NotificationEmpty = props => {
const { children, ...rest } = props
return (
<div className='empty__notification_panel' {...rest}>
<div className='outer-circle'>
<div className='inner-circle'>
<Icon name='bell outline bell_icon' size='big' />
<div className='info_text'>
<span>No New Notifications!</span>
</div>
</div>
</div>
<p className='large-copy'>
Check back again for updates, alerts and any other general
notifications.
</p>
</div>
)
}

NotificationEmpty.defaultProps = {}

NotificationEmpty.propTypes = {}

export default NotificationEmpty
21 changes: 21 additions & 0 deletions src/components/Notification/NotificationFooter.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'

const NotificationFooter = props => {
const { children, onClearAll, empty, selectedNotification, ...rest } = props
function handleClearAllClicked () {
onClearAll()
}
if (empty) return <div className='empty-footer' />
if (selectedNotification) return null
return (
<div className={'notificationFooter'} {...rest}>
{empty ? null : <a onClick={() => handleClearAllClicked()}>Clear All</a>}
</div>
)
}

NotificationFooter.defaultProps = {}

NotificationFooter.propTypes = {}

export default NotificationFooter
43 changes: 43 additions & 0 deletions src/components/Notification/NotificationHeader.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react'
import { Icon } from 'semantic-ui-react'

const NotificationHeader = props => {
const {
title,
notificationCount,
selectedNotification,
children,
onNotificationClicked,
...rest
} = props

function handlelistViewClicked () {
onNotificationClicked(undefined)
}

const detailView = (
<div
className={'notificationHeader detailView clearfix'}
onClick={() => handlelistViewClicked()}
{...rest}
>
<Icon className='angle left backarrow' />
<h4 className='backbtn'>BACK</h4>
</div>
)
const listView = (
<div className={'notificationHeader clearfix'} {...rest}>
<h4 className='notificationTitle'>{title}</h4>
<span className='notificationCount'>{notificationCount}</span>
{children}
</div>
)

return selectedNotification ? detailView : listView
}

NotificationHeader.defaultProps = {}

NotificationHeader.propTypes = {}

export default NotificationHeader
Loading

0 comments on commit e778a9f

Please sign in to comment.