1- import React , { useContext , useCallback } from 'react'
1+ import React , { useContext , useMemo , useCallback , MouseEventHandler } from 'react'
22import { createPortal } from 'react-dom'
33import { RouteComponentProps } from 'react-router-dom'
44import { useTranslation } from 'react-i18next'
5- import { MessageBar , MessageBarType , IconButton } from 'office-ui-fabric-react'
5+ import { Stack , MessageBar , MessageBarType , IconButton , Panel , PanelType , Text } from 'office-ui-fabric-react'
66import { NeuronWalletContext } from 'states/stateProvider'
7- import { StateWithDispatch , AppActions } from 'states/stateProvider/reducer'
7+ import { StateWithDispatch , StateDispatch } from 'states/stateProvider/reducer'
8+ import {
9+ toggleAllNotificationVisibility ,
10+ toggleTopAlertVisibility ,
11+ dismissNotification ,
12+ } from 'states/stateProvider/actionCreators'
813import styles from './Notification.module.scss'
914
1015const notificationType = ( type : 'success' | 'warning' | 'alert' ) => {
@@ -24,27 +29,61 @@ const notificationType = (type: 'success' | 'warning' | 'alert') => {
2429 }
2530}
2631
27- const DismissButton = ( { onDismiss } : { onDismiss : React . MouseEventHandler < HTMLButtonElement > } ) => (
32+ const DismissTopAlertButton = ( { onDismiss } : { onDismiss : React . MouseEventHandler < HTMLButtonElement > } ) => (
2833 < IconButton iconProps = { { iconName : 'Dismiss' } } onClick = { onDismiss } />
2934)
3035
31- const NoticeContent = ( { dispatch } : React . PropsWithoutRef < StateWithDispatch & RouteComponentProps > ) => {
36+ const TopAlertActions = ( {
37+ count = 0 ,
38+ dispatch,
39+ onDismiss,
40+ } : {
41+ count : number
42+ dispatch : StateDispatch
43+ onDismiss : MouseEventHandler
44+ } ) => (
45+ < Stack horizontal verticalAlign = "center" >
46+ { count > 1 ? (
47+ < IconButton
48+ iconProps = { { iconName : 'More' } }
49+ onClick = { ( ) => {
50+ toggleAllNotificationVisibility ( ) ( dispatch )
51+ } }
52+ >
53+ more
54+ </ IconButton >
55+ ) : null }
56+ < DismissTopAlertButton onDismiss = { onDismiss } />
57+ </ Stack >
58+ )
59+
60+ export const NoticeContent = ( { dispatch } : React . PropsWithoutRef < StateWithDispatch & RouteComponentProps > ) => {
3261 const {
33- app : { notifications = [ ] , popups = [ ] } ,
62+ app : { notifications = [ ] , popups = [ ] , showTopAlert = false , showAllNotifications = false } ,
3463 } = useContext ( NeuronWalletContext )
3564 const [ t ] = useTranslation ( )
36- const onDismiss = useCallback ( ( ) => {
37- dispatch ( {
38- type : AppActions . ClearNotifications ,
39- payload : null ,
40- } )
65+
66+ const notificationsInDesc = useMemo ( ( ) => [ ...notifications ] . reverse ( ) , [ notifications ] )
67+ const notification : State . Message | undefined = notificationsInDesc [ 0 ]
68+
69+ const onTopAlertDismiss = useCallback ( ( ) => {
70+ toggleTopAlertVisibility ( false ) ( dispatch )
4171 } , [ dispatch ] )
4272
43- const notification = notifications [ 0 ]
73+ const onPanelDismiss = useCallback ( ( ) => {
74+ toggleAllNotificationVisibility ( ) ( dispatch )
75+ } , [ dispatch ] )
76+
77+ const onNotificationDismiss = useCallback (
78+ ( timestamp : number ) => ( ) => {
79+ dismissNotification ( timestamp ) ( dispatch )
80+ } ,
81+ [ dispatch ]
82+ )
4483
4584 return (
4685 < div >
47- { notifications . length ? (
86+ { showTopAlert && notificationsInDesc . length ? (
4887 < MessageBar
4988 messageBarType = { notificationType ( notification . type ) }
5089 styles = { {
@@ -56,18 +95,70 @@ const NoticeContent = ({ dispatch }: React.PropsWithoutRef<StateWithDispatch & R
5695 marginRight : '12px' ,
5796 } ,
5897 } }
59- actions = { < DismissButton onDismiss = { onDismiss } /> }
98+ actions = {
99+ < TopAlertActions dispatch = { dispatch } count = { notificationsInDesc . length } onDismiss = { onTopAlertDismiss } />
100+ }
60101 >
61102 { t ( notification . content ) }
62103 </ MessageBar >
63104 ) : null }
105+
64106 < div className = { styles . autoDismissMessages } >
65107 { popups . map ( popup => (
66108 < MessageBar key = { `${ popup . timestamp } ` } messageBarType = { MessageBarType . success } >
67109 { t ( popup . text ) }
68110 </ MessageBar >
69111 ) ) }
70112 </ div >
113+
114+ < Panel
115+ isOpen = { showAllNotifications }
116+ type = { PanelType . smallFixedFar }
117+ onDismiss = { onPanelDismiss }
118+ headerText = { t ( 'notification-panel.title' ) }
119+ isHiddenOnDismiss
120+ isLightDismiss
121+ styles = { {
122+ header : {
123+ padding : '0 5px!important' ,
124+ } ,
125+ content : {
126+ padding : '0!important' ,
127+ } ,
128+ navigation : {
129+ display : 'none' ,
130+ } ,
131+ } }
132+ >
133+ { notificationsInDesc . map ( n => {
134+ return (
135+ < Stack
136+ key = { n . timestamp }
137+ styles = { {
138+ root : {
139+ padding : '5px 15px' ,
140+ boxShadow : '1px 1px 3px rgba(0,0,0,0.1)' ,
141+ borderLeft : `4px solid` ,
142+ borderLeftColor : n . type === 'warning' ? '#fff176ba' : '#ff3d00ba' ,
143+ margin : '10px 0' ,
144+ } ,
145+ } }
146+ >
147+ < Stack horizontal horizontalAlign = "space-between" verticalAlign = "center" >
148+ < Text
149+ styles = { {
150+ root : [ { textTransform : 'capitalize' } ] ,
151+ } }
152+ >
153+ { t ( `message-types.${ n . type } ` ) }
154+ </ Text >
155+ < IconButton iconProps = { { iconName : 'Dismiss' } } onClick = { onNotificationDismiss ( n . timestamp ) } />
156+ </ Stack >
157+ < Text as = "p" > { t ( n . content ) } </ Text >
158+ </ Stack >
159+ )
160+ } ) }
161+ </ Panel >
71162 </ div >
72163 )
73164}
0 commit comments