Use global snackbar

This commit is contained in:
rjwats@gmail.com 2018-03-03 22:41:57 +00:00
parent 5ffe4ab235
commit 521462cf75
12 changed files with 70 additions and 60 deletions

View File

@ -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 (
<JssProvider jss={jss} generateClassName={generateClassName}>
<MuiThemeProvider theme={theme}>
<Reboot />
<AppRouting />
<SnackbarNotification>
<Reboot />
<AppRouting />
</SnackbarNotification>
</MuiThemeProvider>
</JssProvider>
)

View File

@ -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 (
<Fragment>
<Snackbar
anchorOrigin={{
vertical: 'bottom',
@ -60,15 +69,27 @@ class SnackbarNotification extends React.Component {
>
<CloseIcon />
</IconButton>
}
/>
}
/>
{this.props.children}
</Fragment>
);
}
}
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 <WrappedComponent raiseNotification={this.context.raiseNotification} {...this.props} />;
}
};
}

View File

@ -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 (
<SectionContent title="AP Settings">
<SnackbarNotification notificationRef={(raiseNotification)=>this.raiseNotification = raiseNotification} />
<APSettingsForm apSettingsFetched={apSettingsFetched} apSettings={apSettings} errorMessage={errorMessage}
onSubmit={this.saveAPSettings} onReset={this.loadAPSettings} handleValueChange={this.wifiSettingValueChange} />
</SectionContent>
@ -67,4 +66,4 @@ class APSettings extends Component {
}
export default APSettings;
export default withNotifier(APSettings);

View File

@ -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 (
<SectionContent title="AP Status">
<SnackbarNotification notificationRef={(snackbarNotification)=>this.snackbarNotification = snackbarNotification} />
{
!fetched ?
<div>
@ -162,4 +156,4 @@ class APStatus extends Component {
}
}
export default withStyles(styles)(APStatus);
export default withNotifier(withStyles(styles)(APStatus));

View File

@ -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 (
<SectionContent title="NTP Settings">
<SnackbarNotification notificationRef={(raiseNotification)=>this.raiseNotification = raiseNotification} />
<NTPSettingsForm ntpSettingsFetched={ntpSettingsFetched} ntpSettings={ntpSettings} errorMessage={errorMessage}
onSubmit={this.saveNTPSettings} onReset={this.loadNTPSettings} handleValueChange={this.ntpSettingValueChange} />
</SectionContent>
@ -67,4 +66,4 @@ class NTPSettings extends Component {
}
export default NTPSettings;
export default withNotifier(NTPSettings);

View File

@ -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 (
<SectionContent title="NTP Status">
<SnackbarNotification notificationRef={(snackbarNotification)=>this.snackbarNotification = snackbarNotification} />
{
!fetched ?
<div>
@ -186,4 +180,4 @@ class NTPStatus extends Component {
}
}
export default withStyles(styles)(NTPStatus);
export default withNotifier(withStyles(styles)(NTPStatus));

View File

@ -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 (
<SectionContent title="OTA Settings">
<SnackbarNotification notificationRef={(raiseNotification)=>this.raiseNotification = raiseNotification} />
<OTASettingsForm otaSettingsFetched={otaSettingsFetched} otaSettings={otaSettings} errorMessage={errorMessage}
onSubmit={this.saveOTASettings} onReset={this.loadOTASettings} handleValueChange={this.otaSettingValueChange}
handleCheckboxChange={this.otaSettingCheckboxChange} />
@ -74,4 +73,4 @@ class OTASettings extends Component {
}
export default OTASettings;
export default withNotifier(OTASettings);

View File

@ -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);

View File

@ -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 (
<SectionContent title="WiFi Settings">
<SnackbarNotification notificationRef={(raiseNotification)=>this.raiseNotification = raiseNotification} />
<WiFiSettingsForm wifiSettingsFetched={wifiSettingsFetched} wifiSettings={wifiSettings} errorMessage={errorMessage} selectedNetwork={selectedNetwork} deselectNetwork={this.deselectNetwork}
onSubmit={this.saveWiFiSettings} onReset={this.loadWiFiSettings} handleValueChange={this.wifiSettingValueChange} handleCheckboxChange={this.wifiSettingCheckboxChange} />
</SectionContent>
@ -99,4 +98,4 @@ WiFiSettings.propTypes = {
selectedNetwork: PropTypes.object
};
export default WiFiSettings;
export default withNotifier(WiFiSettings);

View File

@ -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 (
<SectionContent title="WiFi Status">
<SnackbarNotification notificationRef={(raiseNotification)=>this.raiseNotification = raiseNotification} />
{
!fetched ?
<div>
@ -185,4 +184,4 @@ class WiFiStatus extends Component {
}
}
export default withStyles(styles)(WiFiStatus);
export default withNotifier(withStyles(styles)(WiFiStatus));

View File

@ -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});
});

View File

@ -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});
});
}