diff --git a/app/src/components/KindBadge.tsx b/app/src/components/KindBadge.tsx index b5b3db1..47d6cb8 100644 --- a/app/src/components/KindBadge.tsx +++ b/app/src/components/KindBadge.tsx @@ -1,5 +1,5 @@ import { cn } from "@/lib/utils" -import { KIND_DESCRIPTIONS, kindLabel } from "@/lib/labels" +import { KIND_DESCRIPTIONS, kindIcon, kindLabel } from "@/lib/labels" // Derived deployment kind → badge color. const kindColors: Record = { @@ -12,15 +12,17 @@ const kindColors: Record = { export function KindBadge({ kind }: { kind: string | null }) { if (!kind) return null + const Icon = kindIcon(kind) return ( + {kindLabel(kind)} ) diff --git a/app/src/lib/labels.ts b/app/src/lib/labels.ts index dc74666..76ebcd7 100644 --- a/app/src/lib/labels.ts +++ b/app/src/lib/labels.ts @@ -1,3 +1,24 @@ +import type { LucideIcon } from "lucide-react" +import { Box, Clock, LayoutTemplate, Package, Server, Waypoints, Wrench } from "lucide-react" + +// Canonical kind → icon — the single source of truth so the nav, Overview tiles, +// cards, the System map, and the command palette all speak one visual language. +// (Colors live in KindBadge; labels/descriptions are below.) `program` is the +// catalog pseudo-kind, not a deployment kind — the same Package glyph the +// Programs nav entry and Overview tile use. +export const KIND_ICONS: Record = { + service: Server, + job: Clock, + tool: Wrench, + static: LayoutTemplate, + reference: Waypoints, + program: Package, +} + +export function kindIcon(kind: string): LucideIcon { + return KIND_ICONS[kind] ?? Box +} + export const LAUNCHER_LABELS: Record = { python: "Python", command: "Command", diff --git a/app/src/pages/Overview.tsx b/app/src/pages/Overview.tsx index 30d2d9b..4a3c7c5 100644 --- a/app/src/pages/Overview.tsx +++ b/app/src/pages/Overview.tsx @@ -1,5 +1,6 @@ import { Link } from "react-router-dom" -import { Clock, Globe, Package, Server, Share2, Wrench } from "lucide-react" +import { Globe, Share2 } from "lucide-react" +import { KIND_ICONS } from "@/lib/labels" import { useGateway, useJobs, @@ -33,28 +34,28 @@ export function Overview() { const tiles = [ { to: "/services", - icon: Server, + icon: KIND_ICONS.service, label: "Services", value: services?.length ?? 0, detail: services ? `${upCount(serviceIds)} up` : "", }, { to: "/scheduled", - icon: Clock, + icon: KIND_ICONS.job, label: "Scheduled", value: jobs?.length ?? 0, detail: jobs ? `${jobs.length === 1 ? "job" : "jobs"}` : "", }, { to: "/tools", - icon: Wrench, + icon: KIND_ICONS.tool, label: "Tools", value: tools?.length ?? 0, detail: tools ? "on PATH" : "", }, { to: "/programs", - icon: Package, + icon: KIND_ICONS.program, label: "Programs", value: programs?.length ?? 0, detail: programs ? "in catalog" : "", diff --git a/app/src/pages/ScheduledDetail.tsx b/app/src/pages/ScheduledDetail.tsx index b2c60a0..44f3959 100644 --- a/app/src/pages/ScheduledDetail.tsx +++ b/app/src/pages/ScheduledDetail.tsx @@ -1,5 +1,6 @@ import { useParams, Link } from "react-router-dom" -import { Clock, Package } from "lucide-react" +import { Clock } from "lucide-react" +import { kindIcon } from "@/lib/labels" import { useJob } from "@/services/api/hooks" import { LogViewer } from "@/components/LogViewer" import { DetailHeader } from "@/components/detail/DetailHeader" @@ -8,6 +9,8 @@ import { SystemdPanel } from "@/components/detail/SystemdPanel" import { ConfigPanel } from "@/components/detail/ConfigPanel" import { RelatedDeployments } from "@/components/detail/RelatedDeployments" +const ProgramIcon = kindIcon("program") + export function ScheduledDetailPage() { const { name } = useParams<{ name: string }>() const { data: deployment, isLoading, error, refetch } = useJob(name ?? "") @@ -58,7 +61,7 @@ export function ScheduledDetailPage() { to={`/programs/${deployment.program}`} className="flex items-center gap-1.5 min-w-0 text-[var(--primary)] hover:underline" > - {deployment.program} + {deployment.program} )}