Add error notification
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { Typography, Toolbar, Modal, MenuItem, Button, Grid, Paper, TextField, Switch, FormControlLabel } from '@material-ui/core'
|
import { Typography, Toolbar, Modal, MenuItem, Button, Grid, Paper, TextField, Switch, FormControlLabel } from '@material-ui/core'
|
||||||
import { withStyles, Theme, StyleRulesCallback } from '@material-ui/core/styles'
|
import { withStyles, Theme, StyleRulesCallback } from '@material-ui/core/styles'
|
||||||
|
import Notification from './Notification'
|
||||||
import { MqttOptions, DataSourceState } from '../../../../backend/src/DataSource'
|
import { MqttOptions, DataSourceState } from '../../../../backend/src/DataSource'
|
||||||
import { addMqttConnectionEvent, makeConnectionStateEvent, rendererEvents } from '../../../../events'
|
import { addMqttConnectionEvent, makeConnectionStateEvent, rendererEvents } from '../../../../events'
|
||||||
import sha1 = require('sha1')
|
import sha1 = require('sha1')
|
||||||
@@ -18,6 +19,7 @@ const protocols = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
|
error?: Error
|
||||||
visible: boolean
|
visible: boolean
|
||||||
host: string
|
host: string
|
||||||
protocol: string
|
protocol: string
|
||||||
@@ -79,10 +81,11 @@ class Connection extends React.Component<Props, State> {
|
|||||||
const connectionId = (sha1(Math.random() + JSON.stringify(options)).slice(0, 8)) as string
|
const connectionId = (sha1(Math.random() + JSON.stringify(options)).slice(0, 8)) as string
|
||||||
rendererEvents.emit(addMqttConnectionEvent, { options, id: connectionId })
|
rendererEvents.emit(addMqttConnectionEvent, { options, id: connectionId })
|
||||||
rendererEvents.subscribe(makeConnectionStateEvent(connectionId), (state: DataSourceState) => {
|
rendererEvents.subscribe(makeConnectionStateEvent(connectionId), (state: DataSourceState) => {
|
||||||
console.log(state)
|
|
||||||
if (state.connected) {
|
if (state.connected) {
|
||||||
this.props.onConnection(connectionId)
|
this.props.onConnection(connectionId)
|
||||||
this.setState({ visible: false })
|
this.setState({ visible: false })
|
||||||
|
} else if (state.error) {
|
||||||
|
this.setState({ error: state.error })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -132,7 +135,6 @@ class Connection extends React.Component<Props, State> {
|
|||||||
<Typography className={classes.title} variant="h6" color="inherit">MQTT Connection</Typography>
|
<Typography className={classes.title} variant="h6" color="inherit">MQTT Connection</Typography>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
<form className={classes.container} noValidate autoComplete="off">
|
<form className={classes.container} noValidate autoComplete="off">
|
||||||
|
|
||||||
<Grid container spacing={24}>
|
<Grid container spacing={24}>
|
||||||
<Grid item xs={2}>
|
<Grid item xs={2}>
|
||||||
<TextField
|
<TextField
|
||||||
@@ -221,9 +223,9 @@ class Connection extends React.Component<Props, State> {
|
|||||||
</Grid>
|
</Grid>
|
||||||
<br />
|
<br />
|
||||||
<div style={{ textAlign: 'right' }}>
|
<div style={{ textAlign: 'right' }}>
|
||||||
<Button variant="contained" className={classes.button}>
|
// <Button variant="contained" className={classes.button}>
|
||||||
Test Connection
|
// Test Connection
|
||||||
</Button>
|
// </Button>
|
||||||
<Button variant="contained" color="secondary" className={classes.button} onClick={() => this.saveConnectionSettings()}>
|
<Button variant="contained" color="secondary" className={classes.button} onClick={() => this.saveConnectionSettings()}>
|
||||||
Save
|
Save
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
57
app/src/components/ConnectionSetup/Notification.tsx
Normal file
57
app/src/components/ConnectionSetup/Notification.tsx
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import * as React from 'react'
|
||||||
|
import { Snackbar, SnackbarContent } from '@material-ui/core'
|
||||||
|
import { red, green } from '@material-ui/core/colors'
|
||||||
|
import { withStyles, Theme } from '@material-ui/core/styles'
|
||||||
|
|
||||||
|
enum MessageType {
|
||||||
|
success = 'success',
|
||||||
|
error = 'error',
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
message: string
|
||||||
|
type: MessageType
|
||||||
|
onClose: () => void
|
||||||
|
classes: any
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
snackBarOpen: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
class Notification extends React.Component<Props, State> {
|
||||||
|
constructor(props: Props) {
|
||||||
|
super(props)
|
||||||
|
this.state = { snackBarOpen: false }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static styles = (theme: Theme) => ({
|
||||||
|
success: {
|
||||||
|
backgroundColor: green[600],
|
||||||
|
color: theme.typography.button.color,
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
backgroundColor: red[600],
|
||||||
|
color: theme.typography.button.color,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
return <Snackbar
|
||||||
|
anchorOrigin={{
|
||||||
|
vertical: 'bottom',
|
||||||
|
horizontal: 'left',
|
||||||
|
}}
|
||||||
|
open = {this.state.snackBarOpen}
|
||||||
|
autoHideDuration = {6000}
|
||||||
|
onClose = {() => { this.setState({ snackBarOpen: false }) }}
|
||||||
|
>
|
||||||
|
<SnackbarContent
|
||||||
|
className = {this.props.classes[this.props.type]}
|
||||||
|
message = {this.props.message}
|
||||||
|
/>
|
||||||
|
</Snackbar>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withStyles(Notification.styles)(Notification)
|
||||||
69
app/src/components/Copy.tsx
Normal file
69
app/src/components/Copy.tsx
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import * as React from 'react'
|
||||||
|
import { Snackbar, SnackbarContent } from '@material-ui/core'
|
||||||
|
import FileCopy from '@material-ui/icons/FileCopy'
|
||||||
|
import Check from '@material-ui/icons/Check'
|
||||||
|
import green from '@material-ui/core/colors/green'
|
||||||
|
import { withStyles, Theme } from '@material-ui/core/styles'
|
||||||
|
const copy = require('copy-text-to-clipboard')
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
value: string
|
||||||
|
classes: any
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
didCopy: boolean
|
||||||
|
snackBarOpen: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
class Copy extends React.Component<Props, State> {
|
||||||
|
constructor(props: Props) {
|
||||||
|
super(props)
|
||||||
|
this.state = { didCopy: false, snackBarOpen: false }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static styles = (theme: Theme) => ({
|
||||||
|
snackbar: {
|
||||||
|
backgroundColor: green[600],
|
||||||
|
color: theme.typography.button.color,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
const icon = !this.state.didCopy
|
||||||
|
? <FileCopy fontSize="inherit" style={ { cursor: 'pointer' } } onClick={this.handleClick} />
|
||||||
|
: <Check fontSize="inherit" style={ { cursor: 'default' } } />
|
||||||
|
|
||||||
|
return <span>
|
||||||
|
<span style={{ fontSize: '16px' }}>{icon}</span>
|
||||||
|
<span>
|
||||||
|
<Snackbar
|
||||||
|
anchorOrigin={{
|
||||||
|
vertical: 'bottom',
|
||||||
|
horizontal: 'left',
|
||||||
|
}}
|
||||||
|
open={this.state.snackBarOpen}
|
||||||
|
autoHideDuration={2000}
|
||||||
|
onClose={() => { this.setState({ snackBarOpen: false }) }}
|
||||||
|
>
|
||||||
|
<SnackbarContent
|
||||||
|
className={this.props.classes.snackbar}
|
||||||
|
message="Copied to clipboard"
|
||||||
|
/>
|
||||||
|
</Snackbar>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleClick = (event: React.MouseEvent) => {
|
||||||
|
event.stopPropagation()
|
||||||
|
|
||||||
|
copy(this.props.value)
|
||||||
|
this.setState({ didCopy: true, snackBarOpen: true })
|
||||||
|
setTimeout(() => {
|
||||||
|
this.setState({ didCopy: false })
|
||||||
|
}, 1500)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withStyles(Copy.styles)(Copy)
|
||||||
Reference in New Issue
Block a user