feat: bouton Tester l'upload SharePoint + tooltip erreur SP dans historique BAP

This commit is contained in:
Manus
2026-05-06 10:18:46 -04:00
parent 6c21c71660
commit 94844b0589
3 changed files with 104 additions and 4 deletions

View File

@@ -291,11 +291,21 @@ export default function BapHistory() {
)}
</div>
) : (entry as any).sharepointUploadStatus === 'error' ? (
<div className="flex items-center gap-1" title={(entry as any).sharepointUploadError || 'Erreur SharePoint'}>
<div className="flex items-center gap-1 text-red-600">
<CloudOff className="h-3.5 w-3.5" />
<span className="text-xs">SP Erreur</span>
<div
className="flex items-center gap-1 cursor-help"
title={(entry as any).sharepointUploadError || 'Erreur SharePoint'}
>
<div className="flex items-center gap-1 text-red-600 border border-red-200 bg-red-50 rounded px-1.5 py-0.5">
<CloudOff className="h-3.5 w-3.5 shrink-0" />
<span className="text-xs font-medium">SP Erreur</span>
</div>
{(entry as any).sharepointUploadError && (
<span
className="hidden group-hover:block absolute z-50 max-w-xs bg-gray-900 text-white text-xs rounded p-2 shadow-lg"
>
{(entry as any).sharepointUploadError}
</span>
)}
</div>
) : entry.exportPath ? (
<div className="flex items-center gap-1">

View File

@@ -34,6 +34,7 @@ export default function ImportSettings() {
const startFolderServiceMutation = trpc.folderImportService.start.useMutation();
const stopFolderServiceMutation = trpc.folderImportService.stop.useMutation();
const testAzureConnectionMutation = trpc.importSettings.testAzureConnection.useMutation();
const testSharePointUploadMutation = trpc.importSettings.testSharePointUpload.useMutation();
// Manual import
const [manualImportEnabled, setManualImportEnabled] = useState(true);
@@ -770,6 +771,47 @@ export default function ImportSettings() {
</Button>
<p className="text-xs text-muted-foreground mt-1">Vérifie le token OAuth2 et l'accès au site SharePoint</p>
</div>
{/* Bouton test upload réel */}
<div className="pt-1">
<Button
type="button"
variant="outline"
size="sm"
onClick={async () => {
try {
const result = await testSharePointUploadMutation.mutateAsync();
if (result.success) {
toast.success(
result.webUrl
? `Fichier test déposé avec succès ! Cliquez pour l'ouvrir`
: `Fichier test déposé avec succès dans SharePoint`,
{
duration: 8000,
action: result.webUrl ? { label: 'Ouvrir', onClick: () => window.open(result.webUrl!, '_blank') } : undefined,
}
);
} else {
toast.error(`Échec upload test : ${result.error}`, { duration: 10000 });
if ((result as any).debugInfo) {
console.error('[SharePoint debug]', (result as any).debugInfo);
}
}
} catch (e: any) {
toast.error("Erreur : " + (e?.message || "impossible de tester l'upload"));
}
}}
disabled={testSharePointUploadMutation.isPending || !azureTenantId || !azureClientId || !azureClientSecret || !exportFolder}
className="gap-2 border-blue-300 text-blue-700 hover:bg-blue-50"
>
{testSharePointUploadMutation.isPending ? (
<><Loader2 className="h-4 w-4 animate-spin" />Upload test en cours...</>
) : (
<><Upload className="h-4 w-4" />Tester l'upload SharePoint</>
)}
</Button>
<p className="text-xs text-muted-foreground mt-1">Dépose un fichier texte de 1 Ko dans le dossier SharePoint pour valider les permissions d'upload</p>
</div>
</div>
</div>
)}

View File

@@ -1569,6 +1569,54 @@ export const appRouter = router({
return { success: false, error: err.message || 'Erreur inconnue' };
}
}),
testSharePointUpload: protectedProcedure
.mutation(async ({ ctx }) => {
const settings = await getImportSettingsByUser(ctx.user.id);
const tenantId = (settings as any)?.azureTenantId;
const clientId = (settings as any)?.azureClientId;
const clientSecret = (settings as any)?.azureClientSecret;
const sharepointUrl = settings?.exportFolder;
if (!tenantId || !clientId || !clientSecret) {
return { success: false, error: 'Credentials Azure AD manquants (Tenant ID, Client ID ou Secret)' };
}
if (!sharepointUrl) {
return { success: false, error: 'URL SharePoint non configurée dans le dossier d\'export' };
}
try {
const { uploadToSharePoint } = await import('./sharepoint');
// Créer un fichier test de 1 Ko
const testContent = `Test upload SharePoint - ${new Date().toISOString()}\nApplication : Dématérialisation Facturation\nCe fichier peut être supprimé.`;
const testBuffer = Buffer.from(testContent, 'utf-8');
const testFileName = `test-upload-${Date.now()}.txt`;
const result = await uploadToSharePoint(
{ tenantId, clientId, clientSecret, sharepointUrl },
testBuffer,
testFileName
);
if (result.success) {
return {
success: true,
message: `Fichier test déposé avec succès dans SharePoint`,
webUrl: result.webUrl,
fileName: testFileName,
debugInfo: result.debugInfo,
};
} else {
return {
success: false,
error: result.error || 'Échec de l\'upload test',
debugInfo: result.debugInfo,
};
}
} catch (err: any) {
return { success: false, error: err.message || 'Erreur inconnue' };
}
}),
}),
// ============= DEPARTMENT LIST ROUTES =============