From f879f563084fca85efac424100fc448f83c913a0 Mon Sep 17 00:00:00 2001
From: "mathias.chouet" <mathias.chouet@irstea.fr>
Date: Mon, 14 Oct 2019 17:34:58 +0200
Subject: [PATCH] Progress on Solveur GUI

---
 .../calculators/solveur/solveur.config.json   | 32 +++++++++++
 src/app/calculators/solveur/solveur.en.json   | 10 ++++
 src/app/calculators/solveur/solveur.fr.json   | 10 ++++
 .../definition/concrete/form-solveur.ts       | 53 +++++++++++++++++++
 src/app/formulaire/fieldset.ts                | 21 ++++++++
 src/app/formulaire/select-field.ts            | 25 ++++++++-
 src/app/services/formulaire.service.ts        |  6 +++
 src/locale/messages.en.json                   |  2 +
 src/locale/messages.fr.json                   |  2 +
 9 files changed, 160 insertions(+), 1 deletion(-)
 create mode 100644 src/app/calculators/solveur/solveur.config.json
 create mode 100644 src/app/calculators/solveur/solveur.en.json
 create mode 100644 src/app/calculators/solveur/solveur.fr.json
 create mode 100644 src/app/formulaire/definition/concrete/form-solveur.ts

diff --git a/src/app/calculators/solveur/solveur.config.json b/src/app/calculators/solveur/solveur.config.json
new file mode 100644
index 000000000..7e6ac3bbd
--- /dev/null
+++ b/src/app/calculators/solveur/solveur.config.json
@@ -0,0 +1,32 @@
+[
+    {
+        "id": "fs_target",
+        "type": "fieldset",
+        "fields": [
+            {
+                "id": "select_target_nub",
+                "type": "select",
+                "source": "solveur_target"
+            },
+            "Ytarget"
+        ]
+    },
+    {
+        "id": "fs_searched",
+        "type": "fieldset",
+        "fields": [
+            {
+                "id": "select_searched_param",
+                "type": "select",
+                "source": "solveur_searched"
+            },
+            "Xinit"
+        ]
+    },
+    {
+        "type": "options",
+        "targetNubSelectId": "select_target_nub",
+        "searchedParamSelectId": "select_searched_param",
+        "_help": "solveur.html"
+    }
+]
\ No newline at end of file
diff --git a/src/app/calculators/solveur/solveur.en.json b/src/app/calculators/solveur/solveur.en.json
new file mode 100644
index 000000000..cbf67bcf2
--- /dev/null
+++ b/src/app/calculators/solveur/solveur.en.json
@@ -0,0 +1,10 @@
+{
+    "fs_target": "Target parameter characteristics",
+    "fs_searched": "Searched parameter characteristics",
+
+    "Ytarget": "Value of target parameter",
+    "Xinit": "Initial value for searched parameter",
+
+    "select_target_nub": "Module and parameter to calculate",
+    "select_searched_param": "Searched parameter"
+}
\ No newline at end of file
diff --git a/src/app/calculators/solveur/solveur.fr.json b/src/app/calculators/solveur/solveur.fr.json
new file mode 100644
index 000000000..86899fc0d
--- /dev/null
+++ b/src/app/calculators/solveur/solveur.fr.json
@@ -0,0 +1,10 @@
+{
+    "fs_target": "Caractéristiques du paramètre cible",
+    "fs_searched": "Caractéristiques du paramètre recherché",
+
+    "Ytarget": "Valeur du paramètre cible",
+    "Xinit": "Valeur initiale du paramètre recherché",
+
+    "select_target_nub": "Module et paramètre à calculer",
+    "select_searched_param": "Paramètre recherché"
+}
\ No newline at end of file
diff --git a/src/app/formulaire/definition/concrete/form-solveur.ts b/src/app/formulaire/definition/concrete/form-solveur.ts
new file mode 100644
index 000000000..09d2fe6ab
--- /dev/null
+++ b/src/app/formulaire/definition/concrete/form-solveur.ts
@@ -0,0 +1,53 @@
+import { IObservable } from "jalhyd";
+
+import { FormulaireBase } from "./form-base";
+import { FieldSet } from "../../fieldset";
+
+/**
+ * Formulaire pour les Solveurs
+ */
+export class FormulaireSolveur extends FormulaireBase {
+
+    /** id of select configuring target Nub */
+    private _targetNubSelectId: string;
+
+    /** id of select configuring searched param */
+    private _searchedParamSelectId: string;
+
+    protected parseOptions(json: {}) {
+        super.parseOptions(json);
+        this._targetNubSelectId = this.getOption(json, "targetNubSelectId");
+        this._searchedParamSelectId = this.getOption(json, "searchedParamSelectId");
+    }
+
+    public afterParseFieldset(fs: FieldSet) {
+        if (this._searchedParamSelectId) {
+            const sel = fs.getFormulaireNodeById(this._searchedParamSelectId);
+            if (sel) {
+                fs.properties.addObserver(this);
+            }
+        }
+        if (this._targetNubSelectId) {
+            const sel = fs.getFormulaireNodeById(this._targetNubSelectId);
+            if (sel) {
+                fs.properties.addObserver(this);
+            }
+        }
+    }
+
+    // interface Observer
+
+    public update(sender: IObservable, data: any) {
+        super.update(sender, data);
+        console.log("FormulaireSolveur().update", sender.constructor.name, data);
+        if (data.action === "propertyChange") {
+            if (data.name === "gridType") {
+                this.reset();
+                // Inclined grids have more input fields (OEntH and cIncl)
+                this.getFieldsetById("fs_grille").updateFields();
+                // Alpha and Beta are not always shown
+                this.getFieldsetById("fs_plan").updateFields();
+            }
+        }
+    }
+}
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index b5d4978c5..07c6d3be1 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -10,6 +10,7 @@ import {
     GrilleType,
     GrilleProfile,
     BiefRegime,
+    Solveur,
 } from "jalhyd";
 
 import { FormulaireElement } from "./formulaire-element";
@@ -258,6 +259,26 @@ export class FieldSet extends FormulaireElement implements Observer {
             case "fs_water_line": // Bief
                 this.setSelectValueFromProperty("select_regime", "regime");
                 break;
+
+            case "fs_target": // Solveur
+                this.setSelectValueFromProperty("select_target_nub", "nubToCalculate");
+                break;
+
+            case "fs_searched": // Solveur
+                const selectField: SelectField = this.getFormulaireNodeById("select_searched_param") as SelectField;
+                if (selectField) {
+                    const nub = this.parentForm.currentNub as Solveur;
+                    const X: ParamDefinition = nub.searchedParameter;
+                    if (X !== undefined) {
+                        const selectElement = selectField.getSelectedEntryFromValue(X);
+                        try {
+                            selectField.setValue(selectElement);
+                        } catch (e) {
+                            console.error(`fieldset.updateFields(): cannot set ${X.parentNub.uid}/${X.symbol} on <select> "select_searched_param"`);
+                        }
+                    }
+                }
+                break;
         }
     }
 
diff --git a/src/app/formulaire/select-field.ts b/src/app/formulaire/select-field.ts
index 308b319b0..065b09633 100644
--- a/src/app/formulaire/select-field.ts
+++ b/src/app/formulaire/select-field.ts
@@ -8,7 +8,10 @@ import {
     StructureType,
     LoiDebit,
     GrilleType,
-    GrilleProfile
+    GrilleProfile,
+    Solveur,
+    ParamValueMode,
+    Session
  } from "jalhyd";
 
 import { Field } from "./field";
@@ -188,6 +191,26 @@ export class SelectField extends Field {
                 this.addEntry(new SelectEntry(this._entriesBaseId + BiefRegime.Fluvial, BiefRegime.Fluvial));
                 this.addEntry(new SelectEntry(this._entriesBaseId + BiefRegime.Torrentiel, BiefRegime.Torrentiel));
                 break;
+
+            case "solveur_target": // Solveur, paramètre cible (à calculer)
+                // find all Nubs having at least one link to another Nub's result
+                console.log(">> update solveur targets");
+                const downstreamNubs = Session.getInstance().getDownstreamNubs();
+                for (const dn of downstreamNubs) {
+                    this.addEntry(new SelectEntry(this._entriesBaseId + dn.uid, dn.uid));
+                }
+                break;
+
+            case "solveur_searched": // Solveur, paramètre recherché (à faire varier)
+                // find all non-calculated, non-linked parameters of all Nubs that
+                // the current "target" Nub depends on (if any)
+                console.log(">> update solveur searched");
+                const ntc: Nub = (nub as Solveur).nubToCalculate;
+                const searchableParams = Solveur.getDependingNubsSearchableParams(ntc);
+                for (const p of searchableParams) {
+                    this.addEntry(new SelectEntry(this._entriesBaseId + p.nubUid + "_" + p.symbol, p));
+                }
+                break;
         }
     }
 }
diff --git a/src/app/services/formulaire.service.ts b/src/app/services/formulaire.service.ts
index 65a60d25b..025930609 100644
--- a/src/app/services/formulaire.service.ts
+++ b/src/app/services/formulaire.service.ts
@@ -39,6 +39,7 @@ import { FormulaireMacrorugoCompound } from "../formulaire/definition/concrete/f
 import { FormulaireLechaptCalmon } from "../formulaire/definition/concrete/form-lechapt-calmon";
 import { FormulaireGrille } from "../formulaire/definition/concrete/form-grille";
 import { FormulaireBief } from "../formulaire/definition/concrete/form-bief";
+import { FormulaireSolveur } from "../formulaire/definition/concrete/form-solveur";
 
 @Injectable()
 export class FormulaireService extends Observable {
@@ -84,6 +85,7 @@ export class FormulaireService extends Observable {
         this.calculatorPaths[CalculatorType.Grille] = "grille";
         this.calculatorPaths[CalculatorType.Pente] = "pente";
         this.calculatorPaths[CalculatorType.Bief] = "bief";
+        this.calculatorPaths[CalculatorType.Solveur] = "solveur";
     }
 
     private get _intlService(): I18nService {
@@ -329,6 +331,10 @@ export class FormulaireService extends Observable {
                 f = new FormulaireBief();
                 break;
 
+            case CalculatorType.Solveur:
+                f = new FormulaireSolveur();
+                break;
+
             default:
                 f = new FormulaireBase();
         }
diff --git a/src/locale/messages.en.json b/src/locale/messages.en.json
index 5a3e63c64..ad74567f5 100644
--- a/src/locale/messages.en.json
+++ b/src/locale/messages.en.json
@@ -431,6 +431,8 @@
     "INFO_SNACKBAR_RESULTS_CALCULATED": "Results calculated for",
     "INFO_SNACKBAR_RESULTS_INVALIDATED": "Results invalidated for",
     "INFO_SNACKBAR_SETTINGS_SAVED": "Settings saved on this device",
+    "INFO_SOLVEUR_TITRE": "Multimodule solver",
+    "INFO_SOLVEUR_TITRE_COURT": "Solver",
     "INFO_THEME_CREDITS": "Credit",
     "INFO_THEME_DEVALAISON_TITRE": "Downstream migration",
     "INFO_THEME_DEVALAISON_DESCRIPTION": "Tools for dimensioning the structures present on the water intakes of hydroelectric power plants known as \"ichthyocompatible\" and consisting of fine grid planes associated with one or more outlets.",
diff --git a/src/locale/messages.fr.json b/src/locale/messages.fr.json
index 523d6cd37..e93d09b95 100644
--- a/src/locale/messages.fr.json
+++ b/src/locale/messages.fr.json
@@ -430,6 +430,8 @@
     "INFO_SNACKBAR_RESULTS_CALCULATED": "Résultats calculés pour",
     "INFO_SNACKBAR_RESULTS_INVALIDATED": "Résultats invalidés pour",
     "INFO_SNACKBAR_SETTINGS_SAVED": "Paramètres enregistrés sur cet appareil",
+    "INFO_SOLVEUR_TITRE": "Solveur multimodule",
+    "INFO_SOLVEUR_TITRE_COURT": "Solveur",
     "INFO_THEME_CREDITS": "Crédit",
     "INFO_THEME_DEVALAISON_TITRE": "Dévalaison",
     "INFO_THEME_DEVALAISON_DESCRIPTION": "Outils de dimensionnements des ouvrages présents sur les prises d'eau des centrales hydroélectriques dites \"ichtyocompatibles\" et constituées de plans de grilles fines associés à un ou plusieurs exutoires.",
-- 
GitLab