/** * Report Generator plugin API client. * * All requests use the shared `apiClient` (`baseURL: '/api/v1'`) and target the * Report Generator plugin routes under `/reports/...`. */ import { apiClient, apiDelete, apiGet, apiPost, apiPut } from './client'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; // ─── Types ───────────────────────────────────────────────────────────────── export type OutputFormat = 'csv' | 'excel' | 'json' | 'pdf' | 'print'; export type TemplateType = 'jinja2' | 'sql'; export interface ReportTemplate { id: string; name: string; description: string; template_type: TemplateType; content: string; output_format: OutputFormat; created_by: string; deleted_at?: string | null; created_at?: string | null; updated_at?: string | null; } export interface TemplateCreateInput { name: string; description?: string; template_type?: TemplateType; content: string; output_format?: OutputFormat; } export interface TemplateUpdateInput { name?: string; description?: string; template_type?: TemplateType; content?: string; output_format?: OutputFormat; } export interface ReportGenerateInput { template_id: string; data: Record; output_format?: OutputFormat; } export interface PresetReportInfo { key: string; name: string; description: string; icon: string; output_formats: OutputFormat[]; } export interface PresetGenerateInput { preset: string; output_format: OutputFormat; parameters: Record; } // ─── React Query Hooks ───────────────────────────────────────────────────── const QUERY_KEYS = { templates: ['reports', 'templates'] as const, presets: ['reports', 'presets'] as const, }; /** Fetch all report templates */ export function useReportTemplates() { return useQuery({ queryKey: QUERY_KEYS.templates, queryFn: () => apiGet('/reports/templates'), }); } /** Fetch a single report template by ID */ export function useReportTemplate(templateId: string | null) { return useQuery({ queryKey: ['reports', 'templates', templateId], queryFn: () => apiGet(`/reports/templates/${templateId}`), enabled: !!templateId, }); } /** Create a new report template */ export function useCreateReportTemplate() { const qc = useQueryClient(); return useMutation({ mutationFn: (input: TemplateCreateInput) => apiPost('/reports/templates', input), onSuccess: () => qc.invalidateQueries({ queryKey: QUERY_KEYS.templates }), }); } /** Update an existing report template */ export function useUpdateReportTemplate() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ id, ...input }: TemplateUpdateInput & { id: string }) => apiPut(`/reports/templates/${id}`, input), onSuccess: () => qc.invalidateQueries({ queryKey: QUERY_KEYS.templates }), }); } /** Delete a report template (soft-delete) */ export function useDeleteReportTemplate() { const qc = useQueryClient(); return useMutation({ mutationFn: (id: string) => apiDelete(`/reports/templates/${id}`), onSuccess: () => qc.invalidateQueries({ queryKey: QUERY_KEYS.templates }), }); } /** Fetch all preset report templates */ export function useReportPresets() { return useQuery({ queryKey: QUERY_KEYS.presets, queryFn: async () => { const res = await apiGet('/reports/presets'); return Array.isArray(res) ? res : res.items ?? []; }, }); } /** Generate a report from a template — returns a file download (blob) */ export function useGenerateReport() { return useMutation({ mutationFn: async (input: ReportGenerateInput) => { const response = await apiClient.post('/reports/generate', input, { responseType: 'blob', }); return response; }, }); } /** Generate a preset report — returns a file download (blob) */ export function useGeneratePresetReport() { return useMutation({ mutationFn: async (input: PresetGenerateInput) => { const response = await apiClient.post('/reports/presets/generate', input, { responseType: 'blob', }); return response; }, }); } // ─── Download Helper ─────────────────────────────────────────────────────── /** Trigger a browser download from a blob response */ export function downloadBlob(blob: Blob, filename: string) { const url = window.URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = filename; document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(url); }