From f99a5d49ffb8f52d41f3c9538dd9feb90e554060 Mon Sep 17 00:00:00 2001 From: britea Date: Thu, 16 Apr 2020 17:07:56 +0200 Subject: [PATCH 1/8] 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 3/8] 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 4/8] 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 5/8] 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 6/8] 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 7/8] 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 8/8] 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}