diff --git a/public/locales/en/common.json b/public/locales/en/common.json
index b725132a..7f1a86de 100755
--- a/public/locales/en/common.json
+++ b/public/locales/en/common.json
@@ -357,10 +357,14 @@
},
"glances": {
"cpu": "CPU",
- "mem": "MEM",
+ "load": "Load",
"wait": "Please wait",
"temp": "TEMP",
+ "warn": "Warn",
"uptime": "UP",
+ "total": "Total",
+ "free": "Free",
+ "used": "Used",
"days": "d",
"hours": "h"
},
diff --git a/src/components/widgets/glances/glances.jsx b/src/components/widgets/glances/glances.jsx
index fc0d21ed..85dd44c0 100644
--- a/src/components/widgets/glances/glances.jsx
+++ b/src/components/widgets/glances/glances.jsx
@@ -1,11 +1,14 @@
import useSWR from "swr";
+import { useContext } from "react";
import { BiError } from "react-icons/bi";
import { FaMemory, FaRegClock, FaThermometerHalf } from "react-icons/fa";
-import { FiCpu } from "react-icons/fi";
+import { FiCpu, FiHardDrive } from "react-icons/fi";
import { useTranslation } from "next-i18next";
import UsageBar from "../resources/usage-bar";
+import { SettingsContext } from "utils/contexts/settings";
+
const cpuSensorLabels = ["cpu_thermal", "Core", "Tctl"];
function convertToFahrenheit(t) {
@@ -14,6 +17,7 @@ function convertToFahrenheit(t) {
export default function Widget({ options }) {
const { t, i18n } = useTranslation();
+ const { settings } = useContext(SettingsContext);
const { data, error } = useSWR(
`/api/widgets/glances?${new URLSearchParams({ lang: i18n.language, ...options }).toString()}`, {
@@ -88,8 +92,16 @@ export default function Widget({ options }) {
}
const tempPercent = Math.round((mainTemp / maxTemp) * 100);
+ let disks = [];
+
+ if (options.disk) {
+ disks = Array.isArray(options.disk)
+ ? options.disk.map((disk) => data.fs.find((d) => d.mnt_point === disk)).filter((d) => d)
+ : [data.fs.find((d) => d.mnt_point === options.disk)].filter((d) => d);
+ }
+
return (
-
+
@@ -97,7 +109,7 @@ export default function Widget({ options }) {
{t("common.number", {
- value: data.quicklook.cpu,
+ value: data.cpu.total,
style: "unit",
unit: "percent",
maximumFractionDigits: 0,
@@ -105,7 +117,20 @@ export default function Widget({ options }) {
{t("glances.cpu")}
-
+ {options.expanded && (
+
+
+ {t("common.number", {
+ value: data.load.min15,
+ style: "unit",
+ unit: "percent",
+ maximumFractionDigits: 0,
+ })}
+
+ {t("glances.load")}
+
+ )}
+
@@ -113,18 +138,46 @@ export default function Widget({ options }) {
- {t("common.number", {
- value: data.quicklook.mem,
- style: "unit",
- unit: "percent",
- maximumFractionDigits: 0,
+ {t("common.bytes", {
+ value: data.mem.free,
+ maximumFractionDigits: 1,
+ binary: true,
})}
-
{t("glances.mem")}
+
{t("glances.free")}
-
+ {options.expanded && (
+
+
+ {t("common.bytes", {
+ value: data.mem.total,
+ maximumFractionDigits: 1,
+ binary: true,
+ })}
+
+ {t("glances.total")}
+
+ )}
+
+ {disks.map((disk) => (
+
+
+
+
+ {t("common.bytes", { value: disk.free })}
+ {t("glances.free")}
+
+ {options.expanded && (
+
+ {t("common.bytes", { value: disk.size })}
+ {t("glances.total")}
+
+ )}
+
+
+
))}
{options.cputemp && mainTemp > 0 &&
(
@@ -140,6 +193,19 @@ export default function Widget({ options }) {
{t("glances.temp")}
+ {options.expanded && (
+
+
+ {t("common.number", {
+ value: maxTemp,
+ maximumFractionDigits: 1,
+ style: "unit",
+ unit
+ })}
+
+ {t("glances.warn")}
+
+ )}
)}
@@ -160,6 +226,6 @@ export default function Widget({ options }) {
{options.label && (
{options.label}
)}
-
+
);
}
diff --git a/src/pages/api/widgets/glances.js b/src/pages/api/widgets/glances.js
index 46be14a0..7605144d 100644
--- a/src/pages/api/widgets/glances.js
+++ b/src/pages/api/widgets/glances.js
@@ -40,20 +40,32 @@ async function retrieveFromGlancesAPI(privateWidgetOptions, endpoint) {
}
export default async function handler(req, res) {
- const { index } = req.query;
+ const { index, cputemp: includeCpuTemp, uptime: includeUptime, disk: includeDisks } = req.query;
const privateWidgetOptions = await getPrivateWidgetOptions("glances", index);
try {
- const quicklookData = await retrieveFromGlancesAPI(privateWidgetOptions, "quicklook");
-
+ const cpuData = await retrieveFromGlancesAPI(privateWidgetOptions, "cpu");
+ const loadData = await retrieveFromGlancesAPI(privateWidgetOptions, "load");
+ const memoryData = await retrieveFromGlancesAPI(privateWidgetOptions, "mem");
const data = {
- quicklook: quicklookData
+ cpu: cpuData,
+ load: loadData,
+ mem: memoryData,
+ }
+
+ // Disabled by default, dont call unless needed
+ if (includeUptime) {
+ data.uptime = await retrieveFromGlancesAPI(privateWidgetOptions, "uptime");
+ }
+
+ if (includeCpuTemp) {
+ data.sensors = await retrieveFromGlancesAPI(privateWidgetOptions, "sensors");
+ }
+
+ if (includeDisks) {
+ data.fs = await retrieveFromGlancesAPI(privateWidgetOptions, "fs");
}
-
- data.uptime = await retrieveFromGlancesAPI(privateWidgetOptions, "uptime");
-
- data.sensors = await retrieveFromGlancesAPI(privateWidgetOptions, "sensors");
return res.status(200).send(data);
} catch (e) {
diff --git a/src/utils/config/widget-helpers.js b/src/utils/config/widget-helpers.js
index c03bd906..6f61b7e2 100644
--- a/src/utils/config/widget-helpers.js
+++ b/src/utils/config/widget-helpers.js
@@ -5,8 +5,6 @@ import yaml from "js-yaml";
import checkAndCopyConfig, { substituteEnvironmentVars } from "utils/config/config";
-const exemptWidgets = ["search"];
-
export async function widgetsFromConfig() {
checkAndCopyConfig("widgets.yaml");
@@ -32,15 +30,17 @@ export async function cleanWidgetGroups(widgets) {
return widgets.map((widget, index) => {
const sanitizedOptions = widget.options;
const optionKeys = Object.keys(sanitizedOptions);
- if (!exemptWidgets.includes(widget.type)) {
- ["url", "username", "password", "key"].forEach((pO) => {
- if (optionKeys.includes(pO)) {
- // allow URL in search
- if (widget.type !== "search" && pO !== "key") {
- delete sanitizedOptions[pO];
- }
- }
- });
+
+ // delete private options from the sanitized options
+ ["username", "password", "key"].forEach((pO) => {
+ if (optionKeys.includes(pO)) {
+ delete sanitizedOptions[pO];
+ }
+ });
+
+ // delete url from the sanitized options if the widget is not a search or glances widgeth
+ if (widget.type !== "search" && widget.type !== "glances" && optionKeys.includes("url")) {
+ delete sanitizedOptions.url;
}
return {
@@ -78,4 +78,4 @@ export async function getPrivateWidgetOptions(type, widgetIndex) {
});
return (type !== undefined && widgetIndex !== undefined) ? privateOptions.find(o => o.type === type && o.options.index === parseInt(widgetIndex, 10))?.options : privateOptions;
-}
\ No newline at end of file
+}