Files
sao2.0/AG_GRID_PROGRESS.md
2026-06-02 20:17:32 +02:00

55 KiB

Avancement du projet AG Grid / SAO

Contexte

Objectif: rendre le client web SAO compatible avec une grille open source gratuite, en commencant par AG Grid Community en JavaScript pur, sans React.

Depot analyse: Sao

Date de cet etat: 2026-03-28

Documents deja crees

  • AG_GRID_COMPATIBILITY_ANALYSIS.md
  • AG_GRID_PROGRESS.md

Ce qui a ete decouvert dans le projet

Fichiers principaux

  • tryton-sao.js: coeur applicatif monolithique, inclut les vues tree
  • tryton-sao.css: styles globaux SAO
  • index.html: charge les dependances et les fichiers dist en production

Point d'entree des vues

La creation des vues se fait dans:

  • tryton-sao.js autour de Sao.View.parse

Le type tree etait instancie directement par:

  • new Sao.View.Tree(view_id, screen, xml, children_field)

Cela a ete modifie pour permettre un branchement conditionnel vers une vue AG Grid.

Architecture tree actuelle dans SAO

Les vues tree sont fortement couplees au DOM.

Points importants:

  • Sao.View.TreeXMLViewParser parse le XML Tryton et construit les colonnes
  • Sao.View.Tree construit directement la table HTML et orchestre le comportement
  • Sao.View.Tree.Row construit les <tr> et les <td>
  • les Column gerent le rendu des cellules
  • EditableTree reutilise les widgets de formulaire pour l'edition inline

Conclusion utile:

  • le parsing XML et la logique metier de colonnes sont reutilisables
  • le rendu tabulaire natif ne l'est pas tel quel pour une integration propre AG Grid

Comportements SAO importants a ne pas perdre

  • screen.current_record
  • screen.row_activate()
  • screen.order
  • screen.search_filter(...)
  • selected_records
  • get_selected_paths()
  • get_expanded_paths()
  • colonnes optionnelles
  • widgets de colonne speciaux

Ce qui a ete implemente

1. Feature flag

Ajout de:

  • Sao.config.use_ag_grid = true

But:

  • pouvoir desactiver facilement le POC si besoin

2. Selection conditionnelle du renderer tree

Ajout d'un branchement dans:

  • Sao.View.parse

Via:

  • Sao.View.get_tree_view(...)

Cette fonction choisit:

  • Sao.View.AGGridTree si le contexte est supporte
  • sinon retour a Sao.View.Tree

3. Nouvelle vue POC

Ajout de:

  • Sao.View.AGGridTree

Etat actuel:

  • vise uniquement les vues tree plates
  • pas de support children_field
  • pas de support edition inline
  • pas de drag-and-drop

4. Conditions de support actuelles

Le POC AG Grid ne s'active que si:

  • Sao.config.use_ag_grid est actif
  • children_field est absent
  • la vue n'est pas editable
  • AG Grid est charge dans la page

Sinon:

  • fallback automatique sur la vue SAO historique

5. Integration HTML/CSS

Dans index.html:

  • ajout du script AG Grid Community via CDN
  • ajout des feuilles de style AG Grid via CDN
  • conservation des chemins de production:
    • dist/tryton-sao.js
    • dist/tryton-sao.css

Dans tryton-sao.css:

  • ajout d'un style minimal pour accueillir la grille

6. Fonctions reliees dans le POC

Deja branche:

  • affichage d'une grille AG Grid
  • mapping basique des colonnes SAO
  • mapping des lignes SAO vers rowData
  • double clic ligne -> screen.row_activate()
  • synchronisation partielle de la selection
  • copie des lignes selectionnees
  • lecture partielle du tri depuis AG Grid vers screen.order

Ce qui a ete observe lors du premier essai

D'apres le retour utilisateur et la capture:

Fonctionne deja

  • affichage general de la grille
  • resize des colonnes
  • rendu global suffisamment bon pour un premier POC

Probleme observes

  1. Les delimitations visuelles entre colonnes ne sont pas visibles

Interpretation:

  • surtout un probleme de style / theme
  1. La selection de ligne ne fonctionne pas correctement

Observation:

  • une petite image etrange apparait a la place de la checkbox

Interpretation probable:

  • conflit CSS entre le theme AG Grid et les styles globaux SAO
  • ou mauvaise utilisation du checkboxSelection sur la premiere colonne
  1. Le tri par colonne est absent ou incomplet

Interpretation probable:

  • certaines colonnes ne sont pas effectivement triables dans le columnDef
  • ou l'etat de tri est perdu a cause du cycle display()
  1. L'ordre manuel des colonnes ne persiste pas

Observation:

  • les colonnes peuvent etre inversees
  • mais reviennent a l'ordre initial apres un tri / refresh

Interpretation:

  • la vue reconstruit les columnDefs a chaque display()
  • l'etat local AG Grid n'est pas encore sauvegarde/restaure

Ce qui est normal a ce stade

Pour la phase 1 / POC:

  • pas de support arbre
  • pas d'edition inline
  • pas de drag-and-drop
  • style encore tres basique
  • persistance de l'etat de colonnes non faite

Ce qui n'est pas considere comme "normal final"

Ces points doivent etre corriges rapidement:

  • la fausse checkbox / icone etrange
  • le tri incomplet
  • la perte d'ordre des colonnes apres refresh

Hypotheses techniques importantes pour la suite

Sur la selection

Le plus probable est qu'il faut:

  • utiliser une vraie colonne dediee a la selection
  • ou desactiver certains styles globaux SAO qui polluent les controles AG Grid

Sur la persistance des colonnes

Il faudra stocker et restaurer:

  • columnState
  • ordre des colonnes
  • largeur des colonnes
  • tri actif

Soit:

  • dans l'instance de vue elle-meme
  • soit dans un cache SAO proche de tree_states

Sur le tri

Le tri ne doit pas seulement etre visuel.

Il faut conserver la logique metier SAO:

  • mettre a jour screen.order
  • relancer screen.search_filter(...)
  • puis restaurer l'etat de la grille sans perdre l'ordre utilisateur

Plan conseille pour la prochaine session

Passe 2 prioritaire

  1. Corriger la colonne de selection AG Grid
  2. Ajouter une vraie persistance de columnState
  3. Corriger le tri par colonne
  4. Ajouter un style leger:
    • separateurs verticaux
    • header plus lisible
    • checkbox visible

Passe 3 ensuite

  1. Filtres de colonne
  2. Support de plus de types de colonnes speciaux
  3. Sommes / footer
  4. Eventuelle persistance serveur ou locale des preferences de colonnes

Session du 2026-03-30

Objectif de la session

Faire passer le POC d'un renderer AG Grid "utilisable" a une vraie vue de travail avec:

  • persistance de configuration utilisateur
  • panneau de colonnes exploitable
  • grouping multi-level avec agregations et sous-totaux
  • correction des bugs de state qui bloquaient le debug

Ce qui a ete ajoute

1. Persistance de l'etat de grille par user/vue

Le POC memorise maintenant dans localStorage, par base/utilisateur/modele/vue:

  • ordre des colonnes
  • largeur des colonnes
  • visibilite des colonnes
  • tri actif
  • configuration de grouping

La persistance est reappliquee a l'ouverture de la vue et a chaque display() pour eviter la perte d'etat quand SAO reconstruit la vue.

2. Panneau Columns custom

Le panneau Columns a ete implemente comme un panneau custom, attache au body, et non plus comme un dropdown Bootstrap.

But:

  • eliminer les interferences de layout/overflow du socle legacy
  • garder un comportement previsible
  • permettre un vrai controle de largeur/scroll

Le panneau permet:

  • masquer/afficher les colonnes
  • synchroniser l'etat avec la logique SAO des colonnes optionnelles quand c'est applicable

3. Harmonisation visuelle

Ajouts/corrections de session:

  • harmonisation de la couleur des checkboxes avec accent-color: #145369
  • remplacement des icones toolbar Columns et Grouping par des SVG inline plus sobres
  • retrait du bouton COPY SELECTED ROWS de la toolbar

4. Grouping V1 cote client

Ajout d'un panneau Grouping avec:

  • grouping multi-level
  • reordonnancement des niveaux
  • suppression d'un niveau
  • agregations client-side:
    • sum
    • avg
    • count
    • min
    • max
  • affichage optionnel des sous-totaux
  • affichage optionnel du grand total
  • persistance de l'etat de grouping

Implementation retenue:

  • generation de lignes synthetiques group et total dans rowData
  • pas de dependance au grouping Enterprise
  • comportement borne aux lignes effectivement chargees dans la vue

5. Corrections de bugs importantes pendant l'integration

Les points suivants ont bloque puis ete corriges:

  • crash d'initialisation quand this.screen n'etait pas encore pret au chargement du state
  • panneau Columns trop etroit tant qu'il dependait du dropdown Bootstrap
  • clic sur le bouton de groupe qui ne repliait pas toujours le groupe
  • erreurs de selection car les lignes synthetiques group / total n'ont pas de __record
  • Remove dans le panneau Grouping qui semblait agir mais ne supprimait pas vraiment le state

Cause cle de ce dernier point:

  • jQuery.extend(true, ...) preservait l'ancien contenu des tableaux de state, notamment groupBy

Correction retenue:

  • construction explicite du state grouping
  • remplacement complet de la propriete grouping dans le state persiste
  • eviter les deep-merges pour cette partie

Traces de debug ajoutees

Cette session a confirme qu'il faut instrumenter plus tot les bugs resistants.

Traces ajoutees au fil de la session:

  • COLUMNS_MENU_LAYOUT
  • COLUMNS_MENU_LAYOUT_FLAT_JSON
  • GROUPING_ACTION_FLAT_JSON
  • GROUPING_STATE_FLAT_JSON
  • GROUPING_PERSISTED_FLAT_JSON
  • ROW_DATA_KIND_FLAT_JSON

Lecon importante:

  • les traces doivent etre plus frequentes
  • elles doivent arriver plus tot dans la boucle de debug
  • pour tout partage dans le chat, il faut une variante ..._FLAT_JSON

Etat du POC apres cette session

Le POC couvre maintenant correctement:

  • vues tree plates non editables
  • selection de lignes
  • tri
  • filtres popup
  • persistance locale du layout utilisateur
  • panneau Columns
  • grouping multi-level client-side
  • agregations
  • sous-totaux
  • grand total

Les limitations actuelles restent:

  • pas de children_field
  • pas d'edition inline
  • pas de drag-and-drop metier
  • agregations calculees uniquement sur les lignes chargees localement

Next steps memorises

Priorite produit logique

  1. Presets / bookmarks d'affichage par user/vue

Objectif:

  • donner au user plusieurs configurations nommees et choisissables

Contenu d'un preset:

  • ordre des colonnes
  • largeur des colonnes
  • visibilite des colonnes
  • tri
  • grouping
  • agregations
  • options d'affichage associees

Important:

  • a ce stade, le bookmark SAO existant memorise surtout des filtres/domaines
  • il faut probablement separer:
    • bookmark de recherche/metier
    • preset d'affichage grille
  1. Ajouter un vrai Reset layout / Reset grouping

  2. Ajouter Expand all / Collapse all explicite dans le panneau Grouping

  3. Mieux cadrer le rendu des lignes de sous-total et du grand total

  4. Mieux diagnostiquer les vues qui restent sur l'ancien tree

Objectif:

  • rendre visible la raison du fallback:
    • children_field
    • vue editable
    • AG Grid non charge

Next steps logiques apres grouping et sous-totaux

  • presets d'affichage nommes par user/vue
  • integration UX plus propre entre bookmark de filtre et preset de grille
  • support de plus de colonnes speciales non editables
  • footer/indicateurs numeriques plus riches
  • export des vues en respectant layout/grouping actif
  • instrumentation de fallback plus visible
  • ensuite seulement: evaluation d'un grouping/agregation cote backend pour des totaux "vrais" sur tout le dataset filtre

Plus tard

  1. Edition inline
  2. Tree data
  3. Drag-and-drop metier

Fichiers modifies pendant ce travail

  • index.html
  • tryton-sao.js
  • tryton-sao.css

Notes de deploiement

En production:

  • index.html reste a la racine
  • tryton-sao.js doit etre copie vers ./dist/tryton-sao.js
  • tryton-sao.css doit etre copie vers ./dist/tryton-sao.css

Le index.html a ete remis avec les chemins dist/....

Point d'attention environnement local

Dans cette copie locale du depot:

  • le dossier dist/ n'existait pas
  • node n'etait pas disponible
  • git status etait bloque par un probleme safe.directory

Cela n'empeche pas la continuation du travail, mais limite la verification locale automatisee.

Resume ultra court pour reprise rapide

Nous avons un premier POC AG Grid branche sur les vues tree plates non editables, avec fallback automatique vers la vue historique SAO. L'affichage de base fonctionne, mais la selection, le tri et la persistance de l'ordre des colonnes doivent etre corriges dans la prochaine passe.

Derniere session

Depuis ce premier resume, une grosse passe supplementaire a ete faite sur le POC AG Grid.

Ce qui a ete stabilise

  • colonne de selection avec checkbox visibles
  • tri fonctionnel sans vider la liste quand un filtre local est actif
  • popup filtre repositionne sous la bonne colonne
  • style du popup rapproche du rendu AG Grid standard
  • icones header plus propres
  • etat visuel "filtre actif" sur l'icone menu
  • gros nettoyage des glyphes parasites lies au vieux CSS SAO

Ce qui a coute du temps

  • conflits entre le theme AG Grid et les styles globaux SAO
  • pseudo-elements ::before / ::after
  • controles radio / checkbox pollues par le theme historique
  • corrections visuelles faites trop tot sans dump cible du vrai noeud DOM

Lecture recommandee avant la prochaine session

  1. AG_GRID_SESSION_INDEX.md
  2. AG_GRID_STYLING_NOTES.md

Resume pratique

Le POC est maintenant beaucoup plus abouti visuellement et fonctionnellement. Le prochain gain de temps viendra surtout d'une meilleure isolation entre AG Grid et le vieux socle CSS SAO, plutot que de nouvelles micro-corrections ponctuelles.

Session du 2026-03-30

Ce qui a ete ajoute

  • persistance locale par base/utilisateur/modele/vue de l'etat AG Grid
  • panneau Columns custom attache au body
  • gestion de la visibilite des colonnes
  • memorisation de l'ordre, des largeurs et du tri
  • harmonisation visuelle des checkboxes
  • suppression du bouton Copy Selected Rows de la toolbar
  • nouvelles icones toolbar plus propres pour Columns et Grouping
  • panneau Grouping custom attache au body
  • grouping multi-level client-side sans dependre d'AG Grid Enterprise
  • aggregations client-side:
    • sum
    • avg
    • count
    • min
    • max
  • sous-totaux sur lignes de groupe
  • total global optionnel
  • persistance de l'etat de grouping

Ce qui a demande plusieurs passes

  • stabilisation du panneau Columns
  • remplacement du dropdown Bootstrap par un panneau custom
  • correction du clic sur le bouton expand/collapse des groupes
  • correction des merges profonds sur le state grouping
  • correction de la synchronisation de selection avec les lignes synthetiques group / total

Ce qu'on a appris aujourd'hui

  • pour les panneaux flottants SAO/AG Grid, si le rendu est incoherent mais que les mesures sont bonnes, il faut soupconner le conteneur Bootstrap / stacking context avant le contenu lui-meme
  • les tableaux dans le state ne doivent pas etre reconstruits avec jQuery.extend(true, ...) si l'on veut vraiment remplacer leur contenu
  • sur ce POC, les lignes synthetiques group / total doivent etre traitees explicitement partout:
    • selection
    • row click
    • row id
    • copy
    • refresh

Discipline de debug a garder

  • mettre des traces plus frequentes des qu'un bug resiste a une premiere correction
  • produire une variante ..._FLAT_JSON pour toute trace destinee a etre copiee dans le chat
  • preferer un log "avant/apres state" plutot qu'un seul snapshot final
  • si le probleme touche le rendu, logger aussi:
    • type de lignes envoye a AG Grid
    • largeur/hauteur reelles
    • proprietaire du click

Next steps prioritaires

  1. Bookmarks de configuration d'affichage

    • objectif: permettre a l'utilisateur de memoriser plusieurs setups
    • contenu typique:
      • colonnes visibles
      • ordre des colonnes
      • tailles
      • tri
      • grouping
      • aggregations
    • recommandation: ne pas melanger brutalement avec le bookmark SAO actuel qui memorise surtout un filtre
    • meilleure piste: introduire des "bookmarks de vue" ou "presets d'affichage" distincts, puis eventuellement les relier a l'UI bookmark plus tard
  2. Reset / gestion des presets

    • bouton Reset Columns
    • bouton Reset Grouping
    • bouton Reset View
    • duplication / renommage / suppression d'un preset
  3. Expansion globale du grouping

    • Expand all
    • Collapse all
    • meilleure iconographie de repli/depli

Next steps logiques apres grouping et sous-totaux

  • presets nommes de vue par utilisateur
  • bookmark de tri et de config au sens "choisir une vue memorisee"
  • footer de totaux plus explicite si besoin metier
  • support d'autres types de colonnes dans les aggregations
  • export des donnees dans la configuration active
  • instrumentation claire du fallback vers l'ancien tree
  • indicateur visuel de mode:
    • vue AG Grid
    • vue legacy

Point de vigilance pour la prochaine session

  • penser a retirer les traces GROUPING_* et ROW_DATA_KIND_* une fois la stabilisation terminee
  • conserver cependant le patron de log JSON plat pour les prochains sujets difficiles

Session du 2026-03-31

Ce qui a ete ajoute

  • trace de decision renderer:
    • TREE_VIEW_DECISION_FLAT_JSON
  • diagnostic de fallback plus riche:
    • useAgGrid
    • hasChildrenField
    • agGridLoaded
    • editable
    • xmlEditable
    • screenReadonly
    • excludeField
    • preValidate
    • hasParentGroup
    • childName
    • parentName
    • selectedRenderer
    • fallbackReason

Garde-fou ajoute sur le fallback

Le POC AG Grid ne doit plus seulement exclure:

  • les vues avec children_field
  • les vues editable

Il doit aussi exclure les sous-listes embarquees de type relationnel / one2many qui paraissent "plates" mais restent editables par contexte.

Raison de fallback ajoutee:

  • embedded_relation_tree

Signaux utilises:

  • screen.group.parent
  • screen.group.child_name
  • screen.exclude_field
  • screen.pre_validate

But:

  • eviter qu'une sous-liste embarquee comme purchase.line parte en AG Grid alors qu'elle vit en realite dans un contexte de saisie relationnelle

Dark mode V1 safe

Ajout d'une V1 prudente du dark mode, sans toucher aux composants legacy les plus fragiles.

Infrastructure:

  • toggle global pres du logo
  • persistance locale via localStorage
  • attribut html[data-theme-mode="light|dark"]

Zones couvertes:

  • topbar globale
  • onglets principaux
  • menu gauche
  • shell principal
  • header de filtres modernise
  • toolbar de formulaire
  • AG Grid
  • panneaux Columns / Grouping

Zones volontairement non traitees en profondeur:

  • modales complexes
  • vieux dropdowns peu maitrises
  • widgets speciaux rares

Logo dark

Branchement automatique selon le theme:

  • light -> tradon.png
  • dark -> tradon-dark.png

Le switch du theme met maintenant aussi a jour le logo sans attendre un nouveau chargement logique.

Ajustements dark mode deja stabilises

  • menu gauche:
    • hover/active dark corrige
  • shell formulaire:
    • bandeau clair residuel du header corrige
  • grille:
    • alternance de lignes plus visible
    • hover et selection plus lisibles
    • checkbox dark custom plus coherente
  • toolbar de formulaire:
    • boutons et fond passes en dark

Memo pour la prochaine session

  • continuer a garder le dark mode dans un perimetre "safe" tant que les composants les plus fragiles ne sont pas inventories
  • si un nouveau bloc reste clair en dark mode, le traiter par zone locale au lieu de surcharger tout le theme global
  • si un fallback AG Grid semble anormal, commencer par lire TREE_VIEW_DECISION_FLAT_JSON

Session du 2026-05-04

Sauvegarde Git / repo

  • migration du remote Git vers:
    • https://gitea.open-squared.tech/admin/sao2.0.git
  • commit de sauvegarde global du travail AG Grid / dark mode / notes
  • rappel important d'arborescence:
    • ce repo ne correspond pas exactement a l'arborescence serveur
    • index.html est gere dans le repo parent cote serveur
    • les fichiers effectivement deployes manuellement cote serveur sont surtout dans /dist
    • quand on modifie tryton-sao.js ou tryton-sao.css, penser a synchroniser aussi dist/tryton-sao.js ou dist/tryton-sao.css

Correctif Many2One / icones dans les champs

Probleme observe:

  • dans les champs Many2One, le texte chevauchait l'icone primaire "ouvrir le modele lie"
  • le symptome etait visible sur des champs comme Party, Payment Term, Currency, From location, To location

Cause:

  • la modernisation CSS des inputs dans .screen-container avait casse le padding historique reserve aux icones input-icon-primary / input-icon-secondary
  • une premiere correction CSS ne s'appliquait pas car la page a html lang="en" theme="default" mais pas dir="ltr"
  • autre point important: index.html charge dist/tryton-sao.js et dist/tryton-sao.css, pas seulement les fichiers racine

Correction stabilisee:

  • ajout d'une correction JS dans Sao.View.Form.Many2One
  • nouvelle methode:
    • _sync_icon_padding
  • appelee depuis display
  • elle force le padding gauche/droite de l'input selon les icones visibles
  • correction appliquee dans:
    • tryton-sao.js
    • dist/tryton-sao.js

Trace temporaire utile:

  • [M2O_ICON_LAYOUT]

Note:

  • la trace est volontairement limitee aux premiers champs
  • elle pourra etre retiree apres stabilisation definitive de l'UI

Correctif AG Grid grouping restaure

Probleme observe:

  • en groupant par un champ Many2One comme Supplier, le grouping fonctionnait pendant la session
  • apres fermeture/reouverture de la forme, le panneau Grouping restaurait bien la ligne Supplier
  • mais les donnees etaient regroupees comme si les valeurs etaient vides, avec principalement (Empty)

Cause probable confirmee:

  • le state de grouping etait restaure avant que les valeurs texte des champs groupants soient chargees
  • pour un Many2One, il faut le rec_name
  • si la construction de rowData part trop tot, _get_group_key_text retombe sur une valeur vide et cree le groupe (Empty)

Correction:

  • ajout de _load_grouping_values
  • avant de construire rowData, display attend le chargement des champs presents dans grouping.groupBy
  • ensuite seulement la grille reconstruit les lignes groupees
  • correction appliquee dans:
    • tryton-sao.js
    • dist/tryton-sao.js

Traces utiles:

  • [AGGRID][GROUPING_LOAD_FIELDS_FLAT_JSON]
  • [AGGRID][GROUPING_KEYS_FLAT_JSON]

Favicon Trad'on

  • ajout d'une icone navigateur Trad'on basee sur le style existant:
    • grand T vert
    • fond carre arrondi bleu petrole / vert
  • fichier ajoute:
    • images/tradon-icon.png
  • index.html reference deja:
    • images/tradon-icon.png

Point de deploiement:

  • comme index.html est dans le repo parent cote serveur, verifier que le fichier images/tradon-icon.png est bien servi au bon chemin relatif
  • le cache favicon navigateur peut etre tenace: refresh dur ou vidage cache si besoin

Correctif recherche Many2One / modales de selection

  • probleme observe: depuis la nouvelle AG Grid, les fenetres Search ... ouvertes par la loupe des champs Many2One affichaient une grille vide
  • exemple: Search Broker depuis un contrat, alors que des party.party de categorie Broker existent bien
  • cause: Sao.Window.Search creait une vue tree readonly sans marqueur de contexte, donc le diagnostic AG Grid la prenait pour une liste principale plate
  • correctif: les ecrans crees par Sao.Window.Search portent maintenant search_window: true
  • Sao.View.AGGridTree.get_support_diagnostics exclut ce contexte avec fallbackReason: search_window
  • resultat attendu: les recherches Many2One repassent sur le tree historique, avec selection simple/multiple et search_filter SAO standard

Presets de vues AG Grid

  • ajout d'un menu Views dans la toolbar AG Grid
  • stockage local migre en version: 2 avec plusieurs presets par base/utilisateur/modele/vue
  • l'ancien etat unique est conserve comme currentState lors de la migration
  • actions disponibles:
    • appliquer un preset
    • Save as
    • Update
    • renommer
    • supprimer
    • definir/effacer le preset par defaut
    • revenir au layout standard
  • le bouton affiche le preset actif et ajoute * si l'utilisateur a modifie la grille depuis l'application du preset

Correctif hauteur AG Grid avec filtres hauts

  • probleme observe: dans Lots management, le formulaire de filtres au-dessus de la grille laisse une grille basse avec un scrollbar interne minuscule
  • cause probable: .ag-grid-tree-container forcait height: 100%, ce qui se calcule mal quand la grille est sous un gros bloc de filtres dans un contenu scrollable
  • correctif CSS: hauteur AG Grid autonome basee sur le viewport, avec minimum lisible
  • ne pas modifier les conteneurs internes .ag-center-cols-*: cela peut desynchroniser le scroll virtuel AG Grid apres expansion de groupe
  • ajout d'un refresh layout AG Grid apres chaque changement de rowData
  • traces ajoutees: LAYOUT_REFRESH_FLAT_JSON et compte displayedRowCount dans SCROLL_LAYOUT_DEBUG_JSON
  • diagnostic suivant: le conteneur SAO et le viewport AG Grid avaient chacun leur scroll
  • correctif retenu: AG Grid reste en layout normal avec son scroll interne, et le content-box SAO contenant une AG Grid passe en overflow-y: hidden
  • les options AG Grid alwaysShowHorizontalScroll et alwaysShowVerticalScroll sont activees pour forcer la reservation de la zone de scroll
  • la hauteur effective du host AG Grid est maintenant posee en JS apres rendu, car la regle CSS dynamique retombait a 320px
  • diagnostic suivant: le parent flex SAO comprimait encore le host AG Grid a 320px; content-box.ag-grid-content-box passe en bloc non-flex et overflow visible
  • horizontal: les colonnes AG Grid recoivent maintenant des largeurs minimales metier et les anciens presets trop etroits sont elargis apres restauration
  • diagnostic horizontal ajoute dans SCROLL_LAYOUT_DEBUG_JSON: clientWidth, scrollWidth, colonnes visibles et totalDisplayedWidth
  • artefact visuel corrige: content-box.ag-grid-content-box ne doit pas rester en overflow: visible, sinon la bordure du panneau SAO peut se dessiner au milieu des lignes AG Grid
  • le resize JS force maintenant le conteneur AG Grid et le content-box SAO a englober toolbar + host, pour eviter que le panneau parent se termine avant la fin de la grille
  • trace dediee ajoutee: [AGGRID][CONTAINER_CLIP_DEBUG_JSON], avec les deltas entre le host, le scrollbar horizontal et chaque parent
  • le conteneur AG Grid recoit maintenant une hauteur explicite, pas seulement un min-height, et overflow: hidden
  • trace/correction horizontale ajoutee: [AGGRID][HORIZONTAL_WIDTH_FORCE_JSON] force la largeur minimale totale des colonnes visibles dans le container de scrollbar horizontal
  • ajout d'un scrollbar horizontal externe sous le host AG Grid, synchronise avec les viewports AG Grid, car le scrollbar interne reste invisible malgre une largeur forcee superieure au viewport
  • diagnostic global ajoute: [AGGRID][SAO_AGGRID_LAYOUT_DEBUG_JSON] liste les dimensions page/SAO/AG Grid, les enfants du screen-container et les wideElements qui elargissent le document
  • CSS: les conteneurs AG Grid/SAO dedies recoivent min-width: 0, max-width: 100% et box-sizing: border-box pour eviter qu'un enfant scrollable etire le formulaire complet
  • correction largeur: _resize_grid_host fixe maintenant explicitement la largeur visible du host/conteneur/content-box sur la largeur viewport disponible, separee de la largeur interne scrollable des colonnes
  • cause identifiee via l'inspecteur: #tabcontent > .tab-pane.active etait un flex item dont la taille minimale suivait le contenu AG Grid (~3963px); ajout de min-width: 0 / max-width: 100% / overflow-x: hidden sur la chaine #tabs -> #tabcontent -> tab-pane -> panel -> panel-body
  • ajustement alignement: la largeur visible de la grille est maintenant calculee depuis le bord droit reel du screen-container, pas depuis window.innerWidth - left, pour aligner la grille avec le panneau de filtres/header
  • nettoyage: suppression des traces console AG Grid/M2O temporaires
  • finition scroll horizontal: ajout d'un tampon de 72px a la largeur scrollable pour eviter que la derniere colonne soit coupee par le bord/scrollbar
  • stabilisation largeur apres interaction: les changements de colonnes AG Grid relancent maintenant _resize_grid_host et _force_horizontal_scroll_width; un ResizeObserver surveille aussi le conteneur SAO
  • stabilisation offcanvas: un MutationObserver surveille .row-offcanvas et relance le layout a 0/80/180/320ms apres le toggle du menu lateral
  • filtre multi-valeurs: colonnes non numeriques avec <= 80 valeurs distinctes utilisent un filtre custom a cases a cocher; au-dela on garde le filtre texte/numerique AG Grid standard
  • les filtres AG Grid sont maintenant inclus dans l'etat/presets sauvegardes via getFilterModel / setFilterModel
  • robustesse filtre multi-valeurs: le composant lit les valeurs depuis params.filterParams, params.colDef.filterParams, ou les recalcule depuis les lignes AG Grid si necessaire
  • correction filtre multi-valeurs: le fallback lit maintenant node.data[colDef.field], car params.getValue(node) retournait vide avec notre rowData texte
  • correction filtre multi-valeurs: la checklist se rafraichit maintenant a l'ouverture du popup pour couvrir le cas ou le composant filtre est initialise avant le chargement complet du rowData
  • correction filtre multi-valeurs: ajout de getLiveValues() dans filterParams, relu depuis _last_row_data puis group, afin de ne plus dependre des params internes du composant filtre AG Grid
  • correction filtre multi-valeurs: ajout de getNodeValue() dans filterParams pour que doesFilterPass compare exactement les memes valeurs que celles affichees dans la checklist
  • fiabilisation filtre multi-valeurs: le composant custom ne filtre plus directement; il alimente un etat _sao_value_filters et le filtrage effectif passe par isExternalFilterPresent / doesExternalFilterPass
  • apres changement checklist, _apply_sao_value_filters() force gridApi.onFilterChanged(), remonte au premier index et relance le layout; necessaire apres NONE puis re-selection, sinon AG Grid peut rester sur un viewport vide
  • test mode combinaison checklist: ajout du bouton toolbar All filters / Any filter; all applique un ET entre colonnes filtrees, any applique un OU entre colonnes filtrees
  • apres refresh des filtres header SAO, les domaines all des filtres checklist sont reconciles avec le nouveau row_data; l'activite d'un filtre compare maintenant l'inclusion des valeurs, pas seulement la taille des sets
  • si apres refresh header SAO une checklist active n'a plus aucune valeur selectionnee presente dans le nouveau dataset, le filtre est supprime pour eviter de vider la grille avec une selection fantome
  • stabilisation finale checklist:
    • la liste des valeurs doit venir du group SAO complet, pas des lignes deja filtrees par AG Grid
    • le composant custom ne doit pas filtrer directement via doesFilterPass; il pilote seulement _sao_value_filters
    • le filtrage reel passe par isExternalFilterPresent / doesExternalFilterPass
    • All filters applique un ET entre colonnes; Any filter applique un OU entre colonnes
    • apres refresh des filtres header SAO, reconcilier les filtres checklist avec le nouveau dataset et supprimer les selections devenues fantomes
    • ne pas comparer seulement selected.size et all.size: verifier l'inclusion des valeurs disponibles
    • ne pas laisser les traces VALUE_FILTER_* actives apres diagnostic
  • ordre des colonnes avec grouping: apres restauration de l'etat/preset, _apply_grouping_column_order() place les colonnes groupees en premier dans l'ordre groupBy, puis conserve l'ordre relatif courant des autres colonnes
  • grouping + filtres checklist: les records sont filtres avant _flatten_grouped_rows, afin que __recordCount, sous-totaux et enfants visibles restent coherents; les lignes groupe/total passent toujours le filtre externe
  • grouping manuel + tri AG Grid: l'etat de colonnes restaure ne doit pas reappliquer sort / sortIndex quand le grouping est actif; sinon AG Grid trie le rowData plat et separe les records de leurs lignes groupe.
  • Many2Many embarques: les trees creees par Form.Many2Many portent maintenant relation_widget: 'many2many' et retombent en renderer historique; AG Grid ne doit pas prendre ces listes tant que la suppression/add-remove relationnelle n'est pas explicitement compatible.
  • retour d'action/cancel: _reconcile_sao_value_filters_with_rows() doit passer avant _get_row_data(). Sinon une checklist devenue obsolete apres reload/cancel peut etre supprimee trop tard et laisser la grille vide jusqu'au prochain display.
  • POC logique filtres: le bouton All filters / Any filter ouvre maintenant un panneau Filter logic listant les filtres checklist actifs et permettant de choisir Match all ou Match any, sans changer encore le moteur vers des groupes ET/OU imbriques.
  • POC groupes filtres: le panneau Filter logic peut maintenant activer Use groups, creer des groupes, placer chaque filtre actif dans un groupe, choisir AND/OR dans chaque groupe et AND/OR entre groupes. Le mode simple reste le comportement par defaut.

Correctif retour wizard avec filtres checklist actifs

  • scenario valide: dans Lots management, appliquer un Any filter sur deux periodes (Purchase Delivery Period / Sale Delivery Period), selectionner deux lignes, lancer l'action/wizard Go to matching, puis cliquer Cancel
  • bug observe: au retour du wizard, l'action recevait bien les deux ids selectionnes, mais la grille revenait vide; le compteur SAO restait pourtant non vide (/63) et le refresh du rapport ne restaurait pas les lignes
  • diagnostic: les records etaient encore presents dans screen.group; le probleme venait du filtre externe AG Grid pilote par _sao_value_filters
  • cause technique: apres reload/cancel, les champs utilises par les filtres checklist pouvaient ne pas etre charges au moment de recalculer rowData; le filtre comparait alors les valeurs selectionnees (JUL26) a des valeurs record temporairement vides
  • correctif: display() charge maintenant explicitement les champs des filtres checklist actifs via _load_sao_value_filter_values() avant _reconcile_sao_value_filters_with_rows() et avant _get_row_data()
  • ordre a conserver:
    • charger les valeurs de grouping si besoin
    • charger les champs des filtres checklist actifs
    • reconstruire les colonnes
    • reconcilier les domaines checklist avec screen.group
    • calculer rowData
  • invariant: les valeurs de filtre doivent toujours etre comparees a partir du group SAO complet et de champs charges; ne pas laisser le viewport AG Grid deja filtre ou un record partiellement charge devenir la source de verite
  • trace garde-fou: [AGGRID][VALUE_FILTER_EMPTY_RESULT_JSON] ne doit apparaitre que si un filtre checklist actif donne 0 resultat alors que screen.group contient encore des records; lire sampleRows, les indicateurs *:loaded, et les ensembles selected/all
  • ne pas confondre avec une perte de selection: ici la selection initiale et les ids envoyes au wizard etaient corrects; l'incoherence etait post-retour dans le recalcul du filtre externe

Synthese fin de session AG Grid

  • principe general: distinguer les couches state sauvegarde, state moteur en memoire, rowData donne a AG Grid, viewport/filtre AG Grid; un bug peut venir d'une couche correcte puis detruite par la suivante
  • lifecycle: display() peut passer avec groupSize:0; ne jamais supprimer/reconcilier agressivement des filtres ou des vues sur une passe sans donnees
  • filtres checklist: Sao.View.AGGridValueSetFilter est une UI seulement; le vrai filtre vit dans _sao_value_filters et passe par external filter + prefiltrage du rowData
  • rowData: quand une action checklist peut elargir le resultat (Clear, All, recocher, bascule All/Any), reconstruire rowData depuis screen.group; gridApi.onFilterChanged() seul ne peut pas ramener des lignes absentes du rowData
  • persistence vues: les checklist filters ne doivent pas vivre dans le filterModel AG Grid (saoValueSet), mais dans valueFilters; setModel() du composant custom ne doit pas notifier le moteur
  • actions utilisateur vs guards: les guards anti-perte de filtre ne doivent proteger que les passes techniques de restauration; une action utilisateur explicite doit toujours gagner contre l'etat saved/restored
  • vue vierge: Default view est une entree systeme, pas un preset utilisateur; elle remet a zero colonnes/filtres/valueFilters/grouping custom et retire le preset custom par defaut
  • resize colonnes: separer largeur par defaut et largeur minimale; les helpers de layout/scrollbar ne doivent jamais appeler setColumnWidth() ni reappliquer columnDefs pendant un drag utilisateur
  • scrollbar horizontal: _force_horizontal_scroll_width() doit seulement dimensionner les conteneurs de scroll avec getActualWidth(); il ne doit pas modifier les largeurs utilisateur
  • traces utiles si regression:
    • vue/filtres: [AGGRID][TREE_LIFECYCLE_JSON], [AGGRID][VALUE_FILTER_STATE_JSON], [AGGRID][VALUE_FILTER_CHANGE_JSON], [AGGRID][VALUE_FILTER_EMPTY_RESULT_JSON]
    • resize: [AGGRID][COLUMN_RESIZE_JSON]
    • lire la chaine complete: persisted state -> memory state -> display lifecycle -> rowData -> AG Grid viewport
  • hygiene avant fin: retirer ou reduire les traces temporaires une fois les scenarios valides; garder seulement les traces garde-fou vraiment necessaires

Correctif restauration UI des checklists sauvegardees

  • bug observe: apres Views > Update, le preset restaurait bien le bouton Any filter, mais les popups Purchase Delivery Period / Sale Delivery Period rouvraient avec toutes les valeurs cochees
  • cause: le moteur externe _sao_value_filters etait restaure, mais chaque instance Sao.View.AGGridValueSetFilter recreait son UI avec selected = all values
  • correctif: _get_column_filter_params() fournit maintenant getSavedValueFilter(); le composant custom applique cet etat dans _applySavedSelection() a l'init, dans setModel(null) et apres _refreshValuesFromGrid()
  • correction suite traces: ne pas persister/rejouer les modeles AG Grid filterType: 'saoValueSet' dans state.filters; ils peuvent rappeler setModel() pendant le lifecycle AG Grid et vider _sao_value_filters
  • Sao.View.AGGridValueSetFilter.setModel() ne doit pas appeler _notifySelectionChanged(); seuls les clics utilisateur (change, All, None, Clear) doivent modifier l'etat externe
  • invariant: sauvegarder/restaurer une vue doit garder trois couches coherentes:
    • mode global all/any
    • etat moteur _sao_value_filters
    • cases cochees visibles dans les popups de colonnes
  • test de regression: sauver une vue avec Any filter et deux Delivery Period partiellement cochees, recharger/appliquer la vue, ouvrir chaque filtre colonne; les valeurs non selectionnees doivent rester decochees

Correctif restauration avant chargement du group

  • bug observe: au retour dans une vue sauvegardee, load_persisted_state restaurait bien r_del_period=JUL26 et r_sale_del_period=JUL26, puis la grille affichait les 180 lignes non filtrees jusqu'a une interaction manuelle sur le filtre
  • cause tracee: display() peut s'executer une premiere fois avec groupSize:0; _reconcile_sao_value_filters_with_rows() voyait alors un domaine vide et supprimait les filtres restaures avant l'arrivee du vrai screen.group
  • correctif: si des filtres checklist existent mais que this.group est encore vide, la reconciliation est ignoree et trace reconcile-skip-empty-group; les filtres restent actifs pour la passe suivante avec les records charges
  • invariant: ne jamais supprimer un filtre checklist restaure sur une passe de lifecycle sans records; la suppression des selections obsoletes ne doit se faire que lorsque le dataset courant est reellement disponible
  • lecon de debug: quand une vue restaure mal un filtre, ne pas s'arreter au log load_persisted_state correct; suivre aussi init-end, chaque display-start, display-row-data, filterKeys, activeValueFilters, groupSize et rowDataCount
  • anti-pattern a eviter: une fonction de reconciliation ne doit jamais traiter groupSize:0 comme une preuve que les valeurs sauvegardees sont obsoletes; 0 record pendant le lifecycle peut seulement vouloir dire "les donnees ne sont pas encore arrivees"
  • trace utile pour isoler vite ce type de bug: comparer stateFilterKeys (sauvegarde), memoryFilterKeys / filterKeys (moteur courant), et persistedFilterKeys (etat disponible pour l'UI du popup)
  • diagnostic rapide attendu si regression: load_persisted_state contient les filtres, puis une passe display-start groupSize:0 ne doit plus etre suivie d'une disparition de filterKeys; elle doit produire reconcile-skip-empty-group

Correctif clear/all des checklists sauvegardees

  • bug observe: apres restauration d'une vue avec filtres checklist, remettre une colonne a Clear / tout coche pouvait ne pas ramener les lignes attendues; l'ancien valueFilters sauvegarde restait disponible et pouvait etre relu par getSavedValueFilter()
  • cause: les protections ajoutees contre les pertes de filtre au chargement etaient trop larges (capture/merge reprenaient l'etat persiste des qu'aucun filtre actif n'etait detecte)
  • correctif: les sources utilisateur (checkbox-change, all-button, none-button, clear-button) deviennent prioritaires; elles oublient l'etat restaure/persisted de la colonne touchee dans l'instance courante
  • invariant: un guard de restauration peut proteger une passe technique sans donnees, mais ne doit jamais annuler une intention utilisateur explicite de modifier ou supprimer un filtre
  • consequence: apres Clear d'une checklist, _sao_value_filters[colId] est supprime, l'ancien saved state de cette colonne n'est plus re-injecte, puis _apply_sao_value_filters() relance onFilterChanged()
  • correction suite: les filtres checklist prefiltrent aussi le rowData envoye a AG Grid; quand une action utilisateur elargit le filtre, onFilterChanged() seul ne peut pas faire revenir des records absents du rowData courant
  • correctif rowData: _apply_sao_value_filters() reconstruit maintenant le rowData depuis screen.group via _refresh_sao_value_filter_row_data() avant de relancer le filtre externe AG Grid
  • invariant: si un filtre custom change la population de records avant flatten/grouping, chaque changement utilisateur (All, Clear, checkbox, changement All/Any) doit reconstruire rowData, pas seulement appeler le moteur de filtre AG Grid

Vue systeme vierge

  • ajout d'une entree systeme Default view dans le menu Views de toutes les grilles AG Grid
  • objectif: revenir a une vue vierge de personnalisation sans devoir supprimer ou modifier les presets utilisateur
  • etat standard: pas de colonnes sauvegardees, pas de filtre AG Grid natif, pas de valueFilters, mode checklist all, pas de groupes de filtres, grouping par defaut
  • choisir Default view applique cet etat standard et retire le preset custom marque comme default, afin qu'un reload ne ramene pas immediatement une ancienne vue personnalisee

Resize colonnes

  • bug observe: certaines colonnes revenaient immediatement a leur largeur avant/apres drag, surtout quand on essayait de les reduire
  • cause: _enforce_minimum_column_widths() utilisait _get_default_column_width() comme largeur minimale; une largeur par defaut metier (Supplier=320, Purchase/Sale=220, Period=180) ne doit pas devenir une contrainte de resize utilisateur
  • correctif: separation entre largeur par defaut et vraie largeur minimale via _get_minimum_column_width(); les colonnes gardent leur largeur initiale confortable, mais peuvent etre reduites jusque 80px environ selon le type
  • invariant: les stabilisations de layout doivent corriger les vieux states absurdes, pas annuler une action manuelle valide de resize
  • correction suite: le resize utilisateur ne passe plus par le refresh layout global; pendant le drag, les timers _schedule_grid_layout_refresh() sont annules, puis la largeur est seulement sauvegardee et le scroll horizontal est recalcule
  • invariant: onColumnResized doit capturer/sauver la largeur, mais ne doit pas appeler doLayout() ou reappliquer des columnDefs/state pendant le drag
  • cause finale tracee: _force_horizontal_scroll_width() recalculait le scroll horizontal avec les largeurs par defaut et appelait setColumnWidth() si une colonne etait plus petite; reduire r_supplier a 248px etait aussitot annule vers 320px
  • correctif final: _force_horizontal_scroll_width() additionne maintenant les largeurs reelles getActualWidth() et ne modifie plus jamais les largeurs de colonnes
  • invariant: une fonction de scrollbar peut dimensionner le conteneur de scroll, mais ne doit jamais changer la taille des colonnes utilisateur

A faire - tri en mode grouping AG Grid

  • demande UX: permettre asc / desc / aucun tri sur les colonnes meme quand le grouping AG Grid manuel est actif
  • la configuration de vue doit memoriser ce tri, comme les colonnes, filtres checklist, valueFilters et grouping
  • point de vigilance majeur: ne pas simplement remettre sortable: true avec le tri natif AG Grid sur le rowData groupe
  • raison: le grouping est construit manuellement dans _flatten_grouped_rows() avec lignes group, record, total; un tri natif AG Grid apres coup peut separer les records de leurs groupes ou deplacer sous-totaux/totaux
  • approche recommandee:
    • capturer l'intention de tri utilisateur dans l'etat de vue
    • trier les records source avant _flatten_grouped_rows()
    • pour une colonne de grouping, trier l'ordre des groupes a ce niveau
    • pour une colonne non groupee, trier les records a l'interieur des groupes
    • reconstruire ensuite rowData en preservant expandedPaths, sous-totaux, grand total et filtres checklist actifs
  • invariant: en mode grouping, AG Grid ne doit jamais trier directement les lignes deja groupees; SAO doit trier les records avant construction des groupes
  • tests a prevoir: asc/desc/none, colonne groupee, colonne non groupee, groupes ouverts/fermes, sous-totaux, grand total, filtres checklist actifs, sauvegarde/restauration de preset, retour a Default view

Correctif largeur formulaire avec menu gauche masque

  • bug observe: dans la forme Purchase/contrat, meme menu gauche cache, le formulaire ne s'etirait plus sur toute la largeur; il restait visuellement autour de 75% de l'ecran
  • contexte: les travaux AG Grid avaient beaucoup verrouille la chaine #tabs / #tabcontent / panel avec min-width: 0 et max-width: 100% pour eviter qu'une grille large etire le shell
  • cause: #tabs.main-offcanvas garde les classes Bootstrap col-xs-12 col-sm-8 col-lg-9; quand .row-offcanvas n'est pas active, width: 100% seul ne neutralise pas completement le comportement de colonne Bootstrap sur grand ecran
  • correctif CSS: .row-offcanvas:not(.active) .main-offcanvas force maintenant float: none, flex: 0 0 100%, width: 100%, max-width: 100%
  • correctif complementaire: .screen-container porte aussi min-width: 0, width: 100%, max-width: 100% pour transmettre proprement la largeur au formulaire/contenu
  • fichiers modifies: toujours synchroniser tryton-sao.css et dist/tryton-sao.css, car index.html charge le CSS depuis dist/
  • lecon: apres un correctif AG Grid/offcanvas, tester les deux etats du hamburger; menu visible, la zone centrale doit rester en colonne Bootstrap, menu cache, elle doit redevenir pleine largeur

Invariant critique scroll AG Grid vs formulaire classique

  • regression observee apres les essais de scroll vertical AG Grid: une forme Purchase classique, sans AG Grid principale, etait coupee verticalement et mal redimensionnee, avec ou sans menu gauche
  • cause reelle: _resize_grid_host() pose des dimensions inline sur le content_box quand il contient une AG Grid (height, minHeight, flexBasis, flexShrink, width, maxWidth); si le meme content_box est ensuite reutilise pour une forme classique, ces styles inline peuvent survivre apres retrait de la classe ag-grid-content-box
  • autre cause dangereuse: ne jamais mettre overflow-y: hidden sur .screen-container ou sur un conteneur commun pour supprimer le scroll SAO; cela casse les formulaires classiques et les sous-listes embarquees
  • correctif cle: dans Sao.ScreenContainer.set, quand is_ag_grid est faux, nettoyer explicitement les dimensions inline du content_box avant d'ajouter le widget classique
  • invariant: les adaptations de scroll AG Grid doivent etre strictement limitees a .content-box.ag-grid-content-box et aux conteneurs internes AG Grid; une fiche formulaire doit garder .content-box en flex: 1 1 auto avec overflow-y: auto
  • test obligatoire apres toute retouche layout/scroll: ouvrir une forme Purchase sans AG Grid principale, menu gauche ouvert puis cache; verifier que le formulaire descend jusqu'aux onglets/lignes et que la zone centrale se redimensionne correctement
  • test complementaire: ouvrir Lots Management ou une vue report AG Grid avec filtres hauts; verifier que le scroll vertical utile reste celui de l'AG Grid et que le conteneur SAO ne cree pas un deuxieme scroll parasite

Selection globale AG Grid

  • demande UX: retrouver la tick d'en-tete de l'ancien tree SAO pour selectionner/deselectionner toutes les lignes visibles de la AG Grid
  • implementation: colonne speciale __selection__ avec un headerComponent custom et une checkbox d'en-tete
  • comportement retenu: la tick agit sur les vrais nodes record apres filtre AG Grid, et ignore explicitement les lignes synthetiques group / total
  • la checkbox d'en-tete passe en indeterminate quand une partie seulement des lignes visibles est selectionnee
  • synchronisation: apres un changement de selection, un filtre ou un rebuild de rowData, appeler _sync_selection_header_checkbox() pour garder l'etat visuel coherent avec _selected_ids
  • subtilite AG Grid importante: ne pas passer l'instance Sao.View.AGGridTree dans headerComponentParams ou filterParams; l'objet contient des references circulaires et AG Grid peut partir en too much recursion en traitant les columnDefs
  • correctif retenu: creer le composant d'en-tete via une closure (_get_selection_header_component) plutot qu'en passant l'instance SAO complete dans les params
  • invariant: dans les params AG Grid, passer seulement des primitives, des tableaux/objets simples ou de petites fonctions ciblees; eviter les gros objets SAO (screen, tree, view, widgets jQuery)

Commits importants

  • fc9ab5d Save SAO AG Grid work
  • d9292b8 Fix served Many2One icon padding
  • d78c9e0 Fix AG Grid restored grouping values
  • fb54c32 Add Tradon browser favicon

Memo pour la prochaine session

  • ne pas oublier que les changements utiles au serveur doivent souvent toucher dist/
  • retirer plus tard les traces temporaires:
    • [M2O_ICON_LAYOUT]
    • [AGGRID][GROUPING_LOAD_FIELDS_FLAT_JSON]
    • [AGGRID][GROUPING_KEYS_FLAT_JSON]
    • les anciennes traces GROUPING_* / ROW_DATA_KIND_* si elles ne sont plus necessaires
  • si le grouping restaure retombe encore sur (Empty), lire d'abord:
    • GROUPING_LOAD_FIELDS_FLAT_JSON
    • GROUPING_KEYS_FLAT_JSON
  • si une correction visuelle semble inactive, verifier d'abord quel fichier est charge par index.html et si dist/ a ete synchronise

Session du 2026-06-02 - KPI badges Lots Management non resolu

Demande UX:

  • rapprocher Lots management de la maquette recue:
    • barre KPI compacte entre les boutons AG Grid et la grille
    • compteurs par valeur de badge (Open, Physic, scheduled, shipped, unshipped, etc.)
    • badges en rendu pastel: fond clair + texte couleur forte
    • couleurs proches de la maquette:
      • Open: bleu
      • Physic: violet
      • scheduled: orange
      • shipped: vert
      • unshipped: rouge

Ce qui a ete implemente dans tryton-sao.js / dist/tryton-sao.js:

  • ajout de this.summary_bar sous la toolbar AG Grid
  • appel de _update_summary_bar() apres:
    • changement de colonnes
    • changement de filtre AG Grid
    • refresh de rowData
    • display()
  • prise en compte de la hauteur de la barre KPI dans _resize_grid_host()
  • helpers ajoutes/touches:
    • _get_visible_record_rows
    • _get_summary_badge_columns
    • _render_summary_item
    • _update_summary_bar
    • _normalize_badge_text_key
    • _get_badge_color_order
    • _get_badge_display_colors
    • _append_badge_summary_items
    • _get_summary_status_sources_from_grid
    • _get_default_badge_summary_color
  • tentative de fallback:
    • scanner les columnDefs AG Grid visibles qui ressemblent a des colonnes status, state, type, shipping, shipment, open/physic
    • normaliser les valeurs type emoji + Open en Open

Ce qui a ete implemente dans tryton-sao.css / dist/tryton-sao.css:

  • styles .ag-grid-tree-summary, .ag-grid-summary-item, .ag-grid-summary-label, .ag-grid-summary-value
  • badges .ag-grid-badge passes en fond clair + texte plus fort
  • couleurs dark mode pour la barre KPI

Etat observe par l'utilisateur:

  • les badges de grille sont bien en rendu pastel pour Shipping status
  • Qt type affiche encore Open / Physic en texte simple ou avec rendu partiel selon la config cote Tryton
  • la barre KPI affiche toujours seulement:
    • Rows
    • 192
  • les compteurs par valeur de badge ne s'affichent pas, meme apres les fallbacks ajoutes

Conclusion importante:

  • le probleme des totaux par valeur de badge n'est PAS resolu
  • ne pas considerer les helpers KPI actuels comme valides
  • prochaine reprise: instrumenter avant de retoucher encore

Hypotheses probables a verifier:

  • _get_summary_badge_columns() retourne vide au runtime, ou retourne des colonnes sans valeurs exploitables
  • _get_summary_status_sources_from_grid() ne voit pas les columnDefs attendus au moment ou _update_summary_bar() tourne
  • rows contient bien 192 lignes, mais les proprietes lues (row[name]) ne correspondent pas aux field/colId visibles dans AG Grid
  • les valeurs visibles dans les cellules peuvent venir du valueGetter / renderer, mais ne pas etre presentes dans le rowData sous le meme nom
  • le summary_bar peut etre mis a jour avant que _grid_columns soit disponible ou avant que les columnDefs restaurees soient reappliquees

Trace a ajouter en premier a la prochaine session:

  • une trace plate, appelee par exemple [AGGRID][SUMMARY_BADGES_DEBUG_JSON], dans _update_summary_bar()
  • champs minimum:
    • rowsLength
    • rowKeysSample: Object.keys(rows[0] || {})
    • rowSample: valeurs des colonnes visibles sur 1 ou 2 lignes
    • summaryBadgeColumns: noms/labels/attributs des colonnes retournees par _get_summary_badge_columns()
    • gridColumns: field, colId, headerName, cellClass, headerClass de this._grid_columns
    • displayedColumns: getAllDisplayedColumns().map(col => col.getColId())
    • statusSources: retour de _get_summary_status_sources_from_grid()
    • summaryItemsBeforeRender

Lignes Tryton/XML conseillees pour le rendu badges, mais a confirmer apres debug:

<field name="r_lot_status" widget="badge"
       badge_colors="Open:#2563eb,Physic:#8b5cf6"/>

<field name="r_shipping_status" widget="badge"
       badge_colors="scheduled:#f59e0b,shipped:#16a34a,unshipped:#ef4444"/>

Point de vigilance:

  • si Qt type a un emoji/prefixe cote Python ou XML, SAO doit soit:
    • rendre l'icone separement du texte de valeur
    • soit normaliser la cle avant mapping couleur/KPI
  • eviter de continuer a corriger "a l'oeil"; le prochain pas doit etre une trace runtime partageable.