From 0a2bc8318b43a2745e95301148eeb1169f09fcd7 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 13 Aug 2026 19:15:15 +0000 Subject: [PATCH] Grille : remonter le corps du tableau au changement de colonnes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le repli du bloc mensuel ne repeignait toujours pas les lignes déjà montées : l'en-tête perdait ses douze colonnes, le corps les gardait, et il fallait recharger la page pour retrouver une grille cohérente. Le signal passé aux lignes (`columnsKey`) reposait sur la comparaison de props de `React.memo`. La clé du `` porte désormais cette même signature : un changement de colonnes remonte le corps, sans plus dépendre d'une comparaison qu'une prop oubliée suffit à mettre en défaut. Le mécanisme existait déjà pour la densité d'affichage. Le coût est celui des seules lignes virtualisées (une trentaine), et le redimensionnement d'une colonne ne déclenche rien : les identifiants de colonnes, eux, ne changent pas. Vérifié cette fois sur un BUILD DE PRODUCTION, 2 000 lignes : au repli, 17 en-têtes et 17 cellules pour chaque ligne montée ; toujours 17 après défilement vers des lignes virtualisées ensuite ; 29 partout au retour, et 17 au repli suivant — sans rechargement. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01EYGgoQCG1VCe42HzbzhAXR --- src/features/grid/components/heatmap-grid.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/features/grid/components/heatmap-grid.tsx b/src/features/grid/components/heatmap-grid.tsx index 0af67cb..c48bcb4 100644 --- a/src/features/grid/components/heatmap-grid.tsx +++ b/src/features/grid/components/heatmap-grid.tsx @@ -1062,7 +1062,17 @@ export function HeatmapGrid({ onSelectionChange, isAdmin }: HeatmapGridProps) { ))} - + {/* + * La clé porte AUSSI la signature des colonnes : changer de jeu de + * colonnes remonte le corps du tableau au lieu de compter sur la + * comparaison de props de `React.memo`. Une ligne mémoïsée qui rate + * le signal continue de peindre l'ancien jeu de cellules, et la + * grille se retrouve à deux vitesses — en-tête à jour, corps en + * retard. Un remontage ne coûte que les ~30 lignes virtualisées, et + * le redimensionnement (continu) ne le déclenche pas : les + * identifiants de colonnes ne changent pas. + */} + {rowVirtualizer.getVirtualItems().map((virtualRow) => { const row = tableRows[virtualRow.index]; const isSelected = row.getIsSelected();