This commit is contained in:
Tomas Dvorak
2025-10-19 18:09:28 +02:00
parent abe127fb51
commit 9ccca365b3
40 changed files with 6885 additions and 20 deletions
+116
View File
@@ -0,0 +1,116 @@
import { api } from '../services/api';
/**
* Utility functions for exporting data
*/
/**
* Converts array of objects to CSV string
*/
export function arrayToCSV<T extends Record<string, any>>(
data: T[],
columns?: string[]
): string {
if (data.length === 0) return '';
const headers = columns || Object.keys(data[0]);
const rows = data.map((item) =>
headers.map((header) => {
const value = item[header];
// Escape CSV special characters
if (value === null || value === undefined) return '';
const stringValue = String(value);
if (stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n')) {
return `"${stringValue.replace(/"/g, '""')}"`;
}
return stringValue;
})
);
return [headers.join(','), ...rows.map((row) => row.join(','))].join('\n');
}
/**
* Triggers a file download in the browser
*/
export function downloadFile(content: string, filename: string, mimeType: string = 'text/plain') {
const blob = new Blob([content], { type: mimeType });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
}
/**
* Exports data to CSV file
*/
export function exportToCSV<T extends Record<string, any>>(
data: T[],
filename: string = 'export.csv',
columns?: string[]
) {
const csv = arrayToCSV(data, columns);
downloadFile(csv, filename, 'text/csv');
}
/**
* Exports data to JSON file
*/
export function exportToJSON<T>(data: T, filename: string = 'export.json') {
const json = JSON.stringify(data, null, 2);
downloadFile(json, filename, 'application/json');
}
/**
* Fetches and downloads export from API endpoint
*/
export async function exportFromAPI(
endpoint: string,
filename: string,
format: 'csv' | 'json' = 'csv'
): Promise<void> {
try {
const response = await api.get(endpoint, {
responseType: 'blob',
});
const url = URL.createObjectURL(response.data);
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
} catch (error) {
console.error('Export failed:', error);
throw error;
}
}
/**
* Copies data to clipboard
*/
export async function copyToClipboard(text: string): Promise<boolean> {
try {
await navigator.clipboard.writeText(text);
return true;
} catch (error) {
console.error('Failed to copy to clipboard:', error);
return false;
}
}
/**
* Formats date for export filenames
*/
export function getExportFilename(prefix: string, extension: string): string {
const date = new Date();
const dateStr = date.toISOString().split('T')[0];
const timeStr = date.toTimeString().split(' ')[0].replace(/:/g, '-');
return `${prefix}_${dateStr}_${timeStr}.${extension}`;
}