diff --git a/smart-hut/src/components/HostModal.js b/smart-hut/src/components/HostModal.js new file mode 100644 index 0000000..55f4e4b --- /dev/null +++ b/smart-hut/src/components/HostModal.js @@ -0,0 +1,190 @@ +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 HostModal extends Component { + constructor(props) { + super(props); + this.state = this.initialState; + this.setInitialState(); + + this.addHostModal = this.addHostModal.bind(this); + this.modifyHostModal = this.modifyHostModal.bind(this); + this.deleteHost = this.deleteHost.bind(this); + } + + get initialState() { + return { + //INITIAL STATE HERE + }; + } + + setInitialState() { + this.setState(this.initialState); + } + + get type() { + return !this.props.id ? "new" : "modify"; + } + + addHostModal = (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));*/ + }; + + modifyHostModal = (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));*/ + }; + + deleteHost = (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 hosts" : "Modify hosts"} +
+ + { + //TODO FORM TO ADD OR MODIFY SCENE + } + + {this.type === "modify" ? ( + + ) : null} + + + + + + +
+
+ ); + } +} + +const setActiveHost = (activeHost) => { + return (dispatch) => + dispatch(appActions.setActiveHost(activeHost)); +}; + +const mapStateToProps = (state, ownProps) => ({ + hostss: ownProps.id ? state.hostss[ownProps.id] : null, +}); +const HostModalContainer = connect( + mapStateToProps, + { ...RemoteService, setActiveHost }, + null, + { forwardRef: true } +)(HostModal); +export default HostModalContainer; diff --git a/smart-hut/src/components/dashboard/HostsPanel.js b/smart-hut/src/components/dashboard/HostsPanel.js new file mode 100644 index 0000000..c019c10 --- /dev/null +++ b/smart-hut/src/components/dashboard/HostsPanel.js @@ -0,0 +1,45 @@ +import React, { Component } from "react"; +import { connect } from "react-redux"; +import { RemoteService } from "../../remote"; + +class HostsPanel extends Component { + constructor(props) { + super(props); + } + + render() { + return ( + + {!this.props.isActiveDefaultHost + ? this.props.hostDevices.map((e, i) => { + return ( + + + + ); + }) + : null} + {!this.props.isActiveDefaultHost ? ( + + + + ) : ( + + Welcome to the Host View, select a host to view their devices. + + )} + + ); + } +} + +const mapStateToProps = (state, _) => ({ + activeTab: state.active.activeTab, + activeHost: state.active.activeHost, + hostDevices: state.hostDevices, +}); +const HostsPanelContainer = connect( + mapStateToProps, + RemoteService +)(HostsPanel); +export default HostsPanelContainer; diff --git a/smart-hut/src/remote.js b/smart-hut/src/remote.js index 66d47bd..8b508bc 100644 --- a/smart-hut/src/remote.js +++ b/smart-hut/src/remote.js @@ -346,6 +346,26 @@ export const RemoteService = { }; }, + /** + * Fetches all devices in a particular room, or fetches all devices. + * This also updates the devices attribute on values in the map rooms. + * @param {Number|null} roomId the room to which fetch devices + * from, null to fetch from all rooms + * @returns {Promise} promise that resolves to void and rejects + * with user-fiendly errors as a RemoteError + */ + fetchAllHosts: () => { + return (dispatch) => { + return Endpoint.get(`/user`) + .then((res) => void dispatch(actions.getHosts(res.data))) + .catch((err) => { + // TODO CHANGE ERROR MESSAGE + console.error(`Fetch hosts error`, err); + throw new RemoteError(["Network error"]); + }); + }; + }, + /** * Creates/Updates a room with the given data * @param {String} data.name the room's name, diff --git a/smart-hut/src/store.js b/smart-hut/src/store.js index 350cc7b..d78bac8 100644 --- a/smart-hut/src/store.js +++ b/smart-hut/src/store.js @@ -469,6 +469,15 @@ function reducer(previousState, action) { }, }); break; + case "SET_ACTIVE_HOST": + newState = update(previousState, { + active: { + activeHost: { + $set: action.activeHost, + }, + }, + }); + break; case "REDUX_WEBSOCKET::MESSAGE": const devices = JSON.parse(action.payload.message); //console.log("socket", JSON.stringify(devices, null, 2)); @@ -479,6 +488,13 @@ function reducer(previousState, action) { devices, }); break; + case "GET_HOSTS": + change = {}; + for (const host of action.hosts) { + change.$add = host; + } + newState = update(previousState, change); + break; default: console.warn(`Action type ${action.type} unknown`, action); return previousState; @@ -497,6 +513,7 @@ const initState = { activeTab: "Devices", activeScene: -1, activeAutomation: -1, + activeHost: -1, }, login: { loggedIn: false, @@ -513,6 +530,12 @@ const initState = { devices: {}, /** @type {[integer]SceneState} */ sceneStates: {}, + /** @type {[integer]Guest} */ + guests: {}, + /** @type {[integer]Host} */ + hosts: {}, + /** @type {[integer]HostDevice} */ + hostDevices: {}, }; function createSmartHutStore() { diff --git a/smart-hut/src/storeActions.js b/smart-hut/src/storeActions.js index e8ee30a..769ce8b 100644 --- a/smart-hut/src/storeActions.js +++ b/smart-hut/src/storeActions.js @@ -91,6 +91,11 @@ const actions = { type: "DEVICE_DELETE", deviceId, }), + + getHosts: (hosts) => ({ + type: "GET_HOSTS", + hosts, + }) }; export const appActions = { @@ -111,6 +116,10 @@ export const appActions = { type: "SET_ACTIVE_AUTOMATION", activeAutomation, }), + setActiveHosts: (activeHost = -1) => ({ + type: "SET_ACTIVE_HOST", + activeHost, + }), }; export default actions; diff --git a/smart-hut/src/views/Dashboard.js b/smart-hut/src/views/Dashboard.js index bb92ea8..17772e6 100644 --- a/smart-hut/src/views/Dashboard.js +++ b/smart-hut/src/views/Dashboard.js @@ -2,8 +2,11 @@ import React, { Component } from "react"; import DevicePanel from "../components/dashboard/DevicePanel"; import ScenesPanel from "../components/dashboard/ScenesPanel"; import AutomationsPanel from "../components/dashboard/AutomationsPanel"; +import HostsPanel from "../components/dashboard/HostsPanel"; import Navbar from "./Navbar"; import ScenesNavbar from "./ScenesNavbar"; +import AutomationsNavbar from "./AutomationsNavbar"; +import HostsNavbar from "./HostsNavbar"; import MyHeader from "../components/HeaderController"; import { Grid, Responsive, Button, Menu } from "semantic-ui-react"; import { @@ -55,6 +58,8 @@ class Dashboard extends Component { return ; case "Automations": return ; + case "Hosts": + return ; default: return

ERROR

; } @@ -66,6 +71,10 @@ class Dashboard extends Component { return ; case "Scenes": return ; + case "Automations": + return ; + case "Hosts": + return ; default: return

ERROR

; } @@ -106,6 +115,12 @@ class Dashboard extends Component { active={this.activeTab === "Automations"} onClick={this.selectTab} /> + @@ -153,6 +168,14 @@ class Dashboard extends Component { color={this.activeTab === "Automations" ? "yellow" : "grey"} onClick={this.selectTab} /> + + + + + + + + + + + AUTOMATIONS + + + + {Object.values(this.props.hosts).map((e, i) => { + return ( + + + + {e.name} + + {this.state.editMode ? ( + + ) : null} + + + + + ); + })} + + + + + + + + + + + + + + + + + + + + + + + Hosts + + + + + {Object.values(this.props.hosts).map((e, i) => { + return ( + + + + {e.name} + + {this.state.editMode ? ( + + ) : null} + + + + + ); + })} + + + + + + + + + + {this.activeItemHost !== -1 ? ( + + + + ) : null} + + + + + ); + } +} + +const setActiveHost = (activeHost) => { + return (dispatch) => + dispatch(appActions.setActiveHost(activeHost)); +}; + +const mapStateToProps = (state, _) => ({ + hosts: state.hosts, + activeHost: state.active.activeHost, + hostModalRefs: Object.keys(state.hosts).reduce( + (acc, key) => ({ ...acc, [key]: React.createRef() }), + {} + ), +}); +const HostsNavbarContainer = connect(mapStateToProps, { + ...RemoteService, + setActiveHost, +})(HostsNavbar); +export default HostsNavbarContainer;