Merge branch 'benphelps:main' into add-whatsupdocker-widget
This commit is contained in:
commit
d2ea719cc8
@ -18,13 +18,13 @@
|
||||
"load": "Carga",
|
||||
"cpu": "CPU",
|
||||
"mem": "MEM",
|
||||
"temp": "TEMP",
|
||||
"max": "Max",
|
||||
"uptime": "UP",
|
||||
"months": "mo",
|
||||
"days": "d",
|
||||
"hours": "h",
|
||||
"minutes": "m"
|
||||
"temp": "TEMPORAL",
|
||||
"max": "Máximo",
|
||||
"uptime": "ARRIBA",
|
||||
"months": "Meses",
|
||||
"days": "Días",
|
||||
"hours": "Horas",
|
||||
"minutes": "Minutos"
|
||||
},
|
||||
"docker": {
|
||||
"rx": "Recibido",
|
||||
@ -234,10 +234,10 @@
|
||||
"cpu": "Procesador",
|
||||
"mem": "Memoria",
|
||||
"wait": "Espere por favor",
|
||||
"temp": "TEMP",
|
||||
"uptime": "UP",
|
||||
"days": "d",
|
||||
"hours": "h"
|
||||
"temp": "TEMPORAL",
|
||||
"uptime": "ARRIBA",
|
||||
"days": "Días",
|
||||
"hours": "Horas"
|
||||
},
|
||||
"changedetectionio": {
|
||||
"totalObserved": "Total Observados",
|
||||
|
||||
@ -42,13 +42,13 @@
|
||||
"free": "남음",
|
||||
"used": "사용",
|
||||
"load": "부하",
|
||||
"temp": "TEMP",
|
||||
"max": "Max",
|
||||
"uptime": "UP",
|
||||
"months": "mo",
|
||||
"days": "d",
|
||||
"hours": "h",
|
||||
"minutes": "m"
|
||||
"temp": "온도",
|
||||
"max": "최대",
|
||||
"uptime": "가동",
|
||||
"months": "달",
|
||||
"days": "일",
|
||||
"hours": "시간",
|
||||
"minutes": "분"
|
||||
},
|
||||
"unifi": {
|
||||
"users": "사용자",
|
||||
|
||||
@ -131,11 +131,11 @@
|
||||
"mem": "Пам'ять",
|
||||
"temp": "TEMP",
|
||||
"max": "Max",
|
||||
"uptime": "UP",
|
||||
"months": "mo",
|
||||
"days": "d",
|
||||
"hours": "h",
|
||||
"minutes": "m"
|
||||
"uptime": "Відправка",
|
||||
"months": "міс",
|
||||
"days": "д",
|
||||
"hours": "г",
|
||||
"minutes": "хв"
|
||||
},
|
||||
"unifi": {
|
||||
"users": "Користувачі",
|
||||
@ -359,9 +359,9 @@
|
||||
"mem": "Пам'ять",
|
||||
"wait": "Будь ласка, зачекайте",
|
||||
"temp": "TEMP",
|
||||
"uptime": "UP",
|
||||
"days": "d",
|
||||
"hours": "h"
|
||||
"uptime": "Відправка",
|
||||
"days": "д",
|
||||
"hours": "г"
|
||||
},
|
||||
"quicklaunch": {
|
||||
"bookmark": "Закладка",
|
||||
|
||||
@ -18,13 +18,13 @@
|
||||
"load": "负载",
|
||||
"cpu": "处理器",
|
||||
"mem": "内存",
|
||||
"temp": "TEMP",
|
||||
"max": "Max",
|
||||
"uptime": "UP",
|
||||
"months": "mo",
|
||||
"days": "d",
|
||||
"hours": "h",
|
||||
"minutes": "m"
|
||||
"temp": "温度",
|
||||
"max": "最大",
|
||||
"uptime": "运行时间",
|
||||
"months": "月",
|
||||
"days": "天",
|
||||
"hours": "时",
|
||||
"minutes": "分"
|
||||
},
|
||||
"docker": {
|
||||
"rx": "接收",
|
||||
@ -236,8 +236,8 @@
|
||||
"wait": "请稍等",
|
||||
"temp": "TEMP",
|
||||
"uptime": "UP",
|
||||
"days": "d",
|
||||
"hours": "h"
|
||||
"days": "天",
|
||||
"hours": "时"
|
||||
},
|
||||
"changedetectionio": {
|
||||
"totalObserved": "观察到的总数",
|
||||
|
||||
@ -6,6 +6,12 @@ import { useTranslation } from "next-i18next";
|
||||
|
||||
import UsageBar from "../resources/usage-bar";
|
||||
|
||||
const cpuSensorLabels = ["cpu_thermal", "Core"];
|
||||
|
||||
function convertToFahrenheit(t) {
|
||||
return t * 9/5 + 32
|
||||
}
|
||||
|
||||
export default function Widget({ options }) {
|
||||
const { t, i18n } = useTranslation();
|
||||
|
||||
@ -65,10 +71,22 @@ export default function Widget({ options }) {
|
||||
}
|
||||
|
||||
const unit = options.units === "imperial" ? "fahrenheit" : "celsius";
|
||||
let mainTemp;
|
||||
if (options.cputemp && data.sensors) {
|
||||
mainTemp = unit === "celsius" ? data.sensors.find(s => s.label.includes("cpu_thermal")).value : data.sensors.find(s => s.label.includes("cpu_thermal")).value * 5/9 + 32;
|
||||
let mainTemp = 0;
|
||||
let maxTemp = 80;
|
||||
const cpuSensors = data.sensors?.filter(s => cpuSensorLabels.some(label => s.label.startsWith(label)) && s.type === "temperature_core");
|
||||
if (options.cputemp && cpuSensors) {
|
||||
try {
|
||||
mainTemp = cpuSensors.reduce((acc, s) => acc + s.value, 0) / cpuSensors.length;
|
||||
maxTemp = Math.max(cpuSensors.reduce((acc, s) => acc + s.warning, 0) / cpuSensors.length, maxTemp);
|
||||
if (unit === "fahrenheit") {
|
||||
mainTemp = convertToFahrenheit(mainTemp);
|
||||
maxTemp = convertToFahrenheit(maxTemp);
|
||||
}
|
||||
} catch (e) {
|
||||
// cpu sensor retrieval failed
|
||||
}
|
||||
}
|
||||
const tempPercent = Math.round((mainTemp / maxTemp) * 100);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col max-w:full sm:basis-auto self-center grow-0 flex-wrap ml-4">
|
||||
@ -107,7 +125,7 @@ export default function Widget({ options }) {
|
||||
<UsageBar percent={data.quicklook.mem} />
|
||||
</div>
|
||||
</div>
|
||||
{options.cputemp && mainTemp &&
|
||||
{options.cputemp && mainTemp > 0 &&
|
||||
(<div className="flex-none flex flex-row items-center mr-3 py-1.5">
|
||||
<FaThermometerHalf className="text-theme-800 dark:text-theme-200 w-5 h-5" />
|
||||
<div className="flex flex-col ml-3 text-left min-w-[85px]">
|
||||
@ -122,6 +140,7 @@ export default function Widget({ options }) {
|
||||
</div>
|
||||
<div className="pr-1">{t("glances.temp")}</div>
|
||||
</span>
|
||||
<UsageBar percent={tempPercent} />
|
||||
</div>
|
||||
</div>)}
|
||||
{options.uptime && data.uptime &&
|
||||
@ -134,6 +153,7 @@ export default function Widget({ options }) {
|
||||
</div>
|
||||
<div className="pr-1">{t("glances.uptime")}</div>
|
||||
</span>
|
||||
<UsageBar percent={Math.round((new Date().getSeconds() / 60) * 100)} />
|
||||
</div>
|
||||
</div>)}
|
||||
</div>
|
||||
|
||||
@ -3,6 +3,12 @@ import { FaThermometerHalf } from "react-icons/fa";
|
||||
import { BiError } from "react-icons/bi";
|
||||
import { useTranslation } from "next-i18next";
|
||||
|
||||
import UsageBar from "./usage-bar";
|
||||
|
||||
function convertToFahrenheit(t) {
|
||||
return t * 9/5 + 32
|
||||
}
|
||||
|
||||
export default function CpuTemp({ expanded, units }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -21,7 +27,7 @@ export default function CpuTemp({ expanded, units }) {
|
||||
);
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
if (!data || !data.cputemp) {
|
||||
return (
|
||||
<div className="flex-none flex flex-row items-center mr-3 py-1.5 animate-pulse">
|
||||
<FaThermometerHalf className="text-theme-800 dark:text-theme-200 w-5 h-5" />
|
||||
@ -41,9 +47,16 @@ export default function CpuTemp({ expanded, units }) {
|
||||
);
|
||||
}
|
||||
|
||||
let minTemp = 0;
|
||||
let mainTemp = data.cputemp.main;
|
||||
if (data.cputemp.cores?.length) {
|
||||
mainTemp = data.cputemp.cores.reduce((a, b) => a + b) / data.cputemp.cores.length;
|
||||
minTemp = Math.min(...data.cputemp.cores);
|
||||
}
|
||||
const unit = units === "imperial" ? "fahrenheit" : "celsius";
|
||||
const mainTemp = (unit === "celsius") ? data.cputemp.main : data.cputemp.main * 5/9 + 32;
|
||||
const maxTemp = (unit === "celsius") ? data.cputemp.max : data.cputemp.max * 5/9 + 32;
|
||||
mainTemp = (unit === "celsius") ? mainTemp : convertToFahrenheit(mainTemp);
|
||||
const maxTemp = (unit === "celsius") ? data.cputemp.max : convertToFahrenheit(data.cputemp.max);
|
||||
const percent = Math.round(((mainTemp - minTemp) / (maxTemp - minTemp)) * 100);
|
||||
|
||||
return (
|
||||
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
|
||||
@ -73,6 +86,7 @@ export default function CpuTemp({ expanded, units }) {
|
||||
<div className="pr-1">{t("resources.max")}</div>
|
||||
</span>
|
||||
)}
|
||||
<UsageBar percent={percent} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -44,7 +44,8 @@ export default function Disk({ options, expanded }) {
|
||||
);
|
||||
}
|
||||
|
||||
const percent = Math.round((data.drive.used / data.drive.size) * 100);
|
||||
// data.drive.used not accurate?
|
||||
const percent = Math.round(((data.drive.size - data.drive.available) / data.drive.size) * 100);
|
||||
|
||||
return (
|
||||
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
|
||||
|
||||
@ -44,7 +44,7 @@ export default function Memory({ expanded }) {
|
||||
);
|
||||
}
|
||||
|
||||
const percent = Math.round((data.memory.used / data.memory.total) * 100);
|
||||
const percent = Math.round((data.memory.active / data.memory.total) * 100);
|
||||
|
||||
return (
|
||||
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
|
||||
@ -52,7 +52,7 @@ export default function Memory({ expanded }) {
|
||||
<div className="flex flex-col ml-3 text-left min-w-[85px]">
|
||||
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
|
||||
<div className="pl-0.5 pr-1">
|
||||
{t("common.bytes", { value: data.memory.free, maximumFractionDigits: 1, binary: true })}
|
||||
{t("common.bytes", { value: data.memory.available, maximumFractionDigits: 1, binary: true })}
|
||||
</div>
|
||||
<div className="pr-1">{t("resources.free")}</div>
|
||||
</span>
|
||||
|
||||
@ -3,6 +3,8 @@ import { FaRegClock } from "react-icons/fa";
|
||||
import { BiError } from "react-icons/bi";
|
||||
import { useTranslation } from "next-i18next";
|
||||
|
||||
import UsageBar from "./usage-bar";
|
||||
|
||||
export default function Uptime() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@ -45,6 +47,8 @@ export default function Uptime() {
|
||||
else if (d > 0) uptime = `${d}${t("resources.days")} ${h}${t("resources.hours")}`;
|
||||
else uptime = `${h}${t("resources.hours")} ${m}${t("resources.minutes")}`;
|
||||
|
||||
const percent = Math.round((new Date().getSeconds() / 60) * 100);
|
||||
|
||||
return (
|
||||
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
|
||||
<FaRegClock className="text-theme-800 dark:text-theme-200 w-5 h-5" />
|
||||
@ -55,6 +59,7 @@ export default function Uptime() {
|
||||
</div>
|
||||
<div className="pr-1">{t("resources.uptime")}</div>
|
||||
</span>
|
||||
<UsageBar percent={percent} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -30,7 +30,7 @@ export default async function handler(req, res) {
|
||||
});
|
||||
}
|
||||
|
||||
const containerNames = containers.map((container) => container.Names[0].replace(/^\//, ""));
|
||||
const containerNames = containers.map((container) => container.Names[0]?.replace(/^\//, ""));
|
||||
const containerExists = containerNames.includes(containerName);
|
||||
|
||||
if (containerExists) {
|
||||
@ -75,7 +75,7 @@ export default async function handler(req, res) {
|
||||
}
|
||||
}
|
||||
|
||||
return res.status(200).send({
|
||||
return res.status(404).send({
|
||||
error: "not found",
|
||||
});
|
||||
} catch (e) {
|
||||
|
||||
@ -30,7 +30,7 @@ export default async function handler(req, res) {
|
||||
});
|
||||
}
|
||||
|
||||
const containerNames = containers.map((container) => container.Names[0].replace(/^\//, ""));
|
||||
const containerNames = containers.map((container) => container.Names[0]?.replace(/^\//, ""));
|
||||
const containerExists = containerNames.includes(containerName);
|
||||
|
||||
if (containerExists) {
|
||||
|
||||
@ -249,7 +249,8 @@ export function cleanServiceGroups(groups) {
|
||||
podSelector,
|
||||
wan, // opnsense widget,
|
||||
enableBlocks, // emby/jellyfin
|
||||
enableNowPlaying
|
||||
enableNowPlaying,
|
||||
volume // diskstation widget
|
||||
} = cleanedService.widget;
|
||||
|
||||
const fieldsList = typeof fields === 'string' ? JSON.parse(fields) : fields;
|
||||
@ -281,8 +282,11 @@ export function cleanServiceGroups(groups) {
|
||||
if (wan) cleanedService.widget.wan = wan;
|
||||
}
|
||||
if (type === "emby" || type === "jellyfin") {
|
||||
if (enableBlocks) cleanedService.widget.enableBlocks = enableBlocks === 'true';
|
||||
if (enableNowPlaying) cleanedService.widget.enableNowPlaying = enableNowPlaying === 'true';
|
||||
if (enableBlocks) cleanedService.widget.enableBlocks = enableBlocks;
|
||||
if (enableNowPlaying) cleanedService.widget.enableNowPlaying = enableNowPlaying;
|
||||
}
|
||||
if (type === "diskstation") {
|
||||
if (volume) cleanedService.widget.volume = volume;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -33,8 +33,7 @@ export default function Component({ service }) {
|
||||
const uptime = `${ t("common.number", { value: days }) } ${ t("diskstation.days") }`;
|
||||
|
||||
// storage info
|
||||
// TODO: figure out how to display info for more than one volume
|
||||
const volume = storageData.data.vol_info?.[0];
|
||||
const volume = widget.volume ? storageData.data.vol_info?.find(vol => vol.name === widget.volume) : storageData.data.vol_info?.[0];
|
||||
const usedBytes = parseFloat(volume?.used_size);
|
||||
const totalBytes = parseFloat(volume?.total_size);
|
||||
const freeBytes = totalBytes - usedBytes;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user