CONTENT-WP-0004 keeps outgoing and incoming labels apart, limits the graph to two hops, and stores focus and detail in the URL. Assistant: grok Assistant-Session: 01a1531b-6698-7732-8587-f28ea604bcdf
37 lines
1.4 KiB
TypeScript
37 lines
1.4 KiB
TypeScript
import type { Metadata } from "next";
|
|
import { notFound } from "next/navigation";
|
|
import { GraphExplorer } from "@/components/GraphExplorer";
|
|
import { findGraph } from "@/lib/catalog";
|
|
|
|
function first(value: string | string[] | undefined): string | undefined {
|
|
return Array.isArray(value) ? value[0] : value;
|
|
}
|
|
|
|
export async function generateMetadata({ params }: { params: Promise<{ dataspace: string }> }): Promise<Metadata> {
|
|
const { dataspace } = await params;
|
|
const model = findGraph(dataspace);
|
|
if (!model) return { title: "Content Explorer" };
|
|
return { title: `Graph · ${model.dataspaceTitle} · Content Explorer` };
|
|
}
|
|
|
|
export default async function GraphPage({
|
|
params,
|
|
searchParams,
|
|
}: {
|
|
params: Promise<{ dataspace: string }>;
|
|
searchParams: Promise<Record<string, string | string[] | undefined>>;
|
|
}) {
|
|
const { dataspace } = await params;
|
|
const query = await searchParams;
|
|
const model = findGraph(dataspace);
|
|
if (!model) notFound();
|
|
const initial = new URLSearchParams();
|
|
const focus = first(query.focus);
|
|
const detail = first(query.detail);
|
|
const hops = first(query.hops);
|
|
if (focus) initial.set("focus", focus);
|
|
if (detail) initial.set("detail", detail);
|
|
if (hops) initial.set("hops", hops);
|
|
const initialSearch = initial.size > 0 ? `?${initial.toString()}` : "";
|
|
return <GraphExplorer model={model} initialSearch={initialSearch} />;
|
|
}
|