From a32d39d4e4e23547068be6043ffa974982c405fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Fri, 26 May 2023 14:45:40 +0200
Subject: [PATCH 1/8] refactor: FieldSet: only update own select fields, not
 all form select fields

---
 src/app/formulaire/elements/fieldset.ts | 34 ++++++++++++++-----------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/src/app/formulaire/elements/fieldset.ts b/src/app/formulaire/elements/fieldset.ts
index 179920686..2e008e447 100644
--- a/src/app/formulaire/elements/fieldset.ts
+++ b/src/app/formulaire/elements/fieldset.ts
@@ -16,6 +16,7 @@ import { FieldsetContainer } from "./fieldset-container";
 import { SelectFieldFactory } from "./select/select-field-factory";
 import { FormulaireFixedVar } from "../definition/form-fixedvar";
 import { SelectEntry } from "./select/select-entry";
+import { DeepSelectFieldIterator } from "../form-iterator/deep-selectfield-iterator";
 
 export class FieldSet extends FormulaireElement implements IProperties {
 
@@ -223,11 +224,9 @@ export class FieldSet extends FormulaireElement implements IProperties {
 
         // for all select fields known by the form, set selected value
         // from associated property
-        if (this.parentForm instanceof FormulaireFixedVar) {
-            for (const sel of this.parentForm.allSelectFields) {
-                if (sel.hasAssociatedNubProperty) {  // ie. if select is a standard select
-                    this.setSelectValueFromProperty(sel.id);
-                }
+        for (const sel of this.allSelectFields) {
+            if (sel.hasAssociatedNubProperty) {  // ie. if select is a standard select
+                this.setSelectValueFromProperty(sel.id);
             }
         }
     }
@@ -276,16 +275,14 @@ export class FieldSet extends FormulaireElement implements IProperties {
 
         // for all select fields known by the form, apply default value
         // to associated property, usually from associated enum
-        if (this.parentForm instanceof FormulaireFixedVar) {
-            for (const sel of this.parentForm.allSelectFields) {
-                if (sel.hasAssociatedNubProperty) { // ie. if select is a standard select
-                    const prop = sel.associatedProperty;
-                    const defaultValue = sel.configDefaultValue;
-                    // Sets Nub default property, unless this property is already set
-                    const currentValue = this.getPropValue(prop);
-                    if (defaultValue !== undefined && currentValue === undefined) {
-                        this.setPropValue(prop, enumValueFromString(prop, defaultValue));
-                    }
+        for (const sel of this.allSelectFields) {
+            if (sel.hasAssociatedNubProperty) { // ie. if select is a standard select
+                const prop = sel.associatedProperty;
+                const defaultValue = sel.configDefaultValue;
+                // Sets Nub default property, unless this property is already set
+                const currentValue = this.getPropValue(prop);
+                if (defaultValue !== undefined && currentValue === undefined) {
+                    this.setPropValue(prop, enumValueFromString(prop, defaultValue));
                 }
             }
         }
@@ -312,6 +309,13 @@ export class FieldSet extends FormulaireElement implements IProperties {
         }
     }
 
+    /**
+     * itère sur tous les SelectField
+     */
+    public get allSelectFields(): IterableIterator<SelectField> {
+        return new DeepSelectFieldIterator(this);
+    }
+
     // interface Observer
 
     update(sender: any, data: any) {
-- 
GitLab


From 2027509e4f086f4252f7e2fac530c0f664d50183 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Fri, 26 May 2023 15:03:11 +0200
Subject: [PATCH 2/8] refactor: SelectField: remove _entryMap member

---
 .../formulaire/elements/select/select-field.ts   | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/src/app/formulaire/elements/select/select-field.ts b/src/app/formulaire/elements/select/select-field.ts
index b45f59c42..4d6deed38 100644
--- a/src/app/formulaire/elements/select/select-field.ts
+++ b/src/app/formulaire/elements/select/select-field.ts
@@ -36,11 +36,6 @@ export abstract class SelectField extends Field {
      */
     protected _messageWhenEmpty: string;
 
-    /**
-     * map id <-> select entry
-     */
-    protected _entryMap: { [key: string]: SelectEntry } = {};
-
     constructor(parent: FormulaireNode) {
         super(parent);
         this.clearEntries();
@@ -237,14 +232,21 @@ export abstract class SelectField extends Field {
     }
 
     protected createOrGetEntry(id: string, val: any, lbl?: string): SelectEntry {
-        let res: SelectEntry = this._entryMap[id];
+        let res = this.getEntryFromId(id);
         if (res === undefined) {
             res = new SelectEntry(id, val, lbl);
-            this._entryMap[id] = res;
         }
         return res;
     }
 
+    private getEntryFromId(id: string) {
+        for (const se of this._entries) {
+            if (se.id === id)
+                return se;
+        }
+        return undefined;
+    }
+
     public getEntryFromValue(val: any): SelectEntry {
         for (const se of this._entries) {
             if (se.value === val) {
-- 
GitLab


From b34cfe3df0ad8d63c293e75833df3ea43d1a7627 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Tue, 30 May 2023 09:58:23 +0200
Subject: [PATCH 3/8] fix(e2e): failing test, probably due to insufficent
 timing

refs #621
---
 e2e/pab-cloisons-empty-fields.e2e-spec.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/e2e/pab-cloisons-empty-fields.e2e-spec.ts b/e2e/pab-cloisons-empty-fields.e2e-spec.ts
index d1443fb78..548b10d2e 100644
--- a/e2e/pab-cloisons-empty-fields.e2e-spec.ts
+++ b/e2e/pab-cloisons-empty-fields.e2e-spec.ts
@@ -60,12 +60,12 @@ describe("ngHyd - check the cross walls calculator has empty fields - ", () => {
         // calculate
         const calcButton = await calcPage.getCalculateButton();
         await calcButton.click();
-        await browser.pause(200);
+        await browser.pause(1000);
 
         // click "generate PAB" button
         const genButton = await calcPage.getGeneratePabButton();
         await genButton.click();
-        await browser.pause(2000);
+        await browser.pause(3000);
 
         await calcPage.checkEmptyOrFilledFields(["generatePabNbBassins"], [true]);
     });
-- 
GitLab


From fdcad5cc72232ea23c12faa46d7e1b32941cf0f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Tue, 30 May 2023 10:01:00 +0200
Subject: [PATCH 4/8] refactor: calculators definition files: replace numeric
 values by enum symbolic values

refs #621
---
 DEVELOPERS.md                                 | 12 +++---
 src/app/calculators/bief/config.json          |  8 ++--
 src/app/calculators/bief/en.json              | 12 +++---
 src/app/calculators/bief/fr.json              | 12 +++---
 src/app/calculators/courberemous/config.json  | 16 +++----
 src/app/calculators/courberemous/en.json      | 14 +++---
 src/app/calculators/courberemous/fr.json      | 14 +++---
 src/app/calculators/espece/en.json            |  4 +-
 src/app/calculators/espece/fr.json            |  4 +-
 src/app/calculators/grille/config.json        |  6 +--
 src/app/calculators/grille/en.json            | 12 +++---
 src/app/calculators/grille/fr.json            | 12 +++---
 src/app/calculators/macrorugocompound/en.json |  4 +-
 src/app/calculators/macrorugocompound/fr.json |  4 +-
 src/app/calculators/par/config.json           |  8 ++--
 src/app/calculators/par/en.json               |  8 ++--
 src/app/calculators/par/fr.json               |  8 ++--
 src/app/calculators/parsimulation/config.json |  8 ++--
 src/app/calculators/parsimulation/en.json     |  8 ++--
 src/app/calculators/parsimulation/fr.json     |  8 ++--
 src/app/calculators/pressureloss/config.json  |  4 +-
 src/app/calculators/pressureloss/en.json      | 22 +++++-----
 src/app/calculators/pressureloss/fr.json      | 22 +++++-----
 .../calculators/regimeuniforme/config.json    |  8 ++--
 src/app/calculators/regimeuniforme/en.json    |  8 ++--
 src/app/calculators/regimeuniforme/fr.json    |  8 ++--
 .../calculators/sectionparametree/config.json |  8 ++--
 src/app/calculators/sectionparametree/en.json |  8 ++--
 src/app/calculators/sectionparametree/fr.json |  8 ++--
 src/app/calculators/spp/en.json               |  4 +-
 src/app/calculators/spp/fr.json               |  4 +-
 src/app/calculators/trigo/en.json             | 16 +++----
 src/app/calculators/trigo/fr.json             | 16 +++----
 .../select-field-line.component.ts            | 12 ++----
 .../elements/select/select-field-nub-prop.ts  |  5 ++-
 .../elements/select/select-field.ts           | 43 +++++++++++++++++--
 36 files changed, 208 insertions(+), 170 deletions(-)

diff --git a/DEVELOPERS.md b/DEVELOPERS.md
index 6be017691..066253e54 100644
--- a/DEVELOPERS.md
+++ b/DEVELOPERS.md
@@ -278,7 +278,7 @@ En général les valeurs autorisées sont tirées de l'**enum** correspondant, d
 
 #### configuration
 
-Dans le fichier de configuration du module, ajouter la définition des listes déroulantes dans "fields", notamment la propriété associée et la valeur par défaut; cette dernière est optionnelle et en son absence, la 1ère valeur de la liste sera sélectionnée.
+Dans le fichier de configuration du module, ajouter la définition des listes déroulantes dans "fields", notamment la propriété associée et la valeur par défaut; cette dernière est optionnelle et en son absence, la 1ère valeur de la liste sera sélectionnée. Si la propriété associée est d'un type énuméré, la valeur par défaut est une des valeurs de l'enum.
 
 Exemple dans `trigo/config.json` (ici le 2ème champ ne spécifie pas de valeur par défaut) :
 
@@ -301,6 +301,7 @@ Exemple dans `trigo/config.json` (ici le 2ème champ ne spécifie pas de valeur
     ]
 },
 ```
+Dans cet exemple, la propriété `trigoOperation` est du type énuméré TrigoOperation (cf. code).
 
 **IMPORTANT** : les ids doivent être de la forme `select_`_`unmotclesansespacenitirets`_
 
@@ -415,13 +416,14 @@ Dans la configuration du module, ajouter un sélecteur de section associé à la
     "type": "select",
     "property": "nodeType",
     "help": {
-        "1": "hsl/types_sections.html#section-rectangulaire",
-        "0": "hsl/types_sections.html#section-circulaire",
-        "2": "hsl/types_sections.html#section-trapezoidale",
-        "3": "hsl/types_sections.html#section-parabolique"
+        "SectionRectangle": "hsl/types_sections.html#section-rectangulaire",
+        "SectionCercle": "hsl/types_sections.html#section-circulaire",
+        "SectionTrapeze": "hsl/types_sections.html#section-trapezoidale",
+        "SectionPuissance": "hsl/types_sections.html#section-parabolique"
     }
 }
 ```
+Les clés de la section `help` reprennent les valeurs de l'enum `SectionType`.
 La section par défaut du formulaire sera celle du sélecteur, que celle ci soit ou non configurée explicitement par le champ `default`.
 
 ### si le module agrège des modules enfants
diff --git a/src/app/calculators/bief/config.json b/src/app/calculators/bief/config.json
index 4c486031c..f6296a2ed 100644
--- a/src/app/calculators/bief/config.json
+++ b/src/app/calculators/bief/config.json
@@ -21,10 +21,10 @@
                 "property": "nodeType",
                 "default": "SectionRectangle",
                 "help": {
-                    "1": "hsl/types_sections.html#section-rectangulaire",
-                    "0": "hsl/types_sections.html#section-circulaire",
-                    "2": "hsl/types_sections.html#section-trapezoidale",
-                    "3": "hsl/types_sections.html#section-parabolique"
+                    "SectionRectangle": "hsl/types_sections.html#section-rectangulaire",
+                    "SectionCercle": "hsl/types_sections.html#section-circulaire",
+                    "SectionTrapeze": "hsl/types_sections.html#section-trapezoidale",
+                    "SectionPuissance": "hsl/types_sections.html#section-parabolique"
                 }
             },
             "LargeurFond",
diff --git a/src/app/calculators/bief/en.json b/src/app/calculators/bief/en.json
index 83ef6c03f..705a69b9b 100644
--- a/src/app/calculators/bief/en.json
+++ b/src/app/calculators/bief/en.json
@@ -2,16 +2,16 @@
     "fs_water_line": "Type of water line",
     "select_regime": "Regime",
 
-    "REGIME_0": "Fluvial",
-    "REGIME_1": "Torrential",
+    "REGIME_Fluvial": "Fluvial",
+    "REGIME_Torrentiel": "Torrential",
 
     "fs_section": "Type of section",
     "select_section": "Choice of section type",
 
-    "SECTION_2": "Trapezoidal",
-    "SECTION_1": "Rectangular",
-    "SECTION_0": "Circular",
-    "SECTION_3": "Parabolic",
+    "SECTION_SectionTrapeze": "Trapezoidal",
+    "SECTION_SectionRectangle": "Rectangular",
+    "SECTION_SectionCercle": "Circular",
+    "SECTION_SectionPuissance": "Parabolic",
 
     "LargeurFond": "Width at bottom",
     "Fruit": "Bank slope",
diff --git a/src/app/calculators/bief/fr.json b/src/app/calculators/bief/fr.json
index e2389fae1..cd9db18b3 100644
--- a/src/app/calculators/bief/fr.json
+++ b/src/app/calculators/bief/fr.json
@@ -2,16 +2,16 @@
     "fs_water_line": "Type de ligne d'eau",
     "select_regime": "Régime",
 
-    "REGIME_0": "Fluvial",
-    "REGIME_1": "Torrentiel",
+    "REGIME_Fluvial": "Fluvial",
+    "REGIME_Torrentiel": "Torrentiel",
 
     "fs_section": "Type de section",
     "select_section": "Choix du type de section",
 
-    "SECTION_2": "Trapézoïdale",
-    "SECTION_1": "Rectangulaire",
-    "SECTION_0": "Circulaire",
-    "SECTION_3": "Parabolique",
+    "SECTION_SectionTrapeze": "Trapézoïdale",
+    "SECTION_SectionRectangle": "Rectangulaire",
+    "SECTION_SectionCercle": "Circulaire",
+    "SECTION_SectionPuissance": "Parabolique",
 
     "LargeurFond": "Largeur au fond",
     "Fruit": "Fruit des berges",
diff --git a/src/app/calculators/courberemous/config.json b/src/app/calculators/courberemous/config.json
index 14ee8981c..b4d38751b 100644
--- a/src/app/calculators/courberemous/config.json
+++ b/src/app/calculators/courberemous/config.json
@@ -9,10 +9,10 @@
                 "property": "nodeType",
                 "default": "SectionRectangle",
                 "help": {
-                    "1": "hsl/types_sections.html#section-rectangulaire",
-                    "0": "hsl/types_sections.html#section-circulaire",
-                    "2": "hsl/types_sections.html#section-trapezoidale",
-                    "3": "hsl/types_sections.html#section-parabolique"
+                    "SectionRectangle": "hsl/types_sections.html#section-rectangulaire",
+                    "SectionCercle": "hsl/types_sections.html#section-circulaire",
+                    "SectionTrapeze": "hsl/types_sections.html#section-trapezoidale",
+                    "SectionPuissance": "hsl/types_sections.html#section-parabolique"
                 }
             },
             "LargeurFond",
@@ -65,9 +65,9 @@
                 "property": "methodeResolution",
                 "default": "Trapezes",
                 "help": {
-                    "0": "../methodes_numeriques/integration_trapezes.html",
-                    "1": "../methodes_numeriques/rk4.html",
-                    "2": "../methodes_numeriques/euler_explicite.html"
+                    "Trapezes": "../methodes_numeriques/integration_trapezes.html",
+                    "RungeKutta4": "../methodes_numeriques/rk4.html",
+                    "EulerExplicite": "../methodes_numeriques/euler_explicite.html"
                 }
             }
         ]
@@ -122,4 +122,4 @@
             "Tau0": "hsl/section_parametree.html#la-force-tractrice-pa"
         }
     }
-]
\ No newline at end of file
+]
diff --git a/src/app/calculators/courberemous/en.json b/src/app/calculators/courberemous/en.json
index 8e4ac96ad..c6095e573 100644
--- a/src/app/calculators/courberemous/en.json
+++ b/src/app/calculators/courberemous/en.json
@@ -2,10 +2,10 @@
     "fs_section": "Type of section",
     "select_section": "Choice of section type",
 
-    "SECTION_2": "Trapezoidal",
-    "SECTION_1": "Rectangular",
-    "SECTION_0": "Circular",
-    "SECTION_3": "Parabolic",
+    "SECTION_SectionTrapeze": "Trapezoidal",
+    "SECTION_SectionRectangle": "Rectangular",
+    "SECTION_SectionCercle": "Circular",
+    "SECTION_SectionPuissance": "Parabolic",
 
     "LargeurFond": "Width at bottom",
     "Fruit": "Bank slope",
@@ -44,9 +44,9 @@
     "UNIT_IMP": "N",
     "UNIT_TAU0": "Pa",
 
-    "RESOLUTION_0": "Integration by trapezoid",
-    "RESOLUTION_1": "Runge Kutta fourth order",
-    "RESOLUTION_2": "Explicit Euler",
+    "RESOLUTION_Trapezes": "Integration by trapezoid",
+    "RESOLUTION_RungeKutta4": "Runge Kutta fourth order",
+    "RESOLUTION_EulerExplicite": "Explicit Euler",
 
     "fs_target_data": "Data to compute",
     "select_target": "Choice of the data to compute",
diff --git a/src/app/calculators/courberemous/fr.json b/src/app/calculators/courberemous/fr.json
index 278c16ad4..e4c5140dd 100644
--- a/src/app/calculators/courberemous/fr.json
+++ b/src/app/calculators/courberemous/fr.json
@@ -2,10 +2,10 @@
     "fs_section": "Type de section",
     "select_section": "Choix du type de section",
 
-    "SECTION_2": "Trapézoïdale",
-    "SECTION_1": "Rectangulaire",
-    "SECTION_0": "Circulaire",
-    "SECTION_3": "Parabolique",
+    "SECTION_SectionTrapeze": "Trapézoïdale",
+    "SECTION_SectionRectangle": "Rectangulaire",
+    "SECTION_SectionCercle": "Circulaire",
+    "SECTION_SectionPuissance": "Parabolique",
 
     "LargeurFond": "Largeur au fond",
     "Fruit": "Fruit des berges",
@@ -44,9 +44,9 @@
     "UNIT_IMP": "N",
     "UNIT_TAU0": "Pa",
 
-    "RESOLUTION_0": "Intégration par trapèzes",
-    "RESOLUTION_1": "Runge Kutta d'ordre 4",
-    "RESOLUTION_2": "Euler explicite",
+    "RESOLUTION_Trapezes": "Intégration par trapèzes",
+    "RESOLUTION_RungeKutta4": "Runge Kutta d'ordre 4",
+    "RESOLUTION_EulerExplicite": "Euler explicite",
 
     "fs_target_data": "Donnée à calculer",
     "select_target": "Choix de la donnée à calculer",
diff --git a/src/app/calculators/espece/en.json b/src/app/calculators/espece/en.json
index f88069bf4..6d8117134 100644
--- a/src/app/calculators/espece/en.json
+++ b/src/app/calculators/espece/en.json
@@ -7,6 +7,6 @@
 
     "select_divingjetsupported": "Diving jets support",
 
-    "DIVINGJETSUPPORTED_0": "Not supported",
-    "DIVINGJETSUPPORTED_1": "Supported"
+    "DIVINGJETSUPPORTED_NOT_SUPPORTED": "Not supported",
+    "DIVINGJETSUPPORTED_SUPPORTED": "Supported"
 }
diff --git a/src/app/calculators/espece/fr.json b/src/app/calculators/espece/fr.json
index 98bfd5344..143ecfc31 100644
--- a/src/app/calculators/espece/fr.json
+++ b/src/app/calculators/espece/fr.json
@@ -7,6 +7,6 @@
 
     "select_divingjetsupported": "Support des jets plongeants",
 
-    "DIVINGJETSUPPORTED_0": "Non supportés",
-    "DIVINGJETSUPPORTED_1": "Supportés"
+    "DIVINGJETSUPPORTED_NOT_SUPPORTED": "Non supportés",
+    "DIVINGJETSUPPORTED_SUPPORTED": "Supportés"
 }
diff --git a/src/app/calculators/grille/config.json b/src/app/calculators/grille/config.json
index b01502d19..4a237d19d 100644
--- a/src/app/calculators/grille/config.json
+++ b/src/app/calculators/grille/config.json
@@ -24,9 +24,9 @@
                 "property": "gridType",
                 "default": "Conventional",
                 "help": {
-                    "0": "devalaison/grille.html#grille-conventionnelle",
-                    "1": "devalaison/grille.html#grille-orientee",
-                    "2": "devalaison/grille.html#grille-inclinee"
+                    "Conventional": "devalaison/grille.html#grille-conventionnelle",
+                    "Oriented": "devalaison/grille.html#grille-orientee",
+                    "Inclined": "devalaison/grille.html#grille-inclinee"
                 }
             },
             {
diff --git a/src/app/calculators/grille/en.json b/src/app/calculators/grille/en.json
index 2ce401b7f..00b42e11f 100644
--- a/src/app/calculators/grille/en.json
+++ b/src/app/calculators/grille/en.json
@@ -23,13 +23,13 @@
     "select_gridtype": "Grid type",
     "select_gridprofile": "Bars profile",
 
-    "GRIDTYPE_0": "Conventional",
-    "GRIDTYPE_1": "Oriented",
-    "GRIDTYPE_2": "Inclined",
+    "GRIDTYPE_Conventional": "Conventional",
+    "GRIDTYPE_Oriented": "Oriented",
+    "GRIDTYPE_Inclined": "Inclined",
 
-    "GRIDPROFILE_0": "Rectangular",
-    "GRIDPROFILE_1": "Hydrodynamic",
-    "GRIDPROFILE_2": "Custom",
+    "GRIDPROFILE_Rectangular": "Rectangular",
+    "GRIDPROFILE_Hydrodynamic": "Hydrodynamic",
+    "GRIDPROFILE_Custom": "Custom",
 
     "H": "Water height",
     "HG": "Grid  height",
diff --git a/src/app/calculators/grille/fr.json b/src/app/calculators/grille/fr.json
index 3b15b018f..5b118c5ca 100644
--- a/src/app/calculators/grille/fr.json
+++ b/src/app/calculators/grille/fr.json
@@ -23,13 +23,13 @@
     "select_gridtype": "Type de grille",
     "select_gridprofile": "Profil des barreaux",
 
-    "GRIDTYPE_0": "Conventionnelle",
-    "GRIDTYPE_1": "Orientée",
-    "GRIDTYPE_2": "Inclinée",
+    "GRIDTYPE_Conventional": "Conventionnelle",
+    "GRIDTYPE_Oriented": "Orientée",
+    "GRIDTYPE_Inclined": "Inclinée",
 
-    "GRIDPROFILE_0": "Rectangulaire",
-    "GRIDPROFILE_1": "Hydrodynamique",
-    "GRIDPROFILE_2": "Personnalisé",
+    "GRIDPROFILE_Rectangular": "Rectangulaire",
+    "GRIDPROFILE_Hydrodynamic": "Hydrodynamique",
+    "GRIDPROFILE_Custom": "Personnalisé",
 
     "H": "Hauteur d'eau",
     "HG": "Hauteur de grille",
diff --git a/src/app/calculators/macrorugocompound/en.json b/src/app/calculators/macrorugocompound/en.json
index 502bbb580..3336bce68 100644
--- a/src/app/calculators/macrorugocompound/en.json
+++ b/src/app/calculators/macrorugocompound/en.json
@@ -21,6 +21,6 @@
     "Y": "Water depth",
     "xCenter": "Mid-apron abscissa",
 
-    "PASSTYPE_0": "Multiple aprons",
-    "PASSTYPE_1": "Inclined apron"
+    "PASSTYPE_NOT_INCLINED": "Multiple aprons",
+    "PASSTYPE_INCLINED": "Inclined apron"
 }
\ No newline at end of file
diff --git a/src/app/calculators/macrorugocompound/fr.json b/src/app/calculators/macrorugocompound/fr.json
index 08b69103f..b5c3d4ce6 100644
--- a/src/app/calculators/macrorugocompound/fr.json
+++ b/src/app/calculators/macrorugocompound/fr.json
@@ -21,6 +21,6 @@
     "Y": "Profondeur",
     "xCenter": "Abscisse du milieu du radier",
 
-    "PASSTYPE_0": "Radiers multiples",
-    "PASSTYPE_1": "Radier incliné"
+    "PASSTYPE_NOT_INCLINED": "Radiers multiples",
+    "PASSTYPE_INCLINED": "Radier incliné"
 }
\ No newline at end of file
diff --git a/src/app/calculators/par/config.json b/src/app/calculators/par/config.json
index 00b267c59..513c517ee 100644
--- a/src/app/calculators/par/config.json
+++ b/src/app/calculators/par/config.json
@@ -24,10 +24,10 @@
                 "property": "parType",
                 "default": "PLANE",
                 "help": {
-                    "0": "par/theorie_plans.html",
-                    "1": "par/theorie_fatou.html",
-                    "2": "par/theorie_suractif.html",
-                    "3": "par/theorie_mixte.html"
+                    "PLANE": "par/theorie_plans.html",
+                    "FATOU": "par/theorie_fatou.html",
+                    "SUPERACTIVE": "par/theorie_suractif.html",
+                    "CHEVRON": "par/theorie_mixte.html"
                 }
             },
             "ha",
diff --git a/src/app/calculators/par/en.json b/src/app/calculators/par/en.json
index a1271a1a1..95473e87a 100644
--- a/src/app/calculators/par/en.json
+++ b/src/app/calculators/par/en.json
@@ -31,8 +31,8 @@
     "Hmax": "Maximal baffle height",
 
     "select_partype": "Pass type",
-    "PARTYPE_0": "Plane baffles",
-    "PARTYPE_1": "Fatou",
-    "PARTYPE_2": "Superactive",
-    "PARTYPE_3": "Mixed / chevrons"
+    "PARTYPE_PLANE": "Plane baffles",
+    "PARTYPE_FATOU": "Fatou",
+    "PARTYPE_SUPERACTIVE": "Superactive",
+    "PARTYPE_CHEVRON": "Mixed / chevrons"
 }
\ No newline at end of file
diff --git a/src/app/calculators/par/fr.json b/src/app/calculators/par/fr.json
index 4d38734ca..531e762cb 100644
--- a/src/app/calculators/par/fr.json
+++ b/src/app/calculators/par/fr.json
@@ -31,8 +31,8 @@
     "Hmax": "Hauteur maximale du ralentisseur",
 
     "select_partype": "Type de passe",
-    "PARTYPE_0": "Ralentisseurs plans",
-    "PARTYPE_1": "Fatou",
-    "PARTYPE_2": "Ralentisseurs suractifs",
-    "PARTYPE_3": "Mixte / chevrons"
+    "PARTYPE_PLANE": "Ralentisseurs plans",
+    "PARTYPE_FATOU": "Fatou",
+    "PARTYPE_SUPERACTIVE": "Ralentisseurs suractifs",
+    "PARTYPE_CHEVRON": "Mixte / chevrons"
 }
\ No newline at end of file
diff --git a/src/app/calculators/parsimulation/config.json b/src/app/calculators/parsimulation/config.json
index 64b58bfc5..6b302e7e5 100644
--- a/src/app/calculators/parsimulation/config.json
+++ b/src/app/calculators/parsimulation/config.json
@@ -21,10 +21,10 @@
                 "property": "parType",
                 "default": "PLANE",
                 "help": {
-                    "0": "par/theorie_plans.html",
-                    "1": "par/theorie_fatou.html",
-                    "2": "par/theorie_suractif.html",
-                    "3": "par/theorie_mixte.html"
+                    "PLANE": "par/theorie_plans.html",
+                    "FATOU": "par/theorie_fatou.html",
+                    "SUPERACTIVE": "par/theorie_suractif.html",
+                    "CHEVRON": "par/theorie_mixte.html"
                 }
             },
             "L",
diff --git a/src/app/calculators/parsimulation/en.json b/src/app/calculators/parsimulation/en.json
index f6812ebc5..056b90bf9 100644
--- a/src/app/calculators/parsimulation/en.json
+++ b/src/app/calculators/parsimulation/en.json
@@ -31,8 +31,8 @@
     "Hmax": "Maximal baffle height",
 
     "select_partype": "Pass type",
-    "PARTYPE_0": "Plane baffles",
-    "PARTYPE_1": "Fatou",
-    "PARTYPE_2": "Superactive",
-    "PARTYPE_3": "Mixed / chevrons"
+    "PARTYPE_PLANE": "Plane baffles",
+    "PARTYPE_FATOU": "Fatou",
+    "PARTYPE_SUPERACTIVE": "Superactive",
+    "PARTYPE_CHEVRON": "Mixed / chevrons"
 }
diff --git a/src/app/calculators/parsimulation/fr.json b/src/app/calculators/parsimulation/fr.json
index 59cdeef4f..835ac0f1e 100644
--- a/src/app/calculators/parsimulation/fr.json
+++ b/src/app/calculators/parsimulation/fr.json
@@ -31,8 +31,8 @@
     "Hmax": "Hauteur maximale du ralentisseur",
 
     "select_partype": "Type de passe",
-    "PARTYPE_0": "Ralentisseurs plans",
-    "PARTYPE_1": "Fatou",
-    "PARTYPE_2": "Ralentisseurs suractifs",
-    "PARTYPE_3": "Mixte / chevrons"
+    "PARTYPE_PLANE": "Ralentisseurs plans",
+    "PARTYPE_FATOU": "Fatou",
+    "PARTYPE_SUPERACTIVE": "Ralentisseurs suractifs",
+    "PARTYPE_CHEVRON": "Mixte / chevrons"
 }
diff --git a/src/app/calculators/pressureloss/config.json b/src/app/calculators/pressureloss/config.json
index c4bbbd561..c70981164 100644
--- a/src/app/calculators/pressureloss/config.json
+++ b/src/app/calculators/pressureloss/config.json
@@ -9,8 +9,8 @@
                 "property": "pressureLossType",
                 "default": "LechaptCalmon",
                 "help": {
-                    "0": "hyd_en_charge/lechapt-calmon.html",
-                    "1": "hyd_en_charge/strickler.html"
+                    "LechaptCalmon": "hyd_en_charge/lechapt-calmon.html",
+                    "Strickler": "hyd_en_charge/strickler.html"
                 }
             },
             {
diff --git a/src/app/calculators/pressureloss/en.json b/src/app/calculators/pressureloss/en.json
index 238ce4911..559864d0a 100644
--- a/src/app/calculators/pressureloss/en.json
+++ b/src/app/calculators/pressureloss/en.json
@@ -1,20 +1,20 @@
 {
     "fs_pressureloss_law": "Pressure loss",
     "select_pressurelosstype": "Pressure loss law",
-    "PRESSURELOSSTYPE_0": "Lechapt-Calmon",
-    "PRESSURELOSSTYPE_1": "Strickler",
+    "PRESSURELOSSTYPE_LechaptCalmon": "Lechapt-Calmon",
+    "PRESSURELOSSTYPE_Strickler": "Strickler",
 
     "fs_materiau": "Type of material",
     "select_material": "Choice of material",
-    "MATERIAL_0": "Unlined cast iron - Coarse concrete (corrosive water)",
-    "MATERIAL_1": "Cast steel or uncoated - Coarse concrete (somewhat corrosive water)",
-    "MATERIAL_2": "Cast steel or cement coating",
-    "MATERIAL_3": "Cast iron or steel coating bitumen - Centrifuged concrete ",
-    "MATERIAL_4": "Rolled steel - Smooth concrete",
-    "MATERIAL_5": "Cast iron or steel coating centrifuged",
-    "MATERIAL_6": "PVC - Polyethylene",
-    "MATERIAL_7": "Hydraulically smooth pipe - 0.05 ≤ D ≤ 0.2",
-    "MATERIAL_8": "Hydraulically smooth pipe - 0.25 ≤ D ≤ 1",
+    "MATERIAL_UnlinedCastIronCoarseConcrete": "Unlined cast iron - Coarse concrete (corrosive water)",
+    "MATERIAL_CastSteelOrUncoatedCoarseConcrete": "Cast steel or uncoated - Coarse concrete (somewhat corrosive water)",
+    "MATERIAL_CastSteelOrCementCoating": "Cast steel or cement coating",
+    "MATERIAL_CastIronOrSteelCoatingBitumen": "Cast iron or steel coating bitumen - Centrifuged concrete ",
+    "MATERIAL_RolledSteelSmoothConcrete": "Rolled steel - Smooth concrete",
+    "MATERIAL_CastIronOrSteelCoatingCentrifuged": "Cast iron or steel coating centrifuged",
+    "MATERIAL_PVCPolyethylene": "PVC - Polyethylene",
+    "MATERIAL_HydraulicallySmoothPipe005D02": "Hydraulically smooth pipe - 0.05 ≤ D ≤ 0.2",
+    "MATERIAL_HydraulicallySmoothPipe025D1": "Hydraulically smooth pipe - 0.25 ≤ D ≤ 1",
     "L": "L",
     "M": "M",
     "N": "N",
diff --git a/src/app/calculators/pressureloss/fr.json b/src/app/calculators/pressureloss/fr.json
index fd1bd9c2f..7dacfc3d5 100644
--- a/src/app/calculators/pressureloss/fr.json
+++ b/src/app/calculators/pressureloss/fr.json
@@ -1,20 +1,20 @@
 {
     "fs_pressureloss_law": "Perte de charge",
     "select_pressurelosstype": "Loi de perte de charge",
-    "PRESSURELOSSTYPE_0": "Lechapt-Calmon",
-    "PRESSURELOSSTYPE_1": "Strickler",
+    "PRESSURELOSSTYPE_LechaptCalmon": "Lechapt-Calmon",
+    "PRESSURELOSSTYPE_Strickler": "Strickler",
 
     "fs_materiau": "Type du matériau",
     "select_material": "Choix du matériau",
-    "MATERIAL_0": "Fonte ou acier non revêtus - Béton grossier (eau corrosive)",
-    "MATERIAL_1": "Fonte ou acier non revêtus - Béton grossier (eau peu corrosive)",
-    "MATERIAL_2": "Fonte ou acier revêtement ciment",
-    "MATERIAL_3": "Fonte ou acier revêtement bitume - Béton centrifugé",
-    "MATERIAL_4": "Acier laminé - Béton lisse",
-    "MATERIAL_5": "Fonte ou acier revêtement centrifugé",
-    "MATERIAL_6": "PVC - Polyéthylène",
-    "MATERIAL_7": "Tuyau hydrauliquement lisse - 0.05 ≤ D ≤ 0.2",
-    "MATERIAL_8": "Tuyau hydrauliquement lisse - 0.25 ≤ D ≤ 1",
+    "MATERIAL_UnlinedCastIronCoarseConcrete": "Fonte ou acier non revêtus - Béton grossier (eau corrosive)",
+    "MATERIAL_CastSteelOrUncoatedCoarseConcrete": "Fonte ou acier non revêtus - Béton grossier (eau peu corrosive)",
+    "MATERIAL_CastSteelOrCementCoating": "Fonte ou acier revêtement ciment",
+    "MATERIAL_CastIronOrSteelCoatingBitumen": "Fonte ou acier revêtement bitume - Béton centrifugé",
+    "MATERIAL_RolledSteelSmoothConcrete": "Acier laminé - Béton lisse",
+    "MATERIAL_CastIronOrSteelCoatingCentrifuged": "Fonte ou acier revêtement centrifugé",
+    "MATERIAL_PVCPolyethylene": "PVC - Polyéthylène",
+    "MATERIAL_HydraulicallySmoothPipe005D02": "Tuyau hydrauliquement lisse - 0.05 ≤ D ≤ 0.2",
+    "MATERIAL_HydraulicallySmoothPipe025D1": "Tuyau hydrauliquement lisse - 0.25 ≤ D ≤ 1",
     "L": "L",
     "M": "M",
     "N": "N",
diff --git a/src/app/calculators/regimeuniforme/config.json b/src/app/calculators/regimeuniforme/config.json
index c51679f69..24bcb81ad 100644
--- a/src/app/calculators/regimeuniforme/config.json
+++ b/src/app/calculators/regimeuniforme/config.json
@@ -9,10 +9,10 @@
                 "property": "nodeType",
                 "default": "SectionRectangle",
                 "help": {
-                    "1": "hsl/types_sections.html#section-rectangulaire",
-                    "0": "hsl/types_sections.html#section-circulaire",
-                    "2": "hsl/types_sections.html#section-trapezoidale",
-                    "3": "hsl/types_sections.html#section-parabolique"
+                    "SectionRectangle": "hsl/types_sections.html#section-rectangulaire",
+                    "SectionCercle": "hsl/types_sections.html#section-circulaire",
+                    "SectionTrapeze": "hsl/types_sections.html#section-trapezoidale",
+                    "SectionPuissance": "hsl/types_sections.html#section-parabolique"
                 }
             },
             "LargeurFond",
diff --git a/src/app/calculators/regimeuniforme/en.json b/src/app/calculators/regimeuniforme/en.json
index f1ea50fcc..c8f402974 100644
--- a/src/app/calculators/regimeuniforme/en.json
+++ b/src/app/calculators/regimeuniforme/en.json
@@ -2,10 +2,10 @@
     "fs_section": "Type of section",
     "select_section": "Choice of section type",
 
-    "SECTION_2": "Trapezoidal",
-    "SECTION_1": "Rectangular",
-    "SECTION_0": "Circular",
-    "SECTION_3": "Parabolic",
+    "SECTION_SectionTrapeze": "Trapezoidal",
+    "SECTION_SectionRectangle": "Rectangular",
+    "SECTION_SectionCercle": "Circular",
+    "SECTION_SectionPuissance": "Parabolic",
 
     "LargeurFond": "Width at bottom",
     "Fruit": "Bank slope",
diff --git a/src/app/calculators/regimeuniforme/fr.json b/src/app/calculators/regimeuniforme/fr.json
index 1363f6303..012efb53a 100644
--- a/src/app/calculators/regimeuniforme/fr.json
+++ b/src/app/calculators/regimeuniforme/fr.json
@@ -2,10 +2,10 @@
     "fs_section": "Type de section",
     "select_section": "Choix du type de section",
 
-    "SECTION_2": "Trapézoïdale",
-    "SECTION_1": "Rectangulaire",
-    "SECTION_0": "Circulaire",
-    "SECTION_3": "Parabolique",
+    "SECTION_SectionTrapeze": "Trapézoïdale",
+    "SECTION_SectionRectangle": "Rectangulaire",
+    "SECTION_SectionCercle": "Circulaire",
+    "SECTION_SectionPuissance": "Parabolique",
 
     "LargeurFond": "Largeur au fond",
     "Fruit": "Fruit des berges",
diff --git a/src/app/calculators/sectionparametree/config.json b/src/app/calculators/sectionparametree/config.json
index a54bed3df..c7fab63ee 100644
--- a/src/app/calculators/sectionparametree/config.json
+++ b/src/app/calculators/sectionparametree/config.json
@@ -9,10 +9,10 @@
                 "property": "nodeType",
                 "default": "SectionRectangle",
                 "help": {
-                    "1": "hsl/types_sections.html#section-rectangulaire",
-                    "0": "hsl/types_sections.html#section-circulaire",
-                    "2": "hsl/types_sections.html#section-trapezoidale",
-                    "3": "hsl/types_sections.html#section-parabolique"
+                    "SectionRectangle": "hsl/types_sections.html#section-rectangulaire",
+                    "SectionCercle": "hsl/types_sections.html#section-circulaire",
+                    "SectionTrapeze": "hsl/types_sections.html#section-trapezoidale",
+                    "SectionPuissance": "hsl/types_sections.html#section-parabolique"
                 }
             },
             "LargeurBerge",
diff --git a/src/app/calculators/sectionparametree/en.json b/src/app/calculators/sectionparametree/en.json
index b13efd538..78b03c486 100644
--- a/src/app/calculators/sectionparametree/en.json
+++ b/src/app/calculators/sectionparametree/en.json
@@ -2,10 +2,10 @@
     "fs_section": "Type of section",
     "select_section": "Choice of section type",
 
-    "SECTION_2": "Trapezoidal",
-    "SECTION_1": "Rectangular",
-    "SECTION_0": "Circular",
-    "SECTION_3": "Parabolic",
+    "SECTION_SectionTrapeze": "Trapezoidal",
+    "SECTION_SectionRectangle": "Rectangular",
+    "SECTION_SectionCercle": "Circular",
+    "SECTION_SectionPuissance": "Parabolic",
 
     "LargeurFond": "Width at bottom",
     "Fruit": "Bank slope",
diff --git a/src/app/calculators/sectionparametree/fr.json b/src/app/calculators/sectionparametree/fr.json
index 769792403..0640146b2 100644
--- a/src/app/calculators/sectionparametree/fr.json
+++ b/src/app/calculators/sectionparametree/fr.json
@@ -2,10 +2,10 @@
     "fs_section": "Type de section",
     "select_section": "Choix du type de section",
 
-    "SECTION_2": "Trapézoïdale",
-    "SECTION_1": "Rectangulaire",
-    "SECTION_0": "Circulaire",
-    "SECTION_3": "Parabolique",
+    "SECTION_SectionTrapeze": "Trapézoïdale",
+    "SECTION_SectionRectangle": "Rectangulaire",
+    "SECTION_SectionCercle": "Circulaire",
+    "SECTION_SectionPuissance": "Parabolique",
 
     "LargeurFond": "Largeur au fond",
     "Fruit": "Fruit des berges",
diff --git a/src/app/calculators/spp/en.json b/src/app/calculators/spp/en.json
index faa569be4..9dfa115e4 100644
--- a/src/app/calculators/spp/en.json
+++ b/src/app/calculators/spp/en.json
@@ -2,8 +2,8 @@
     "fs_spp": "Parameters",
 
     "select_sppoperation": "Operation",
-    "SPPOPERATION_0": "Sum",
-    "SPPOPERATION_1": "Product",
+    "SPPOPERATION_SUM": "Sum",
+    "SPPOPERATION_PRODUCT": "Product",
 
     "Y": "Y",
 
diff --git a/src/app/calculators/spp/fr.json b/src/app/calculators/spp/fr.json
index f4de7fb40..50fca2e6a 100644
--- a/src/app/calculators/spp/fr.json
+++ b/src/app/calculators/spp/fr.json
@@ -2,8 +2,8 @@
     "fs_spp": "Paramètres",
 
     "select_sppoperation": "Opération",
-    "SPPOPERATION_0": "Somme",
-    "SPPOPERATION_1": "Produit",
+    "SPPOPERATION_SUM": "Somme",
+    "SPPOPERATION_PRODUCT": "Produit",
 
     "Y": "Y",
 
diff --git a/src/app/calculators/trigo/en.json b/src/app/calculators/trigo/en.json
index 90e4f849e..248506c18 100644
--- a/src/app/calculators/trigo/en.json
+++ b/src/app/calculators/trigo/en.json
@@ -2,16 +2,16 @@
     "fs_trigo": "Trigonometric parameters",
 
     "select_operation": "Operation",
-    "OPERATION_0": "cos",
-    "OPERATION_1": "sin",
-    "OPERATION_2": "tan",
-    "OPERATION_3": "cosh",
-    "OPERATION_4": "sinh",
-    "OPERATION_5": "tanh",
+    "OPERATION_COS": "cos",
+    "OPERATION_SIN": "sin",
+    "OPERATION_TAN": "tan",
+    "OPERATION_COSH": "cosh",
+    "OPERATION_SINH": "sinh",
+    "OPERATION_TANH": "tanh",
 
     "select_unit": "Unit",
-    "UNIT_0": "Degrees",
-    "UNIT_1": "Radians",
+    "UNIT_DEG": "Degrees",
+    "UNIT_RAD": "Radians",
 
     "fs_params": "Equation parameters",
 
diff --git a/src/app/calculators/trigo/fr.json b/src/app/calculators/trigo/fr.json
index 2135546ca..b52adc748 100644
--- a/src/app/calculators/trigo/fr.json
+++ b/src/app/calculators/trigo/fr.json
@@ -2,16 +2,16 @@
     "fs_trigo": "Paramètres trigonométriques",
 
     "select_operation": "Opération",
-    "OPERATION_0": "cos",
-    "OPERATION_1": "sin",
-    "OPERATION_2": "tan",
-    "OPERATION_3": "cosh",
-    "OPERATION_4": "sinh",
-    "OPERATION_5": "tanh",
+    "OPERATION_COS": "cos",
+    "OPERATION_SIN": "sin",
+    "OPERATION_TAN": "tan",
+    "OPERATION_COSH": "cosh",
+    "OPERATION_SINH": "sinh",
+    "OPERATION_TANH": "tanh",
 
     "select_unit": "Unité",
-    "UNIT_0": "Degrés",
-    "UNIT_1": "Radians",
+    "UNIT_DEG": "Degrés",
+    "UNIT_RAD": "Radians",
 
     "fs_params": "Paramètres de l'équation",
 
diff --git a/src/app/components/select-field-line/select-field-line.component.ts b/src/app/components/select-field-line/select-field-line.component.ts
index 7c4b067ef..10e11497d 100644
--- a/src/app/components/select-field-line/select-field-line.component.ts
+++ b/src/app/components/select-field-line/select-field-line.component.ts
@@ -74,10 +74,8 @@ export class SelectFieldLineComponent implements OnInit {
         if (typeof this._select.helpLink === "string") {
             link = this._select.helpLink;
         } else { // object
-            if (! this.isMultiple) { // @TODO manage multiple selections ?
-                const cv = this._select.getValue() as SelectEntry;
-                const entryId = cv.id.substring(this._select.entriesBaseId.length);
-                link = this._select.helpLink[entryId];
+            if (!this.isMultiple) { // @TODO manage multiple selections ?
+                link = this._select.currentEntryHelpLink;
             }
         }
         window.open("assets/docs/" + this.appSetupService.language + "/calculators/" + link, "_blank");
@@ -91,10 +89,8 @@ export class SelectFieldLineComponent implements OnInit {
             if (typeof this._select.helpLink === "string") {
                 return true;
             } else { // object
-                if (! this.isMultiple) { // @TODO manage multiple selections ?
-                    const cv = this._select.getValue() as SelectEntry;
-                    const entryId = cv.id.substring(this._select.entriesBaseId.length);
-                    return Object.keys(this._select.helpLink).includes(entryId);
+                if (!this.isMultiple) { // @TODO manage multiple selections ?
+                    return this._select.currentEntryHasHelpLink;
                 }
             }
         }
diff --git a/src/app/formulaire/elements/select/select-field-nub-prop.ts b/src/app/formulaire/elements/select/select-field-nub-prop.ts
index 233502db0..865cd3d3b 100644
--- a/src/app/formulaire/elements/select/select-field-nub-prop.ts
+++ b/src/app/formulaire/elements/select/select-field-nub-prop.ts
@@ -28,9 +28,12 @@ export class SelectFieldNubProperty extends SelectField {
         // find enum associated to property
         const enumClass = Props.enumFromProperty[this._associatedProperty];
         if (enumClass !== undefined) {
+            const keys = Object.keys(enumClass);
             // add one select entry per enum entry, in the enum order
             for (let j = 0; j < Object.keys(enumClass).length / 2; j++) {
-                this.addEntry(this.createOrGetEntry(this._entriesBaseId + j, j));
+                const strEnum = enumClass[j];
+                const enumVal = enumClass[strEnum];
+                this.addEntry(this.createOrGetEntry(this._entriesBaseId + j, enumVal, strEnum));
             }
         }
     }
diff --git a/src/app/formulaire/elements/select/select-field.ts b/src/app/formulaire/elements/select/select-field.ts
index 4d6deed38..397a2e2cf 100644
--- a/src/app/formulaire/elements/select/select-field.ts
+++ b/src/app/formulaire/elements/select/select-field.ts
@@ -4,7 +4,7 @@ import { arraysAreEqual } from "../../../util/util";
 import { FormulaireNode } from "../formulaire-node";
 import { ServiceFactory } from "app/services/service-factory";
 import { FormulaireDefinition } from "../../definition/form-definition";
-import { enumValueFromString, Nub } from "jalhyd";
+import { enumValueFromString, Nub, Props } from "jalhyd";
 
 export abstract class SelectField extends Field {
 
@@ -212,6 +212,13 @@ export abstract class SelectField extends Field {
         return this._associatedProperty !== undefined;
     }
 
+    /**
+     * @returns true if select field is associated to a nub property which is an enum
+     */
+    public get hasAssociatedEnumProperty(): boolean {
+        return this._associatedProperty !== undefined && Props.enumFromProperty[this._associatedProperty] !== undefined;
+    }
+
     /**
      * default value from configuration
      */
@@ -255,6 +262,35 @@ export abstract class SelectField extends Field {
         }
     }
 
+    /**
+     * @returns enum value associated to the given entry
+     * @param val currently selected entry if undefined
+     */
+    private getEnumFromEntry(val: SelectEntry = undefined) {
+        const cv = val ?? this.getValue() as SelectEntry;
+        const entryId = cv.value;
+        const enumClass = Props.enumFromProperty[this.associatedProperty];
+        if (enumClass === undefined) {
+            return undefined;
+        }
+        return enumClass[entryId];
+    }
+
+    /**
+     * @returns help link associated to the current entry
+     */
+    public get currentEntryHelpLink() {
+        return this._helpLink[this.getEnumFromEntry()];
+    }
+
+    /**
+     * @returns true if current entry has an help link
+     */
+    public get currentEntryHasHelpLink(): boolean {
+        const currValue = this.getEnumFromEntry();
+        return Object.keys(this._helpLink).includes(currValue);
+    }
+
     /**
     * Reloads available entries, trying to keep the current selected
     * value; does not notify observers if value did not change
@@ -309,9 +345,10 @@ export abstract class SelectField extends Field {
     public updateLocalisation() {
         super.updateLocalisation();
         for (const e of this._entries) {
-            const aId = e.id.split("_");
+            const tmp = e.id.split("_");
+            const id = this.hasAssociatedEnumProperty ? this.getEnumFromEntry(e) : tmp[2];
             const trad = ServiceFactory.formulaireService.localizeText(
-                `${aId[1].toUpperCase()}_${aId[2]}`,
+                `${tmp[1].toUpperCase()}_${id}`,
                 this.parentForm.currentNub.calcType
             );
             e.label = trad;
-- 
GitLab


From a924fbbe2691add7ab2cfa5b2613313ee1446a4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Wed, 31 May 2023 13:53:01 +0200
Subject: [PATCH 5/8] refactor: convert (some of the) enums used in
 translations

refs #621
---
 .../services/internationalisation.service.ts  | 17 ++++++++++-
 src/locale/messages.en.json                   | 30 +++++++++----------
 src/locale/messages.fr.json                   | 30 +++++++++----------
 3 files changed, 46 insertions(+), 31 deletions(-)

diff --git a/src/app/services/internationalisation.service.ts b/src/app/services/internationalisation.service.ts
index deee494fe..95895d47d 100644
--- a/src/app/services/internationalisation.service.ts
+++ b/src/app/services/internationalisation.service.ts
@@ -1,6 +1,6 @@
 import { Injectable, isDevMode } from "@angular/core";
 
-import { Message, MessageCode, Observable, Observer, Nub, CalculatorType, PreBarrage, PbCloison, PbBassin } from "jalhyd";
+import { Message, MessageCode, Observable, Observer, Nub, CalculatorType, PreBarrage, PbCloison, PbBassin, enumValueFromString } from "jalhyd";
 
 import { StringMap } from "../stringmap";
 import { ApplicationSetupService } from "./app-setup.service";
@@ -165,6 +165,21 @@ export class I18nService extends Observable implements Observer {
         if (! this._Messages) {
             return `*** messages not loaded: ${this._currentLanguage} ***`;
         }
+
+        // key is an enum ?
+        if (textKey.indexOf("INFO_ENUM_") !== -1) {
+            // key ends with a number ?
+            const re = /^((INFO_ENUM)_(.+)_)([0-9]+)$/;
+            const res = textKey.match(re);
+            if (res !== null) {
+                // convert end number to enum symbolic value
+                const enumClass = res[3];
+                const value = res[4];
+                const val = enumValueFromString(enumClass, value);
+                textKey = res[1] + val;
+            }
+        }
+
         if (this._Messages[textKey] !== undefined) {
             return this.translateMessage(this._Messages[textKey], vars);
         } else {
diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index de71e8bbb..98aaefe3e 100755
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -156,9 +156,9 @@
     "INFO_DIALOG_SAVE_SESSION_TITLE": "Save calculator modules",
     "INFO_EMPTY_SESSION_DIALOGUE_TEXT": "Warning ! All open calculators will be lost. Continue ?",
     "INFO_EMPTY_SESSION_DIALOGUE_TITRE": "New session",
-    "INFO_ENUM_MACRORUGOFLOWTYPE_0": "Emergent",
-    "INFO_ENUM_MACRORUGOFLOWTYPE_1": "Quasi-emergent",
-    "INFO_ENUM_MACRORUGOFLOWTYPE_2": "Submerged",
+    "INFO_ENUM_MACRORUGOFLOWTYPE_EMERGENT": "Emergent",
+    "INFO_ENUM_MACRORUGOFLOWTYPE_QUASI_EMERGENT": "Quasi-emergent",
+    "INFO_ENUM_MACRORUGOFLOWTYPE_SUBMERGED": "Submerged",
     "INFO_ENUM_OUVRAGE_Q_MODE_0": "Weir",
     "INFO_ENUM_OUVRAGE_Q_MODE_1": "Orifice",
     "INFO_ENUM_OUVRAGE_Q_MODE_2": "Zero flow",
@@ -166,8 +166,8 @@
     "INFO_ENUM_OUVRAGE_Q_REGIME_1": "Partially submerged",
     "INFO_ENUM_OUVRAGE_Q_REGIME_2": "Submerged",
     "INFO_ENUM_OUVRAGE_Q_REGIME_3": "Zero flow",
-    "INFO_ENUM_PARFLOWREGIME_0": "Free",
-    "INFO_ENUM_PARFLOWREGIME_1": "Submerged",
+    "INFO_ENUM_PARFLOWREGIME_FREE": "Free",
+    "INFO_ENUM_PARFLOWREGIME_SUBMERGED": "Submerged",
     "INFO_ENUM_SPECIES_1": "Salmon, trout [50-100] (1)",
     "INFO_ENUM_SPECIES_2": "Mule (2)",
     "INFO_ENUM_SPECIES_3a": "Great shad (3a)",
@@ -188,16 +188,16 @@
     "INFO_ENUM_SPECIES_10": "Sunbleak, bitterling, stickleback, minnow (10)",
     "INFO_ENUM_SPECIES_11a": "European eel [yellow] (11a)",
     "INFO_ENUM_SPECIES_11b": "European Eel [glass eel] (11b)",
-    "INFO_ENUM_STRUCTUREFLOWMODE_0": "Weir",
-    "INFO_ENUM_STRUCTUREFLOWMODE_1": "Orifice",
-    "INFO_ENUM_STRUCTUREFLOWMODE_2": "Zero flow",
-    "INFO_ENUM_STRUCTUREFLOWREGIME_0": "Free flow",
-    "INFO_ENUM_STRUCTUREFLOWREGIME_1": "Partially submerged",
-    "INFO_ENUM_STRUCTUREFLOWREGIME_2": "Submerged",
-    "INFO_ENUM_STRUCTUREFLOWREGIME_3": "Zero flow",
-    "INFO_ENUM_STRUCTUREJETTYPE_0": "diving",
-    "INFO_ENUM_STRUCTUREJETTYPE_1": "surface",
-    "INFO_ENUM_STRUCTUREJETTYPE_2": "not applicable",
+    "INFO_ENUM_STRUCTUREFLOWMODE_WEIR": "Weir",
+    "INFO_ENUM_STRUCTUREFLOWMODE_ORIFICE": "Orifice",
+    "INFO_ENUM_STRUCTUREFLOWMODE_NULL": "Zero flow",
+    "INFO_ENUM_STRUCTUREFLOWREGIME_FREE": "Free flow",
+    "INFO_ENUM_STRUCTUREFLOWREGIME_PARTIAL": "Partially submerged",
+    "INFO_ENUM_STRUCTUREFLOWREGIME_SUBMERGED": "Submerged",
+    "INFO_ENUM_STRUCTUREFLOWREGIME_NULL": "Zero flow",
+    "INFO_ENUM_STRUCTUREJETTYPE_PLONGEANT": "diving",
+    "INFO_ENUM_STRUCTUREJETTYPE_SURFACE": "surface",
+    "INFO_ENUM_STRUCTUREJETTYPE_SO": "not applicable",
     "INFO_CHART_BUTTON_TITLE_RESET_ZOOM": "Restore default zoom",
     "INFO_CHART_BUTTON_TITLE_EXPORT_IMAGE": "Save picture",
     "INFO_CHART_BUTTON_TITLE_ENTER_FS": "Display fullscreen",
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index fa3145215..07fee9502 100755
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -156,9 +156,9 @@
     "INFO_DIALOG_SAVE_SESSION_TITLE": "Enregistrer les modules de calcul",
     "INFO_EMPTY_SESSION_DIALOGUE_TEXT": "Attention&nbsp;! Tous les modules de calcul ouverts seront perdus.",
     "INFO_EMPTY_SESSION_DIALOGUE_TITRE": "Démarrer une nouvelle session",
-    "INFO_ENUM_MACRORUGOFLOWTYPE_0": "Émergent",
-    "INFO_ENUM_MACRORUGOFLOWTYPE_1": "Quasi-émergent",
-    "INFO_ENUM_MACRORUGOFLOWTYPE_2": "Immergé",
+    "INFO_ENUM_MACRORUGOFLOWTYPE_EMERGENT": "Émergent",
+    "INFO_ENUM_MACRORUGOFLOWTYPE_QUASI_EMERGENT": "Quasi-émergent",
+    "INFO_ENUM_MACRORUGOFLOWTYPE_SUBMERGED": "Immergé",
     "INFO_ENUM_OUVRAGE_Q_MODE_0": "Surface libre",
     "INFO_ENUM_OUVRAGE_Q_MODE_1": "En charge",
     "INFO_ENUM_OUVRAGE_Q_MODE_2": "Débit nul",
@@ -166,8 +166,8 @@
     "INFO_ENUM_OUVRAGE_Q_REGIME_1": "Partiellement noyé",
     "INFO_ENUM_OUVRAGE_Q_REGIME_2": "Noyé",
     "INFO_ENUM_OUVRAGE_Q_REGIME_3": "Débit nul",
-    "INFO_ENUM_PARFLOWREGIME_0": "Dénoyé",
-    "INFO_ENUM_PARFLOWREGIME_1": "Noyé",
+    "INFO_ENUM_PARFLOWREGIME_FREE": "Dénoyé",
+    "INFO_ENUM_PARFLOWREGIME_SUBMERGED": "Noyé",
     "INFO_ENUM_SPECIES_1": "Saumon, truite [50-100] (1)",
     "INFO_ENUM_SPECIES_2": "Mulets (2)",
     "INFO_ENUM_SPECIES_3a": "Grande Alose (3a)",
@@ -188,16 +188,16 @@
     "INFO_ENUM_SPECIES_10": "Able, bouvière, épinoche(tte), vairons (10)",
     "INFO_ENUM_SPECIES_11a": "Anguille européenne [jaune] (11a)",
     "INFO_ENUM_SPECIES_11b": "Anguille européenne [civelle] (11b)",
-    "INFO_ENUM_STRUCTUREFLOWMODE_0": "Surface libre",
-    "INFO_ENUM_STRUCTUREFLOWMODE_1": "En charge",
-    "INFO_ENUM_STRUCTUREFLOWMODE_2": "Débit nul",
-    "INFO_ENUM_STRUCTUREFLOWREGIME_0": "Dénoyé",
-    "INFO_ENUM_STRUCTUREFLOWREGIME_1": "Partiellement noyé",
-    "INFO_ENUM_STRUCTUREFLOWREGIME_2": "Noyé",
-    "INFO_ENUM_STRUCTUREFLOWREGIME_3": "Débit nul",
-    "INFO_ENUM_STRUCTUREJETTYPE_0": "plongeant",
-    "INFO_ENUM_STRUCTUREJETTYPE_1": "de surface",
-    "INFO_ENUM_STRUCTUREJETTYPE_2": "sans objet",
+    "INFO_ENUM_STRUCTUREFLOWMODE_WEIR": "Surface libre",
+    "INFO_ENUM_STRUCTUREFLOWMODE_ORIFICE": "En charge",
+    "INFO_ENUM_STRUCTUREFLOWMODE_NULL": "Débit nul",
+    "INFO_ENUM_STRUCTUREFLOWREGIME_FREE": "Dénoyé",
+    "INFO_ENUM_STRUCTUREFLOWREGIME_PARTIAL": "Partiellement noyé",
+    "INFO_ENUM_STRUCTUREFLOWREGIME_SUBMERGED": "Noyé",
+    "INFO_ENUM_STRUCTUREFLOWREGIME_NULL": "Débit nul",
+    "INFO_ENUM_STRUCTUREJETTYPE_PLONGEANT": "plongeant",
+    "INFO_ENUM_STRUCTUREJETTYPE_SURFACE": "de surface",
+    "INFO_ENUM_STRUCTUREJETTYPE_SO": "sans objet",
     "INFO_CHART_BUTTON_TITLE_RESET_ZOOM": "Réinitialiser le zoom",
     "INFO_CHART_BUTTON_TITLE_EXPORT_IMAGE": "Enregistrer l'image",
     "INFO_CHART_BUTTON_TITLE_ENTER_FS": "Afficher en plein écran",
-- 
GitLab


From f9b85702d2cb3163ad44b0e62795c3989d4e8fe4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Wed, 31 May 2023 15:02:29 +0200
Subject: [PATCH 6/8] refactor: fish species enums translation in select

refs #621
---
 .../select/select-field-species-list.ts       |  2 +-
 .../services/internationalisation.service.ts  | 32 ++++++++-------
 src/locale/messages.en.json                   | 40 +++++++++----------
 src/locale/messages.fr.json                   | 40 +++++++++----------
 4 files changed, 58 insertions(+), 56 deletions(-)

diff --git a/src/app/formulaire/elements/select/select-field-species-list.ts b/src/app/formulaire/elements/select/select-field-species-list.ts
index 7b94345aa..3784ace7d 100644
--- a/src/app/formulaire/elements/select/select-field-species-list.ts
+++ b/src/app/formulaire/elements/select/select-field-species-list.ts
@@ -32,7 +32,7 @@ export class SelectFieldSpeciesList extends SelectField {
         for (let j = 1; j < Object.keys(FishSpecies).length / 2; j++) { // exclude "0" (SPECIES_CUSTOM)
             const spgId = FishSpecies[j].substring(FishSpecies[j].lastIndexOf("_") + 1);
             const e = this.createOrGetEntry(this._entriesBaseId + spgId, FishSpecies[j]);
-            e.intlInfo = { "isnub": false, "code": FishSpecies[j] }
+            e.intlInfo = { "isnub": false, "code": "FISHSPECIES_" + FishSpecies[j] }
             this.addEntry(e);
         }
     }
diff --git a/src/app/services/internationalisation.service.ts b/src/app/services/internationalisation.service.ts
index 95895d47d..2209fd17d 100644
--- a/src/app/services/internationalisation.service.ts
+++ b/src/app/services/internationalisation.service.ts
@@ -167,27 +167,29 @@ export class I18nService extends Observable implements Observer {
         }
 
         // key is an enum ?
-        if (textKey.indexOf("INFO_ENUM_") !== -1) {
-            // key ends with a number ?
-            const re = /^((INFO_ENUM)_(.+)_)([0-9]+)$/;
-            const res = textKey.match(re);
-            if (res !== null) {
-                // convert end number to enum symbolic value
-                const enumClass = res[3];
-                const value = res[4];
-                const val = enumValueFromString(enumClass, value);
-                textKey = res[1] + val;
+        let key = textKey;
+        if (key.indexOf("INFO_ENUM_") !== -1) {
+            // key ends with a number ? convert end number to enum symbolic value
+            if (key.indexOf("_FISHSPECIES_") === -1) { // do not process fish species which values include '_' and numbers'...
+                const re = /^((INFO_ENUM)_(.+)_)([0-9]+)$/;
+                const res = key.match(re);
+                if (res !== null) {
+                    const enumClass = res[3];
+                    const value = res[4];
+                    const val = enumValueFromString(enumClass, value);
+                    key = res[1] + val;
+                }
             }
         }
 
-        if (this._Messages[textKey] !== undefined) {
-            return this.translateMessage(this._Messages[textKey], vars);
+        if (this._Messages[key] !== undefined) {
+            return this.translateMessage(this._Messages[key], vars);
         } else {
             // try general message
-            if (this._Messages !== undefined && this._Messages["INFO_LIB_" + textKey.toUpperCase()] !== undefined) {
-                return decodeHtml(this._Messages["INFO_LIB_" + textKey.toUpperCase()]);
+            if (this._Messages !== undefined && this._Messages["INFO_LIB_" + key.toUpperCase()] !== undefined) {
+                return decodeHtml(this._Messages["INFO_LIB_" + key.toUpperCase()]);
             }
-            return `*** message not found: ${textKey} ***`;
+            return `*** message not found: ${key} ***`;
         }
     }
 
diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index 98aaefe3e..ed23c49fc 100755
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -168,26 +168,26 @@
     "INFO_ENUM_OUVRAGE_Q_REGIME_3": "Zero flow",
     "INFO_ENUM_PARFLOWREGIME_FREE": "Free",
     "INFO_ENUM_PARFLOWREGIME_SUBMERGED": "Submerged",
-    "INFO_ENUM_SPECIES_1": "Salmon, trout [50-100] (1)",
-    "INFO_ENUM_SPECIES_2": "Mule (2)",
-    "INFO_ENUM_SPECIES_3a": "Great shad (3a)",
-    "INFO_ENUM_SPECIES_3b": "Shad (3b)",
-    "INFO_ENUM_SPECIES_3c": "Sea lamprey (3c)",
-    "INFO_ENUM_SPECIES_4a": "Trout [25-55] (4a)",
-    "INFO_ENUM_SPECIES_4b": "River trout [15-30] (4b)",
-    "INFO_ENUM_SPECIES_5": "Aspe, pike (5)",
-    "INFO_ENUM_SPECIES_6": "Common grayling (6)",
-    "INFO_ENUM_SPECIES_7a": "Barbel, chub, nase (7a)",
-    "INFO_ENUM_SPECIES_7b": "River lamprey (7b)",
-    "INFO_ENUM_SPECIES_8a": "Common carp (8a)",
-    "INFO_ENUM_SPECIES_8b": "Common bream, pike-perch (8b)",
-    "INFO_ENUM_SPECIES_8c": "White bream, ide, burbot, perch, tench (8c)",
-    "INFO_ENUM_SPECIES_8d": "Common dace (8d)",
-    "INFO_ENUM_SPECIES_9a": "Bleak, spirlin, barbel, souffia, crucian carp, roach... (9a)",
-    "INFO_ENUM_SPECIES_9b": "Apron, sculpins, ruffe, loach... (9b)",
-    "INFO_ENUM_SPECIES_10": "Sunbleak, bitterling, stickleback, minnow (10)",
-    "INFO_ENUM_SPECIES_11a": "European eel [yellow] (11a)",
-    "INFO_ENUM_SPECIES_11b": "European Eel [glass eel] (11b)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_1": "Salmon, trout [50-100] (1)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_2": "Mule (2)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_3a": "Great shad (3a)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_3b": "Shad (3b)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_3c": "Sea lamprey (3c)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_4a": "Trout [25-55] (4a)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_4b": "River trout [15-30] (4b)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_5": "Aspe, pike (5)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_6": "Common grayling (6)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_7a": "Barbel, chub, nase (7a)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_7b": "River lamprey (7b)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_8a": "Common carp (8a)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_8b": "Common bream, pike-perch (8b)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_8c": "White bream, ide, burbot, perch, tench (8c)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_8d": "Common dace (8d)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_9a": "Bleak, spirlin, barbel, souffia, crucian carp, roach... (9a)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_9b": "Apron, sculpins, ruffe, loach... (9b)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_10": "Sunbleak, bitterling, stickleback, minnow (10)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_11a": "European eel [yellow] (11a)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_11b": "European Eel [glass eel] (11b)",
     "INFO_ENUM_STRUCTUREFLOWMODE_WEIR": "Weir",
     "INFO_ENUM_STRUCTUREFLOWMODE_ORIFICE": "Orifice",
     "INFO_ENUM_STRUCTUREFLOWMODE_NULL": "Zero flow",
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index 07fee9502..5751ec720 100755
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -168,26 +168,26 @@
     "INFO_ENUM_OUVRAGE_Q_REGIME_3": "Débit nul",
     "INFO_ENUM_PARFLOWREGIME_FREE": "Dénoyé",
     "INFO_ENUM_PARFLOWREGIME_SUBMERGED": "Noyé",
-    "INFO_ENUM_SPECIES_1": "Saumon, truite [50-100] (1)",
-    "INFO_ENUM_SPECIES_2": "Mulets (2)",
-    "INFO_ENUM_SPECIES_3a": "Grande Alose (3a)",
-    "INFO_ENUM_SPECIES_3b": "Alose feinte (3b)",
-    "INFO_ENUM_SPECIES_3c": "Lamproie marine (3c)",
-    "INFO_ENUM_SPECIES_4a": "Truite [25-55] (4a)",
-    "INFO_ENUM_SPECIES_4b": "Truite de rivière [15-30] (4b)",
-    "INFO_ENUM_SPECIES_5": "Aspe, brochet (5)",
-    "INFO_ENUM_SPECIES_6": "Ombre commun (6)",
-    "INFO_ENUM_SPECIES_7a": "Barbeau, chevaine, hotu (7a)",
-    "INFO_ENUM_SPECIES_7b": "Lamproie fluviatile (7b)",
-    "INFO_ENUM_SPECIES_8a": "Carpe commune (8a)",
-    "INFO_ENUM_SPECIES_8b": "Brème commune, sandre (8b)",
-    "INFO_ENUM_SPECIES_8c": "Brème bordelière, ide, lotte, perche, tanche (8c)",
-    "INFO_ENUM_SPECIES_8d": "Vandoises (8d)",
-    "INFO_ENUM_SPECIES_9a": "Ablette, blageon, carrassin, gardon... (9a)",
-    "INFO_ENUM_SPECIES_9b": "Apron, chabots, goujons, loche... (9b)",
-    "INFO_ENUM_SPECIES_10": "Able, bouvière, épinoche(tte), vairons (10)",
-    "INFO_ENUM_SPECIES_11a": "Anguille européenne [jaune] (11a)",
-    "INFO_ENUM_SPECIES_11b": "Anguille européenne [civelle] (11b)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_1": "Saumon, truite [50-100] (1)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_2": "Mulets (2)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_3a": "Grande Alose (3a)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_3b": "Alose feinte (3b)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_3c": "Lamproie marine (3c)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_4a": "Truite [25-55] (4a)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_4b": "Truite de rivière [15-30] (4b)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_5": "Aspe, brochet (5)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_6": "Ombre commun (6)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_7a": "Barbeau, chevaine, hotu (7a)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_7b": "Lamproie fluviatile (7b)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_8a": "Carpe commune (8a)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_8b": "Brème commune, sandre (8b)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_8c": "Brème bordelière, ide, lotte, perche, tanche (8c)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_8d": "Vandoises (8d)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_9a": "Ablette, blageon, carrassin, gardon... (9a)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_9b": "Apron, chabots, goujons, loche... (9b)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_10": "Able, bouvière, épinoche(tte), vairons (10)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_11a": "Anguille européenne [jaune] (11a)",
+    "INFO_ENUM_FISHSPECIES_SPECIES_11b": "Anguille européenne [civelle] (11b)",
     "INFO_ENUM_STRUCTUREFLOWMODE_WEIR": "Surface libre",
     "INFO_ENUM_STRUCTUREFLOWMODE_ORIFICE": "En charge",
     "INFO_ENUM_STRUCTUREFLOWMODE_NULL": "Débit nul",
-- 
GitLab


From bfe1b7b0d807b099b56f9a2a38ff85fa708b6452 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Wed, 31 May 2023 15:51:42 +0200
Subject: [PATCH 7/8] refactor: translation/calculator configuration: remove
 unused values

refs #621
---
 src/app/calculators/verificateur/en.json | 4 ----
 src/app/calculators/verificateur/fr.json | 4 ----
 src/locale/messages.en.json              | 7 -------
 src/locale/messages.fr.json              | 7 -------
 4 files changed, 22 deletions(-)

diff --git a/src/app/calculators/verificateur/en.json b/src/app/calculators/verificateur/en.json
index eb48e9835..57ac4f9ac 100644
--- a/src/app/calculators/verificateur/en.json
+++ b/src/app/calculators/verificateur/en.json
@@ -3,10 +3,6 @@
 
     "select_target_pass": "Fish pass to verify",
 
-    "select_pab_jet_type": "Jet type (PAB)",
-    "select_pab_jet_type_0": "Diving",
-    "select_pab_jet_type_1": "Surface",
-
     "fs_species": "Species parameters",
 
     "select_species_list": "Species groups"
diff --git a/src/app/calculators/verificateur/fr.json b/src/app/calculators/verificateur/fr.json
index 13b6430de..595e5b961 100644
--- a/src/app/calculators/verificateur/fr.json
+++ b/src/app/calculators/verificateur/fr.json
@@ -3,10 +3,6 @@
 
     "select_target_pass": "Passe à vérifier",
 
-    "select_pab_jet_type": "Type de jet (PAB)",
-    "select_pab_jet_type_0": "Plongeant",
-    "select_pab_jet_type_1": "Surface",
-
     "fs_species": "Paramètres des espèces",
 
     "select_species_list": "Groupes d'espèces"
diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index ed23c49fc..c17b98aa4 100755
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -159,13 +159,6 @@
     "INFO_ENUM_MACRORUGOFLOWTYPE_EMERGENT": "Emergent",
     "INFO_ENUM_MACRORUGOFLOWTYPE_QUASI_EMERGENT": "Quasi-emergent",
     "INFO_ENUM_MACRORUGOFLOWTYPE_SUBMERGED": "Submerged",
-    "INFO_ENUM_OUVRAGE_Q_MODE_0": "Weir",
-    "INFO_ENUM_OUVRAGE_Q_MODE_1": "Orifice",
-    "INFO_ENUM_OUVRAGE_Q_MODE_2": "Zero flow",
-    "INFO_ENUM_OUVRAGE_Q_REGIME_0": "Free flow",
-    "INFO_ENUM_OUVRAGE_Q_REGIME_1": "Partially submerged",
-    "INFO_ENUM_OUVRAGE_Q_REGIME_2": "Submerged",
-    "INFO_ENUM_OUVRAGE_Q_REGIME_3": "Zero flow",
     "INFO_ENUM_PARFLOWREGIME_FREE": "Free",
     "INFO_ENUM_PARFLOWREGIME_SUBMERGED": "Submerged",
     "INFO_ENUM_FISHSPECIES_SPECIES_1": "Salmon, trout [50-100] (1)",
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index 5751ec720..9b9b7c1d4 100755
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -159,13 +159,6 @@
     "INFO_ENUM_MACRORUGOFLOWTYPE_EMERGENT": "Émergent",
     "INFO_ENUM_MACRORUGOFLOWTYPE_QUASI_EMERGENT": "Quasi-émergent",
     "INFO_ENUM_MACRORUGOFLOWTYPE_SUBMERGED": "Immergé",
-    "INFO_ENUM_OUVRAGE_Q_MODE_0": "Surface libre",
-    "INFO_ENUM_OUVRAGE_Q_MODE_1": "En charge",
-    "INFO_ENUM_OUVRAGE_Q_MODE_2": "Débit nul",
-    "INFO_ENUM_OUVRAGE_Q_REGIME_0": "Dénoyé",
-    "INFO_ENUM_OUVRAGE_Q_REGIME_1": "Partiellement noyé",
-    "INFO_ENUM_OUVRAGE_Q_REGIME_2": "Noyé",
-    "INFO_ENUM_OUVRAGE_Q_REGIME_3": "Débit nul",
     "INFO_ENUM_PARFLOWREGIME_FREE": "Dénoyé",
     "INFO_ENUM_PARFLOWREGIME_SUBMERGED": "Noyé",
     "INFO_ENUM_FISHSPECIES_SPECIES_1": "Saumon, truite [50-100] (1)",
-- 
GitLab


From 1becb5554c48b4ae9f008d7346c2b1e741922ecc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Wed, 31 May 2023 16:35:42 +0200
Subject: [PATCH 8/8] update jalhyd_branc to
 335-utiliser-des-identifiants-symboliques-plutot-que-numeriques-dans-les-fichiers

refs #621
---
 jalhyd_branch | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/jalhyd_branch b/jalhyd_branch
index 9426cd154..5a7919cd9 100644
--- a/jalhyd_branch
+++ b/jalhyd_branch
@@ -1 +1,5 @@
+<<<<<<< Updated upstream
 302-structure-ajouter-une-erreur-sur-l-ennoiement
+=======
+335-utiliser-des-identifiants-symboliques-plutot-que-numeriques-dans-les-fichiers
+>>>>>>> Stashed changes
-- 
GitLab