diff --git a/src/components/widgets/glances/glances.jsx b/src/components/widgets/glances/glances.jsx index debb09c7..b45dfefe 100644 --- a/src/components/widgets/glances/glances.jsx +++ b/src/components/widgets/glances/glances.jsx @@ -4,12 +4,8 @@ import { FaMemory, FaRegClock, FaThermometerHalf } from "react-icons/fa"; import { FiCpu, FiHardDrive } from "react-icons/fi"; import { useTranslation } from "next-i18next"; -import UsageBar from "../resources/usage-bar"; import Error from "../widget/error"; -import SingleResource from "../widget/single_resource"; -import WidgetIcon from "../widget/widget_icon"; -import ResourceValue from "../widget/resource_value"; -import ResourceLabel from "../widget/resource_label"; +import Resource from "../widget/resource"; import Resources from "../widget/resources"; import WidgetLabel from "../widget/widget_label"; @@ -37,31 +33,11 @@ export default function Widget({ options }) { if (!data) { return <Resources options={options}> - <SingleResource> - <WidgetIcon icon={FiCpu} /> - <ResourceLabel>{t("glances.wait")}</ResourceLabel> - <UsageBar percent="0" /> - </SingleResource> - <SingleResource> - <WidgetIcon icon={FaMemory} /> - <ResourceLabel>{t("glances.wait")}</ResourceLabel> - <UsageBar percent="0" /> - </SingleResource> - {options.cputemp && - <SingleResource> - <WidgetIcon icon={FaThermometerHalf} /> - <ResourceLabel>{t("glances.wait")}</ResourceLabel> - <UsageBar percent="0" /> - </SingleResource> - } - {options.uptime && - <SingleResource> - <WidgetIcon icon={FaRegClock} /> - <ResourceLabel>{t("glances.wait")}</ResourceLabel> - <UsageBar percent="0" /> - </SingleResource> - } - {options.label && <WidgetLabel label={options.label} />} + <Resource icon={FiCpu} label={t("glances.wait")} percentage="0" /> + <Resource icon={FaMemory} label={t("glances.wait")} percentage="0" /> + { options.cputemp && <Resource icon={FaThermometerHalf} label={t("glances.wait")} percentage="0" /> } + { options.uptime && <Resource icon={FaRegClock} label={t("glances.wait")} percentage="0" /> } + { options.label && <WidgetLabel label={options.label} /> } </Resources>; } @@ -93,77 +69,81 @@ export default function Widget({ options }) { return ( <Resources options={options} target={settings.target ?? "_blank"}> - <SingleResource> - <WidgetIcon icon={FiCpu} /> - <ResourceValue>{t("common.number", { + <Resource + icon={FiCpu} + value={t("common.number", { value: data.cpu.total, style: "unit", unit: "percent", maximumFractionDigits: 0, - })}</ResourceValue> - <ResourceLabel>{t("glances.cpu")}</ResourceLabel> - <ResourceValue>{t("common.number", { + })} + label={t("glances.cpu")} + expandedValue={t("common.number", { value: data.load.min15, style: "unit", unit: "percent", - maximumFractionDigits: 0, - })}</ResourceValue> - <ResourceLabel>{t("glances.load")}</ResourceLabel> - <UsageBar percent={data.cpu.total} /> - </SingleResource> - <SingleResource> - <WidgetIcon icon={FaMemory} /> - <ResourceValue>{t("common.bytes", { + maximumFractionDigits: 0 + })} + expandedLabel={t("glances.load")} + percentage={data.cpu.total} + expanded={options.expanded} + /> + <Resource + icon={FaMemory} + value={t("common.bytes", { value: data.mem.free, maximumFractionDigits: 1, binary: true, - })}</ResourceValue> - <ResourceLabel>{t("glances.free")}</ResourceLabel> - <ResourceValue>{t("common.bytes", { + })} + label={t("glances.free")} + expandedValue={t("common.bytes", { value: data.mem.total, maximumFractionDigits: 1, binary: true, - })}</ResourceValue> - <ResourceLabel>{t("glances.total")}</ResourceLabel> - <UsageBar percent={data.mem.percent} /> - </SingleResource> + })} + expandedLabel={t("glances.total")} + percentage={data.mem.percent} + expanded={options.expanded} + /> {disks.map((disk) => ( - <SingleResource key={disk.mnt_point}> - <WidgetIcon icon={FiHardDrive} /> - <ResourceValue>{t("common.bytes", { value: disk.free })}</ResourceValue> - <ResourceLabel>{t("glances.free")}</ResourceLabel> - <ResourceValue>{t("common.bytes", { value: disk.size })}</ResourceValue> - <ResourceLabel>{t("glances.total")}</ResourceLabel> - <UsageBar percent={disk.percent} /> - </SingleResource> + <Resource key={disk.mnt_point} + icon={FiHardDrive} + value={t("common.bytes", { value: disk.free })} + label={t("glances.free")} + expandedValue={t("common.bytes", { value: disk.size })} + expandedLabel={t("glances.total")} + percentage={disk.percent} + expanded={options.expanded} + /> ))} {options.cputemp && mainTemp > 0 && - <SingleResource> - <WidgetIcon icon={FaThermometerHalf} /> - <ResourceValue>{t("common.number", { + <Resource + icon={FaThermometerHalf} + value={t("common.number", { value: mainTemp, maximumFractionDigits: 1, style: "unit", unit - })}</ResourceValue> - <ResourceLabel>{t("glances.temp")}</ResourceLabel> - <ResourceValue>{t("common.number", { + })} + label={t("glances.temp")} + expandedValue={t("common.number", { value: maxTemp, maximumFractionDigits: 1, style: "unit", unit - })}</ResourceValue> - <ResourceLabel>{t("glances.warn")}</ResourceLabel> - <UsageBar percent={tempPercent} /> - </SingleResource> + })} + expandedLabel={t("glances.warn")} + percentage={tempPercent} + expanded={options.expanded} + /> } {options.uptime && data.uptime && - <SingleResource> - <WidgetIcon icon={FaRegClock} /> - <ResourceValue>{data.uptime.replace(" days,", t("glances.days")).replace(/:\d\d:\d\d$/g, t("glances.hours"))}</ResourceValue> - <ResourceLabel>{t("glances.uptime")}</ResourceLabel> - <UsageBar percent={Math.round((new Date().getSeconds() / 60) * 100)} /> - </SingleResource> + <Resource + icon={FaRegClock} + value={data.uptime.replace(" days,", t("glances.days")).replace(/:\d\d:\d\d$/g, t("glances.hours"))} + label={t("glances.uptime")} + percentage={Math.round((new Date().getSeconds() / 60) * 100).toString()} + /> } {options.label && <WidgetLabel label={options.label} />} </Resources> diff --git a/src/components/widgets/longhorn/node.jsx b/src/components/widgets/longhorn/node.jsx index 9983486e..5235698a 100644 --- a/src/components/widgets/longhorn/node.jsx +++ b/src/components/widgets/longhorn/node.jsx @@ -1,23 +1,20 @@ import { useTranslation } from "next-i18next"; import { FaThermometerHalf } from "react-icons/fa"; -import UsageBar from "../resources/usage-bar"; -import SingleResource from "../widget/single_resource"; -import WidgetIcon from "../widget/widget_icon"; -import ResourceValue from "../widget/resource_value"; -import ResourceLabel from "../widget/resource_label"; +import Resource from "../widget/resource"; import WidgetLabel from "../widget/widget_label"; export default function Node({ data, expanded, labels }) { const { t } = useTranslation(); - return <SingleResource expanded={expanded}> - <WidgetIcon icon={FaThermometerHalf} /> - <ResourceValue>{t("common.bytes", { value: data.node.available })}</ResourceValue> - <ResourceLabel>{t("resources.free")}</ResourceLabel> - <ResourceValue>{t("common.bytes", { value: data.node.maximum })}</ResourceValue> - <ResourceLabel>{t("resources.total")}</ResourceLabel> - <UsageBar percent={Math.round(((data.node.maximum - data.node.available) / data.node.maximum) * 100)} /> - { labels && <WidgetLabel label={data.node.id} /> } - </SingleResource> + return <Resource + icon={FaThermometerHalf} + value={t("common.bytes", { value: data.node.available })} + label={t("resources.free")} + expandedValue={t("common.bytes", { value: data.node.maximum })} + expandedLabel={t("resources.total")} + percentage={Math.round(((data.node.maximum - data.node.available) / data.node.maximum) * 100)} + expanded={expanded} + >{ labels && <WidgetLabel label={data.node.id} /> } + </Resource> } diff --git a/src/components/widgets/resources/cpu.jsx b/src/components/widgets/resources/cpu.jsx index 242e7a3d..12972fe8 100644 --- a/src/components/widgets/resources/cpu.jsx +++ b/src/components/widgets/resources/cpu.jsx @@ -2,14 +2,9 @@ import useSWR from "swr"; import { FiCpu } from "react-icons/fi"; import { useTranslation } from "next-i18next"; -import SingleResource from "../widget/single_resource"; -import WidgetIcon from "../widget/widget_icon"; -import ResourceValue from "../widget/resource_value"; -import ResourceLabel from "../widget/resource_label"; +import Resource from "../widget/resource"; import Error from "../widget/error"; -import UsageBar from "./usage-bar"; - export default function Cpu({ expanded }) { const { t } = useTranslation(); @@ -22,34 +17,25 @@ export default function Cpu({ expanded }) { } if (!data) { - return <SingleResource expanded={expanded}> - <WidgetIcon icon={FiCpu} /> - <ResourceValue>-</ResourceValue> - <ResourceLabel>{t("resources.cpu")}</ResourceLabel> - <ResourceValue>-</ResourceValue> - <ResourceLabel>{t("resources.load")}</ResourceLabel> - <UsageBar percent={0} /> - </SingleResource> + return <Resource icon={FiCpu} value="-" label={t("resources.cpu")} expandedValue="-" + expandedLabel={t("resources.load")} percentage="0" expanded={expanded} /> } - return <SingleResource expanded={expanded}> - <WidgetIcon icon={FiCpu} /> - <ResourceValue> - {t("common.number", { - value: data.cpu.usage, - style: "unit", - unit: "percent", - maximumFractionDigits: 0, - })} - </ResourceValue> - <ResourceLabel>{t("resources.cpu")}</ResourceLabel> - <ResourceValue> - {t("common.number", { - value: data.cpu.load, - maximumFractionDigits: 2, - })} - </ResourceValue> - <ResourceLabel>{t("resources.load")}</ResourceLabel> - <UsageBar percent={data.cpu.usage} /> - </SingleResource> + return <Resource + icon={FiCpu} + value={t("common.number", { + value: data.cpu.usage, + style: "unit", + unit: "percent", + maximumFractionDigits: 0, + })} + label={t("resources.cpu")} + expandedValue={t("common.number", { + value: data.cpu.load, + maximumFractionDigits: 2, + })} + expandedLabel={t("resources.load")} + percentage={data.cpu.usage} + expanded={expanded} + /> } diff --git a/src/components/widgets/resources/cputemp.jsx b/src/components/widgets/resources/cputemp.jsx index 1a62aa31..ba6d9b73 100644 --- a/src/components/widgets/resources/cputemp.jsx +++ b/src/components/widgets/resources/cputemp.jsx @@ -2,14 +2,9 @@ import useSWR from "swr"; import { FaThermometerHalf } from "react-icons/fa"; import { useTranslation } from "next-i18next"; -import SingleResource from "../widget/single_resource"; -import WidgetIcon from "../widget/widget_icon"; -import ResourceValue from "../widget/resource_value"; -import ResourceLabel from "../widget/resource_label"; +import Resource from "../widget/resource"; import Error from "../widget/error"; -import UsageBar from "./usage-bar"; - function convertToFahrenheit(t) { return t * 9/5 + 32 } @@ -26,13 +21,14 @@ export default function CpuTemp({ expanded, units }) { } if (!data || !data.cputemp) { - return <SingleResource expanded={expanded}> - <WidgetIcon icon={FaThermometerHalf} /> - <ResourceValue>-</ResourceValue> - <ResourceLabel>{t("resources.temp")}</ResourceLabel> - <ResourceValue>-</ResourceValue> - <ResourceLabel>{t("resources.max")}</ResourceLabel> - </SingleResource> + return <Resource + icon={FaThermometerHalf} + value="-" + label={t("resources.temp")} + expandedValue="-" + expandedLabel={t("resources.max")} + expanded={expanded} + />; } let mainTemp = data.cputemp.main; @@ -43,26 +39,23 @@ export default function CpuTemp({ expanded, units }) { mainTemp = (unit === "celsius") ? mainTemp : convertToFahrenheit(mainTemp); const maxTemp = (unit === "celsius") ? data.cputemp.max : convertToFahrenheit(data.cputemp.max); - return <SingleResource expanded={expanded}> - <WidgetIcon icon={FaThermometerHalf} /> - <ResourceValue> - {t("common.number", { - value: mainTemp, - maximumFractionDigits: 1, - style: "unit", - unit - })} - </ResourceValue> - <ResourceLabel>{t("resources.temp")}</ResourceLabel> - <ResourceValue> - {t("common.number", { - value: maxTemp, - maximumFractionDigits: 1, - style: "unit", - unit - })} - </ResourceValue> - <ResourceLabel>{t("resources.max")}</ResourceLabel> - <UsageBar percent={Math.round((mainTemp / maxTemp) * 100)} /> - </SingleResource>; + return <Resource + icon={FaThermometerHalf} + value={t("common.number", { + value: mainTemp, + maximumFractionDigits: 1, + style: "unit", + unit + })} + label={t("resources.temp")} + expandedValue={t("common.number", { + value: maxTemp, + maximumFractionDigits: 1, + style: "unit", + unit + })} + expandedLabel={t("resources.max")} + percentage={Math.round((mainTemp / maxTemp) * 100)} + expanded={expanded} + />; } diff --git a/src/components/widgets/resources/disk.jsx b/src/components/widgets/resources/disk.jsx index 742ff9d7..ab56624d 100644 --- a/src/components/widgets/resources/disk.jsx +++ b/src/components/widgets/resources/disk.jsx @@ -2,14 +2,9 @@ import useSWR from "swr"; import { FiHardDrive } from "react-icons/fi"; import { useTranslation } from "next-i18next"; -import SingleResource from "../widget/single_resource"; -import WidgetIcon from "../widget/widget_icon"; -import ResourceValue from "../widget/resource_value"; -import ResourceLabel from "../widget/resource_label"; +import Resource from "../widget/resource"; import Error from "../widget/error"; -import UsageBar from "./usage-bar"; - export default function Disk({ options, expanded }) { const { t } = useTranslation(); @@ -22,25 +17,27 @@ export default function Disk({ options, expanded }) { } if (!data) { - return <SingleResource expanded={expanded}> - <WidgetIcon icon={FiHardDrive} /> - <ResourceValue>-</ResourceValue> - <ResourceLabel>{t("resources.free")}</ResourceLabel> - <ResourceValue>-</ResourceValue> - <ResourceLabel>{t("resources.total")}</ResourceLabel> - <UsageBar percent={0} /> - </SingleResource>; + return <Resource + icon={FiHardDrive} + value="-" + label={t("resources.free")} + expandedValue="-" + expandedLabel={t("resources.total")} + expanded={expanded} + percentage="0" + />; } // data.drive.used not accurate? const percent = Math.round(((data.drive.size - data.drive.available) / data.drive.size) * 100); - return <SingleResource expanded={expanded}> - <WidgetIcon icon={FiHardDrive} /> - <ResourceValue>{t("common.bytes", { value: data.drive.available })}</ResourceValue> - <ResourceLabel>{t("resources.free")}</ResourceLabel> - <ResourceValue>{t("common.bytes", { value: data.drive.size })}</ResourceValue> - <ResourceLabel>{t("resources.total")}</ResourceLabel> - <UsageBar percent={percent} /> - </SingleResource>; + return <Resource + icon={FiHardDrive} + value={t("common.bytes", { value: data.drive.available })} + label={t("resources.free")} + expandedValue={t("common.bytes", { value: data.drive.size })} + expandedLabel={t("resources.total")} + percentage={percent} + expanded={expanded} + />; } diff --git a/src/components/widgets/resources/memory.jsx b/src/components/widgets/resources/memory.jsx index 97c74acc..19ae8687 100644 --- a/src/components/widgets/resources/memory.jsx +++ b/src/components/widgets/resources/memory.jsx @@ -2,14 +2,9 @@ import useSWR from "swr"; import { FaMemory } from "react-icons/fa"; import { useTranslation } from "next-i18next"; -import SingleResource from "../widget/single_resource"; -import WidgetIcon from "../widget/widget_icon"; -import ResourceValue from "../widget/resource_value"; -import ResourceLabel from "../widget/resource_label"; +import Resource from "../widget/resource"; import Error from "../widget/error"; -import UsageBar from "./usage-bar"; - export default function Memory({ expanded }) { const { t } = useTranslation(); @@ -22,30 +17,26 @@ export default function Memory({ expanded }) { } if (!data) { - return <SingleResource expanded={expanded}> - <WidgetIcon icon={FaMemory} /> - <ResourceValue>-</ResourceValue> - <ResourceLabel>{t("resources.free")}</ResourceLabel> - <ResourceValue>-</ResourceValue> - <ResourceLabel>{t("resources.total")}</ResourceLabel> - <UsageBar percent={0} /> - </SingleResource>; + return <Resource + icon={FaMemory} + value="-" + label={t("resources.free")} + expandedValue="-" + expandedLabel={t("resources.total")} + expanded={expanded} + percentage="0" + />; } const percent = Math.round((data.memory.active / data.memory.total) * 100); - return <SingleResource expanded={expanded}> - <WidgetIcon icon={FaMemory} /> - <ResourceValue>{t("common.bytes", { value: data.memory.available, maximumFractionDigits: 1, binary: true })}</ResourceValue> - <ResourceLabel>{t("resources.free")}</ResourceLabel> - <ResourceValue> - {t("common.bytes", { - value: data.memory.total, - maximumFractionDigits: 1, - binary: true, - })} - </ResourceValue> - <ResourceLabel>{t("resources.total")}</ResourceLabel> - <UsageBar percent={percent} /> - </SingleResource>; + return <Resource + icon={FaMemory} + value={t("common.bytes", { value: data.memory.available, maximumFractionDigits: 1, binary: true })} + label={t("resources.free")} + expandedValue={t("common.bytes", { value: data.memory.total, maximumFractionDigits: 1, binary: true })} + expandedLabel={t("resources.total")} + percentage={percent} + expanded={expanded} + />; } diff --git a/src/components/widgets/resources/uptime.jsx b/src/components/widgets/resources/uptime.jsx index 6cc2b8c5..3984975f 100644 --- a/src/components/widgets/resources/uptime.jsx +++ b/src/components/widgets/resources/uptime.jsx @@ -2,14 +2,9 @@ import useSWR from "swr"; import { FaRegClock } from "react-icons/fa"; import { useTranslation } from "next-i18next"; -import SingleResource from "../widget/single_resource"; -import WidgetIcon from "../widget/widget_icon"; -import ResourceValue from "../widget/resource_value"; -import ResourceLabel from "../widget/resource_label"; +import Resource from "../widget/resource"; import Error from "../widget/error"; -import UsageBar from "./usage-bar"; - export default function Uptime() { const { t } = useTranslation(); @@ -22,11 +17,7 @@ export default function Uptime() { } if (!data) { - return <SingleResource> - <WidgetIcon icon={FaRegClock} /> - <ResourceValue>-</ResourceValue> - <ResourceLabel>{t("resources.uptime")}</ResourceLabel> - </SingleResource>; + return <Resource icon={FaRegClock} value="-" label={t("resources.uptime")} percentage="0" />; } const mo = Math.floor(data.uptime / (3600 * 24 * 31)); @@ -39,12 +30,7 @@ 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); + const percent = Math.round((new Date().getSeconds() / 60) * 100).toString(); - return <SingleResource> - <WidgetIcon icon={FaRegClock} /> - <ResourceValue>{uptime}</ResourceValue> - <ResourceLabel>{t("resources.uptime")}</ResourceLabel> - <UsageBar percent={percent} /> - </SingleResource>; + return <Resource icon={FaRegClock} value={uptime} label={t("resources.uptime")} percentage={percent} />; } diff --git a/src/components/widgets/widget/resource.jsx b/src/components/widgets/widget/resource.jsx new file mode 100644 index 00000000..e77bcb5a --- /dev/null +++ b/src/components/widgets/widget/resource.jsx @@ -0,0 +1,22 @@ +import UsageBar from "../resources/usage-bar"; + +export default function Resource({ children, icon, value, label, expandedValue, expandedLabel, percentage, key, expanded = false }) { + const Icon = icon; + + return <div key={key} className="flex-none flex flex-row items-center mr-3 py-1.5"> + <Icon className="text-theme-800 dark:text-theme-200 w-5 h-5"/> + <div className="flex flex-col ml-3 text-left min-w-[85px]"> + <div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between"> + <div className="pl-0.5">{value}</div> + <div className="pr-1">{label}</div> + </div> + { expanded && <div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between"> + <div className="pl-0.5">{expandedValue}</div> + <div className="pr-1">{expandedLabel}</div> + </div> + } + { percentage && <UsageBar percent={percentage} /> } + { children } + </div> + </div>; +} diff --git a/src/components/widgets/widget/resource_label.jsx b/src/components/widgets/widget/resource_label.jsx deleted file mode 100644 index 87f2ad22..00000000 --- a/src/components/widgets/widget/resource_label.jsx +++ /dev/null @@ -1,5 +0,0 @@ -export default function ResourceLabel({ children }) { - return ( - <div className="pr-1">{children}</div> - ); -} diff --git a/src/components/widgets/widget/resource_value.jsx b/src/components/widgets/widget/resource_value.jsx deleted file mode 100644 index 8971c748..00000000 --- a/src/components/widgets/widget/resource_value.jsx +++ /dev/null @@ -1,5 +0,0 @@ -export default function ResourceValue({ children }) { - return ( - <div className="pl-0.5">{children}</div> - ); -} diff --git a/src/components/widgets/widget/resources.jsx b/src/components/widgets/widget/resources.jsx index 0771ec5e..19fb021d 100644 --- a/src/components/widgets/widget/resources.jsx +++ b/src/components/widgets/widget/resources.jsx @@ -1,5 +1,5 @@ import ContainerLink from "./container_link"; -import SingleResource from "./single_resource"; +import Resource from "./resource"; import Raw from "./raw"; import WidgetLabel from "./widget_label"; @@ -7,9 +7,9 @@ export default function Resources({ options, children, target }) { return <ContainerLink options={options} target={target}> <Raw> <div className="flex flex-row self-center flex-wrap justify-between"> - {children.filter(child => child && child.type === SingleResource)} + { children.filter(child => child && child.type === Resource) } </div> - {children.filter(child => child && child.type === WidgetLabel)} + { children.filter(child => child && child.type === WidgetLabel) } </Raw> </ContainerLink>; } diff --git a/src/components/widgets/widget/single_resource.jsx b/src/components/widgets/widget/single_resource.jsx deleted file mode 100644 index 7a83d8be..00000000 --- a/src/components/widgets/widget/single_resource.jsx +++ /dev/null @@ -1,28 +0,0 @@ -import UsageBar from "../resources/usage-bar"; - -import WidgetIcon from "./widget_icon"; -import ResourceValue from "./resource_value"; -import ResourceLabel from "./resource_label"; -import Raw from "./raw"; - -export default function SingleResource({ children, key, expanded = false }) { - const values = children.filter(child => child.type === ResourceValue); - const labels = children.filter(child => child.type === ResourceLabel); - - return <div key={key} className="flex-none flex flex-row items-center mr-3 py-1.5"> - {children.find(child => child.type === WidgetIcon)} - <div className="flex flex-col ml-3 text-left min-w-[85px]"> - <div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between"> - {values.pop()} - {labels.pop()} - </div> - { expanded && <div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between"> - {values.pop()} - {labels.pop()} - </div> - } - {children.find(child => child.type === UsageBar)} - </div> - {children.find(child => child.type === Raw)} - </div>; -}