import type { Status } from "@/lib/issue-meta"; // The issue list's view state (scope, layout, grouping, filters) and its URL form. // Shared by the server page, which parses it, and the client tracker. export type Scope = "all" | "active" | "backlog"; export type ViewMode = "list" | "board"; export type Grouping = "status" | "priority" | "assignee" | "none"; export type Ordering = "manual" | "priority" | "updated" | "created"; export type TrackerView = { scope: Scope; view: ViewMode; group: Grouping; order: Ordering; q: string; assignee: string[]; priority: string[]; label: string[]; }; export const DEFAULT_VIEW: TrackerView = { scope: "all", view: "list", group: "status", order: "manual", q: "", assignee: [], priority: [], label: [], }; export const SCOPE_STATUSES: Record = { all: null, active: ["todo", "in_progress", "in_review"], backlog: ["backlog"], }; /** Reads a view from URL search params, ignoring anything unknown. */ export function parseView(params: Record): TrackerView { const one = (key: string) => (typeof params[key] === "string" ? (params[key] as string) : ""); const list = (key: string) => one(key).split(",").filter(Boolean); const pick = (value: string, allowed: readonly T[], fallback: T) => (allowed as readonly string[]).includes(value) ? (value as T) : fallback; return { scope: pick(one("scope"), ["all", "active", "backlog"], DEFAULT_VIEW.scope), view: pick(one("view"), ["list", "board"], DEFAULT_VIEW.view), group: pick(one("group"), ["status", "priority", "assignee", "none"], DEFAULT_VIEW.group), order: pick(one("order"), ["manual", "priority", "updated", "created"], DEFAULT_VIEW.order), q: one("q"), assignee: list("assignee"), priority: list("priority"), label: list("label"), }; } export function viewToQuery(view: TrackerView) { const params = new URLSearchParams(); for (const key of Object.keys(DEFAULT_VIEW) as (keyof TrackerView)[]) { const value = view[key]; const text = Array.isArray(value) ? value.join(",") : value; const fallback = DEFAULT_VIEW[key]; if (text && text !== (Array.isArray(fallback) ? fallback.join(",") : fallback)) params.set(key, text); } const query = params.toString(); return query ? `?${query}` : ""; }