Extended Devices with buttons and status
This commit is contained in:
		@@ -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();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user