Skip to content
Snippets Groups Projects
Commit f23bc481 authored by mathias.chouet's avatar mathias.chouet
Browse files

Fix #316, #317 - rewrote developers doc

parent f658c689
No related branches found
No related tags found
No related merge requests found
......@@ -56,15 +56,13 @@ L'interface s'appuie sur les principes de **material design** et de **responsive
L'état de la session, des modules, des paramètres et des résultats numériques est conservé par JaLHyd. Seules les représentations graphiques sont conservées par la couche ngHyd.
#### formulaires
nodes
Pour chaque module chargé en session, un arbre d'objets partant d'une instance de `FormulaireDefinition` représente la structure des éléments à l'écran : groupes de champs (répétables ou non), champs, listes déroulantes. Ces éléments sont déclarés dans les fichiers du dossier `src/app/formulaire`.
ngparam
#### formulaires
form*, form-compute*, form-result*
Les formulaires dérivent de `FormulaireBase`. Lors de leur instanciation, ils se chargent de lire leur configuration (voir "configuration/modules" ci-dessous) et instancier les éléments enfants qui y sont déclarés : groupes de champs ("fieldset"), groupes de champs répétables ("fieldset_container"), paramètres d'entrée ("ngparam"), listes déroulantes ("select_field"). Ensuite le formulaire est lié au Nub de JaLHyd correspondant au module créé.
#### résultats
Chaque formulaire est associé à une instance d'une classe `FormCompute*` et une instance d'une classe `FormResult*`. La première est chargée d'exécuter le Nub de JaLHYd associé au formulaire, et de transmettre les résultats de calcul à la seconde. La seconde est chargée d'organiser les résultats (par défaut les grouper en résultats fixes / résultats variés) afin de faciliter leur représentation par les composants graphiques.
### configuration
......@@ -134,7 +132,7 @@ Le dossier `scripts` contient des scripts d'aide à la compilation, utilisés pa
## Ajouter un module de calcul
Dans cet exemple nous considérerons le module fictif "Addition" proposé dans la documentation de JaLHyd (voir ci-dessous).
Dans cet exemple nous considérerons le module fictif "Addition" proposé dans la documentation de JaLHyd (voir ci-dessous), tout en ajoutant des informations utiles pour des cas plus complexes.
### JaLHyd
......@@ -240,29 +238,167 @@ Dans les fichiers `locale/messages.*.json` :
### classes de formulaire personnalisées
2. **Si nécessaire** créer la classe du formulaire dans _src/app/formulaire/definition/concrete_ . Une classe de base gérant la majorité des cas est déjà disponible, en général cette étape n'est pas nécessaire
En général la classe `FormulaireBase` est suffisante pour gérer un nouveau module, et est instanciée automatiquement par `FormulaireService` lors de la création d'un nouveau module. Elle agrège es instances de `FormComputeFixedVar` et `FormResultFixedVar`.
- Par ex : _FormulaireMaCalculette_ dans _src/app/formulaire/definition/concrete/form-ma-calculette.ts_
Mais dans des cas plus complexes, par exemple si le module contient des listes déroulantes ou des sous-modules, répétables ou non, il est nécessaire de créer de nouvelles classes de formulaires dérivées de celles-ci.
Ces classes concrètes sont construites par composition des classes dans _src/app/formulaire/definition_ :
- _form-def-*_ : définition/description du formulaire.
- _FormDefSection_ : avec paramètre à varier
- _FormDefParamToCalculate_ : avec paramètre à calculer
- etc...
- _form-compute-*_ : aspects calculatoires
- _form-result-*_ : affichage des résultats
Dans un tel cas, créer la classe du formulaire dans un nouveau fichier, dans le dossier `src/app/formulaire/definition/concrete/`/ Par exemple `form-macrorugo-compound.ts`.
On peut soit composer la classe concrète directement avec ces classes, soient dériver ces dernières et composer avec.
Si les mécanismes de calcul ou de récupération des résultats doivent être modifiés, créer les classes nécessaires dans le dossier `src/app/formulaire/definition`, par exemple `form-compute-macrorugo-compound.ts` et `form-result-macrorugo-compound.ts`. Sinon, agréger des classes `FormCompute*` et `FormResult*` existantes.
Si une nouvelle classe de formulaire a été créée, ajouter un `case` dans la méthode `newFormulaire()` de `FormulaireService`, dand `src/app/services/formulaire.service.ts`. Exemple :
5. **Si une nouvelle classe a été créée à l'étape 2**, dans la méthode _FormulaireService.newFormulaire()_, compléter le _switch_ pour fournir la classe à instancier.
```TypeScript
case CalculatorType.Trigo:
f = new FormulaireTrigo();
break;
```
### si le module agrège des modules enfants
La traduction des variables des modules enfants doit aussi être ajoutée dans les fichiers de langues, dans le dossier de configuration du module.
#### si ces modules enfants sont répétables ("fs_container)
Il est nécessaire de créer une nouvelle classe de formulaire dérivée de `FormulaireBase` (voir "classes de formulaire personnalisées" ci-dessus), en s'inspirant de `FormulaireMacrorugoCompound` par exemple. Notamment, implémenter ou surcharger les méthodes :
* `createFieldset()`
* `moveFieldsetUp()`
* `moveFieldsetDown()`
* `removeFieldset()`
* `completeParse()`
* `update()` (action "newFieldset")
Dans la méthode `create()` de `CalculatorListComponent`, dans le fichier `src/app/components/calculator-list/calculator-list.component.ts`, ajouter la création d'un enfant par défaut. Exemple pour `MacrorugoCompound` :
```TypeScript
if (f instanceof FormulaireMacrorugoCompound) {
for (const e of f.allFormElements) {
if (e instanceof FieldsetContainer) {
e.addFromTemplate(0, 0, f.mrcNub.children[0]);
break;
}
}
}
```
Dans cet exemple, on ajoute l'interface pour le premier enfant du Nub (instancié par JaLHyd), à l'élément de formulaire de type `FieldsetContainer` (ici, il n'y en a qu'un).
Ajouter ensuite la création de fieldsets pour les enfants existants, dans la méthode `createFormulaire()` de `FormulaireService`, dans le fichier `src/app/services/formulaire.service.ts`. Exemple pour `ParallelStructures` :
```TypeScript
if (f.currentNub instanceof ParallelStructure) {
for (const struct of f.currentNub.structures) {
for (const e of f.allFormElements) {
if (e instanceof FieldsetContainer) {
e.addFromTemplate(0, undefined, struct);
}
}
}
}
```
Dans chaque fichier de langue du dossier `src/locale`, ajouter les traductions pour le nom type d'enfant (voir la documentation développeurs de JaLHyd), au singulier et au pluriel sous les clés `INFO_CHILD_TYPE_typedenfant` et `INFO_CHILD_TYPE_typedenfant_PLUR`. Par exemple pour le type d'enfant `Macrorugo` en français :
```json
"INFO_CHILD_TYPE_MACRORUGO": "radier",
"INFO_CHILD_TYPE_MACRORUGO_PLUR": "radiers",
```
### si le formulaire comprend des listes déroulantes
Il est nécessaire de créer une nouvelle classe de formulaire dérivée de `FormulaireBase` (voir "classes de formulaire personnalisées" ci-dessus), en s'inspirant de FormulaireTrigo par exemple. Notamment, implémenter ou surcharger les méthodes :
* `afterParseFieldset()`
* `parseOptions()`
* `update()` (appeler `reset()` lors de l'action "propertyChange")
#### configuration
Dans le fichier de configuration du module, ajouter la définition des listes déroulantes dans "fields" notamment leur **source** (voir "sources" plus bas), ainsi que leur valeur par défaut dans le "fieldset" parent. Exemple dans `trigo.config.json`
```json
{
"id": "fs_trigo",
"type": "fieldset",
"defaultOperation": "COS",
"defaultUnit": "DEG",
"fields": [
{
"id": "select_operation",
"type": "select",
"source": "trigo_operation"
},
{
"id": "select_unit",
"type": "select",
"source": "trigo_unit"
}
]
},
```
Dans ce même fichier de configuration, dans le dernier élément "options", ajouter une entrée par liste déroulante :
```json
{
"type": "options",
"operationSelectId": "select_operation",
"unitSelectId": "select_unit",
```
#### sources
Chaque liste déroulante est associée à une **source** (voir "configuration" plus haut), qui détermine quels sont les choix possibles. Pour ajouter une source, modifier la méthode `parseConfig()` de la classe `SelectField`, dans le fichier `src/app/formulaire/select-field.ts`. Exemple pour "trigoOperation" :
```TypeScript
case "trigo_operation": // (cos, sin…)
for (let j = 0; j < Object.keys(TrigoOperation).length / 2; j++) {
this.addEntry(new SelectEntry(this._entriesBaseId + j, j));
}
break;
```
#### lien avec les propriétés
Les listes déroulantes doivent être liées à des **propriétés** du Nub. Pour ce faire, modifier la classe `FieldSet` dans le fichier `src/app/formulaire/fieldset.ts` comme suit (exemple pour le module `Trigo`).
Ajouter un `case` dans la fonction `updateFields()`
```TypeScript
case "fs_trigo": // Trigo
this.setSelectValueFromProperty("select_operation", "trigoOperation");
this.setSelectValueFromProperty("select_unit", "trigoUnit");
break;
```
Ajouter un `case` dans la fonction `update()`
```TypeScript
case "select_operation": // Trigo
this.setPropValue("trigoOperation", data.value.value);
break;
case "select_unit": // Trigo
this.setPropValue("trigoUnit", data.value.value);
break;
```
Dans la fonction `parseConfig()`, ajouter un appel par à `setPropertyValueFromConfig()` pour chaque liste déroulante.
```TypeScript
this.setPropertyValueFromConfig(json, "defaultOperation", "trigoOperation", TrigoOperation);
this.setPropertyValueFromConfig(json, "defaultUnit", "trigoUnit", TrigoUnit);
```
### documentation
Pour chaque langue, ajouter un fichier .md dans les dossiers `docs-*/calculators`, puis placer ce nouveau fichier dans la hiérarchie de la documentation, en ajoutant son chemin dans les fichiers `mkdocs-*.yml`.
Lier ce fichier au module via la clé `help` du bloc d'options de la configuration du module. Exemple pour un fichier de documentation dont le chemin est `calculators/math/addition.md` : `"help" : "math/addition.html"` (MkDocs convertit les fichiers MarkDown en HTML)
### tests unitaires
Plusieurs tests unitaires passent en revue les modules pour les tester un par un. Pour que le nouveau module soit testé, son `CalculatorType` doit être ajouté à la liste dans le fichier `e2e/tested_calctypes.ts.
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment