Skip to content

Commit

Permalink
Update panels structure
Browse files Browse the repository at this point in the history
  • Loading branch information
LeoMartinDev committed Dec 6, 2021
1 parent b9c851c commit bdadc0e
Show file tree
Hide file tree
Showing 25 changed files with 585 additions and 147 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
LOGGER_LEVEL=debug
MONITORING_INTERVAL=60000 # 1 minute
MONITORING_INTERVAL=120000 # 2 minutes
DATABASE_TYPE=sqlite

# DATABASE_HOST=
Expand Down
40 changes: 31 additions & 9 deletions client/App.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import * as React from 'react';

import { createTheme, CssBaseline, ThemeProvider, Typography, useMediaQuery } from '@mui/material';
import { Box } from '@mui/system';
import { createTheme, CssBaseline, ThemeProvider, useMediaQuery } from '@mui/material';
import PanelsPage from './pages/Panels';
import { getStats } from './api';

export function App() {
let timeoutId;
const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');

const theme = React.useMemo(
Expand All @@ -18,19 +17,42 @@ export function App() {
[prefersDarkMode],
);

const [stats, setStats] = React.useState([]);
const [state, setState] = React.useState({
stats: [],
units: {},
});

React.useEffect(async () => {
const response = await getStats();
// const fetchStats = async () => {
// const { stats, units } = await getStats();

setStats(response);
}, []);
// setState((prevState) => ({
// ...prevState,
// stats,
// units,
// }));
// };

// const pollStats = async () => {
// await fetchStats();

// timeoutId = setTimeout(async () => {
// pollStats();
// }, 120000);
// };

// React.useEffect(async () => {
// // pollStats();

// return () => {
// clearTimeout(timeoutId);
// };
// }, []);

return (
<React.StrictMode>
<ThemeProvider theme={theme}>
<CssBaseline />
<PanelsPage stats={stats} />
<PanelsPage stats={state.stats} units={state.units} />
</ThemeProvider>
</React.StrictMode>
);
Expand Down
33 changes: 24 additions & 9 deletions client/api.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,31 @@
import useSWR from "swr";

export {
useNetworkSpeedPanelData,
};

const BASE_URL = 'http://localhost:3000/api';

async function request({ path }) {
const fetchResult = await fetch(`${BASE_URL}/${path}`);
const response = await fetchResult.json();
const fetcher = async (url) => {
const response = await fetch(`${BASE_URL}/${url}`);

if (!response.ok) {
const error = new Error('An error occurred while fetching the data.')

if (fetchResult.ok) {
return response;
error.info = await response.json()
error.status = response.status
throw error
}

throw response;
}
return response.json()
};

function useNetworkSpeedPanelData(options) {
const { data, error } = useSWR(`panels/network-speed`, fetcher, options)

export function getStats() {
return request({ path: 'stats'});
return {
data,
error,
isLoading: !error && !data,
};
}
30 changes: 30 additions & 0 deletions client/modules/panels/DailyAveragePanel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import dayjs from 'dayjs';
import { Typography } from '@mui/material';
import AvTimer from '@mui/icons-material/AvTimer';
import Upload from '@mui/icons-material/Upload';
import Download from '@mui/icons-material/Download';

import Panel from "./Panel";
import { Box } from '@mui/system';

const getMeanMetric = ({ last24HoursStats, metricName }) =>
_.chain(last24HoursStats).meanBy(`metrics.${metricName}`).round(2).value() || undefined;

export default function NetworkSpeedsPanel({ stats, units }) {
const last24HoursStats = _.filter(stats, ({ date }) =>
dayjs(date).isAfter(dayjs().subtract(24, 'hours')));

const meanPing = getMeanMetric({ last24HoursStats, metricName: 'ping' });
const downloadPing = getMeanMetric({ last24HoursStats, metricName: 'download' });
const uploadPing = getMeanMetric({ last24HoursStats, metricName: 'upload' });

return (
<Panel title="Last 24 hours averages">
<Box sx={{ display: 'flex', flexDirection: 'column' }}>
<Box sx={{ display: 'inline-flex' }}><AvTimer /><Typography>Ping: {meanPing} {units?.ping}</Typography></Box>
<Box sx={{ display: 'inline-flex' }}><Download /><Typography>Download speed: {downloadPing} {units?.download}</Typography></Box>
<Box sx={{ display: 'inline-flex' }}><Upload /><Typography>Upload speed: {uploadPing} {units?.upload}</Typography></Box>
</Box>
</Panel>
);
}
181 changes: 181 additions & 0 deletions client/modules/panels/NetworkSpeedPanel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// import get from 'lodash/get';
// import capitalize from 'lodash/capitalize';
// import map from 'lodash/map';
// import { useEffect, useState } from "react";
// import { Line } from "react-chartjs-2";
// import { ToggleButton, ToggleButtonGroup } from '@mui/material';

// import { useNetworkSpeedPanelData } from "../../api";
// import Panel from "./Panel";

// export default function NetworkSpeedPanelContainer() {
// const {
// data,
// error,
// isLoading,
// } = useNetworkSpeedPanelData();

// return <NetworkSpeedPanel isLoading={isLoading} data={data} error={error} fetchData={fetchData} />;
// }

// function PeriodTypeToggleButton({ onChange, periodTypes, periodType }) {
// const formatPeriodType = ({ periodType }) => capitalize(periodType);

// return (
// <ToggleButtonGroup
// sx={{ flex: '1' }}
// size="small"
// value={periodType}
// exclusive
// onChange={onChange}
// >
// {map(periodTypes, (periodType) => <ToggleButton key={periodType} value={periodType}>{formatPeriodType({ periodType })}</ToggleButton>)}
// </ToggleButtonGroup>
// );
// }

// function NetworkSpeedPanel({ isLoading, data, fetchData }) {
// const [state, setState] = useState({
// labels: undefined,
// stats: undefined,
// metricsLabels: undefined,
// periodTypes: undefined,
// periodType: undefined,
// chartjsData: undefined,
// });

// const getDataset = ({ metricName, color, stats, metricsLabels }) => ({
// label: metricsLabels?.[metricName],
// data: stats?.[metricName],
// fill: false,
// borderColor: color,
// tension: 0.1,
// });

// useEffect(() => {
// if (!data) {
// return;
// }

// const labels = get(data, 'periods');
// const stats = get(data, 'data');
// const metricsLabels = get(data, 'metricsLabels');

// setState({
// labels,
// stats,
// metricsLabels,
// periodTypes: get(data, 'periodTypes'),
// periodType: get(data, 'periodType'),
// chartjsData: {
// labels,
// datasets: [
// getDataset({ metricName: 'download', color: '#4caf50', stats, metricsLabels }),
// getDataset({ metricName: 'upload', color: '#f50057', stats, metricsLabels }),
// getDataset({ metricName: 'ping', color: '#2196f3', stats, metricsLabels }),
// ],
// },
// });
// }, [isLoading]);

// const onPeriodTypeChange = (_event, newPeriodType) => {
// setState((prevState) => ({ ...prevState, periodType: newPeriodType }));

// fetchData({ periodType: newPeriodType });
// };

// return (
// <Panel
// title="Speeds"
// isLoading={isLoading}
// header={
// <PeriodTypeToggleButton onChange={onPeriodTypeChange} periodType={state.periodType} periodTypes={state.periodTypes} />
// }
// >
// {state.chartjsData ? <Line data={state.chartjsData} /> : null}
// </Panel>
// );
// }

import get from 'lodash/get';
import capitalize from 'lodash/capitalize';
import map from 'lodash/map';
import { useEffect, useState } from "react";
import { Line } from "react-chartjs-2";
import { ToggleButton, ToggleButtonGroup } from '@mui/material';

import { useNetworkSpeedPanelData } from "../../api";
import Panel from "./Panel";

function PeriodTypeToggleButton({ onChange, periodTypes, periodType }) {
const formatPeriodType = ({ periodType }) => capitalize(periodType);

return (
<ToggleButtonGroup
sx={{ flex: '1' }}
size="small"
value={periodType}
exclusive
onChange={onChange}
>
{map(periodTypes, (periodType) => <ToggleButton key={periodType} value={periodType}>{formatPeriodType({ periodType })}</ToggleButton>)}
</ToggleButtonGroup>
);
}

export default function NetworkSpeedPanel() {
const {
data,
error,
isLoading,
} = useNetworkSpeedPanelData({
refreshInterval: 60 * 1000,
});

const getDataset = ({ metricName, color, stats, metricsLabels }) => ({
label: metricsLabels?.[metricName],
data: stats?.[metricName],
fill: false,
borderColor: color,
tension: 0.1,
});

const labels = get(data, 'periods');
const stats = get(data, 'data');
const metricsLabels = get(data, 'metricsLabels');
const periodTypes = get(data, 'periodTypes');
const [periodType, setPeriodType] = useState(get(data, 'periodType'));
const chartjsData = {
labels,
datasets: [
getDataset({ metricName: 'download', color: '#4caf50', stats, metricsLabels }),
getDataset({ metricName: 'upload', color: '#f50057', stats, metricsLabels }),
getDataset({ metricName: 'ping', color: '#2196f3', stats, metricsLabels }),
],
};

const onPeriodTypeChange = (_event, newPeriodType) => {
setPeriodType(newPeriodType);
};

if (isLoading) {
return (
<Panel
title="Speeds"
isLoading={isLoading}
/>
);
}

return (
<Panel
title="Speeds"
isLoading={isLoading}
header={
<PeriodTypeToggleButton onChange={onPeriodTypeChange} periodType={periodType} periodTypes={periodTypes} />
}
>
<Line data={chartjsData} />
</Panel>
);
}
41 changes: 0 additions & 41 deletions client/modules/panels/NetworkSpeedsPanel.jsx

This file was deleted.

Loading

0 comments on commit bdadc0e

Please sign in to comment.