Checkpoint: Ajout colonne "Source import" (Email / Dossier / Fichier) dans l'historique des imports : schéma DB migré, backend mis à jour (routers.ts, emailImportService.ts, folderImportService.ts), frontend History.tsx avec badges colorés dans le tableau et le dialog de détails.
This commit is contained in:
@@ -23,6 +23,9 @@ import {
|
||||
RotateCcw,
|
||||
Package,
|
||||
X,
|
||||
Upload,
|
||||
FolderOpen,
|
||||
Mail,
|
||||
} from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { toast } from "sonner";
|
||||
@@ -307,6 +310,7 @@ export default function History() {
|
||||
<TableRow className="bg-gray-50">
|
||||
<TableHead className="font-semibold">Fichier importé</TableHead>
|
||||
<TableHead className="font-semibold">Date d'import</TableHead>
|
||||
<TableHead className="font-semibold text-center">Source</TableHead>
|
||||
<TableHead className="font-semibold text-center">Détectées</TableHead>
|
||||
<TableHead className="font-semibold text-center">Importées</TableHead>
|
||||
<TableHead className="font-semibold text-center">Doublons</TableHead>
|
||||
@@ -326,6 +330,24 @@ export default function History() {
|
||||
<TableCell className="text-sm text-gray-600">
|
||||
{new Date(log.importedAt).toLocaleString("fr-FR")}
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
{log.importSource === "email" ? (
|
||||
<span className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-700 border border-blue-200">
|
||||
<Mail className="h-3 w-3" />
|
||||
Email
|
||||
</span>
|
||||
) : log.importSource === "folder" ? (
|
||||
<span className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-700 border border-purple-200">
|
||||
<FolderOpen className="h-3 w-3" />
|
||||
Dossier
|
||||
</span>
|
||||
) : (
|
||||
<span className="inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-700 border border-gray-200">
|
||||
<Upload className="h-3 w-3" />
|
||||
Fichier
|
||||
</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
<Badge variant="outline" className="font-mono">
|
||||
{log.totalInvoicesDetected}
|
||||
@@ -408,6 +430,18 @@ export default function History() {
|
||||
<p className="text-xs text-gray-500 font-medium mb-1">Date d'import</p>
|
||||
<p className="text-sm font-semibold">{new Date(selectedLog.importedAt).toLocaleString("fr-FR")}</p>
|
||||
</div>
|
||||
<div className="bg-gray-50 rounded-lg p-3">
|
||||
<p className="text-xs text-gray-500 font-medium mb-1">Source import</p>
|
||||
<p className="text-sm font-semibold">
|
||||
{selectedLog.importSource === "email" ? (
|
||||
<span className="inline-flex items-center gap-1 text-blue-700"><Mail className="h-4 w-4" /> Email</span>
|
||||
) : selectedLog.importSource === "folder" ? (
|
||||
<span className="inline-flex items-center gap-1 text-purple-700"><FolderOpen className="h-4 w-4" /> Dossier</span>
|
||||
) : (
|
||||
<span className="inline-flex items-center gap-1 text-gray-700"><Upload className="h-4 w-4" /> Fichier</span>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Statistiques */}
|
||||
|
||||
1
drizzle/0032_volatile_jocasta.sql
Normal file
1
drizzle/0032_volatile_jocasta.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE `importLogs` ADD `importSource` enum('file','folder','email') DEFAULT 'file' NOT NULL;
|
||||
2155
drizzle/meta/0032_snapshot.json
Normal file
2155
drizzle/meta/0032_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -225,6 +225,13 @@
|
||||
"when": 1781021650065,
|
||||
"tag": "0031_mean_squadron_supreme",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 32,
|
||||
"version": "5",
|
||||
"when": 1781690960721,
|
||||
"tag": "0032_volatile_jocasta",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -223,6 +223,8 @@ export const importLogs = mysqlTable("importLogs", {
|
||||
duplicateDetails: text("duplicateDetails"), // JSON array of duplicate invoice info
|
||||
errorDetails: text("errorDetails"), // JSON array of error messages
|
||||
warningMessage: text("warningMessage"), // Warning message (e.g. quota exhausted)
|
||||
/** Source du mode d'import : 'file' = upload manuel, 'folder' = dossier automatique, 'email' = import par email */
|
||||
importSource: mysqlEnum("importSource", ["file", "folder", "email"]).default("file").notNull(),
|
||||
importedAt: timestamp("importedAt").defaultNow().notNull(),
|
||||
});
|
||||
|
||||
|
||||
@@ -232,6 +232,7 @@ async function processEmailAttachment(
|
||||
duplicateDetails: duplicateDetails.length > 0 ? JSON.stringify(duplicateDetails) : null,
|
||||
errorDetails: errorDetails.length > 0 ? JSON.stringify(errorDetails) : null,
|
||||
warningMessage,
|
||||
importSource: "email",
|
||||
});
|
||||
|
||||
console.log(`[EmailImport] Successfully processed attachment: ${fileName}`);
|
||||
|
||||
@@ -191,6 +191,7 @@ async function processFolderFile(
|
||||
errors: errorsCount,
|
||||
duplicateDetails: duplicateDetails.length > 0 ? JSON.stringify(duplicateDetails) : null,
|
||||
errorDetails: errorDetails.length > 0 ? JSON.stringify(errorDetails) : null,
|
||||
importSource: "folder",
|
||||
});
|
||||
|
||||
// Move file to processed folder
|
||||
|
||||
@@ -370,6 +370,7 @@ export const appRouter = router({
|
||||
errors: errorsCount,
|
||||
duplicateDetails: JSON.stringify(duplicateDetails),
|
||||
errorDetails: JSON.stringify(errorDetails),
|
||||
importSource: "file",
|
||||
});
|
||||
|
||||
} catch (error: any) {
|
||||
|
||||
8
todo.md
8
todo.md
@@ -667,3 +667,11 @@
|
||||
- [x] Job cron WebDev : vérification périodique selon fréquence configurée (setInterval en mémoire)
|
||||
- [x] Frontend VentilationFreePro.tsx : wrapper Tabs (onglet 1 = import manuel, onglet 2 = paramétrage)
|
||||
- [x] Onglet Paramétrage : formulaire credentials FreePro web, fréquence, date antériorité, bouton "Forcer récupération", statut dernière récupération
|
||||
|
||||
## Colonne Source import dans l'historique des imports
|
||||
- [x] Ajouter colonne importSource (file/folder/email) dans la table importLogs (schéma + migration)
|
||||
- [x] Enregistrer importSource="file" lors d'un import manuel (routers.ts)
|
||||
- [x] Enregistrer importSource="email" lors d'un import par email (emailImportService.ts)
|
||||
- [x] Enregistrer importSource="folder" lors d'un import par dossier (folderImportService.ts)
|
||||
- [x] Afficher la colonne "Source" avec badge coloré dans le tableau History.tsx (Email=bleu, Dossier=violet, Fichier=gris)
|
||||
- [x] Afficher la source dans le dialog de détails de l'import
|
||||
|
||||
Reference in New Issue
Block a user