Save SAO AG Grid work

This commit is contained in:
2026-05-04 10:38:07 +02:00
parent ce1be14602
commit fc9ab5da0b
8 changed files with 5825 additions and 229 deletions

View File

@@ -0,0 +1,478 @@
# Analyse de compatibilite SAO / AG Grid
## Objectif
Evaluer si la vue `tree` de SAO peut etre rendue compatible avec une grille open source gratuite, en particulier AG Grid Community, sans React, en JavaScript pur.
## Conclusion courte
Oui, c'est faisable, mais pas comme un simple remplacement visuel de `<table>` par AG Grid.
La vue `tree` actuelle de SAO embarque a la fois:
- le rendu HTML du tableau
- la logique de selection
- l'expansion arborescente
- l'edition inline
- des widgets de cellule lies aux champs Tryton
- le tri
- les colonnes optionnelles
- les boutons d'action
- le drag-and-drop
- les chargements asynchrones de champs
La bonne approche est donc de creer une couche d'adaptation entre:
- le modele Tryton/SAO existant
- et un moteur de rendu "grid"
Autrement dit: il faut decoupler `Sao.View.Tree` de son rendu DOM actuel, puis brancher AG Grid comme renderer alternatif.
## Ce que fait aujourd'hui la vue tree
### 1. Parsing XML des colonnes
La vue `tree` est construite depuis le XML Tryton via `Sao.View.TreeXMLViewParser`, qui instancie des colonnes specialisees selon `attributes.widget`.
References:
- `tryton-sao.js:21678` `Sao.View.TreeXMLViewParser`
- `tryton-sao.js:24807` `Sao.View.TreeXMLViewParser.WIDGETS`
Implication:
- la definition des colonnes est deja structuree
- c'est un bon point d'entree pour produire des `columnDefs` AG Grid
### 2. La vue Tree est tres couplee au DOM table
`Sao.View.Tree` construit directement:
- `div.tree-container`
- `table`
- `colgroup`
- `thead`
- `tbody`
- `tfoot`
References:
- `tryton-sao.js:21755`
- `tryton-sao.js:21796`
- `tryton-sao.js:21803`
- `tryton-sao.js:21810`
- `tryton-sao.js:21908`
Implication:
- aujourd'hui, `Tree` n'est pas un controleur de donnees avec un renderer interchangeable
- c'est deja le renderer
### 3. Les lignes encapsulent elles aussi rendu + comportement
`Sao.View.Tree.Row` construit chaque `<tr>` et tous les `<td>`, gere les clics, doubles clics, la selection, l'expansion, et le rendu cellule par cellule.
References:
- `tryton-sao.js:23219` `Sao.View.Tree.Row`
- `tryton-sao.js:23270` `_construct`
- `tryton-sao.js:23378` `redraw`
- `tryton-sao.js:23528` `toggle_row`
- `tryton-sao.js:23536` `expand_row`
- `tryton-sao.js:23575` `expand_children`
Implication:
- remplacer seulement `table` ne suffit pas
- il faut aussi contourner ou remplacer `Row`
### 4. Le rendu cellule depend fortement des classes Column
Chaque type de colonne sait:
- charger les donnees au besoin
- formatter la valeur
- masquer selon l'etat du champ
- ouvrir des liens Tryton
- afficher des icones/prefixes/suffixes
- gerer des actions particuliere
References:
- `tryton-sao.js:24089` `Sao.View.Tree.CharColumn`
- `tryton-sao.js:24204` `BooleanColumn`
- `tryton-sao.js:24239` `Many2OneColumn`
- `tryton-sao.js:24365` `SelectionColumn`
- `tryton-sao.js:24630` `BinaryColumn`
- `tryton-sao.js:24755` `ButtonColumn`
Implication:
- ces classes sont reutilisables
- mais aujourd'hui elles renvoient surtout du DOM jQuery, pas des objets de configuration AG Grid
### 5. L'edition inline repose sur les widgets Form existants
L'edition tree editable utilise `Sao.View.EditableTree.*`, qui reutilise les widgets formulaire SAO dans les cellules.
References:
- `tryton-sao.js:23737` `Sao.View.Tree.RowEditable`
- `tryton-sao.js:24834` `Sao.View.EditableTree`
Implication:
- c'est une excellente nouvelle pour un POC
- on peut probablement injecter ces widgets dans des `cellEditor` / `cellRenderer` AG Grid custom
- mais il faudra un pont entre le cycle de vie AG Grid et le cycle de vie jQuery/SAO
## Fonctionnalites compatibles assez directement
### Faisable avec une couche d'adaptation raisonnable
- affichage tabulaire
- tri simple sur colonne
- affichage/masquage de colonnes
- selection simple ou multiple
- rendu des types de base: texte, nombre, booleen, date, selection
- boutons de ligne
- copier les lignes selectionnees
Pourquoi:
- SAO a deja les meta-donnees de colonnes
- AG Grid sait tres bien rendre et mettre a jour ces cas
## Fonctionnalites plus sensibles
### 1. Arborescence
SAO gere le mode arbre via `children_field`, expansion paresseuse et chemins de lignes.
References:
- `tryton-sao.js:21836`
- `tryton-sao.js:23479`
- `tryton-sao.js:23575`
Risque:
- il faut mapper cela soit sur le mode tree data AG Grid, soit sur un flattening manuel
- le comportement exact Tryton devra etre conserve, surtout avec chargement lazy
### 2. Edition inline riche
Le flux actuel depend de:
- validation Tryton
- focus clavier
- navigation tab/up/down/enter
- creation de nouvelle ligne a la volee
- sauvegarde conditionnelle
References:
- `tryton-sao.js:23122` `save_row`
- `tryton-sao.js:23163` `edit_row`
- `tryton-sao.js:23893` `key_press`
Risque:
- AG Grid a son propre cycle d'edition
- si on force trop AG Grid, on peut casser le comportement SAO historique
### 3. Chargement asynchrone champ par champ
Le rendu actuel charge les champs a la demande:
- `record.load(...)`
- puis rendu de cellule
References:
- `tryton-sao.js:23204`
- `tryton-sao.js:24120`
- `tryton-sao.js:24681`
Risque:
- AG Grid prefere un modele de `rowData` deja exploitable
- il faudra soit pre-hydrater les lignes, soit supporter des renderers asynchrones
### 4. Drag-and-drop
Le drag-and-drop actuel est tres metier:
- reordonnancement
- changement de parent
- mise a jour des groupes Tryton
- sequence
References:
- `tryton-sao.js:22193` `_add_drag_n_drop`
- `tryton-sao.js:22229` `drag_data_received`
Risque:
- il vaut mieux le repousser a une phase 2
### 5. Sommes de colonnes
Les aggregats sont calcules cote SAO avec prise en compte de la selection.
References:
- `tryton-sao.js:23000`
- `tryton-sao.js:22799`
Risque:
- simple a refaire
- mais il faut decider si l'on garde le footer SAO ou si l'on utilise un footer AG Grid
## Niveau de couplage actuel
Le couplage le plus fort est ici:
1. `Tree` construit la structure HTML complete
2. `Row` construit la structure HTML de chaque ligne
3. `Column.render()` renvoie des fragments DOM jQuery
4. `EditableTree` suppose une presence directe dans le DOM de la cellule
Donc:
- brancher AG Grid directement dans `Sao.View.Tree` sans abstraction serait fragile
- mieux vaut introduire une interface de rendu
## Architecture recommandee
## Option A: remplacement direct de `Sao.View.Tree`
Creer `Sao.View.AGGridTree` qui:
- reutilise `TreeXMLViewParser`
- produit des `columnDefs`
- produit des `rowData`
- delegue a AG Grid pour le rendu
- conserve les appels metier SAO sur `screen`, `record`, `field`
Avantages:
- architecture propre
- bon potentiel a long terme
Inconvenients:
- investissement initial important
- beaucoup de points de compatibilite a reproduire
Verdict:
- meilleur choix si vous voulez un vrai basculement progressif vers une grid moderne
## Option B: mode hybride avec adaptateur de cellules
Conserver `Sao.View.Tree` comme source de verite fonctionnelle, mais:
- remplacer le rendu des lignes par AG Grid
- encapsuler les `Column.render()` existants dans des `cellRenderer`
- encapsuler `EditableTree.*` dans des `cellEditor`
Avantages:
- permet un POC plus vite
- reutilise plus de logique existante
Inconvenients:
- couche d'adaptation plus complexe
- risque de double logique DOM
Verdict:
- meilleur choix pour prouver la faisabilite rapidement
## Option C: simple relooking du tableau actuel
Ne pas utiliser AG Grid, seulement moderniser la table SAO actuelle.
Verdict:
- utile pour du cosmetique
- ne repond pas a l'objectif
## Recommandation concrete
Je recommande une strategie en 3 phases.
### Phase 1: abstraction minimale
Introduire une couche d'adaptation dans SAO:
- `TreeDataAdapter`
- `TreeColumnAdapter`
- `TreeSelectionAdapter`
But:
- separer les donnees et comportements du rendu HTML actuel
### Phase 2: POC AG Grid Community
Cibler uniquement:
- vue tree non hierarchique
- non editable dans un premier temps
- tri
- selection
- affichage/masquage colonnes
- boutons simples
- rendu texte/nombre/date/booleen/selection
Ne pas viser tout de suite:
- tree data
- drag-and-drop
- edition inline riche
- aggregats complexes
### Phase 3: extension progressive
Ajouter ensuite:
- edition inline
- tree data
- aggregates
- drag-and-drop
- compatibilite complete des widgets speciaux
## POC minimal realiste
Le plus petit POC utile serait:
1. Ajouter AG Grid Community dans `index.html`
2. Introduire une option de feature flag, par exemple:
- `Sao.config.use_ag_grid`
3. Si activée et si la vue est `tree` sans `children_field` et sans `editable`:
- construire une vue AG Grid
4. Mapper les colonnes SAO vers `columnDefs`
5. Mapper `screen.group` vers `rowData`
6. Reconnecter:
- clic ligne -> `screen.current_record`
- double clic -> `screen.row_activate()`
- tri -> `screen.order` puis `screen.search_filter(...)`
## Mapping propose
### Colonnes SAO -> AG Grid
- `attributes.name` -> `field`
- `attributes.string` -> `headerName`
- `column.sortable` -> `sortable`
- `column.attributes.width` -> `width`
- `column.attributes.readonly` -> `editable: false`
- `column.render(...)` -> `cellRenderer`
### Lignes SAO -> AG Grid
Chaque ligne doit garder:
- le `record` Tryton original
- un `id`
- des valeurs calculees affichables
Exemple de forme:
```js
{
__record: record,
__id: record.id,
customer: "...",
amount: "...",
state: "..."
}
```
Important:
- ne pas perdre la reference vers `record`, car toute la logique SAO en depend
## Points d'attention AG Grid
D'apres la documentation officielle AG Grid:
- AG Grid Community existe bien en JavaScript pur
- elle peut etre instanciee sans React avec `agGrid.createGrid(...)`
- elle peut etre chargee par bundle/CDN
Sources:
- https://www.ag-grid.com/javascript-data-grid/getting-started/
- https://www.ag-grid.com/javascript-data-grid/installation/
Inference:
- techniquement, votre environnement SAO charge deja des librairies JS globales via `index.html`, donc l'integration sans React est coherent avec l'architecture actuelle
## Risques principaux
### Risque 1: regressions fonctionnelles
Le danger n'est pas le rendu brut, mais les details de comportement Tryton:
- selection exacte
- edition
- navigation clavier
- chargement lazy
- etats invisibles/readonly
### Risque 2: dette de double implementation
Pendant la transition, vous aurez probablement:
- la vue tree legacy
- la vue tree AG Grid
Il faut donc mutualiser au plus vite:
- les colonnes
- l'acces aux valeurs
- la selection
### Risque 3: AG Grid Community vs besoins reels
Certaines fonctions avancees existent surtout en Enterprise selon les versions et editions.
A verifier au moment du POC, fonctionnalite par fonctionnalite, sans supposer que tout le comportement tree legacy est couvert nativement.
## Estimation honnete
### Faisabilite
- POC non editable, liste plate: elevee
- grille utilisable sur plusieurs vues simples: bonne
- compatibilite complete avec toutes les vues tree SAO: moyenne a difficile
### Cout relatif
- POC: faible a moyen
- integration propre: moyen
- remplacement complet: eleve
## Recommendation finale
Oui, il est pertinent de tenter AG Grid Community en JavaScript pur, mais il faut:
- commencer par les vues tree plates
- introduire un adaptateur plutot qu'un remplacement brutal
- traiter l'edition inline et l'arborescence dans un second temps
Le meilleur prochain pas est de realiser un POC isole sur:
- une vue tree non editable
- sans `children_field`
- avec 3 a 5 types de colonnes
- selection + tri + double-clic ouverture
Si ce POC marche bien, on pourra ensuite brancher l'edition et les widgets complexes.