Save SAO AG Grid work
This commit is contained in:
478
AG_GRID_COMPATIBILITY_ANALYSIS.md
Normal file
478
AG_GRID_COMPATIBILITY_ANALYSIS.md
Normal 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.
|
||||
Reference in New Issue
Block a user