Add Notifier component
This commit is contained in:
parent
d4ed0d7f4a
commit
aa613de2e7
|
@ -0,0 +1,16 @@
|
|||
// @flow
|
||||
import enqueueSnackbar from '~/logic/notifications/store/actions/enqueueSnackbar'
|
||||
import closeSnackbar from '~/logic/notifications/store/actions/closeSnackbar'
|
||||
import removeSnackbar from '~/logic/notifications/store/actions/removeSnackbar'
|
||||
|
||||
export type Actions = {
|
||||
enqueueSnackbar: typeof enqueueSnackbar,
|
||||
closeSnackbar: typeof closeSnackbar,
|
||||
removeSnackbar: typeof removeSnackbar,
|
||||
}
|
||||
|
||||
export default {
|
||||
enqueueSnackbar,
|
||||
closeSnackbar,
|
||||
removeSnackbar,
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
// @flow
|
||||
import React, { Component } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import { withSnackbar } from 'notistack'
|
||||
import actions from './actions'
|
||||
import selector from './selector'
|
||||
|
||||
class Notifier extends Component {
|
||||
displayed = []
|
||||
|
||||
shouldComponentUpdate({ notifications: newSnacks = [] }) {
|
||||
const { notifications: currentSnacks, closeSnackbar, removeSnackbar } = this.props
|
||||
|
||||
if (!newSnacks.size) {
|
||||
this.displayed = []
|
||||
return false
|
||||
}
|
||||
let notExists = false
|
||||
for (let i = 0; i < newSnacks.size; i += 1) {
|
||||
const newSnack = newSnacks.get(i)
|
||||
|
||||
if (newSnack.dismissed) {
|
||||
closeSnackbar(newSnack.key)
|
||||
removeSnackbar(newSnack.key)
|
||||
}
|
||||
|
||||
if (notExists) {
|
||||
continue
|
||||
}
|
||||
notExists = notExists || !currentSnacks.filter(({ key }) => newSnack.key === key).length
|
||||
}
|
||||
return notExists
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const { notifications = [], enqueueSnackbar, removeSnackbar } = this.props
|
||||
|
||||
notifications.map(({ key, message, options = {} }) => {
|
||||
// Do nothing if snackbar is already displayed
|
||||
if (this.displayed.includes(key)) {
|
||||
return
|
||||
}
|
||||
// Display snackbar using notistack
|
||||
enqueueSnackbar(message, {
|
||||
...options,
|
||||
onClose: (event, reason, key) => {
|
||||
if (options.onClose) {
|
||||
options.onClose(event, reason, key)
|
||||
}
|
||||
// Dispatch action to remove snackbar from redux store
|
||||
removeSnackbar(key)
|
||||
},
|
||||
})
|
||||
// Keep track of snackbars that we've displayed
|
||||
this.storeDisplayed(key)
|
||||
})
|
||||
}
|
||||
|
||||
storeDisplayed = (id) => {
|
||||
this.displayed = [...this.displayed, id]
|
||||
}
|
||||
|
||||
render() {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export default withSnackbar(
|
||||
connect(
|
||||
selector,
|
||||
actions,
|
||||
)(Notifier),
|
||||
)
|
|
@ -0,0 +1,7 @@
|
|||
// @flow
|
||||
import { createStructuredSelector } from 'reselect'
|
||||
import { notificationsListSelector } from '~/logic/notifications/store/selectors'
|
||||
|
||||
export default createStructuredSelector<Object, *>({
|
||||
notifications: notificationsListSelector,
|
||||
})
|
|
@ -5,6 +5,7 @@ import { withStyles } from '@material-ui/core/styles'
|
|||
import SidebarProvider from '~/components/Sidebar'
|
||||
import Header from '~/components/Header'
|
||||
import Img from '~/components/layout/Img'
|
||||
import Notifier from '~/components/Notifier'
|
||||
import AlertLogo from './assets/alert.svg'
|
||||
import CheckLogo from './assets/check.svg'
|
||||
import ErrorLogo from './assets/error.svg'
|
||||
|
@ -72,6 +73,7 @@ const PageFrame = ({ children, classes }: Props) => (
|
|||
info: '',
|
||||
}}
|
||||
>
|
||||
<Notifier />
|
||||
<SidebarProvider>
|
||||
<Header />
|
||||
{children}
|
||||
|
|
Loading…
Reference in New Issue