Files
ITWorx_MCP_Hub-Public/apps/web/src/routing.ts
T

24 lines
1.6 KiB
TypeScript

import { useCallback, useEffect, useState } from "react";
import type { ResourceKind } from "./contracts";
const resourceRoutes: Record<string, ResourceKind> = { "/projects": "projects", "/servers": "servers", "/tools": "tools", "/connectors": "connectors", "/clients": "clients", "/policies": "policies", "/audit": "audit" };
export function usePath() {
const [path, setPath] = useState(window.location.pathname + window.location.search);
useEffect(() => { const onPopState = () => setPath(window.location.pathname + window.location.search); window.addEventListener("popstate", onPopState); return () => window.removeEventListener("popstate", onPopState); }, []);
const navigate = useCallback((next: string) => {
window.history.pushState({}, "", next);
setPath(next);
}, []);
return [path, navigate] as const;
}
export function basePath(path: string) { return (path.split("?")[0] ?? "").replace(/\/$/, "") || "/"; }
export function projectDetailId(path: string): string | null { return decodeDetailId(path, "projects"); }
export function connectorDetailId(path: string): string | null { return decodeDetailId(path, "connectors"); }
function decodeDetailId(path: string, collection: "projects" | "connectors"): string | null {
const match = new RegExp(`^/${collection}/([^/]+)$`).exec(basePath(path));
if (!match?.[1]) return null;
try { return decodeURIComponent(match[1]); } catch { return null; }
}
export function resourceKind(path: string): ResourceKind | null { const base = basePath(path); if (projectDetailId(base)) return "projects"; if (connectorDetailId(base)) return null; return resourceRoutes[base] ?? null; }