a3a5a10514
- Workflows UI: full page with definitions/instances tabs, step editor, instance detail with approve/reject - Dedup/Merge UI: duplicate detection, side-by-side comparison, field-level merge dialog, merge history - Import/Export UI: import wizard (dry-run preview), export panel (CSV/XLSX), backend export route added - Print/PDF: PrintButton component, print.css, integrated in Contacts/Calendar/Reports/ContactDetail - Backend: GET /api/v1/export endpoint, export_companies_csv() service function - Routes: /workflows, /contacts/dedup, /import-export registered - Menu items: Workflows, Import/Export, Duplikate added to automation plugin manifest - IMPLEMENTATION_PLAN.md: audit-corrected plan for all 14 remaining features
67 lines
2.3 KiB
TypeScript
67 lines
2.3 KiB
TypeScript
import { apiClient } from './client';
|
|
|
|
// ─── Types ──────────────────────────────────────────────────────────────────
|
|
|
|
export interface ImportResult {
|
|
total?: number;
|
|
created?: number;
|
|
updated?: number;
|
|
errors?: string[];
|
|
warnings?: string[];
|
|
rows?: Record<string, unknown>[];
|
|
preview?: boolean;
|
|
}
|
|
|
|
export type EntityType = 'companies' | 'contacts';
|
|
export type ExportFormat = 'csv' | 'xlsx';
|
|
|
|
// ─── Import ─────────────────────────────────────────────────────────────────
|
|
|
|
/**
|
|
* Import a CSV file. When dryRun is true, a preview is returned without
|
|
* writing to the database.
|
|
*/
|
|
export async function importCsv(
|
|
file: File,
|
|
entityType: string,
|
|
dryRun: boolean
|
|
): Promise<ImportResult> {
|
|
const url = dryRun ? '/import/preview' : '/import';
|
|
const formData = new FormData();
|
|
formData.append('file', file);
|
|
formData.append('entity_type', entityType);
|
|
|
|
const response = await apiClient.post<ImportResult>(url, formData, {
|
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
});
|
|
return response.data;
|
|
}
|
|
|
|
// ─── Export ─────────────────────────────────────────────────────────────────
|
|
|
|
/**
|
|
* Export data as CSV or XLSX and trigger a browser download.
|
|
*/
|
|
export async function exportData(
|
|
entityType: string,
|
|
format: string
|
|
): Promise<void> {
|
|
const url = `/export?entity_type=${encodeURIComponent(entityType)}&format=${encodeURIComponent(format)}`;
|
|
const response = await apiClient.get(url, { responseType: 'blob' });
|
|
|
|
const blob = new Blob([response.data], {
|
|
type: format === 'xlsx'
|
|
? 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
: 'text/csv',
|
|
});
|
|
|
|
const blobUrl = URL.createObjectURL(blob);
|
|
const link = document.createElement('a');
|
|
link.href = blobUrl;
|
|
link.download = `${entityType}_export.${format}`;
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
URL.revokeObjectURL(blobUrl);
|
|
}
|