diff --git a/docs_test/src/assets/helpers.tsx b/docs_test/src/assets/helpers.tsx index 743e660..5cfe8eb 100644 --- a/docs_test/src/assets/helpers.tsx +++ b/docs_test/src/assets/helpers.tsx @@ -1,4 +1,17 @@ +import React from "react"; + export type DataPoint = { timestamp: string; // ISO format value: number; }; + +// Define the type for each entry in the topic_map +export type TopicEntry = { + current: T; + update: React.Dispatch>; +}; + +// Define the topic_map type +export type TopicMap = { + [topic: string]: TopicEntry; +}; \ No newline at end of file diff --git a/docs_test/src/dashboard/components/MainGrid.tsx b/docs_test/src/dashboard/components/MainGrid.tsx index e98c298..cb012dc 100644 --- a/docs_test/src/dashboard/components/MainGrid.tsx +++ b/docs_test/src/dashboard/components/MainGrid.tsx @@ -7,7 +7,7 @@ import SessionsChart from './SessionsChart'; import {useEffect, useState} from "react"; // @ts-ignore import useMqtt from '../../assets/usemqtt'; -import type {DataPoint} from '../../assets/helpers'; +import type {DataPoint, TopicMap} from '../../assets/helpers'; import {Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow} from "@mui/material"; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome' import {faGithub, faPython, faDocker, faDiscord} from "@fortawesome/free-brands-svg-icons"; @@ -23,6 +23,8 @@ export default function MainGrid() { const [clientsConnected, setClientsConnected] = useState([]); const [serverStart, setServerStart] = useState(''); const [serverUptime, setServerUptime] = useState(''); + const [cpuPercent, setCpuPercent] = useState([]); + const [memSize, setMemSize] = useState([]); function getRandomInt(min: number, max: number) { min = Math.ceil(min); @@ -65,9 +67,21 @@ export default function MainGrid() { mqttSubscribe('$SYS/broker/uptime/formatted'); mqttSubscribe('$SYS/broker/uptime'); mqttSubscribe('$SYS/broker/clients/connected'); + mqttSubscribe('$SYS/broker/cpu/percent'); + mqttSubscribe('$SYS/broker/heap/size') } }, [isConnected, mqttSubscribe]); + const topic_map: TopicMap = { + '$SYS/broker/messages/publish/sent': { current: sent, update: setSent }, + '$SYS/broker/messages/publish/received': { current: received, update: setReceived }, + '$SYS/broker/load/bytes/received': { current: bytesIn, update: setBytesIn }, + '$SYS/broker/load/bytes/sent': { current: bytesOut, update: setBytesOut }, + '$SYS/broker/clients/connected': { current: clientsConnected, update: setClientsConnected }, + '$SYS/broker/cpu/percent': { current: cpuPercent, update: setCpuPercent}, + '$SYS/broker/heap/size': { current: memSize, update: setMemSize} +}; + useEffect(() => { while (messageQueue.current.length > 0) { @@ -75,37 +89,14 @@ export default function MainGrid() { try { const d = payload.message; - if (payload.topic === '$SYS/broker/messages/publish/sent') { + + if(payload.topic in topic_map) { + const { update } = topic_map[payload.topic]; const newPoint: DataPoint = { timestamp: new Date().toISOString(), value: d }; - setSent(sent => [...sent, newPoint]); - } else if (payload.topic === '$SYS/broker/messages/publish/received') { - const newPoint: DataPoint = { - timestamp: new Date().toISOString(), - value: d - } - setReceived(received => [...received, newPoint]); - } else if (payload.topic === '$SYS/broker/load/bytes/received') { - const newPoint: DataPoint = { - timestamp: new Date().toISOString(), - value: d - } - setBytesIn(bytesIn => [...bytesIn, newPoint]); - } else if (payload.topic === '$SYS/broker/load/bytes/sent') { - const newPoint: DataPoint = { - timestamp: new Date().toISOString(), - value: d - } - setBytesOut(bytesOut => [...bytesOut, newPoint]); - } else if (payload.topic === '$SYS/broker/clients/connected') { - const newPoint: DataPoint = { - timestamp: new Date().toISOString(), - value: d - } - setClientsConnected(clientsConnected => [...clientsConnected, newPoint]); - + update(current => [...current, newPoint]) } else if (payload.topic === '$SYS/broker/uptime/formatted') { const dt = new Date(d + "Z"); setServerStart(dt.toLocaleString()); @@ -235,10 +226,10 @@ export default function MainGrid() { up for {serverUptime} - + - + @@ -249,6 +240,16 @@ export default function MainGrid() { + + + + + + + + + + diff --git a/docs_test/src/dashboard/components/SessionsChart.tsx b/docs_test/src/dashboard/components/SessionsChart.tsx index 1e66afd..0708355 100644 --- a/docs_test/src/dashboard/components/SessionsChart.tsx +++ b/docs_test/src/dashboard/components/SessionsChart.tsx @@ -1,147 +1,154 @@ -import { useTheme } from '@mui/material/styles'; -import Card from '@mui/material/Card'; -import CardContent from '@mui/material/CardContent'; -import Typography from '@mui/material/Typography'; -import Stack from '@mui/material/Stack'; -import { LineChart } from '@mui/x-charts/LineChart'; -import CountUp from 'react-countup'; -import type { DataPoint } from '../../assets/helpers.jsx'; -import {CircularProgress} from "@mui/material"; + import { useTheme } from '@mui/material/styles'; + import Card from '@mui/material/Card'; + import CardContent from '@mui/material/CardContent'; + import Typography from '@mui/material/Typography'; + import Stack from '@mui/material/Stack'; + import { LineChart } from '@mui/x-charts/LineChart'; + import CountUp from 'react-countup'; + import type { DataPoint } from '../../assets/helpers.jsx'; + import {CircularProgress} from "@mui/material"; -const currentTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; + const currentTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone; -function formatDate(date: Date) { + function formatDate(date: Date) { - return date.toLocaleTimeString('en-US', { - timeZone: currentTimeZone, - hour: '2-digit', - minute: '2-digit', - second: '2-digit', - }); + return date.toLocaleTimeString('en-US', { + timeZone: currentTimeZone, + hour: '2-digit', + minute: '2-digit', + second: '2-digit', + }); -} + } -function AreaGradient({ color, id }: { color: string; id: string }) { - return ( - - - - - - - ); -} + function AreaGradient({ color, id }: { color: string; id: string }) { + return ( + + + + + + + ); + } -function NoDataDisplay(props: any) { - return <> - {!props.isConnected ?
- - Connecting... - - -
: -
- - Connected, waiting for data... - + function NoDataDisplay(props: any) { + return <> + {!props.isConnected ?
+ + Connecting... + -
} - +
: +
+ + Connected, waiting for data... + + +
} + -} + } -function LinearChart(props: any) { + function LinearChart(props: any) { - const theme = useTheme(); + const theme = useTheme(); - const colorPalette = [ - theme.palette.primary.light, - theme.palette.primary.main, - theme.palette.primary.dark, - ]; + const colorPalette = [ + theme.palette.primary.light, + theme.palette.primary.main, + theme.palette.primary.dark, + ]; - const label: string = props.label || '--'; + const label: string = props.label || '--'; - return - formatDate(new Date(dp.timestamp)) - ), - tickInterval: (_index, i) => (i + 1) % (Math.floor(props.data.length/10) + 1) === 0, - }, - ]} - series={[ - { - id: 'direct', - label: label, - showMark: false, - curve: 'linear', - stack: 'total', - area: true, - stackOrder: 'ascending', - data: props.data.map( (dp:DataPoint) => dp.value), - } - ]} - height={175} - margin={{ left: 50, right: 20, top: 20, bottom: 20 }} - grid={{ horizontal: true }} - sx={{ - '& .MuiAreaElement-series-organic': { - fill: "url('#organic')", - }, - '& .MuiAreaElement-series-referral': { - fill: "url('#referral')", - }, - '& .MuiAreaElement-series-direct': { - fill: "url('#direct')", - }, - }} - hideLegend - slotProps={{ - legend: { - }, - }} - > + const baseline: number = props.baseline || 0; - - -} + return + formatDate(new Date(dp.timestamp)) + ), + tickInterval: (_index, i) => (i + 1) % (Math.floor(props.data.length/10) + 1) === 0, + }, + ]} + series={[ + { + id: 'direct', + label: label, + showMark: false, + curve: 'linear', + stack: 'total', + area: true, + stackOrder: 'ascending', + data: props.data.map( (dp:DataPoint) => dp.value), + baseline: baseline + } + ]} + height={175} -export default function SessionsChart(props: any) { - - return ( - - - - {props.title} - - - - - { props.data.length < 2 ? "" : - } - + + + } + + export default function SessionsChart(props: any) { + + return ( + + + + {props.title} + + + + + + { props.data.length < 2 ? "" : + } {props.label} + + - - { props.data.length < 2 ? : - } + { props.data.length < 2 ? : + } - - - ); -} + + + ); + }