diff --git a/beszel/internal/users/users.go b/beszel/internal/users/users.go index ca4dfda..8ed7dda 100644 --- a/beszel/internal/users/users.go +++ b/beszel/internal/users/users.go @@ -14,18 +14,6 @@ type UserManager struct { app core.App } -type UserSettings struct { - ChartTime string `json:"chartTime"` - NotificationEmails []string `json:"emails"` - NotificationWebhooks []string `json:"webhooks"` - // UnitTemp uint8 `json:"unitTemp"` // 0 for Celsius, 1 for Fahrenheit - // UnitNet uint8 `json:"unitNet"` // 0 for bytes, 1 for bits - // UnitDisk uint8 `json:"unitDisk"` // 0 for bytes, 1 for bits - - // New field for alert history retention (e.g., "1m", "3m", "6m", "1y") - AlertHistoryRetention string `json:"alertHistoryRetention,omitempty"` -} - func NewUserManager(app core.App) *UserManager { return &UserManager{ app: app, @@ -44,7 +32,10 @@ func (um *UserManager) InitializeUserRole(e *core.RecordEvent) error { func (um *UserManager) InitializeUserSettings(e *core.RecordEvent) error { record := e.Record // intialize settings with defaults (zero values can be ignored) - settings := UserSettings{ + settings := struct { + ChartTime string `json:"chartTime"` + Emails []string `json:"emails"` + }{ ChartTime: "1h", } record.UnmarshalJSONField("settings", &settings) @@ -59,10 +50,7 @@ func (um *UserManager) InitializeUserSettings(e *core.RecordEvent) error { log.Println("failed to get user email", "err", err) return err } - settings.NotificationEmails = []string{user.Email} - if len(settings.NotificationWebhooks) == 0 { - settings.NotificationWebhooks = []string{""} - } + settings.Emails = []string{user.Email} record.Set("settings", settings) return e.Next() } diff --git a/beszel/site/src/components/routes/settings/general.tsx b/beszel/site/src/components/routes/settings/general.tsx index 753bb6f..956b0ab 100644 --- a/beszel/site/src/components/routes/settings/general.tsx +++ b/beszel/site/src/components/routes/settings/general.tsx @@ -12,29 +12,17 @@ import languages from "@/lib/languages" import { dynamicActivate } from "@/lib/i18n" import { useLingui } from "@lingui/react/macro" import { Input } from "@/components/ui/input" -// import { setLang } from "@/lib/i18n" import { Unit } from "@/lib/enums" export default function SettingsProfilePage({ userSettings }: { userSettings: UserSettings }) { const [isLoading, setIsLoading] = useState(false) const { i18n } = useLingui() - // Remove all per-metric threshold state and UI - // Only keep general yellow/red threshold state and UI - const [yellow, setYellow] = useState(userSettings.meterThresholds?.yellow ?? 65) - const [red, setRed] = useState(userSettings.meterThresholds?.red ?? 90) - - function handleResetThresholds() { - setYellow(65) - setRed(90) - } - async function handleSubmit(e: React.FormEvent) { e.preventDefault() setIsLoading(true) const formData = new FormData(e.target as HTMLFormElement) const data = Object.fromEntries(formData) as Partial - data.meterThresholds = { yellow, red } await saveSettings(data) setIsLoading(false) } @@ -114,45 +102,6 @@ export default function SettingsProfilePage({ userSettings }: { userSettings: Us

-
-
-

- Dashboard meter thresholds -

-

- Choose when the dashboard meters changes colors, based on percentage values. -

-
-
-
- - setYellow(Number(e.target.value))} - /> -
-
- - setRed(Number(e.target.value))} - /> -
- -
-
- - {/* Unit preferences section fixed and wrapped in a div */}

@@ -232,6 +181,47 @@ export default function SettingsProfilePage({ userSettings }: { userSettings: Us

+
+
+

+ Warning thresholds +

+

+ Set percentage thresholds for meter colors. +

+
+
+
+ + +
+
+ + +
+
+
+ ) } + function CellFormatter(info: CellContext) { + const userSettings = useStore($userSettings) const val = Number(info.getValue()) || 0 + const { colorWarn = 65, colorCrit = 90 } = userSettings return (
{decimalString(val, val >= 10 ? 1 : 2)}% @@ -289,8 +292,8 @@ function CellFormatter(info: CellContext) { className={cn( "absolute inset-0 w-full h-full origin-left", (info.row.original.status !== "up" && "bg-primary/30") || - (val < 65 && "bg-green-500") || - (val < 90 && "bg-yellow-500") || + (val < colorWarn && "bg-green-500") || + (val < colorCrit && "bg-yellow-500") || "bg-red-600" )} style={{ diff --git a/beszel/site/src/components/systems-table/systems-table.tsx b/beszel/site/src/components/systems-table/systems-table.tsx index e7fde1a..f81a0b1 100644 --- a/beszel/site/src/components/systems-table/systems-table.tsx +++ b/beszel/site/src/components/systems-table/systems-table.tsx @@ -51,49 +51,6 @@ import AlertButton from "../alerts/alert-button" type ViewMode = "table" | "grid" -function CellFormatter(info: CellContext) { - const val = (info.getValue() as number) || 0 - const userSettings = useStore($userSettings) - const yellow = userSettings?.meterThresholds?.yellow ?? 65 - const red = userSettings?.meterThresholds?.red ?? 90 - return ( -
- {decimalString(val, 1)}% - - - -
- ) -} - -function sortableHeader(context: HeaderContext) { - const { column } = context - // @ts-ignore - const { Icon, hideSort, name }: { Icon: React.ElementType; name: () => string; hideSort: boolean } = column.columnDef - return ( - - ) -} - export default function SystemsTable() { const data = useStore($systems) const { i18n, t } = useLingui() diff --git a/beszel/site/src/lib/stores.ts b/beszel/site/src/lib/stores.ts index eb99aaa..e8167b0 100644 --- a/beszel/site/src/lib/stores.ts +++ b/beszel/site/src/lib/stores.ts @@ -24,17 +24,21 @@ export const $chartTime = atom("1h") as PreinitializedWritableAtom /** Whether to display average or max chart values */ export const $maxValues = atom(false) +// export const UserSettingsSchema = v.object({ +// chartTime: v.picklist(["1h", "12h", "24h", "1w", "30d"]), +// emails: v.optional(v.array(v.pipe(v.string(), v.email())), [pb?.authStore?.record?.email ?? ""]), +// webhooks: v.optional(v.array(v.string())), +// colorWarn: v.optional(v.pipe(v.number(), v.minValue(1), v.maxValue(100))), +// colorDanger: v.optional(v.pipe(v.number(), v.minValue(1), v.maxValue(100))), +// unitTemp: v.optional(v.enum(Unit)), +// unitNet: v.optional(v.enum(Unit)), +// unitDisk: v.optional(v.enum(Unit)), +// }) + /** User settings */ export const $userSettings = map({ chartTime: "1h", emails: [pb.authStore.record?.email || ""], - meterThresholds: { - yellow: 65, - red: 90, - }, - // unitTemp: "celsius", - // unitNet: "mbps", - // unitDisk: "mbps", }) // update local storage on change $userSettings.subscribe((value) => { diff --git a/beszel/site/src/types.d.ts b/beszel/site/src/types.d.ts index 9011ba5..6639daf 100644 --- a/beszel/site/src/types.d.ts +++ b/beszel/site/src/types.d.ts @@ -224,17 +224,14 @@ export interface ChartTimeData { } export interface UserSettings { - // lang?: string chartTime: ChartTimes emails?: string[] webhooks?: string[] - meterThresholds?: { - yellow?: number - red?: number - } unitTemp?: Unit unitNet?: Unit unitDisk?: Unit + colorWarn?: number + colorCrit?: number } type ChartDataContainer = {