From 01e8bdf0400ff4a2cf022edbf5a05ee18f42de51 Mon Sep 17 00:00:00 2001 From: Sven van Ginkel Date: Thu, 19 Feb 2026 19:15:12 +0100 Subject: [PATCH] feat: allow precise value entry for alerts via text input (#1718) --- .../src/components/alerts/alert-button.tsx | 2 +- .../src/components/alerts/alerts-sheet.tsx | 51 +++++++++++++++---- internal/site/src/lib/alerts.ts | 2 +- 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/internal/site/src/components/alerts/alert-button.tsx b/internal/site/src/components/alerts/alert-button.tsx index 472d922d..bffe691d 100644 --- a/internal/site/src/components/alerts/alert-button.tsx +++ b/internal/site/src/components/alerts/alert-button.tsx @@ -26,7 +26,7 @@ export default memo(function AlertsButton({ system }: { system: SystemRecord }) /> - + {opened && } diff --git a/internal/site/src/components/alerts/alerts-sheet.tsx b/internal/site/src/components/alerts/alerts-sheet.tsx index 6d831141..214a427f 100644 --- a/internal/site/src/components/alerts/alerts-sheet.tsx +++ b/internal/site/src/components/alerts/alerts-sheet.tsx @@ -7,6 +7,7 @@ import { lazy, memo, Suspense, useMemo, useState } from "react" import { $router, Link } from "@/components/router" import { Checkbox } from "@/components/ui/checkbox" import { DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog" +import { Input } from "@/components/ui/input" import { Switch } from "@/components/ui/switch" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { toast } from "@/components/ui/use-toast" @@ -20,7 +21,7 @@ const Slider = lazy(() => import("@/components/ui/slider")) const endpoint = "/api/beszel/user-alerts" -const alertDebounce = 100 +const alertDebounce = 400 const alertKeys = Object.keys(alertInfo) as (keyof typeof alertInfo)[] @@ -244,7 +245,7 @@ export function AlertContent({ }> {!singleDescription && (
-

+

{alertData.invert ? ( Average drops below{" "} @@ -263,21 +264,38 @@ export function AlertContent({ )}

-
+
sendUpsert(min, val[0])} onValueChange={(val) => setValue(val[0])} step={alertData.step ?? 1} min={alertData.min ?? 1} max={alertData.max ?? 99} /> + { + let val = parseFloat(e.target.value) + if (!Number.isNaN(val)) { + if (alertData.max != null) val = Math.min(val, alertData.max) + if (alertData.min != null) val = Math.max(val, alertData.min) + setValue(val) + sendUpsert(min, val) + } + }} + step={alertData.step ?? 1} + min={alertData.min ?? 1} + max={alertData.max ?? 99} + className="w-16 h-8 text-center px-1" + />
)}
-

+

{singleDescription && ( <> {singleDescription} @@ -289,15 +307,30 @@ export function AlertContent({

-
+
sendUpsert(minVal[0], value)} + aria-labelledby={`t${name}`} + value={[min]} + onValueCommit={(val) => sendUpsert(val[0], value)} onValueChange={(val) => setMin(val[0])} min={1} max={60} /> + { + let val = parseInt(e.target.value, 10) + if (!Number.isNaN(val)) { + val = Math.max(1, Math.min(val, 60)) + setMin(val) + sendUpsert(val, value) + } + }} + min={1} + max={60} + className="w-16 h-8 text-center px-1" + />
diff --git a/internal/site/src/lib/alerts.ts b/internal/site/src/lib/alerts.ts index dc0c5180..b6644772 100644 --- a/internal/site/src/lib/alerts.ts +++ b/internal/site/src/lib/alerts.ts @@ -40,7 +40,7 @@ export const alertInfo: Record = { unit: " MB/s", icon: EthernetIcon, desc: () => t`Triggers when combined up/down exceeds a threshold`, - max: 125, + max: 250, }, GPU: { name: () => t`GPU Usage`,