From 089260924ee35678e05519ee60a12b7099c76a48 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Wed, 15 Feb 2023 09:12:24 +0100
Subject: [PATCH 1/8] refactor(e2e): add changeSelectValue() as a util function

refs #586
---
 e2e/calculate-linked-params.e2e-spec.ts       | 13 +++++++------
 e2e/calculator.po.ts                          |  7 -------
 e2e/cloisons.e2e-spec.ts                      |  3 ++-
 e2e/clone-calc.e2e-spec.ts                    |  6 +++---
 e2e/examples-empty-fields.e2e-spec.ts         |  3 ++-
 e2e/lechapt-calmon.e2e-spec.ts                |  5 +++--
 e2e/linked-parameter-section-type.e2e-spec.ts |  3 ++-
 e2e/load-save-session.e2e-spec.ts             |  6 +++---
 e2e/ouvrages-empty-fields.e2e-spec.ts         | 11 ++++++-----
 e2e/pab.e2e-spec.ts                           |  4 ++--
 e2e/preferences.po.ts                         |  6 ++----
 e2e/pressure-loss-empty-fields.e2e-spec.ts    |  3 ++-
 e2e/remous.e2e-spec.ts                        |  3 ++-
 e2e/solveur.e2e-spec.ts                       | 10 +++++-----
 e2e/util.po.ts                                | 10 +++++++++-
 15 files changed, 50 insertions(+), 43 deletions(-)

diff --git a/e2e/calculate-linked-params.e2e-spec.ts b/e2e/calculate-linked-params.e2e-spec.ts
index 12e68d423..7c54f5af4 100644
--- a/e2e/calculate-linked-params.e2e-spec.ts
+++ b/e2e/calculate-linked-params.e2e-spec.ts
@@ -5,6 +5,7 @@ import { Navbar } from "./navbar.po";
 import { SideNav } from "./sidenav.po";
 import { browser, by } from "protractor";
 import { PreferencesPage } from "./preferences.po";
+import { changeSelectValue } from "./util.po";
 
 /**
  * Uses an example configuration to calculate :
@@ -62,7 +63,7 @@ describe("ngHyd − calculate with linked parameters", () => {
         const Y = calcPage.getInputById("Y");
         await calcPage.setParamMode(Y, "link");
         const sel = await calcPage.getLinkedValueSelect(Y);
-        await calcPage.changeSelectValue(sel, 0);
+        await changeSelectValue(sel, 0);
 
         await computeAndCheckPresenceOfResults();
     });
@@ -79,7 +80,7 @@ describe("ngHyd − calculate with linked parameters", () => {
         const Y = calcPage.getInputById("Y");
         await calcPage.setParamMode(Y, "link");
         const sel = await calcPage.getLinkedValueSelect(Y);
-        await calcPage.changeSelectValue(sel, 0);
+        await changeSelectValue(sel, 0);
         // vary W
         const W = calcPage.getInputById("W");
         await calcPage.setParamMode(W, "var");
@@ -102,7 +103,7 @@ describe("ngHyd − calculate with linked parameters", () => {
         const Y2 = calcPage.getInputById("Y");
         await calcPage.setParamMode(Y2, "link");
         const sel = await calcPage.getLinkedValueSelect(Y2);
-        await calcPage.changeSelectValue(sel, 0);
+        await changeSelectValue(sel, 0);
 
         await computeAndCheckPresenceOfResults();
     });
@@ -122,7 +123,7 @@ describe("ngHyd − calculate with linked parameters", () => {
         const Y2 = calcPage.getInputById("Y");
         await calcPage.setParamMode(Y2, "link");
         const sel = await calcPage.getLinkedValueSelect(Y2);
-        await calcPage.changeSelectValue(sel, 0);
+        await changeSelectValue(sel, 0);
 
         await computeAndCheckPresenceOfResults();
     });
@@ -142,7 +143,7 @@ describe("ngHyd − calculate with linked parameters", () => {
         const Y2 = calcPage.getInputById("Y");
         await calcPage.setParamMode(Y2, "link");
         const sel = await calcPage.getLinkedValueSelect(Y2);
-        await calcPage.changeSelectValue(sel, 0);
+        await changeSelectValue(sel, 0);
         // vary W
         const W = calcPage.getInputById("W");
         await calcPage.setParamMode(W, "var");
@@ -168,7 +169,7 @@ describe("ngHyd − calculate with linked parameters", () => {
         const Y2 = calcPage.getInputById("Y");
         await calcPage.setParamMode(Y2, "link");
         const sel = await calcPage.getLinkedValueSelect(Y2);
-        await calcPage.changeSelectValue(sel, 0);
+        await changeSelectValue(sel, 0);
 
         await computeAndCheckPresenceOfResults();
     });
diff --git a/e2e/calculator.po.ts b/e2e/calculator.po.ts
index af1e1803c..12c5a8de4 100644
--- a/e2e/calculator.po.ts
+++ b/e2e/calculator.po.ts
@@ -331,13 +331,6 @@ export class CalculatorPage {
         return calcButton;
     }
 
-    async changeSelectValue(elt: ElementFinder, index: number) {
-        await elt.click();
-        const optionId = ".cdk-overlay-container mat-option:nth-of-type(" + (index + 1) + ")";
-        const option = element(by.css(optionId));
-        await option.click();
-    }
-
     // find parent element of elt having class "container"
     async findParentContainer(elt: ElementFinder): Promise<ElementFinder> {
         let i = 8; // garde fous
diff --git a/e2e/cloisons.e2e-spec.ts b/e2e/cloisons.e2e-spec.ts
index 2febdc57e..f251afabc 100644
--- a/e2e/cloisons.e2e-spec.ts
+++ b/e2e/cloisons.e2e-spec.ts
@@ -3,6 +3,7 @@ import { CalculatorPage } from "./calculator.po";
 import { browser } from "protractor";
 import { Navbar } from "./navbar.po";
 import { PreferencesPage } from "./preferences.po";
+import { changeSelectValue } from "./util.po";
 
 /**
  * Cloisons - différents tests qui n'ont pas tant de rapport que ça avec les cloisons :)
@@ -44,7 +45,7 @@ describe("ngHyd − cloisons", () => {
         await browser.sleep(300);
 
         // 4. change LoiDebit
-        await calcPage.changeSelectValue(calcPage.getSelectById("select_loidebit"), 1);
+        await changeSelectValue(calcPage.getSelectById("select_loidebit"), 1);
         await browser.sleep(300);
 
         // 5. check number of inputs in CALC mode
diff --git a/e2e/clone-calc.e2e-spec.ts b/e2e/clone-calc.e2e-spec.ts
index 038a90e66..a63f565b0 100644
--- a/e2e/clone-calc.e2e-spec.ts
+++ b/e2e/clone-calc.e2e-spec.ts
@@ -4,7 +4,7 @@ import { CalculatorPage } from "./calculator.po";
 import { Navbar } from "./navbar.po";
 import { browser } from "protractor";
 import { PreferencesPage } from "./preferences.po";
-import { scrollPageToTop } from "./util.po";
+import { changeSelectValue, scrollPageToTop } from "./util.po";
 
 /**
  * Clone calculators
@@ -54,7 +54,7 @@ describe("ngHyd − clone a calculator", () => {
             k: 0.6,
             Ks: 42
         };
-        await calcPage.changeSelectValue(calcPage.getSelectById("select_section"), 3); // mode "parabolique"
+        await changeSelectValue(calcPage.getSelectById("select_section"), 3); // mode "parabolique"
         await calcPage.getInputById("k").clear();
         await calcPage.getInputById("k").sendKeys(sourceValues["k"]);
         await calcPage.getInputById("Ks").clear();
@@ -63,7 +63,7 @@ describe("ngHyd − clone a calculator", () => {
         const debitSP = calcPage.getInputById("Q");
         await calcPage.setParamMode(debitSP, "link");
         await browser.sleep(500);
-        await calcPage.changeSelectValue(calcPage.getSelectById("linked_Q"), 1); // "Courbe de remous"
+        await changeSelectValue(calcPage.getSelectById("linked_Q"), 1); // "Courbe de remous"
         await browser.sleep(500);
 
         // otherwise clickCloneCalcButton() fails with "Element is not clickable at point"
diff --git a/e2e/examples-empty-fields.e2e-spec.ts b/e2e/examples-empty-fields.e2e-spec.ts
index 08f40c467..3a8d3942c 100644
--- a/e2e/examples-empty-fields.e2e-spec.ts
+++ b/e2e/examples-empty-fields.e2e-spec.ts
@@ -3,6 +3,7 @@ import { CalculatorPage } from "./calculator.po";
 import { ListPage } from "./list.po";
 import { Navbar } from "./navbar.po";
 import { PreferencesPage } from "./preferences.po"
+import { changeSelectValue } from "./util.po";
 
 /**
  * check that fields are empty on creation
@@ -60,7 +61,7 @@ describe("ngHyd - Check that examples fields are not empty with 'empty fields on
 
         // modify 1st structure discharge law
         const dischargeSelect = calcPage.getSelectById("select_loidebit");
-        await calcPage.changeSelectValue(dischargeSelect, 1);
+        await changeSelectValue(dischargeSelect, 1);
         await browser.sleep(200);
 
         // open initial dialog
diff --git a/e2e/lechapt-calmon.e2e-spec.ts b/e2e/lechapt-calmon.e2e-spec.ts
index 91dea3194..f3be14a59 100644
--- a/e2e/lechapt-calmon.e2e-spec.ts
+++ b/e2e/lechapt-calmon.e2e-spec.ts
@@ -3,6 +3,7 @@ import { browser, by } from "protractor";
 import { CalculatorPage } from "./calculator.po";
 import { PreferencesPage } from "./preferences.po";
 import { Navbar } from "./navbar.po";
+import { changeSelectValue } from "./util.po";
 
 /**
  * Check that created/cloned structures have empty fields when
@@ -45,7 +46,7 @@ describe("Lechapt&Calmon - ", () => {
 
         // select last material type
         const materialSelect = calcPage.getSelectById("select_material");
-        await calcPage.changeSelectValue(materialSelect, 8);
+        await changeSelectValue(materialSelect, 8);
         await browser.sleep(200);
 
         // run calculation
@@ -58,7 +59,7 @@ describe("Lechapt&Calmon - ", () => {
         const pl1 = await res1.all(by.css("td")).get(1).getText();
 
         // select first material type
-        await calcPage.changeSelectValue(materialSelect, 0);
+        await changeSelectValue(materialSelect, 0);
         await browser.sleep(200);
 
         // run calculation
diff --git a/e2e/linked-parameter-section-type.e2e-spec.ts b/e2e/linked-parameter-section-type.e2e-spec.ts
index b42c13d0f..a863f273e 100644
--- a/e2e/linked-parameter-section-type.e2e-spec.ts
+++ b/e2e/linked-parameter-section-type.e2e-spec.ts
@@ -3,6 +3,7 @@ import { ListPage } from "./list.po";
 import { Navbar } from "./navbar.po";
 import { PreferencesPage } from "./preferences.po";
 import { CalculatorPage } from "./calculator.po";
+import { changeSelectValue } from "./util.po";
 
 describe("linked parameter in calculator with section - ", () => {
     let listPage: ListPage;
@@ -42,7 +43,7 @@ describe("linked parameter in calculator with section - ", () => {
         await calcPage.setParamMode(inputQ, "link");
 
         // change section type
-        await calcPage.changeSelectValue(calcPage.getSelectById("select_section"), 3); // mode "parabolique"
+        await changeSelectValue(calcPage.getSelectById("select_section"), 3); // mode "parabolique"
 
         // check Q is still in linked mode
         expect(await calcPage.inputIsInLinkedMode(inputQ)).toBe(true);
diff --git a/e2e/load-save-session.e2e-spec.ts b/e2e/load-save-session.e2e-spec.ts
index 436058e6f..8689c6f13 100644
--- a/e2e/load-save-session.e2e-spec.ts
+++ b/e2e/load-save-session.e2e-spec.ts
@@ -5,7 +5,7 @@ import { Navbar } from "./navbar.po";
 import { SideNav } from "./sidenav.po";
 import { browser, by, element } from "protractor";
 import { PreferencesPage } from "./preferences.po";
-import { expectNumber } from "./util.po";
+import { changeSelectValue, expectNumber } from "./util.po";
 
 const fs = require("fs");
 const path = require("path");
@@ -122,7 +122,7 @@ describe("ngHyd − save and load sessions", () => {
         await listPage.clickMenuEntryForCalcType(2); // Section paramétrée
         await browser.sleep(500);
 
-        await calcPage.changeSelectValue(calcPage.getSelectById("select_section"), 2); // mode "trapezoidal"
+        await changeSelectValue(calcPage.getSelectById("select_section"), 2); // mode "trapezoidal"
 
         await calcPage.getInputById("Ks").clear(); // coefficient de Strickler
         await browser.sleep(1000);
@@ -190,7 +190,7 @@ describe("ngHyd − save and load sessions", () => {
 
                         // select next select option (optionally looping)
                         const nextInd = (ind + 1) % optionCount;
-                        await calcPage.changeSelectValue(sel, nextInd);
+                        await changeSelectValue(sel, nextInd);
                         await browser.sleep(200);
 
                         // save session
diff --git a/e2e/ouvrages-empty-fields.e2e-spec.ts b/e2e/ouvrages-empty-fields.e2e-spec.ts
index 4a28316f8..918107e2c 100644
--- a/e2e/ouvrages-empty-fields.e2e-spec.ts
+++ b/e2e/ouvrages-empty-fields.e2e-spec.ts
@@ -4,6 +4,7 @@ import { CalculatorPage } from "./calculator.po";
 import { AppPage } from "./app.po";
 import { PreferencesPage } from "./preferences.po";
 import { Navbar } from "./navbar.po";
+import { changeSelectValue } from "./util.po";
 
 /**
  * Check that created/cloned structures have empty fields when
@@ -51,7 +52,7 @@ describe("ngHyd - check that created/cloned structures have empty fields - ", ()
 
         // change 1st structure type to rectangular weir
         const structSelect = calcPage.getSelectById("select_structure");
-        await calcPage.changeSelectValue(structSelect, 1);
+        await changeSelectValue(structSelect, 1);
         await browser.sleep(200);
 
         // check 1st structure empty fields
@@ -91,7 +92,7 @@ describe("ngHyd - check that created/cloned structures have empty fields - ", ()
 
         // change 1st structure type to rectangular weir
         const structSelect = calcPage.getSelectById("select_structure");
-        await calcPage.changeSelectValue(structSelect, 1);
+        await changeSelectValue(structSelect, 1);
         await browser.sleep(200);
 
         // copy structure
@@ -102,7 +103,7 @@ describe("ngHyd - check that created/cloned structures have empty fields - ", ()
         // change 2nd structure type to rectangular gate
         const selects = await element.all(by.css("mat-select#select_structure"));
         const structSelect2 = selects[1];
-        await calcPage.changeSelectValue(structSelect2, 5);
+        await changeSelectValue(structSelect2, 5);
         await browser.sleep(200);
 
         // check empty fields
@@ -135,12 +136,12 @@ describe("ngHyd - check that created/cloned structures have empty fields - ", ()
 
         // change 1st structure type to rectangular weir
         const structSelect = calcPage.getSelectById("select_structure");
-        await calcPage.changeSelectValue(structSelect, 1);
+        await changeSelectValue(structSelect, 1);
         await browser.sleep(200);
 
         // change discharge law to Larinier
         const dischargeSelect = calcPage.getSelectById("select_loidebit");
-        await calcPage.changeSelectValue(dischargeSelect, 3);
+        await changeSelectValue(dischargeSelect, 3);
         await browser.sleep(200);
 
         // check empty fields
diff --git a/e2e/pab.e2e-spec.ts b/e2e/pab.e2e-spec.ts
index 866f67fb5..edcdd9750 100644
--- a/e2e/pab.e2e-spec.ts
+++ b/e2e/pab.e2e-spec.ts
@@ -5,7 +5,7 @@ import { browser, by, element } from "protractor";
 import { AppPage } from "./app.po";
 import { SideNav } from "./sidenav.po";
 import { PreferencesPage } from "./preferences.po";
-import { scrollPageToTop } from "./util.po";
+import { changeSelectValue, scrollPageToTop } from "./util.po";
 
 /**
  * Clone calculators
@@ -297,7 +297,7 @@ describe("ngHyd − Passe à Bassins", () => {
 
             // change iteration
             const pve = calcPage.getSelectById("pab-variating-element");
-            calcPage.changeSelectValue(pve, 3);
+            await changeSelectValue(pve, 3);
             await browser.sleep(300);
             // check absence of logs
             expect(await calcPage.nbLogEntries()).toBe(2);
diff --git a/e2e/preferences.po.ts b/e2e/preferences.po.ts
index 264ebb84f..51c1fc8de 100644
--- a/e2e/preferences.po.ts
+++ b/e2e/preferences.po.ts
@@ -1,4 +1,5 @@
 import { browser, by, element, ElementFinder } from "protractor";
+import { changeSelectValue } from "./util.po";
 
 export class PreferencesPage {
     navigateTo() {
@@ -43,10 +44,7 @@ export class PreferencesPage {
 
     async changeLanguage(index: number) {
         const select = this.getLanguageSelect();
-        await select.click();
-        const optionId = ".cdk-overlay-container mat-option#mat-option-" + index;
-        const option = element(by.css(optionId));
-        await option.click();
+        await changeSelectValue(select, index);
     }
 
     async enableEvilEmptyFields() {
diff --git a/e2e/pressure-loss-empty-fields.e2e-spec.ts b/e2e/pressure-loss-empty-fields.e2e-spec.ts
index c4516a88b..59eb87c64 100644
--- a/e2e/pressure-loss-empty-fields.e2e-spec.ts
+++ b/e2e/pressure-loss-empty-fields.e2e-spec.ts
@@ -3,6 +3,7 @@ import { Navbar } from "./navbar.po";
 import { browser } from "protractor";
 import { CalculatorPage } from "./calculator.po";
 import { PreferencesPage } from "./preferences.po";
+import { changeSelectValue } from "./util.po";
 
 describe("Check fields are empty in 'pressure loss' calculator when created with 'empty fields' option -", () => {
     let listPage: ListPage;
@@ -32,7 +33,7 @@ describe("Check fields are empty in 'pressure loss' calculator when created with
 
         // select Lechapt-Calmon pressure loss law
         const materialSelect = calcPage.getSelectById("select_pressurelosstype");
-        await calcPage.changeSelectValue(materialSelect, 0);
+        await changeSelectValue(materialSelect, 0);
         await browser.sleep(200);
 
         expect(calcPage.checkEmptyOrFilledFields(["Q", "D", "Lg", "Kloc"], [true, true, true, true]));
diff --git a/e2e/remous.e2e-spec.ts b/e2e/remous.e2e-spec.ts
index d13ccd48b..342d35edb 100644
--- a/e2e/remous.e2e-spec.ts
+++ b/e2e/remous.e2e-spec.ts
@@ -4,6 +4,7 @@ import { browser } from "protractor";
 import { Navbar } from "./navbar.po";
 import { PreferencesPage } from "./preferences.po";
 import { SideNav } from "./sidenav.po";
+import { changeSelectValue } from "./util.po";
 
 /**
  * Remous
@@ -59,7 +60,7 @@ describe("ngHyd − remous", () => {
         await browser.sleep(300);
 
         // 2. Set to trapezoidal section with bank slope of 2m/m and 20 meter width bed
-        await calcPage.changeSelectValue(calcPage.getSelectById("select_section"), 2);
+        await changeSelectValue(calcPage.getSelectById("select_section"), 2);
         await browser.sleep(300);
         await calcPage.getInputById("LargeurFond").clear();
         await browser.sleep(300);
diff --git a/e2e/solveur.e2e-spec.ts b/e2e/solveur.e2e-spec.ts
index 89ca70d6e..afe88721e 100644
--- a/e2e/solveur.e2e-spec.ts
+++ b/e2e/solveur.e2e-spec.ts
@@ -5,7 +5,7 @@ import { Navbar } from "./navbar.po";
 import { browser, by, element } from "protractor";
 import { SideNav } from "./sidenav.po";
 import { PreferencesPage } from "./preferences.po";
-import { scrollPageToTop } from "./util.po";
+import { changeSelectValue, scrollPageToTop } from "./util.po";
 
 /**
  * Clone calculators
@@ -76,7 +76,7 @@ describe("Solveur - ", () => {
         expect(hasResults).toBe(true);
 
         // change targetted Nub, check that targetted result changes too
-        await calcPage.changeSelectValue(ntc, 0);
+        await changeSelectValue(ntc, 0);
         const nttV2 = await calcPage.getSelectValueText(ntt);
         expect(nttV2).not.toContain("Puissance dissipée (PV)");
     });
@@ -111,9 +111,9 @@ describe("Solveur - ", () => {
         // Go back to Solveur
         await navbar.clickCalculatorTab(0);
 
-        await calcPage.changeSelectValue(calcPage.getSelectById("select_target_nub"), 1); // "Puissance / PV"
+        await changeSelectValue(calcPage.getSelectById("select_target_nub"), 1); // "Puissance / PV"
         await browser.sleep(500);
-        await calcPage.changeSelectValue(calcPage.getSelectById("select_searched_param"), 2); // "Chute / Z2"
+        await changeSelectValue(calcPage.getSelectById("select_searched_param"), 2); // "Chute / Z2"
         await browser.sleep(500);
         await calcPage.getInputById("Ytarget").sendKeys("318");
 
@@ -159,7 +159,7 @@ describe("Solveur - ", () => {
 
         // modify searched parameter
         const sel = calcPage.getSelectById("select_searched_param");
-        await calcPage.changeSelectValue(sel, 11);
+        await changeSelectValue(sel, 11);
         await browser.sleep(300);
         const selText = await calcPage.getSelectValueText(sel);
 
diff --git a/e2e/util.po.ts b/e2e/util.po.ts
index e772a28ce..aded71c16 100644
--- a/e2e/util.po.ts
+++ b/e2e/util.po.ts
@@ -1,4 +1,4 @@
-import { ElementFinder, browser } from "protractor";
+import { ElementFinder, browser, by, element } from "protractor";
 
 /**
  * scroll page to make element visible
@@ -27,3 +27,11 @@ export function expectNumber(msg: string, val: number, expected: number) {
     }
     expect(val).toEqual(expected);
 }
+
+export async function changeSelectValue(elt: ElementFinder, index: number) {
+    await elt.click();
+    const optionId = ".cdk-overlay-container mat-option:nth-of-type(" + (index + 1) + ")";
+    const option = element(by.css(optionId));
+    await option.click();
+    await browser.sleep(200);
+}
-- 
GitLab


From e7bec0d51002da010c36047bfdd0ac919cd6ba9e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Wed, 15 Feb 2023 09:39:11 +0100
Subject: [PATCH 2/8] test(e2e): check that changing language setting changes
 labels in results

refs #586
---
 e2e/preferences.po.ts       | 17 +++++++
 e2e/translation.e2e-spec.ts | 97 +++++++++++++++++++++++++++++++++++++
 2 files changed, 114 insertions(+)
 create mode 100644 e2e/translation.e2e-spec.ts

diff --git a/e2e/preferences.po.ts b/e2e/preferences.po.ts
index 51c1fc8de..39604b8cb 100644
--- a/e2e/preferences.po.ts
+++ b/e2e/preferences.po.ts
@@ -63,6 +63,23 @@ export class PreferencesPage {
         }
     }
 
+    /**
+     * enable/disable option "empty fields on module creation"
+     * @param b true to enable "empty fields on module creation" option, false to disable it (fill fields with default values)
+     */
+    async setEmptyFields(b: boolean) {
+        await this.navigateTo();
+        await browser.sleep(200);
+
+        if (b) {
+            await this.enableEvilEmptyFields();
+        }
+        else {
+            await this.disableEvilEmptyFields();
+        }
+        await browser.sleep(200);
+    }
+
     async setIterationCount(n: number) {
         const input = this.getInputFromName("nmi");
         input.clear();
diff --git a/e2e/translation.e2e-spec.ts b/e2e/translation.e2e-spec.ts
new file mode 100644
index 000000000..b0118eac9
--- /dev/null
+++ b/e2e/translation.e2e-spec.ts
@@ -0,0 +1,97 @@
+import { ListPage } from "./list.po";
+import { Navbar } from "./navbar.po";
+import { browser, by } from "protractor";
+import { CalculatorPage } from "./calculator.po";
+import { PreferencesPage } from "./preferences.po";
+import { SideNav } from "./sidenav.po";
+
+describe("Check translation", () => {
+    let listPage: ListPage;
+    let navBar: Navbar;
+    let calcPage: CalculatorPage;
+    let prefPage: PreferencesPage;
+    let sideNav: SideNav;
+
+    beforeAll(async () => {
+        listPage = new ListPage();
+        navBar = new Navbar();
+        calcPage = new CalculatorPage();
+        prefPage = new PreferencesPage();
+        sideNav = new SideNav();
+    });
+
+    beforeEach(async () => {
+        prefPage.setEmptyFields(false);
+    });
+
+    it("variables in results", async () => {
+        // *** results in french ***
+
+        prefPage.changeLanguage(1); // fr
+        await browser.sleep(200);
+
+        // open "fish ladder: fall" calculator
+        await navBar.clickNewCalculatorButton();
+        await listPage.clickMenuEntryForCalcType(12);
+        await browser.sleep(200);
+
+        // set Z2 to variated mode
+        const inpZ2 = calcPage.getInputById("Z2");
+        await calcPage.setParamMode(inpZ2, "var");
+
+        // run calculation
+        await calcPage.getCalculateButton().click();
+        await browser.sleep(500);
+
+        // "variable for X axis" select label
+        const selXaxis = calcPage.getSelectById("selectX");
+        expect(await calcPage.getMatselectCurrentOptionText(selXaxis)).toEqual("Cote aval");
+
+        // "variable for Y axis" select label
+        const selYaxis = calcPage.getSelectById("selectY");
+        expect(await calcPage.getMatselectCurrentOptionText(selYaxis)).toEqual("DH : Chute (m)");
+
+        // fixed results variables
+        const frr = calcPage.getAllFixedResultsRows();
+        let lbl1 = await frr.all(by.css("td")).get(0).getText();
+        expect(lbl1).toEqual("Cote amont (m)");
+
+        // variated results headers
+        const vrh = calcPage.getAllVariatedResultsTableHeaders();
+        let lbl2 = await vrh.get(0).getText();
+        expect(lbl2).toEqual("Cote aval");
+        let lbl3 = await vrh.get(1).getText();
+        expect(lbl3).toEqual("Chute (m)");
+
+        // *** results in english ***
+
+        // setup -> english
+        await navBar.clickMenuButton();
+        await browser.sleep(200);
+        const setupBtn = await sideNav.getSetupButton();
+        await setupBtn.click();
+        await browser.sleep(200);
+        await prefPage.changeLanguage(0); // en
+        await browser.sleep(200);
+
+        // back to calculator
+        await navBar.clickCalculatorTab(0);
+        await browser.sleep(200);
+
+        // "variable for X axis" select label
+        expect(await calcPage.getMatselectCurrentOptionText(selXaxis)).toEqual("Downstream elevation");
+
+        // "variable for Y axis" select label
+        expect(await calcPage.getMatselectCurrentOptionText(selYaxis)).toEqual("DH : Fall (m)");
+
+        // fixed results variables
+        lbl1 = await frr.all(by.css("td")).get(0).getText();
+        expect(lbl1).toEqual("Upstream elevation (m)");
+
+        // variated results headers
+        lbl2 = await vrh.get(0).getText();
+        expect(lbl2).toEqual("Downstream elevation");
+        lbl3 = await vrh.get(1).getText();
+        expect(lbl3).toEqual("Fall (m)");
+    });
+});
-- 
GitLab


From 3d5312616777b5333d9f8eb8908c086ea999c418 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Wed, 15 Feb 2023 16:40:45 +0100
Subject: [PATCH 3/8] refactor: remove useless code

refs #586
---
 .../definition/form-section-parametree.ts     |  4 ---
 src/app/formulaire/definition/form-section.ts |  5 ----
 src/app/formulaire/elements/fieldset.ts       | 30 -------------------
 3 files changed, 39 deletions(-)

diff --git a/src/app/formulaire/definition/form-section-parametree.ts b/src/app/formulaire/definition/form-section-parametree.ts
index 7f91f2fca..7ddfdefaf 100644
--- a/src/app/formulaire/definition/form-section-parametree.ts
+++ b/src/app/formulaire/definition/form-section-parametree.ts
@@ -23,10 +23,6 @@ export class FormulaireSectionParametree extends FormulaireSection {
         this.reaffectResultComponents();
     }
 
-    protected runNubCalc(nub: Nub, computedParam?: ParamDefinition): Result {
-        return nub.CalcSerie();
-    }
-
     protected reaffectResultComponents() {
         this.resetFormResults(); // to avoid adding fixed parameters more than once (see below)
         const sectNub: SectionParametree = this.currentNub as SectionParametree;
diff --git a/src/app/formulaire/definition/form-section.ts b/src/app/formulaire/definition/form-section.ts
index bf06c16b2..3a6906d1a 100644
--- a/src/app/formulaire/definition/form-section.ts
+++ b/src/app/formulaire/definition/form-section.ts
@@ -47,11 +47,6 @@ export class FormulaireSection extends FormulaireFixedVar {
             const newSect = Session.getInstance().createSection(data.value);
             (this._currentNub as SectionNub).setSection(newSect);
             // reflect changes in GUI
-            for (const fs of this.allFieldsets) {
-                // show / hide dependent fields
-                fs.updateFields();
-            }
-            // show / hide dependent fields
             this.refreshFieldsets();
             this.reset();
         }
diff --git a/src/app/formulaire/elements/fieldset.ts b/src/app/formulaire/elements/fieldset.ts
index c1678a93b..a705ab392 100644
--- a/src/app/formulaire/elements/fieldset.ts
+++ b/src/app/formulaire/elements/fieldset.ts
@@ -38,7 +38,6 @@ export class FieldSet extends FormulaireElement implements IProperties {
 
     public setNub(sn: Nub, update: boolean = true) {
         this._nub = sn;
-        this.setParentNubForAllFields();
         if (update) {
             this.updateFields();
         }
@@ -135,9 +134,6 @@ export class FieldSet extends FormulaireElement implements IProperties {
         return this._jsonConfig;
     }
 
-    private setParentNubForAllFields() {
-    }
-
     /**
      * crée un input
      * @param json definition de l'input, extrait du fichier de conf du module de calcul
@@ -280,32 +276,6 @@ export class FieldSet extends FormulaireElement implements IProperties {
         }
     }
 
-    public getNodeParameter(symbol: string): NgParameter {
-        for (const p of this.kids) {
-            if (p instanceof NgParameter) {
-                if (p.isDisplayed && p.symbol === symbol) {
-                    return p;
-                }
-            }
-        }
-    }
-
-    public getNodeParameterValue(symbol: string): number {
-        const p = this.getNodeParameter(symbol);
-        if (!p) {
-            throw new Error(`FieldSet.getNodeParameterValue() : pas de paramètre ${symbol} trouvé`);
-        }
-
-        switch (p.radioState) {
-            case ParamRadioConfig.FIX:
-                return p.getValue();
-
-            case ParamRadioConfig.VAR:
-            case ParamRadioConfig.CAL:
-                return undefined;
-        }
-    }
-
     /**
      * retourne la valeur actuellement sélectionnée d'un SelectField (qui doit être affiché)
      * @param selectFieldId id du SelectField
-- 
GitLab


From 90ff0a177a315b514d447eb27ca0384c71cc896a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Wed, 15 Feb 2023 16:44:56 +0100
Subject: [PATCH 4/8] refactor: rename
 FormulaireDefinition.getParamFromSymbol() to getNgparamFromNubParam()

refs #586
---
 src/app/formulaire/definition/form-definition.ts | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 9acb17e78..eec033312 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -346,11 +346,10 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
     }
 
     /**
-     * Trouve le Ngparameter correspondant au symbole "symbol", parmi tous les
-     * éléments du formulaire
-     * @param symbol string
+     * Trouve le NgParameter correspondant au paramètre Nub parmi tous les éléments du formulaire
+     * @param param paramètre critère de recherche
      */
-    public getParamFromSymbol(param: ParamDefinition): NgParameter {
+    private getNgparamFromNubParam(param: ParamDefinition): NgParameter {
         for (const p of this.allFormElements) {
             if (p instanceof NgParameter) {
                 if (p.symbol === param.symbol && p.paramDefinition.parentNub.uid === param.parentNub.uid) {
@@ -552,7 +551,7 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
         const fixedParams: ParamDefinition[] = this._currentNub.findFixedParams();
         let fnp: NgParameter[] = [];
         for (const fp of fixedParams) {
-            fnp.push(this.getParamFromSymbol(fp));
+            fnp.push(this.getNgparamFromNubParam(fp));
         }
         fnp = fnp.filter((e) => e !== undefined);
         return fnp;
-- 
GitLab


From 32ae1dfce014403b9fff84935c58905c9e646d15 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Wed, 15 Feb 2023 16:48:29 +0100
Subject: [PATCH 5/8] refactor: avoid NgParameter duplication

refs #586
---
 .../calculator.component.ts                   |  2 +-
 .../formulaire/definition/form-definition.ts  | 16 ++++++----
 .../formulaire/definition/form-fixedvar.ts    |  9 +++---
 .../definition/form-macrorugo-compound.ts     |  2 +-
 .../formulaire/definition/form-prebarrage.ts  |  2 +-
 .../definition/form-pressureloss.ts           | 27 ++++++++++-------
 src/app/formulaire/definition/form-section.ts |  2 +-
 src/app/formulaire/definition/form-solveur.ts |  2 +-
 src/app/formulaire/elements/fieldset.ts       | 29 ++++++++++++++-----
 9 files changed, 57 insertions(+), 34 deletions(-)

diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index 49e81d946..46a03da75 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -1259,7 +1259,7 @@ export class GenericCalculatorComponent implements OnInit, DoCheck, AfterViewChe
                 const form = this._formulaire as FormulaireFixedVar;
                 const nub = (form.currentNub as Espece);
                 nub.loadPredefinedSpecies(result.selected);
-                form.refreshFieldsets();
+                form.refreshFieldsets(false);
             }
         });
     }
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index eec033312..c6b05ea1b 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -359,6 +359,14 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
         }
     }
 
+    public getOrCreateParam(nubParam: ParamDefinition, parent: FormulaireNode): NgParameter {
+        const res = this.getNgparamFromNubParam(nubParam);
+        if (res === undefined) {
+            return new NgParameter(nubParam, parent);
+        }
+        return res;
+    }
+
     public getFieldById(id: string): Field {
         const res = this.getFormulaireNodeById(id);
         if (res instanceof Field) {
@@ -531,14 +539,10 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
 
     protected getComputedParameter(): NgParameter {
         const cpd = this.currentNub.calculatedParam;
-        let ngparam: NgParameter;
         if (cpd !== undefined) {
-            ngparam = this.getParamFromSymbol(cpd);
-            if (ngparam === undefined) { // calculated parameter is not displayed on screen
-                ngparam = new NgParameter(cpd, this);
-            }
+            return this.getOrCreateParam(cpd, this);
         }
-        return ngparam;
+        return undefined;
     }
 
     /** find variated (possibly linked) parameters from model, and get their values at the same time */
diff --git a/src/app/formulaire/definition/form-fixedvar.ts b/src/app/formulaire/definition/form-fixedvar.ts
index 8eb6917e7..f20ce41fe 100644
--- a/src/app/formulaire/definition/form-fixedvar.ts
+++ b/src/app/formulaire/definition/form-fixedvar.ts
@@ -82,8 +82,7 @@ export class FormulaireFixedVar extends FormulaireDefinition {
 
     protected compute() {
         this.runNubCalc(this.currentNub);
-        this.refreshFieldsets(); // important: before reaffectResultComponents() or it will break results components localization
-        // this.reaffectResultComponents();  // seems useless since called from runNubCalc()
+        this.reaffectResultComponents();
     }
 
     protected reaffectResultComponents() {
@@ -115,9 +114,9 @@ export class FormulaireFixedVar extends FormulaireDefinition {
     /**
      * Forces all fieldsets to update all their fields
      */
-    public refreshFieldsets() {
+    public refreshFieldsets(forceClear: boolean) {
         for (const fs of this.allFieldsets) {
-            fs.updateFields();
+            fs.updateFields(forceClear);
         }
         this.completeParse(false); // re-add observers that were destroyed by updateFields()
     }
@@ -130,7 +129,7 @@ export class FormulaireFixedVar extends FormulaireDefinition {
         if (data.action === "propertyChange") {
             this.reset();
             // reflect changes in GUI (who knows ?), for ex. show / hide dependent fields
-            this.refreshFieldsets();
+            this.refreshFieldsets(true);
         }
     }
 }
diff --git a/src/app/formulaire/definition/form-macrorugo-compound.ts b/src/app/formulaire/definition/form-macrorugo-compound.ts
index 306332cb5..5dd33e865 100644
--- a/src/app/formulaire/definition/form-macrorugo-compound.ts
+++ b/src/app/formulaire/definition/form-macrorugo-compound.ts
@@ -84,7 +84,7 @@ export class FormulaireMacrorugoCompound extends FormulaireRepeatableFieldset {
      */
     public updateApronState(inclined: MRCInclination) {
         // show / hide dependent fields (read from model)
-        this.refreshFieldsets();
+        this.refreshFieldsets(false);
         // show / hide children list (GUI only)
         for (const elt of this.allFormElements) {
             if (elt instanceof FieldsetContainer) {
diff --git a/src/app/formulaire/definition/form-prebarrage.ts b/src/app/formulaire/definition/form-prebarrage.ts
index c9a0d9e0d..09a2b1570 100644
--- a/src/app/formulaire/definition/form-prebarrage.ts
+++ b/src/app/formulaire/definition/form-prebarrage.ts
@@ -239,7 +239,7 @@ export class FormulairePrebarrage extends FormulaireFixedVar {
 
     protected compute() {
         this.runNubCalc(this.currentNub);
-        this.refreshFieldsets(); // important: before reaffectResultComponents() or it will break results components localization
+        this.refreshFieldsets(false); // important: before reaffectResultComponents() or it will break results components localization
         // reset variable index to avoid trying to access an index > 0 when nothing varies
         this._pbResults.variableIndex = 0;
 
diff --git a/src/app/formulaire/definition/form-pressureloss.ts b/src/app/formulaire/definition/form-pressureloss.ts
index 26c862355..9260bc79a 100644
--- a/src/app/formulaire/definition/form-pressureloss.ts
+++ b/src/app/formulaire/definition/form-pressureloss.ts
@@ -36,16 +36,23 @@ export class FormulairePressureLoss extends FormulaireFixedVar {
     }
 
     public update(sender: IObservable, data: any) {
-        // changement de propriété du FieldSet contenant le select de choix du type de perte de charge
-        if (sender instanceof FieldSet && sender.id === "fs_pressureloss_law" && data.action === "propertyChange") {
-            // replace underlying pressure loss law without replacing whole Nub
-            const newPLL = Session.getInstance().createPressureLossLaw(data.value, undefined, this.currentNub.getPropValue(Prop_NullParameters));
-            (this._currentNub as PressureLoss).setLaw(newPLL);
-            // show / hide dependent fields
-            this.refreshFieldsets();
-            this.reset();
+        // if (sender instanceof FieldSet && sender.id === "fs_pressureloss_law" && data.action === "propertyChange") {
+        if (data.action === "propertyChange") {
+            if (data.name === "pressurelosstype") {
+                // changement de propriété du FieldSet contenant le select de choix du type de perte de charge
+
+                // replace underlying pressure loss law without replacing whole Nub
+                const newPLL = Session.getInstance().createPressureLossLaw(data.value, undefined, this.currentNub.getPropValue(Prop_NullParameters));
+                (this._currentNub as PressureLoss).setLaw(newPLL);
+                // show / hide dependent fields
+                this.refreshFieldsets(true);
+                this.reset();
+            }
+            else if (data.name === "material") {
+                // changement de propriété du FieldSet contenant le select de choix du type de matériau
+                this.refreshFieldsets(false);
+                this.reset();
+            }
         }
-        else
-            super.update(sender, data);
     }
 }
diff --git a/src/app/formulaire/definition/form-section.ts b/src/app/formulaire/definition/form-section.ts
index 3a6906d1a..d2aa08b33 100644
--- a/src/app/formulaire/definition/form-section.ts
+++ b/src/app/formulaire/definition/form-section.ts
@@ -47,7 +47,7 @@ export class FormulaireSection extends FormulaireFixedVar {
             const newSect = Session.getInstance().createSection(data.value);
             (this._currentNub as SectionNub).setSection(newSect);
             // reflect changes in GUI
-            this.refreshFieldsets();
+            this.refreshFieldsets(true);
             this.reset();
         }
     }
diff --git a/src/app/formulaire/definition/form-solveur.ts b/src/app/formulaire/definition/form-solveur.ts
index 0a3d446ef..ce7be1797 100644
--- a/src/app/formulaire/definition/form-solveur.ts
+++ b/src/app/formulaire/definition/form-solveur.ts
@@ -63,7 +63,7 @@ export class FormulaireSolveur extends FormulaireFixedVar {
                 // refresh targetted result selector
                 const trSel = this.getFormulaireNodeById(this._targettedResultSelectId) as SelectField;
                 if (trSel) {
-                    (trSel.parent as FieldSet).updateFields();
+                    (trSel.parent as FieldSet).updateFields(true);
                     // trick to re-set observers
                     this.completeParse(false);
                 }
diff --git a/src/app/formulaire/elements/fieldset.ts b/src/app/formulaire/elements/fieldset.ts
index a705ab392..7b709eb76 100644
--- a/src/app/formulaire/elements/fieldset.ts
+++ b/src/app/formulaire/elements/fieldset.ts
@@ -10,7 +10,7 @@ import {
 import { FormulaireElement } from "./formulaire-element";
 import { Field } from "./field";
 import { SelectField } from "./select/select-field";
-import { NgParameter, ParamRadioConfig } from "./ngparam";
+import { NgParameter } from "./ngparam";
 import { FieldsetContainer } from "./fieldset-container";
 import { SelectFieldFactory } from "./select/select-field-factory";
 import { FormulaireFixedVar } from "../definition/form-fixedvar";
@@ -39,7 +39,7 @@ export class FieldSet extends FormulaireElement implements IProperties {
     public setNub(sn: Nub, update: boolean = true) {
         this._nub = sn;
         if (update) {
-            this.updateFields();
+            this.updateFields(true);
         }
     }
 
@@ -47,7 +47,9 @@ export class FieldSet extends FormulaireElement implements IProperties {
         if (!f) {
             throw new Error("FieldSet.addField() : argument incorrect (undefined)");
         }
-        this.kids.push(f);
+        if (this.kids.indexOf(f) === -1) {
+            this.kids.push(f);
+        }
     }
 
     /**
@@ -105,6 +107,15 @@ export class FieldSet extends FormulaireElement implements IProperties {
         }
     }
 
+    private getOrCreateSelect(json: {}): SelectField {
+        const id: string = json["id"];
+        const res = this.getFormulaireNodeById(id);
+        if (res === undefined || !(res instanceof SelectField)) {
+            return SelectFieldFactory.newSelectField(json, this);
+        }
+        return res;
+    }
+
     private parse_select(json: {}): SelectField {
         let ok: boolean = true;
         // in case select is associated to a property, check nub has the property
@@ -113,7 +124,7 @@ export class FieldSet extends FormulaireElement implements IProperties {
             ok = this.parentForm.getPropValue(p) !== undefined;
         }
         if (ok) {
-            const res: SelectField = SelectFieldFactory.newSelectField(json, this);
+            const res: SelectField = this.getOrCreateSelect(json);
             res.parseConfig(json);
             res.afterParseConfig();
             res.addObserver(this);
@@ -147,7 +158,7 @@ export class FieldSet extends FormulaireElement implements IProperties {
         try {
             nubParam = this.getNubParamFromSymbol(input_id);
             if (nubParam.visible) {
-                res = new NgParameter(nubParam, this);
+                res = this.parentForm.getOrCreateParam(nubParam, this);
                 res.parseConfig(json);
             }
         } catch (e) {
@@ -157,8 +168,6 @@ export class FieldSet extends FormulaireElement implements IProperties {
     }
 
     private parseFields() {
-        // clear everything so that parseFields() is idempotent
-        this.clearFields();
         // parse children fields from config
         const fields = this._jsonConfig["fields"];
         for (const field_index in fields) {
@@ -203,7 +212,10 @@ export class FieldSet extends FormulaireElement implements IProperties {
     /**
      * Reloads the model values and properties, and reloads localisation strings
      */
-    public updateFields() {
+    public updateFields(forceClear: boolean) {
+        if (forceClear) {
+            this.clearFields();
+        }
         this.parseFields();
         this.updateLocalisation();
 
@@ -257,6 +269,7 @@ export class FieldSet extends FormulaireElement implements IProperties {
 
         // parse fields once, so that SelectField elements are present
         // when setting default properties below
+        this.clearFields();
         this.parseFields();
 
         // for all select fields known by the form, apply default value
-- 
GitLab


From 73dedf3ef575ce008678aaa04be30f0acf4dbac6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Wed, 15 Feb 2023 17:22:06 +0100
Subject: [PATCH 6/8] fix: variated results headers translation update after
 langage setting modification

refs #586
---
 .../fixedvar-results/var-results.component.ts   | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/src/app/components/fixedvar-results/var-results.component.ts b/src/app/components/fixedvar-results/var-results.component.ts
index 7493401d2..3ba2053f5 100644
--- a/src/app/components/fixedvar-results/var-results.component.ts
+++ b/src/app/components/fixedvar-results/var-results.component.ts
@@ -3,7 +3,7 @@ import { Component, ViewChild, ElementRef, Input } from "@angular/core";
 import { MatDialog } from "@angular/material/dialog";
 
 import { VarResults } from "../../results/var-results";
-import { ResultElement, Message, MessageSeverity } from "jalhyd";
+import { ResultElement, Message, MessageSeverity, Observer } from "jalhyd";
 import { I18nService } from "../../services/internationalisation.service";
 import { ResultsComponentDirective } from "./results.component";
 import { DialogLogEntriesDetailsComponent } from "../dialog-log-entries-details/dialog-log-entries-details.component";
@@ -17,7 +17,7 @@ import { longestVarParam } from "../../../app/util";
         "./var-results.component.scss"
     ]
 })
-export class VarResultsComponent extends ResultsComponentDirective {
+export class VarResultsComponent extends ResultsComponentDirective implements Observer {
 
     /** size of the longest variated parameter */
     public size: number;
@@ -42,12 +42,17 @@ export class VarResultsComponent extends ResultsComponentDirective {
         protected logEntriesDetailsDialog: MatDialog
     ) {
         super();
+        this.intlService.addObserver(this);
     }
 
     /** Refreshes results and builds the dataset */
     @Input()
     public set results(r: VarResults) {
         this._varResults = r;
+        this.updateResults();
+    }
+
+    private updateResults() {
         this._results = [];
         this._headers = [];
         this._messages = [];
@@ -190,4 +195,12 @@ export class VarResultsComponent extends ResultsComponentDirective {
             }
         );
     }
+
+    // Observer interface
+
+    update(sender: any, data: any): void {
+        if (sender instanceof I18nService) {
+            this._varResults.update();
+        }
+    }
 }
-- 
GitLab


From 50b72f15f8fc9404455855fb3b8a218f77f3f405 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Thu, 16 Feb 2023 09:48:32 +0100
Subject: [PATCH 7/8] fix: variable results graph: select entries not
 translated when modifying langage setting

refs #586
---
 .../fixedvar-results/var-results.component.ts    |  8 ++++++--
 src/app/results/param-calc-results.ts            | 16 +++++++++++++---
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/src/app/components/fixedvar-results/var-results.component.ts b/src/app/components/fixedvar-results/var-results.component.ts
index 3ba2053f5..f6204377d 100644
--- a/src/app/components/fixedvar-results/var-results.component.ts
+++ b/src/app/components/fixedvar-results/var-results.component.ts
@@ -1,4 +1,4 @@
-import { Component, ViewChild, ElementRef, Input } from "@angular/core";
+import { Component, ViewChild, ElementRef, Input, OnInit } from "@angular/core";
 
 import { MatDialog } from "@angular/material/dialog";
 
@@ -17,7 +17,7 @@ import { longestVarParam } from "../../../app/util";
         "./var-results.component.scss"
     ]
 })
-export class VarResultsComponent extends ResultsComponentDirective implements Observer {
+export class VarResultsComponent extends ResultsComponentDirective implements Observer, OnInit {
 
     /** size of the longest variated parameter */
     public size: number;
@@ -196,6 +196,10 @@ export class VarResultsComponent extends ResultsComponentDirective implements Ob
         );
     }
 
+    ngOnInit(): void {
+        this._varResults.updateCalculatedParameterHeader();
+    }
+
     // Observer interface
 
     update(sender: any, data: any): void {
diff --git a/src/app/results/param-calc-results.ts b/src/app/results/param-calc-results.ts
index eaca087d3..9e22d98b4 100644
--- a/src/app/results/param-calc-results.ts
+++ b/src/app/results/param-calc-results.ts
@@ -12,7 +12,7 @@ export abstract class CalculatedParamResults extends CalculatorResults {
     protected _calculatedParam: NgParameter;
 
     /** titre de la colonne du paramètre calculé */
-    public calculatedParameterHeader: string;
+    private _calculatedParameterHeader: string;
 
     /** résultat du calcul sur le paramètre calculé */
     public result: Result;
@@ -22,7 +22,7 @@ export abstract class CalculatedParamResults extends CalculatorResults {
 
     public reset() {
         this._calculatedParam = undefined;
-        this.calculatedParameterHeader = undefined;
+        this._calculatedParameterHeader = undefined;
         this.result = undefined;
     }
 
@@ -32,7 +32,17 @@ export abstract class CalculatedParamResults extends CalculatorResults {
 
     public set calculatedParameter(p: NgParameter) {
         this._calculatedParam = p;
-        this.calculatedParameterHeader = CalculatorResults.paramLabel(this._calculatedParam, true);
+        this.updateCalculatedParameterHeader();
+    }
+
+    public updateCalculatedParameterHeader() {
+        if (this._calculatedParam !== undefined) {
+            this._calculatedParameterHeader = CalculatorResults.paramLabel(this._calculatedParam, true);
+        }
+    }
+
+    public get calculatedParameterHeader(): string {
+        return this._calculatedParameterHeader;
     }
 
     public get hasResults(): boolean {
-- 
GitLab


From 0ab34d388e87c56b9f3005877f4deea6275c6ea8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Thu, 16 Feb 2023 10:29:00 +0100
Subject: [PATCH 8/8] fix: variated results graph: axis Y label not translated
 when changing langage setting

refs #586
---
 src/app/components/results-chart/results-chart.component.ts | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/app/components/results-chart/results-chart.component.ts b/src/app/components/results-chart/results-chart.component.ts
index 0b33967f3..0bb985913 100644
--- a/src/app/components/results-chart/results-chart.component.ts
+++ b/src/app/components/results-chart/results-chart.component.ts
@@ -182,6 +182,10 @@ export class ResultsChartComponent extends ResultsComponentDirective implements
     }
 
     public ngOnChanges() {
+        if (this._results instanceof VarResults) {
+            this._results.updateCalculatedParameterHeader();
+        }
+
         // redessiner le graphique chaque fois qu'une entrée change
         this.drawChart();
     }
-- 
GitLab