remove boilerplate from settings

This commit is contained in:
rjwats@gmail.com 2018-03-04 17:36:04 +00:00
parent eb4bcf708e
commit 62ca13b1a4
6 changed files with 77 additions and 204 deletions

View File

@ -1,6 +1,13 @@
import React from 'react'; import React from 'react';
import {withNotifier} from '../components/SnackbarNotification'; import {withNotifier} from '../components/SnackbarNotification';
/*
* It is unlikely this application will grow complex enough to require redux.
*
* This HOC acts as an interface to a REST service, providing data and change
* event callbacks to the wrapped components along with a function to persist the
* changes.
*/
export const restComponent = (endpointUrl, FormComponent) => { export const restComponent = (endpointUrl, FormComponent) => {
return withNotifier( return withNotifier(
@ -9,6 +16,12 @@ export const restComponent = (endpointUrl, FormComponent) => {
constructor(props) { constructor(props) {
super(props); super(props);
this.state={
data:null,
fetched: false,
errorMessage:null
};
this.setState = this.setState.bind(this); this.setState = this.setState.bind(this);
this.loadData = this.loadData.bind(this); this.loadData = this.loadData.bind(this);
this.saveData = this.saveData.bind(this); this.saveData = this.saveData.bind(this);
@ -47,7 +60,7 @@ export const restComponent = (endpointUrl, FormComponent) => {
this.setState({fetched: false}); this.setState({fetched: false});
fetch(endpointUrl, { fetch(endpointUrl, {
method: 'POST', method: 'POST',
body: JSON.stringify(this.statedata), body: JSON.stringify(this.state.data),
headers: new Headers({ headers: new Headers({
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}) })
@ -67,13 +80,13 @@ export const restComponent = (endpointUrl, FormComponent) => {
}); });
} }
valueChange = name => event => { handleValueChange = name => event => {
const { data } = this.state; const { data } = this.state;
data[name] = event.target.value; data[name] = event.target.value;
this.setState({data}); this.setState({data});
}; };
checkboxChange = name => event => { handleCheckboxChange = name => event => {
const { data } = this.state; const { data } = this.state;
data[name] = event.target.checked; data[name] = event.target.checked;
this.setState({data}); this.setState({data});
@ -81,8 +94,8 @@ export const restComponent = (endpointUrl, FormComponent) => {
render() { render() {
return <FormComponent return <FormComponent
valueChange={this.valueChange} handleValueChange={this.handleValueChange}
checkboxChange={this.checkboxChange} handleCheckboxChange={this.handleCheckboxChange}
setData={this.setData} setData={this.setData}
saveData={this.saveData} saveData={this.saveData}
loadData={this.loadData} loadData={this.loadData}

View File

@ -1,69 +1,32 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { AP_SETTINGS_ENDPOINT } from '../constants/Endpoints'; import { AP_SETTINGS_ENDPOINT } from '../constants/Endpoints';
import {withNotifier} from '../components/SnackbarNotification'; import { restComponent } from '../components/RestComponent';
import SectionContent from '../components/SectionContent'; import SectionContent from '../components/SectionContent';
import APSettingsForm from '../forms/APSettingsForm'; import APSettingsForm from '../forms/APSettingsForm';
import { simpleGet } from '../helpers/SimpleGet';
import { simplePost } from '../helpers/SimplePost';
class APSettings extends Component { class APSettings extends Component {
constructor(props) {
super(props);
this.state = {
apSettings:null,
apSettingsFetched: false,
errorMessage:null
};
this.setState = this.setState.bind(this);
this.loadAPSettings = this.loadAPSettings.bind(this);
this.saveAPSettings = this.saveAPSettings.bind(this);
}
componentDidMount() { componentDidMount() {
this.loadAPSettings(); this.props.loadData();
} }
loadAPSettings() {
simpleGet(
AP_SETTINGS_ENDPOINT,
this.setState,
this.props.raiseNotification,
"apSettings",
"apSettingsFetched"
);
}
saveAPSettings(e) {
simplePost(
AP_SETTINGS_ENDPOINT,
this.state,
this.setState,
this.props.raiseNotification,
"apSettings",
"apSettingsFetched"
);
}
wifiSettingValueChange = name => event => {
const { apSettings } = this.state;
apSettings[name] = event.target.value;
this.setState({apSettings});
};
render() { render() {
const { apSettingsFetched, apSettings, errorMessage } = this.state; const { data, fetched, errorMessage } = this.props;
return ( return (
<SectionContent title="AP Settings"> <SectionContent title="AP Settings">
<APSettingsForm apSettingsFetched={apSettingsFetched} apSettings={apSettings} errorMessage={errorMessage} <APSettingsForm
onSubmit={this.saveAPSettings} onReset={this.loadAPSettings} handleValueChange={this.wifiSettingValueChange} /> apSettings={data}
apSettingsFetched={fetched}
errorMessage={errorMessage}
onSubmit={this.props.saveData}
onReset={this.props.loadData}
handleValueChange={this.props.handleValueChange}
/>
</SectionContent> </SectionContent>
) )
} }
} }
export default withNotifier(APSettings); export default restComponent(AP_SETTINGS_ENDPOINT, APSettings);

View File

@ -16,7 +16,6 @@ import SectionContent from '../components/SectionContent'
import * as Highlight from '../constants/Highlight'; import * as Highlight from '../constants/Highlight';
import { AP_STATUS_ENDPOINT } from '../constants/Endpoints'; import { AP_STATUS_ENDPOINT } from '../constants/Endpoints';
import { simpleGet } from '../helpers/SimpleGet';
const styles = theme => ({ const styles = theme => ({
["apStatus_" + Highlight.SUCCESS]: { ["apStatus_" + Highlight.SUCCESS]: {

View File

@ -1,7 +1,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { NTP_SETTINGS_ENDPOINT } from '../constants/Endpoints'; import { NTP_SETTINGS_ENDPOINT } from '../constants/Endpoints';
import {withNotifier} from '../components/SnackbarNotification'; import {restComponent} from '../components/RestComponent';
import SectionContent from '../components/SectionContent'; import SectionContent from '../components/SectionContent';
import NTPSettingsForm from '../forms/NTPSettingsForm'; import NTPSettingsForm from '../forms/NTPSettingsForm';
import { simpleGet } from '../helpers/SimpleGet'; import { simpleGet } from '../helpers/SimpleGet';
@ -9,61 +9,26 @@ import { simplePost } from '../helpers/SimplePost';
class NTPSettings extends Component { class NTPSettings extends Component {
constructor(props) {
super(props);
this.state = {
ntpSettings:{},
ntpSettingsFetched: false,
errorMessage:null
};
this.setState = this.setState.bind(this);
this.loadNTPSettings = this.loadNTPSettings.bind(this);
this.saveNTPSettings = this.saveNTPSettings.bind(this);
}
componentDidMount() { componentDidMount() {
this.loadNTPSettings(); this.props.loadData();
} }
loadNTPSettings() {
simpleGet(
NTP_SETTINGS_ENDPOINT,
this.setState,
this.props.raiseNotification,
"ntpSettings",
"ntpSettingsFetched"
);
}
saveNTPSettings(e) {
simplePost(
NTP_SETTINGS_ENDPOINT,
this.state,
this.setState,
this.props.raiseNotification,
"ntpSettings",
"ntpSettingsFetched"
);
}
ntpSettingValueChange = name => event => {
const { ntpSettings } = this.state;
ntpSettings[name] = event.target.value;
this.setState({ntpSettings});
};
render() { render() {
const { ntpSettingsFetched, ntpSettings, errorMessage } = this.state; const { data, fetched, errorMessage } = this.props;
return ( return (
<SectionContent title="NTP Settings"> <SectionContent title="NTP Settings">
<NTPSettingsForm ntpSettingsFetched={ntpSettingsFetched} ntpSettings={ntpSettings} errorMessage={errorMessage} <NTPSettingsForm
onSubmit={this.saveNTPSettings} onReset={this.loadNTPSettings} handleValueChange={this.ntpSettingValueChange} /> ntpSettings={data}
ntpSettingsFetched={fetched}
errorMessage={errorMessage}
onSubmit={this.props.saveData}
onReset={this.props.loadData}
handleValueChange={this.props.handleValueChange}
/>
</SectionContent> </SectionContent>
) )
} }
} }
export default withNotifier(NTPSettings); export default restComponent(NTP_SETTINGS_ENDPOINT, NTPSettings);

View File

@ -1,7 +1,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { OTA_SETTINGS_ENDPOINT } from '../constants/Endpoints'; import { OTA_SETTINGS_ENDPOINT } from '../constants/Endpoints';
import {withNotifier} from '../components/SnackbarNotification'; import {restComponent} from '../components/RestComponent';
import SectionContent from '../components/SectionContent'; import SectionContent from '../components/SectionContent';
import OTASettingsForm from '../forms/OTASettingsForm'; import OTASettingsForm from '../forms/OTASettingsForm';
import { simpleGet } from '../helpers/SimpleGet'; import { simpleGet } from '../helpers/SimpleGet';
@ -9,68 +9,27 @@ import { simplePost } from '../helpers/SimplePost';
class OTASettings extends Component { class OTASettings extends Component {
constructor(props) {
super(props);
this.state = {
otaSettings:null,
otaSettingsFetched: false,
errorMessage:null
};
this.setState = this.setState.bind(this);
this.loadOTASettings = this.loadOTASettings.bind(this);
this.saveOTASettings = this.saveOTASettings.bind(this);
}
componentDidMount() { componentDidMount() {
this.loadOTASettings(); this.props.loadData();
}
loadOTASettings() {
simpleGet(
OTA_SETTINGS_ENDPOINT,
this.setState,
this.props.raiseNotification,
"otaSettings",
"otaSettingsFetched"
);
}
saveOTASettings(e) {
simplePost(
OTA_SETTINGS_ENDPOINT,
this.state,
this.setState,
this.props.raiseNotification,
"otaSettings",
"otaSettingsFetched"
);
}
otaSettingValueChange = name => event => {
const { otaSettings } = this.state;
otaSettings[name] = event.target.value;
this.setState({otaSettings});
};
otaSettingCheckboxChange = name => event => {
const { otaSettings } = this.state;
otaSettings[name] = event.target.checked;
this.setState({otaSettings});
} }
render() { render() {
const { otaSettingsFetched, otaSettings, errorMessage } = this.state; const { data, fetched, errorMessage } = this.props;
return ( return (
<SectionContent title="OTA Settings"> <SectionContent title="OTA Settings">
<OTASettingsForm otaSettingsFetched={otaSettingsFetched} otaSettings={otaSettings} errorMessage={errorMessage} <OTASettingsForm
onSubmit={this.saveOTASettings} onReset={this.loadOTASettings} handleValueChange={this.otaSettingValueChange} otaSettings={data}
handleCheckboxChange={this.otaSettingCheckboxChange} /> otaSettingsFetched={fetched}
errorMessage={errorMessage}
onSubmit={this.props.saveData}
onReset={this.props.loadData}
handleValueChange={this.props.handleValueChange}
handleCheckboxChange={this.props.handleCheckboxChange}
/>
</SectionContent> </SectionContent>
) )
} }
} }
export default withNotifier(OTASettings); export default restComponent(OTA_SETTINGS_ENDPOINT, OTASettings);

View File

@ -2,7 +2,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { WIFI_SETTINGS_ENDPOINT } from '../constants/Endpoints'; import { WIFI_SETTINGS_ENDPOINT } from '../constants/Endpoints';
import {withNotifier} from '../components/SnackbarNotification'; import { restComponent } from '../components/RestComponent';
import SectionContent from '../components/SectionContent'; import SectionContent from '../components/SectionContent';
import WiFiSettingsForm from '../forms/WiFiSettingsForm'; import WiFiSettingsForm from '../forms/WiFiSettingsForm';
import { simpleGet } from '../helpers/SimpleGet'; import { simpleGet } from '../helpers/SimpleGet';
@ -14,15 +14,8 @@ class WiFiSettings extends Component {
super(props); super(props);
this.state = { this.state = {
wifiSettingsFetched: false,
wifiSettings:{},
selectedNetwork: null, selectedNetwork: null,
errorMessage:null
}; };
this.setState = this.setState.bind(this);
this.loadWiFiSettings = this.loadWiFiSettings.bind(this);
this.saveWiFiSettings = this.saveWiFiSettings.bind(this);
this.deselectNetwork = this.deselectNetwork.bind(this); this.deselectNetwork = this.deselectNetwork.bind(this);
} }
@ -35,58 +28,39 @@ class WiFiSettings extends Component {
hostname:"esp8266-react", hostname:"esp8266-react",
static_ip_config:false, static_ip_config:false,
} }
this.setState({wifiSettingsFetched:true, wifiSettings, selectedNetwork, errorMessage:null}); this.props.setData(wifiSettings);
this.setState({ selectedNetwork });
deselectNetwork(); deselectNetwork();
}else { }else {
this.loadWiFiSettings(); this.props.loadData();
} }
} }
loadWiFiSettings() { deselectNetworkAndLoadData() {
this.deselectNetwork(); this.deselectNetwork();
this.props.loadData();
simpleGet(
WIFI_SETTINGS_ENDPOINT,
this.setState,
this.props.raiseNotification,
"wifiSettings",
"wifiSettingsFetched"
);
} }
saveWiFiSettings(e) { deselectNetwork() {
simplePost( this.setState({ selectedNetwork:null });
WIFI_SETTINGS_ENDPOINT,
this.state,
this.setState,
this.props.raiseNotification,
"wifiSettings",
"wifiSettingsFetched"
);
}
deselectNetwork(nextNetwork) {
this.setState({selectedNetwork:null});
}
wifiSettingValueChange = name => event => {
const { wifiSettings } = this.state;
wifiSettings[name] = event.target.value;
this.setState({wifiSettings});
};
wifiSettingCheckboxChange = name => event => {
const { wifiSettings } = this.state;
wifiSettings[name] = event.target.checked;
this.setState({wifiSettings});
} }
render() { render() {
const { wifiSettingsFetched, wifiSettings, errorMessage, selectedNetwork } = this.state; const { selectedNetwork } = this.state;
const { data, fetched, errorMessage } = this.props;
return ( return (
<SectionContent title="WiFi Settings"> <SectionContent title="WiFi Settings">
<WiFiSettingsForm wifiSettingsFetched={wifiSettingsFetched} wifiSettings={wifiSettings} errorMessage={errorMessage} selectedNetwork={selectedNetwork} deselectNetwork={this.deselectNetwork} <WiFiSettingsForm
onSubmit={this.saveWiFiSettings} onReset={this.loadWiFiSettings} handleValueChange={this.wifiSettingValueChange} handleCheckboxChange={this.wifiSettingCheckboxChange} /> wifiSettings={data}
wifiSettingsFetched={fetched}
errorMessage={errorMessage}
selectedNetwork={selectedNetwork}
deselectNetwork={this.deselectNetwork}
onSubmit={this.props.saveData}
onReset={this.deselectNetworkAndLoadData}
handleValueChange={this.props.handleValueChange}
handleCheckboxChange={this.props.handleCheckboxChange}
/>
</SectionContent> </SectionContent>
) )
} }
@ -98,4 +72,4 @@ WiFiSettings.propTypes = {
selectedNetwork: PropTypes.object selectedNetwork: PropTypes.object
}; };
export default withNotifier(WiFiSettings); export default restComponent(WIFI_SETTINGS_ENDPOINT, WiFiSettings);