From 62ca13b1a440a5648c512a43e151ecd672a23b56 Mon Sep 17 00:00:00 2001 From: "rjwats@gmail.com" Date: Sun, 4 Mar 2018 17:36:04 +0000 Subject: [PATCH] remove boilerplate from settings --- interface/src/components/RestComponent.js | 23 ++++++-- interface/src/containers/APSettings.js | 61 ++++---------------- interface/src/containers/APStatus.js | 1 - interface/src/containers/NTPSettings.js | 59 ++++--------------- interface/src/containers/OTASettings.js | 67 +++++----------------- interface/src/containers/WiFiSettings.js | 70 +++++++---------------- 6 files changed, 77 insertions(+), 204 deletions(-) diff --git a/interface/src/components/RestComponent.js b/interface/src/components/RestComponent.js index 1aad357..4d29d40 100644 --- a/interface/src/components/RestComponent.js +++ b/interface/src/components/RestComponent.js @@ -1,6 +1,13 @@ import React from 'react'; 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) => { return withNotifier( @@ -9,6 +16,12 @@ export const restComponent = (endpointUrl, FormComponent) => { constructor(props) { super(props); + this.state={ + data:null, + fetched: false, + errorMessage:null + }; + this.setState = this.setState.bind(this); this.loadData = this.loadData.bind(this); this.saveData = this.saveData.bind(this); @@ -47,7 +60,7 @@ export const restComponent = (endpointUrl, FormComponent) => { this.setState({fetched: false}); fetch(endpointUrl, { method: 'POST', - body: JSON.stringify(this.statedata), + body: JSON.stringify(this.state.data), headers: new Headers({ 'Content-Type': 'application/json' }) @@ -67,13 +80,13 @@ export const restComponent = (endpointUrl, FormComponent) => { }); } - valueChange = name => event => { + handleValueChange = name => event => { const { data } = this.state; data[name] = event.target.value; this.setState({data}); }; - checkboxChange = name => event => { + handleCheckboxChange = name => event => { const { data } = this.state; data[name] = event.target.checked; this.setState({data}); @@ -81,8 +94,8 @@ export const restComponent = (endpointUrl, FormComponent) => { render() { return event => { - const { apSettings } = this.state; - apSettings[name] = event.target.value; - this.setState({apSettings}); - }; - render() { - const { apSettingsFetched, apSettings, errorMessage } = this.state; + const { data, fetched, errorMessage } = this.props; return ( - + ) } } -export default withNotifier(APSettings); +export default restComponent(AP_SETTINGS_ENDPOINT, APSettings); diff --git a/interface/src/containers/APStatus.js b/interface/src/containers/APStatus.js index 5313b61..b911b9e 100644 --- a/interface/src/containers/APStatus.js +++ b/interface/src/containers/APStatus.js @@ -16,7 +16,6 @@ import SectionContent from '../components/SectionContent' import * as Highlight from '../constants/Highlight'; import { AP_STATUS_ENDPOINT } from '../constants/Endpoints'; -import { simpleGet } from '../helpers/SimpleGet'; const styles = theme => ({ ["apStatus_" + Highlight.SUCCESS]: { diff --git a/interface/src/containers/NTPSettings.js b/interface/src/containers/NTPSettings.js index 29380e3..54af15a 100644 --- a/interface/src/containers/NTPSettings.js +++ b/interface/src/containers/NTPSettings.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import { NTP_SETTINGS_ENDPOINT } from '../constants/Endpoints'; -import {withNotifier} from '../components/SnackbarNotification'; +import {restComponent} from '../components/RestComponent'; import SectionContent from '../components/SectionContent'; import NTPSettingsForm from '../forms/NTPSettingsForm'; import { simpleGet } from '../helpers/SimpleGet'; @@ -9,61 +9,26 @@ import { simplePost } from '../helpers/SimplePost'; 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() { - 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() { - const { ntpSettingsFetched, ntpSettings, errorMessage } = this.state; + const { data, fetched, errorMessage } = this.props; return ( - + ) } } -export default withNotifier(NTPSettings); +export default restComponent(NTP_SETTINGS_ENDPOINT, NTPSettings); diff --git a/interface/src/containers/OTASettings.js b/interface/src/containers/OTASettings.js index 472c836..ebc1cc8 100644 --- a/interface/src/containers/OTASettings.js +++ b/interface/src/containers/OTASettings.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import { OTA_SETTINGS_ENDPOINT } from '../constants/Endpoints'; -import {withNotifier} from '../components/SnackbarNotification'; +import {restComponent} from '../components/RestComponent'; import SectionContent from '../components/SectionContent'; import OTASettingsForm from '../forms/OTASettingsForm'; import { simpleGet } from '../helpers/SimpleGet'; @@ -9,68 +9,27 @@ import { simplePost } from '../helpers/SimplePost'; 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() { - this.loadOTASettings(); - } - - 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}); + this.props.loadData(); } render() { - const { otaSettingsFetched, otaSettings, errorMessage } = this.state; + const { data, fetched, errorMessage } = this.props; return ( - + ) } } -export default withNotifier(OTASettings); +export default restComponent(OTA_SETTINGS_ENDPOINT, OTASettings); diff --git a/interface/src/containers/WiFiSettings.js b/interface/src/containers/WiFiSettings.js index c1e9cbd..03a49a6 100644 --- a/interface/src/containers/WiFiSettings.js +++ b/interface/src/containers/WiFiSettings.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { WIFI_SETTINGS_ENDPOINT } from '../constants/Endpoints'; -import {withNotifier} from '../components/SnackbarNotification'; +import { restComponent } from '../components/RestComponent'; import SectionContent from '../components/SectionContent'; import WiFiSettingsForm from '../forms/WiFiSettingsForm'; import { simpleGet } from '../helpers/SimpleGet'; @@ -14,15 +14,8 @@ class WiFiSettings extends Component { super(props); this.state = { - wifiSettingsFetched: false, - wifiSettings:{}, 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); } @@ -35,58 +28,39 @@ class WiFiSettings extends Component { hostname:"esp8266-react", static_ip_config:false, } - this.setState({wifiSettingsFetched:true, wifiSettings, selectedNetwork, errorMessage:null}); + this.props.setData(wifiSettings); + this.setState({ selectedNetwork }); deselectNetwork(); }else { - this.loadWiFiSettings(); + this.props.loadData(); } } - loadWiFiSettings() { + deselectNetworkAndLoadData() { this.deselectNetwork(); - - simpleGet( - WIFI_SETTINGS_ENDPOINT, - this.setState, - this.props.raiseNotification, - "wifiSettings", - "wifiSettingsFetched" - ); + this.props.loadData(); } - saveWiFiSettings(e) { - simplePost( - 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}); + deselectNetwork() { + this.setState({ selectedNetwork:null }); } render() { - const { wifiSettingsFetched, wifiSettings, errorMessage, selectedNetwork } = this.state; + const { selectedNetwork } = this.state; + const { data, fetched, errorMessage } = this.props; return ( - + ) } @@ -98,4 +72,4 @@ WiFiSettings.propTypes = { selectedNetwork: PropTypes.object }; -export default withNotifier(WiFiSettings); +export default restComponent(WIFI_SETTINGS_ENDPOINT, WiFiSettings);