From e14fbc9205a57cefd08dcc1faf63f28d8224bf75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Mon, 17 Aug 2026 21:23:01 +0200 Subject: [PATCH] feat: streamline traefik widget with icon/status dot, fix grid gap Traefik's widget was the only card without a BrandIcon or StatusDot in its header, and had no href either - added icon/href fields to the schema and matched the exact docker/service widget header markup. StatusDot reuses the same "running once data loaded" convention the other widgets already use for a non-container up/down signal. System's widget was span=5 while every other widget in this app is span=4 (docker/service/traefik) or 3 (http) - on a 12-column grid that left a permanent 3-column gap next to it every row. Matched it to span=4 so system+traefik+one more widget tile a full row exactly. Also added grid-auto-flow: dense as a general safety net against future span-mismatch gaps. --- app/globals.css | 1 + components/widgets/system/Widget.tsx | 2 +- components/widgets/traefik/Widget.tsx | 33 +++++++++++++++++++++------ lib/config/schema.ts | 2 ++ 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/app/globals.css b/app/globals.css index c482064..4f141da 100644 --- a/app/globals.css +++ b/app/globals.css @@ -144,6 +144,7 @@ body { .pn-bento { display: grid; grid-template-columns: repeat(12, 1fr); + grid-auto-flow: dense; } @media (max-width: 860px) { diff --git a/components/widgets/system/Widget.tsx b/components/widgets/system/Widget.tsx index 2446096..00a904b 100644 --- a/components/widgets/system/Widget.tsx +++ b/components/widgets/system/Widget.tsx @@ -19,7 +19,7 @@ export function SystemWidget({ widget, widgetId }: { widget: SystemWidget; widge const errorMessage = result?.type === "error" ? result.message : null; return ( - +
System
{widget.name} {errorMessage && {errorMessage}} diff --git a/components/widgets/traefik/Widget.tsx b/components/widgets/traefik/Widget.tsx index 410d57e..af68f4c 100644 --- a/components/widgets/traefik/Widget.tsx +++ b/components/widgets/traefik/Widget.tsx @@ -4,6 +4,8 @@ import type { Widget } from "@/lib/config/schema"; import { useWidgetSubscription } from "@/lib/ws/client"; import { SkeletonLines } from "@/components/widgets/Skeleton"; import { WidgetCard } from "@/components/widgets/WidgetCard"; +import { StatusDot } from "@/components/widgets/StatusDot"; +import { BrandIcon } from "@/components/widgets/BrandIcon"; type TraefikWidget = Extract; @@ -15,13 +17,30 @@ export function TraefikWidget({ widget, widgetId }: { widget: TraefikWidget; wid return ( -
- {widget.name} - {data && ( - - {data.entrypoints.length} entrypoints - - )} +
+
+ + {widget.href ? ( + + {widget.name} + + ) : ( + {widget.name} + )} +
+
+ {data && ( + + {data.entrypoints.length} entrypoints + + )} + +
{errorMessage && {errorMessage}} {!result && !errorMessage && } diff --git a/lib/config/schema.ts b/lib/config/schema.ts index abb5f47..7223cf1 100644 --- a/lib/config/schema.ts +++ b/lib/config/schema.ts @@ -62,6 +62,8 @@ export const traefikWidgetSchema = z.object({ type: z.literal("traefik"), name: z.string().default("Traefik"), apiUrl: z.string().url(), + href: z.string().url().optional(), + icon: z.string().optional(), interval: durationSchema.default("15s"), });