Refonte export PDF, colonne commentaire et UX résumés
- Export PDF: nouveau nommage AAAAMM/AAAA_Trajets_MATRICULE_PLAQUE.pdf, logo carré embarqué en en-tête, km formatés selon Precision_Distance, restructuration en-têtes (Domicile déplacé, période/année fusionnées au titre) - Correction bug: le nom de fichier suggéré au téléchargement ne remontait pas au frontend (CORS WithExposedHeaders manquant + composants résumé ne lisaient pas Content-Disposition) - Résumé mensuel: colonne Commentaire, sélecteur temporel unifié (auto-chargement), km selon précision - Résumé annuel: bouton Export PDF repositionné, km selon précision - Panneau totaux: renommage "Remboursement indicatif" + infobulles d'aide (icône) au lieu du texte permanent - Ajout de PdfServiceIntegrationTests (3 tests), 65/65 tests backend OK - Mise à jour requirements.md et design.md en conséquence
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { HttpClient, HttpParams } from '@angular/common/http';
|
||||
import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@@ -77,22 +77,46 @@ export class TrajetService {
|
||||
});
|
||||
}
|
||||
|
||||
/** Export PDF mensuel (GET /api/exports/mensuel/{annee}/{mois}). */
|
||||
exportPdfMensuel(annee: number, mois: number, vehiculeId?: number): Observable<Blob> {
|
||||
/**
|
||||
* Export PDF mensuel (GET /api/exports/mensuel/{annee}/{mois}). Réponse complète
|
||||
* (et non le seul Blob) afin que l'appelant puisse lire le nom de fichier suggéré
|
||||
* par le backend depuis l'en-tête `Content-Disposition`.
|
||||
*/
|
||||
exportPdfMensuel(annee: number, mois: number, vehiculeId?: number): Observable<HttpResponse<Blob>> {
|
||||
return this.http.get(`${this.baseUrl}/exports/mensuel/${annee}/${mois}`, {
|
||||
params: this.vehiculeParams(vehiculeId),
|
||||
responseType: 'blob'
|
||||
responseType: 'blob',
|
||||
observe: 'response'
|
||||
});
|
||||
}
|
||||
|
||||
/** Export PDF annuel (GET /api/exports/annuel/{annee}). */
|
||||
exportPdfAnnuel(annee: number, vehiculeId?: number): Observable<Blob> {
|
||||
/**
|
||||
* Export PDF annuel (GET /api/exports/annuel/{annee}). Réponse complète (et non le
|
||||
* seul Blob) afin que l'appelant puisse lire le nom de fichier suggéré par le backend
|
||||
* depuis l'en-tête `Content-Disposition`.
|
||||
*/
|
||||
exportPdfAnnuel(annee: number, vehiculeId?: number): Observable<HttpResponse<Blob>> {
|
||||
return this.http.get(`${this.baseUrl}/exports/annuel/${annee}`, {
|
||||
params: this.vehiculeParams(vehiculeId),
|
||||
responseType: 'blob'
|
||||
responseType: 'blob',
|
||||
observe: 'response'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Extrait le nom de fichier suggéré par le backend depuis l'en-tête
|
||||
* `Content-Disposition: attachment; filename="..."` d'une réponse HTTP.
|
||||
* Retourne `null` si l'en-tête est absent ou ne contient pas de nom de fichier.
|
||||
*/
|
||||
extraireNomFichier(reponse: HttpResponse<Blob>): string | null {
|
||||
const entete = reponse.headers.get('Content-Disposition');
|
||||
if (!entete) {
|
||||
return null;
|
||||
}
|
||||
const correspondance = /filename\*?=(?:UTF-8'')?"?([^;"]+)"?/i.exec(entete);
|
||||
return correspondance ? decodeURIComponent(correspondance[1]) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trajets d'une journée avec géométries pour la carte
|
||||
* (GET /api/trajets/journee/{date}). La date est au format ISO (yyyy-MM-dd).
|
||||
|
||||
Reference in New Issue
Block a user