feat(FN-3786): add reports dashboard view and comparison tooling
Adds a Reports dashboard view (`ReportsView`) to the reports plugin with a full supporting stack of components (`ReportComparisonDrawer`, `ReportDetailPanel`, `ReportFiltersBar`, `ReportListItem`, `ReportEmptyState`), hooks (`useReports`, `useReportPreview`, `useReportSectionDiff`, `useViewportMode` Fusion-Task-Id: FN-3786
This commit is contained in:
53
plugins/fusion-plugin-reports/src/dashboard/api.ts
Normal file
53
plugins/fusion-plugin-reports/src/dashboard/api.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import type { ReportRecord } from "./types.js";
|
||||
|
||||
const BASE = "/api/plugins/reports";
|
||||
|
||||
interface ListReportsParams {
|
||||
cadence?: string;
|
||||
status?: string;
|
||||
from?: string;
|
||||
to?: string;
|
||||
q?: string;
|
||||
agentId?: string;
|
||||
projectId?: string;
|
||||
}
|
||||
|
||||
function qp(params: Record<string, string | undefined>): string {
|
||||
const entries = Object.entries(params).filter(([, value]) => typeof value === "string" && value.length > 0) as Array<[string, string]>;
|
||||
if (entries.length === 0) return "";
|
||||
return `?${entries.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`).join("&")}`;
|
||||
}
|
||||
|
||||
async function request<T>(path: string, init?: RequestInit, responseType: "json" | "text" = "json"): Promise<T> {
|
||||
const response = await fetch(`${BASE}${path}`, init);
|
||||
if (!response.ok) {
|
||||
let message = `${response.status} ${response.statusText}`;
|
||||
try {
|
||||
const data = (await response.json()) as { error?: string };
|
||||
if (data.error) message = data.error;
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
throw new Error(message);
|
||||
}
|
||||
if (responseType === "text") return (await response.text()) as T;
|
||||
return (await response.json()) as T;
|
||||
}
|
||||
|
||||
export async function listReports(params: ListReportsParams = {}): Promise<ReportRecord[]> {
|
||||
const data = await request<{ reports: ReportRecord[] }>(`/reports${qp({ ...params })}`);
|
||||
return data.reports;
|
||||
}
|
||||
|
||||
export async function getReport(id: string, projectId?: string): Promise<ReportRecord> {
|
||||
const data = await request<{ report: ReportRecord }>(`/reports/${encodeURIComponent(id)}${qp({ projectId })}`);
|
||||
return data.report;
|
||||
}
|
||||
|
||||
export function getReportPreviewHtml(id: string, projectId?: string): Promise<string> {
|
||||
return request<string>(`/reports/${encodeURIComponent(id)}/preview.html${qp({ projectId })}`, undefined, "text");
|
||||
}
|
||||
|
||||
export function getReportExportUrl(id: string, projectId?: string): string {
|
||||
return `${BASE}/reports/${encodeURIComponent(id)}/export.html${qp({ projectId })}`;
|
||||
}
|
||||
Reference in New Issue
Block a user