implemented device statistics
This commit is contained in:
parent
0076f2d208
commit
3a000b0094
8 changed files with 276 additions and 111 deletions
|
|
@ -1,5 +1,4 @@
|
|||
import {
|
||||
CircularProgress,
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
|
|
@ -20,9 +19,8 @@ import TagSettings from "common/TagSettings";
|
|||
import { Device, Tag } from "models";
|
||||
import { filterByTag } from "pbHelpers/Tag";
|
||||
import { useDeviceAPI, useSnackbar, useTagAPI } from "providers";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { pond } from "protobuf-ts/pond";
|
||||
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
|
||||
|
||||
const useStyles = makeStyles((_theme: Theme) => {
|
||||
return ({
|
||||
|
|
@ -137,14 +135,14 @@ export default function DeviceTags(props: DeviceTagsProps) {
|
|||
// const [{ tags }] = useGlobalState();
|
||||
const tagAPI = useTagAPI()
|
||||
const [tags, setTags] = useState<Tag[]>([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
// const [loading, setLoading] = useState(false)
|
||||
const deviceAPI = useDeviceAPI();
|
||||
const { error } = useSnackbar();
|
||||
const [deviceTags, setDeviceTags] = useState<string[]>(device.status.tagKeys);
|
||||
const previousDeviceRef = useRef(device);
|
||||
// const previousDeviceRef = useRef(device);
|
||||
|
||||
const loadTags = () => {
|
||||
setLoading(true)
|
||||
// setLoading(true)
|
||||
tagAPI.listTags().then(resp => {
|
||||
let newTags: Tag[] = [];
|
||||
resp.data.tags.forEach((tag: pond.Tag) => {
|
||||
|
|
@ -152,12 +150,11 @@ export default function DeviceTags(props: DeviceTagsProps) {
|
|||
})
|
||||
setTags(newTags)
|
||||
}).finally(() => {
|
||||
setLoading(false)
|
||||
// setLoading(false)
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log(props.tags)
|
||||
let newTags: string[] = []
|
||||
props.tags.forEach(tag => {
|
||||
if (tag.settings) newTags.push(tag.settings?.key)
|
||||
|
|
@ -169,34 +166,6 @@ export default function DeviceTags(props: DeviceTagsProps) {
|
|||
loadTags()
|
||||
}, [])
|
||||
|
||||
// useEffect(() => {
|
||||
// // if (previousDeviceRef.current !== device) {
|
||||
// let keys = getContextKeys()
|
||||
// keys.push(device.id().toString())
|
||||
// let types = getContextTypes()
|
||||
// types.push("device")
|
||||
// setDeviceTags(device.status.tagKeys);
|
||||
// previousDeviceRef.current = device;
|
||||
// tagAPI.listTags(
|
||||
// undefined,
|
||||
// undefined,
|
||||
// undefined,
|
||||
// undefined,
|
||||
// undefined,
|
||||
// undefined,
|
||||
// keys,
|
||||
// types,
|
||||
// ).then(resp => {
|
||||
// // console.log(resp.data)
|
||||
// let newTagKeys: string[] = []
|
||||
// resp.data.tags.forEach((tag: any) => {
|
||||
// newTagKeys.push(tag.settings.key)
|
||||
// })
|
||||
// setDeviceTags(newTagKeys)
|
||||
// })
|
||||
// // }
|
||||
// }, [device]);
|
||||
|
||||
const addTag = (tag: Tag) => {
|
||||
if (!deviceTags.some(dt => dt === tag.key())) {
|
||||
deviceAPI
|
||||
|
|
|
|||
140
src/device/DevicesSummary.tsx
Normal file
140
src/device/DevicesSummary.tsx
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
import {
|
||||
AutoAwesomeMosaic,
|
||||
Battery20,
|
||||
Check,
|
||||
CheckCircle,
|
||||
PermScanWifi,
|
||||
} from "@mui/icons-material";
|
||||
import { Card, Grid2, Typography, useTheme } from "@mui/material";
|
||||
import { blue, green, purple, red } from "@mui/material/colors";
|
||||
import CircleGraphIcon from "common/CircleGraphIcon";
|
||||
import { getContextKeys, getContextTypes } from "pbHelpers/Context";
|
||||
import { pond } from "protobuf-ts/pond";
|
||||
import { useDeviceAPI } from "providers";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
interface Props {}
|
||||
|
||||
export default function DevicesSummary(props: Props) {
|
||||
|
||||
const deviceAPI = useDeviceAPI()
|
||||
const theme = useTheme()
|
||||
|
||||
const [stats, setStats] = useState<pond.DeviceStatistics>(pond.DeviceStatistics.create())
|
||||
const [loadingStats, setLoadingStats] = useState(false)
|
||||
|
||||
const loadDeviceStatistics = () => {
|
||||
setLoadingStats(true)
|
||||
deviceAPI.statistics(
|
||||
getContextKeys(),
|
||||
getContextTypes()
|
||||
).then(resp => {
|
||||
let stats = pond.DeviceStatistics.fromObject(resp.data.stats)
|
||||
setStats(stats)
|
||||
}).finally(() => {
|
||||
setLoadingStats(false)
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
loadDeviceStatistics()
|
||||
}, [])
|
||||
|
||||
const getPercent = (devices: number) => {
|
||||
const ratio = devices/stats.total
|
||||
return ratio*100
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid2 container spacing={1} marginBlock={1} >
|
||||
<Grid2 size={{xs: 6, sm: 3}}>
|
||||
<Card sx={{ padding: 1 }}>
|
||||
<Grid2 container spacing={1} justifyContent={"center"} alignItems={"center"} >
|
||||
<Grid2>
|
||||
<CircleGraphIcon
|
||||
sx={{ marginRight: 1, marginLeft: 1 }}
|
||||
progress={100}
|
||||
color={"info"}
|
||||
icon={<AutoAwesomeMosaic />}
|
||||
/>
|
||||
</Grid2>
|
||||
<Grid2 marginRight={1}>
|
||||
<Typography variant="h6" >
|
||||
{stats.total} Devices
|
||||
</Typography>
|
||||
<Typography variant="subtitle2" color="textSecondary">
|
||||
Total
|
||||
</Typography>
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
</Card>
|
||||
</Grid2>
|
||||
<Grid2 size={{xs: 6, sm: 3}}>
|
||||
<Card sx={{ padding: 1 }}>
|
||||
<Grid2 container spacing={1} justifyContent={"center"} alignItems={"center"} >
|
||||
<Grid2>
|
||||
<CircleGraphIcon
|
||||
sx={{ marginRight: 1, marginLeft: 1 }}
|
||||
progress={getPercent(stats.active)}
|
||||
color={"success"}
|
||||
icon={<Check />}
|
||||
/>
|
||||
</Grid2>
|
||||
<Grid2 marginRight={1}>
|
||||
<Typography variant="h6" >
|
||||
{stats.active} Devices
|
||||
</Typography>
|
||||
<Typography variant="subtitle2" color="textSecondary">
|
||||
Active
|
||||
</Typography>
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
</Card>
|
||||
</Grid2>
|
||||
<Grid2 size={{xs: 6, sm: 3}}>
|
||||
<Card sx={{ padding: 1 }}>
|
||||
<Grid2 container spacing={1} justifyContent={"center"} alignItems={"center"} >
|
||||
<Grid2>
|
||||
<CircleGraphIcon
|
||||
sx={{ marginRight: 1, marginLeft: 1 }}
|
||||
progress={getPercent(stats.warning)}
|
||||
color="warning"
|
||||
icon={<Battery20 />}
|
||||
/>
|
||||
</Grid2>
|
||||
<Grid2 marginRight={1}>
|
||||
<Typography variant="h6" >
|
||||
{stats.warning} Devices
|
||||
</Typography>
|
||||
<Typography variant="subtitle2" color="textSecondary">
|
||||
Low Power
|
||||
</Typography>
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
</Card>
|
||||
</Grid2>
|
||||
<Grid2 size={{xs: 6, sm: 3}}>
|
||||
<Card sx={{ padding: 1 }}>
|
||||
<Grid2 container spacing={1} justifyContent={"center"} alignItems={"center"} >
|
||||
<Grid2>
|
||||
<CircleGraphIcon
|
||||
sx={{ marginRight: 1, marginLeft: 1 }}
|
||||
progress={100}
|
||||
color={green[50]}
|
||||
icon={<PermScanWifi />}
|
||||
/>
|
||||
</Grid2>
|
||||
<Grid2 marginRight={1}>
|
||||
<Typography variant="h6" >
|
||||
{stats.offline} Devices
|
||||
</Typography>
|
||||
<Typography variant="subtitle2" color="textSecondary">
|
||||
Offline
|
||||
</Typography>
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
</Card>
|
||||
</Grid2>
|
||||
</Grid2>
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue