From 82c4f3ea57505f8c1c81cc1c147ff88e066a471f Mon Sep 17 00:00:00 2001 From: britea Date: Tue, 14 Apr 2020 14:58:03 +0200 Subject: [PATCH 01/15] Basic Tabs system --- .../components/dashboard/AutomationsPanel.js | 23 +++++ .../src/components/dashboard/DevicePanel.js | 29 +++---- .../src/components/dashboard/ScenesPanel.js | 23 +++++ .../dashboard/devices/styleComponents.js | 1 + smart-hut/src/store.js | 10 +++ smart-hut/src/storeActions.js | 4 + smart-hut/src/views/Dashboard.js | 83 ++++++++++++++++++- 7 files changed, 154 insertions(+), 19 deletions(-) create mode 100644 smart-hut/src/components/dashboard/AutomationsPanel.js create mode 100644 smart-hut/src/components/dashboard/ScenesPanel.js diff --git a/smart-hut/src/components/dashboard/AutomationsPanel.js b/smart-hut/src/components/dashboard/AutomationsPanel.js new file mode 100644 index 0000000..4fbf809 --- /dev/null +++ b/smart-hut/src/components/dashboard/AutomationsPanel.js @@ -0,0 +1,23 @@ +import React, { Component } from "react"; +import { connect } from "react-redux"; +import { RemoteService } from "../../remote"; + +class AutomationsPanel extends Component { + constructor(props) { + super(props); + } + + render() { + return

AUTOMATIONS

; + } +} + +const mapStateToProps = (state, _) => ({ + activeRoom: state.active.activeRoom, + activeTab: state.active.activeTab, +}); +const AutomationsPanelContainer = connect( + mapStateToProps, + RemoteService +)(AutomationsPanel); +export default AutomationsPanelContainer; diff --git a/smart-hut/src/components/dashboard/DevicePanel.js b/smart-hut/src/components/dashboard/DevicePanel.js index 5e0fb17..92cdb7c 100644 --- a/smart-hut/src/components/dashboard/DevicePanel.js +++ b/smart-hut/src/components/dashboard/DevicePanel.js @@ -2,7 +2,6 @@ import React, { Component } from "react"; import { Grid } from "semantic-ui-react"; -import { panelStyle } from "./devices/styleComponents"; import Device from "./devices/Device"; import NewDevice from "./devices/NewDevice"; import { connect } from "react-redux"; @@ -23,22 +22,20 @@ class DevicePanel extends Component { render() { return ( -
- - {this.props.devices.map((e, i) => { - return ( - - - - ); - })} - {!this.props.isActiveRoomHome ? ( - - + + {this.props.devices.map((e, i) => { + return ( + + - ) : null} - -
+ ); + })} + {!this.props.isActiveRoomHome ? ( + + + + ) : null} + ); } } diff --git a/smart-hut/src/components/dashboard/ScenesPanel.js b/smart-hut/src/components/dashboard/ScenesPanel.js new file mode 100644 index 0000000..e33da64 --- /dev/null +++ b/smart-hut/src/components/dashboard/ScenesPanel.js @@ -0,0 +1,23 @@ +import React, { Component } from "react"; +import { connect } from "react-redux"; +import { RemoteService } from "../../remote"; + +class ScenesPanel extends Component { + constructor(props) { + super(props); + } + + render() { + return

SCENES

; + } +} + +const mapStateToProps = (state, _) => ({ + activeRoom: state.active.activeRoom, + activeTab: state.active.activeTab, +}); +const ScenesPanelContainer = connect( + mapStateToProps, + RemoteService +)(ScenesPanel); +export default ScenesPanelContainer; diff --git a/smart-hut/src/components/dashboard/devices/styleComponents.js b/smart-hut/src/components/dashboard/devices/styleComponents.js index 9c052f7..1eba7d1 100644 --- a/smart-hut/src/components/dashboard/devices/styleComponents.js +++ b/smart-hut/src/components/dashboard/devices/styleComponents.js @@ -23,6 +23,7 @@ export const panelStyle = { height: "100vh", width: "auto", padding: "0rem 3rem", + color: "#000000", }; export const editModeStyle = { diff --git a/smart-hut/src/store.js b/smart-hut/src/store.js index 7b04a89..bc93159 100644 --- a/smart-hut/src/store.js +++ b/smart-hut/src/store.js @@ -231,6 +231,15 @@ function reducer(previousState, action) { }, }); break; + case "SET_ACTIVE_TAB": + newState = update(previousState, { + active: { + activeTab: { + $set: action.activeTab, + }, + }, + }); + break; case "REDUX_WEBSOCKET::MESSAGE": const devices = JSON.parse(action.payload.message); console.log(devices); @@ -255,6 +264,7 @@ const initState = { }, active: { activeRoom: -1, + activeTab: "Devices", }, login: { loggedIn: false, diff --git a/smart-hut/src/storeActions.js b/smart-hut/src/storeActions.js index 3a20fee..349983c 100644 --- a/smart-hut/src/storeActions.js +++ b/smart-hut/src/storeActions.js @@ -52,6 +52,10 @@ export const appActions = { type: "SET_ACTIVE_ROOM", activeRoom, }), + setActiveTab: (activeTab) => ({ + type: "SET_ACTIVE_TAB", + activeTab, + }), }; export default actions; diff --git a/smart-hut/src/views/Dashboard.js b/smart-hut/src/views/Dashboard.js index 06c10ef..0be3f8d 100644 --- a/smart-hut/src/views/Dashboard.js +++ b/smart-hut/src/views/Dashboard.js @@ -1,10 +1,48 @@ import React, { Component } from "react"; import DevicePanel from "../components/dashboard/DevicePanel"; +import ScenesPanel from "../components/dashboard/ScenesPanel"; +import AutomationsPanel from "../components/dashboard/AutomationsPanel"; import Navbar from "./Navbar"; import MyHeader from "../components/HeaderController"; -import { Grid, Responsive } from "semantic-ui-react"; +import { Grid, Responsive, Button } from "semantic-ui-react"; +import { panelStyle } from "../components/dashboard/devices/styleComponents"; + +import { RemoteService } from "../remote"; +import { connect } from "react-redux"; +import { appActions } from "../storeActions"; + +class Dashboard extends Component { + constructor(props) { + super(props); + + this.selectTab = this.selectTab.bind(this); + } + + get activeTab() { + return this.props.activeTab; + } + + set activeTab(tab) { + this.props.setActiveTab(tab); + } + + selectTab(e, { name }) { + this.activeTab = name; + } + + renderTab(tab) { + switch (tab) { + case "Devices": + return ; + case "Scenes": + return ; + case "Automations": + return ; + default: + return

ERROR

; + } + } -export default class Dashboard extends Component { render() { return (
@@ -15,13 +53,38 @@ export default class Dashboard extends Component { + + + + ) : ( + + )} + + + {this.type === "new" ? ( + + ) : ( + + )} + +
+ ) : null} + + +
+ {this.type === "new" ? "Add new automation" : "Modify automation"} +
+ + { + //TODO FORM TO ADD OR MODIFY SCENE + } + + {this.type === "modify" ? ( + + ) : null} + + + + + + +
+ + ); + } +} + +const setActiveAutomation = (activeAutomation) => { + return (dispatch) => + dispatch(appActions.setActiveAutomation(activeAutomation)); +}; + +const mapStateToProps = (state, ownProps) => ({ + automations: ownProps.id ? state.automations[ownProps.id] : null, +}); +const AutomationModalContainer = connect( + mapStateToProps, + { ...RemoteService, setActiveAutomation }, + null, + { forwardRef: true } +)(AutomationModal); +export default AutomationModalContainer; diff --git a/smart-hut/src/components/SceneModal.js b/smart-hut/src/components/SceneModal.js new file mode 100644 index 0000000..af97d89 --- /dev/null +++ b/smart-hut/src/components/SceneModal.js @@ -0,0 +1,187 @@ +import React, { Component } from "react"; +import { Button, Header, Modal, Icon, Responsive } from "semantic-ui-react"; +import { connect } from "react-redux"; +import { RemoteService } from "../remote"; +import { appActions } from "../storeActions"; +//import { update } from "immutability-helper"; + +class SceneModal extends Component { + constructor(props) { + super(props); + this.state = this.initialState; + this.setInitialState(); + + this.addSceneModal = this.addSceneModal.bind(this); + this.modifySceneModal = this.modifySceneModal.bind(this); + this.deleteScene = this.deleteScene.bind(this); + } + + get initialState() { + return { + //INITIAL STATE HERE + }; + } + + setInitialState() { + this.setState(this.initialState); + } + + get type() { + return !this.props.id ? "new" : "modify"; + } + + addSceneModal = (e) => { + /*let data = { + // DATA HERE + };*/ + // TODO CALL TO REMOTE SERVER TO ADD SCENE + /*this.props + .saveRoom(data, null) + .then(() => { + this.setInitialState(); + this.closeModal(); + }) + .catch((err) => console.error("error in creating room", err));*/ + }; + + modifySceneModal = (e) => { + /*let data = { + // DATA HERE + };*/ + // TODO CALL TO REMOTE SERVER TO MODIFY SCENE + /*this.props + .saveRoom(data, this.props.id) + .then(() => { + this.setInitialState(); + this.closeModal(); + }) + .catch((err) => console.error("error in updating room", err));*/ + }; + + deleteScene = (e) => { + // TODO CALL TO REMOTE SERVER TO DELETE SCENE + /* + this.props + .deleteRoom(this.props.id) + .then(() => this.closeModal()) + .catch((err) => console.error("error in deleting room", err));*/ + }; + + changeSomething = (event) => { + let nam = event.target.name; + let val = event.target.value; + this.setState({ [nam]: val }); + }; + + closeModal = (e) => { + this.setState({ openModal: false }); + }; + + openModal = (e) => { + this.setState({ openModal: true }); + }; + + render() { + return ( +
+ {!this.props.nicolaStop ? ( +
+ + {this.type === "new" ? ( + + ) : ( + + )} + + + {this.type === "new" ? ( + + ) : ( + + )} + +
+ ) : null} + + +
+ {this.type === "new" ? "Add new scene" : "Modify scene"} +
+ + { + //TODO FORM TO ADD OR MODIFY SCENE + } + + {this.type === "modify" ? ( + + ) : null} + + + + + + +
+
+ ); + } +} + +const setActiveScene = (activeScene) => { + return (dispatch) => dispatch(appActions.setActiveScene(activeScene)); +}; + +const mapStateToProps = (state, ownProps) => ({ + scene: ownProps.id ? state.scenes[ownProps.id] : null, +}); +const SceneModalContainer = connect( + mapStateToProps, + { ...RemoteService, setActiveScene }, + null, + { forwardRef: true } +)(SceneModal); +export default SceneModalContainer; diff --git a/smart-hut/src/components/dashboard/ScenesPanel.js b/smart-hut/src/components/dashboard/ScenesPanel.js index e33da64..1a6db3e 100644 --- a/smart-hut/src/components/dashboard/ScenesPanel.js +++ b/smart-hut/src/components/dashboard/ScenesPanel.js @@ -5,6 +5,7 @@ import { RemoteService } from "../../remote"; class ScenesPanel extends Component { constructor(props) { super(props); + console.log(this.props.activeRoom, this.props.activeTab); } render() { diff --git a/smart-hut/src/store.js b/smart-hut/src/store.js index bc93159..a2b031a 100644 --- a/smart-hut/src/store.js +++ b/smart-hut/src/store.js @@ -240,6 +240,24 @@ function reducer(previousState, action) { }, }); break; + case "SET_ACTIVE_SCENE": + newState = update(previousState, { + active: { + activeScene: { + $set: action.activeScene, + }, + }, + }); + break; + case "SET_ACTIVE_AUTOMATION": + newState = update(previousState, { + active: { + activeAutomation: { + $set: action.activeAutomation, + }, + }, + }); + break; case "REDUX_WEBSOCKET::MESSAGE": const devices = JSON.parse(action.payload.message); console.log(devices); @@ -261,10 +279,14 @@ const initState = { errors: {}, pendingJoins: { rooms: {}, + scenes: {}, + automations: {}, }, active: { activeRoom: -1, activeTab: "Devices", + activeScene: -1, + activeAutomation: -1, }, login: { loggedIn: false, @@ -273,6 +295,10 @@ const initState = { userInfo: null, /** @type {[integer]Room} */ rooms: {}, + /** @type {[integer]Scenes} */ + scenes: {}, + /** @type {[integer]Automations} */ + automations: {}, /** @type {[integer]Device} */ devices: {}, }; diff --git a/smart-hut/src/storeActions.js b/smart-hut/src/storeActions.js index 349983c..e224b99 100644 --- a/smart-hut/src/storeActions.js +++ b/smart-hut/src/storeActions.js @@ -56,6 +56,14 @@ export const appActions = { type: "SET_ACTIVE_TAB", activeTab, }), + setActiveScene: (activeScene = -1) => ({ + type: "SET_ACTIVE_SCENE", + activeScene, + }), + setActiveAutomations: (activeAutomation = -1) => ({ + type: "SET_ACTIVE_AUTOMATION", + activeAutomation, + }), }; export default actions; diff --git a/smart-hut/src/views/AutomationsNavbar.js b/smart-hut/src/views/AutomationsNavbar.js new file mode 100644 index 0000000..3378a90 --- /dev/null +++ b/smart-hut/src/views/AutomationsNavbar.js @@ -0,0 +1,165 @@ +import React, { Component } from "react"; +import { + Menu, + Button, + Grid, + Icon, + Responsive, + Dropdown, +} from "semantic-ui-react"; +import { editButtonStyle } from "../components/dashboard/devices/styleComponents"; +import AutomationModal from "../components/AutomationModal"; +import { RemoteService } from "../remote"; +import { connect } from "react-redux"; +import { appActions } from "../storeActions"; + +class AutomationsNavbar extends Component { + constructor(props) { + super(props); + this.state = { + editMode: false, + }; + + this.toggleEditMode = this.toggleEditMode.bind(this); + this.openCurrentModalMobile = this.openCurrentModalMobile.bind(this); + } + + get activeItemAutomation() { + return this.props.activeAutomation; + } + + set activeItemAutomation(item) { + this.props.setActiveAutomation(item); + } + + get activeItemAutomationsName() { + if (this.props.activeAutomation === -1) return "Home"; + return this.props.automations[this.props.activeAutomation].name; + } + + openCurrentModalMobile() { + console.log(this.activeItemAutomation, this.props.automationsModalRefs); + const currentModal = this.props.automationsModalRefs[ + this.activeItemAutomation + ].current; + currentModal.openModal(); + } + + toggleEditMode(e) { + this.setState((prevState) => ({ editMode: !prevState.editMode })); + } + + render() { + return ( +
+ + + + + + + + + + + + + + AUTOMATIONS + + + + { + //INSERT LIST OF AUTOMATIONS HERE + } + + + + + + + + + + + + + + + + + + + + + + + Automations + + + + + { + //INSERT LIST OF AUTOMATIONS HERE + } + + + + + + + + + {this.activeItemAutomation !== -1 ? ( + + + + ) : null} + + + +
+ ); + } +} + +const setActiveAutomation = (activeAutomation) => { + return (dispatch) => + dispatch(appActions.setActiveAutomation(activeAutomation)); +}; + +const mapStateToProps = (state, _) => ({ + automations: state.automations, + activeAutomation: state.active.activeAutomation, + automationModalRefs: Object.keys(state.automations).reduce( + (acc, key) => ({ ...acc, [key]: React.createRef() }), + {} + ), +}); +const AutomationsNavbarContainer = connect(mapStateToProps, { + ...RemoteService, + setActiveAutomation, +})(AutomationsNavbar); +export default AutomationsNavbarContainer; diff --git a/smart-hut/src/views/Dashboard.js b/smart-hut/src/views/Dashboard.js index 17a1367..f3c204f 100644 --- a/smart-hut/src/views/Dashboard.js +++ b/smart-hut/src/views/Dashboard.js @@ -3,6 +3,8 @@ import DevicePanel from "../components/dashboard/DevicePanel"; import ScenesPanel from "../components/dashboard/ScenesPanel"; import AutomationsPanel from "../components/dashboard/AutomationsPanel"; import Navbar from "./Navbar"; +import ScenesNavbar from "./ScenesNavbar"; +import AutomationsNavbar from "./AutomationsNavbar"; import MyHeader from "../components/HeaderController"; import { Grid, Responsive, Button } from "semantic-ui-react"; import { @@ -46,6 +48,19 @@ class Dashboard extends Component { } } + renderNavbar(tab) { + switch (tab) { + case "Devices": + return ; + case "Scenes": + return ; + case "Automations": + return ; + default: + return

ERROR

; + } + } + render() { return (
@@ -87,7 +102,7 @@ class Dashboard extends Component { - + {this.renderNavbar(this.activeTab)} diff --git a/smart-hut/src/views/ScenesNavbar.js b/smart-hut/src/views/ScenesNavbar.js new file mode 100644 index 0000000..27862a6 --- /dev/null +++ b/smart-hut/src/views/ScenesNavbar.js @@ -0,0 +1,162 @@ +import React, { Component } from "react"; +import { + Menu, + Button, + Grid, + Icon, + Responsive, + Dropdown, +} from "semantic-ui-react"; +import { editButtonStyle } from "../components/dashboard/devices/styleComponents"; +import SceneModal from "../components/SceneModal"; +import { RemoteService } from "../remote"; +import { connect } from "react-redux"; +import { appActions } from "../storeActions"; + +class ScenesNavbar extends Component { + constructor(props) { + super(props); + this.state = { + editMode: false, + }; + + this.toggleEditMode = this.toggleEditMode.bind(this); + this.openCurrentModalMobile = this.openCurrentModalMobile.bind(this); + } + + get activeItemScene() { + return this.props.activeScene; + } + + set activeItemScene(item) { + this.props.setActiveScene(item); + } + + get activeItemSceneName() { + if (this.props.activeScene === -1) return "Home"; + return this.props.scenes[this.props.activeScene].name; + } + + openCurrentModalMobile() { + console.log(this.activeItem, this.props.roomModalRefs); + const currentModal = this.props.roomModalRefs[this.activeItem].current; + currentModal.openModal(); + } + + toggleEditMode(e) { + this.setState((prevState) => ({ editMode: !prevState.editMode })); + } + + render() { + return ( +
+ + + + + + + + + + + + + + SCENES + + + + { + //INSERT LIST OF SCENES HERE + } + + + + + + + + + + + + + + + + + + + + + + + Scene + + + + + { + //INSERT LIST OF SCENES HERE + } + + + + + + + + + {this.activeItemScene !== -1 ? ( + + + + ) : null} + + + +
+ ); + } +} + +const setActiveScene = (activeScene) => { + return (dispatch) => dispatch(appActions.setActiveScene(activeScene)); +}; + +const mapStateToProps = (state, _) => ({ + scenes: state.scenes, + activeScene: state.active.activeScene, + sceneModalRefs: Object.keys(state.scenes).reduce( + (acc, key) => ({ ...acc, [key]: React.createRef() }), + {} + ), +}); +const ScenesNavbarContainer = connect(mapStateToProps, { + ...RemoteService, + setActiveScene, +})(ScenesNavbar); +export default ScenesNavbarContainer; From 56da195894992f3ea411d78cc77f62c03ffd829f Mon Sep 17 00:00:00 2001 From: britea Date: Thu, 16 Apr 2020 15:15:33 +0200 Subject: [PATCH 04/15] Fixed registration bug --- smart-hut/src/components/RoomModal.js | 11 ++- smart-hut/src/components/SceneModal.js | 73 ++++++++++++++-- .../components/dashboard/NewSceneDevice.js | 87 +++++++++++++++++++ .../src/components/dashboard/ScenesPanel.js | 23 ++++- smart-hut/src/remote.js | 14 +-- smart-hut/src/views/Login.js | 2 +- 6 files changed, 193 insertions(+), 17 deletions(-) create mode 100644 smart-hut/src/components/dashboard/NewSceneDevice.js diff --git a/smart-hut/src/components/RoomModal.js b/smart-hut/src/components/RoomModal.js index eabdb89..36496b2 100644 --- a/smart-hut/src/components/RoomModal.js +++ b/smart-hut/src/components/RoomModal.js @@ -49,7 +49,16 @@ class RoomModal extends Component { } setInitialState() { - this.setState(this.initialState); + for (let key in this.initialState) { + if (this.initialState.hasOwnProperty(key)) { + //console.log(key + " -> " + this.initialState[key]); + this.setState({ + key: this.initialState[key], + }); + } + } + console.log(this.initialState); + //this.setState(state); } get type() { diff --git a/smart-hut/src/components/SceneModal.js b/smart-hut/src/components/SceneModal.js index af97d89..cff8630 100644 --- a/smart-hut/src/components/SceneModal.js +++ b/smart-hut/src/components/SceneModal.js @@ -1,5 +1,14 @@ import React, { Component } from "react"; -import { Button, Header, Modal, Icon, Responsive } from "semantic-ui-react"; +import { + Button, + Header, + Modal, + Icon, + Responsive, + Form, + Input, + Dropdown, +} from "semantic-ui-react"; import { connect } from "react-redux"; import { RemoteService } from "../remote"; import { appActions } from "../storeActions"; @@ -10,6 +19,7 @@ class SceneModal extends Component { super(props); this.state = this.initialState; this.setInitialState(); + this.getDevices(); this.addSceneModal = this.addSceneModal.bind(this); this.modifySceneModal = this.modifySceneModal.bind(this); @@ -18,7 +28,9 @@ class SceneModal extends Component { get initialState() { return { - //INITIAL STATE HERE + name: this.type === "new" ? "New Scene" : this.props.room.name, + sceneDevices: this.type === "new" ? [{}] : [this.props.scene.devices], + openModal: false, }; } @@ -30,6 +42,12 @@ class SceneModal extends Component { return !this.props.id ? "new" : "modify"; } + getDevices() { + this.props + .fetchDevices() + .catch((err) => console.error(`error fetching devices:`, err)); + } + addSceneModal = (e) => { /*let data = { // DATA HERE @@ -81,7 +99,21 @@ class SceneModal extends Component { this.setState({ openModal: true }); }; + setSceneDevice(e, d) { + this.setState({ sceneDevices: d.value }); + } + render() { + const availableDevices = []; + this.props.devices.forEach((e) => { + if (!this.state.sceneDevices.includes(e)) { + availableDevices.push({ + key: e.id, + text: e.name, + id: e.id, + }); + } + }); return (
{!this.props.nicolaStop ? ( @@ -132,9 +164,30 @@ class SceneModal extends Component { {this.type === "new" ? "Add new scene" : "Modify scene"} - { - //TODO FORM TO ADD OR MODIFY SCENE - } +
+

Insert the name of the scene:

+ + + + + + + +
{this.type === "modify" ? ( + + + ); + } +} + +const mapStateToProps = (state, _) => ({ + devices: Object.values(state.devices), + activeRoom: state.active.activeRoom, +}); +const NewSceneDeviceContainer = connect( + mapStateToProps, + RemoteService +)(NewSceneDevice); +export default NewSceneDeviceContainer; diff --git a/smart-hut/src/components/dashboard/ScenesPanel.js b/smart-hut/src/components/dashboard/ScenesPanel.js index 1a6db3e..ca96e0b 100644 --- a/smart-hut/src/components/dashboard/ScenesPanel.js +++ b/smart-hut/src/components/dashboard/ScenesPanel.js @@ -1,21 +1,36 @@ import React, { Component } from "react"; import { connect } from "react-redux"; import { RemoteService } from "../../remote"; +import NewSceneDevice from "./NewSceneDevice"; +import { Grid } from "semantic-ui-react"; class ScenesPanel extends Component { constructor(props) { super(props); - console.log(this.props.activeRoom, this.props.activeTab); + console.log(this.props.activeScene); } render() { - return

SCENES

; + return ( + + { + //TODO DISPLAY DEVICES IN SCENE + } + {this.props.isActiveDefaultScene ? ( + + + + ) : null} + + ); } } const mapStateToProps = (state, _) => ({ - activeRoom: state.active.activeRoom, - activeTab: state.active.activeTab, + get isActiveDefaultScene() { + return state.active.activeScene === -1; + }, + activeScene: state.active.activeScene, }); const ScenesPanelContainer = connect( mapStateToProps, diff --git a/smart-hut/src/remote.js b/smart-hut/src/remote.js index 3100417..825ba1d 100644 --- a/smart-hut/src/remote.js +++ b/smart-hut/src/remote.js @@ -39,8 +39,8 @@ const Endpoint = { * @param {[String]String} query query ('?') parameters (no params by default) * @param {any} body the JSON request body */ - send: (method, route, query = {}, body = null) => { - if (!Endpoint.token) { + send: (method, route, query = {}, body = null, registration) => { + if (!registration && !Endpoint.token) { throw new Error("No token while performing authenticated request"); } @@ -48,9 +48,11 @@ const Endpoint = { method: method, params: query, data: ["put", "post"].indexOf(method) !== -1 ? body : null, - headers: { - Authorization: `Bearer ${Endpoint.token}`, - }, + headers: !registration + ? { + Authorization: `Bearer ${Endpoint.token}`, + } + : {}, }).then((res) => { if (!res.data && method !== "delete") { console.error("Response body is empty"); @@ -109,7 +111,7 @@ const Endpoint = { * @returns {Promise<*, *>} The Axios-generated promise */ post(route, query, body) { - return this.send("post", route, query, body); + return this.send("post", route, query, body, true); }, /** diff --git a/smart-hut/src/views/Login.js b/smart-hut/src/views/Login.js index 375d1a5..3544e7a 100644 --- a/smart-hut/src/views/Login.js +++ b/smart-hut/src/views/Login.js @@ -31,7 +31,7 @@ class Login extends Component { .login(this.state.user, this.state.password) .then(() => this.props.history.push("/dashboard")) .catch((err) => { - console.log(err); + console.log("CIAO", err); this.setState({ error: { state: true, message: err.messages.join(" - ") }, }); From b070273c7361980e2be741da70c21c920ed63f0b Mon Sep 17 00:00:00 2001 From: "Claudio Maggioni (maggicl)" Date: Thu, 16 Apr 2020 15:58:56 +0200 Subject: [PATCH 05/15] Fix to socket state reducer and state updated in devices that use circularinput --- .../src/components/dashboard/devices/Light.js | 6 ++++++ .../src/components/dashboard/devices/Sensor.js | 14 ++++++++++++++ smart-hut/src/store.js | 14 +++++++++----- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/smart-hut/src/components/dashboard/devices/Light.js b/smart-hut/src/components/dashboard/devices/Light.js index 9143ec3..5d01d89 100644 --- a/smart-hut/src/components/dashboard/devices/Light.js +++ b/smart-hut/src/components/dashboard/devices/Light.js @@ -44,6 +44,12 @@ class Light extends Component { this.setIntensity = this.setIntensity.bind(this); } + componentDidUpdate(prevProps, prevState) { + if (this.props.device.intensity !== prevProps.device.intensity) { + this.setState({ intensity: this.props.device.intensity, timeout: null }); + } + } + get turnedOn() { return this.props.device.on; } diff --git a/smart-hut/src/components/dashboard/devices/Sensor.js b/smart-hut/src/components/dashboard/devices/Sensor.js index 938209c..4d3cf81 100644 --- a/smart-hut/src/components/dashboard/devices/Sensor.js +++ b/smart-hut/src/components/dashboard/devices/Sensor.js @@ -62,6 +62,20 @@ class Sensor extends Component { return this.props.device.name; }; + componentDidUpdate(prevProps) { + if ( + this.props.device.kind === "sensor" && + this.props.device.value !== prevProps.device.value + ) { + this.setState({ value: this.props.device.value }); + } else if ( + this.props.device.kind === "motionSensor" && + this.props.device.detected !== prevProps.device.detected + ) { + this.setState({ motion: true, detected: this.props.device.detected }); + } + } + componentDidMount() { if (this.props.device.kind === "sensor") { switch (this.props.device.sensor) { diff --git a/smart-hut/src/store.js b/smart-hut/src/store.js index a2b031a..e8f0d83 100644 --- a/smart-hut/src/store.js +++ b/smart-hut/src/store.js @@ -89,12 +89,16 @@ function reducer(previousState, action) { }; for (const device of action.devices) { - const roomId = previousState.devices[device.id].roomId; - change.rooms[roomId] = change.rooms[roomId] || { - devices: { $remove: [] }, - }; - change.rooms[roomId].devices.$remove.push(device.id); + if (!previousState.devices[device.id]) continue; change.devices.$unset.push(device.id); + const roomId = previousState.devices[device.id].roomId; + + if (roomId in previousState.rooms) { + change.rooms[roomId] = change.rooms[roomId] || { + devices: { $remove: [] }, + }; + change.rooms[roomId].devices.$remove.push(device.id); + } } } else { // otherwise, just delete all devices and all joins From f99a5d49ffb8f52d41f3c9538dd9feb90e554060 Mon Sep 17 00:00:00 2001 From: britea Date: Thu, 16 Apr 2020 17:07:56 +0200 Subject: [PATCH 06/15] fixed major bug --- smart-hut/src/components/SceneModal.js | 44 ------------- .../components/dashboard/NewSceneDevice.js | 45 ++++++++++++- smart-hut/src/remote.js | 64 +++++++++++++++---- 3 files changed, 95 insertions(+), 58 deletions(-) diff --git a/smart-hut/src/components/SceneModal.js b/smart-hut/src/components/SceneModal.js index cff8630..4f4901d 100644 --- a/smart-hut/src/components/SceneModal.js +++ b/smart-hut/src/components/SceneModal.js @@ -7,7 +7,6 @@ import { Responsive, Form, Input, - Dropdown, } from "semantic-ui-react"; import { connect } from "react-redux"; import { RemoteService } from "../remote"; @@ -19,7 +18,6 @@ class SceneModal extends Component { super(props); this.state = this.initialState; this.setInitialState(); - this.getDevices(); this.addSceneModal = this.addSceneModal.bind(this); this.modifySceneModal = this.modifySceneModal.bind(this); @@ -29,7 +27,6 @@ class SceneModal extends Component { get initialState() { return { name: this.type === "new" ? "New Scene" : this.props.room.name, - sceneDevices: this.type === "new" ? [{}] : [this.props.scene.devices], openModal: false, }; } @@ -42,12 +39,6 @@ class SceneModal extends Component { return !this.props.id ? "new" : "modify"; } - getDevices() { - this.props - .fetchDevices() - .catch((err) => console.error(`error fetching devices:`, err)); - } - addSceneModal = (e) => { /*let data = { // DATA HERE @@ -99,21 +90,7 @@ class SceneModal extends Component { this.setState({ openModal: true }); }; - setSceneDevice(e, d) { - this.setState({ sceneDevices: d.value }); - } - render() { - const availableDevices = []; - this.props.devices.forEach((e) => { - if (!this.state.sceneDevices.includes(e)) { - availableDevices.push({ - key: e.id, - text: e.name, - id: e.id, - }); - } - }); return (
{!this.props.nicolaStop ? ( @@ -176,17 +153,6 @@ class SceneModal extends Component { value={this.state.name} /> - - - - {this.type === "modify" ? ( @@ -229,16 +195,6 @@ const setActiveScene = (activeScene) => { }; const mapStateToProps = (state, ownProps) => ({ - get devices() { - if (state.active.activeRoom === -1) { - return Object.values(state.devices); - } else { - const deviceArray = [ - ...state.rooms[state.active.activeRoom].devices, - ].sort(); - return deviceArray.map((id) => state.devices[id]); - } - }, scene: ownProps.id ? state.scenes[ownProps.id] : null, }); const SceneModalContainer = connect( diff --git a/smart-hut/src/components/dashboard/NewSceneDevice.js b/smart-hut/src/components/dashboard/NewSceneDevice.js index 0a37af2..affacb5 100644 --- a/smart-hut/src/components/dashboard/NewSceneDevice.js +++ b/smart-hut/src/components/dashboard/NewSceneDevice.js @@ -1,5 +1,5 @@ import React, { Component } from "react"; -import { Button, Modal, Icon, Image } from "semantic-ui-react"; +import { Button, Modal, Icon, Image, Form, Dropdown } from "semantic-ui-react"; import { connect } from "react-redux"; import { RemoteService } from "../../remote"; import styled from "styled-components"; @@ -30,7 +30,18 @@ class NewSceneDevice extends Component { this.state = { openModal: false, + sceneDevices: this.props.scene ? this.props.scene.devices : {}, + deviceName: "", }; + this.getDevices(); + + this.setSceneDevice = this.setSceneDevice.bind(this); + } + + getDevices() { + this.props + .fetchDevices() + .catch((err) => console.error(`error fetching devices:`, err)); } handleOpen = () => { @@ -45,7 +56,21 @@ class NewSceneDevice extends Component { this.handleClose(); }; + setSceneDevice(e, d) { + this.setState({ devicesAttached: d.value }); + } + render() { + const availableDevices = []; + this.props.devices.forEach((e) => { + if (!Object.keys(this.state.sceneDevices).find((d) => e.id === d)) { + availableDevices.push({ + key: e.id, + text: e.name, + value: e.id, + }); + } + }); return ( Add a New Scene Device - + +
+ + + + +
+
); @@ -176,7 +180,7 @@ class Sensor extends Component { dy="0.4em" fontWeight="bold" > - {this.setName()} ({this.props.device.id}) + {this.name} From 1239559f4578eadef02514aa1ea2ed6ad37d3ca8 Mon Sep 17 00:00:00 2001 From: Nicola Brunner Date: Thu, 16 Apr 2020 18:38:34 +0200 Subject: [PATCH 08/15] changed Home in navbar into House view as required by user story 1 --- smart-hut/src/views/Navbar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smart-hut/src/views/Navbar.js b/smart-hut/src/views/Navbar.js index cfa7b0e..d7462a5 100644 --- a/smart-hut/src/views/Navbar.js +++ b/smart-hut/src/views/Navbar.js @@ -82,7 +82,7 @@ class Navbar extends Component { - HOME + House View
From b3abffa5b70554d0491c89b6957d71a591a68288 Mon Sep 17 00:00:00 2001 From: Nicola Brunner Date: Fri, 17 Apr 2020 11:29:40 +0200 Subject: [PATCH 09/15] made some design changes --- .../dashboard/devices/DeviceSettingsModal.js | 42 +++++-- smart-hut/src/views/ConfirmForgotPassword.js | 106 ++++++------------ smart-hut/src/views/ConfirmRegistration.js | 106 ++++++------------ smart-hut/src/views/ConfirmResetPassword.js | 104 ++++++----------- smart-hut/src/views/Forgot-password.js | 2 +- 5 files changed, 135 insertions(+), 225 deletions(-) diff --git a/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js b/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js index 037118a..44e160b 100644 --- a/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js +++ b/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js @@ -4,10 +4,21 @@ import { connect } from "react-redux"; import { RemoteService } from "../../../remote"; const DeleteModal = (props) => ( - Remove} closeIcon> + + + Delete device + + } + closeIcon + >
- + //{" "} + + + + //{" "} + ); }; diff --git a/smart-hut/src/views/ConfirmForgotPassword.js b/smart-hut/src/views/ConfirmForgotPassword.js index 99b194b..627b123 100644 --- a/smart-hut/src/views/ConfirmForgotPassword.js +++ b/smart-hut/src/views/ConfirmForgotPassword.js @@ -1,79 +1,43 @@ import React, { Component } from "react"; import HomeNavbar from "./../components/HomeNavbar"; -import { Image, Divider, Message, Grid } from "semantic-ui-react"; - -class Paragraph extends Component { - state = { visible: true }; - - handleDismiss = () => { - this.setState({ visible: false }); - - setTimeout(() => { - this.setState({ visible: true }); - }, 2000); - }; +import { + Image, + Divider, + Message, + Grid, + Button, + Icon, + Header, + Container, +} from "semantic-ui-react"; +export default class ConfirmForgotPasswrod extends Component { render() { - if (this.state.visible) { - return ( - - ); - } - return ( -

-
- The message will return in 2s -
-
-

+ + + + +
+ Link has been sent! +
+ +

+ An E-mail has been sent to your address, please follow the + instructions to create a new password. If you don't find the + E-mail please check also the spam folder. +

+
+
+
+
); } } - -const MessageReg = () => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -); - -export default class ConfirmForgotPasswrod extends React.Component { - render() { - return ; - } -} diff --git a/smart-hut/src/views/ConfirmRegistration.js b/smart-hut/src/views/ConfirmRegistration.js index 13af1b5..a4ea1fe 100644 --- a/smart-hut/src/views/ConfirmRegistration.js +++ b/smart-hut/src/views/ConfirmRegistration.js @@ -1,79 +1,43 @@ import React, { Component } from "react"; import HomeNavbar from "./../components/HomeNavbar"; -import { Image, Divider, Message, Grid } from "semantic-ui-react"; - -class Paragraph extends Component { - state = { visible: true }; - - handleDismiss = () => { - this.setState({ visible: false }); - - setTimeout(() => { - this.setState({ visible: true }); - }, 2000); - }; +import { + Image, + Divider, + Message, + Grid, + Button, + Icon, + Header, + Container, +} from "semantic-ui-react"; +export default class ConfirmRegistration extends Component { render() { - if (this.state.visible) { - return ( - - ); - } - return ( -

-
- The message will return in 2s -
-
-

+ + + + +
+ Congratulation! +
+ +

+ An E-mail has been sent to your address, confirm your + registration by following the enclosed link. If you don't find + the E-mail please check also the spam folder. +

+
+
+
+
); } } - -const MessageReg = () => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -); - -export default class ConfirmRegistration extends React.Component { - render() { - return ; - } -} diff --git a/smart-hut/src/views/ConfirmResetPassword.js b/smart-hut/src/views/ConfirmResetPassword.js index 0d6123d..ea4d77a 100644 --- a/smart-hut/src/views/ConfirmResetPassword.js +++ b/smart-hut/src/views/ConfirmResetPassword.js @@ -1,79 +1,39 @@ import React, { Component } from "react"; import HomeNavbar from "./../components/HomeNavbar"; -import { Image, Divider, Message, Grid } from "semantic-ui-react"; - -class Paragraph extends Component { - state = { visible: true }; - - handleDismiss = () => { - this.setState({ visible: false }); - - setTimeout(() => { - this.setState({ visible: true }); - }, 2000); - }; - - render() { - if (this.state.visible) { - return ( - - - Congratulations! - - Your password has been successfully reset - - ); - } - - return ( -

-
- The message will return in 2s -
-
-

- ); - } -} - -const MessageReg = () => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -); +import { + Image, + Divider, + Message, + Grid, + Button, + Icon, + Header, + Container, +} from "semantic-ui-react"; export default class ConfirmResetPassword extends Component { render() { - return ; + return ( + + + + +
+ Congratulation! +
+ +

Your password has been successfully reset.

+
+
+
+
+ ); } } diff --git a/smart-hut/src/views/Forgot-password.js b/smart-hut/src/views/Forgot-password.js index 511a881..6ebc2a5 100644 --- a/smart-hut/src/views/Forgot-password.js +++ b/smart-hut/src/views/Forgot-password.js @@ -77,7 +77,7 @@ export default class ForgotPass extends Component { Date: Fri, 17 Apr 2020 14:15:22 +0200 Subject: [PATCH 10/15] back to previous settings device --- .../dashboard/devices/DeviceSettingsModal.js | 42 +++++-------------- 1 file changed, 10 insertions(+), 32 deletions(-) diff --git a/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js b/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js index 44e160b..037118a 100644 --- a/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js +++ b/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js @@ -4,21 +4,10 @@ import { connect } from "react-redux"; import { RemoteService } from "../../../remote"; const DeleteModal = (props) => ( - - - Delete device - - } - closeIcon - > + Remove} closeIcon>
- - - //{" "} - + ); }; From dc22c008d32399b15717c826f59e1a6c07deff64 Mon Sep 17 00:00:00 2001 From: Nicola Brunner Date: Fri, 17 Apr 2020 14:25:22 +0200 Subject: [PATCH 11/15] changed design things --- smart-hut/src/components/HeaderController.js | 4 +++- .../dashboard/devices/DeviceSettingsModal.js | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/smart-hut/src/components/HeaderController.js b/smart-hut/src/components/HeaderController.js index d6ef4c5..1d84c6b 100644 --- a/smart-hut/src/components/HeaderController.js +++ b/smart-hut/src/components/HeaderController.js @@ -57,7 +57,9 @@ export class MyHeader extends React.Component { {this.props.username} - + diff --git a/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js b/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js index 037118a..846e8f0 100644 --- a/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js +++ b/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js @@ -4,7 +4,15 @@ import { connect } from "react-redux"; import { RemoteService } from "../../../remote"; const DeleteModal = (props) => ( - Remove} closeIcon> + + + Delete device + + } + closeIcon + >
); From d219716526512133a1431a1f88ba5d9efd97962f Mon Sep 17 00:00:00 2001 From: britea Date: Fri, 17 Apr 2020 14:30:34 +0200 Subject: [PATCH 12/15] Fix data on adding room --- smart-hut/src/components/RoomModal.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/smart-hut/src/components/RoomModal.js b/smart-hut/src/components/RoomModal.js index 36496b2..08f75d2 100644 --- a/smart-hut/src/components/RoomModal.js +++ b/smart-hut/src/components/RoomModal.js @@ -49,19 +49,11 @@ class RoomModal extends Component { } setInitialState() { - for (let key in this.initialState) { - if (this.initialState.hasOwnProperty(key)) { - //console.log(key + " -> " + this.initialState[key]); - this.setState({ - key: this.initialState[key], - }); - } - } - console.log(this.initialState); - //this.setState(state); + this.setState(this.initialState); } get type() { + console.log(this.props.id); return !this.props.id ? "new" : "modify"; } From 9c2a16732fb6f045635fd3942f59bbb11cbe01f8 Mon Sep 17 00:00:00 2001 From: britea Date: Sat, 18 Apr 2020 16:26:12 +0200 Subject: [PATCH 13/15] Fixed bugs and Initial Scene Navbar --- smart-hut/src/components/RoomModal.js | 1 - smart-hut/src/components/SceneModal.js | 36 ++++---- .../src/components/dashboard/DevicePanel.js | 2 +- .../src/components/dashboard/ScenesPanel.js | 1 - .../components/dashboard/devices/Device.js | 16 ++-- .../dashboard/devices/DeviceSettingsModal.js | 5 +- .../src/components/dashboard/devices/Light.js | 1 + smart-hut/src/remote.js | 75 +++++++++++++++ smart-hut/src/store.js | 69 +++++++++++++- smart-hut/src/storeActions.js | 12 +++ smart-hut/src/views/Dashboard.js | 17 +++- smart-hut/src/views/ScenesNavbar.js | 91 ++++++++++++++----- 12 files changed, 266 insertions(+), 60 deletions(-) diff --git a/smart-hut/src/components/RoomModal.js b/smart-hut/src/components/RoomModal.js index 08f75d2..eabdb89 100644 --- a/smart-hut/src/components/RoomModal.js +++ b/smart-hut/src/components/RoomModal.js @@ -53,7 +53,6 @@ class RoomModal extends Component { } get type() { - console.log(this.props.id); return !this.props.id ? "new" : "modify"; } diff --git a/smart-hut/src/components/SceneModal.js b/smart-hut/src/components/SceneModal.js index 4f4901d..9183a58 100644 --- a/smart-hut/src/components/SceneModal.js +++ b/smart-hut/src/components/SceneModal.js @@ -26,7 +26,7 @@ class SceneModal extends Component { get initialState() { return { - name: this.type === "new" ? "New Scene" : this.props.room.name, + name: this.type === "new" ? "New Scene" : this.props.scene.name, openModal: false, }; } @@ -40,40 +40,38 @@ class SceneModal extends Component { } addSceneModal = (e) => { - /*let data = { - // DATA HERE - };*/ - // TODO CALL TO REMOTE SERVER TO ADD SCENE - /*this.props - .saveRoom(data, null) + let data = { + name: this.state.name, + }; + + this.props + .saveScene(data, null) .then(() => { this.setInitialState(); this.closeModal(); }) - .catch((err) => console.error("error in creating room", err));*/ + .catch((err) => console.error("error in creating room", err)); }; modifySceneModal = (e) => { - /*let data = { - // DATA HERE - };*/ - // TODO CALL TO REMOTE SERVER TO MODIFY SCENE - /*this.props - .saveRoom(data, this.props.id) + let data = { + name: this.state.name, + }; + + this.props + .saveScene(data, this.props.id) .then(() => { this.setInitialState(); this.closeModal(); }) - .catch((err) => console.error("error in updating room", err));*/ + .catch((err) => console.error("error in updating room", err)); }; deleteScene = (e) => { - // TODO CALL TO REMOTE SERVER TO DELETE SCENE - /* this.props - .deleteRoom(this.props.id) + .deleteScene(this.props.id) .then(() => this.closeModal()) - .catch((err) => console.error("error in deleting room", err));*/ + .catch((err) => console.error("error in deleting room", err)); }; changeSomething = (event) => { diff --git a/smart-hut/src/components/dashboard/DevicePanel.js b/smart-hut/src/components/dashboard/DevicePanel.js index 92cdb7c..2b45083 100644 --- a/smart-hut/src/components/dashboard/DevicePanel.js +++ b/smart-hut/src/components/dashboard/DevicePanel.js @@ -26,7 +26,7 @@ class DevicePanel extends Component { {this.props.devices.map((e, i) => { return ( - + ); })} diff --git a/smart-hut/src/components/dashboard/ScenesPanel.js b/smart-hut/src/components/dashboard/ScenesPanel.js index ca96e0b..0395e0e 100644 --- a/smart-hut/src/components/dashboard/ScenesPanel.js +++ b/smart-hut/src/components/dashboard/ScenesPanel.js @@ -7,7 +7,6 @@ import { Grid } from "semantic-ui-react"; class ScenesPanel extends Component { constructor(props) { super(props); - console.log(this.props.activeScene); } render() { diff --git a/smart-hut/src/components/dashboard/devices/Device.js b/smart-hut/src/components/dashboard/devices/Device.js index 6ad0ac4..c019ddb 100644 --- a/smart-hut/src/components/dashboard/devices/Device.js +++ b/smart-hut/src/components/dashboard/devices/Device.js @@ -32,21 +32,21 @@ class Device extends React.Component { renderDeviceComponent() { switch (this.props.device.kind) { case "regularLight": - return ; + return ; case "sensor": - return ; + return ; case "motionSensor": - return ; + return ; case "buttonDimmer": - return ; + return ; case "knobDimmer": - return ; + return ; case "smartPlug": - return ; + return ; case "switch": - return ; + return ; case "dimmableLight": - return ; + return ; default: throw new Error("Device type unknown"); } diff --git a/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js b/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js index 846e8f0..ec979d6 100644 --- a/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js +++ b/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js @@ -36,12 +36,12 @@ const SettingsForm = (props) => { return (
- + @@ -112,6 +112,7 @@ class DeviceSettingsModal extends Component { Settings of {this.props.device.name} } promise that resolves to void and rejects + * with user-fiendly errors as a RemoteError + */ + fetchAllScenes: () => { + return (dispatch) => { + return Endpoint.get("/scene") + .then((res) => void dispatch(actions.scenesUpdate(res.data))) + .catch((err) => { + console.error("Fetch all scenes error", err); + throw new RemoteError(["Network error"]); + }); + }; + }, + /** * Fetches all devices in a particular room, or fetches all devices. * This also updates the devices attribute on values in the map rooms. @@ -290,6 +307,25 @@ export const RemoteService = { }; }, + /** + * Fetches all devices in a particular scene, or fetches all devices. + * This also updates the devices attribute on values in the map scenes. + * @param {Number} sceneId the scene to which fetch devices + * from, null to fetch from all scenes + * @returns {Promise} promise that resolves to void and rejects + * with user-fiendly errors as a RemoteError + */ + fetchStates: (sceneId) => { + return (dispatch) => { + return Endpoint.get(`/scene/${sceneId}/states`) + .then((res) => void dispatch(actions.statesUpdate(sceneId, res.data))) + .catch((err) => { + console.error(`Fetch devices sceneId=${sceneId} error`, err); + throw new RemoteError(["Network error"]); + }); + }; + }, + /** * Creates/Updates a room with the given data * @param {String} data.name the room's name, @@ -316,6 +352,28 @@ export const RemoteService = { }; }, + /** + * Creates/Updates a scene with the given data + * @param {String} data.name the scene's name, + * @param {Number|null} sceneId the scene's id if update, null for creation + * @returns {Promise} promise that resolves to void and rejects + * with user-fiendly errors as a RemoteError + */ + saveScene: (data, sceneId = null) => { + return (dispatch) => { + data = { + name: data.name, + }; + + return (sceneId + ? Endpoint.put(`/scene/${sceneId}`, {}, data) + : Endpoint.post(`/scene`, {}, data) + ) + .then((res) => void dispatch(actions.sceneSave(res.data))) + .catch(parseValidationErrors); + }; + }, + /** * Creates/Updates a device with the given data. If * data.id is truthy, then a update call is performed, @@ -496,6 +554,23 @@ export const RemoteService = { }; }, + /** + * Deletes a scene + * @param {Number} sceneId the id of the scene to delete + * @returns {Promise} promise that resolves to void and rejects + * with user-fiendly errors as a RemoteError + */ + deleteScene: (sceneId) => { + return (dispatch) => { + return Endpoint.delete(`/scene/${sceneId}`) + .then((_) => dispatch(actions.sceneDelete(sceneId))) + .catch((err) => { + console.warn("Scene deletion error", err); + throw new RemoteError(["Network error"]); + }); + }; + }, + /** * Deletes a device * @param {Device} device the device to delete diff --git a/smart-hut/src/store.js b/smart-hut/src/store.js index e8f0d83..984c5a3 100644 --- a/smart-hut/src/store.js +++ b/smart-hut/src/store.js @@ -38,6 +38,35 @@ function reducer(previousState, action) { } }; + const createOrUpdateScene = (scene) => { + if (!newState.scenes[scene.id]) { + newState = update(newState, { + scenes: { [scene.id]: { $set: { ...scene, states: new Set() } } }, + }); + } else { + newState = update(newState, { + scenes: { + [scene.id]: { + name: { $set: scene.name }, + }, + }, + }); + } + + if (newState.pendingJoins.scenes[scene.id]) { + newState = update(newState, { + pendingJoins: { scenes: { $unset: [scene.id] } }, + scenes: { + [scene.id]: { + states: { + $add: [...newState.pendingJoins.scenes[scene.id]], + }, + }, + }, + }); + } + }; + const updateDeviceProps = (device) => { // In some updates the information regarding a device is incomplete // due to a fault in the type system and JPA repository management @@ -63,6 +92,13 @@ function reducer(previousState, action) { createOrUpdateRoom(room); } break; + case "SCENES_UPDATE": + newState = previousState; + console.log(action.scenes); + for (const scene of action.scenes) { + createOrUpdateScene(scene); + } + break; case "DEVICES_UPDATE": change = null; @@ -156,6 +192,10 @@ function reducer(previousState, action) { newState = previousState; createOrUpdateRoom(action.room); break; + case "SCENE_SAVE": + newState = previousState; + createOrUpdateScene(action.scene); + break; case "DEVICE_SAVE": change = { devices: { [action.device.id]: { $set: action.device } }, @@ -201,6 +241,30 @@ function reducer(previousState, action) { change.active = { activeRoom: { $set: -1 } }; } + newState = update(previousState, change); + break; + case "SCENE_DELETE": + console.log("SCENE", action.sceneId); + if (!(action.sceneId in previousState.scenes)) { + console.warn(`Scene to delete ${action.sceneId} does not exist`); + break; + } + + // This update does not ensure the consistent update of switchId/dimmerId properties + // on output devices connected to an input device in this room. Please manually request + // all devices again if consistent update is desired + change = { states: { $unset: [] } }; + + for (const id of previousState.scenes[action.sceneId].states) { + change.states.$unset.push(id); + } + + change.scenes = { $unset: [action.sceneId] }; + + if (previousState.active.activeScene === action.sceneId) { + change.active = { activeScene: { $set: -1 } }; + } + newState = update(previousState, change); break; case "DEVICE_DELETE": @@ -280,7 +344,6 @@ function reducer(previousState, action) { } const initState = { - errors: {}, pendingJoins: { rooms: {}, scenes: {}, @@ -299,9 +362,9 @@ const initState = { userInfo: null, /** @type {[integer]Room} */ rooms: {}, - /** @type {[integer]Scenes} */ + /** @type {[integer]Scene} */ scenes: {}, - /** @type {[integer]Automations} */ + /** @type {[integer]Automation} */ automations: {}, /** @type {[integer]Device} */ devices: {}, diff --git a/smart-hut/src/storeActions.js b/smart-hut/src/storeActions.js index e224b99..3afa192 100644 --- a/smart-hut/src/storeActions.js +++ b/smart-hut/src/storeActions.js @@ -17,6 +17,10 @@ const actions = { type: "ROOM_SAVE", room, }), + sceneSave: (scene) => ({ + type: "SCENE_SAVE", + scene, + }), deviceSave: (device) => ({ type: "DEVICE_SAVE", device, @@ -40,6 +44,14 @@ const actions = { type: "ROOM_DELETE", roomId, }), + sceneDelete: (sceneId) => ({ + type: "SCENE_DELETE", + sceneId, + }), + scenesUpdate: (scenes) => ({ + type: "SCENES_UPDATE", + scenes, + }), deviceDelete: (deviceId) => ({ type: "DEVICE_DELETE", deviceId, diff --git a/smart-hut/src/views/Dashboard.js b/smart-hut/src/views/Dashboard.js index f3c204f..11d6d7c 100644 --- a/smart-hut/src/views/Dashboard.js +++ b/smart-hut/src/views/Dashboard.js @@ -19,10 +19,22 @@ import { appActions } from "../storeActions"; class Dashboard extends Component { constructor(props) { super(props); + this.state = this.initialState; + this.setInitialState(); this.selectTab = this.selectTab.bind(this); } + get initialState() { + return { + activeTab: this.activeTab, + }; + } + + setInitialState() { + this.setState(this.initialState); + } + get activeTab() { return this.props.activeTab; } @@ -32,13 +44,14 @@ class Dashboard extends Component { } selectTab(e, { name }) { + this.setState({ activeTab: name }); this.activeTab = name; } renderTab(tab) { switch (tab) { case "Devices": - return ; + return ; case "Scenes": return ; case "Automations": @@ -148,7 +161,7 @@ class Dashboard extends Component { - + {this.renderNavbar(this.activeTab)} diff --git a/smart-hut/src/views/ScenesNavbar.js b/smart-hut/src/views/ScenesNavbar.js index 27862a6..74003ea 100644 --- a/smart-hut/src/views/ScenesNavbar.js +++ b/smart-hut/src/views/ScenesNavbar.js @@ -2,8 +2,8 @@ import React, { Component } from "react"; import { Menu, Button, - Grid, Icon, + Grid, Responsive, Dropdown, } from "semantic-ui-react"; @@ -19,9 +19,12 @@ class ScenesNavbar extends Component { this.state = { editMode: false, }; - + console.log(this.props.scenes); this.toggleEditMode = this.toggleEditMode.bind(this); this.openCurrentModalMobile = this.openCurrentModalMobile.bind(this); + this.selectScene = this.selectScene.bind(this); + + this.getScenes(); } get activeItemScene() { @@ -33,13 +36,21 @@ class ScenesNavbar extends Component { } get activeItemSceneName() { - if (this.props.activeScene === -1) return "Home"; + if (this.props.activeScene === -1) return "Scene"; return this.props.scenes[this.props.activeScene].name; } + getScenes() { + this.props + .fetchAllScenes() + .then(() => console.log(this.props.scenes)) + .catch(console.error); + } + openCurrentModalMobile() { - console.log(this.activeItem, this.props.roomModalRefs); - const currentModal = this.props.roomModalRefs[this.activeItem].current; + console.log(this.activeItemScene, this.props.sceneModalRefs); + const currentModal = this.props.sceneModalRefs[this.activeItemScene] + .current; currentModal.openModal(); } @@ -47,6 +58,10 @@ class ScenesNavbar extends Component { this.setState((prevState) => ({ editMode: !prevState.editMode })); } + selectScene(e, { id }) { + this.activeItemScene = id || -1; + } + render() { return (
@@ -66,18 +81,32 @@ class ScenesNavbar extends Component { active={this.activeItemScene === -1} onClick={this.selectScene} > - - - - - - SCENES - - + SCENES - { - //INSERT LIST OF SCENES HERE - } + + {Object.values(this.props.scenes).map((e, i) => { + return ( + + + + {e.name} + + {this.state.editMode ? ( + + ) : null} + + + + + ); + })} + @@ -103,17 +132,33 @@ class ScenesNavbar extends Component { > - - - Scene - { - //INSERT LIST OF SCENES HERE - } + {Object.values(this.props.scenes).map((e, i) => { + return ( + + + + {e.name} + + + + + ); + })} @@ -131,7 +176,7 @@ class ScenesNavbar extends Component { onClick={this.openCurrentModalMobile} > - EDIT ROOM + EDIT SCENE ) : null} From 0b4fefbd359a34fce8ddf3c311e8f13d02b08571 Mon Sep 17 00:00:00 2001 From: britea Date: Tue, 21 Apr 2020 14:58:36 +0200 Subject: [PATCH 14/15] Able to add scenes and get scenes in a right way --- .../src/components/dashboard/DevicePanel.js | 8 +- .../components/dashboard/NewSceneDevice.js | 28 +++-- .../src/components/dashboard/ScenesPanel.js | 29 ++++- .../components/dashboard/devices/Device.js | 49 ++++++--- .../src/components/dashboard/devices/Light.js | 1 - smart-hut/src/remote.js | 29 +++++ smart-hut/src/store.js | 102 +++++++++++++++++- smart-hut/src/storeActions.js | 9 ++ smart-hut/src/views/ConfirmForgotPassword.js | 3 - smart-hut/src/views/ConfirmRegistration.js | 3 - smart-hut/src/views/ConfirmResetPassword.js | 3 - smart-hut/src/views/Dashboard.js | 2 +- smart-hut/src/views/ScenesNavbar.js | 22 ++-- 13 files changed, 236 insertions(+), 52 deletions(-) diff --git a/smart-hut/src/components/dashboard/DevicePanel.js b/smart-hut/src/components/dashboard/DevicePanel.js index 2b45083..449642e 100644 --- a/smart-hut/src/components/dashboard/DevicePanel.js +++ b/smart-hut/src/components/dashboard/DevicePanel.js @@ -15,9 +15,11 @@ class DevicePanel extends Component { } getDevices() { - this.props - .fetchDevices() - .catch((err) => console.error(`error fetching devices:`, err)); + if (this.props.tab === "Devices") { + this.props + .fetchDevices() + .catch((err) => console.error(`error fetching devices:`, err)); + } } render() { diff --git a/smart-hut/src/components/dashboard/NewSceneDevice.js b/smart-hut/src/components/dashboard/NewSceneDevice.js index affacb5..7ea1664 100644 --- a/smart-hut/src/components/dashboard/NewSceneDevice.js +++ b/smart-hut/src/components/dashboard/NewSceneDevice.js @@ -30,12 +30,13 @@ class NewSceneDevice extends Component { this.state = { openModal: false, - sceneDevices: this.props.scene ? this.props.scene.devices : {}, + sceneDevices: this.props.scene ? this.props.scene.sceneStates : {}, deviceName: "", }; this.getDevices(); - this.setSceneDevice = this.setSceneDevice.bind(this); + this.setSceneState = this.setSceneState.bind(this); + this.createState = this.createState.bind(this); } getDevices() { @@ -56,10 +57,25 @@ class NewSceneDevice extends Component { this.handleClose(); }; - setSceneDevice(e, d) { + setSceneState(e, d) { this.setState({ devicesAttached: d.value }); } + createState() { + const device = this.props.devices.filter( + (e) => this.state.devicesAttached[0] === e.id + ); + let data = { + sceneId: this.props.activeScene, + id: device[0].id, + kind: device[0].kind, + }; + this.props + .saveState(data) + .catch((err) => console.error("error in creating state", err)); + this.resetState(); + } + render() { const availableDevices = []; this.props.devices.forEach((e) => { @@ -83,7 +99,7 @@ class NewSceneDevice extends Component { } centered={true} > - Add a New Scene Device + Add a New Scene State @@ -93,7 +109,7 @@ class NewSceneDevice extends Component { placeholder="Select Devices" fluid multiple - onChange={this.setSceneDevice} + onChange={this.setSceneState} options={availableDevices} /> @@ -101,7 +117,7 @@ class NewSceneDevice extends Component { - {this.props.device.kind === "smartPlug" ? ( + {this.props.tab === "Devices" ? ( + +
{this.props.stateOrDevice.name}
- ) : null} -
+ {this.props.stateOrDevice.kind === "smartPlug" ? ( + + ) : null} + + ) : ( + +
{this.props.stateOrDevice.name}
+
+ )} +
@@ -83,7 +95,14 @@ class Device extends React.Component { } const mapStateToProps = (state, ownProps) => ({ - device: state.devices[ownProps.id], + get stateOrDevice() { + if (state.active.activeTab === "Devices") { + return state.devices[ownProps.id]; + } else { + const sceneState = state.sceneStates[ownProps.id]; + return state.devices[sceneState]; + } + }, }); const DeviceContainer = connect(mapStateToProps, RemoteService)(Device); export default DeviceContainer; diff --git a/smart-hut/src/components/dashboard/devices/Light.js b/smart-hut/src/components/dashboard/devices/Light.js index 5e8e53e..5d01d89 100644 --- a/smart-hut/src/components/dashboard/devices/Light.js +++ b/smart-hut/src/components/dashboard/devices/Light.js @@ -37,7 +37,6 @@ class Light extends Component { constructor(props) { super(props); this.state = { intensity: this.props.device.intensity, timeout: null }; - console.log(this.props); this.iconOn = "/img/lightOn.svg"; this.iconOff = "/img/lightOff.svg"; diff --git a/smart-hut/src/remote.js b/smart-hut/src/remote.js index f2b0555..6ea0454 100644 --- a/smart-hut/src/remote.js +++ b/smart-hut/src/remote.js @@ -405,6 +405,35 @@ export const RemoteService = { }; }, + /** + * Creates/Updates a state with the given data. If + * data.id is truthy, then a update call is performed, + * otherwise a create call is performed. The update URL + * is computed based on data.kind when data.flowType = + * 'OUTPUT', otherwise the PUT "/device" endpoint + * is used for updates and the POST "/" + * endpoints are used for creation. + * @param {State} data the device to update. + * @returns {Promise} promise that resolves to the saved device and rejects + * with user-fiendly errors as a RemoteError + */ + saveState: (data) => { + return (dispatch) => { + let url = + "/" + data.kind + "/" + data.id + "/state?sceneId=" + data.sceneId; + + return Endpoint["post"](url, {}, data) + .then((res) => { + dispatch(actions.stateSave(res.data)); + return res.data; + }) + .catch((err) => { + console.warn("Update device: ", data, "error: ", err); + throw new RemoteError(["Network error"]); + }); + }; + }, + /** * Connetcs a series of output devices to an input device. * Output devices for Switch input can be: Normal Light, Dimmable Light, Smart Plug. diff --git a/smart-hut/src/store.js b/smart-hut/src/store.js index 984c5a3..930f387 100644 --- a/smart-hut/src/store.js +++ b/smart-hut/src/store.js @@ -41,7 +41,7 @@ function reducer(previousState, action) { const createOrUpdateScene = (scene) => { if (!newState.scenes[scene.id]) { newState = update(newState, { - scenes: { [scene.id]: { $set: { ...scene, states: new Set() } } }, + scenes: { [scene.id]: { $set: { ...scene, sceneStates: new Set() } } }, }); } else { newState = update(newState, { @@ -58,7 +58,7 @@ function reducer(previousState, action) { pendingJoins: { scenes: { $unset: [scene.id] } }, scenes: { [scene.id]: { - states: { + sceneStates: { $add: [...newState.pendingJoins.scenes[scene.id]], }, }, @@ -79,6 +79,11 @@ function reducer(previousState, action) { } }; + const updateSceneStateProps = (state) => { + change.sceneStates[state.deviceId] = {}; + change.sceneStates[state.deviceId] = { $set: state.deviceId }; + }; + switch (action.type) { case "LOGIN_UPDATE": newState = update(previousState, { login: { $set: action.login } }); @@ -94,10 +99,70 @@ function reducer(previousState, action) { break; case "SCENES_UPDATE": newState = previousState; - console.log(action.scenes); for (const scene of action.scenes) { createOrUpdateScene(scene); } + break; + case "STATE_UPDATE": + newState = previousState; + change = null; + + // if room is given, delete all devices in that room + // and remove any join between that room and deleted + // devices + change = { + scenes: { [action.sceneId]: { sceneStates: { $set: new Set() } } }, + sceneStates: { $unset: [] }, + }; + + const scene = newState.scenes[action.sceneId]; + for (const stateId of scene.sceneStates) { + change.sceneStates.$unset.push(stateId); + } + + newState = update(previousState, change); + + change = { + sceneStates: {}, + scenes: {}, + pendingJoins: { scenes: {} }, + }; + + for (const sceneState of action.sceneStates) { + if (!newState.sceneStates[sceneState.deviceId]) { + change.sceneStates[sceneState.deviceId] = { + $set: sceneState.deviceId, + }; + } else { + updateSceneStateProps(sceneState); + } + + if (sceneState.sceneId in newState.scenes) { + change.scenes[sceneState.sceneId] = + change.scenes[sceneState.sceneId] || {}; + change.scenes[sceneState.sceneId].sceneStates = + change.scenes[sceneState.sceneId].sceneStates || {}; + const sceneStates = change.scenes[sceneState.sceneId].sceneStates; + sceneStates.$add = sceneStates.$add || []; + sceneStates.$add.push(sceneState.deviceId); + } else { + // room does not exist yet, so add to the list of pending + // joins + + if (!change.pendingJoins.scenes[sceneState.sceneId]) { + change.pendingJoins.scenes[sceneState.sceneId] = { + $set: new Set([sceneState.deviceId]), + }; + } else { + change.pendingJoins.scenes[sceneState.sceneId].$set.add( + sceneState.deviceId + ); + } + } + } + + newState = update(newState, change); + break; case "DEVICES_UPDATE": change = null; @@ -220,6 +285,31 @@ function reducer(previousState, action) { } newState = update(previousState, change); break; + case "STATE_SAVE": + console.log("Store", action.sceneState); + change = { + sceneStates: { [action.sceneState.id]: { $set: action.sceneState } }, + }; + + if (previousState.scenes[action.sceneState.sceneId]) { + change.scenes = { + [action.sceneState.sceneId]: { + sceneStates: { + $add: [action.sceneState.id], + }, + }, + }; + } else { + change.pendingJoins = { + scenes: { + [action.sceneState.sceneId]: { + $add: [action.sceneState.id], + }, + }, + }; + } + newState = update(previousState, change); + break; case "ROOM_DELETE": if (!(action.roomId in previousState.rooms)) { console.warn(`Room to delete ${action.roomId} does not exist`); @@ -255,8 +345,8 @@ function reducer(previousState, action) { // all devices again if consistent update is desired change = { states: { $unset: [] } }; - for (const id of previousState.scenes[action.sceneId].states) { - change.states.$unset.push(id); + for (const id of previousState.scenes[action.sceneId].sceneStates) { + change.sceneStates.$unset.push(id); } change.scenes = { $unset: [action.sceneId] }; @@ -368,6 +458,8 @@ const initState = { automations: {}, /** @type {[integer]Device} */ devices: {}, + /** @type {[integer]SceneState} */ + sceneStates: {}, }; function createSmartHutStore() { diff --git a/smart-hut/src/storeActions.js b/smart-hut/src/storeActions.js index 3afa192..3ca8bcf 100644 --- a/smart-hut/src/storeActions.js +++ b/smart-hut/src/storeActions.js @@ -25,6 +25,15 @@ const actions = { type: "DEVICE_SAVE", device, }), + stateSave: (sceneState) => ({ + type: "STATE_SAVE", + sceneState, + }), + statesUpdate: (sceneId, sceneStates) => ({ + type: "STATE_UPDATE", + sceneId, + sceneStates, + }), devicesUpdate: (roomId, devices, partial = false) => ({ type: "DEVICES_UPDATE", roomId, diff --git a/smart-hut/src/views/ConfirmForgotPassword.js b/smart-hut/src/views/ConfirmForgotPassword.js index 627b123..1f4d0ec 100644 --- a/smart-hut/src/views/ConfirmForgotPassword.js +++ b/smart-hut/src/views/ConfirmForgotPassword.js @@ -1,9 +1,6 @@ import React, { Component } from "react"; -import HomeNavbar from "./../components/HomeNavbar"; import { Image, - Divider, - Message, Grid, Button, Icon, diff --git a/smart-hut/src/views/ConfirmRegistration.js b/smart-hut/src/views/ConfirmRegistration.js index a4ea1fe..05adedd 100644 --- a/smart-hut/src/views/ConfirmRegistration.js +++ b/smart-hut/src/views/ConfirmRegistration.js @@ -1,9 +1,6 @@ import React, { Component } from "react"; -import HomeNavbar from "./../components/HomeNavbar"; import { Image, - Divider, - Message, Grid, Button, Icon, diff --git a/smart-hut/src/views/ConfirmResetPassword.js b/smart-hut/src/views/ConfirmResetPassword.js index ea4d77a..75c0bdc 100644 --- a/smart-hut/src/views/ConfirmResetPassword.js +++ b/smart-hut/src/views/ConfirmResetPassword.js @@ -1,9 +1,6 @@ import React, { Component } from "react"; -import HomeNavbar from "./../components/HomeNavbar"; import { Image, - Divider, - Message, Grid, Button, Icon, diff --git a/smart-hut/src/views/Dashboard.js b/smart-hut/src/views/Dashboard.js index 11d6d7c..651a1e5 100644 --- a/smart-hut/src/views/Dashboard.js +++ b/smart-hut/src/views/Dashboard.js @@ -53,7 +53,7 @@ class Dashboard extends Component { case "Devices": return ; case "Scenes": - return ; + return ; case "Automations": return ; default: diff --git a/smart-hut/src/views/ScenesNavbar.js b/smart-hut/src/views/ScenesNavbar.js index 74003ea..cb35572 100644 --- a/smart-hut/src/views/ScenesNavbar.js +++ b/smart-hut/src/views/ScenesNavbar.js @@ -19,7 +19,6 @@ class ScenesNavbar extends Component { this.state = { editMode: false, }; - console.log(this.props.scenes); this.toggleEditMode = this.toggleEditMode.bind(this); this.openCurrentModalMobile = this.openCurrentModalMobile.bind(this); this.selectScene = this.selectScene.bind(this); @@ -41,14 +40,11 @@ class ScenesNavbar extends Component { } getScenes() { - this.props - .fetchAllScenes() - .then(() => console.log(this.props.scenes)) - .catch(console.error); + this.props.fetchAllScenes().catch(console.error); } openCurrentModalMobile() { - console.log(this.activeItemScene, this.props.sceneModalRefs); + //console.log(this.activeItemScene, this.props.sceneModalRefs); const currentModal = this.props.sceneModalRefs[this.activeItemScene] .current; currentModal.openModal(); @@ -60,6 +56,15 @@ class ScenesNavbar extends Component { selectScene(e, { id }) { this.activeItemScene = id || -1; + this.getStates(id); + } + + getStates(sceneId) { + if (sceneId) { + this.props + .fetchStates(sceneId) + .catch((err) => console.error(`error fetching states:`, err)); + } } render() { @@ -194,11 +199,14 @@ const setActiveScene = (activeScene) => { const mapStateToProps = (state, _) => ({ scenes: state.scenes, - activeScene: state.active.activeScene, sceneModalRefs: Object.keys(state.scenes).reduce( (acc, key) => ({ ...acc, [key]: React.createRef() }), {} ), + get isActiveDefaultScene() { + return state.active.activeScene === -1; + }, + activeScene: state.active.activeScene, }); const ScenesNavbarContainer = connect(mapStateToProps, { ...RemoteService, From 3b67e57f1a7dd524fac97c000cc2685b9bbe0e72 Mon Sep 17 00:00:00 2001 From: britea Date: Tue, 21 Apr 2020 16:18:05 +0200 Subject: [PATCH 15/15] fixed edit name on devices --- .../components/dashboard/devices/DeviceSettingsModal.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js b/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js index ec979d6..ebb2d91 100644 --- a/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js +++ b/smart-hut/src/components/dashboard/devices/DeviceSettingsModal.js @@ -1,5 +1,5 @@ import React, { Component, useState } from "react"; -import { Button, Form, Icon, Header, Modal } from "semantic-ui-react"; +import { Button, Form, Icon, Header, Modal, Input } from "semantic-ui-react"; import { connect } from "react-redux"; import { RemoteService } from "../../../remote"; @@ -37,12 +37,11 @@ const SettingsForm = (props) => { - @@ -85,7 +84,7 @@ class DeviceSettingsModal extends Component { if (values.name.length === 0) return; this.props .saveDevice({ ...this.props.device, name: values.name }) - .then(() => this.setState({ open: false })) + .then(() => this.setState({ openModal: false })) .catch((err) => console.error( `settings modal for device ${this.props.id} deletion error`,