From c95f7a95f7ca92727207a0f73c9c3b7c059e253f Mon Sep 17 00:00:00 2001 From: "Claudio Maggioni (maggicl)" Date: Sun, 3 May 2020 17:18:34 +0200 Subject: [PATCH] Fixes to Device in preparation to use in Hosts tab --- .../src/components/dashboard/DevicePanel.js | 2 +- .../src/components/dashboard/HostsPanel.js | 21 ++++- .../src/components/dashboard/ScenesPanel.js | 1 - .../components/dashboard/devices/Device.js | 78 +++++++++---------- smart-hut/src/remote.js | 18 ++++- smart-hut/src/store.js | 14 ++++ smart-hut/src/storeActions.js | 5 ++ 7 files changed, 90 insertions(+), 49 deletions(-) diff --git a/smart-hut/src/components/dashboard/DevicePanel.js b/smart-hut/src/components/dashboard/DevicePanel.js index 15206b8..73196df 100644 --- a/smart-hut/src/components/dashboard/DevicePanel.js +++ b/smart-hut/src/components/dashboard/DevicePanel.js @@ -29,7 +29,7 @@ class DevicePanel extends Component { return ; })} {!this.props.isActiveRoomHome ? ( - + diff --git a/smart-hut/src/components/dashboard/HostsPanel.js b/smart-hut/src/components/dashboard/HostsPanel.js index 7b6ffac..538cb89 100644 --- a/smart-hut/src/components/dashboard/HostsPanel.js +++ b/smart-hut/src/components/dashboard/HostsPanel.js @@ -2,9 +2,18 @@ import React, { Component } from "react"; import { connect } from "react-redux"; import { RemoteService } from "../../remote"; import { Card, Segment, Header, Icon } from "semantic-ui-react"; +import Device from "../../components/dashboard/devices/Device"; class HostsPanel extends Component { + constructor(props) { + super(props); + if (this.props.activeHost !== -1) { + this.props.fetchDevices(null, this.props.activeHost).catch(console.error); + } + } + render() { + console.log(this.props); return ( {this.props.isActiveDefaultHost && ( @@ -15,6 +24,16 @@ class HostsPanel extends Component { )} + {this.props.hostDeviceIds.map((id) => { + return ( + + ); + })} ); } @@ -23,7 +42,7 @@ class HostsPanel extends Component { const mapStateToProps = (state, _) => ({ isActiveDefaultHost: state.active.activeHost === -1, activeHost: state.active.activeHost, - hostDevices: state.hostDevices, + hostDeviceIds: Object.keys(state.hostDevices[state.activeHost] || {}), }); const HostsPanelContainer = connect(mapStateToProps, RemoteService)(HostsPanel); export default HostsPanelContainer; diff --git a/smart-hut/src/components/dashboard/ScenesPanel.js b/smart-hut/src/components/dashboard/ScenesPanel.js index 7a69fc5..a9b2210 100644 --- a/smart-hut/src/components/dashboard/ScenesPanel.js +++ b/smart-hut/src/components/dashboard/ScenesPanel.js @@ -65,7 +65,6 @@ const mapStateToProps = (state, _) => ({ const stateArray = [ ...state.scenes[state.active.activeScene].sceneStates, ].sort(); - console.log("STATESCENE", stateArray); return stateArray.map((id) => state.sceneStates[id]); } else { return []; diff --git a/smart-hut/src/components/dashboard/devices/Device.js b/smart-hut/src/components/dashboard/devices/Device.js index ac13888..61ee18b 100644 --- a/smart-hut/src/components/dashboard/devices/Device.js +++ b/smart-hut/src/components/dashboard/devices/Device.js @@ -41,16 +41,11 @@ class Device extends React.Component { } deleteState() { - console.log("alpaca ", this.props); this.props.deleteState(this.props.id, this.props.stateOrDevice.kind); } renderDeviceComponent() { - switch ( - this.props.tab === "Devices" - ? this.props.stateOrDevice.kind - : this.props.type - ) { + switch (this.props.type) { case "curtains": return ( +
{this.deviceName}
- {this.props.tab === "Scenes" ? ( -
{this.props.roomName}
- ) : ( - "" - )} +
{this.props.roomName}
@@ -189,42 +178,45 @@ class Device extends React.Component { } } +function getStateOrDevice(state, ownProps) { + switch (state.active.activeTab) { + case "Devices": + return state.devices[ownProps.id]; + case "Scenes": + return state.sceneStates[ownProps.id]; + case "Hosts": + return state.hostDevices[ownProps.hostId][ownProps.id]; + default: + throw new Error( + `stateOrDevice has no value in tab "${state.active.activeTab}"` + ); + } +} + +function getDevice(state, ownProps) { + switch (state.active.activeTab) { + case "Scenes": + return state.devices[getStateOrDevice(state, ownProps).deviceId]; + case "Devices": + case "Hosts": + return getStateOrDevice(state, ownProps); + default: + throw new Error(`device has no value in tab "${state.active.activeTab}"`); + } +} + const mapStateToProps = (state, ownProps) => ({ get stateOrDevice() { - if (state.active.activeTab === "Devices") { - return state.devices[ownProps.id]; - } else { - return state.sceneStates[ownProps.id]; - } + return getStateOrDevice(state, ownProps); }, get device() { - if (state.active.activeTab === "Devices") { - return state.devices[ownProps.id]; - } else { - return state.devices[state.sceneStates[ownProps.id].deviceId]; - } + return getDevice(state, ownProps); }, get roomName() { - if (state.active.activeTab === "Scenes") { - const device = state.devices[state.sceneStates[ownProps.id].deviceId]; - return state.rooms[device.roomId].name; - } else { - return ""; - } + return (state.rooms[getDevice(state, ownProps).roomId] || {}).name; }, get type() { - if (state.active.activeTab === "Scenes") { - if (state.sceneStates[ownProps.id]) { - //console.log(state.sceneStates[ownProps.id], ownProps.id); - const id = state.sceneStates[ownProps.id].deviceId; - //console.log(id, state.devices[id].kind); - return state.devices[id].kind; - } else { - return ""; - } - } else { - return null; - } + return getDevice(state, ownProps).kind; }, }); const DeviceContainer = connect(mapStateToProps, RemoteService)(Device); diff --git a/smart-hut/src/remote.js b/smart-hut/src/remote.js index 424feb6..3bbb42c 100644 --- a/smart-hut/src/remote.js +++ b/smart-hut/src/remote.js @@ -297,13 +297,25 @@ export const RemoteService = { * This also updates the devices attribute on values in the map rooms. * @param {Number|null} roomId the rsoom to which fetch devices * from, null to fetch from all rooms + * @param {Number|null} hostId the user id of the owner of the devices to get + * (can be used for host view) * @returns {Promise} promise that resolves to void and rejects * with user-fiendly errors as a RemoteError */ - fetchDevices: (roomId = null) => { + fetchDevices: (roomId = null, hostId = null) => { return (dispatch) => { - return Endpoint.get(roomId ? `/room/${roomId}/device` : "/device") - .then((res) => void dispatch(actions.devicesUpdate(roomId, res.data))) + return Endpoint.get( + roomId ? `/room/${roomId}/device` : "/device", + hostId ? { hostId } : null + ) + .then( + (res) => + void dispatch( + !hostId + ? actions.devicesUpdate(roomId, res.data, hostId) + : actions.hostDevicesUpdate(hostId, res.data) + ) + ) .catch((err) => { console.error(`Fetch devices roomId=${roomId} error`, err); throw new RemoteError(["Network error"]); diff --git a/smart-hut/src/store.js b/smart-hut/src/store.js index 43abf85..33b0bef 100644 --- a/smart-hut/src/store.js +++ b/smart-hut/src/store.js @@ -3,6 +3,7 @@ import thunk from "redux-thunk"; import update from "immutability-helper"; import reduxWebSocket, { connect } from "@giantmachines/redux-websocket"; import { socketURL } from "./endpoint"; +import actions from "./storeActions"; function reducer(previousState, action) { let newState, change; @@ -255,7 +256,20 @@ function reducer(previousState, action) { newState = update(newState, change); break; + case "HOST_DEVICES_UPDATE": + change = { + hostDevices: { + [action.hostId]: { $set: {} }, + }, + }; + const deviceMap = change.hostDevices[action.hostId].$set; + for (const device of action.devices) { + deviceMap[device.id] = device; + } + + newState = update(previousState, change); + break; case "AUTOMATION_UPDATE": const automations = {}; for (const automation of action.automations) { diff --git a/smart-hut/src/storeActions.js b/smart-hut/src/storeActions.js index 1d8f77e..fbd02c7 100644 --- a/smart-hut/src/storeActions.js +++ b/smart-hut/src/storeActions.js @@ -58,6 +58,11 @@ const actions = { devices, partial, }), + hostDevicesUpdate: (hostId, devices) => ({ + type: "HOST_DEVICES_UPDATE", + hostId, + devices, + }), stateDelete: (stateId) => ({ type: "STATE_DELETE", stateId,