Saved view The same five filters, every morning, as one click. The part teams get wrong is the unsaved-changes state: a view that silently drifts from what its name says stops being trustworthy within a week. npx shadcn@latest add button toggle-group Tokens this needs: --card, --card-foreground, --foreground, --muted-foreground, --border, --status-warn The status, chart, scale, state and direction names are an extension, not a rename. shadcn has --destructive and five --chart-* and nothing else in this territory. ──────────────────────────────────────────────────────────────────────── // SavedViewCard.tsx ──────────────────────────────────────────────────────────────────────── import { Button } from "@/components/ui/button"; import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"; import { cn } from "@/lib/utils"; /** * What a saved view holds, shown before it is opened. * * The type is the decision about what gets captured. Filters, sort, columns, * expansion and a relative range are in it. An absolute range is not, and * there is no field to put one in: a view saved during an incident with its * absolute range reopens next month still showing that incident. The card * says "not kept" on the page so the person opening it knows what it will * not restore. */ export type Scope = "personal" | "shared" | "default"; export type SavedView = { name: string; scope: Scope; /** A shared or default view needs a name against it. */ owner: string; /** Dimension to value, in the operator syntax the page uses: { sev: ">=2" }. */ filters: Record; sort: { by: string; dir: "asc" | "desc" }; columns: { shown: string[]; of: number }; expandedRows: boolean; /** Relative only. "last 24h" reopens as the last 24 hours from whenever it is opened. */ range: `last ${string}`; }; const SCOPES: Record string }> = { personal: { label: "Personal", hint: () => "Only you see it." }, shared: { label: "Shared", hint: (v) => `Owned by ${v.owner}.` }, default: { label: "Default", hint: () => "What everyone sees first." }, }; type Props = { view: SavedView; /** Whether a filter's dimension value still exists in the source. A view * pointed at a service that was deleted should say so; returning nothing * is indistinguishable from a healthy quiet system. */ exists: (dimension: string, value: string) => boolean; /** What the view returns right now. */ rows: number; onOpen: (view: SavedView) => void; onScopeChange: (scope: Scope) => void; }; export function SavedViewCard({ view, exists, rows, onOpen, onScopeChange }: Props) { const missing = Object.entries(view.filters).filter(([k, v]) => !exists(k, v)); const drifted = missing.length > 0; const filters = Object.entries(view.filters).map(([k, v]) => `${k}${/^[<>=!]/.test(v) ? v : `=${v}`}`).join(", "); const row = (label: string, value: string, flag = false) => (
{label}
{value}
); return (

{view.name}

{row("filters", filters, drifted)} {row("sort", `${view.sort.by}, ${view.sort.dir}`)} {row("columns", `${view.columns.shown.length} of ${view.columns.of}`)} {row("expanded rows", view.expandedRows ? "yes" : "no")} {row("range", view.range)}
{drifted ? (

{missing.map(([k, v]) => `${k}=${v}`).join(", ")} no longer exists · {rows} rows

) : (
{row("absolute range", "not kept", true)}
)}

Who owns it

s && onScopeChange(s as Scope)} aria-label="Who owns it" className="mt-1.5 justify-start gap-1" > {(Object.keys(SCOPES) as Scope[]).map((s) => ( {SCOPES[s].label} ))}

{SCOPES[view.scope].hint(view)}

); } ──────────────────────────────────────────────────────────────────────── // demo.tsx ──────────────────────────────────────────────────────────────────────── import { useState } from "react"; import { SavedViewCard, type SavedView, type Scope } from "./SavedViewCard"; /** * Two views. Morning triage is a shared view that still resolves. The second * filters on a service that was decommissioned, and says so instead of * quietly returning an empty table. */ const SERVICES = ["cart", "checkout", "search", "auth"]; const exists = (dimension: string, value: string) => dimension !== "service" || SERVICES.includes(value); const MORNING: SavedView = { name: "Morning triage", scope: "shared", owner: "Priya", filters: { env: "prod", sev: ">=2" }, sort: { by: "last seen", dir: "desc" }, columns: { shown: ["title", "service", "sev", "count", "first seen", "last seen", "owner"], of: 14 }, expandedRows: true, range: "last 24h", }; const LEGACY: SavedView = { name: "Legacy cart errors", scope: "personal", owner: "Priya", filters: { service: "legacy-cart" }, sort: { by: "count", dir: "desc" }, columns: { shown: ["title", "count", "last seen"], of: 14 }, expandedRows: false, range: "last 7d", }; export default function Demo() { const [scope, setScope] = useState(MORNING.scope); const open = (v: SavedView) => { location.hash = `#view/${encodeURIComponent(v.name)}`; }; return (
{}} />
); }