Commit Graph

408 Commits

Author SHA1 Message Date
Colin Maudry 70ca65e962 Adaptation de l'effet de TOUS_ABONNES 2026-07-14 12:53:01 +02:00
Colin Maudry ad293acd88 Message d'info pour les users en trial dans /compte/roadmap 2026-07-14 11:48:29 +02:00
Colin Maudry 906c6a7f15 Changement font en-tetes colonnes (akshar) 2026-07-13 23:48:54 +02:00
Colin Maudry f84ca73b04 fix(abonnement): erreurs console JS et re-render en boucle sur la page mes-infos
Le label du checklist CGU mélangeait des chaînes brutes et un composant
html.A dans une liste, ce que le rendu compound-label de dcc.Checklist
ne supporte pas (chaque item passe par ExternalWrapper qui suppose un
vrai composant Dash). Ça crashait en boucle et déclenchait des dizaines
de re-render, ce qui faisait aussi clignoter le lien Abonnement dans le
menu latéral. Fix : tout regrouper dans un seul html.Span.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-13 23:38:29 +02:00
Colin Maudry a225dbb0ef Normalisation du style des boutons 2026-07-13 23:24:27 +02:00
Colin Maudry 34f10f2283 Tooltips abonnement sur Sauvegarder vue et Mes vues 2026-07-13 23:04:48 +02:00
Colin Maudry 8b9433b7f2 Amélioration de la modale de renommage des vues 2026-07-13 22:50:23 +02:00
Colin Maudry bee401430b feat(tableau): lien « Gérer mes vues » en tête du dropdown + fix hover dropdown (#112)
- Dropdown « Mes vues » : ajoute en tête un lien « Gérer mes vues » (couleur
  primary) vers /compte/vues, séparé de la liste des vues.
- Corrige l'override de --bs-dropdown-link-hover-bg : Bootstrap 5.3 scope cette
  variable sur .dropdown-menu, donc un override sur :root est masqué. Déplacé
  sur .dropdown-menu.
2026-07-13 22:38:57 +02:00
Colin Maudry e0828a7e13 feat(vues): bouton « Copier le lien » + lien de partage en texte stylé (#112)
- Bouton de copie explicite (icône copy.svg + « Copier le lien » + retour
  « ✓ Copié ») sur /tableau et /compte/vues, via dcc.Clipboard (children /
  copied_children), à la place de l'icône seule.
- Le lien direct s'affiche en texte (span#share-url-text) plutôt qu'un
  <input> : évite la troncature d'affichage du champ Bootstrap form-control en
  flex (zone de texte bloquée ~218px), montre tout le lien avec retour à la
  ligne, et prend la largeur du lien. Stylé comme un champ (bordure, coins
  arrondis, texte 90%).
- Instructions /compte/vues simplifiées ; E2E adapté (#share-url-text).
2026-07-13 22:08:00 +02:00
Colin Maudry f0a891b73f fix(tableau): griser/désactiver les boutons vues pour les non-abonnés
La barre des vues sauvegardées restait masquée pour les non-abonnés via un
style inline display:none — inopérant car .d-inline-flex est
display:inline-flex !important, la barre était donc toujours visible.

La barre reste désormais visible pour tous ; « Sauvegarder la vue » et
« Mes vues » sont grisés et désactivés (disabled) pour les non-abonnés. Le
gating serveur de save_view (prepare_view_to_save) reste inchangé.
2026-07-13 19:23:03 +02:00
Colin Maudry 3034e911e7 feat(tableau): masquage du bloc de partage piloté par événements AG Grid (#112)
Remplace le verrou de dérive à compteur (suppress-next) par une détection
événementielle : eventListeners AG Grid (filterChanged/sortChanged) →
dashAgGridFunctions.hideShareOnUserAction, qui efface active-view sur action
utilisateur (source != 'api') et ignore l'écho de l'application programmatique.

Le compteur suppress-next souffrait d'une course d'ordonnancement Dash (l'écho
lisait la valeur pré-batch) et le diff de columnState était impraticable (état
réémis bruité). La visibilité du bloc bascule via la classe (d-flex/d-none) et
non le style inline, car .d-flex est display:flex !important.

Task 7 : test E2E de bout en bout (application + masquage sur action).
2026-07-13 18:41:36 +02:00
Colin Maudry 2a22951829 feat(tableau): verrou de derive + affichage du bloc de partage (#112) 2026-07-13 17:34:29 +02:00
Colin Maudry 301a8668b3 feat(tableau): resolution ?vue= + bloc URL de partage (#112) 2026-07-13 17:32:48 +02:00
Colin Maudry 03afb8347c feat(mcp): instructions OAuth Claude.ai/ChatGPT sur /compte/mcp (#114)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 14:43:01 +02:00
Colin Maudry 8b3e72d20a MCP uniquemnet pour les clients CLI 2026-07-13 12:53:14 +02:00
Colin Maudry 7d413ccda4 feat(titulaire): migration du tableau des marchés vers AG Grid (#41) 2026-07-13 12:03:37 +02:00
Colin Maudry 639c2eb986 feat(acheteur): migration du tableau des marchés vers AG Grid (#41) 2026-07-13 12:03:37 +02:00
Colin Maudry 10c1e45d71 Update version de Dash dans CLAUDE.md 2026-07-13 12:01:00 +02:00
Colin Maudry f2810640ba %àj instructions clients MCP 2026-07-13 09:25:39 +02:00
Colin Maudry b4e778ab8c Mode d'emploi tableau 2026-07-13 07:50:34 +02:00
Colin Maudry 6dd7dca271 Améliorations sur le style de l'ag grid, ajout nb marchés uniques #47 2026-07-12 20:44:43 +02:00
Colin Maudry f580459bd5 Améliorations sur le style de l'ag grid #47 2026-07-11 16:58:36 +02:00
Colin Maudry 117ce9a4ab fix(tableau): filtres à conditions multiples ignorés + tri non réinitialisé (#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>
2026-07-10 20:21:53 +02:00
Colin Maudry 34e5065550 Merge branch 'worktree-111-mcp-connecteur' into dev (connecteur MCP, scope B #111) 2026-07-10 16:13:06 +02:00
Colin Maudry ff78b86ad0 feat(mcp): page compte Connecteur MCP + instructions clients (scope B #111)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-10 15:16:36 +02:00
Colin Maudry 4f36022443 fix(tableau): vues sauvegardées en AST canonique, cache du comptage, synchro visibilité colonnes (#41) 2026-07-10 14:44:14 +02:00
Colin Maudry 0bfac680a5 fix(tableau): vues sauvegardées pré-migration + double comptage track_search (#41)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-10 14:34:47 +02:00
Colin Maudry 055b0edc7e docs(tableau): mode d'emploi réécrit pour AG Grid (#41)
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>
2026-07-10 13:53:19 +02:00
Colin Maudry 8efd8db07e feat(tableau): vues sauvegardées en JSON AST, retrait URL riche (#41)
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).
2026-07-10 08:35:31 +02:00
Colin Maudry fbea2ebd53 feat(tableau): export Excel via DuckDB (AST->SQL) (#41)
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>
2026-07-10 08:26:10 +02:00
Colin Maudry 436906911b feat(tableau): sélecteur de colonnes piloté par columnDefs (#41)
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>
2026-07-10 08:17:44 +02:00
Colin Maudry 4c1c1cc987 feat(tableau): grille AG Grid + datasource getRows server-side (#41)
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.
2026-07-10 08:11:06 +02:00
Colin Maudry dee6e37932 Liste des codes CPV 2026-07-09 20:32:29 +02:00
Colin Maudry 9cf065e0db fix: traduire en français les libellés des dcc.Dropdown (#101)
Dash 4 introduit le prop labels sur dcc.Dropdown ("Select all",
"Deselect all", placeholder "Search", etc.). Ajout d'un dict partagé
DROPDOWN_LABELS_FR (src/utils/frontend.py) appliqué aux 11 dcc.Dropdown
de l'app (observatoire.py, acheteur.py, titulaire.py).
2026-07-09 17:41:05 +02:00
Colin Maudry 73b06c324a Changement titre page d'accueil 2026-07-07 21:26:36 +02:00
Colin Maudry 2376987982 fix(admin): revérifier is_admin() dans le callback _update_table (#110)
Le callback Dash _update_table est un endpoint serveur global
(/_dash-update-component) invocable indépendamment du layout : la garde
is_admin() de layout() ne protégeait que l'affichage. Sans contrôle dans
le callback, un non-admin — voire un anonyme sur le chemin lecture —
pouvait lire/écrire toute la base SQLite utilisateurs.

Ajoute la garde en tête du callback + test de non-régression.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 18:47:11 +02:00
Colin Maudry 92e30979d9 fix(abonnement): erreur Dash au chargement de mes-infos en mode configure
Le callback _toggle_submit référence inf-cb-retractation/inf-cb-cgu en
Input sans condition, mais ces cases n'étaient rendues qu'en mode
"subscribe". Elles sont maintenant toujours montées (masquées et
pré-cochées en mode configure) pour que Dash trouve toujours ces ids.
2026-07-06 11:01:26 +02:00
Colin Maudry ad028b9e6b Rédactionnel 2026-07-06 10:49:08 +02:00
Colin Maudry e8f74aa529 feat(abonnement): message 'changement à la prochaine échéance' sous les cards (#109)
Ajoute la fonction _change_hint et étend le callback _select_plan pour afficher
un hint "changement à la prochaine échéance" quand l'utilisateur sélectionne
un plan différent du plan courant.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-05 20:46:54 +02:00
Colin Maudry 7ae5b75db9 feat(abonnement): mode configure sur mes-infos (formule préactivée, sans cases) (#109)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-05 20:42:09 +02:00
Colin Maudry a2962c2163 feat(abonnement): prix + bouton Configurer sur /compte/abonnement (#109)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-05 20:35:50 +02:00
Colin Maudry ee214677bd feat(abonnement): bouton changer de méthode de paiement sur /compte/abonnement
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-05 17:03:28 +02:00
Colin Maudry 349fb17c90 feat(abonnement): sélection de formule par cartes cliquables dans mes-infos
Remplace la garde ?plan= (redirection si absent) par une sélection
interactive : deux cartes de formule (réutilisées de la page publique via
_plan_card) cliquables, un callback recopie le choix dans un champ caché
natif soumis avec le POST du formulaire. Le bouton de soumission reste
désactivé tant qu'aucune formule n'est choisie (en plus des cases à
cocher existantes).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-04 23:43:39 +02:00
Colin Maudry 315c500005 feat(abonnement): CTA connexion vers /a-propos/abonnement
Remplace le CTA du bas de /connexion ("Créer un compte avec mon adresse
email" → "/inscription") par un lien vers l'offre d'abonnement ("Pas encore
de compte ? Voir les abonnements" → "/a-propos/abonnement").

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-04 23:39:06 +02:00
Colin Maudry 3b744d87f0 feat(abonnement): /compte/abonnement non-abonné affiche M'abonner/Me réabonner 2026-07-04 23:34:35 +02:00
Colin Maudry c5c63cb68e fix(abonnement): calcul du prix TTC robuste (évite les artefacts flottants)
Remplace le hack `str(int(prix_ht) * 1.2).replace('.0', '')` par
`round(prix_ht * 1.2, 2)` formaté avec `:g`, qui gère correctement les
prix qui ne multiplient pas proprement par 1.2 (ex: 24 -> 28.8 au lieu
de 28.799999999999997).

Le fichier src/pages/compte/abonnement.py contient le même bug mais
n'est pas touché ici : sa copie de _plan_card sera supprimée à la
tâche 4 du plan de refonte du tunnel d'abonnement.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-04 23:28:14 +02:00
Colin Maudry e904ec4a7d feat(abonnement): page publique avec cards et bouton Je m'abonne conditionnel
La page publique /a-propos/abonnement affiche désormais les cards de
formule (informatives, sans bouton par card), un explainer des
fonctionnalités, et un unique CTA "Je m'abonne" dont la cible dépend
de l'état d'authentification/abonnement. Retrait de la sous-section
"Fonctionnalités incluses" des CGU (doublon avec l'explainer).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-04 23:21:19 +02:00
Colin Maudry cc2b34e84a feat(abonnement): linkedin_button paramétrable par next, inscription vers mes-infos
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-04 23:13:11 +02:00
Colin Maudry c748cb944e Déplacement de la matrice de doublon vers Données 2026-07-04 20:44:41 +02:00
Colin Maudry c9ece32601 Rédactionnel, tableau étapes dans Donnéees 2026-07-04 20:19:51 +02:00