import { useMemo } from "react"; import { useParams } from "react-router-dom"; import { Boxes } from "lucide-react"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Skeleton } from "@/components/ui/skeleton"; import { useDashboardBySlug } from "../hooks/useDashboards"; import { PinnedServiceLink } from "../components/PinnedServiceLink"; /** * Payload model for named dashboards (design choice: inline items, not widget * instance ids). The payload stores an ordered list of items: * * ``` * { items: DashboardItem[] } * ``` * * Where `DashboardItem` is either a pinned service link (this slice) or a * future widget reference (follow-up). Widget composition on named dashboards * is deferred — the main Dashboard already has the rich widget config dialog. */ interface LinkItem { type: "link"; label: string; target: string; } type DashboardItem = LinkItem; function parseItems(payload: Record): DashboardItem[] { const items = payload.items; if (!Array.isArray(items)) return []; return items.filter( (item): item is LinkItem => typeof item === "object" && item !== null && item.type === "link" && typeof item.label === "string" && typeof item.target === "string", ); } export function NamedDashboardPage() { const { slug = "" } = useParams<{ slug: string }>(); const { data: dashboard, isLoading, isError } = useDashboardBySlug(slug); const items = useMemo( () => parseItems(dashboard?.payload ?? {}), [dashboard?.payload], ); if (isLoading) { return ; } if (isError || !dashboard) { return ( Dashboard not found. It may have been deleted or the link is invalid. ); } return (

{dashboard.label}

{items.length === 0 ? ( This dashboard has no shortcuts yet. Add pinned service links from the dashboard management panel on the Services page. ) : (
{items.map((item, index) => ( ))}
)}
); }