alwaysShowHorizontalScroll force la piste de scroll à rester visible
en permanence (comportement déjà natif sous Chrome). Sans effet sur
Firefox, dont le curseur en overlay est géré par l'OS/le navigateur
et non contrôlable côté appli (#41).
Deux bugs découverts en usage réel sur /tableau :
1. filtermodel_to_ast lisait condition1/condition2 pour un filtre à
deux conditions (ET/OU) sur une colonne — mais AG Grid >=29.2 (la
version 35.2.0 utilisée ici) encode ça via une liste `conditions`,
confirmé par la doc Dash AG Grid "Filter Model & Dash Callbacks" >
"Filter Model Multiple Conditions". Le filtre était donc
silencieusement ignoré (colonne exclue du AST, comme si aucun
filtre n'était posé), d'où des résultats sans rapport avec les
valeurs saisies. Corrigé : filtermodel_to_ast lit désormais
`conditions` (N éléments) en priorité, avec repli sur
condition1/condition2 (forme dépréciée mais "still accepted" selon
AG Grid). L'inverse (ast_to_filtermodel, utilisé au rappel d'une
vue sauvegardée) produit aussi la forme `conditions`.
2. Le bouton "Réinitialiser" ("Supprime tous les filtres et les tris")
ne réinitialisait que filterModel, jamais le tri. Corrigé via
resetColumnState (remet les colonnes à l'état de columnDefs, qui
reflète déjà la visibilité choisie via le sélecteur de colonnes —
seul le tri est donc affecté).
Reproduit et corrigé en TDD (tests/test_query_ast.py,
tests/test_grid.py), vérifié manuellement en navigateur par l'auteur
du rapport de bug.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Menu de filtre de colonne (Contient, Égal à, Vide, ET/OU, etc.) traduit
via l'option native AG Grid localeText, exposée par dashGridOptions.
N'affecte pas l'apparence de base conservée au Lot 1 (aucun thème/CSS
custom) — uniquement le texte des libellés.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Les tests qui démarrent l'app complète (Selenium) écrivent dans la base
users pointée par USERS_DB_PATH (comptes créés, vues sauvegardées...).
Comme ce fichier était le fixture committé lui-même, chaque exécution de
la suite le laissait modifié dans l'arbre de travail — gênant pour les
commits et le nettoyage de worktree.
Même schéma déjà utilisé pour DUCKDB_PATH et DATA_SCHEMA_CACHE dans ce
fichier : le fixture committé est copié vers une base jetable gitignorée
(tests/users.runtime.sqlite) au chargement de conftest.py, et
USERS_DB_PATH pointe sur la copie. tests/users.test.sqlite reste
désormais toujours propre.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ajoute des tests de bout en bout pour les filtres montant/date/cpv, le
chemin titulaire de search_organisations, et la pagination (page>1,
clamping page=0). Normalise montant_total en float dans les deux
branches de compute_org_stats.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Vérifie via Selenium/DashComposite que /tableau charge et affiche la
grille AG Grid avec au moins une ligne rendue, sans erreur console
SEVERE. Dernière tâche de la migration DataTable -> AG Grid.
Décrit les filtres de colonne AG Grid (flottant/entonnoir, texte/numérique/
date, combinaison ET/OU), le tri multi-colonne (Maj+clic) et le défilement
infini, à la place de l'ancienne syntaxe icontains/i</i> et des liens
d'exemple ?filtres=... (mécanisme retiré à la tâche 10). Retire la ligne
"Partager la vue" de la légende des boutons (bouton supprimé).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Les vues stockent désormais {filterModel, columnState} en JSON dans
saved_views.query au lieu d'une query string DSL. Le rappel d'une vue
applique filterModel + columnState à la grille AG Grid via un nouveau
callback apply_saved_view, déclenché par pattern-matching sur les items
du menu "Mes vues" (désormais cliquables au lieu de liens href).
Retire restore_view_from_url, sync_url_and_reset_button,
show_confirmation, le bouton "Partager la vue" et le clientside
clean_filters de tableau.py - la migration AG Grid retire le mécanisme
d'URL riche sans rétrocompatibilité.
Le lien "Ouvrir" de compte/vues.py pointe maintenant vers /tableau nu
(limitation connue documentée, le rappel cross-page reste à faire).
Rewrite download_data to read filterModel/columnState from the AG Grid
component and add export_dataframe (compiles filterModel to SQL via
filtermodel_to_ast/ast_to_sql, builds ORDER BY, excludes hidden columns,
queries DuckDB via query_marches). Replaces the old Polars filter_query
pipeline tied to the removed DataTable.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
apply_hidden_columns régénère columnDefs (via grid_column_defs) sur
tableau_grid quand le Store tableau-hidden-columns change, remplaçant
store_hidden_columns qui ciblait l'ancienne prop hidden_columns de la
DataTable (supprimée en tâche 7). update_checkboxes_from_hidden_columns
lit désormais directement le Store plutôt que la prop de la DataTable
disparue, pour que la synchronisation cases à cocher <-> colonnes
masquées continue de fonctionner.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Remplace le composant DataTable et le callback update_table de tableau.py
par la grille dash-ag-grid (mode ligne infini) et un callback get_rows_tableau
piloté par getRowsRequest/getRowsResponse, plus un callback update_meta qui
synchronise nb_rows/btn-download-data/download-hint via un dcc.Store du total.
Les autres callbacks de la page (sélecteur de colonnes, vues sauvegardées,
export, restauration URL, aide) référencent encore les anciens
id/props (tableau_datatable, hidden_columns, filter_query, sort_by) et seront
mis à jour dans les tâches suivantes (8-11) du plan de migration #41.
Ajoute sort_model_to_sql (adapte le sortModel AG Grid vers sort_by_to_sql
existant) et ast_to_dict/ast_from_dict pour le round-trip JSON de l'AST,
nécessaire aux vues sauvegardées.