diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index bb7e3b805..7f04d6b06 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -3664,7 +3664,12 @@ "description": "Time-series charts for CPU, memory, disk, network, and Docker container metrics", "option": { "systemId": { - "label": "System ID" + "label": "System", + "description": "Select a Beszel system to display stats for", + "configureIntegrationFirst": "Configure a Beszel integration first", + "loading": "Loading systems...", + "placeholder": "Select a system", + "noSystems": "No systems found" }, "timePeriod": { "label": "Time period" diff --git a/packages/widgets/src/_inputs/index.ts b/packages/widgets/src/_inputs/index.ts index 639a9df5e..82b02078f 100644 --- a/packages/widgets/src/_inputs/index.ts +++ b/packages/widgets/src/_inputs/index.ts @@ -16,6 +16,7 @@ import { WidgetTextInput } from "./widget-text-input"; import { WidgetUmamiEventInput } from "./widget-umami-event-input"; import { WidgetUmamiEventNamesInput } from "./widget-umami-event-names-input"; import { WidgetUmamiWebsiteInput } from "./widget-umami-website-input"; +import { WidgetBeszelSystemInput } from "./widget-beszel-system-input"; const mapping = { anchorNote: WidgetAnchorNoteInput, @@ -35,6 +36,7 @@ const mapping = { umamiEventNames: WidgetUmamiEventNamesInput, umamiWebsite: WidgetUmamiWebsiteInput, customWidgetSelect: WidgetCustomWidgetSelectInput, + beszelSystem: WidgetBeszelSystemInput, } satisfies Record; export const getInputForType = (type: TType) => { diff --git a/packages/widgets/src/_inputs/widget-beszel-system-input.tsx b/packages/widgets/src/_inputs/widget-beszel-system-input.tsx new file mode 100644 index 000000000..4b5604c28 --- /dev/null +++ b/packages/widgets/src/_inputs/widget-beszel-system-input.tsx @@ -0,0 +1,46 @@ +"use client"; + +import { Select, Text } from "@mantine/core"; + +import { clientApi } from "@homarr/api/client"; +import { useScopedI18n } from "@homarr/translation/client"; + +import type { CommonWidgetInputProps } from "./common"; +import { useWidgetInputTranslation } from "./common"; +import { useFormContext } from "./form"; + +export const WidgetBeszelSystemInput = ({ property, kind }: CommonWidgetInputProps<"beszelSystem">) => { + const t = useScopedI18n("widget.beszelSystemStats.option.systemId"); + const tInput = useWidgetInputTranslation(kind, property); + const form = useFormContext(); + + const integrationIds = form.values.integrationIds; + + const { data: systemsResult = [], isPending } = clientApi.widget.beszel.getSystems.useQuery( + { integrationIds }, + { enabled: integrationIds.length > 0, staleTime: 30_000 }, + ); + + if (integrationIds.length === 0) { + return ( + + {t("configureIntegrationFirst")} + + ); + } + + const systems = systemsResult.flatMap((r) => r.systems.map((s) => ({ value: s.id, label: s.name }))); + + return ( +