---
suivi: 1422
date: 2026-09-03
sujet: Avis d'imposition — menu, style, filtres, pièces jointes
chantier: foncier
type: feature
statut: poussé
hash: 1422a0b1
fichiers:
  - resources/js/Layouts/AppShell.vue
  - resources/js/Pages/Foncier/Patrimoine/AvisImposition/Index.vue
  - app/Http/Controllers/Foncier/AvisImpositionController.php
  - app/Models/AvisImposition.php
  - app/Models/AvisImpositionDocument.php
  - app/Services/Foncier/AvisImpositionDocumentService.php
  - database/migrations/2026_09_03_160000_create_avis_imposition_documents_table.php
  - routes/web.php
---

# SUIVI #1422 — Avis d'imposition : menu, style, filtres, pièces jointes

## PROMPT ENVOYÉ

Quatre corrections sur la page livrée au #1420 : entrée de menu dans le sous-menu Patrimoine, fond bleu sur colonne Adresse, bande de filtres vide, pièces jointes par ligne.

## SYNTHÈSE

### Volet 1 — Menu Patrimoine
- **Avant #1420** : Patrimoine était un lien de premier niveau seul (pas de sous-menu).
- **#1420** : « Avis d'imposition » ajouté en lien de premier niveau à côté — erreur.
- **#1422** : pattern GEMME/FONCIER réutilisé (`patrimoineDropdownOpen`, `patrimoineNavWrapRef`, hover + click, chevron `pi-angle-down`). Deux entrées dans le dropdown : Patrimoine + Avis d'imposition. Contrôle d'accès inchangé : `peutVoirMenuFoncier`.

### Volet 2 — Fond bleu colonne Adresse
- **Cause** : `Index.vue` L268-271 (scoped CSS) — `:deep(.p-datatable-thead > tr > th:first-child) { background: #1B2B4B; color: white; }` surchargeait la première colonne figée en bleu en-tête, y compris visuellement sous l'en-tête.
- **Fix** : suppression de la surcharge ; fond opaque zebra (`odd`/`even`/`hover`) aligné sur `envolDataTablePt.bodyrow`. En-tête Adresse hérite du `thead bg-[#1B2B4B]` global comme les autres colonnes.

### Volet 3 — Filtres
- **Cause** : `filters = ref({})` vide — PrimeVue `filter-display="row"` exige un objet `{ champ: { value, matchMode } }` par colonne (cf. `/factures` Global.vue `buildFiltersFromProps`).
- **Fix** : initialisation `FilterMatchMode.CONTAINS` pour chaque colonne + attribut `filter` sur `<Column>`. Tableau vide en prod : la bande affiche les champs « Filtrer… » mais sans effet visible tant qu'il n'y a pas de lignes.

### Volet 4 — Pièces jointes
- **Stockage retenu** : disque `local` privé (pattern `FoncierEntityDocumentService`), **pas SharePoint** — pas de dépendance Graph/OVH CLI, pas de risque perte item_id, contrôle d'accès serveur sur download.
- **Limite** : 20 Mo/fichier (`max:20480`), source `DepotFactureController` L181.
- **Table** : `avis_imposition_documents` (migration additive, sans `->after()`).
- **Journal** : actions `document_ajoute` / `document_supprime` dans `avis_imposition_historique`.

## DÉPLOIEMENT-TEST

1. `git pull origin main`
2. `php artisan migrate --force`
3. `php artisan optimize:clear && php artisan view:clear && php artisan journal:sync`

## LEÇON

- PrimeVue filtres row : toujours initialiser `filters` avec `matchMode` par colonne, même tableau vide.
- Colonne sticky : ne pas surcharger `th:first-child` en bleu si les données doivent rester blanches/zebra.
