1- import React , { createElement } from 'react' ;
2- import { Observable as obs } from 'rxjs' ;
31import {
42 IconButton ,
53 Snackbar ,
64 SnackbarContent ,
5+ WithStyles ,
76 withStyles ,
87} from '@material-ui/core' ;
9- import { Close , CheckCircle , Warning , Error , Info } from '../components/Icons' ;
10- import { green , amber , blue , red } from '@material-ui/core/colors' ;
8+ import { amber , blue , green , red } from '@material-ui/core/colors' ;
119import classNames from 'classnames' ;
10+ import React , { ComponentType , createElement , ReactNode , StatelessComponent } from 'react' ;
11+ import { Observable as obs } from 'rxjs' ;
1212import uuid from 'uuid' ;
13- import { actions } from '../stream-store ' ;
13+ import { CheckCircle , Close , Error , Info , Warning } from '../components/Icons ' ;
1414import { connect , createAction , createState } from '../reactive' ;
15+ import { actions } from '../stream-store' ;
16+ import { HttpProblemDetailsResponse , HttpResponse } from '../types' ;
1517
1618const iconsByVariant = {
17- success : CheckCircle ,
18- warning : Warning ,
1919 error : Error ,
2020 info : Info ,
21+ success : CheckCircle ,
22+ warning : Warning ,
2123} ;
2224
23- const formatTitle = ( { status, statusText } ) => `${ status } ${ statusText } ` ;
25+ const formatTitle = ( {
26+ status,
27+ statusText,
28+ } : {
29+ status : number ;
30+ statusText : string ;
31+ } ) => `${ status } ${ statusText } ` ;
2432
25- const formatSubheader = ( { title, type } ) =>
33+ const formatSubheader = ( { title, type } : { title : string ; type : string } ) =>
2634 title ? `${ title } (${ type } )` : null ;
2735
28- const formatContent = ( { detail } ) =>
29- detail
36+ const formatContent = ( { detail } : { detail ?: string } ) : ReactNode [ ] =>
37+ ! ! detail
3038 ? detail
3139 . split ( / \r | \n / )
3240 . filter ( x => x . length )
@@ -38,28 +46,28 @@ const formatContent = ({ detail }) =>
3846 ] ,
3947 [ ] ,
4048 )
41- : null ;
49+ : [ ] ;
4250
4351const responses$ = obs . merge (
4452 ...Object . keys ( actions ) . map ( verb => actions [ verb ] . response ) ,
4553) ;
4654
4755const clientError$ = responses$
4856 . filter ( ( { status } ) => status >= 400 && status < 500 )
49- . map ( ( { body, ...response } ) => ( {
50- variant : 'warning' ,
51- title : formatTitle ( response ) ,
52- subheader : formatSubheader ( body ) ,
57+ . map ( ( { body, ...response } : HttpProblemDetailsResponse ) => ( {
5358 content : formatContent ( body ) ,
59+ subheader : formatSubheader ( body ) ,
60+ title : formatTitle ( response ) ,
61+ variant : 'warning' ,
5462 } ) ) ;
5563
5664const serverError$ = responses$
5765 . filter ( ( { status } ) => status >= 500 )
58- . map ( ( { body, ...response } ) => ( {
59- variant : 'error' ,
60- title : formatTitle ( response ) ,
61- subheader : formatSubheader ( body ) ,
66+ . map ( ( { body, ...response } : HttpProblemDetailsResponse ) => ( {
6267 content : formatContent ( body ) ,
68+ subheader : formatSubheader ( body ) ,
69+ title : formatTitle ( response ) ,
70+ variant : 'error' ,
6371 } ) ) ;
6472
6573const unsafe = Object . keys ( actions )
@@ -69,10 +77,10 @@ const unsafe = Object.keys(actions)
6977const success$ = obs
7078 . merge ( ...unsafe )
7179 . filter ( ( { status } ) => status < 400 )
72- . map ( response => ( {
73- variant : 'success' ,
74- title : formatTitle ( response ) ,
80+ . map ( ( response : HttpResponse ) => ( {
7581 autoHideDuration : 2000 ,
82+ title : formatTitle ( response ) ,
83+ variant : 'success' ,
7684 } ) ) ;
7785
7886const dismiss = createAction ( ) ;
@@ -102,48 +110,58 @@ const state$ = createState(
102110) ;
103111
104112const styles = theme => ( {
105- success : {
106- backgroundColor : green [ 600 ] ,
107- } ,
108113 error : {
109114 backgroundColor : red [ 500 ] ,
110115 } ,
111- info : {
112- backgroundColor : blue [ 500 ] ,
113- } ,
114- warning : {
115- backgroundColor : amber [ 700 ] ,
116- } ,
117116 icon : {
118117 fontSize : 20 ,
119118 } ,
120119 iconVariant : {
121- opacity : 0.9 ,
122120 marginRight : theme . spacing . unit ,
121+ opacity : 0.9 ,
122+ } ,
123+ info : {
124+ backgroundColor : blue [ 500 ] ,
123125 } ,
124126 message : {
125- display : 'flex' ,
126127 alignItems : 'center' ,
128+ display : 'flex' ,
129+ } ,
130+ success : {
131+ backgroundColor : green [ 600 ] ,
132+ } ,
133+ warning : {
134+ backgroundColor : amber [ 700 ] ,
127135 } ,
128136} ) ;
129137
130- const Notification = withStyles ( styles ) (
138+ interface NotificationProps {
139+ autoHideDuration : number | undefined ;
140+ className : string ;
141+ content : ReactNode ;
142+ messageId : string ;
143+ subheader : string ;
144+ title : string ;
145+ variant : string ;
146+ }
147+
148+ const Notification : ComponentType < NotificationProps > = withStyles ( styles ) (
131149 ( {
132- classes ,
150+ autoHideDuration ,
133151 className,
152+ classes,
153+ content,
134154 messageId,
135- title,
136155 subheader,
137- content ,
156+ title ,
138157 variant,
139- autoHideDuration,
140158 ...other
141- } ) => (
159+ } : NotificationProps & WithStyles < typeof styles > ) => (
142160 < Snackbar
143161 open
144162 anchorOrigin = { {
145- vertical : 'bottom' ,
146163 horizontal : 'right' ,
164+ vertical : 'bottom' ,
147165 } }
148166 autoHideDuration = { autoHideDuration }
149167 >
@@ -166,7 +184,6 @@ const Notification = withStyles(styles)(
166184 < IconButton
167185 key = "close"
168186 color = "inherit"
169- className = { classes . close }
170187 onClick = { ( ) => dismiss . next ( messageId ) }
171188 >
172189 < Close className = { classes . icon } />
@@ -178,7 +195,7 @@ const Notification = withStyles(styles)(
178195 ) ,
179196) ;
180197
181- const Notifications = ( { notifications } ) => (
198+ const Notifications : StatelessComponent < { notifications : NotificationProps [ ] } > = ( { notifications } ) => (
182199 < div >
183200 { notifications . map ( notification => (
184201 < Notification key = { notification . messageId } { ...notification } />
0 commit comments