diff --git a/interface/src/App.js b/interface/src/App.js index 6bf088a..e1b5c8c 100644 --- a/interface/src/App.js +++ b/interface/src/App.js @@ -2,11 +2,12 @@ import React, { Component } from 'react'; import AppRouting from './AppRouting'; +import SnackbarNotification from './components/SnackbarNotification'; + import JssProvider from 'react-jss/lib/JssProvider'; import { create } from 'jss'; import Reboot from 'material-ui/Reboot'; - import blueGrey from 'material-ui/colors/blueGrey'; import indigo from 'material-ui/colors/indigo'; import orange from 'material-ui/colors/orange'; @@ -43,8 +44,10 @@ class App extends Component { return ( - - + + + + ) diff --git a/interface/src/components/SnackbarNotification.js b/interface/src/components/SnackbarNotification.js index 35b9643..cad65d7 100644 --- a/interface/src/components/SnackbarNotification.js +++ b/interface/src/components/SnackbarNotification.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, {Fragment} from 'react'; import PropTypes from 'prop-types'; import { withStyles } from 'material-ui/styles'; import Snackbar from 'material-ui/Snackbar'; @@ -13,6 +13,20 @@ const styles = theme => ({ }); class SnackbarNotification extends React.Component { + + constructor(props) { + super(props); + this.raiseNotification=this.raiseNotification.bind(this); + } + + static childContextTypes = { + raiseNotification: PropTypes.func.isRequired + } + + getChildContext = () => { + return {raiseNotification : this.raiseNotification}; + }; + state = { open: false, message: null @@ -29,15 +43,10 @@ class SnackbarNotification extends React.Component { this.setState({ open: false }); }; - componentWillReceiveProps(nextProps){ - if (nextProps.notificationRef){ - nextProps.notificationRef(this.raiseNotification); - } - } - render() { const { classes } = this.props; return ( + - } - /> + } + /> + {this.props.children} + ); } } SnackbarNotification.propTypes = { - classes: PropTypes.object.isRequired, - notificationRef: PropTypes.func.isRequired, + classes: PropTypes.object.isRequired }; export default withStyles(styles)(SnackbarNotification); + +export function withNotifier(WrappedComponent) { + return class extends React.Component { + static contextTypes = { + raiseNotification: PropTypes.func.isRequired + }; + render() { + return ; + } + }; +} diff --git a/interface/src/containers/APSettings.js b/interface/src/containers/APSettings.js index 073b4c4..2268e25 100644 --- a/interface/src/containers/APSettings.js +++ b/interface/src/containers/APSettings.js @@ -1,8 +1,8 @@ import React, { Component } from 'react'; import { AP_SETTINGS_ENDPOINT } from '../constants/Endpoints'; +import {withNotifier} from '../components/SnackbarNotification'; import SectionContent from '../components/SectionContent'; -import SnackbarNotification from '../components/SnackbarNotification'; import APSettingsForm from '../forms/APSettingsForm'; import { simpleGet } from '../helpers/SimpleGet'; import { simplePost } from '../helpers/SimplePost'; @@ -31,7 +31,7 @@ class APSettings extends Component { simpleGet( AP_SETTINGS_ENDPOINT, this.setState, - this.raiseNotification, + this.props.raiseNotification, "apSettings", "apSettingsFetched" ); @@ -42,7 +42,7 @@ class APSettings extends Component { AP_SETTINGS_ENDPOINT, this.state, this.setState, - this.raiseNotification, + this.props.raiseNotification, "apSettings", "apSettingsFetched" ); @@ -58,7 +58,6 @@ class APSettings extends Component { const { apSettingsFetched, apSettings, errorMessage } = this.state; return ( - this.raiseNotification = raiseNotification} /> @@ -67,4 +66,4 @@ class APSettings extends Component { } -export default APSettings; +export default withNotifier(APSettings); diff --git a/interface/src/containers/APStatus.js b/interface/src/containers/APStatus.js index e44821b..ce74b23 100644 --- a/interface/src/containers/APStatus.js +++ b/interface/src/containers/APStatus.js @@ -11,7 +11,7 @@ import SettingsInputAntennaIcon from 'material-ui-icons/SettingsInputAntenna'; import DeviceHubIcon from 'material-ui-icons/DeviceHub'; import ComputerIcon from 'material-ui-icons/Computer'; -import SnackbarNotification from '../components/SnackbarNotification' +import {withNotifier} from '../components/SnackbarNotification'; import SectionContent from '../components/SectionContent' import * as Highlight from '../constants/Highlight'; @@ -48,7 +48,6 @@ class APStatus extends Component { this.setState = this.setState.bind(this); this.loadAPStatus = this.loadAPStatus.bind(this); - this.raiseNotification=this.raiseNotification.bind(this); } componentDidMount() { @@ -59,14 +58,10 @@ class APStatus extends Component { simpleGet( AP_STATUS_ENDPOINT, this.setState, - this.raiseNotification + this.props.raiseNotification ); } - raiseNotification(errorMessage) { - this.snackbarNotification(errorMessage); - } - apStatusHighlight(status){ return status.active ? Highlight.SUCCESS : Highlight.IDLE; } @@ -136,7 +131,6 @@ class APStatus extends Component { return ( - this.snackbarNotification = snackbarNotification} /> { !fetched ?
@@ -162,4 +156,4 @@ class APStatus extends Component { } } -export default withStyles(styles)(APStatus); +export default withNotifier(withStyles(styles)(APStatus)); diff --git a/interface/src/containers/NTPSettings.js b/interface/src/containers/NTPSettings.js index 08643ac..29380e3 100644 --- a/interface/src/containers/NTPSettings.js +++ b/interface/src/containers/NTPSettings.js @@ -1,8 +1,8 @@ import React, { Component } from 'react'; import { NTP_SETTINGS_ENDPOINT } from '../constants/Endpoints'; +import {withNotifier} from '../components/SnackbarNotification'; import SectionContent from '../components/SectionContent'; -import SnackbarNotification from '../components/SnackbarNotification'; import NTPSettingsForm from '../forms/NTPSettingsForm'; import { simpleGet } from '../helpers/SimpleGet'; import { simplePost } from '../helpers/SimplePost'; @@ -31,7 +31,7 @@ class NTPSettings extends Component { simpleGet( NTP_SETTINGS_ENDPOINT, this.setState, - this.raiseNotification, + this.props.raiseNotification, "ntpSettings", "ntpSettingsFetched" ); @@ -42,7 +42,7 @@ class NTPSettings extends Component { NTP_SETTINGS_ENDPOINT, this.state, this.setState, - this.raiseNotification, + this.props.raiseNotification, "ntpSettings", "ntpSettingsFetched" ); @@ -58,7 +58,6 @@ class NTPSettings extends Component { const { ntpSettingsFetched, ntpSettings, errorMessage } = this.state; return ( - this.raiseNotification = raiseNotification} /> @@ -67,4 +66,4 @@ class NTPSettings extends Component { } -export default NTPSettings; +export default withNotifier(NTPSettings); diff --git a/interface/src/containers/NTPStatus.js b/interface/src/containers/NTPStatus.js index a759506..74344b9 100644 --- a/interface/src/containers/NTPStatus.js +++ b/interface/src/containers/NTPStatus.js @@ -19,7 +19,7 @@ import * as Highlight from '../constants/Highlight'; import { unixTimeToTimeAndDate } from '../constants/TimeFormat'; import { NTP_STATUS_ENDPOINT } from '../constants/Endpoints'; -import SnackbarNotification from '../components/SnackbarNotification'; +import {withNotifier} from '../components/SnackbarNotification'; import SectionContent from '../components/SectionContent'; import { simpleGet } from '../helpers/SimpleGet'; @@ -59,7 +59,6 @@ class NTPStatus extends Component { this.setState = this.setState.bind(this); this.loadNTPStatus = this.loadNTPStatus.bind(this); - this.raiseNotification=this.raiseNotification.bind(this); } componentDidMount() { @@ -70,14 +69,10 @@ class NTPStatus extends Component { simpleGet( NTP_STATUS_ENDPOINT, this.setState, - this.raiseNotification + this.props.raiseNotification ); } - raiseNotification(errorMessage) { - this.snackbarNotification(errorMessage); - } - renderNTPStatus(status, fullDetails, classes){ const listItems = []; @@ -160,7 +155,6 @@ class NTPStatus extends Component { return ( - this.snackbarNotification = snackbarNotification} /> { !fetched ?
@@ -186,4 +180,4 @@ class NTPStatus extends Component { } } -export default withStyles(styles)(NTPStatus); +export default withNotifier(withStyles(styles)(NTPStatus)); diff --git a/interface/src/containers/OTASettings.js b/interface/src/containers/OTASettings.js index 5132425..472c836 100644 --- a/interface/src/containers/OTASettings.js +++ b/interface/src/containers/OTASettings.js @@ -1,8 +1,8 @@ import React, { Component } from 'react'; import { OTA_SETTINGS_ENDPOINT } from '../constants/Endpoints'; +import {withNotifier} from '../components/SnackbarNotification'; import SectionContent from '../components/SectionContent'; -import SnackbarNotification from '../components/SnackbarNotification'; import OTASettingsForm from '../forms/OTASettingsForm'; import { simpleGet } from '../helpers/SimpleGet'; import { simplePost } from '../helpers/SimplePost'; @@ -31,7 +31,7 @@ class OTASettings extends Component { simpleGet( OTA_SETTINGS_ENDPOINT, this.setState, - this.raiseNotification, + this.props.raiseNotification, "otaSettings", "otaSettingsFetched" ); @@ -42,7 +42,7 @@ class OTASettings extends Component { OTA_SETTINGS_ENDPOINT, this.state, this.setState, - this.raiseNotification, + this.props.raiseNotification, "otaSettings", "otaSettingsFetched" ); @@ -64,7 +64,6 @@ class OTASettings extends Component { const { otaSettingsFetched, otaSettings, errorMessage } = this.state; return ( - this.raiseNotification = raiseNotification} /> @@ -74,4 +73,4 @@ class OTASettings extends Component { } -export default OTASettings; +export default withNotifier(OTASettings); diff --git a/interface/src/containers/WiFiNetworkScanner.js b/interface/src/containers/WiFiNetworkScanner.js index eb621d6..e32e222 100644 --- a/interface/src/containers/WiFiNetworkScanner.js +++ b/interface/src/containers/WiFiNetworkScanner.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import { SCAN_NETWORKS_ENDPOINT, LIST_NETWORKS_ENDPOINT } from '../constants/Endpoints'; import SectionContent from '../components/SectionContent'; import WiFiNetworkSelector from '../forms/WiFiNetworkSelector'; +import {withNotifier} from '../components/SnackbarNotification'; const NUM_POLLS = 10 const POLLING_FREQUENCY = 500 @@ -44,6 +45,7 @@ class WiFiNetworkScanner extends Component { } throw Error("Scanning for networks returned unexpected response code: " + response.status); }).catch(error => { + this.props.raiseNotification("Problem scanning: " + error.message); this.setState({scanningForNetworks:false, networkList: null, errorMessage:error.message}); }); } @@ -78,7 +80,7 @@ class WiFiNetworkScanner extends Component { this.schedulePollTimeout(); throw this.retryError(); }else{ - throw Error("Device did not return network list in timley manner."); + throw Error("Device did not return network list in timely manner."); } } throw Error("Device returned unexpected response code: " + response.status); @@ -90,6 +92,7 @@ class WiFiNetworkScanner extends Component { .catch(error => { console.log(error.message); if (error.name !== RETRY_EXCEPTION_TYPE) { + this.props.raiseNotification("Problem scanning: " + error.message); this.setState({scanningForNetworks:false, networkList: null, errorMessage:error.message}); } }); @@ -115,4 +118,4 @@ WiFiNetworkScanner.propTypes = { selectNetwork: PropTypes.func.isRequired }; -export default (WiFiNetworkScanner); +export default withNotifier(WiFiNetworkScanner); diff --git a/interface/src/containers/WiFiSettings.js b/interface/src/containers/WiFiSettings.js index 201c226..c1e9cbd 100644 --- a/interface/src/containers/WiFiSettings.js +++ b/interface/src/containers/WiFiSettings.js @@ -2,8 +2,8 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { WIFI_SETTINGS_ENDPOINT } from '../constants/Endpoints'; +import {withNotifier} from '../components/SnackbarNotification'; import SectionContent from '../components/SectionContent'; -import SnackbarNotification from '../components/SnackbarNotification'; import WiFiSettingsForm from '../forms/WiFiSettingsForm'; import { simpleGet } from '../helpers/SimpleGet'; import { simplePost } from '../helpers/SimplePost'; @@ -48,7 +48,7 @@ class WiFiSettings extends Component { simpleGet( WIFI_SETTINGS_ENDPOINT, this.setState, - this.raiseNotification, + this.props.raiseNotification, "wifiSettings", "wifiSettingsFetched" ); @@ -59,7 +59,7 @@ class WiFiSettings extends Component { WIFI_SETTINGS_ENDPOINT, this.state, this.setState, - this.raiseNotification, + this.props.raiseNotification, "wifiSettings", "wifiSettingsFetched" ); @@ -85,7 +85,6 @@ class WiFiSettings extends Component { const { wifiSettingsFetched, wifiSettings, errorMessage, selectedNetwork } = this.state; return ( - this.raiseNotification = raiseNotification} /> @@ -99,4 +98,4 @@ WiFiSettings.propTypes = { selectedNetwork: PropTypes.object }; -export default WiFiSettings; +export default withNotifier(WiFiSettings); diff --git a/interface/src/containers/WiFiStatus.js b/interface/src/containers/WiFiStatus.js index 2bf2068..0a36d51 100644 --- a/interface/src/containers/WiFiStatus.js +++ b/interface/src/containers/WiFiStatus.js @@ -5,7 +5,7 @@ import Button from 'material-ui/Button'; import { LinearProgress } from 'material-ui/Progress'; import Typography from 'material-ui/Typography'; -import SnackbarNotification from '../components/SnackbarNotification'; +import {withNotifier} from '../components/SnackbarNotification'; import SectionContent from '../components/SectionContent'; import { WIFI_STATUS_ENDPOINT } from '../constants/Endpoints'; @@ -75,7 +75,7 @@ class WiFiStatus extends Component { simpleGet( WIFI_STATUS_ENDPOINT, this.setState, - this.raiseNotification + this.props.raiseNotification ); } @@ -159,7 +159,6 @@ class WiFiStatus extends Component { return ( - this.raiseNotification = raiseNotification} /> { !fetched ?
@@ -185,4 +184,4 @@ class WiFiStatus extends Component { } } -export default withStyles(styles)(WiFiStatus); +export default withNotifier(withStyles(styles)(WiFiStatus)); diff --git a/interface/src/helpers/SimpleGet.js b/interface/src/helpers/SimpleGet.js index fe262f6..01db80f 100644 --- a/interface/src/helpers/SimpleGet.js +++ b/interface/src/helpers/SimpleGet.js @@ -28,7 +28,7 @@ export const simpleGet = ( .then(json => {setState({[dataKey]: json, [fetchedKey]:true})}) .catch(error =>{ if (raiseNotification) { - raiseNotification("Problem fetching. " + error.message); + raiseNotification("Problem fetching: " + error.message); } setState({[dataKey]: null, [fetchedKey]:true, [errorMessageKey]:error.message}); }); diff --git a/interface/src/helpers/SimplePost.js b/interface/src/helpers/SimplePost.js index 7991570..b56696e 100644 --- a/interface/src/helpers/SimplePost.js +++ b/interface/src/helpers/SimplePost.js @@ -32,7 +32,7 @@ export const simplePost = ( raiseNotification("Changes successfully applied."); setState({[dataKey]: json, [fetchedKey]:true}); }).catch(error => { - raiseNotification("Problem saving. " + error.message); + raiseNotification("Problem saving: " + error.message); setState({[dataKey]: null, [fetchedKey]:true, [errorMessageKey]:error.message}); }); }