Fixes to Device in preparation to use in Hosts tab

This commit is contained in:
Claudio Maggioni (maggicl) 2020-05-03 17:18:34 +02:00
parent f6f46918c6
commit c95f7a95f7
7 changed files with 90 additions and 49 deletions

View file

@ -29,7 +29,7 @@ class DevicePanel extends Component {
return <Device key={i} tab={this.props.tab} id={e.id} />;
})}
{!this.props.isActiveRoomHome ? (
<Card style={{ height: "23em" }}>
<Card style={{ height: "27em" }}>
<Segment basic style={{ width: "100%", height: "100%" }}>
<NewDevice />
</Segment>

View file

@ -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 (
<Card.Group centered style={{ paddingTop: "3rem" }}>
{this.props.isActiveDefaultHost && (
@ -15,6 +24,16 @@ class HostsPanel extends Component {
</Header>
</Segment>
)}
{this.props.hostDeviceIds.map((id) => {
return (
<Device
key={id}
hostId={this.props.activeHost}
tab="Hosts"
id={id}
/>
);
})}
</Card.Group>
);
}
@ -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;

View file

@ -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 [];

View file

@ -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 (
<Curtains
@ -151,22 +146,16 @@ class Device extends React.Component {
}
get deviceName() {
return this.props.tab === "Devices"
? this.props.stateOrDevice.name
: this.props.device.name;
return this.props.device.name;
}
render() {
return (
<Card style={{ height: this.props.tab === "Devices" ? "23em" : "27em" }}>
<Card style={{ height: "27em" }}>
<Card.Content>
<Card.Header textAlign="center">
<Header as="h3">{this.deviceName}</Header>
{this.props.tab === "Scenes" ? (
<Header as="h4">{this.props.roomName}</Header>
) : (
""
)}
</Card.Header>
<Card.Description style={centerComponent}>
@ -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);

View file

@ -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<Undefined, RemoteError>} 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"]);

View file

@ -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) {

View file

@ -58,6 +58,11 @@ const actions = {
devices,
partial,
}),
hostDevicesUpdate: (hostId, devices) => ({
type: "HOST_DEVICES_UPDATE",
hostId,
devices,
}),
stateDelete: (stateId) => ({
type: "STATE_DELETE",
stateId,