From b61ec9836efc2cf5576f249cabcca4d5fd45f03d Mon Sep 17 00:00:00 2001 From: Ben Phelps Date: Sat, 27 Aug 2022 00:55:13 +0300 Subject: [PATCH] refactor information widgets --- src/components/widgets/resources/cpu.jsx | 45 ++++++++ src/components/widgets/resources/disk.jsx | 48 ++++++++ src/components/widgets/resources/memory.jsx | 48 ++++++++ .../widgets/resources/resources.jsx | 106 +++--------------- src/components/widgets/weather/weather.jsx | 23 ++-- src/pages/api/docker/stats/[...service].js | 6 +- src/pages/api/docker/status/[...service].js | 6 +- src/pages/api/widgets/resources.js | 30 +++-- src/pages/index.js | 14 ++- src/utils/stats-helpers.js | 2 +- 10 files changed, 208 insertions(+), 120 deletions(-) create mode 100644 src/components/widgets/resources/cpu.jsx create mode 100644 src/components/widgets/resources/disk.jsx create mode 100644 src/components/widgets/resources/memory.jsx diff --git a/src/components/widgets/resources/cpu.jsx b/src/components/widgets/resources/cpu.jsx new file mode 100644 index 000000000..36bda7435 --- /dev/null +++ b/src/components/widgets/resources/cpu.jsx @@ -0,0 +1,45 @@ +import useSWR from "swr"; +import { FiCpu } from "react-icons/fi"; +import { BiError } from "react-icons/bi"; + +export default function Cpu() { + const { data, error } = useSWR(`/api/widgets/resources?type=cpu`, { + refreshInterval: 1500, + }); + + if (error || data?.error) { + return ( +
+ +
+ Resources + Error +
+
+ ); + } + + if (!data) { + return ( +
+ +
+ - Usage + - Load +
+
+ ); + } + + return ( +
+ +
+ {Math.round(data.cpu.usage)}% Usage + + {(Math.round(data.cpu.load * 100) / 100).toFixed(1)} Load + +
+
+ ); +} diff --git a/src/components/widgets/resources/disk.jsx b/src/components/widgets/resources/disk.jsx new file mode 100644 index 000000000..e181c6044 --- /dev/null +++ b/src/components/widgets/resources/disk.jsx @@ -0,0 +1,48 @@ +import useSWR from "swr"; +import { FiHardDrive } from "react-icons/fi"; +import { BiError } from "react-icons/bi"; +import { formatBytes } from "utils/stats-helpers"; + +export default function Disk({ options }) { + const { data, error } = useSWR(`/api/widgets/resources?type=disk&target=${options.disk}`, { + refreshInterval: 1500, + }); + + if (error || data?.error) { + return ( +
+ +
+ Resources + Error +
+
+ ); + } + + if (!data) { + return ( +
+ +
+ - Free + - Used +
+
+ ); + } + + return ( +
+ +
+ + {formatBytes(data.drive.freeGb * 1024 * 1024 * 1024)} Free + + + {formatBytes(data.drive.usedGb * 1024 * 1024 * 1024)} Used + +
+
+ ); +} diff --git a/src/components/widgets/resources/memory.jsx b/src/components/widgets/resources/memory.jsx new file mode 100644 index 000000000..9f2b341c2 --- /dev/null +++ b/src/components/widgets/resources/memory.jsx @@ -0,0 +1,48 @@ +import useSWR from "swr"; +import { FaMemory } from "react-icons/fa"; +import { BiError } from "react-icons/bi"; +import { formatBytes } from "utils/stats-helpers"; + +export default function Memory() { + const { data, error } = useSWR(`/api/widgets/resources?type=memory`, { + refreshInterval: 1500, + }); + + if (error || data?.error) { + return ( +
+ +
+ Resources + Error +
+
+ ); + } + + if (!data) { + return ( +
+ +
+ - GB Used + - GB Free +
+
+ ); + } + + return ( +
+ +
+ + {formatBytes(data.memory.usedMemMb * 1024 * 1024)} Used + + + {formatBytes(data.memory.freeMemMb * 1024 * 1024)} Free + +
+
+ ); +} diff --git a/src/components/widgets/resources/resources.jsx b/src/components/widgets/resources/resources.jsx index 5b54d7b98..1509dc9e3 100644 --- a/src/components/widgets/resources/resources.jsx +++ b/src/components/widgets/resources/resources.jsx @@ -1,102 +1,22 @@ -import useSWR from "swr"; -import { FiHardDrive, FiCpu } from "react-icons/fi"; -import { FaMemory } from "react-icons/fa"; -import { BiError } from "react-icons/bi"; +import Disk from "./disk"; +import Cpu from "./cpu"; +import Memory from "./memory"; export default function Resources({ options }) { - const { data, error } = useSWR(`/api/widgets/resources?disk=${options.disk}`, { - refreshInterval: 1500, - }); - - if (error) { - return ( -
- -
- Resources - Error -
-
- ); - } - - if (!data) { - return ( - <> - {options.disk && ( -
- -
- - GB free - - GB used -
-
- )} - - {options.cpu && ( -
- -
- - Usage - - Load -
-
- )} - - {options.memory && ( -
- -
- - GB Used - - GB Free -
-
- )} - - ); - } - - if (data.error) { - return
; - } - return ( <> - {options.disk && ( -
- -
- {Math.round(data.drive.freeGb)} GB free - {Math.round(data.drive.usedGb)} GB used -
+
+
+ {options.disk && } + {options.cpu && } + {options.memory && }
- )} - - {options.cpu && ( -
- -
- {Math.round(data.cpu.usage)}% Usage - - {Math.round(data.cpu.load * 100) / 100} Load - + {options.label && ( +
+ {options.label}
-
- )} - - {options.memory && ( -
- -
- - {Math.round((data.memory.usedMemMb / 1024) * 100) / 100} GB Used - - - {Math.round((data.memory.freeMemMb / 1024) * 100) / 100} GB Free - -
-
- )} + )} +
); } diff --git a/src/components/widgets/weather/weather.jsx b/src/components/widgets/weather/weather.jsx index 0308932dd..7a606469f 100644 --- a/src/components/widgets/weather/weather.jsx +++ b/src/components/widgets/weather/weather.jsx @@ -10,7 +10,7 @@ export default function Weather({ options }) { if (error) { return ( -
+
API @@ -21,22 +21,25 @@ export default function Weather({ options }) { } if (!data) { - return
; + return
; } if (data.error) { - return
; + return
; } return ( -
- -
- - {options.units === "metric" ? data.current.temp_c : data.current.temp_f}° - - {data.current.condition.text} +
+
+ +
+ + {options.units === "metric" ? data.current.temp_c : data.current.temp_f}° + + {data.current.condition.text} +
+ {options.label &&
{options.label}
}
); } diff --git a/src/pages/api/docker/stats/[...service].js b/src/pages/api/docker/stats/[...service].js index af6a1a3b8..34f387b76 100644 --- a/src/pages/api/docker/stats/[...service].js +++ b/src/pages/api/docker/stats/[...service].js @@ -14,7 +14,9 @@ export default async function handler(req, res) { try { const docker = new Docker(await getDockerArguments(containerServer)); - const containers = await docker.listContainers(); + const containers = await docker.listContainers({ + all: true, + }); // bad docker connections can result in a object? // in any case, this ensures the result is the expected array @@ -30,7 +32,7 @@ export default async function handler(req, res) { const containerExists = containerNames.includes(containerName); if (!containerExists) { - return res.status(404).send({ + return res.status(200).send({ error: "not found", }); } diff --git a/src/pages/api/docker/status/[...service].js b/src/pages/api/docker/status/[...service].js index a0c8cd5aa..d59fffd7b 100644 --- a/src/pages/api/docker/status/[...service].js +++ b/src/pages/api/docker/status/[...service].js @@ -13,7 +13,9 @@ export default async function handler(req, res) { try { const docker = new Docker(await getDockerArguments(containerServer)); - const containers = await docker.listContainers(); + const containers = await docker.listContainers({ + all: true, + }); // bad docker connections can result in a object? // in any case, this ensures the result is the expected array @@ -29,7 +31,7 @@ export default async function handler(req, res) { const containerExists = containerNames.includes(containerName); if (!containerExists) { - return res.status(404).send({ + return res.status(200).send({ error: "not found", }); } diff --git a/src/pages/api/widgets/resources.js b/src/pages/api/widgets/resources.js index 528f50fdb..f9e51b195 100644 --- a/src/pages/api/widgets/resources.js +++ b/src/pages/api/widgets/resources.js @@ -1,14 +1,26 @@ import { cpu, drive, mem, netstat } from "node-os-utils"; export default async function handler(req, res) { - const { disk } = req.query; + const { type, target } = req.query; - res.send({ - cpu: { - usage: await cpu.usage(), - load: cpu.loadavgTime(5), - }, - drive: await drive.info(disk || "/"), - memory: await mem.info(), - }); + if (type == "cpu") { + return res.status(200).json({ + cpu: { + usage: await cpu.usage(1000), + load: cpu.loadavgTime(5), + }, + }); + } else if (type == "disk") { + return res.status(200).json({ + drive: await drive.info(target || "/"), + }); + } else if (type == "memory") { + return res.status(200).json({ + memory: await mem.info(), + }); + } else { + return res.status(400).json({ + error: "invalid type", + }); + } } diff --git a/src/pages/index.js b/src/pages/index.js index 858850317..6910f9624 100644 --- a/src/pages/index.js +++ b/src/pages/index.js @@ -32,9 +32,17 @@ export default function Home() {
{widgets && ( <> - {widgets.map((widget) => ( - - ))} + {widgets + .filter((widget) => widget.type !== "weather") + .map((widget, i) => ( + + ))} +
+ {widgets + .filter((widget) => widget.type === "weather") + .map((widget, i) => ( + + ))} )}
diff --git a/src/utils/stats-helpers.js b/src/utils/stats-helpers.js index eba5b05d2..281c36d05 100644 --- a/src/utils/stats-helpers.js +++ b/src/utils/stats-helpers.js @@ -19,5 +19,5 @@ export function formatBytes(bytes, decimals = 2) { const i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; + return parseFloat(bytes / Math.pow(k, i)).toFixed(dm) + " " + sizes[i]; }