-
-
Save barbagrigia/308e057036aa190ad69ebc3abccf81a6 to your computer and use it in GitHub Desktop.
React / Redux / Semantic-UI toast notifications implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import _ from "lodash"; | |
import {generateUUID} from "common/utils/UUID"; | |
import { | |
NOTIFICATION_CLEAR, | |
NOTIFICATION_DISMISS, | |
NOTIFICATION_SHOW, | |
NotificationType, | |
} from "./notificationConstants"; | |
export {NotificationType}; | |
export function showNotification(options = {}) { | |
return (dispatch, getState) => { | |
const {message = ""} = options; | |
const {header = ""} = options; | |
const {type = NotificationType.INFO} = options; | |
const {id = generateUUID("notification")} = options; | |
const {dismissAfter = 5000} = options; | |
const showPayload = {message, header, type, id}; | |
dispatch({type : NOTIFICATION_SHOW, payload : showPayload}); | |
if(_.isNumber(dismissAfter)) { | |
setTimeout(() => { | |
dispatch(dismissNotification(id)); | |
}, dismissAfter); | |
} | |
} | |
} | |
export function dismissNotification(id) { | |
return { | |
type : NOTIFICATION_DISMISS, | |
payload : {id} | |
}; | |
} | |
export function clearAllNotifications() { | |
return { | |
type : NOTIFICATION_CLEAR, | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const NOTIFICATION_SHOW = "NOTIFICATION_SHOW"; | |
export const NOTIFICATION_DISMISS = "NOTIFICATION_DISMISS"; | |
export const NOTIFICATION_CLEAR = "NOTIFICATION_CLEAR"; | |
export const NotificationType = { | |
SUCCESS : "SUCCESS", | |
INFO : "INFO", | |
WARNING : "WARNING", | |
ERROR : "ERROR", | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component} from "react"; | |
import {connect} from "react-redux"; | |
import _ from "lodash"; | |
import { Message } from "semantic-ui-react"; | |
import {Portal} from 'react-portal'; | |
import {selectNotifications} from "./notificationSelectors"; | |
import {dismissNotification} from "./notificationActions"; | |
const mapState = (state) => ({ | |
notifications : selectNotifications(state), | |
}); | |
const NOTIFICATION_CONTAINER_STYLE = { | |
position : "fixed", | |
top : "10px", | |
right : 0, | |
left : 0, | |
zIndex : 1000, | |
width : "80%", | |
maxWidth : "400px", | |
margin : "auto", | |
}; | |
const Notification = ({message, header, type, id, onCloseClick=_.noop}) => { | |
let headerText = header; | |
let messageText = message; | |
if(!headerText) { | |
headerText = message; | |
messageText = null; | |
} | |
const messageHeader = headerText ? <Message.Header>{headerText}</Message.Header> : null; | |
// Turn the type string into a boolean prop with the same name | |
const typeProp = type.toLowerCase(); | |
const typeObj = { [typeProp] : true}; | |
if(messageText) { | |
const messagePieces = messageText.split("\n"); | |
messageText = messagePieces.map(piece => <div>{piece}</div>); | |
} | |
const onDismiss = () => onCloseClick(id); | |
return ( | |
<Message {...typeObj} onDismiss={onDismiss} > | |
{messageHeader} | |
<Message.Content>{messageText}</Message.Content> | |
</Message> | |
); | |
} | |
const actions = {dismissNotification}; | |
export class NotificationManager extends Component { | |
render() { | |
let {notifications = []} = this.props; | |
const renderedNotifications = notifications.map( notification => { | |
const {id} = notification; | |
return ( | |
<Notification | |
key={id} | |
onCloseClick={this.props.dismissNotification} | |
{...notification} | |
/> | |
) | |
}); | |
return ( | |
<Portal isOpened={true} key="notificationsPortal"> | |
<div style={NOTIFICATION_CONTAINER_STYLE}> | |
{renderedNotifications} | |
</div> | |
</Portal> | |
) | |
} | |
} | |
export default connect(mapState, actions)(NotificationManager); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {createReducer} from "common/utils/utils"; | |
import { | |
NOTIFICATION_CLEAR, | |
NOTIFICATION_DISMISS, | |
NOTIFICATION_SHOW, | |
} from "./notificationConstants"; | |
const initialState = []; | |
function filterNotifications(notifications, id) { | |
return notifications.filter(notification => notification.id !== id); | |
} | |
export function showNotification(state, payload) { | |
const filteredNotifications = filterNotifications(state, payload.id); | |
return [payload, ...filteredNotifications]; | |
} | |
export function dismissNotification(state, payload) { | |
return filterNotifications(state, payload.id); | |
} | |
export function clearNotifications(state, payload) { | |
return []; | |
} | |
export default createReducer(initialState, { | |
[NOTIFICATION_CLEAR] : clearNotifications, | |
[NOTIFICATION_DISMISS] : dismissNotification, | |
[NOTIFICATION_SHOW] : showNotification, | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {createSelector} from "reselect"; | |
export const selectUI = state => state.ui; | |
export const selectNotifications = createSelector( | |
selectUI, | |
ui => ui.notifications, | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment