- améliore l'export/import (format de fichiers en paramètres, amélioration de la robustesse, )
- ajout bouton tout effacer des propositions et participants
This commit is contained in:
@@ -23,15 +23,34 @@ export function parseCSV(file: File): Promise<ParsedFileData> {
|
||||
return;
|
||||
}
|
||||
|
||||
const headers = lines[0].split(',').map(h => h.trim().replace(/"/g, ''));
|
||||
const data = lines.slice(1).map(line => {
|
||||
const values = line.split(',').map(v => v.trim().replace(/"/g, ''));
|
||||
const row: any = {};
|
||||
headers.forEach((header, index) => {
|
||||
row[header] = values[index] || '';
|
||||
// Trouver la ligne d'en-têtes (ignorer les lignes de titre et vides)
|
||||
let headerLineIndex = 0;
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i].trim();
|
||||
// Si la ligne contient des virgules et ressemble à des en-têtes
|
||||
if (line.includes(',') && !line.toLowerCase().includes('modèle') && !line.toLowerCase().includes('liste')) {
|
||||
headerLineIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const headers = lines[headerLineIndex].split(',').map(h => h.trim().replace(/"/g, ''));
|
||||
const dataLines = lines.slice(headerLineIndex + 1);
|
||||
|
||||
const data = dataLines
|
||||
.filter(line => line.trim()) // Ignorer les lignes vides
|
||||
.map(line => {
|
||||
const values = line.split(',').map(v => v.trim().replace(/"/g, ''));
|
||||
const row: any = {};
|
||||
headers.forEach((header, index) => {
|
||||
row[header] = values[index] || '';
|
||||
});
|
||||
return row;
|
||||
})
|
||||
.filter(row => {
|
||||
// Ignorer les lignes où tous les champs sont vides
|
||||
return Object.values(row).some(value => value && value.toString().trim());
|
||||
});
|
||||
return row;
|
||||
});
|
||||
|
||||
resolve({ data, headers });
|
||||
} catch (error) {
|
||||
@@ -62,16 +81,39 @@ export function parseExcel(file: File): Promise<ParsedFileData> {
|
||||
return;
|
||||
}
|
||||
|
||||
const headers = jsonData[0] as string[];
|
||||
const rows = jsonData.slice(1) as any[][];
|
||||
// Trouver la ligne d'en-têtes (ignorer les lignes de titre et vides)
|
||||
let headerLineIndex = 0;
|
||||
for (let i = 0; i < jsonData.length; i++) {
|
||||
const row = jsonData[i] as any[];
|
||||
if (row && row.length > 0) {
|
||||
const firstCell = row[0];
|
||||
// Si la première cellule ressemble à un en-tête et pas à un titre
|
||||
if (firstCell && typeof firstCell === 'string' &&
|
||||
!firstCell.toLowerCase().includes('modèle') &&
|
||||
!firstCell.toLowerCase().includes('liste') &&
|
||||
!firstCell.toLowerCase().includes('propositions')) {
|
||||
headerLineIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const headers = (jsonData[headerLineIndex] as string[]).filter(h => h && h.toString().trim());
|
||||
const rows = jsonData.slice(headerLineIndex + 1) as any[][];
|
||||
|
||||
const parsedData = rows.map(row => {
|
||||
const rowData: any = {};
|
||||
headers.forEach((header, index) => {
|
||||
rowData[header] = row[index] || '';
|
||||
const parsedData = rows
|
||||
.filter(row => row && row.length > 0) // Ignorer les lignes vides
|
||||
.map(row => {
|
||||
const rowData: any = {};
|
||||
headers.forEach((header, index) => {
|
||||
rowData[header] = row[index] || '';
|
||||
});
|
||||
return rowData;
|
||||
})
|
||||
.filter(rowData => {
|
||||
// Ignorer les lignes où tous les champs sont vides
|
||||
return Object.values(rowData).some(value => value && value.toString().trim());
|
||||
});
|
||||
return rowData;
|
||||
});
|
||||
|
||||
resolve({ data: parsedData, headers });
|
||||
} catch (error) {
|
||||
@@ -84,22 +126,47 @@ export function parseExcel(file: File): Promise<ParsedFileData> {
|
||||
|
||||
export function getExpectedColumns(type: 'propositions' | 'participants'): string[] {
|
||||
if (type === 'propositions') {
|
||||
return ['title', 'description', 'author_first_name', 'author_last_name', 'author_email'];
|
||||
return ['Titre', 'Description', 'Prénom', 'Nom', 'Email'];
|
||||
} else {
|
||||
return ['first_name', 'last_name', 'email'];
|
||||
return ['Prénom', 'Nom', 'Email'];
|
||||
}
|
||||
}
|
||||
|
||||
export function downloadTemplate(type: 'propositions' | 'participants'): void {
|
||||
export async function downloadTemplate(type: 'propositions' | 'participants'): Promise<void> {
|
||||
const columns = getExpectedColumns(type);
|
||||
const csvContent = columns.join(',') + '\n';
|
||||
const blob = new Blob([csvContent], { type: 'text/csv' });
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `template_${type}.csv`;
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
|
||||
// Importer dynamiquement la fonction pour éviter les dépendances circulaires
|
||||
const { getExportFileFormat, generateExportFile, downloadExportFile } = await import('./export-utils');
|
||||
const format = await getExportFileFormat();
|
||||
|
||||
// Créer la matrice de données avec les en-têtes
|
||||
const matrix: string[][] = [];
|
||||
|
||||
// Pour les formats Excel/ODS, ajouter un titre
|
||||
if (format !== 'csv') {
|
||||
matrix.push([`Modèle d'import - ${type === 'propositions' ? 'Propositions' : 'Participants'}`]);
|
||||
matrix.push([]); // Ligne vide
|
||||
}
|
||||
|
||||
matrix.push(columns); // En-têtes des colonnes
|
||||
|
||||
// Ajouter quelques lignes d'exemple
|
||||
if (type === 'propositions') {
|
||||
matrix.push(['Exemple de proposition', 'Description de la proposition', 'Jean', 'Dupont', 'jean.dupont@example.com']);
|
||||
matrix.push(['Autre proposition', 'Autre description', 'Marie', 'Martin', 'marie.martin@example.com']);
|
||||
} else {
|
||||
matrix.push(['Jean', 'Dupont', 'jean.dupont@example.com']);
|
||||
matrix.push(['Marie', 'Martin', 'marie.martin@example.com']);
|
||||
}
|
||||
|
||||
// Générer le fichier dans le format configuré
|
||||
const data = generateExportFile(matrix, format);
|
||||
|
||||
// Créer le nom de fichier avec l'extension appropriée
|
||||
const filename = `template_${type}.${format}`;
|
||||
|
||||
// Télécharger le fichier
|
||||
downloadExportFile(data, filename, format);
|
||||
}
|
||||
|
||||
export function validateFileType(file: File): { isValid: boolean; error?: string } {
|
||||
|
||||
Reference in New Issue
Block a user