Écran unique « Synthèse Kms » fusionnant résumés et montants réglés
- Nouvelle page Synthèse Kms (/synthese-kms) : sélecteur temporel en mode année seule + véhicule + Afficher, barème appliqué, tableau 12 mois (km, remb. réel du mois, indication 80%, montant réglé saisissable, export PDF mensuel), ligne TOTAL (km annuel, montant réel, total réglé, export PDF annuel), bouton Enregistrer global (seuls les montants modifiés), auto-affichage à l'arrivée. Aucun nouvel endpoint (composition d'endpoints existants). - Suppression des écrans « Résumé mensuel », « Résumé annuel » et « Montants réglés » (routes et liens de menu retirés). - SelecteurTemporelComponent : mode « année seule » (Input/Output dédiés) et repli automatique au clic sur le niveau le plus bas. - Pleine largeur des écrans Trajets, Carnet d'adresses et Synthèse Kms (Specs conserve sa largeur de lecture). - Liste des trajets : boutons d'action déplacés en début de ligne (après la poignée, avant A/R), alignés à droite. - Specs (requirements/design-requirements/design) synchronisées : glossaire Synthèse_Kms, Exigences 3/4/13/14 adaptées, critères 12.25-27.
This commit is contained in:
@@ -16,8 +16,8 @@
|
||||
|---|----------------|-------------|
|
||||
| 1 | Saisie d'un trajet | Formulaire avec date (JJ/MM/AAAA), adresse départ, adresse arrivée, commentaire |
|
||||
| 2 | Calcul automatique de distance | Via ORS (routier), fallback orthodromique |
|
||||
| 3 | Résumé mensuel | Liste des trajets + total km du mois |
|
||||
| 4 | Vue annuelle | 12 résumés mensuels + total annuel |
|
||||
| 3 | Synthèse Kms (mensuel) | Total km par mois agrégé dans l'écran unique Synthèse Kms (ex-« Résumé mensuel », fusionné) ; le détail trajet par trajet reste sur l'écran « Trajets » |
|
||||
| 4 | Synthèse Kms (annuel) | 12 lignes mensuelles + ligne TOTAL annuel dans l'écran unique Synthèse Kms (ex-« Résumé annuel », fusionné) |
|
||||
| 5 | Modification / suppression | Édition avec recalcul conditionnel de distance |
|
||||
| 6 | Persistance et cohérence | Base relationnelle avec invariants d'agrégation et transactions |
|
||||
| 7 | Export PDF | Fichiers `AAAAMM_Trajets_MATRICULE_PLAQUE.pdf` et `AAAA_Trajets_MATRICULE_PLAQUE.pdf` |
|
||||
@@ -31,7 +31,7 @@
|
||||
| 15 | Profil enrichi & véhicules | Nom, prénom, matricule (8 car.), plaque, puissance fiscale ; historique des véhicules daté |
|
||||
| 16 | Association véhicule par trajet | Chaque trajet référence un véhicule + puissance fiscale ; totaux filtrés par véhicule |
|
||||
| 17 | Barème kilométrique annuel | Saisie par tranches (puissance fiscale, bornes km, coefficient, part fixe) ; montant prévisionnel minoré 80% |
|
||||
| 18 | Montants réglés & régularisation | Saisie du montant réglé par mois ; rapport annuel avec montant réel, versé, dû et régularisation |
|
||||
| 18 | Montants réglés & régularisation | Saisie du montant réglé par mois et régularisation intégrées à l'écran unique Synthèse Kms (ex-« Montants réglés », fusionné) ; rapport annuel avec montant réel, versé, dû et régularisation |
|
||||
| 19 | Carnet d'adresses nommées | Menu CRUD d'Adresses_Nommées (Dénomination unique + adresse BAN) ; réutilisation par Dénomination dans la saisie et l'insertion de Trajets |
|
||||
| 20 | Onboarding première utilisation | Présentation de la saisie du profil (identité + véhicule) si le Profil n'est pas configuré, avant tout accès à la saisie / consultation des trajets |
|
||||
| 21 | Authentification | Compte unique (e-mail + mot de passe), connexion par JWT (12 h par défaut), réinitialisation de mot de passe par e-mail, garde de session serveur |
|
||||
@@ -40,6 +40,7 @@
|
||||
| 24 | Consultation des specs | Lien « Specs » vers une page dédiée (menu latéral Exigences / Conception / Tâches) affichant les documents Markdown rendus (dont les diagrammes Mermaid), en lecture seule et derrière l'authentification |
|
||||
| 25 | Changement de mot de passe | Page Compte utilisateur : formulaire dédié (mot de passe actuel + nouveau + confirmation) ; endpoint protégé distinct de la réinitialisation par e-mail |
|
||||
| 26 | Navigation utilisateur | Avatar (initiales) à droite de la barre, sous-menu au survol (Prénom Nom, Paramétrage, Maintenance, Se déconnecter) ; Page_Parametrage (Compte / Véhicules / Barème) et Page_Maintenance dédiées ; barre masquée sur les pages publiques ; contrôle afficher/masquer sur tous les champs mot de passe |
|
||||
| 27 | Synthèse Kms (écran unique) | Fusion des ex-écrans « Résumé mensuel » / « Résumé annuel » / « Montants réglés » (supprimés) : critères sur une ligne (Sélecteur_Temporel année seule + sélecteur Véhicule + bouton Afficher), barème appliqué, tableau 12 mois (km, Frais_Reel_Mensuel, indication 80%, Montant_Regle saisissable, Export PDF mensuel), ligne TOTAL (km annuel, Montant_Reel, total réglé, Export PDF annuel), bouton « Enregistrer » global (seuls les montants modifiés), auto-affichage initial, aucun nouvel endpoint |
|
||||
|
||||
### Contraintes techniques
|
||||
|
||||
@@ -178,12 +179,9 @@ src/
|
||||
│ │ ├── trajet-form/
|
||||
│ │ │ ├── trajet-form.component.ts # Saisie + édition
|
||||
│ │ │ └── trajet-form.component.html
|
||||
│ │ ├── resume-mensuel/
|
||||
│ │ │ ├── resume-mensuel.component.ts
|
||||
│ │ │ └── resume-mensuel.component.html
|
||||
│ │ ├── resume-annuel/
|
||||
│ │ │ ├── resume-annuel.component.ts
|
||||
│ │ │ └── resume-annuel.component.html
|
||||
│ │ ├── synthese-kms/
|
||||
│ │ │ ├── synthese-kms.component.ts # Écran unique : synthèse annuelle par mois + saisie Montant_Regle + exports PDF
|
||||
│ │ │ └── synthese-kms.component.html
|
||||
│ │ ├── trajet-list/
|
||||
│ │ │ ├── trajet-list.component.ts
|
||||
│ │ │ └── trajet-list.component.html
|
||||
@@ -209,9 +207,6 @@ src/
|
||||
│ │ ├── bareme/
|
||||
│ │ │ ├── bareme.component.ts # Saisie du barème par année/tranches
|
||||
│ │ │ └── bareme.component.html
|
||||
│ │ ├── montants-regles/
|
||||
│ │ │ ├── montants-regles.component.ts # Saisie montant réglé par mois
|
||||
│ │ │ └── montants-regles.component.html
|
||||
│ │ ├── carnet-adresses/
|
||||
│ │ │ ├── carnet-adresses.component.ts # CRUD des Adresses_Nommées (liste + formulaire)
|
||||
│ │ │ └── carnet-adresses.component.html
|
||||
@@ -251,23 +246,24 @@ src/
|
||||
- **Autocomplétion BAN** : appel à `https://api-adresse.data.gouv.fr/search/?q={saisie}&limit=5` dès 3 caractères saisis ; chaque suggestion affiche le libellé + code postal + commune ; à la sélection d'une suggestion, les coordonnées `(lat, lon)` sont stockées dans l'état local du composant et transmises avec le formulaire
|
||||
- Si l'utilisateur tape une adresse sans passer par BAN (pas de sélection), les coordonnées sont absentes et un avertissement discret s'affiche
|
||||
|
||||
**`ResumeMensuelComponent`**
|
||||
- Réutilise le même `SelecteurTemporelComponent` que `ConsultationJourComponent` (sélection successive année puis mois, surbrillance des périodes ayant des données) au lieu de sélecteurs distincts mois/année ; la sélection d'un mois (événement `moisSelectionne`) déclenche automatiquement le chargement du Résumé_Mensuel, sans bouton "Afficher" sur cet écran
|
||||
- Affiche la liste des trajets, avec une colonne **Commentaire** entre les colonnes Date et Départ (valorisée avec le commentaire du Trajet, ou « — » si absent), et le total mensuel
|
||||
- Bouton "Export PDF mensuel" positionné à droite du `SelecteurTemporelComponent`
|
||||
- La Distance de chaque Trajet et le total mensuel sont formatés selon `formatKm()` (pipe `number` alimenté par le signal `precisionDistance` de `ParametresApplicationService`), reflétant Precision_Distance (0, 1 ou 2 décimales) au lieu d'un affichage fixe à 2 décimales — voir spec `precision-distances-km`
|
||||
|
||||
**`ResumeAnnuelComponent`**
|
||||
- Sélecteur année (2000–2100) et bouton "Afficher" **inchangés** (pas de remplacement par `SelecteurTemporelComponent` sur cet écran — décision explicite de l'utilisateur, à la différence du Résumé_Mensuel et de la Vue_Consultation)
|
||||
- Tableau 12 lignes (mois, total km) + ligne total annuel (max 999 999,99)
|
||||
- Bouton "Export PDF annuel" positionné à droite du formulaire sélecteur/bouton "Afficher" (même agencement visuel que sur le Résumé_Mensuel), sans changement de comportement
|
||||
- Le total kilométrique de chaque mois et le total annuel sont formatés selon `formatKm()`, reflétant Precision_Distance au lieu d'un affichage fixe à 2 décimales — voir spec `precision-distances-km`
|
||||
**`SyntheseKmsComponent`** (écran unique — Exigences 3, 4, 13, 14)
|
||||
- **Fusionne et remplace** les anciens composants `ResumeMensuelComponent`, `ResumeAnnuelComponent` et `MontantsReglesComponent` (tous supprimés), ainsi que leurs routes `/resume-mensuel`, `/resume-annuel`, `/montants-regles` et leurs liens de menu. Route unique : `/synthese-kms`, lien de menu « Synthèse Kms »
|
||||
- **En-tête sur une même ligne** : le titre « Synthèse Kms » et la zone de critères — `SelecteurTemporelComponent` en **mode « année seule »**, sélecteur de Véhicule, bouton « Afficher »
|
||||
- **Auto-affichage initial** : à l'initialisation, la synthèse est chargée automatiquement pour la pré-sélection (Véhicule_Courant + année courante), sans attendre d'action sur « Afficher »
|
||||
- **Barème appliqué** affiché au-dessus du tableau : tranche, Puissance_Fiscale, coefficient, base
|
||||
- **Tableau une ligne par mois** : libellé du mois, kilomètres du mois, Frais_Reel_Mensuel (remboursement réel propre au mois = km du mois × coefficient de la tranche annuelle), indication 80% (Montant_Previsionnel_Mensuel), Montant_Regle **saisissable**, et colonne « Action » avec un bouton « Export PDF » (rapport mensuel du mois)
|
||||
- **Barre d'action au-dessus du tableau** : un unique bouton « Enregistrer » qui persiste uniquement les Montant_Regle **modifiés** depuis le dernier chargement (plusieurs mois en une seule action) ; pas de bouton d'enregistrement par ligne
|
||||
- **Ligne TOTAL** : total kilométrique annuel, Montant_Reel (total du remboursement réel), **cellule « indication 80% » vide**, total réglé (somme des Montant_Regle, non modifiable), bouton « Export PDF » qui exporte le rapport **annuel** ; aucun bouton « Enregistrer » sur cette ligne
|
||||
- **Aucun nouvel endpoint backend** : composition d'endpoints existants — `GET /api/regularisation/{annee}` (barème, km mensuels, Frais_Reel_Mensuel, total annuel, Montant_Reel, total réglé), `GET /api/montant-previsionnel/{annee}/{mois}` (indication 80%), `PUT /api/montants-regles` (upsert à l'enregistrement), `GET /api/exports/mensuel/{annee}/{mois}` et `GET /api/exports/annuel/{annee}` (exports PDF)
|
||||
- **Pleine largeur** : l'écran occupe toute la largeur disponible (pas de largeur maximale centrée)
|
||||
- Tous les kilomètres sont formatés selon `formatKm()` (signal `precisionDistance` de `ParametresApplicationService`), reflétant Precision_Distance — voir spec `precision-distances-km` ; les montants en euros à 2 décimales
|
||||
- Le **détail des Trajets un par un n'est plus affiché** dans cet écran de synthèse : il reste consultable sur `ConsultationJourComponent` (écran « Trajets »)
|
||||
|
||||
**`TrajetListComponent`**
|
||||
- Affiche TOUS les trajets du mois, regroupés par journée : chaque groupe/jour a un **en-tête repliable** (jour de la semaine avant la date, ex. « Lundi 15/09/2026 », puis nombre de trajets) ; par défaut tout est replié sauf le dernier jour du mois ayant des trajets.
|
||||
- **Bouton dédié « + » à droite de l'en-tête** (`Output ajouterSurJournee: string`) : ouvre le formulaire de création avec la date de CETTE journée, sans dépendre de la journée affichée sur la Carte (pilotée par le survol) — évite qu'un déplacement de souris à travers plusieurs journées ouvertes ne fasse dériver la date visée en se dirigeant vers le bouton principal d'ajout. Le conteneur fixe `date` sur cette valeur avant d'ouvrir la création (`ouvrirCreationSur`).
|
||||
- Ligne par trajet (triée par `Position` croissante au sein du jour) : colonne dédiée **A/R** en début de ligne pour les allers/retours, commentaire (si présent), adresses (taille réduite), distance effective
|
||||
- Actions par trajet : modifier (→ `TrajetFormComponent` pré-rempli en < 500 ms), supprimer (→ dialog de confirmation), **insérer après** (→ `TrajetFormComponent` en mode insertion avec `adresseDepart` = point de fin du trajet courant — son arrivée, ou son **départ** si le trajet est un aller/retour —, la **date de la journée** du trajet, `positionApres` = Position du trajet courant)
|
||||
- Ligne par trajet (triée par `Position` croissante au sein du jour) : les **boutons d'action** sont placés **en début de ligne** (après la poignée de glisser-déposer, avant la colonne A/R) et **alignés à droite au sein de leur colonne** pour conserver l'alignement vertical du bouton « insérer après » ; puis colonne dédiée **A/R** pour les allers/retours, commentaire (si présent), adresses (taille réduite), distance effective
|
||||
- Actions par trajet (regroupées en début de ligne) : modifier (→ `TrajetFormComponent` pré-rempli en < 500 ms), supprimer (→ dialog de confirmation), **insérer avant/après** — l'insérer après ouvre `TrajetFormComponent` en mode insertion avec `adresseDepart` = point de fin du trajet courant (son arrivée, ou son **départ** si le trajet est un aller/retour), la **date de la journée** du trajet, `positionApres` = Position du trajet courant
|
||||
- Si le trajet n'est pas le dernier de la journée : action **insérer avant le suivant** disponible, pré-remplissant l'adresse de départ avec le point de fin du trajet courant (départ si aller/retour) et l'adresse d'arrivée avec le départ du trajet suivant, en calculant la position d'insertion `(P_courant + P_suivant) / 2`
|
||||
- Méthode publique `ouvrirJour(dateIso)` : déplie une journée donnée (appelée par le conteneur après ajout/insertion pour rendre le trajet visible) ; `ouvrirToutesLesJournees()` déplie tous les groupes ; `aDesJourneesFermees()` conditionne l'affichage du bouton « Ouvrir toutes les journées »
|
||||
- `@Input jourAffiche` : la journée affichée sur la Carte ; le groupe correspondant est mis en surbrillance (`estJourAffiche`)
|
||||
@@ -310,13 +306,16 @@ src/
|
||||
- Deux actions : "Réaffecter au nouveau véhicule" (POST reaffectation accepter=true) / "Conserver l'existant" (accepter=false)
|
||||
|
||||
**`SelecteurTemporelComponent`**
|
||||
- **Repliable** ; l'en-tête affiche le mois et l'année sélectionnés (ex. « Septembre 2026 »)
|
||||
- Sélecteur d'année : liste limitée à l'année courante + années ayant des données (endpoint `/api/annees-disponibles`)
|
||||
- Sélecteur de mois : 12 mois affichés, surbrillance des mois avec données (endpoint `/api/mois-disponibles/{annee}`), avec le même code couleur bleu que la journée mise en avant dans la liste ; le mois sélectionné reste en bleu plein
|
||||
- Pas de sélecteur de jour (la consultation se fait par mois) ; désactivation de tout mois > mois courant
|
||||
- Émet un événement `moisSelectionne: { annee: number, mois: number }` à chaque changement
|
||||
- **Repliable** ; l'en-tête affiche la période sélectionnée (ex. « Septembre 2026 » en mode année + mois, « 2026 » en mode année seule)
|
||||
- **Deux modes** pilotés par un `@Input` :
|
||||
- **Mode « année + mois »** (par défaut, utilisé par `ConsultationJourComponent`) : choix successif année puis mois ; émet un événement `moisSelectionne: { annee: number, mois: number }` à chaque changement
|
||||
- **Mode « année seule »** (utilisé par `SyntheseKmsComponent`) : la grille des 12 mois **n'est pas affichée** ; seul le choix de l'année est proposé et le composant émet l'année choisie (`@Output` dédié)
|
||||
- Sélecteur d'année (dans les deux modes) : liste limitée à l'année courante + années ayant des données (endpoint `/api/annees-disponibles`)
|
||||
- Sélecteur de mois (mode année + mois uniquement) : 12 mois affichés, surbrillance des mois avec données (endpoint `/api/mois-disponibles/{annee}`), avec le même code couleur bleu que la journée mise en avant dans la liste ; le mois sélectionné reste en bleu plein ; désactivation de tout mois > mois courant
|
||||
- **Repli automatique** : lors d'un clic sur le niveau le plus bas (le mois en mode année + mois, l'année en mode année seule), le composant se referme automatiquement (collapse). Comportement appliqué partout où le sélecteur est utilisé
|
||||
|
||||
**`ConsultationJourComponent`** (composant conteneur / layout principal)
|
||||
- **Pleine largeur** : l'écran « Trajets » occupe toute la largeur disponible (plus de largeur maximale centrée)
|
||||
- Deux états : un signal `mois` (`{ annee, mois }`) pilote la **liste mensuelle** ; un signal `date` (ISO) pilote la **carte** et la date par défaut d'ajout/insertion
|
||||
- Colonne gauche (fixe) : `SelecteurTemporelComponent`, puis `PanneauTotauxComponent`, puis `CarteTrajetsComponent` (plus de bande de navigation par jour)
|
||||
- Colonne droite : bande fixe (sélecteur de Véhicule + bouton « Ajouter un trajet »), puis `TrajetListComponent` du mois avec scroll vertical
|
||||
@@ -348,14 +347,12 @@ src/
|
||||
- Bouton **« Recopier le dernier barème connu »** (recopie l'année antérieure la plus récente, confirmation si l'année cible contient déjà des tranches, inaccessible sur l'année du dernier barème)
|
||||
- Validation du non-chevauchement des tranches pour une même puissance fiscale et année
|
||||
|
||||
**`MontantsReglesComponent`**
|
||||
- Saisie du Montant_Regle par mois pour l'année et le véhicule sélectionnés
|
||||
- Affichage en regard : Montant_Previsionnel_Mensuel minoré 80% (indicatif), désormais calculé sur le seul mois affiché (et non plus sur le cumul annuel) — voir spec `precision-distances-km`, Requirement 7
|
||||
- Montants en euros à 2 décimales
|
||||
> **Saisie des Montant_Regle** : l'ancien composant `MontantsReglesComponent` (écran dédié « Montants réglés ») est supprimé ; la saisie des Montant_Regle par mois est désormais assurée directement dans le tableau mensuel du `SyntheseKmsComponent` ci-dessus, avec l'affichage en regard du Montant_Previsionnel_Mensuel (indication 80%, calculé sur le seul mois affiché — voir spec `precision-distances-km`, Requirement 7).
|
||||
|
||||
**`CarnetAdressesComponent`**
|
||||
- Liste des Adresses_Nommées (Dénomination + adresse + indication si coordonnées disponibles), triée par Dénomination, avec un bouton « Ajouter une adresse » au-dessus de la liste
|
||||
- **Disposition en grille de cartes** : les adresses sont affichées les unes à côté des autres puis retournent à la ligne selon la largeur disponible (`display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr))`). Chaque carte a une taille homogène (colonnes de largeur égale, cartes étirées à la même hauteur par rangée via `align-items: stretch`), un contour (`border: 1px solid #e0e0e0; border-radius: 10px`) et un effet d'ombre (`box-shadow: 0 2px 8px rgba(0,0,0,0.1)`) la détachant du fond. La zone de contenu de la page est élargie (`max-width: 1080px`) pour laisser la place à plusieurs colonnes ; la dénomination et l'adresse sont en haut de la carte, les actions Modifier/Supprimer en bas à droite
|
||||
- **Pleine largeur** : l'écran « Carnet d'adresses » occupe toute la largeur disponible (plus de largeur maximale centrée)
|
||||
- **Disposition en grille de cartes** : les adresses sont affichées les unes à côté des autres puis retournent à la ligne selon la largeur disponible (`display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr))`). Chaque carte a une taille homogène (colonnes de largeur égale, cartes étirées à la même hauteur par rangée via `align-items: stretch`), un contour (`border: 1px solid #e0e0e0; border-radius: 10px`) et un effet d'ombre (`box-shadow: 0 2px 8px rgba(0,0,0,0.1)`) la détachant du fond. La zone de contenu de la page occupe toute la largeur disponible pour laisser la place à plusieurs colonnes ; la dénomination et l'adresse sont en haut de la carte, les actions Modifier/Supprimer en bas à droite
|
||||
- Formulaire de création / modification présenté dans une **fenêtre modale** (overlay `.modale-overlay` + panneau `.modale-panneau`, motif partagé avec `ConfirmDialogComponent` / `ConsultationJourComponent`), ouvert via le bouton « Ajouter une adresse » (mode création) ou l'action « Modifier » d'une ligne (mode édition) ; fermée par enregistrement réussi, par le bouton « Annuler », ou par un clic sur l'arrière-plan. Le signal `modaleOuverte` pilote l'affichage
|
||||
- Champ `denomination` (1–100 car.) et champ `adresse` avec autocomplétion BAN (1–255 car.) ; dans la modale, les suggestions BAN sont rendues **dans le flux** du panneau (et non en position absolue) pour éviter toute troncature par le défilement du panneau
|
||||
- **Autocomplétion BAN** : appel à `https://api-adresse.data.gouv.fr/search/?q={saisie}&limit=5` dès 3 caractères saisis, avec debounce de 300 ms, maximum 5 suggestions ; à la sélection, le libellé normalisé remplit le champ et les coordonnées `(lat, lon)` sont conservées pour transmission
|
||||
@@ -397,6 +394,7 @@ src/
|
||||
- Rendu : le Markdown (`GET /api/specs/{cle}`) est converti en HTML par **`marked`** (GFM : titres, listes, tableaux, code), puis **assaini par `DOMPurify`** avant injection (`[innerHTML]`) — Exigence 19.7
|
||||
- **Diagrammes Mermaid** : un renderer `marked` transforme les blocs ` ```mermaid ` en `<pre class="mermaid">` ; après injection du HTML (déclenchée via `setTimeout` pour laisser Angular résoudre le `@ViewChild`), **Mermaid.js** (importé dynamiquement) rend ces blocs en SVG (`securityLevel: 'loose'` pour accepter les libellés HTML type `<br/>`). En cas d'échec de rendu d'un diagramme, le bloc de code brut reste visible.
|
||||
- Accès derrière `authGuard` (mêmes règles que les autres vues protégées)
|
||||
- **Largeur de lecture limitée** : à la différence des écrans « Trajets », « Carnet d'adresses » et « Synthèse Kms » (passés en pleine largeur), le `SpecsComponent` conserve une largeur maximale centrée adaptée à la lecture (comportement inchangé)
|
||||
|
||||
**`ProfilConfigureGuard`** (garde de route Angular — `CanActivate` / `CanActivateFn`)
|
||||
- Au chargement de l'application, appelle `ProfilService.getEtat()` (`GET /api/profil/etat`)
|
||||
@@ -406,7 +404,7 @@ src/
|
||||
- Déclaré dans `app-routing.module.ts` sur les routes protégées (consultation, saisie, résumés, etc.) ; la route `/onboarding` reste accessible sans garde
|
||||
|
||||
**`AppComponent`** (coquille applicative — barre de navigation, Exigence 21)
|
||||
- Barre de navigation : logo (format horizontal, icône + texte), liens métier (Trajets, Carnet d'adresses, Montants réglés, Résumé mensuel, Résumé annuel), menu déroulant « Specs », puis l'Avatar_Utilisateur poussé à l'extrémité droite (`margin-left: auto`)
|
||||
- Barre de navigation : logo (format horizontal, icône + texte), liens métier (Trajets, Carnet d'adresses, Synthèse Kms), menu déroulant « Specs », puis l'Avatar_Utilisateur poussé à l'extrémité droite (`margin-left: auto`). Les anciens liens « Montants réglés », « Résumé mensuel » et « Résumé annuel » sont retirés : ils sont remplacés par l'unique lien « Synthèse Kms »
|
||||
- **Menus déroulants (Specs, Avatar)** : s'ouvrent au survol (`mouseenter`) ET restent utilisables au clic (tactile, clavier) ; se ferment au `mouseleave` du bloc conteneur ou au clic extérieur (`@HostListener('document:click')`)
|
||||
- **Piège évité** : le panneau déroulant ne doit PAS être séparé du bouton par un espace (`top: calc(100% + Xpx)`), sous peine de déclencher un `mouseleave` prématuré lorsque le curseur traverse cet espace mort en descendant vers le panneau. Le panneau touche directement le bouton (`top: 100%`) et l'espacement visuel est reporté en `padding-top` À L'INTÉRIEUR du panneau (zone `__panneau-contenu` séparée pour le fond/l'ombre), de sorte que la zone de survol reste continue.
|
||||
- **Affichage conditionnel** : la barre de navigation (avatar inclus) est masquée non seulement en l'absence de jeton, mais aussi sur les pages PUBLIQUES (`/login`, `/register`, `/forgot-password`, `/reset-password`), détectées via les événements du `Router` (`NavigationEnd`). Ce deuxième critère est nécessaire car un jeton résiduel expiré ou invalide peut rester en `localStorage` sans qu'aucun appel HTTP protégé ne le purge sur ces pages (aucune requête vers un endpoint protégé n'y est faite) ; se fier uniquement à la présence du jeton ferait réapparaître la barre à tort.
|
||||
|
||||
Reference in New Issue
Block a user