Add DebugView component to show raw lore status data for visual verification that the data pipeline works end-to-end: - Frontend -> Tauri IPC -> Rust backend -> lore CLI -> parsed data New files: - src/components/DebugView.tsx - Debug component with health indicator - src/hooks/useLoreData.ts - TanStack Query hook for lore status - tests/components/DebugView.test.tsx - Component tests - tests/hooks/useLoreData.test.ts - Hook tests Modified: - src/App.tsx - Add QueryClientProvider wrapper - src/stores/nav-store.ts - Add 'debug' ViewId - src/components/AppShell.tsx - Add Debug nav tab and view routing - tests/components/AppShell.test.tsx - Update tests for new nav
114 lines
3.9 KiB
TypeScript
114 lines
3.9 KiB
TypeScript
/**
|
|
* DebugView -- displays raw lore data for debugging.
|
|
*
|
|
* Shows the raw JSON response from get_lore_status for visual
|
|
* verification that the data pipeline is working end-to-end.
|
|
* Access via the debug view in the navigation.
|
|
*/
|
|
|
|
import { useLoreData } from "@/hooks/useLoreData";
|
|
|
|
export function DebugView(): React.ReactElement {
|
|
const { data, isLoading, error, refetch } = useLoreData();
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div className="flex min-h-[calc(100vh-3rem)] items-center justify-center">
|
|
<div className="text-zinc-500">Loading lore data...</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (error) {
|
|
return (
|
|
<div className="flex min-h-[calc(100vh-3rem)] flex-col items-center justify-center gap-4">
|
|
<div className="text-red-500">Error: {error.message}</div>
|
|
<button
|
|
onClick={() => refetch()}
|
|
className="rounded bg-zinc-700 px-3 py-1.5 text-sm text-zinc-200 hover:bg-zinc-600"
|
|
>
|
|
Retry
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="p-4">
|
|
<div className="mb-4 flex items-center justify-between">
|
|
<h2 className="text-lg font-semibold text-zinc-200">Lore Debug</h2>
|
|
<button
|
|
onClick={() => refetch()}
|
|
className="rounded bg-zinc-700 px-3 py-1.5 text-sm text-zinc-200 hover:bg-zinc-600"
|
|
>
|
|
Refresh
|
|
</button>
|
|
</div>
|
|
|
|
{/* Status overview */}
|
|
<div className="mb-6 rounded-lg border border-zinc-800 bg-zinc-900 p-4">
|
|
<h3 className="mb-3 text-sm font-medium text-zinc-400">Status</h3>
|
|
<div className="space-y-2">
|
|
<div className="flex items-center gap-2">
|
|
<span className="text-zinc-500">Health:</span>
|
|
<div
|
|
data-testid="health-indicator"
|
|
className={`h-2.5 w-2.5 rounded-full ${
|
|
data?.is_healthy ? "bg-green-500" : "bg-red-500"
|
|
}`}
|
|
/>
|
|
<span className="text-zinc-300">
|
|
{data?.is_healthy ? "Healthy" : "Unhealthy"}
|
|
</span>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<span className="text-zinc-500">Last Sync:</span>
|
|
<span className="font-mono text-zinc-300">
|
|
{data?.last_sync ?? "never"}
|
|
</span>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<span className="text-zinc-500">Message:</span>
|
|
<span className="text-zinc-300">{data?.message}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Summary counts */}
|
|
{data?.summary && (
|
|
<div className="mb-6 rounded-lg border border-zinc-800 bg-zinc-900 p-4">
|
|
<h3 className="mb-3 text-sm font-medium text-zinc-400">Summary</h3>
|
|
<div className="grid grid-cols-3 gap-4">
|
|
<div className="text-center">
|
|
<div className="text-2xl font-semibold text-zinc-200">
|
|
{data.summary.open_issues}
|
|
</div>
|
|
<div className="text-sm text-zinc-500">Open Issues</div>
|
|
</div>
|
|
<div className="text-center">
|
|
<div className="text-2xl font-semibold text-zinc-200">
|
|
{data.summary.authored_mrs}
|
|
</div>
|
|
<div className="text-sm text-zinc-500">Authored MRs</div>
|
|
</div>
|
|
<div className="text-center">
|
|
<div className="text-2xl font-semibold text-zinc-200">
|
|
{data.summary.reviewing_mrs}
|
|
</div>
|
|
<div className="text-sm text-zinc-500">Reviewing MRs</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Raw JSON output */}
|
|
<div className="rounded-lg border border-zinc-800 bg-zinc-900 p-4">
|
|
<h3 className="mb-3 text-sm font-medium text-zinc-400">Raw Response</h3>
|
|
<pre className="overflow-x-auto whitespace-pre-wrap font-mono text-xs text-zinc-300">
|
|
{JSON.stringify(data, null, 2)}
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|