Extended Devices with buttons and status
This commit is contained in:
parent
181985859e
commit
f84ea8f0c5
@ -52,7 +52,7 @@ function App() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const DevicesComponent = () => {
|
const DevicesComponent = () => {
|
||||||
return <Devices/>;
|
return <Devices isAdmin={isAdmin}/>;
|
||||||
|
|
||||||
};
|
};
|
||||||
const HeatmapComponent = () => {
|
const HeatmapComponent = () => {
|
||||||
@ -69,9 +69,9 @@ function App() {
|
|||||||
<Switch>
|
<Switch>
|
||||||
<PublicRoute path="/login" component={AuthComponent} />
|
<PublicRoute path="/login" component={AuthComponent} />
|
||||||
<DevicesContextProvider>
|
<DevicesContextProvider>
|
||||||
<PrivateRoute path="/" exact authenticated={authenticated} isAdmin={isAdmin} component={DashboardComponent} />
|
<PrivateRoute path="/" exact authenticated={authenticated} component={DashboardComponent} />
|
||||||
<PrivateRoute path="/devices/:id?" exact authenticated={authenticated} isAdmin={isAdmin} component={DevicesComponent} />
|
<PrivateRoute path="/devices/:id?" exact authenticated={authenticated} component={DevicesComponent} />
|
||||||
<PrivateRoute path="/heatmap" exact authenticated={authenticated} isAdmin={isAdmin} component={HeatmapComponent} />
|
<PrivateRoute path="/heatmap" exact authenticated={authenticated} component={HeatmapComponent} />
|
||||||
</DevicesContextProvider>
|
</DevicesContextProvider>
|
||||||
</Switch>
|
</Switch>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
@ -89,17 +89,17 @@ const PublicRoute = ({ component: Component, ...rest }: { [x: string]: any, comp
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const PrivateRoute = ({ component: Component, authenticated: Authenticated, isAdmin: IsAdmin, ...rest }: { [x: string]: any, component: any, authenticated: any, isAdmin: any }) => {
|
const PrivateRoute = ({ component: Component, authenticated: Authenticated, ...rest }: { [x: string]: any, component: any, authenticated: any }) => {
|
||||||
return (
|
return (
|
||||||
<Route {...rest} render={matchProps => (
|
<Route {...rest} render={matchProps => (
|
||||||
Authenticated
|
Authenticated
|
||||||
? <DefaultLayout component={Component} authenticated={Authenticated} isAdmin={IsAdmin} {...matchProps} />
|
? <DefaultLayout component={Component} authenticated={Authenticated} {...matchProps} />
|
||||||
: <Redirect to='/login' />
|
: <Redirect to='/login' />
|
||||||
)} />
|
)} />
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const DefaultLayout = ({ component: Component, authenticated: Authenticated, isAdmin: IsAdmin, ...rest }: { [x: string]: any, component: any, authenticated: any, isAdmin: any }) => {
|
const DefaultLayout = ({ component: Component, authenticated: Authenticated, ...rest }: { [x: string]: any, component: any, authenticated: any }) => {
|
||||||
const classes = useDefaultLayoutStyles();
|
const classes = useDefaultLayoutStyles();
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
const anchorRef = React.useRef<HTMLButtonElement>(null);
|
const anchorRef = React.useRef<HTMLButtonElement>(null);
|
||||||
@ -186,7 +186,7 @@ const DefaultLayout = ({ component: Component, authenticated: Authenticated, isA
|
|||||||
</Toolbar>
|
</Toolbar>
|
||||||
</AppBar>
|
</AppBar>
|
||||||
<Box zIndex="modal" className={classes.box_root}>
|
<Box zIndex="modal" className={classes.box_root}>
|
||||||
<Component isAdmin={IsAdmin} {...rest} />
|
<Component {...rest} />
|
||||||
</Box>
|
</Box>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
|
@ -430,7 +430,9 @@ var DeviceService = /** @class */ (function () {
|
|||||||
url_ = url_.replace(/[?&]$/, "");
|
url_ = url_.replace(/[?&]$/, "");
|
||||||
var options_ = {
|
var options_ = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {}
|
headers: {
|
||||||
|
'Authorization': sessionStorage.getItem('user')
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return this.http.fetch(url_, options_).then(function (_response) {
|
return this.http.fetch(url_, options_).then(function (_response) {
|
||||||
return _this.processOnlinesensor(_response);
|
return _this.processOnlinesensor(_response);
|
||||||
|
File diff suppressed because one or more lines are too long
@ -391,6 +391,7 @@ export default class DeviceService {
|
|||||||
let options_ = <RequestInit>{
|
let options_ = <RequestInit>{
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
|
'Authorization': sessionStorage.getItem('user')
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,14 +1,22 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import Accordion from '@material-ui/core/Accordion';
|
import Accordion from '@material-ui/core/Accordion';
|
||||||
import { blue, red, yellow } from '@material-ui/core/colors';
|
import { blue, blueGrey, green, orange, red, yellow } from '@material-ui/core/colors';
|
||||||
import AccordionSummary from '@material-ui/core/AccordionSummary';
|
import AccordionSummary from '@material-ui/core/AccordionSummary';
|
||||||
import AccordionDetails from '@material-ui/core/AccordionDetails';
|
import AccordionDetails from '@material-ui/core/AccordionDetails';
|
||||||
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
|
||||||
import { Grid, Typography, Paper } from '@material-ui/core';
|
import { Grid, Typography, Paper, IconButton, Box, FormControlLabel } from '@material-ui/core';
|
||||||
import { withStyles } from '@material-ui/styles';
|
import { withStyles } from '@material-ui/styles';
|
||||||
import { withRouter } from "react-router";
|
import { withRouter } from "react-router";
|
||||||
|
import { Power, PowerOff, Refresh } from '@material-ui/icons/';
|
||||||
|
import DeviceService from '../../common/DeviceService'
|
||||||
|
|
||||||
const styles = theme => ({
|
const styles = theme => ({
|
||||||
|
acc_summary: {
|
||||||
|
backgroundColor: blueGrey[50],
|
||||||
|
},
|
||||||
|
acc_details: {
|
||||||
|
backgroundColor: blueGrey[100],
|
||||||
|
},
|
||||||
grid_typo: {
|
grid_typo: {
|
||||||
fontSize: theme.typography.pxToRem(20),
|
fontSize: theme.typography.pxToRem(20),
|
||||||
fontWeight: theme.typography.fontWeightRegular,
|
fontWeight: theme.typography.fontWeightRegular,
|
||||||
@ -32,6 +40,9 @@ const styles = theme => ({
|
|||||||
fontSize: theme.typography.pxToRem(15),
|
fontSize: theme.typography.pxToRem(15),
|
||||||
fontWeight: theme.typography.fontWeightRegular,
|
fontWeight: theme.typography.fontWeightRegular,
|
||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
|
},
|
||||||
|
icon_box: {
|
||||||
|
marginRight: '15px',
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -46,9 +57,9 @@ class DeviceComponent extends Component {
|
|||||||
|
|
||||||
getColor(status) {
|
getColor(status) {
|
||||||
if (status == "Online") {
|
if (status == "Online") {
|
||||||
return { color: blue[800] };
|
return { color: green[600] };
|
||||||
} else if (status == "Offline") {
|
} else if (status == "Offline") {
|
||||||
return { color: yellow[800] };
|
return { color: orange[900] };
|
||||||
} else /* if (device.status == "unknown") */ {
|
} else /* if (device.status == "unknown") */ {
|
||||||
return { color: red[800] };
|
return { color: red[800] };
|
||||||
}
|
}
|
||||||
@ -59,12 +70,71 @@ class DeviceComponent extends Component {
|
|||||||
this.setState({ expanded: id });
|
this.setState({ expanded: id });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderSensorButtons(device, sensor) {
|
||||||
|
var service = new DeviceService();
|
||||||
|
return this.renderButtons(
|
||||||
|
() => service.onlinesensor(device.id, sensor.id),
|
||||||
|
() => service.offlinesensor(device.id, sensor.id),
|
||||||
|
() => service.getsensor(device.id, sensor.id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderDeviceButtons(device) {
|
||||||
|
var service = new DeviceService();
|
||||||
|
return this.renderButtons(
|
||||||
|
() => service.onlinedevice(device.id),
|
||||||
|
() => service.offlinedevice(device.id),
|
||||||
|
() => service.getdevice(device.id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderButtons(onPower, onPowerOff, onRefresh) {
|
||||||
|
const renderOnOff = () => {
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<IconButton color="primary" onClick={onPower}>
|
||||||
|
<Power />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton color="primary" onClick={onPowerOff}>
|
||||||
|
<PowerOff />
|
||||||
|
</IconButton>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { classes } = this.props;
|
||||||
|
return (
|
||||||
|
<Box className={classes.icon_box}>
|
||||||
|
{this.props.isAdmin ? renderOnOff() : null}
|
||||||
|
<IconButton color="primary" onClick={onRefresh}>
|
||||||
|
<Refresh />
|
||||||
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { classes } = this.props;
|
const { classes } = this.props;
|
||||||
const Sensors = this.props.device.sensors.map((sensor, index) => (
|
const Sensors = this.props.device.sensors.map((sensor, index) => (
|
||||||
<Grid item className={classes.grid_item} key={sensor.id}>
|
<Grid item className={classes.grid_item} key={sensor.id}>
|
||||||
<Typography className={classes.grid_item_typo}>Sensor {index}</Typography>
|
<Grid container
|
||||||
<Typography className={classes.grid_item_typo_2}>{sensor.id}</Typography>
|
spacing={3}
|
||||||
|
direction="row"
|
||||||
|
justify="space-between"
|
||||||
|
alignItems="center">
|
||||||
|
<Grid item>
|
||||||
|
<Typography className={classes.grid_item_typo}>Sensor {index}</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<Typography className={classes.grid_item_typo_2}>{sensor.id}</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<Typography style={this.getColor(sensor.status)}>Status: <b>{sensor.status}</b></Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
{this.renderSensorButtons(this.props.device, sensor)}
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -74,22 +144,41 @@ class DeviceComponent extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Accordion expanded={this.state.expanded === this.props.device.id} onChange={handleChange(this.props.device.id)}>
|
<Accordion expanded={this.state.expanded === this.props.device.id} onChange={handleChange(this.props.device.id)}>
|
||||||
<AccordionSummary
|
<AccordionSummary className={classes.acc_summary}
|
||||||
expandIcon={<ExpandMoreIcon />}
|
expandIcon={<ExpandMoreIcon />}
|
||||||
aria-controls={"device-panel-/" + this.props.device.id}
|
aria-controls={"device-panel-/" + this.props.device.id}
|
||||||
id={"device-panel-/" + this.props.device.id}>
|
id={"device-panel-/" + this.props.device.id}>
|
||||||
<Typography className={classes.grid_typo}>Device {this.props.index}</Typography>
|
<Grid container
|
||||||
<Typography className={classes.grid_typo_2}>{this.props.device.id}</Typography>
|
spacing={3}
|
||||||
|
direction="row"
|
||||||
|
justify="space-between"
|
||||||
|
alignItems="center">
|
||||||
|
<Grid item>
|
||||||
|
<Typography className={classes.grid_typo}>Device {this.props.index}</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<Typography className={classes.grid_typo_2}>{this.props.device.id}</Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<Typography style={this.getColor(this.props.device.status)}>Status: <b>{this.props.device.status}</b></Typography>
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<FormControlLabel
|
||||||
|
onClick={(event) => event.stopPropagation()}
|
||||||
|
onFocus={(event) => event.stopPropagation()}
|
||||||
|
control={this.renderDeviceButtons(this.props.device)}/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
</AccordionSummary>
|
</AccordionSummary>
|
||||||
<AccordionDetails>
|
<AccordionDetails className={classes.acc_details}>
|
||||||
<Grid className={classes.grid_item}
|
<Grid className={classes.grid_item}
|
||||||
container
|
container
|
||||||
spacing={3}
|
spacing={3}
|
||||||
direction="column"
|
direction="column"
|
||||||
justify="center"
|
justify="center"
|
||||||
alignItems="flex-start">
|
alignItems="flex-start">
|
||||||
{Sensors}
|
{Sensors}
|
||||||
</Grid>
|
</Grid>
|
||||||
</AccordionDetails>
|
</AccordionDetails>
|
||||||
</Accordion>
|
</Accordion>
|
||||||
);
|
);
|
||||||
|
@ -24,7 +24,7 @@ class Devices extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
const { classes } = this.props;
|
const { classes } = this.props;
|
||||||
const Devices = this.context.devices.map((device, index) => (
|
const Devices = this.context.devices.map((device, index) => (
|
||||||
<DeviceComponent device={device} index={index} key={device.id}/>
|
<DeviceComponent isAdmin={this.props.isAdmin} device={device} index={index} key={device.id}/>
|
||||||
));
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -75,6 +75,7 @@ namespace Birdmap.API.Controllers
|
|||||||
{
|
{
|
||||||
_logger.LogInformation($"Getting device [{deviceID}]...");
|
_logger.LogInformation($"Getting device [{deviceID}]...");
|
||||||
|
|
||||||
|
await _hubContext.Clients.All.NotifyDeviceUpdatedAsync(deviceID);
|
||||||
return await _service.GetdeviceAsync(deviceID);
|
return await _service.GetdeviceAsync(deviceID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +118,7 @@ namespace Birdmap.API.Controllers
|
|||||||
{
|
{
|
||||||
_logger.LogInformation($"Getting sensor [{sensorID}] of device [{deviceID}]...");
|
_logger.LogInformation($"Getting sensor [{sensorID}] of device [{deviceID}]...");
|
||||||
|
|
||||||
|
await _hubContext.Clients.All.NotifyDeviceUpdatedAsync(deviceID);
|
||||||
return await _service.GetsensorAsync(deviceID, sensorID);
|
return await _service.GetsensorAsync(deviceID, sensorID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +133,7 @@ namespace Birdmap.API.Controllers
|
|||||||
_logger.LogInformation($"Turning off sensor [{sensorID}] of device [{deviceID}]...");
|
_logger.LogInformation($"Turning off sensor [{sensorID}] of device [{deviceID}]...");
|
||||||
|
|
||||||
await _service.OfflinesensorAsync(deviceID, sensorID);
|
await _service.OfflinesensorAsync(deviceID, sensorID);
|
||||||
|
await _hubContext.Clients.All.NotifyDeviceUpdatedAsync(deviceID);
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
@ -146,6 +149,7 @@ namespace Birdmap.API.Controllers
|
|||||||
_logger.LogInformation($"Turning on sensor [{sensorID}] of device [{deviceID}]...");
|
_logger.LogInformation($"Turning on sensor [{sensorID}] of device [{deviceID}]...");
|
||||||
|
|
||||||
await _service.OnlinesensorAsync(deviceID, sensorID);
|
await _service.OnlinesensorAsync(deviceID, sensorID);
|
||||||
|
await _hubContext.Clients.All.NotifyDeviceUpdatedAsync(deviceID);
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user