diff --git a/src/components/widgets/datetime/datetime.jsx b/src/components/widgets/datetime/datetime.jsx index 454d004dc..869834736 100644 --- a/src/components/widgets/datetime/datetime.jsx +++ b/src/components/widgets/datetime/datetime.jsx @@ -1,9 +1,6 @@ import { useState, useEffect } from "react"; import { useTranslation } from "next-i18next"; -import Container from "../widget/container"; -import Raw from "../widget/raw"; - const textSizes = { "4xl": "text-4xl", "3xl": "text-3xl", @@ -20,7 +17,7 @@ export default function DateTime({ options }) { const { i18n } = useTranslation(); const [date, setDate] = useState(""); const dateLocale = locale ?? i18n.language; - + useEffect(() => { const dateFormat = new Intl.DateTimeFormat(dateLocale, { ...format }); const interval = setInterval(() => { @@ -30,14 +27,12 @@ export default function DateTime({ options }) { }, [date, setDate, dateLocale, format]); return ( - - -
- - {date} - -
-
-
+
+
+ + {date} + +
+
); } diff --git a/src/components/widgets/glances/glances.jsx b/src/components/widgets/glances/glances.jsx index b45dfefeb..85dd44c0c 100644 --- a/src/components/widgets/glances/glances.jsx +++ b/src/components/widgets/glances/glances.jsx @@ -1,13 +1,11 @@ import useSWR from "swr"; import { useContext } from "react"; +import { BiError } from "react-icons/bi"; import { FaMemory, FaRegClock, FaThermometerHalf } from "react-icons/fa"; import { FiCpu, FiHardDrive } from "react-icons/fi"; import { useTranslation } from "next-i18next"; -import Error from "../widget/error"; -import Resource from "../widget/resource"; -import Resources from "../widget/resources"; -import WidgetLabel from "../widget/widget_label"; +import UsageBar from "../resources/usage-bar"; import { SettingsContext } from "utils/contexts/settings"; @@ -28,17 +26,52 @@ export default function Widget({ options }) { ); if (error || data?.error) { - return + return ( +
+
+
+ +
+ {t("widget.api_error")} +
+
+
+
+ ); } if (!data) { - return - - - { options.cputemp && } - { options.uptime && } - { options.label && } - ; + return ( +
+
+
+ +
+
+
+ {t("glances.wait")} +
+
+ +
+
+
+ +
+
+
+ {t("glances.wait")} +
+
+ +
+
+
+ {options.label && ( +
{options.label}
+ )} +
+ ); } const unit = options.units === "imperial" ? "fahrenheit" : "celsius"; @@ -68,84 +101,131 @@ export default function Widget({ options }) { } return ( - - - - {disks.map((disk) => ( - - ))} - {options.cputemp && mainTemp > 0 && - - } - {options.uptime && data.uptime && - - } - {options.label && } - + +
+
+ +
+
+
+ {t("common.number", { + value: data.cpu.total, + style: "unit", + unit: "percent", + maximumFractionDigits: 0, + })} +
+
{t("glances.cpu")}
+
+ {options.expanded && ( + +
+ {t("common.number", { + value: data.load.min15, + style: "unit", + unit: "percent", + maximumFractionDigits: 0, + })} +
+
{t("glances.load")}
+
+ )} + +
+
+
+ +
+
+
+ {t("common.bytes", { + value: data.mem.free, + maximumFractionDigits: 1, + binary: true, + })} +
+
{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 && + (
+ +
+ +
+ {t("common.number", { + value: mainTemp, + maximumFractionDigits: 1, + style: "unit", + unit + })} +
+
{t("glances.temp")}
+
+ {options.expanded && ( + +
+ {t("common.number", { + value: maxTemp, + maximumFractionDigits: 1, + style: "unit", + unit + })} +
+
{t("glances.warn")}
+
+ )} + +
+
)} + {options.uptime && data.uptime && + (
+ +
+ +
+ {data.uptime.replace(" days,", t("glances.days")).replace(/:\d\d:\d\d$/g, t("glances.hours"))} +
+
{t("glances.uptime")}
+
+ +
+
)} +
+ {options.label && ( +
{options.label}
+ )} +
); } diff --git a/src/components/widgets/greeting/greeting.jsx b/src/components/widgets/greeting/greeting.jsx index 11de571c8..da0f063d1 100644 --- a/src/components/widgets/greeting/greeting.jsx +++ b/src/components/widgets/greeting/greeting.jsx @@ -1,6 +1,3 @@ -import Container from "../widget/container"; -import Raw from "../widget/raw"; - const textSizes = { "4xl": "text-4xl", "3xl": "text-3xl", @@ -14,12 +11,12 @@ const textSizes = { export default function Greeting({ options }) { if (options.text) { - return - + return ( +
{options.text} - - ; +
+ ); } } diff --git a/src/components/widgets/kubernetes/kubernetes.jsx b/src/components/widgets/kubernetes/kubernetes.jsx index 2d1f55e4b..78c4caaf9 100644 --- a/src/components/widgets/kubernetes/kubernetes.jsx +++ b/src/components/widgets/kubernetes/kubernetes.jsx @@ -1,15 +1,12 @@ import useSWR from "swr"; +import { BiError } from "react-icons/bi"; import { useTranslation } from "next-i18next"; -import Error from "../widget/error"; -import Container from "../widget/container"; -import Raw from "../widget/raw"; - import Node from "./node"; export default function Widget({ options }) { const { cluster, nodes } = options; - const { i18n } = useTranslation(); + const { t, i18n } = useTranslation(); const defaultData = { cpu: { @@ -21,7 +18,7 @@ export default function Widget({ options }) { used: 0, total: 0, free: 0, - percent: 0 + precent: 0 } }; @@ -32,12 +29,23 @@ export default function Widget({ options }) { ); if (error || data?.error) { - return + return ( +
+
+
+ +
+ {t("widget.api_error")} +
+
+
+
+ ); } if (!data) { - return - + return ( +
{cluster.show && @@ -46,12 +54,12 @@ export default function Widget({ options }) { }
- - ; +
+ ); } - return - + return ( +
{cluster.show && @@ -61,6 +69,6 @@ export default function Widget({ options }) { ) }
- - ; +
+ ); } diff --git a/src/components/widgets/kubernetes/node.jsx b/src/components/widgets/kubernetes/node.jsx index cc864be68..7a7c322d4 100644 --- a/src/components/widgets/kubernetes/node.jsx +++ b/src/components/widgets/kubernetes/node.jsx @@ -3,7 +3,8 @@ import { FiAlertTriangle, FiCpu, FiServer } from "react-icons/fi"; import { SiKubernetes } from "react-icons/si"; import { useTranslation } from "next-i18next"; -import UsageBar from "../resources/usage-bar"; +import UsageBar from "./usage-bar"; + export default function Node({ type, options, data }) { const { t } = useTranslation(); @@ -28,7 +29,7 @@ export default function Node({ type, options, data }) {
{t("common.number", { - value: data?.cpu?.percent ?? 0, + value: data.cpu.percent, style: "unit", unit: "percent", maximumFractionDigits: 0 @@ -36,18 +37,18 @@ export default function Node({ type, options, data }) {
- +
{t("common.bytes", { - value: data?.memory?.free ?? 0, + value: data.memory.free, maximumFractionDigits: 0, binary: true })}
- + {options.showLabel && (
{type === "cluster" ? options.label : data.name}
)} diff --git a/src/components/widgets/kubernetes/usage-bar.jsx b/src/components/widgets/kubernetes/usage-bar.jsx new file mode 100644 index 000000000..c817db4c4 --- /dev/null +++ b/src/components/widgets/kubernetes/usage-bar.jsx @@ -0,0 +1,12 @@ +export default function UsageBar({ percent }) { + return ( +
+
+
+ ); +} diff --git a/src/components/widgets/logo/logo.jsx b/src/components/widgets/logo/logo.jsx index 3a4a25651..96e8569fc 100644 --- a/src/components/widgets/logo/logo.jsx +++ b/src/components/widgets/logo/logo.jsx @@ -1,13 +1,9 @@ -import Container from "../widget/container"; -import Raw from "../widget/raw"; - import ResolvedIcon from "components/resolvedicon" export default function Logo({ options }) { return ( - - - {options.icon ? +
+ {options.icon ? : // fallback to homepage logo } - - +
) } diff --git a/src/components/widgets/longhorn/longhorn.jsx b/src/components/widgets/longhorn/longhorn.jsx index c0169ceb9..9fcb21b4a 100644 --- a/src/components/widgets/longhorn/longhorn.jsx +++ b/src/components/widgets/longhorn/longhorn.jsx @@ -1,31 +1,37 @@ import useSWR from "swr"; - -import Error from "../widget/error"; -import Container from "../widget/container"; -import Raw from "../widget/raw"; +import { BiError } from "react-icons/bi"; +import { useTranslation } from "next-i18next"; import Node from "./node"; export default function Longhorn({ options }) { const { expanded, total, labels, include, nodes } = options; + const { t } = useTranslation(); const { data, error } = useSWR(`/api/widgets/longhorn`, { refreshInterval: 1500 }); if (error || data?.error) { - return + return ( +
+ +
+ {t("widget.api_error")} +
+
+ ); } if (!data) { - return - + return ( +
- - ; +
+ ); } - return - + return ( +
{data.nodes .filter((node) => { @@ -46,6 +52,6 @@ export default function Longhorn({ options }) {
)}
-
-
; +
+ ); } diff --git a/src/components/widgets/longhorn/node.jsx b/src/components/widgets/longhorn/node.jsx index 5235698a4..e0ee69afb 100644 --- a/src/components/widgets/longhorn/node.jsx +++ b/src/components/widgets/longhorn/node.jsx @@ -1,20 +1,32 @@ +import { FiHardDrive } from "react-icons/fi"; import { useTranslation } from "next-i18next"; -import { FaThermometerHalf } from "react-icons/fa"; -import Resource from "../widget/resource"; -import WidgetLabel from "../widget/widget_label"; +import UsageBar from "../resources/usage-bar"; export default function Node({ data, expanded, labels }) { const { t } = useTranslation(); - return { labels && } - + return ( + <> +
+ +
+ +
{t("common.bytes", { value: data.node.available })}
+
{t("resources.free")}
+
+ {expanded && ( + +
{t("common.bytes", { value: data.node.maximum })}
+
{t("resources.total")}
+
+ )} + +
+
+ {labels && ( +
{data.node.id}
+ )} + + ); } diff --git a/src/components/widgets/openmeteo/openmeteo.jsx b/src/components/widgets/openmeteo/openmeteo.jsx index 040a3b6b1..0d29aef53 100644 --- a/src/components/widgets/openmeteo/openmeteo.jsx +++ b/src/components/widgets/openmeteo/openmeteo.jsx @@ -1,16 +1,10 @@ import useSWR from "swr"; import { useState } from "react"; +import { BiError } from "react-icons/bi"; import { WiCloudDown } from "react-icons/wi"; import { MdLocationDisabled, MdLocationSearching } from "react-icons/md"; import { useTranslation } from "next-i18next"; -import Error from "../widget/error"; -import Container from "../widget/container"; -import ContainerButton from "../widget/container_button"; -import WidgetIcon from "../widget/widget_icon"; -import PrimaryText from "../widget/primary_text"; -import SecondaryText from "../widget/secondary_text"; - import Icon from "./icon"; function Widget({ options }) { @@ -21,35 +15,60 @@ function Widget({ options }) { ); if (error || data?.error) { - return + return ( +
+
+
+ +
+ {t("widget.api_error")} + - +
+
+
+
+ ); } if (!data) { - return - {t("weather.updating")} - {t("weather.wait")} - - ; + return ( +
+
+
+ +
+
+ {t("weather.updating")} + {t("weather.wait")} +
+
+
+ ); } const unit = options.units === "metric" ? "celsius" : "fahrenheit"; - const weatherInfo = { - condition: data.current_weather.weathercode, - timeOfDay: data.current_weather.time > data.daily.sunrise[0] && data.current_weather.time < data.daily.sunset[0] ? "day" : "night" - }; + const timeOfDay = data.current_weather.time > data.daily.sunrise[0] && data.current_weather.time < data.daily.sunset[0] ? "day" : "night"; - return - - {options.label && `${options.label}, `} - {t("common.number", { - value: data.current_weather.temperature, - style: "unit", - unit, - })} - - {t(`wmo.${data.current_weather.weathercode}-${weatherInfo.timeOfDay}`)} - - ; + return ( +
+
+
+ +
+
+ + {options.label && `${options.label}, `} + {t("common.number", { + value: data.current_weather.temperature, + style: "unit", + unit, + })} + + {t(`wmo.${data.current_weather.weathercode}-${timeOfDay}`)} +
+
+
+ ); } export default function OpenMeteo({ options }) { @@ -84,11 +103,27 @@ export default function OpenMeteo({ options }) { // if (!requesting && !location) requestLocation(); if (!location) { - return - {t("weather.current")} - {t("weather.allow")} - - ; + return ( + + ); } return ; diff --git a/src/components/widgets/openweathermap/weather.jsx b/src/components/widgets/openweathermap/weather.jsx index 305315139..49f428a04 100644 --- a/src/components/widgets/openweathermap/weather.jsx +++ b/src/components/widgets/openweathermap/weather.jsx @@ -1,19 +1,12 @@ import useSWR from "swr"; import { useState } from "react"; +import { BiError } from "react-icons/bi"; import { WiCloudDown } from "react-icons/wi"; import { MdLocationDisabled, MdLocationSearching } from "react-icons/md"; import { useTranslation } from "next-i18next"; -import Error from "../widget/error"; -import Container from "../widget/container"; -import ContainerButton from "../widget/container_button"; -import PrimaryText from "../widget/primary_text"; -import SecondaryText from "../widget/secondary_text"; -import WidgetIcon from "../widget/widget_icon"; - import Icon from "./icon"; - function Widget({ options }) { const { t, i18n } = useTranslation(); @@ -22,30 +15,58 @@ function Widget({ options }) { ); if (error || data?.cod === 401 || data?.error) { - return + return ( +
+
+
+ +
+ {t("widget.api_error")} + - +
+
+
+
+ ); } if (!data) { - return - {t("weather.updating")} - {t("weather.wait")} - - ; + return ( +
+
+
+ +
+
+ {t("weather.updating")} + {t("weather.wait")} +
+
+
+ ); } const unit = options.units === "metric" ? "celsius" : "fahrenheit"; - const weatherInfo = { - condition: data.weather[0].id, - timeOfDay: data.dt > data.sys.sunrise && data.dt < data.sys.sunset ? "day" : "night" - }; - - return - {options.label && `${options.label}, `} - {t("common.number", { value: data.main.temp, style: "unit", unit })} - {data.weather[0].description} - - ; + return ( +
+
+
+ data.sys.sunrise && data.dt < data.sys.sunset ? "day" : "night"} + /> +
+
+ + {options.label && `${options.label}, `} + {t("common.number", { value: data.main.temp, style: "unit", unit })} + + {data.weather[0].description} +
+
+
+ ); } export default function OpenWeatherMap({ options }) { @@ -77,12 +98,30 @@ export default function OpenWeatherMap({ options }) { } }; + // if (!requesting && !location) requestLocation(); + if (!location) { - return - {t("weather.current")} - {t("weather.allow")} - - ; + return ( + + ); } return ; diff --git a/src/components/widgets/resources/cpu.jsx b/src/components/widgets/resources/cpu.jsx index 12972fe89..7069e3c4a 100644 --- a/src/components/widgets/resources/cpu.jsx +++ b/src/components/widgets/resources/cpu.jsx @@ -1,9 +1,9 @@ import useSWR from "swr"; import { FiCpu } from "react-icons/fi"; +import { BiError } from "react-icons/bi"; import { useTranslation } from "next-i18next"; -import Resource from "../widget/resource"; -import Error from "../widget/error"; +import UsageBar from "./usage-bar"; export default function Cpu({ expanded }) { const { t } = useTranslation(); @@ -13,29 +13,67 @@ export default function Cpu({ expanded }) { }); if (error || data?.error) { - return + return ( +
+ +
+ {t("widget.api_error")} +
+
+ ); } if (!data) { - return + return ( +
+ +
+
+
-
+
{t("resources.cpu")}
+
+ {expanded && ( +
+
-
+
{t("resources.load")}
+
+ )} + +
+
+ ); } - return + const percent = data.cpu.usage; + + return ( +
+ +
+
+
+ {t("common.number", { + value: data.cpu.usage, + style: "unit", + unit: "percent", + maximumFractionDigits: 0, + })} +
+
{t("resources.cpu")}
+
+ {expanded && ( +
+
+ {t("common.number", { + value: data.cpu.load, + maximumFractionDigits: 2, + })} +
+
{t("resources.load")}
+
+ )} + +
+
+ ); } diff --git a/src/components/widgets/resources/cputemp.jsx b/src/components/widgets/resources/cputemp.jsx index ba6d9b730..571e6c8a7 100644 --- a/src/components/widgets/resources/cputemp.jsx +++ b/src/components/widgets/resources/cputemp.jsx @@ -1,9 +1,9 @@ import useSWR from "swr"; import { FaThermometerHalf } from "react-icons/fa"; +import { BiError } from "react-icons/bi"; import { useTranslation } from "next-i18next"; -import Resource from "../widget/resource"; -import Error from "../widget/error"; +import UsageBar from "./usage-bar"; function convertToFahrenheit(t) { return t * 9/5 + 32 @@ -17,18 +17,34 @@ export default function CpuTemp({ expanded, units }) { }); if (error || data?.error) { - return + return ( +
+ +
+ {t("widget.api_error")} +
+
+ ); } if (!data || !data.cputemp) { - return ; + return ( +
+ +
+ +
-
+
{t("resources.temp")}
+
+ {expanded && ( + +
-
+
{t("resources.max")}
+
+ )} +
+
+ ); } let mainTemp = data.cputemp.main; @@ -38,24 +54,38 @@ export default function CpuTemp({ expanded, units }) { const unit = units === "imperial" ? "fahrenheit" : "celsius"; mainTemp = (unit === "celsius") ? mainTemp : convertToFahrenheit(mainTemp); const maxTemp = (unit === "celsius") ? data.cputemp.max : convertToFahrenheit(data.cputemp.max); + const percent = Math.round((mainTemp / maxTemp) * 100); - return ; + return ( +
+ +
+ +
+ {t("common.number", { + value: mainTemp, + maximumFractionDigits: 1, + style: "unit", + unit + })} +
+
{t("resources.temp")}
+
+ {expanded && ( + +
+ {t("common.number", { + value: maxTemp, + maximumFractionDigits: 1, + style: "unit", + unit + })} +
+
{t("resources.max")}
+
+ )} + +
+
+ ); } diff --git a/src/components/widgets/resources/disk.jsx b/src/components/widgets/resources/disk.jsx index ab56624d9..ca09c0958 100644 --- a/src/components/widgets/resources/disk.jsx +++ b/src/components/widgets/resources/disk.jsx @@ -1,9 +1,9 @@ import useSWR from "swr"; import { FiHardDrive } from "react-icons/fi"; +import { BiError } from "react-icons/bi"; import { useTranslation } from "next-i18next"; -import Resource from "../widget/resource"; -import Error from "../widget/error"; +import UsageBar from "./usage-bar"; export default function Disk({ options, expanded }) { const { t } = useTranslation(); @@ -13,31 +13,56 @@ export default function Disk({ options, expanded }) { }); if (error || data?.error) { - return + return ( +
+ +
+ {t("widget.api_error")} +
+
+ ); } if (!data) { - return ; + return ( +
+ +
+ +
-
+
{t("resources.free")}
+
+ {expanded && ( + +
-
+
{t("resources.total")}
+
+ )} + +
+
+ ); } // data.drive.used not accurate? const percent = Math.round(((data.drive.size - data.drive.available) / data.drive.size) * 100); - return ; + return ( +
+ +
+ +
{t("common.bytes", { value: data.drive.available })}
+
{t("resources.free")}
+
+ {expanded && ( + +
{t("common.bytes", { value: data.drive.size })}
+
{t("resources.total")}
+
+ )} + +
+
+ ); } diff --git a/src/components/widgets/resources/memory.jsx b/src/components/widgets/resources/memory.jsx index 19ae86879..30b7c8eb8 100644 --- a/src/components/widgets/resources/memory.jsx +++ b/src/components/widgets/resources/memory.jsx @@ -1,9 +1,9 @@ import useSWR from "swr"; import { FaMemory } from "react-icons/fa"; +import { BiError } from "react-icons/bi"; import { useTranslation } from "next-i18next"; -import Resource from "../widget/resource"; -import Error from "../widget/error"; +import UsageBar from "./usage-bar"; export default function Memory({ expanded }) { const { t } = useTranslation(); @@ -13,30 +13,63 @@ export default function Memory({ expanded }) { }); if (error || data?.error) { - return + return ( +
+ +
+ {t("widget.api_error")} +
+
+ ); } if (!data) { - return ; + return ( +
+ +
+ +
-
+
{t("resources.free")}
+
+ {expanded && ( + +
-
+
{t("resources.total")}
+
+ )} + +
+
+ ); } const percent = Math.round((data.memory.active / data.memory.total) * 100); - return ; + return ( +
+ +
+ +
+ {t("common.bytes", { value: data.memory.available, maximumFractionDigits: 1, binary: true })} +
+
{t("resources.free")}
+
+ {expanded && ( + +
+ {t("common.bytes", { + value: data.memory.total, + maximumFractionDigits: 1, + binary: true, + })} +
+
{t("resources.total")}
+
+ )} + +
+
+ ); } diff --git a/src/components/widgets/resources/resources.jsx b/src/components/widgets/resources/resources.jsx index 0cc2c3013..4ff0c81cd 100644 --- a/src/components/widgets/resources/resources.jsx +++ b/src/components/widgets/resources/resources.jsx @@ -1,6 +1,3 @@ -import Container from "../widget/container"; -import Raw from "../widget/raw"; - import Disk from "./disk"; import Cpu from "./cpu"; import Memory from "./memory"; @@ -9,8 +6,8 @@ import Uptime from "./uptime"; export default function Resources({ options }) { const { expanded, units } = options; - return - + return ( +
{options.cpu && } {options.memory && } @@ -23,6 +20,6 @@ export default function Resources({ options }) { {options.label && (
{options.label}
)} - - ; +
+ ); } diff --git a/src/components/widgets/resources/uptime.jsx b/src/components/widgets/resources/uptime.jsx index 3984975f1..3bf785b1e 100644 --- a/src/components/widgets/resources/uptime.jsx +++ b/src/components/widgets/resources/uptime.jsx @@ -1,9 +1,9 @@ import useSWR from "swr"; import { FaRegClock } from "react-icons/fa"; +import { BiError } from "react-icons/bi"; import { useTranslation } from "next-i18next"; -import Resource from "../widget/resource"; -import Error from "../widget/error"; +import UsageBar from "./usage-bar"; export default function Uptime() { const { t } = useTranslation(); @@ -13,24 +13,54 @@ export default function Uptime() { }); if (error || data?.error) { - return + return ( +
+ +
+ {t("widget.api_error")} +
+
+ ); } if (!data) { - return ; + return ( +
+ +
+ +
-
+
{t("resources.temp")}
+
+
+
+ ); } const mo = Math.floor(data.uptime / (3600 * 24 * 31)); const d = Math.floor(data.uptime % (3600 * 24 * 31) / (3600 * 24)); const h = Math.floor(data.uptime % (3600 * 24) / 3600); const m = Math.floor(data.uptime % 3600 / 60); - + let uptime; if (mo > 0) uptime = `${mo}${t("resources.months")} ${d}${t("resources.days")}`; 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).toString(); + const percent = Math.round((new Date().getSeconds() / 60) * 100); - return ; + return ( +
+ +
+ +
+ {uptime} +
+
{t("resources.uptime")}
+
+ +
+
+ ); } diff --git a/src/components/widgets/search/search.jsx b/src/components/widgets/search/search.jsx index 1bac4a619..4689567f3 100644 --- a/src/components/widgets/search/search.jsx +++ b/src/components/widgets/search/search.jsx @@ -1,13 +1,10 @@ -import { useState, useEffect, useCallback, Fragment } from "react"; +import { useState, useEffect, Fragment } from "react"; import { useTranslation } from "next-i18next"; import { FiSearch } from "react-icons/fi"; import { SiDuckduckgo, SiMicrosoftbing, SiGoogle, SiBaidu, SiBrave } from "react-icons/si"; import { Listbox, Transition } from "@headlessui/react"; import classNames from "classnames"; -import ContainerForm from "../widget/container_form"; -import Raw from "../widget/raw"; - export const searchProviders = { google: { name: "Google", @@ -79,9 +76,14 @@ export default function Search({ options }) { setSelectedProvider(storedProvider); } }, [availableProviderIds]); + + if (!availableProviderIds) { + return null; + } - const submitCallback = useCallback(event => { + function handleSubmit(event) { const q = encodeURIComponent(query); + const { url } = selectedProvider; if (url) { window.open(`${url}${q}`, options.target || "_blank"); @@ -92,10 +94,6 @@ export default function Search({ options }) { event.preventDefault(); event.target.reset(); setQuery(""); - }, [options.target, options.url, query, selectedProvider]); - - if (!availableProviderIds) { - return null; } const onChangeProvider = (provider) => { @@ -103,79 +101,77 @@ export default function Search({ options }) { localStorage.setItem(localStorageKey, provider.name); } - return - -
-
- setQuery(s.currentTarget.value)} - required - autoCapitalize="off" - autoCorrect="off" - autoComplete="off" - // eslint-disable-next-line jsx-a11y/no-autofocus - autoFocus={options.focus} - /> - -
- - - {t("search.search")} - -
- +
+ setQuery(s.currentTarget.value)} + required + autoCapitalize="off" + autoCorrect="off" + autoComplete="off" + // eslint-disable-next-line jsx-a11y/no-autofocus + autoFocus={options.focus} + /> + +
+ + + {t("search.search")} + +
+ + - -
- {availableProviderIds.map((providerId) => { - const p = searchProviders[providerId]; - return ( - - {({ active }) => ( -
  • - -
  • - )} -
    - ); - })} -
    -
    -
    -
    -
    - - ; +
    + {availableProviderIds.map((providerId) => { + const p = searchProviders[providerId]; + return ( + + {({ active }) => ( +
  • + +
  • + )} +
    + ); + })} +
    + +
    +
    + + ); } diff --git a/src/components/widgets/unifi_console/unifi_console.jsx b/src/components/widgets/unifi_console/unifi_console.jsx index dad92cc78..13c90bd42 100644 --- a/src/components/widgets/unifi_console/unifi_console.jsx +++ b/src/components/widgets/unifi_console/unifi_console.jsx @@ -3,12 +3,6 @@ import { MdSettingsEthernet } from "react-icons/md"; import { useTranslation } from "next-i18next"; import { SiUbiquiti } from "react-icons/si"; -import Error from "../widget/error"; -import Container from "../widget/container"; -import Raw from "../widget/raw"; -import WidgetIcon from "../widget/widget_icon"; -import PrimaryText from "../widget/primary_text"; - import useWidgetAPI from "utils/proxy/use-widget-api"; export default function Widget({ options }) { @@ -19,16 +13,35 @@ export default function Widget({ options }) { const { data: statsData, error: statsError } = useWidgetAPI(options, "stat/sites", { index: options.index }); if (statsError) { - return + return ( +
    +
    +
    + +
    + {t("widget.api_error")} +
    +
    +
    +
    + ); } const defaultSite = options.site ? statsData?.data.find(s => s.desc === options.site) : statsData?.data?.find(s => s.name === "default"); if (!defaultSite) { - return - {t("unifi.wait")} - - ; + return ( +
    +
    +
    + +
    +
    + {t("unifi.wait")} +
    +
    +
    + ); } const wan = defaultSite.health.find(h => h.subsystem === "wan"); @@ -43,9 +56,8 @@ export default function Widget({ options }) { const dataEmpty = !(wan.show || lan.show || wlan.show || uptime); - return - -
    + return ( +
    @@ -129,7 +141,6 @@ export default function Widget({ options }) {
    }
    -
    -
    -
    +
    + ); } diff --git a/src/components/widgets/weather/weather.jsx b/src/components/widgets/weather/weather.jsx index 702ea6693..20bf3dec2 100644 --- a/src/components/widgets/weather/weather.jsx +++ b/src/components/widgets/weather/weather.jsx @@ -1,16 +1,10 @@ import useSWR from "swr"; import { useState } from "react"; +import { BiError } from "react-icons/bi"; import { WiCloudDown } from "react-icons/wi"; import { MdLocationDisabled, MdLocationSearching } from "react-icons/md"; import { useTranslation } from "next-i18next"; -import Error from "../widget/error"; -import Container from "../widget/container"; -import PrimaryText from "../widget/primary_text"; -import SecondaryText from "../widget/secondary_text"; -import WidgetIcon from "../widget/widget_icon"; -import ContainerButton from "../widget/container_button"; - import Icon from "./icon"; function Widget({ options }) { @@ -21,35 +15,59 @@ function Widget({ options }) { ); if (error || data?.error) { - return + return ( +
    +
    +
    + +
    + {t("widget.api_error")} + - +
    +
    +
    +
    + ); } if (!data) { - return - {t("weather.updating")} - {t("weather.wait")} - - ; + return ( +
    +
    +
    + +
    +
    + {t("weather.updating")} + {t("weather.wait")} +
    +
    +
    + ); } const unit = options.units === "metric" ? "celsius" : "fahrenheit"; - const weatherInfo = { - condition: data.current.condition.code, - timeOfDay: data.current.is_day ? "day" : "night", - }; - return - - {options.label && `${options.label}, `} - {t("common.number", { - value: options.units === "metric" ? data.current.temp_c : data.current.temp_f, - style: "unit", - unit, - })} - - {data.current.condition.text} - - ; + return ( +
    +
    +
    + +
    +
    + + {options.label && `${options.label}, `} + {t("common.number", { + value: options.units === "metric" ? data.current.temp_c : data.current.temp_f, + style: "unit", + unit, + })} + + {data.current.condition.text} +
    +
    +
    + ); } export default function WeatherApi({ options }) { @@ -81,12 +99,30 @@ export default function WeatherApi({ options }) { } }; + // if (!requesting && !location) requestLocation(); + if (!location) { - return - {t("weather.current")} - {t("weather.allow")} - - ; + return ( + + ); } return ; diff --git a/src/components/widgets/widget.jsx b/src/components/widgets/widget.jsx index b4fdb1434..471418872 100644 --- a/src/components/widgets/widget.jsx +++ b/src/components/widgets/widget.jsx @@ -17,13 +17,13 @@ const widgetMappings = { kubernetes: dynamic(() => import("components/widgets/kubernetes/kubernetes")), }; -export default function Widget({ widget, style }) { +export default function Widget({ widget }) { const InfoWidget = widgetMappings[widget.type]; if (InfoWidget) { return ( - + ); } diff --git a/src/components/widgets/widget/container.jsx b/src/components/widgets/widget/container.jsx deleted file mode 100644 index 3a4a9f57e..000000000 --- a/src/components/widgets/widget/container.jsx +++ /dev/null @@ -1,42 +0,0 @@ -import classNames from "classnames"; - -import WidgetIcon from "./widget_icon"; -import PrimaryText from "./primary_text"; -import SecondaryText from "./secondary_text"; -import Raw from "./raw"; - -export function getAllClasses(options, additionalClassNames = '') { - return classNames( - "flex flex-col justify-center first:ml-0 ml-4 mr-2", - additionalClassNames, - options?.style === "boxedWidgets" && " ml-4 mt-2 m:mb-0 rounded-md shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 dark:bg-white/5 p-2 pl-3", - ); -} - -export function getInnerBlock(children) { - // children won't be an array if it's Raw component - return Array.isArray(children) &&
    -
    {children.find(child => child.type === WidgetIcon)}
    -
    - {children.find(child => child.type === PrimaryText)} - {children.find(child => child.type === SecondaryText)} -
    -
    ; -} - -export function getBottomBlock(children) { - if (children.type !== Raw) { - return children.find(child => child.type === Raw) || []; - } - - return [children]; -} - -export default function Container({ children = [], options, additionalClassNames = '' }) { - return ( -
    - {getInnerBlock(children)} - {getBottomBlock(children)} -
    - ); -} diff --git a/src/components/widgets/widget/container_button.jsx b/src/components/widgets/widget/container_button.jsx deleted file mode 100644 index 92d8a4166..000000000 --- a/src/components/widgets/widget/container_button.jsx +++ /dev/null @@ -1,10 +0,0 @@ -import { getAllClasses, getInnerBlock, getBottomBlock } from "./container"; - -export default function ContainerButton ({ children = [], options, additionalClassNames = '', callback }) { - return ( - - ); -} diff --git a/src/components/widgets/widget/container_form.jsx b/src/components/widgets/widget/container_form.jsx deleted file mode 100644 index 7d28a1bb3..000000000 --- a/src/components/widgets/widget/container_form.jsx +++ /dev/null @@ -1,10 +0,0 @@ -import { getAllClasses, getInnerBlock, getBottomBlock } from "./container"; - -export default function ContainerForm ({ children = [], options, additionalClassNames = '', callback }) { - return ( -
    - {getInnerBlock(children)} - {getBottomBlock(children)} -
    - ); -} diff --git a/src/components/widgets/widget/container_link.jsx b/src/components/widgets/widget/container_link.jsx deleted file mode 100644 index 8ef0e80aa..000000000 --- a/src/components/widgets/widget/container_link.jsx +++ /dev/null @@ -1,10 +0,0 @@ -import { getAllClasses, getInnerBlock, getBottomBlock } from "./container"; - -export default function ContainerLink ({ children = [], options, additionalClassNames = '', target }) { - return ( - - {getInnerBlock(children)} - {getBottomBlock(children)} - - ); -} diff --git a/src/components/widgets/widget/error.jsx b/src/components/widgets/widget/error.jsx deleted file mode 100644 index a3dbab85e..000000000 --- a/src/components/widgets/widget/error.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import { useTranslation } from "react-i18next"; -import { BiError } from "react-icons/bi"; - -import Container from "./container"; -import PrimaryText from "./primary_text"; -import WidgetIcon from "./widget_icon"; - -export default function Error({ options }) { - const { t } = useTranslation(); - - return - {t("widget.api_error")} - - ; -} diff --git a/src/components/widgets/widget/primary_text.jsx b/src/components/widgets/widget/primary_text.jsx deleted file mode 100644 index 3418b92c7..000000000 --- a/src/components/widgets/widget/primary_text.jsx +++ /dev/null @@ -1,5 +0,0 @@ -export default function PrimaryText({ children }) { - return ( - {children} - ); -} diff --git a/src/components/widgets/widget/raw.jsx b/src/components/widgets/widget/raw.jsx deleted file mode 100644 index 44e3dddc4..000000000 --- a/src/components/widgets/widget/raw.jsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function Raw({ children }) { - if (children.type === Raw) { - return [children]; - } - - return children; -} diff --git a/src/components/widgets/widget/resource.jsx b/src/components/widgets/widget/resource.jsx deleted file mode 100644 index e77bcb5a7..000000000 --- a/src/components/widgets/widget/resource.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import UsageBar from "../resources/usage-bar"; - -export default function Resource({ children, icon, value, label, expandedValue, expandedLabel, percentage, key, expanded = false }) { - const Icon = icon; - - return
    - -
    -
    -
    {value}
    -
    {label}
    -
    - { expanded &&
    -
    {expandedValue}
    -
    {expandedLabel}
    -
    - } - { percentage && } - { children } -
    -
    ; -} diff --git a/src/components/widgets/widget/resources.jsx b/src/components/widgets/widget/resources.jsx deleted file mode 100644 index 19fb021de..000000000 --- a/src/components/widgets/widget/resources.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import ContainerLink from "./container_link"; -import Resource from "./resource"; -import Raw from "./raw"; -import WidgetLabel from "./widget_label"; - -export default function Resources({ options, children, target }) { - return - -
    - { children.filter(child => child && child.type === Resource) } -
    - { children.filter(child => child && child.type === WidgetLabel) } -
    -
    ; -} diff --git a/src/components/widgets/widget/secondary_text.jsx b/src/components/widgets/widget/secondary_text.jsx deleted file mode 100644 index 363d1bd04..000000000 --- a/src/components/widgets/widget/secondary_text.jsx +++ /dev/null @@ -1,5 +0,0 @@ -export default function SecondaryText({ children }) { - return ( - {children} - ); -} diff --git a/src/components/widgets/widget/widget_icon.jsx b/src/components/widgets/widget/widget_icon.jsx deleted file mode 100644 index 9766a8791..000000000 --- a/src/components/widgets/widget/widget_icon.jsx +++ /dev/null @@ -1,18 +0,0 @@ -export default function WidgetIcon({ icon, size = "s", pulse = false, weatherInfo = {} }) { - const Icon = icon; - const { condition, timeOfDay } = weatherInfo; - let additionalClasses = "text-theme-800 dark:text-theme-200 "; - - switch (size) { - case "m": additionalClasses += "w-6 h-6 "; break; - case "l": additionalClasses += "w-8 h-8 "; break; - case "xl": additionalClasses += "w-10 h-10 "; break; - default: additionalClasses += "w-5 h-5 "; - } - - if (pulse) { - additionalClasses += "animate-pulse "; - } - - return ; -} diff --git a/src/components/widgets/widget/widget_label.jsx b/src/components/widgets/widget/widget_label.jsx deleted file mode 100644 index dcb9b9e96..000000000 --- a/src/components/widgets/widget/widget_label.jsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function WidgetLabel({ label = "" }) { - return
    {label}
    -} diff --git a/src/pages/api/widgets/longhorn.js b/src/pages/api/widgets/longhorn.js index d23a7f61b..a6b6781c8 100644 --- a/src/pages/api/widgets/longhorn.js +++ b/src/pages/api/widgets/longhorn.js @@ -46,7 +46,7 @@ function parseLonghornData(data) { export default async function handler(req, res) { const settings = getSettings(); - const longhornSettings = settings?.providers?.longhorn || {}; + const longhornSettings = settings?.providers?.longhorn; const {url, username, password} = longhornSettings; if (!url) { diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 006456f9d..e170d4e1d 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -160,7 +160,6 @@ const headerStyles = { "m-4 mb-0 sm:m-8 sm:mb-0 rounded-md shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 dark:bg-white/5 p-3", underlined: "m-4 mb-0 sm:m-8 sm:mb-1 border-b-2 pb-4 border-theme-800 dark:border-theme-200/50", clean: "m-4 mb-0 sm:m-8 sm:mb-0", - boxedWidgets: "m-4 mb-0 sm:m-8 sm:mb-0 sm:mt-1", }; function Home({ initialSettings }) { @@ -209,7 +208,6 @@ function Home({ initialSettings }) { searchProvider = searchProviders[searchWidget.options?.provider]; } } - const headerStyle = initialSettings?.headerStyle || "underlined"; useEffect(() => { function handleKeyDown(e) { @@ -258,7 +256,7 @@ function Home({ initialSettings }) {
    !rightAlignedWidgets.includes(widget.type)) .map((widget, i) => ( - + ))} -
    +
    {widgets .filter((widget) => rightAlignedWidgets.includes(widget.type)) .map((widget, i) => ( - + ))}