diff --git a/smart-hut/src/components/dashboard/AutomationsPanel.js b/smart-hut/src/components/dashboard/AutomationsPanel.js index c730332..dd49666 100644 --- a/smart-hut/src/components/dashboard/AutomationsPanel.js +++ b/smart-hut/src/components/dashboard/AutomationsPanel.js @@ -1,597 +1,571 @@ -import React, {Component, useState, useEffect} from "react"; -import {connect} from "react-redux"; -import {RemoteService} from "../../remote"; +import React, { Component, useState, useEffect } from "react"; +import { connect } from "react-redux"; +import { RemoteService } from "../../remote"; import "./Automations.css"; import { - Segment, - Grid, - Icon, - Header, - Input, - Button, - List, - Dropdown, - Form, - Divider, - Checkbox, - Menu, - Label, + Segment, + Grid, + Icon, + Header, + Input, + Button, + List, + Dropdown, + Form, + Divider, + Checkbox, + Menu, + Label, } from "semantic-ui-react"; const operands = [ - {key: "EQUAL", text: "=", value: "EQUAL"}, - { - key: "GREATER_EQUAL", - text: "\u2265", - value: "GREATER_EQUAL", - }, - { - key: "GREATER", - text: ">", - value: "GREATER", - }, - { - key: "LESS_EQUAL", - text: "\u2264", - value: "LESS_EQUAL", - }, - { - key: "LESS", - text: "<", - value: "LESS", - }, + { key: "EQUAL", text: "=", value: "EQUAL" }, + { + key: "GREATER_EQUAL", + text: "\u2265", + value: "GREATER_EQUAL", + }, + { + key: "GREATER", + text: ">", + value: "GREATER", + }, + { + key: "LESS_EQUAL", + text: "\u2264", + value: "LESS_EQUAL", + }, + { + key: "LESS", + text: "<", + value: "LESS", + }, ]; const deviceStateOptions = [ - {key: "off", text: "off", value: false}, - {key: "on", text: "on", value: true}, + { key: "off", text: "off", value: false }, + { key: "on", text: "on", value: true }, ]; const CreateTrigger = (props) => { - const [activeOperand, setActiveOperand] = useState(true); - const admitedDevices = ["sensor", "regularLight", "dimmableLight"]; // TODO Complete this list - const deviceList = props.devices - .map((device) => { - return { - key: device.id, - text: device.name, - value: device.id, - kind: device.kind, - }; - }) - .filter((e) => admitedDevices.includes(e.kind)); + const [activeOperand, setActiveOperand] = useState(true); + const admitedDevices = ["sensor", "regularLight", "dimmableLight"]; // TODO Complete this list + const deviceList = props.devices + .map((device) => { + return { + key: device.id, + text: device.name, + value: device.id, + kind: device.kind, + }; + }) + .filter((e) => admitedDevices.includes(e.kind)); - const onChange = (e, val) => { - props.inputChange(val); - if ( - props.devices - .filter((d) => d.id === val.value)[0] - .hasOwnProperty("on") - ) { - setActiveOperand(false); - } else { - setActiveOperand(true); - } - }; + const onChange = (e, val) => { + props.inputChange(val); + if ( + props.devices.filter((d) => d.id === val.value)[0].hasOwnProperty("on") + ) { + setActiveOperand(false); + } else { + setActiveOperand(true); + } + }; - return ( - - -
- - - - - {activeOperand ? ( - - - - props.inputChange(val) - } - name="operand" - compact - selection - options={operands} - /> - - - - props.inputChange(val) - } - name="value" - type="number" - placeholder="Value" - /> - - - ) : ( - - - props.inputChange(val) - } - placeholder="State" - name="value" - compact - selection - options={deviceStateOptions} - /> - - )} - -
-
-
- ); + return ( + + +
+ + + + + {activeOperand ? ( + + + props.inputChange(val)} + name="operand" + compact + selection + options={operands} + /> + + + props.inputChange(val)} + name="value" + type="number" + placeholder="Value" + /> + + + ) : ( + + props.inputChange(val)} + placeholder="State" + name="value" + compact + selection + options={deviceStateOptions} + /> + + )} + +
+
+
+ ); }; const SceneItem = (props) => { - let position = props.order.indexOf(props.scene.id); - return ( - - - - - - - props.orderScenes( - props.scene.id, - val.checked - ) - } - checked={position + 1 > 0} - /> - - -

{props.scene.name}

-
- -

- {position !== -1 ? "# " + (position + 1) : ""} -

-
-
-
-
-
- ); + let position = props.order.indexOf(props.scene.id); + return ( + + + + + + + props.orderScenes(props.scene.id, val.checked) + } + checked={position + 1 > 0} + /> + + +

{props.scene.name}

+
+ +

{position !== -1 ? "# " + (position + 1) : ""}

+
+
+
+
+
+ ); }; -const Trigger = ({deviceName, trigger, onRemove, index}) => { - const {device, operand, value} = trigger; - let symbol; - if (operand) { - symbol = operands.filter((opt) => opt.key === operand)[0].text; - } - return ( - - - {deviceName} - {operand ? {symbol} : ""} - - {operand ? value : value ? "on" : "off"} - - - onRemove(index)} - className="remove-icon" - name="remove" - /> - - ); +const Trigger = ({ deviceName, trigger, onRemove, index }) => { + const { device, operand, value } = trigger; + let symbol; + if (operand) { + symbol = operands.filter((opt) => opt.key === operand)[0].text; + } + return ( + + + {deviceName} + {operand ? {symbol} : ""} + + {operand ? value : value ? "on" : "off"} + + + onRemove(index)} + className="remove-icon" + name="remove" + /> + + ); }; export const CreateAutomation = (props) => { - const [triggerList, setTrigger] = useState([]); - const [order, setOrder] = useState([]); - const [stateScenes, setScenes] = useState(props.scenes); - const [automationName, setautomationName] = useState("New Automation"); - const [editName, setEditName] = useState(false); - const [newTrigger, setNewTrigger] = useState({}); + const [triggerList, setTrigger] = useState([]); + const [order, setOrder] = useState([]); + const [stateScenes, setScenes] = useState(props.scenes); + const [automationName, setautomationName] = useState("New Automation"); + const [editName, setEditName] = useState(false); + const [newTrigger, setNewTrigger] = useState({}); - useEffect(() => { - setScenes(props.scenes); - }, [props]); + useEffect(() => { + setScenes(props.scenes); + }, [props]); - const _checkNewTrigger = (trigger) => { - const auxDevice = props.devices.filter( - (d) => d.id === trigger.device - )[0]; - if (auxDevice && auxDevice.hasOwnProperty("on")) { - if (!trigger.device || !trigger.value == null) { - return { - result: false, - message: "There are missing fields!", - }; - } - } else { - if (!trigger.device || !trigger.operand || !trigger.value) { - return { - result: false, - message: "There are missing fields", - }; - } - } - const result = !triggerList.some( - (t) => t.device === trigger.device && t.operand === trigger.operand - ); + const _checkNewTrigger = (trigger) => { + const auxDevice = props.devices.filter((d) => d.id === trigger.device)[0]; + if (auxDevice && auxDevice.hasOwnProperty("on")) { + if (!trigger.device || !trigger.value == null) { return { - result: result, - message: result - ? "" - : "You have already created a trigger for this device with the same conditions", + result: false, + message: "There are missing fields!", }; - }; - const addTrigger = () => { - const {result, message} = _checkNewTrigger(newTrigger); - const auxTrigger = newTrigger; - if (result) { - if ( - props.devices - .filter((d) => d.id === newTrigger.device)[0] - .hasOwnProperty("on") - ) { - delete auxTrigger.operand; - } - setTrigger((prevList) => [...prevList, auxTrigger]); - } else { - alert(message); - } - }; - - const removeTrigger = (index) => { - setTrigger((prevList) => prevList.filter((t, i) => i !== index)); - }; - - // This gets triggered when the devices dropdown changes the value. - const onInputChange = (val) => { - setNewTrigger({...newTrigger, [val.name]: val.value}); - }; - const onChangeName = (e, val) => setautomationName(val.value); - - const orderScenes = (id, checked) => { - if (checked) { - setOrder((prevList) => [...prevList, id]); - } else { - setOrder((prevList) => prevList.filter((e) => e !== id)); - } - }; - const searchScenes = (e, {value}) => { - if (value.length > 0) { - setScenes((prevScenes) => { - return stateScenes.filter((e) => { - return e.name.includes(value); - }); - }); - } else { - setScenes(props.scenes); - } - }; - - const _generateKey = (trigger) => { - if (trigger.hasOwnProperty("operand")) { - return trigger.device + trigger.operand + trigger.value; - } - return trigger.device + trigger.value; - }; - - const checkBeforeSave = () => { - if (automationName.length <= 0) { - alert("Give a name to the automation"); - return false; - } - if (triggerList.length <= 0) { - alert("You have to create a trigger"); - return false; - } - if (order.length <= 0) { - alert("You need at least one active scene"); - return false; - } - return true; - }; - - const saveAutomation = () => { - //if(checkBeforeSave()){ - const automation = { - name: automationName, + } + } else { + if (!trigger.device || !trigger.operand || !trigger.value) { + return { + result: false, + message: "There are missing fields", }; - props.save({automation, triggerList, order}); - //} - }; - - return ( - -
- {editName ? ( - - ) : ( - automationName - )} -
- - -
- )} - - - - - - - - - - - - + } + } + const result = !triggerList.some( + (t) => t.device === trigger.device && t.operand === trigger.operand ); + return { + result: result, + message: result + ? "" + : "You have already created a trigger for this device with the same conditions", + }; + }; + const addTrigger = () => { + const { result, message } = _checkNewTrigger(newTrigger); + const auxTrigger = newTrigger; + if (result) { + if ( + props.devices + .filter((d) => d.id === newTrigger.device)[0] + .hasOwnProperty("on") + ) { + delete auxTrigger.operand; + } + setTrigger((prevList) => [...prevList, auxTrigger]); + } else { + alert(message); + } + }; + + const removeTrigger = (index) => { + setTrigger((prevList) => prevList.filter((t, i) => i !== index)); + }; + + // This gets triggered when the devices dropdown changes the value. + const onInputChange = (val) => { + setNewTrigger({ ...newTrigger, [val.name]: val.value }); + }; + const onChangeName = (e, val) => setautomationName(val.value); + + const orderScenes = (id, checked) => { + if (checked) { + setOrder((prevList) => [...prevList, id]); + } else { + setOrder((prevList) => prevList.filter((e) => e !== id)); + } + }; + const searchScenes = (e, { value }) => { + if (value.length > 0) { + setScenes((prevScenes) => { + return stateScenes.filter((e) => { + return e.name.includes(value); + }); + }); + } else { + setScenes(props.scenes); + } + }; + + const _generateKey = (trigger) => { + if (trigger.hasOwnProperty("operand")) { + return trigger.device + trigger.operand + trigger.value; + } + return trigger.device + trigger.value; + }; + + const checkBeforeSave = () => { + if (automationName.length <= 0) { + alert("Give a name to the automation"); + return false; + } + if (triggerList.length <= 0) { + alert("You have to create a trigger"); + return false; + } + if (order.length <= 0) { + alert("You need at least one active scene"); + return false; + } + return true; + }; + + const saveAutomation = () => { + //if(checkBeforeSave()){ + const automation = { + name: automationName, + }; + props.save({ automation, triggerList, order }); + //} + }; + + return ( + +
+ {editName ? ( + + ) : ( + automationName + )} +
+ + +
+ )} + + + + + + + + + + + + + ); }; -const Automation = ({automation, devices, scenes, removeAutomation}) => { - const {triggers} = automation; - const scenePriorities = automation.scenes; - const getOperator = (operand) => - operands.filter((o) => o.key == operand)[0].text; +const Automation = ({ automation, devices, scenes, removeAutomation }) => { + const { triggers } = automation; + const scenePriorities = automation.scenes; + const getOperator = (operand) => + operands.filter((o) => o.key == operand)[0].text; - - return ( - -
- {automation.name} -
- - )} - - - - - {this.props.automations.map((automation, i) => { - return ( - - - - ); - })} - - - ); - } + render() { + return ( + + + + {!this.state.openModal ? ( + + + + ) : ( + + )} + + + + {this.props.automations.map((automation, i) => { + console.log(23, automation, i, this.props.automations); + return ( + + + + ); + })} + + + ); + } } const mapStateToProps = (state, _) => ({ - activeRoom: state.active.activeRoom, - activeTab: state.active.activeTab, - get scenes() { - return Object.values(state.scenes); - }, - get devices() { - return Object.values(state.devices); - }, - get automations() { - return Object.values(state.automations); - }, + activeRoom: state.active.activeRoom, + activeTab: state.active.activeTab, + get scenes() { + return Object.values(state.scenes); + }, + get devices() { + return Object.values(state.devices); + }, + get automations() { + console.log(state.automations); + return Object.values(state.automations); + }, }); const AutomationsPanelContainer = connect( - mapStateToProps, - RemoteService + mapStateToProps, + RemoteService )(AutomationsPanel); export default AutomationsPanelContainer; diff --git a/smart-hut/src/store.js b/smart-hut/src/store.js index 7c0507f..0087e46 100644 --- a/smart-hut/src/store.js +++ b/smart-hut/src/store.js @@ -256,8 +256,13 @@ function reducer(previousState, action) { case "AUTOMATION_UPDATE": newState = previousState; + const automations = {}; + for (const automation of action.automations) { + automations[automation.id] = automation; + } + change = { - automations : {$set: action.automations} + automations: { $set: automations }, }; newState = update(previousState, change); break; @@ -297,15 +302,13 @@ function reducer(previousState, action) { case "AUTOMATION_SAVE": console.log("ID: ", action.automation.id); change = { - automations : {[action.automation.id] : {$set : action.automation}} + automations: { [action.automation.id]: { $set: action.automation } }, }; - newState = update(previousState, change); break; - case "STATE_SAVE": change = { sceneStates: { [action.sceneState.id]: { $set: action.sceneState } }, @@ -355,15 +358,14 @@ function reducer(previousState, action) { break; case "AUTOMATION_DELETE": - change = { automations: { $unset: [action.id] }, }; - console.log("CHANGE ", change) + console.log("CHANGE ", change); console.log("Action id: ", action.id); newState = update(previousState, change); - console.log("NEW STATE ", newState) + console.log("NEW STATE ", newState); break; case "SCENE_DELETE": console.log("SCENE", action.sceneId);