diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 6d9b76a7..461551ee 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -710,6 +710,8 @@ "passed": "Passed", "failed": "Failed", "zfsHits": "Hits", - "zfsMisses": "Misses" + "zfsMisses": "Misses", + "updatesAvailable": "Updates available", + "packageCount": "Package count: {{ value, number }}" } } diff --git a/src/components/widgets/openmediavault/openmediavault.jsx b/src/components/widgets/openmediavault/openmediavault.jsx new file mode 100644 index 00000000..9d8be5c2 --- /dev/null +++ b/src/components/widgets/openmediavault/openmediavault.jsx @@ -0,0 +1,21 @@ +import Container from "../widget/container"; +import Raw from "../widget/raw"; + +import Updates from "./updates"; + +export default function Resources({ options }) { + const { expanded } = options; + + return ( + + + + {("updates" in options ? options.updates : true) && } + + {options.label && ( + {options.label} + )} + + + ); +} diff --git a/src/components/widgets/openmediavault/updates.jsx b/src/components/widgets/openmediavault/updates.jsx new file mode 100644 index 00000000..c50751ea --- /dev/null +++ b/src/components/widgets/openmediavault/updates.jsx @@ -0,0 +1,29 @@ +import useSWR from "swr"; +import { FaCheck } from "react-icons/fa"; +import { useTranslation } from "next-i18next"; + +import Resource from "../widget/resource"; +import Error from "../widget/error"; + +export default function Uptime({ expanded }) { + const { t, i18n } = useTranslation(); + const params = { lang: i18n.language, method: "apt.enumerateUpgraded" }; + const { data, error } = useSWR(`/api/widgets/openmediavault?${new URLSearchParams(params).toString()}`); + + if (error || data?.error) { + return ; + } + + if (!data || data?.response?.length === 0) { + return null; + } + + return ( + + ); +} diff --git a/src/components/widgets/widget.jsx b/src/components/widgets/widget.jsx index b4fdb143..f1e18c9d 100644 --- a/src/components/widgets/widget.jsx +++ b/src/components/widgets/widget.jsx @@ -15,6 +15,7 @@ const widgetMappings = { openmeteo: dynamic(() => import("components/widgets/openmeteo/openmeteo")), longhorn: dynamic(() => import("components/widgets/longhorn/longhorn")), kubernetes: dynamic(() => import("components/widgets/kubernetes/kubernetes")), + openmediavault: dynamic(() => import("components/widgets/openmediavault/openmediavault")), }; export default function Widget({ widget, style }) { diff --git a/src/pages/api/widgets/openmediavault.js b/src/pages/api/widgets/openmediavault.js new file mode 100644 index 00000000..dcf49f2b --- /dev/null +++ b/src/pages/api/widgets/openmediavault.js @@ -0,0 +1,16 @@ +import { processReq } from "../../../widgets/openmediavault/proxy"; + +import { getPrivateWidgetOptions } from "utils/config/widget-helpers"; + +export default async function handler(req, res) { + const { index, method } = req.query; + + const [{ options }] = await getPrivateWidgetOptions("openmediavault", index); + const widget = { + type: "openmediavault", + method, + ...options, + }; + + return processReq(widget, res); +} diff --git a/src/widgets/openmediavault/proxy.js b/src/widgets/openmediavault/proxy.js index 06380b13..0b0fd35e 100644 --- a/src/widgets/openmediavault/proxy.js +++ b/src/widgets/openmediavault/proxy.js @@ -104,12 +104,7 @@ async function processBg(url, filename) { return resp; } -export default async function proxyHandler(req, res) { - const widget = await getWidget(req); - if (!widget) { - return res.status(400).json({ error: "Invalid proxy service type" }); - } - +export async function processReq(widget, res) { const api = widgets?.[widget.type]?.api; if (!api) { return res.status(403).json({ error: "Service does not support RPC calls" }); @@ -152,3 +147,12 @@ export default async function proxyHandler(req, res) { return res.status(resp.status).send(resp.data); } + +export default async function proxyHandler(req, res) { + const widget = await getWidget(req); + if (!widget) { + return res.status(400).json({ error: "Invalid proxy service type" }); + } + + return processReq(widget, res); +}