feat(frontend): v2 artifact viewers for cte_plan/cte_result/phase
Add CtePlanViewer, CteResultViewer, and PhaseSummaryViewer to render the structured v2 payloads (schema_version: 2) the harness now emits for artifact-gate widgets, per contracts.md. Extract PreviewGrid from ResultsPanel as a reusable AG Grid component shared by CteResultViewer. ArtifactView dispatches to the new viewers on a schema_version/shape guard, falling back to the existing legacy renderers unchanged for older sessions and replay fixtures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { AgGridReact } from "ag-grid-react";
|
||||
import { AllCommunityModule, ModuleRegistry } from "ag-grid-community";
|
||||
|
||||
// Register AG Grid modules once at module load time
|
||||
ModuleRegistry.registerModules([AllCommunityModule]);
|
||||
|
||||
interface Props {
|
||||
columns: string[];
|
||||
rows: unknown[][];
|
||||
}
|
||||
|
||||
/** Reusable read-only preview grid: columns + row tuples → AG Grid. */
|
||||
export function PreviewGrid({ columns, rows }: Props) {
|
||||
const columnDefs = columns.map((col) => ({ field: col, headerName: col }));
|
||||
|
||||
const rowData = rows.map((row) => {
|
||||
const obj: Record<string, unknown> = {};
|
||||
columns.forEach((col, i) => {
|
||||
obj[col] = row[i];
|
||||
});
|
||||
return obj;
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="overflow-hidden rounded-xl border border-border/70 shadow-xs">
|
||||
<div className="ag-theme-alpine" style={{ height: 400, width: "100%" }}>
|
||||
<AgGridReact columnDefs={columnDefs} rowData={rowData} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user