From 78b48c74f6ff074d2c2dd9261045d9c64d3fda1d Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 29 Mar 2018 15:55:47 +0200
Subject: [PATCH 01/53] =?UTF-8?q?=20#77=20adaptation=20de=20la=20conduite?=
 =?UTF-8?q?=20distributrice=20=C3=A0=20la=20factory=20de=20Nub=20-=20fichi?=
 =?UTF-8?q?er=20de=20config=20de=20la=20calculette=20:=20suppression=20des?=
 =?UTF-8?q?=20valeurs=20de=20param=C3=A8tres,=20fournis=20maintenant=20par?=
 =?UTF-8?q?=20la=20factory=20dans=20la=20lib=20-=20FormulaireDefinition=20?=
 =?UTF-8?q?:=20ajout=20d'une=20m=C3=A9thode=20abstraite=20de=20cr=C3=A9ati?=
 =?UTF-8?q?on=20des=20Nub=20associ=C3=A9s=20=C3=A0=20un=20formulaire=20-?=
 =?UTF-8?q?=20FormCompute=20:=20getNubAndParameters()=20remplac=C3=A9e=20p?=
 =?UTF-8?q?ar=20getCurrentNub()=20-=20modif=20de=20l'analyse=20des=20fichi?=
 =?UTF-8?q?ers=20de=20configuration=20des=20calculettes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../cond_distri/cond_distri.config.json       |  15 +--
 .../definition/concrete/form-cond-distri.ts   |   6 +-
 .../definition/concrete/form-courbe-remous.ts |   3 +
 .../concrete/form-lechapt-calmon.ts           |   3 +
 .../concrete/form-parallel-structures.ts      |   3 +
 .../concrete/form-passe-bassin-dim.ts         |   3 +
 .../concrete/form-passe-bassin-puissance.ts   |   3 +
 .../concrete/form-regime-uniforme.ts          |   3 +
 .../concrete/form-section-parametree.ts       |   3 +
 .../definition/form-compute-cond-distri.ts    |  13 +-
 .../definition/form-compute-courbe-remous.ts  |   4 +
 .../definition/form-compute-fixedvar.ts       |   8 +-
 .../definition/form-compute-lechapt-calmon.ts |   4 +
 .../definition/form-compute-pab-bassin-dim.ts |   4 +
 .../form-compute-pab-bassin-puissance.ts      |   4 +
 .../form-compute-parallel-structures.ts       |   4 +
 .../form-compute-regime-uniforme.ts           |   4 +
 .../form-compute-section-parametree.ts        |   4 +
 src/app/formulaire/definition/form-compute.ts |   2 +-
 .../formulaire/definition/form-definition.ts  |  38 +++++-
 src/app/formulaire/fieldset.ts                |  28 ++--
 src/app/services/param/param.service.ts       | 124 ++++++++++--------
 22 files changed, 185 insertions(+), 98 deletions(-)

diff --git a/src/app/calculators/cond_distri/cond_distri.config.json b/src/app/calculators/cond_distri/cond_distri.config.json
index 06ef5a56c..81b10e531 100644
--- a/src/app/calculators/cond_distri/cond_distri.config.json
+++ b/src/app/calculators/cond_distri/cond_distri.config.json
@@ -7,32 +7,27 @@
             {
                 "type": "input",
                 "id": "Q",
-                "unit": "m³/s",
-                "value": 3
+                "unit": "m³/s"
             },
             {
                 "type": "input",
                 "id": "D",
-                "unit": "m",
-                "value": 1.2
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "J",
-                "unit": "m",
-                "value": 0.6
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "Lg",
-                "unit": "m",
-                "value": 100
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "Nu",
-                "unit": "Pa·s",
-                "value": 1E-6
+                "unit": "Pa·s"
             }
         ]
     },
diff --git a/src/app/formulaire/definition/concrete/form-cond-distri.ts b/src/app/formulaire/definition/concrete/form-cond-distri.ts
index 9c11da38b..a150653e0 100644
--- a/src/app/formulaire/definition/concrete/form-cond-distri.ts
+++ b/src/app/formulaire/definition/concrete/form-cond-distri.ts
@@ -1,5 +1,5 @@
 import { FormDefFixedVar } from "../form-def-fixedvar";
-import { CalculatorType } from "jalhyd";
+import { CalculatorType, ComputeNodeType } from "jalhyd";
 import { ParamService } from "../../../services/param/param.service";
 import { ApplicationSetupService } from "../../../services/app-setup/app-setup.service";
 import { FormResultFixedVar } from "../form-result-fixedvar";
@@ -25,6 +25,10 @@ export class FormulaireConduiteDistributrice extends FormulaireDefinition {
         this._formCompute = new FormComputeConduiteDistributrice(this, this._formResult);
     }
 
+    protected createNubs() {
+        this._nubs.set(ComputeNodeType.None, this.paramService.createNub(this.calculatorType));
+    }
+
     protected initParse() {
         this._formParamCalc.initParse();
     }
diff --git a/src/app/formulaire/definition/concrete/form-courbe-remous.ts b/src/app/formulaire/definition/concrete/form-courbe-remous.ts
index 88bd5a352..2ee614614 100644
--- a/src/app/formulaire/definition/concrete/form-courbe-remous.ts
+++ b/src/app/formulaire/definition/concrete/form-courbe-remous.ts
@@ -22,6 +22,9 @@ export class FormulaireCourbeRemous extends FormulaireDefinition {
         this._formCompute = new FormComputeCourbeRemous(this, this._formSection, this._formResult);
     }
 
+    protected createNubs() {
+    }
+
     protected initParse() {
         this._formSection.initParse();
     }
diff --git a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
index 44f3de56e..7a86a94b3 100644
--- a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
+++ b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
@@ -26,6 +26,9 @@ export class FormulaireLechaptCalmon extends FormulaireDefinition {
         this._formCompute = new FormComputeLechaptCalmon(this, this._formResult);
     }
 
+    protected createNubs() {
+    }
+
     protected initParse() {
         this._formParamCalc.initParse();
     }
diff --git a/src/app/formulaire/definition/concrete/form-parallel-structures.ts b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
index d1bf99873..963b7d918 100644
--- a/src/app/formulaire/definition/concrete/form-parallel-structures.ts
+++ b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
@@ -33,6 +33,9 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
         this._formCompute = new FormComputeParallelStructures(this, this._formParallelStruct, this._formResult);
     }
 
+    protected createNubs() {
+    }
+
     protected initParse() {
         this._formParamCalc.initParse();
     }
diff --git a/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts b/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
index 6a7041919..7869967dc 100644
--- a/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
+++ b/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
@@ -26,6 +26,9 @@ export class FormulairePasseBassinDimensions extends FormulaireDefinition {
         this._formCompute = new FormComputePasseBassinDimensions(this, this._formResult);
     }
 
+    protected createNubs() {
+    }
+
     protected initParse() {
         this._formParamCalc.initParse();
     }
diff --git a/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts b/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
index 7ade60201..2dd9ae040 100644
--- a/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
+++ b/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
@@ -25,6 +25,9 @@ export class FormulairePasseBassinPuissance extends FormulaireDefinition {
         this._formCompute = new FormComputePasseBassinPuissance(this, this._formResult);
     }
 
+    protected createNubs() {
+    }
+
     protected initParse() {
         this._formParamCalc.initParse();
     }
diff --git a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
index 48207f7bb..389715403 100644
--- a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
+++ b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
@@ -29,6 +29,9 @@ export class FormulaireRegimeUniforme extends FormulaireDefinition {
         this._formCompute = new FormComputeRegimeUniforme(this, this._formSection, this._formResult);
     }
 
+    protected createNubs() {
+    }
+
     protected initParse() {
         this._formSection.initParse();
         this._formParamCalc.initParse();
diff --git a/src/app/formulaire/definition/concrete/form-section-parametree.ts b/src/app/formulaire/definition/concrete/form-section-parametree.ts
index 6b05a78ab..b336f2872 100644
--- a/src/app/formulaire/definition/concrete/form-section-parametree.ts
+++ b/src/app/formulaire/definition/concrete/form-section-parametree.ts
@@ -33,6 +33,9 @@ export class FormulaireSectionParametree extends FormulaireDefinition {
         this._formCompute = new FormComputeSectionParametree(this, this._formSection, this._formSectionResult, intlService, paramService);
     }
 
+    protected createNubs() {
+    }
+
     protected initParse() {
         this._formSection.initParse();
     }
diff --git a/src/app/formulaire/definition/form-compute-cond-distri.ts b/src/app/formulaire/definition/form-compute-cond-distri.ts
index 62099c01b..44481cab8 100644
--- a/src/app/formulaire/definition/form-compute-cond-distri.ts
+++ b/src/app/formulaire/definition/form-compute-cond-distri.ts
@@ -1,4 +1,4 @@
-import { ComputeNode, ParamsEquation, ConduiteDistribParams, ConduiteDistrib } from "jalhyd";
+import { ComputeNode, ParamsEquation, ConduiteDistribParams, ConduiteDistrib, ComputeNodeType } from "jalhyd";
 
 import { FormComputeFixedVar } from "./form-compute-fixedvar";
 import { FormulaireDefinition } from "./form-definition";
@@ -9,14 +9,7 @@ export class FormComputeConduiteDistributrice extends FormComputeFixedVar {
         super(formBase, formResult);
     }
 
-    public getNubAndParameters(): [ComputeNode, ParamsEquation] {
-        let Q: number = this._formBase.getParameterValue("Q"); // débit Q
-        let D: number = this._formBase.getParameterValue("D"); // diamètre D
-        let J: number = this._formBase.getParameterValue("J"); // perte de charge J
-        let Lg: number = this._formBase.getParameterValue("Lg"); // Longueur de la conduite Lg
-        let Nu: number = this._formBase.getParameterValue("Nu"); // viscosité dynamique 
-        let prms = new ConduiteDistribParams(Q, D, J, Lg, Nu);
-        let nub = new ConduiteDistrib(prms);
-        return [nub, prms];
+    protected getCurrentNub() {
+        return this._formBase.getNub(ComputeNodeType.None);
     }
 }
diff --git a/src/app/formulaire/definition/form-compute-courbe-remous.ts b/src/app/formulaire/definition/form-compute-courbe-remous.ts
index 68c0f7e34..6c48fe4ce 100644
--- a/src/app/formulaire/definition/form-compute-courbe-remous.ts
+++ b/src/app/formulaire/definition/form-compute-courbe-remous.ts
@@ -16,6 +16,10 @@ export class FormComputeCourbeRemous extends FormCompute {
         return this._formSection.getSectionNubAndParameters(false);
     }
 
+    protected getCurrentNub() {
+        return undefined;
+    }
+
     private get remousResults(): RemousResults {
         const f = this._formResult as FormResultRemous;
         return f.remousResults;
diff --git a/src/app/formulaire/definition/form-compute-fixedvar.ts b/src/app/formulaire/definition/form-compute-fixedvar.ts
index 6b9dd4d48..f11fc9d86 100644
--- a/src/app/formulaire/definition/form-compute-fixedvar.ts
+++ b/src/app/formulaire/definition/form-compute-fixedvar.ts
@@ -66,11 +66,7 @@ export abstract class FormComputeFixedVar extends FormCompute {
     }
 
     protected compute() {
-        let nub: Nub;
-        let prms: ParamsEquation;
-        let np: [ComputeNode, ParamsEquation] = this.getNubAndParameters();
-        nub = np[0] as Nub;
-        prms = np[1];
+        const nub: Nub = this.getCurrentNub();
 
         if (this._formBase.hasParameter("Pr"))
             var computePrec: number = this._formBase.getParameterValue("Pr"); // précision de calcul
@@ -109,11 +105,9 @@ export abstract class FormComputeFixedVar extends FormCompute {
 
             const res: Result = this.runNubCalc(nub, computedParam, computePrec);
 
-
             this.formResult.varResults.variatedParameter = varParam;
             this.formResult.varResults.calculatedParameter = computedParam;
 
-      
             this.formResult.varResults.result = res;
             this.formResult.graphTitle = computedParam.symbol + " = f( " + varParam.symbol + " )";
             this.formResult.varResults.update(false);
diff --git a/src/app/formulaire/definition/form-compute-lechapt-calmon.ts b/src/app/formulaire/definition/form-compute-lechapt-calmon.ts
index 21f1e8b38..10a34b28e 100644
--- a/src/app/formulaire/definition/form-compute-lechapt-calmon.ts
+++ b/src/app/formulaire/definition/form-compute-lechapt-calmon.ts
@@ -21,4 +21,8 @@ export class FormComputeLechaptCalmon extends FormComputeFixedVar {
         let nub = new LechaptCalmon(prms);
         return [nub, prms];
     }
+
+    protected getCurrentNub() {
+        return undefined;
+    }
 }
diff --git a/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts b/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts
index 266812988..30c1d82d4 100644
--- a/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts
+++ b/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts
@@ -18,4 +18,8 @@ export class FormComputePasseBassinDimensions extends FormComputeFixedVar {
         let nub = new PabDimension(prms); // pour initialiser la calculabilité des paramètres
         return [nub, prms];
     }
+
+    protected getCurrentNub() {
+        return undefined;
+    }
 }
\ No newline at end of file
diff --git a/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts b/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts
index 829300d29..c8bd05ea4 100644
--- a/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts
+++ b/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts
@@ -18,4 +18,8 @@ export class FormComputePasseBassinPuissance extends FormComputeFixedVar {
         let nub = new PabPuissance(prms); // pour initialiser la calculabilité des paramètres
         return [nub, prms];
     }
+
+    protected getCurrentNub() {
+        return undefined;
+    }
 }
\ No newline at end of file
diff --git a/src/app/formulaire/definition/form-compute-parallel-structures.ts b/src/app/formulaire/definition/form-compute-parallel-structures.ts
index 572bc88a1..3509249bd 100644
--- a/src/app/formulaire/definition/form-compute-parallel-structures.ts
+++ b/src/app/formulaire/definition/form-compute-parallel-structures.ts
@@ -107,4 +107,8 @@ export class FormComputeParallelStructures extends FormComputeFixedVar {
 
         return [nub, prms];
     }
+
+    protected getCurrentNub() {
+        return undefined;
+    }
 }
diff --git a/src/app/formulaire/definition/form-compute-regime-uniforme.ts b/src/app/formulaire/definition/form-compute-regime-uniforme.ts
index 2f004b303..8313bf199 100644
--- a/src/app/formulaire/definition/form-compute-regime-uniforme.ts
+++ b/src/app/formulaire/definition/form-compute-regime-uniforme.ts
@@ -14,4 +14,8 @@ export class FormComputeRegimeUniforme extends FormComputeFixedVar {
         const snp: [acSection, ParamsEquation] = this._formSection.getSectionNubAndParameters();
         return [new RegimeUniforme(snp[0]), snp[1]];
     }
+
+    protected getCurrentNub() {
+        return undefined;
+    }
 }
\ No newline at end of file
diff --git a/src/app/formulaire/definition/form-compute-section-parametree.ts b/src/app/formulaire/definition/form-compute-section-parametree.ts
index bce6c9e73..dc955dc38 100644
--- a/src/app/formulaire/definition/form-compute-section-parametree.ts
+++ b/src/app/formulaire/definition/form-compute-section-parametree.ts
@@ -41,6 +41,10 @@ export class FormComputeSectionParametree extends FormCompute {
         return this._formSection.getSectionNubAndParameters();
     }
 
+    protected getCurrentNub() {
+        return undefined;
+    }
+
     /**
      * calcul de la section paramétrée dans le cas d'un paramètre à varier
      * @param varParam paramètre à varier
diff --git a/src/app/formulaire/definition/form-compute.ts b/src/app/formulaire/definition/form-compute.ts
index ea59f851b..4aee71752 100644
--- a/src/app/formulaire/definition/form-compute.ts
+++ b/src/app/formulaire/definition/form-compute.ts
@@ -7,7 +7,7 @@ export abstract class FormCompute {
     constructor(protected _formBase: FormulaireDefinition, protected _formResult: FormResult) {
     }
 
-    protected abstract getNubAndParameters(): [ComputeNode, ParamsEquation];
+    protected abstract getCurrentNub(): Nub;
 
     protected abstract compute();
 
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 6c6e393f4..4c8b18f72 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -1,4 +1,4 @@
-import { CalculatorType, ComputeNodeType } from "jalhyd";
+import { CalculatorType, ComputeNodeType, Nub } from "jalhyd";
 import { FormulaireElement } from "../formulaire-element";
 import { NgParameter, ParamRadioConfig } from "../ngparam";
 import { Field } from "../field";
@@ -28,12 +28,18 @@ export abstract class FormulaireDefinition extends FormulaireNode {
      */
     private _calculatorName: string;
 
+    /**
+     * map des Nub appartenant à ce formulaire
+     */
+    protected _nubs: Map<ComputeNodeType, Nub>;
+
     constructor(calcType: CalculatorType,
-        private paramService: ParamService,
+        protected paramService: ParamService,
         private appSetupService: ApplicationSetupService
     ) {
         super();
         this._calcType = calcType;
+        this._nubs = new Map();
     }
 
     public get calculatorType(): CalculatorType {
@@ -48,6 +54,30 @@ export abstract class FormulaireDefinition extends FormulaireNode {
         this._calculatorName = name;
     }
 
+    /**
+     * @return le Nub associé à un type de noeud donné
+     * @param nodeType type de noeud
+     */
+    public getNub(nodeType: ComputeNodeType): Nub {
+        return this._nubs.get(nodeType);
+    }
+
+    /**
+     * @return le paramètre d'un type de noeud
+     * @param symbol symbole du paramètre
+     * @param nodeType type de noeud
+     */
+    public getNubParamFromSymbol(nodeType: ComputeNodeType, symbol: string) {
+        const nub = this._nubs.get(nodeType);
+        return nub.getParameter(symbol);
+    }
+
+    /**
+     * crée le(s) Nub(s) associés au formulaire
+     * (dépend essentiellement du type de calculette)
+     */
+    protected abstract createNubs();
+
     protected abstract initParse();
     protected abstract parseOptions(json: {});
     protected abstract completeParse();
@@ -67,7 +97,8 @@ export abstract class FormulaireDefinition extends FormulaireNode {
         res.parseConfig(json,
             {
                 "paramService": this.paramService,
-                "appSetupService": this.appSetupService
+                "appSetupService": this.appSetupService,
+                "parentForm": this
             });
         return res;
     }
@@ -104,6 +135,7 @@ export abstract class FormulaireDefinition extends FormulaireNode {
     }
 
     public parseConfig(json: {}) {
+        this.createNubs();
         this.initParse();
 
         const templates: { [key: string]: FieldSet } = {};
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index a49ced8ce..9d3a22499 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -1,4 +1,4 @@
-import { CalculatorType, ComputeNodeType } from "jalhyd";
+import { CalculatorType, ComputeNodeType, ParamDefinition } from "jalhyd";
 
 import { FormulaireElement } from "./formulaire-element";
 import { Dependency } from "./dependency/dependency";
@@ -86,16 +86,23 @@ export class FieldSet extends FormulaireElement {
         return res;
     }
 
-    private parse_input(json: {}, default_calc_type: CalculatorType, default_node_type: ComputeNodeType, default_radio_config: string,
-        paramService: ParamService, appSetupService: ApplicationSetupService): NgParameter {
-        let input_id: string = json["id"];
+    private parse_input(json: {}, parentForm: FormulaireDefinition, default_radio_config: string, paramService: ParamService, appSetupService: ApplicationSetupService): NgParameter {
+        const input_id: string = json["id"];
 
-        const nt: string = json["nodeType"];
-        let node_type: ComputeNodeType = nt == undefined ? default_node_type : ComputeNodeType[nt];
+        switch (input_id) {
+            case "Pr":
+                var res: NgParameter = paramService.createParameter(input_id, this.isTemplate);
+                break;
+
+            default:
+                const nt: string = json["nodeType"];
+                let node_type: ComputeNodeType = nt == undefined ? ComputeNodeType.None : ComputeNodeType[nt];
 
-        let res: NgParameter = paramService.createNodeParameter(default_calc_type, node_type, input_id, this.isTemplate);
-        if (res == undefined)
-            throw new Error(`pas de paramètre '${input_id}' trouvé dans le noeud ${ComputeNodeType[node_type]} (${node_type}) ou ComputeNodeType.None`);
+                const nubParam: ParamDefinition = parentForm.getNubParamFromSymbol(node_type, input_id);
+                if (nubParam == undefined)
+                    throw new Error(`pas de paramètre '${input_id}' trouvé dans le noeud ${ComputeNodeType[node_type]} (${node_type}) ou ComputeNodeType.None`);
+                res = new NgParameter(nubParam, this.isTemplate);
+        }
 
         res.parseConfig(json, { "appSetupService": appSetupService, "radioConfig": default_radio_config });
 
@@ -105,6 +112,7 @@ export class FieldSet extends FormulaireElement {
     public parseConfig(json: {}, data?: {}) {
         const paramService: ParamService = data["paramService"];
         const appSetupService: ApplicationSetupService = data["appSetupService"];
+        const parentForm: FormulaireDefinition = data["parentForm"];
 
         this._confId = json["id"];
 
@@ -117,7 +125,7 @@ export class FieldSet extends FormulaireElement {
 
             if (field["type"] === "input") {
                 const default_radio_config = json["option"];
-                const param = this.parse_input(field, this._calcType, node_type, default_radio_config, paramService, appSetupService);
+                const param = this.parse_input(field, parentForm, default_radio_config, paramService, appSetupService);
                 this.addField(param);
             } else if (field["type"] === "select") {
                 const param = this.parse_select(field);
diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts
index 7d028bb64..ec22b47ff 100644
--- a/src/app/services/param/param.service.ts
+++ b/src/app/services/param/param.service.ts
@@ -1,4 +1,4 @@
-import { ParamDomain, ComputeNodeType, ComputeNodeParameters, ParamsEquation, ParamDefinition, ParamDomainValue, ParamCalculability, CalculatorType } from "jalhyd";
+import { ParamDomain, ComputeNodeType, ParamDefinition, ParamDomainValue, ParamCalculability, CalculatorType, NubFactory } from "jalhyd";
 
 import { NgParameter } from "../../formulaire/ngparam";
 import { FormulaireDefinition } from "../../formulaire/definition/form-definition";
@@ -23,73 +23,85 @@ export class ParamService {
      * @param symbol symbole du paramètre
      * @param isTmpl true si le paramètre créé est un template
      */
-    public createNodeParameter(calcType: CalculatorType, nodeType: ComputeNodeType, symbol: string, isTmpl = false): NgParameter {
-        if (symbol === "Pr")
-            var prmDef: ParamDefinition = this.createAccuracyParameter();
-        else
-            prmDef = ComputeNodeParameters.getInstance().getComputeNodeParameter(calcType, nodeType, symbol);
+    // public createNodeParameter(calcType: CalculatorType, nodeType: ComputeNodeType, symbol: string, isTmpl = false): NgParameter {
+    //     if (symbol === "Pr")
+    //         var prmDef: ParamDefinition = this.createAccuracyParameter();
+    //     else
+    //         prmDef = ComputeNodeParameters.getInstance().getComputeNodeParameter(calcType, nodeType, symbol);
 
-        if (prmDef == undefined)
-            throw new Error(`ParamService.createParameter() : pas de paramètre '${symbol}' pour la calculette ${CalculatorType[calcType]}/type de noeud ${ComputeNodeType[nodeType]}`);
+    //     if (prmDef == undefined)
+    //         throw new Error(`ParamService.createParameter() : pas de paramètre '${symbol}' pour la calculette ${CalculatorType[calcType]}/type de noeud ${ComputeNodeType[nodeType]}`);
 
-        return new NgParameter(prmDef.clone(), isTmpl);
-    }
+    //     return new NgParameter(prmDef.clone(), isTmpl);
+    // }
 
     /**
      * 
      * @param calcType crée un NgParameter n'appartenant pas à un ComputeNode
      * @param symbol symbole du paramètre à créer
      */
-    public createParameter(symbol: string): NgParameter {
-        const dom = new ParamDomain(ParamDomainValue.POS_NULL);
-        const p = new NgParameter(new ParamDefinition(symbol, dom));
-        p.confId = symbol;
-
-        switch (symbol) {
-            case "Hs":
-            case "Hsc":
-            case "B":
-            case "P":
-            case "R":
-            case "Yc":
-            case "Yn":
-            case "Yf":
-            case "Yt":
-            case "Yco":
-            case "J":
-                p.unit = "m";
-                break;
-
-            case "S":
-                p.unit = "m2";
-                break;
-
-            case "V":
-                p.unit = "m/s";
-                break;
-
-            case "I-J":
-                p.unit = "m/m";
-                break;
-
-            case "Fr":
-                p.unit = "";
-                break;
-
-            case "Imp":
-                p.unit = "N";
-                break;
-
-            case "Tau0":
-                p.unit = "Pa";
-                break;
-
-            default:
-                throw new Error(`ComputeNodeParameters.getParameter() : symbole ${symbol} non pris en charge`);
+    public createParameter(symbol: string, isTmpl = false): NgParameter {
+        if (symbol === "Pr") {
+            var prmDef: ParamDefinition = this.createAccuracyParameter();
+            var p = new NgParameter(prmDef.clone(), isTmpl);
+        }
+        else {
+            const dom = new ParamDomain(ParamDomainValue.POS_NULL);
+            const p = new NgParameter(new ParamDefinition(symbol, dom));
+            p.confId = symbol;
+
+            switch (symbol) {
+                case "Hs":
+                case "Hsc":
+                case "B":
+                case "P":
+                case "R":
+                case "Yc":
+                case "Yn":
+                case "Yf":
+                case "Yt":
+                case "Yco":
+                case "J":
+                    p.unit = "m";
+                    break;
+
+                case "S":
+                    p.unit = "m2";
+                    break;
+
+                case "V":
+                    p.unit = "m/s";
+                    break;
+
+                case "I-J":
+                    p.unit = "m/m";
+                    break;
+
+                case "Fr":
+                    p.unit = "";
+                    break;
+
+                case "Imp":
+                    p.unit = "N";
+                    break;
+
+                case "Tau0":
+                    p.unit = "Pa";
+                    break;
+
+                case "Pr":
+                    break;
+
+                default:
+                    throw new Error(`ComputeNodeParameters.getParameter() : symbole ${symbol} non pris en charge`);
+            }
         }
 
         p.updateLocalisation(this.intlService.currentMap);
         return p;
     }
 
+    public createNub(calcType: CalculatorType, nodeType: ComputeNodeType = ComputeNodeType.None) {
+        return NubFactory.getInstance().createNub(calcType, nodeType);
+    }
 }
-- 
GitLab


From 0b80841a90622a0580814dcd09d92b3373364764 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 29 Mar 2018 16:35:42 +0200
Subject: [PATCH 02/53] =?UTF-8?q?=20#77=20ParamService=20:=20affection=20d?=
 =?UTF-8?q?e=20la=20valeur=20param=C3=A9tr=C3=A9e=20lors=20de=20la=20cr?=
 =?UTF-8?q?=C3=A9ation=20du=20param?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/services/param/param.service.ts | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts
index ec22b47ff..a72909743 100644
--- a/src/app/services/param/param.service.ts
+++ b/src/app/services/param/param.service.ts
@@ -4,14 +4,15 @@ import { NgParameter } from "../../formulaire/ngparam";
 import { FormulaireDefinition } from "../../formulaire/definition/form-definition";
 import { InternationalisationService } from "../internationalisation/internationalisation.service";
 import { Injectable } from "@angular/core";
+import { ApplicationSetupService } from "../app-setup/app-setup.service";
 
 @Injectable()
 export class ParamService {
-    constructor(private intlService: InternationalisationService) { }
+    constructor(private intlService: InternationalisationService, private appSetupService: ApplicationSetupService) { }
 
     private createAccuracyParameter(): ParamDefinition {
         const d = new ParamDomain(ParamDomainValue.INTERVAL, 1e-10, 100);
-        const p = new ParamDefinition('Pr', d);
+        const p = new ParamDefinition('Pr', d, this.appSetupService.computePrecision);
         p.calculability = ParamCalculability.FREE;
         return p;
     }
-- 
GitLab


From 6cfd1047a2b9895c268097bf9bce29d535b1041c Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Fri, 30 Mar 2018 10:21:33 +0200
Subject: [PATCH 03/53] =?UTF-8?q?=20#77=20effacement=20des=20r=C3=A9sultat?=
 =?UTF-8?q?s=20quand=20on=20modifie=20un=20input?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../field-set/field-set.component.html           |  2 +-
 .../components/field-set/field-set.component.ts  | 13 +++++++++++++
 .../fieldset-container.component.html            |  2 +-
 .../fieldset-container.component.ts              | 13 +++++++++++++
 .../generic-calculator/calculator.component.html |  2 +-
 .../generic-calculator/calculator.component.ts   |  7 +++++++
 .../param-field-line.component.ts                | 16 +++++++++++++---
 7 files changed, 49 insertions(+), 6 deletions(-)

diff --git a/src/app/components/field-set/field-set.component.html b/src/app/components/field-set/field-set.component.html
index cd33a4983..50c2405b0 100644
--- a/src/app/components/field-set/field-set.component.html
+++ b/src/app/components/field-set/field-set.component.html
@@ -15,7 +15,7 @@
 -->
 
 <ng-template ngFor let-p [ngForOf]="fields">
-    <param-field-line *ngIf="isInputField(p)" [param]=p (onRadio)=onRadioClick($event) (onValid)=onParamLineValid()>
+    <param-field-line *ngIf="isInputField(p)" [param]=p (onRadio)=onRadioClick($event) (onValid)=onParamLineValid() (inputChange)=onInputChange()>
     </param-field-line>
 
     <select-field-line *ngIf="isSelectField(p)" [param]=p>
diff --git a/src/app/components/field-set/field-set.component.ts b/src/app/components/field-set/field-set.component.ts
index 462644627..a192bd1d7 100644
--- a/src/app/components/field-set/field-set.component.ts
+++ b/src/app/components/field-set/field-set.component.ts
@@ -45,6 +45,12 @@ export class FieldSetComponent implements DoCheck {
     @Output()
     private validChange = new EventEmitter();
 
+    /**
+     * événément de changement de valeur d'un input
+     */
+    @Output()
+    private inputChange = new EventEmitter();
+
     /**
      * flag de validité de la saisie
      */
@@ -177,4 +183,11 @@ export class FieldSetComponent implements DoCheck {
     private onParamLineValid(event: boolean) {
         this.updateValidity();
     }
+
+    /**
+    * réception d'un événement de changement de valeur d'un input
+    */
+    private onInputChange(event: boolean) {
+        this.inputChange.emit();
+    }
 }
diff --git a/src/app/components/fieldset-container/fieldset-container.component.html b/src/app/components/fieldset-container/fieldset-container.component.html
index 154696041..9ba68f234 100644
--- a/src/app/components/fieldset-container/fieldset-container.component.html
+++ b/src/app/components/fieldset-container/fieldset-container.component.html
@@ -6,6 +6,6 @@
         <!-- bouton d'ajout d'un ouvrage -->
         <button type="button" class="btn btn-grey waves-light" mdbRippleRadius (click)="addStructure()">Ajouter un ouvrage</button>
     </div>
-    <field-set *ngFor="let fs of fieldsets" [fieldSet]=fs (onRadio)=onRadioClick($event) (onValid)=onFieldsetValid()>
+    <field-set *ngFor="let fs of fieldsets" [fieldSet]=fs (onRadio)=onRadioClick($event) (onValid)=onFieldsetValid() (inputChange)=onInputChange()>
     </field-set>
 </div>
\ No newline at end of file
diff --git a/src/app/components/fieldset-container/fieldset-container.component.ts b/src/app/components/fieldset-container/fieldset-container.component.ts
index 26ac2f5f1..e091ef408 100644
--- a/src/app/components/fieldset-container/fieldset-container.component.ts
+++ b/src/app/components/fieldset-container/fieldset-container.component.ts
@@ -101,4 +101,17 @@ export class FieldsetContainerComponent implements DoCheck {
     private onFieldsetValid() {
         this.updateValidity();
     }
+
+    /**
+     * événément de changement de valeur d'un input
+     */
+    @Output()
+    private inputChange = new EventEmitter();
+
+    /**
+    * réception d'un événement de changement de valeur d'un input
+    */
+    private onInputChange(event: boolean) {
+        this.inputChange.emit();
+    }
 }
\ No newline at end of file
diff --git a/src/app/components/generic-calculator/calculator.component.html b/src/app/components/generic-calculator/calculator.component.html
index 47e2a2e53..058792c2a 100644
--- a/src/app/components/generic-calculator/calculator.component.html
+++ b/src/app/components/generic-calculator/calculator.component.html
@@ -24,7 +24,7 @@
             <!-- chapitres -->
             <ng-template ngFor let-fe [ngForOf]="formElements">
                 <field-set *ngIf="isFieldset(fe)" [style.display]="getFieldsetStyleDisplay(fe.id)" [fieldSet]=fe (onRadio)=onRadioClick($event)
-                    (validChange)=OnFieldsetValid()></field-set>
+                    (validChange)=OnFieldsetValid() (inputChange)=onInputChange()></field-set>
 
                 <fieldset-container *ngIf="isFieldsetContainer(fe)" [container]=fe (onRadio)=onRadioClick($event) (validChange)=onFieldsetContainerValid()></fieldset-container>
             </ng-template>
diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index 3e0d05322..2ed9990ca 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -332,4 +332,11 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
     private onFieldsetContainerValid() {
         this.updateUIValidity();
     }
+
+    /**
+     * réception d'un événement de changement de valeur d'un input
+     */
+    private onInputChange() {
+        this._formulaire.reset();
+    }
 }
diff --git a/src/app/components/param-field-line/param-field-line.component.ts b/src/app/components/param-field-line/param-field-line.component.ts
index 5ec1d3de0..ebee96d49 100644
--- a/src/app/components/param-field-line/param-field-line.component.ts
+++ b/src/app/components/param-field-line/param-field-line.component.ts
@@ -36,6 +36,9 @@ export class ParamFieldLineComponent implements OnChanges {
     @Output()
     private onValid: EventEmitter<void>;
 
+    @Output()
+    private inputChange: EventEmitter<void>;
+
     /**
      * true si la valeur saisie est valide
      */
@@ -50,6 +53,7 @@ export class ParamFieldLineComponent implements OnChanges {
         private formulaireService: FormulaireService
     ) {
         this.onValid = new EventEmitter();
+        this.inputChange = new EventEmitter();
     }
 
     private get title(): string {
@@ -261,9 +265,15 @@ export class ParamFieldLineComponent implements OnChanges {
      * réception d'un événement de NgParamInputComponent
      */
     private onInputChange(event: any) {
-        if (event.action == "valid") {
-            this._isInputValid = event.value;
-            this.emitValidity();
+        switch (event.action) {
+            case "valid":
+                this._isInputValid = event.value;
+                this.emitValidity();
+                break;
+
+            case "model":
+                this.inputChange.emit();
+                break;
         }
     }
 
-- 
GitLab


From 5e8c2573ff08c64d54b30fbf4396cd80fa03bea8 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Fri, 30 Mar 2018 11:16:41 +0200
Subject: [PATCH 04/53] =?UTF-8?q?=20#77=20Lechapt-Calmon=20:=20correction?=
 =?UTF-8?q?=20d'un=20bug=20ne=20mettant=20pas=20=C3=A0=20jour=20L,M,N=20qu?=
 =?UTF-8?q?and=20on=20modifie=20le=20select=20des=20mat=C3=A9riaux=20(suit?=
 =?UTF-8?q?e=20du=20remplacement=20des=20=C3=A9v=C3=A9nements=20Angular=20?=
 =?UTF-8?q?=C3=A9mis=20par=20les=20select=20par=20des=20notifications=20ob?=
 =?UTF-8?q?serv=C3=A9=20->=20observateur,=20commenc=C3=A9=20dans=20la=20br?=
 =?UTF-8?q?anche=2027)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../generic-select/generic-select.component.ts   | 10 +---------
 .../definition/concrete/form-lechapt-calmon.ts   | 16 +++++++++++++++-
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/app/components/generic-select/generic-select.component.ts b/src/app/components/generic-select/generic-select.component.ts
index e4182c434..8e457e2dd 100644
--- a/src/app/components/generic-select/generic-select.component.ts
+++ b/src/app/components/generic-select/generic-select.component.ts
@@ -15,12 +15,6 @@ import { BaseComponent } from "../base/base.component";
 */
 
 export abstract class GenericSelectComponent<T> {
-    /**
-     * selected value event
-     */
-    @Output()
-    private selectChange = new EventEmitter<T>();
-
     private get currentLabel(): string {
         for (let e of this.entries)
             if (e == this.selectedValue)
@@ -34,10 +28,8 @@ export abstract class GenericSelectComponent<T> {
      */
     private onSelect(event: any) {
         const val = event.target.value;
-        if (val != undefined) {
+        if (val != undefined)
             this.selectedValue = val;
-            this.selectChange.emit(this.selectedValue);
-        }
     }
 
     /**
diff --git a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
index 7a86a94b3..6d1b2eb1e 100644
--- a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
+++ b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
@@ -8,8 +8,10 @@ import { FormComputeLechaptCalmon } from "../form-compute-lechapt-calmon";
 import { FormulaireDefinition } from "../form-definition";
 import { CalculatorResults } from "../../../results/calculator-results";
 import { FormDefParamToCalculate } from "../form-def-paramcalc";
+import { Observer } from "../../../services/observer";
+import { SelectField } from "../../select-field";
 
-export class FormulaireLechaptCalmon extends FormulaireDefinition {
+export class FormulaireLechaptCalmon extends FormulaireDefinition implements Observer {
     private _formFixedVar: FormDefFixedVar;
 
     private _formParamCalc: FormDefParamToCalculate;
@@ -38,6 +40,8 @@ export class FormulaireLechaptCalmon extends FormulaireDefinition {
     }
 
     protected completeParse() {
+        // abonnement au changement de valeur du select de matériau
+        this.getFormulaireNodeById("select_material").addObserver(this);
     }
 
     /**
@@ -62,4 +66,14 @@ export class FormulaireLechaptCalmon extends FormulaireDefinition {
     public get results(): CalculatorResults[] {
         return this._formResult.results;
     }
+
+    // interface Observer
+
+    public update(sender: any, data: any) {
+        // en cas de changement de valeur du select de matériau, effacement des résultats et MAJ des champs L,M,N
+        if (sender instanceof SelectField) {
+            if (data.action == "select")
+                this.reset();
+        }
+    }
 }
-- 
GitLab


From 294e48b69f8a4d4687fa889733205e3f51cc3dca Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Fri, 30 Mar 2018 13:13:11 +0200
Subject: [PATCH 05/53] =?UTF-8?q?=20#77=20correction=20d'un=20bug=20emp?=
 =?UTF-8?q?=C3=AAchant=20de=20choisir=20le=20type=20de=20graphique=20dans?=
 =?UTF-8?q?=20les=20r=C3=A9sultats=20(param=C3=A8tre=20=C3=A0=20varier)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../results-graph/graph-type.component.ts     | 42 +++++++++++++++++--
 .../results-graph.component.html              |  2 +-
 .../results-graph/results-graph.component.ts  | 15 +++++--
 3 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/src/app/components/results-graph/graph-type.component.ts b/src/app/components/results-graph/graph-type.component.ts
index 4eae8af94..e3b3c0333 100644
--- a/src/app/components/results-graph/graph-type.component.ts
+++ b/src/app/components/results-graph/graph-type.component.ts
@@ -2,16 +2,24 @@ import { Component } from '@angular/core';
 
 import { GenericSelectComponent } from '../generic-select/generic-select.component';
 import { GraphType } from "../../results/var-results";
+import { Observable, IObservable, Observer } from '../../services/observer';
 
 @Component({
     selector: "graph-type",
     templateUrl: "../generic-select/generic-select.component.html"
 })
-export class GraphTypeSelectComponent extends GenericSelectComponent<GraphType> {
+export class GraphTypeSelectComponent extends GenericSelectComponent<GraphType> implements IObservable {
     private _entries: GraphType[] = [GraphType.Histogram, GraphType.Scatter];
     private _entriesLabels: string[] = ["Histogramme", "XY"];
     private _selected: GraphType;
 
+    private _observable: Observable;
+
+    constructor() {
+        super();
+        this._observable = new Observable();
+    }
+
     protected get entries(): GraphType[] {
         return this._entries;
     }
@@ -25,8 +33,36 @@ export class GraphTypeSelectComponent extends GenericSelectComponent<GraphType>
         return this._selected;
     }
 
-
     public set selectedValue(v: GraphType) {
-        this._selected = v;
+        if (this._selected !== v) {
+            this._selected = v;
+            this.notifyObservers({
+                "action": "select",
+                "value": v
+            }, this);
+        }
+    }
+
+    // interface IObservable
+
+    /**
+     * ajoute un observateur à la liste
+     */
+    addObserver(o: Observer) {
+        this._observable.addObserver(o);
+    }
+
+    /**
+     * supprime un observateur de la liste
+     */
+    removeObserver(o: Observer) {
+        this._observable.removeObserver(o);
+    }
+
+    /**
+     * notifie un événement aux observateurs
+     */
+    notifyObservers(data: any, sender?: any) {
+        this._observable.notifyObservers(data, sender);
     }
 }
diff --git a/src/app/components/results-graph/results-graph.component.html b/src/app/components/results-graph/results-graph.component.html
index 316485524..73ad69b83 100644
--- a/src/app/components/results-graph/results-graph.component.html
+++ b/src/app/components/results-graph/results-graph.component.html
@@ -7,6 +7,6 @@
 
 <div class="row">
     <div class="col-4 mx-auto">
-        <graph-type (selectChange)="onGraphTypeSelectChange($event)"></graph-type>
+        <graph-type></graph-type>
     </div>
 </div>
\ No newline at end of file
diff --git a/src/app/components/results-graph/results-graph.component.ts b/src/app/components/results-graph/results-graph.component.ts
index b24994a39..1d47ecfbc 100644
--- a/src/app/components/results-graph/results-graph.component.ts
+++ b/src/app/components/results-graph/results-graph.component.ts
@@ -1,13 +1,14 @@
-import { Component, ViewChild } from '@angular/core';
+import { Component, ViewChild, AfterContentInit } from '@angular/core';
 
 import { VarResults, GraphType } from "../../results/var-results";
 import { GraphTypeSelectComponent } from './graph-type.component';
+import { Observer } from '../../services/observer';
 
 @Component({
     selector: 'results-graph',
     templateUrl: './results-graph.component.html'
 })
-export class ResultsGraphComponent {
+export class ResultsGraphComponent implements AfterContentInit, Observer {
     private _results: VarResults;
 
     @ViewChild(GraphTypeSelectComponent)
@@ -58,8 +59,8 @@ export class ResultsGraphComponent {
         }
     }
 
-    private onGraphTypeSelectChange(event) {
-        this.updateView();
+    public ngAfterContentInit() {
+        this._graphTypeComponent.addObserver(this);
     }
 
     /**
@@ -162,4 +163,10 @@ export class ResultsGraphComponent {
             ]
         };
     }
+
+    // interface Observer 
+
+    update(sender: any, data: any) {
+        this.updateView();
+    }
 }
-- 
GitLab


From 617ad9f3c59c5b8ed9549195293b82e6f42e7935 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Fri, 30 Mar 2018 15:12:08 +0200
Subject: [PATCH 06/53] =?UTF-8?q?=20#77=20adaptation=20de=20Lechapt-Calmon?=
 =?UTF-8?q?=20=C3=A0=20la=20factory=20de=20Nub?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../lechapt-calmon/lechapt-calmon.config.json   | 12 ++++--------
 .../definition/concrete/form-lechapt-calmon.ts  |  3 ++-
 .../definition/form-compute-lechapt-calmon.ts   | 17 ++---------------
 3 files changed, 8 insertions(+), 24 deletions(-)

diff --git a/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json b/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json
index 1cc7e8861..1fecb054d 100644
--- a/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json
+++ b/src/app/calculators/lechapt-calmon/lechapt-calmon.config.json
@@ -203,26 +203,22 @@
             {
                 "type": "input",
                 "id": "Q",
-                "unit": "m³/s",
-                "value": 3
+                "unit": "m³/s"
             },
             {
                 "type": "input",
                 "id": "D",
-                "unit": "m",
-                "value": 1.2
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "J",
-                "unit": "m",
-                "value": 0.6
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "Lg",
-                "unit": "m",
-                "value": 100
+                "unit": "m"
             }
         ]
     },
diff --git a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
index 6d1b2eb1e..ec897fb98 100644
--- a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
+++ b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
@@ -1,4 +1,4 @@
-import { CalculatorType } from "jalhyd";
+import { CalculatorType, ComputeNodeType } from "jalhyd";
 
 import { FormResultFixedVar } from "../form-result-fixedvar";
 import { ParamService } from "../../../services/param/param.service";
@@ -29,6 +29,7 @@ export class FormulaireLechaptCalmon extends FormulaireDefinition implements Obs
     }
 
     protected createNubs() {
+        this._nubs.set(ComputeNodeType.None, this.paramService.createNub(this.calculatorType));
     }
 
     protected initParse() {
diff --git a/src/app/formulaire/definition/form-compute-lechapt-calmon.ts b/src/app/formulaire/definition/form-compute-lechapt-calmon.ts
index 10a34b28e..7af295988 100644
--- a/src/app/formulaire/definition/form-compute-lechapt-calmon.ts
+++ b/src/app/formulaire/definition/form-compute-lechapt-calmon.ts
@@ -1,4 +1,4 @@
-import { ComputeNode, ParamsEquation, LechaptCalmonParams, LechaptCalmon } from "jalhyd";
+import { ComputeNode, ComputeNodeType, ParamsEquation, LechaptCalmonParams, LechaptCalmon } from "jalhyd";
 
 import { FormComputeFixedVar } from "./form-compute-fixedvar";
 import { FormulaireDefinition } from "./form-definition";
@@ -9,20 +9,7 @@ export class FormComputeLechaptCalmon extends FormComputeFixedVar {
         super(formBase, formResult);
     }
 
-    public getNubAndParameters(): [ComputeNode, ParamsEquation] {
-        let Q: number = this._formBase.getParameterValue("Q"); // débit Q
-        let D: number = this._formBase.getParameterValue("D"); // diamètre D
-        let J: number = this._formBase.getParameterValue("J"); // perte de charge J
-        let Lg: number = this._formBase.getParameterValue("Lg"); // Longueur de la conduite Lg
-        let L: number = this._formBase.getParameterValue("L"); // paramètre de matériau 1
-        let M: number = this._formBase.getParameterValue("M"); // paramètre de matériau 2
-        let N: number = this._formBase.getParameterValue("N"); // paramètre de matériau 3
-        let prms = new LechaptCalmonParams(Q, D, J, Lg, L, M, N);
-        let nub = new LechaptCalmon(prms);
-        return [nub, prms];
-    }
-
     protected getCurrentNub() {
-        return undefined;
+        return this._formBase.getNub(ComputeNodeType.None);
     }
 }
-- 
GitLab


From 02bc89381376d91411640d59fbb49d5ae22c9043 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Fri, 30 Mar 2018 15:12:57 +0200
Subject: [PATCH 07/53] =?UTF-8?q?=20#77=20Lechapt-Calmon=20:=20correction?=
 =?UTF-8?q?=20d'un=20bug=20emp=C3=AAchant=20de=20prendre=20en=20compte=20l?=
 =?UTF-8?q?es=20modifs=20sur=20L,M,N=20pour=20le=20calcul=20(d=C3=A9pendan?=
 =?UTF-8?q?ces=20r=C3=A9appliqu=C3=A9es=20lors=20de=20la=20modif=20d'un=20?=
 =?UTF-8?q?input=20suite=20=C3=A0=20la=20r=C3=A9initialisation=20du=20form?=
 =?UTF-8?q?ulaire=20pour=20effacer=20les=20r=C3=A9sultats)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/components/generic-calculator/calculator.component.ts | 2 +-
 src/app/formulaire/definition/form-definition.ts              | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index 2ed9990ca..36988a83d 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -337,6 +337,6 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
      * réception d'un événement de changement de valeur d'un input
      */
     private onInputChange() {
-        this._formulaire.reset();
+        this._formulaire.resetResults();
     }
 }
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 4c8b18f72..e317913cc 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -284,7 +284,7 @@ export abstract class FormulaireDefinition extends FormulaireNode {
             fe.applyDependencies(this);
     }
 
-    protected abstract resetResults();
+    public abstract resetResults();
     public abstract doCompute();
     public abstract get hasResults(): boolean;
     public abstract get results(): CalculatorResults[];
-- 
GitLab


From 0b1b82d4ee92f0315ab75cfd0921995bddc7cc07 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Wed, 4 Apr 2018 10:35:50 +0200
Subject: [PATCH 08/53] =?UTF-8?q?=20#77=20adaptation=20des=20sections=20pa?=
 =?UTF-8?q?ram=C3=A9tr=C3=A9es=20=C3=A0=20la=20factory=20de=20Nub=20(cas?=
 =?UTF-8?q?=20d'un=20param=C3=A8tre=20=C3=A0=20varier)=20-=20section-param?=
 =?UTF-8?q?.config.json=20:=20suppression=20des=20valeurs=20par=20d=C3=A9f?=
 =?UTF-8?q?aut,=20d=C3=A9placement=20de=20nodeType=20du=20fieldset=20->=20?=
 =?UTF-8?q?field=20-=20d=C3=A9placement=20de=20FormComputeFixedVar.runNubC?=
 =?UTF-8?q?alc()=20dans=20FormCompute=20-=20FormulaireDefinition.getNubPar?=
 =?UTF-8?q?amFromSymbol()=20:=20modif=20pour=20traiter=20le=20cas=20d'un?=
 =?UTF-8?q?=20param=C3=A8tre=20associ=C3=A9=20=C3=A0=20aucun=20ComputeNode?=
 =?UTF-8?q?Type?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../section-param/section-param.config.json   | 43 +++++-------
 .../concrete/form-section-parametree.ts       |  6 +-
 .../definition/form-compute-fixedvar.ts       | 31 +--------
 .../form-compute-section-parametree.ts        | 61 ++++++-----------
 src/app/formulaire/definition/form-compute.ts | 28 +++++++-
 .../formulaire/definition/form-def-section.ts | 68 ++-----------------
 .../formulaire/definition/form-definition.ts  | 18 +++--
 src/app/formulaire/fieldset.ts                |  2 +-
 src/app/services/param/param.service.ts       |  2 +-
 9 files changed, 93 insertions(+), 166 deletions(-)

diff --git a/src/app/calculators/section-param/section-param.config.json b/src/app/calculators/section-param/section-param.config.json
index a082a2db9..4f896ad7b 100644
--- a/src/app/calculators/section-param/section-param.config.json
+++ b/src/app/calculators/section-param/section-param.config.json
@@ -26,7 +26,6 @@
     {
         "id": "fs_section_trapez",
         "type": "fieldset",
-        "nodeType": "SectionTrapeze",
         "option": "var",
         "dep_exist": [
             {
@@ -38,21 +37,20 @@
             {
                 "type": "input",
                 "id": "LargeurFond",
-                "unit": "m",
-                "value": 2.5
+                "nodeType": "SectionTrapeze",
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "Fruit",
-                "unit": "m/m",
-                "value": 0.56
+                "nodeType": "SectionTrapeze",
+                "unit": "m/m"
             }
         ]
     },
     {
         "id": "fs_section_rect",
         "type": "fieldset",
-        "nodeType": "SectionRectangle",
         "option": "var",
         "dep_exist": [
             {
@@ -64,15 +62,14 @@
             {
                 "type": "input",
                 "id": "LargeurBerge",
-                "unit": "m",
-                "value": 2.5
+                "nodeType": "SectionRectangle",
+                "unit": "m"
             }
         ]
     },
     {
         "id": "fs_section_circ",
         "type": "fieldset",
-        "nodeType": "SectionCercle",
         "option": "var",
         "dep_exist": [
             {
@@ -84,15 +81,14 @@
             {
                 "type": "input",
                 "id": "D",
-                "unit": "m",
-                "value": 2
+                "nodeType": "SectionCercle",
+                "unit": "m"
             }
         ]
     },
     {
         "id": "fs_section_puissance",
         "type": "fieldset",
-        "nodeType": "SectionPuissance",
         "option": "var",
         "dep_exist": [
             {
@@ -104,14 +100,14 @@
             {
                 "type": "input",
                 "id": "k",
-                "unit": "",
-                "value": 0.5
+                "nodeType": "SectionPuissance",
+                "unit": ""
             },
             {
                 "type": "input",
                 "id": "LargeurBerge",
-                "unit": "m",
-                "value": 2
+                "nodeType": "SectionPuissance",
+                "unit": "m"
             }
         ]
     },
@@ -123,20 +119,17 @@
             {
                 "type": "input",
                 "id": "Ks",
-                "unit": "m1/3s-1",
-                "value": 40
+                "unit": "m1/3s-1"
             },
             {
                 "type": "input",
                 "id": "If",
-                "unit": "m/m",
-                "value": 0.001
+                "unit": "m/m"
             },
             {
                 "type": "input",
                 "id": "YB",
-                "unit": "m",
-                "value": 1
+                "unit": "m"
             }
         ]
     },
@@ -148,14 +141,12 @@
             {
                 "type": "input",
                 "id": "Q",
-                "unit": "m³/s",
-                "value": 1.2
+                "unit": "m³/s"
             },
             {
                 "type": "input",
                 "id": "Y",
-                "unit": "m",
-                "value": 0.8
+                "unit": "m"
             }
         ]
     },
diff --git a/src/app/formulaire/definition/concrete/form-section-parametree.ts b/src/app/formulaire/definition/concrete/form-section-parametree.ts
index b336f2872..6f5e84835 100644
--- a/src/app/formulaire/definition/concrete/form-section-parametree.ts
+++ b/src/app/formulaire/definition/concrete/form-section-parametree.ts
@@ -1,4 +1,4 @@
-import { CalculatorType, acSection, ParamsEquation } from "jalhyd";
+import { CalculatorType, acSection, ParamsEquation, ComputeNodeType } from "jalhyd";
 
 import { FormResultSection } from "../form-result-section";
 import { ParamService } from "../../../services/param/param.service";
@@ -34,6 +34,10 @@ export class FormulaireSectionParametree extends FormulaireDefinition {
     }
 
     protected createNubs() {
+        this._nubs.set(ComputeNodeType.SectionCercle, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionCercle));
+        this._nubs.set(ComputeNodeType.SectionPuissance, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionPuissance));
+        this._nubs.set(ComputeNodeType.SectionRectangle, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionRectangle));
+        this._nubs.set(ComputeNodeType.SectionTrapeze, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionTrapeze));
     }
 
     protected initParse() {
diff --git a/src/app/formulaire/definition/form-compute-fixedvar.ts b/src/app/formulaire/definition/form-compute-fixedvar.ts
index f11fc9d86..d862d7ef0 100644
--- a/src/app/formulaire/definition/form-compute-fixedvar.ts
+++ b/src/app/formulaire/definition/form-compute-fixedvar.ts
@@ -1,9 +1,8 @@
-import { Nub, ParamsEquation, Result, ParamDomainValue, ComputeNode, ParamValueMode } from "jalhyd";
+import { Nub, Result, ComputeNode, ParamValueMode } from "jalhyd";
 
 import { FormCompute } from "./form-compute";
 import { NgParameter, ParamRadioConfig } from "../ngparam";
 import { FormResultFixedVar } from "./form-result-fixedvar";
-import { GraphType } from "../../results/var-results";
 import { FormulaireDefinition } from "./form-definition";
 
 export abstract class FormComputeFixedVar extends FormCompute {
@@ -31,30 +30,6 @@ export abstract class FormComputeFixedVar extends FormCompute {
         return p.symbol;
     }
 
-    /**
-     * lance le calcul d'un paramètre en déterminant une valeur initiale
-     */
-    private runNubCalc(nub: Nub, p: NgParameter, prec: number): Result {
-        let init: number;
-        switch (p.domain.domain) {
-            case ParamDomainValue.ANY:
-            case ParamDomainValue.POS_NULL:
-                init = 0;
-                break;
-
-            case ParamDomainValue.INTERVAL:
-                init = p.domain.minValue;
-                break;
-
-            case ParamDomainValue.NOT_NULL:
-            case ParamDomainValue.POS:
-                init = 1e-8;
-                break;
-        }
-
-        return nub.CalcSerie(prec, init);
-    }
-
     /**
      * fixe la valeur d'un paramètre de ComputeNode
      * @param node ComputeNode contenant le paramètre
@@ -82,7 +57,7 @@ export abstract class FormComputeFixedVar extends FormCompute {
         if (varParam == undefined) {
             // pas de paramètre à varier
 
-            const res: Result = this.runNubCalc(nub, computedParam, computePrec);
+            const res: Result = this.runNubCalc(nub, computedParam.domain, computePrec);
             this.formResult.fixedResults.result = res;
             this.formResult.fixedResults.calculatedParameter = computedParam;
         }
@@ -103,7 +78,7 @@ export abstract class FormComputeFixedVar extends FormCompute {
                     break;
             }
 
-            const res: Result = this.runNubCalc(nub, computedParam, computePrec);
+            const res: Result = this.runNubCalc(nub, computedParam.domain, computePrec);
 
             this.formResult.varResults.variatedParameter = varParam;
             this.formResult.varResults.calculatedParameter = computedParam;
diff --git a/src/app/formulaire/definition/form-compute-section-parametree.ts b/src/app/formulaire/definition/form-compute-section-parametree.ts
index dc955dc38..3a05fe434 100644
--- a/src/app/formulaire/definition/form-compute-section-parametree.ts
+++ b/src/app/formulaire/definition/form-compute-section-parametree.ts
@@ -1,6 +1,7 @@
+import { SectionParametree, acSection, ParamsEquation, ComputeNode, Result, ParamValueMode, Nub, ParamsSection } from "jalhyd";
+
 import { FormCompute } from "./form-compute";
 import { NgParameter } from "../ngparam";
-import { acSection, ParamsEquation, ComputeNode, Result, ParamValueMode } from "jalhyd";
 import { FormResult } from "./form-result";
 import { Form } from "@angular/forms";
 import { FormDefSection } from "./form-def-section";
@@ -37,12 +38,8 @@ export class FormComputeSectionParametree extends FormCompute {
         return this._formSectionResult.sectionResults;
     }
 
-    protected getNubAndParameters(): [ComputeNode, ParamsEquation] {
-        return this._formSection.getSectionNubAndParameters();
-    }
-
-    protected getCurrentNub() {
-        return undefined;
+    protected getCurrentNub(): Nub {
+        return this._formBase.getNub(this._formSection.sectionNodeType);
     }
 
     /**
@@ -56,55 +53,39 @@ export class FormComputeSectionParametree extends FormCompute {
         this._formSectionResult.addSectionFixedParameters(false);
 
         // paramètre à calculer en fonction du paramètre à varier
-        let computedParam = this._formSection.getSectionComputedParam();
+        let computedParamInfo = this._formSection.getSectionComputedParam();
 
-        var np: [ComputeNode, ParamsEquation] = this.getNubAndParameters();
-        let sect: acSection = np[0] as acSection;
-        let prms: ParamsEquation = np[1];
+        const sectNub: SectionParametree = this.getCurrentNub() as SectionParametree;
+        const sect: acSection = sectNub.section;
+        const prms = sectNub.parameters;
 
         this._sectionResults.section = sect;
 
         this._varResults.variatedParameter = varParam;
-        this._varResults.calculatedParameter = this.paramService.createParameter(computedParam.symbol);
 
-        const result = new Result();
-        let compSymbol = computedParam["symbol"];
+        const computedParam: NgParameter = this.paramService.createParameter(computedParamInfo.symbol);
+        this._varResults.calculatedParameter = computedParam;
+
+        let compSymbol: string = computedParamInfo["symbol"];
 
         let yField: InputField = <InputField>this._formBase.getFormulaireNodeById("Y");
         let Y: number = yField.getValue();
 
         switch (varParam.valueMode) {
-            case ParamValueMode.MINMAX:
-                let min: number = +varParam.minValue;
-                let max: number = +varParam.maxValue;
-                let step: number = +varParam.stepValue;
-
-                for (let val = min; val <= max; val += step) {
-                    prms[varParam.symbol].v = val;
-
-                    const res = sect.Calc(compSymbol, Y);
-                    result.addResultElement(res.resultElement);
-                    result.addLog(res.log);
-                }
-                break;
-
             case ParamValueMode.LISTE:
-                const it = varParam.valuesIterator;
-                for (const val of it) {
-                    prms[varParam.symbol].v = val;
-
-                    const res = sect.Calc(compSymbol, Y);
-                    result.addResultElement(res.resultElement);
-                    result.addLog(res.log);
-                }
+                varParam.paramDefinition.paramValues.setValues(varParam.paramDefinition.paramValues.valueList);
                 break;
 
-            default:
-                throw new Error(`section paramétrée : mode de génération de valeurs ${ParamValueMode[varParam.valueMode]} non pris en charge`);
+            case ParamValueMode.MINMAX:
+                const min = varParam.paramDefinition.paramValues.min;
+                const max = varParam.paramDefinition.paramValues.max;
+                const step = varParam.paramDefinition.paramValues.step;
+                varParam.paramDefinition.paramValues.setValues(min, max, step);
+                break;
         }
 
-        this._varResults.result = result;
-        this._varResults.graphTitle = computedParam.symbol + " = f( " + varParam.symbol + " )";
+        this._varResults.result = this.runNubCalc(sectNub, computedParam.domain, computePrec, computedParam.symbol);
+        this._varResults.graphTitle = computedParamInfo.symbol + " = f( " + varParam.symbol + " )";
         this._varResults.update(false);
     }
 
diff --git a/src/app/formulaire/definition/form-compute.ts b/src/app/formulaire/definition/form-compute.ts
index 4aee71752..79abc4ba5 100644
--- a/src/app/formulaire/definition/form-compute.ts
+++ b/src/app/formulaire/definition/form-compute.ts
@@ -1,5 +1,6 @@
+import { ParamValueMode, Nub, Result, ParamDomainValue, ParamDomain } from "jalhyd";
+
 import { FormResult } from "./form-result";
-import { ParamsEquation, ComputeNode, ParamValueMode, Nub } from "jalhyd";
 import { FormulaireDefinition } from "./form-definition";
 import { NgParameter } from "../ngparam";
 
@@ -26,6 +27,31 @@ export abstract class FormCompute {
         nub.initParametersValueMode(computedParam.paramDefinition, variatedParam && variatedParam.paramDefinition, variatedMode);
     }
 
+
+    /**
+     * lance le calcul d'un paramètre en déterminant une valeur initiale
+     */
+    protected runNubCalc(nub: Nub, computedParamDomain: ParamDomain, prec: number, computedParam?: string): Result {
+        let init: number;
+        switch (computedParamDomain.domain) {
+            case ParamDomainValue.ANY:
+            case ParamDomainValue.POS_NULL:
+                init = 0;
+                break;
+
+            case ParamDomainValue.INTERVAL:
+                init = computedParamDomain.minValue;
+                break;
+
+            case ParamDomainValue.NOT_NULL:
+            case ParamDomainValue.POS:
+                init = 1e-8;
+                break;
+        }
+
+        return nub.CalcSerie(prec, init, computedParam);
+    }
+
     public doCompute() {
         this._formResult.resetResults();
 
diff --git a/src/app/formulaire/definition/form-def-section.ts b/src/app/formulaire/definition/form-def-section.ts
index 9a3a49503..d99c7ae5e 100644
--- a/src/app/formulaire/definition/form-def-section.ts
+++ b/src/app/formulaire/definition/form-def-section.ts
@@ -32,6 +32,10 @@ export class FormDefSection implements Observer {
         return this._sectionSelectFieldId != undefined;
     }
 
+    public get sectionNodeType(): ComputeNodeType {
+        return this._sectionNodeType;
+    }
+
     private updateSectionNodeType() {
         const nt = this.getNodeTypeFromSelectField();
         if (this._sectionNodeType !== nt) {
@@ -44,70 +48,6 @@ export class FormDefSection implements Observer {
         return this._formBase.getDisplayedParamFromState(ParamRadioConfig.VAR);
     }
 
-    public getSectionNubAndParameters(getY: boolean = true): [acSection, ParamsEquation] {
-        // bief
-        let Ks = this._formBase.getParameterValue("Ks"); // Strickler
-        let If: number = this._formBase.getParameterValue("If"); // Pente du fond
-        let YB: number = this._formBase.getParameterValue("YB"); // Hauteur de berge
-
-        // caractéristiques hydro
-        let Q: number = this._formBase.getParameterValue("Q"); // débit Q
-        if (getY)
-            var Y: number = this._formBase.getParameterValue("Y"); // tirant d'eau
-        else
-            Y = undefined;
-
-        let Prec = this._formBase.getParameterValue("Pr"); // précision calcul/affichage
-
-        // ??
-        // let YCL: number = f.getParameterValue("YCL"); // Condition limite en cote à l'amont ou à l'aval
-        // let Dx: number = f.getParameterValue("Dx"); // Pas d'espace (positif en partant de l'aval, négatif en partant de l'amont)
-        // let Long: number = f.getParameterValue("Long"); // Longueur du bief
-
-        switch (this._sectionNodeType) {
-            case ComputeNodeType.SectionTrapeze:
-                {
-                    let LargeurFond = this._formBase.getParameterValue("LargeurFond"); // Largeur au fond
-                    let Fruit = this._formBase.getParameterValue("Fruit"); // Fruit des berges
-                    let prms = new ParamsSectionTrapez(LargeurFond, Fruit, Y, Ks, Q, If, Prec, YB);
-                    let cn = new cSnTrapez(prms);
-                    cn.newtonMaxIter = this.appSetupService.newtonMaxIter;
-                    return [cn, prms];
-                }
-
-            case ComputeNodeType.SectionRectangle:
-                {
-                    let LargeurFond = this._formBase.getParameterValue("LargeurBerge"); // Largeur au fond
-                    let prms = new ParamsSectionRectang(Y, LargeurFond, Ks, Q, If, Prec, YB);
-                    let cn = new cSnRectang(prms);
-                    cn.newtonMaxIter = this.appSetupService.newtonMaxIter;
-                    return [cn, prms];
-                }
-
-            case ComputeNodeType.SectionCercle:
-                {
-                    let D = this._formBase.getParameterValue("D"); // Largeur au fond
-                    let prms = new ParamsSectionCirc(D, Y, Ks, Q, If, Prec, YB);
-                    let cn = new cSnCirc(prms);
-                    cn.newtonMaxIter = this.appSetupService.newtonMaxIter;
-                    return [cn, prms];
-                }
-
-            case ComputeNodeType.SectionPuissance:
-                {
-                    let k = this._formBase.getParameterValue("k"); // coefficient
-                    let LargeurBerge = this._formBase.getParameterValue("LargeurBerge"); // Largeur au niveau des berges
-                    let prms = new ParamsSectionPuiss(k, Y, LargeurBerge, Ks, Q, If, Prec, YB);
-                    let cn = new cSnPuiss(prms);
-                    cn.newtonMaxIter = this.appSetupService.newtonMaxIter;
-                    return [cn, prms];
-                }
-
-            default:
-                throw new Error(`FormWithSection.getSectionNubAndParameters() : valeur de ComputeNodeType ${this._sectionNodeType} non prise en charge`);
-        }
-    }
-
     public getSectionComputedParam(): { symbol: string, label: string } {
         const symbol = this._formBase.getSelectedValue("select_target");
         const label = this._formBase.getSelectedLabel("select_target");
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index e317913cc..92f52fcec 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -1,4 +1,4 @@
-import { CalculatorType, ComputeNodeType, Nub } from "jalhyd";
+import { CalculatorType, ComputeNodeType, Nub, ParamDefinition } from "jalhyd";
 import { FormulaireElement } from "../formulaire-element";
 import { NgParameter, ParamRadioConfig } from "../ngparam";
 import { Field } from "../field";
@@ -67,9 +67,19 @@ export abstract class FormulaireDefinition extends FormulaireNode {
      * @param symbol symbole du paramètre
      * @param nodeType type de noeud
      */
-    public getNubParamFromSymbol(nodeType: ComputeNodeType, symbol: string) {
-        const nub = this._nubs.get(nodeType);
-        return nub.getParameter(symbol);
+    public getNubParamFromSymbol(nodeType: ComputeNodeType, symbol: string): ParamDefinition {
+        let nub = this._nubs.get(nodeType);
+
+        if (nub == undefined) // on prend le 1er
+            for (const e of this._nubs.entries()) {
+                nub = e[1]; // valeur
+                break;
+            }
+
+        if (nub)
+            return nub.getParameter(symbol);
+
+        return undefined;
     }
 
     /**
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 9d3a22499..4094c69d2 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -100,7 +100,7 @@ export class FieldSet extends FormulaireElement {
 
                 const nubParam: ParamDefinition = parentForm.getNubParamFromSymbol(node_type, input_id);
                 if (nubParam == undefined)
-                    throw new Error(`pas de paramètre '${input_id}' trouvé dans le noeud ${ComputeNodeType[node_type]} (${node_type}) ou ComputeNodeType.None`);
+                    throw new Error(`pas de paramètre '${input_id}' trouvé pour CalculatorType.${CalculatorType[parentForm.calculatorType]}/ComputeNodeType.${ComputeNodeType[node_type]}`);
                 res = new NgParameter(nubParam, this.isTemplate);
         }
 
diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts
index a72909743..902774585 100644
--- a/src/app/services/param/param.service.ts
+++ b/src/app/services/param/param.service.ts
@@ -48,7 +48,7 @@ export class ParamService {
         }
         else {
             const dom = new ParamDomain(ParamDomainValue.POS_NULL);
-            const p = new NgParameter(new ParamDefinition(symbol, dom));
+            p = new NgParameter(new ParamDefinition(symbol, dom));
             p.confId = symbol;
 
             switch (symbol) {
-- 
GitLab


From ccd82ce7b349d0fddcdd2e81b0f1d34bc39d646a Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Wed, 4 Apr 2018 17:52:35 +0200
Subject: [PATCH 09/53] =?UTF-8?q?=20#77=20sections=20param=C3=A9tr=C3=A9es?=
 =?UTF-8?q?=20:=20utilisation=20de=20SectionParametree.CalcSerie()=20(de?=
 =?UTF-8?q?=20jalhyd)=20pour=20le=20cas=20"aucun=20param=C3=A8tre=20=C3=A0?=
 =?UTF-8?q?=20varier"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../section-results.component.html            |  9 +-
 .../section-results.component.ts              | 42 +++++++---
 .../form-compute-section-parametree.ts        | 83 ++-----------------
 .../definition/form-result-section.ts         |  4 -
 src/app/results/section-results.ts            | 18 ++--
 5 files changed, 48 insertions(+), 108 deletions(-)

diff --git a/src/app/components/section-results/section-results.component.html b/src/app/components/section-results/section-results.component.html
index 77d384f65..e9a103d4e 100644
--- a/src/app/components/section-results/section-results.component.html
+++ b/src/app/components/section-results/section-results.component.html
@@ -9,13 +9,10 @@
     <!-- tableau de valeurs -->
     <div class="row">
         <div class="col mx-auto">
-            <table style="width: 100%">
-                <tr *ngFor="let r of sectionResults; let i=index" [class]="getResultClass(i)">
-                    <td class="result_label">{{r.label}}</td>
-                    <td horizontal-result-element [result-element]=r.value class="result_value">
-                    </td>
+            <table style="width: 100%" cellpadding="15">
+                <tr vertical-result-element [result-element]=resultElement>
                 </tr>
             </table>
         </div>
     </div>
-</div>
\ No newline at end of file
+</div>
diff --git a/src/app/components/section-results/section-results.component.ts b/src/app/components/section-results/section-results.component.ts
index ea6daaae4..0656b917a 100644
--- a/src/app/components/section-results/section-results.component.ts
+++ b/src/app/components/section-results/section-results.component.ts
@@ -1,11 +1,12 @@
 import { Component, ViewChild, DoCheck } from '@angular/core';
 
-import { acSection, Result } from 'jalhyd';
+import { acSection, Result, ResultElement } from 'jalhyd';
 
 import { SectionCanvasComponent } from '../section-canvas/section-canvas.component';
 import { SectionResults } from '../../results/section-results';
 import { ApplicationSetupService } from '../../services/app-setup/app-setup.service';
 import { CalculatorResults } from '../../results/calculator-results';
+import { InternationalisationService } from '../../services/internationalisation/internationalisation.service';
 
 @Component({
     selector: 'section-results',
@@ -37,7 +38,12 @@ export class SectionResultsComponent implements DoCheck {
     */
     private _results: SectionResults;
 
-    constructor(private appSetupService: ApplicationSetupService) { }
+    /**
+     * ResultElement mis en forme (symboles des variables traduits)
+     */
+    private _resultElement: ResultElement;
+
+    constructor(private appSetupService: ApplicationSetupService, private intlService: InternationalisationService) { }
 
     private static labelColors: { [key: string]: any; } = {
         "Hs": { r: 255, g: 0, b: 0 },
@@ -55,6 +61,8 @@ export class SectionResultsComponent implements DoCheck {
     private _sectionCanvas: SectionCanvasComponent;
 
     public set results(rs: CalculatorResults[]) {
+        this._resultElement = undefined;
+
         this._results = undefined;
         if (rs != undefined)
             for (const r of rs) {
@@ -82,18 +90,30 @@ export class SectionResultsComponent implements DoCheck {
             this._doUpdate = !this.updateResults();
     }
 
+    private isSectionLevel(s: string) {
+        for (const k in SectionResultsComponent.labelColors)
+            if (k === s)
+                return true;
+        return false;
+    }
+
     private updateResults() {
-        if (this._results != undefined && this._sectionCanvas != undefined) {
+        if (this._results && this._sectionCanvas) {
             const nDigits = this.appSetupService.displayDigits;
 
-            for (let r of this._results.results) {
-                const v: Result = r["value"];
-                const l = r["label"];
+            this._resultElement = new ResultElement();
 
-                const drawLabel = r["drawLabel"];
-                if (drawLabel != undefined && v.vCalc != undefined)
-                    this._sectionCanvas.addLevel(v.vCalc, drawLabel + " = " + v.vCalc.toFixed(nDigits), SectionResultsComponent.labelColors[drawLabel]);
+            // traduction des symboles des variables calculées
+            for (const k in this._results.result.extraResults) {
+                const k2 = "INFO_GRANDEUR_" + k.toUpperCase();
+                const lbl = this.intlService.localizeText(k2);
+                const er = this._results.result.getExtraResult(k);
+                this._resultElement.addExtraResult(lbl, er);
+
+                if (this.isSectionLevel(k))
+                    this._sectionCanvas.addLevel(er, k + " = " + er.toFixed(nDigits), SectionResultsComponent.labelColors[k]);
             }
+
             this._sectionCanvas.section = this._results.section;
             return true;
         }
@@ -104,8 +124,8 @@ export class SectionResultsComponent implements DoCheck {
         return this._results != undefined && this._results.hasResults;
     }
 
-    private get sectionResults() {
-        return this._results.results;
+    private get resultElement() {
+        return this._resultElement;
     }
 
     private getResultClass(i: number) {
diff --git a/src/app/formulaire/definition/form-compute-section-parametree.ts b/src/app/formulaire/definition/form-compute-section-parametree.ts
index 3a05fe434..864d8b6e4 100644
--- a/src/app/formulaire/definition/form-compute-section-parametree.ts
+++ b/src/app/formulaire/definition/form-compute-section-parametree.ts
@@ -96,84 +96,15 @@ export class FormComputeSectionParametree extends FormCompute {
             return;
         }
 
-        var np: [ComputeNode, ParamsEquation] = this.getNubAndParameters();
-
-        let sect: acSection = np[0] as acSection;
-        let prms: ParamsEquation = np[1];
+        const sectNub: SectionParametree = this.getCurrentNub() as SectionParametree;
 
+        const sect: acSection = sectNub.section;
         this._sectionResults.section = sect;
 
-        let computePrec: number = this._formBase.getParameterValue("Pr"); // précision de calcul
-        let nDigits = -Math.log10(computePrec);
-
-        let Y = prms.map.Y.v; // tirant d'eau original (doit être fourni à acSection.Calc() sous peine d'être modifié par les appels successifs car c'est en même temps un paramètre et une variable temporaire)
-
-        // charge spécifique
-        let Hs = sect.Calc("Hs", Y);
-        this._formSectionResult.addSectionFixedResult(Hs.resultElement, this.intlService.localizeText("INFO_GRANDEUR_HS"), "Hs");
-
-        // charge critique
-        let Hsc = sect.Calc("Hsc", Y);
-        this._formSectionResult.addSectionFixedResult(Hsc.resultElement, this.intlService.localizeText("INFO_GRANDEUR_HSC"), "Hsc");
-
-        // largeur au miroir
-        let B = sect.Calc("B", Y);
-        this._formSectionResult.addSectionFixedResult(B.resultElement, this.intlService.localizeText("INFO_GRANDEUR_B"));
-
-        // périmètre hydraulique
-        let P = sect.Calc("P", Y);
-        this._formSectionResult.addSectionFixedResult(P.resultElement, this.intlService.localizeText("INFO_GRANDEUR_P"));
-
-        // surface hydraulique
-        let S = sect.Calc("S", Y);
-        this._formSectionResult.addSectionFixedResult(S.resultElement, this.intlService.localizeText("INFO_GRANDEUR_S"));
-
-        // rayon hydraulique
-        let R = sect.Calc("R", Y);
-        this._formSectionResult.addSectionFixedResult(R.resultElement, this.intlService.localizeText("INFO_GRANDEUR_R"));
-
-        // vitesse moyenne
-        let V = sect.Calc("V", Y);
-        this._formSectionResult.addSectionFixedResult(V.resultElement, this.intlService.localizeText("INFO_GRANDEUR_V"));
-
-        // nombre de Froude
-        let Fr = sect.Calc("Fr", Y);
-        this._formSectionResult.addSectionFixedResult(Fr.resultElement, this.intlService.localizeText("INFO_GRANDEUR_FR"), );
-
-        // tirant d'eau critique
-        let Yc = sect.Calc("Yc", Y);
-        this._formSectionResult.addSectionFixedResult(Yc.resultElement, this.intlService.localizeText("INFO_GRANDEUR_YC"), "Yc");
-
-        // tirant d'eau normal
-        let Yn = sect.Calc("Yn", Y);
-        this._formSectionResult.addSectionFixedResult(Yn.resultElement, this.intlService.localizeText("INFO_GRANDEUR_YN"), "Yn");
-
-        // tirant d'eau fluvial
-        let Yf = sect.Calc("Yf", Y);
-        this._formSectionResult.addSectionFixedResult(Yf.resultElement, this.intlService.localizeText("INFO_GRANDEUR_YF"), "Yf");
-
-        // tirant d'eau torrentiel
-        let Yt = sect.Calc("Yt", Y);
-        this._formSectionResult.addSectionFixedResult(Yt.resultElement, this.intlService.localizeText("INFO_GRANDEUR_YT"), "Yt");
-
-        // tirant d'eau conjugué
-        let Yco = sect.Calc("Yco", Y);
-        this._formSectionResult.addSectionFixedResult(Yco.resultElement, this.intlService.localizeText("INFO_GRANDEUR_YCO"), "Yco");
-
-        // perte de charge
-        let J = sect.Calc("J", Y);
-        this._formSectionResult.addSectionFixedResult(J.resultElement, this.intlService.localizeText("INFO_GRANDEUR_J"));
-
-        // Variation linéaire de l'énergie spécifique
-        let IJ = sect.Calc("I-J", Y);
-        this._formSectionResult.addSectionFixedResult(IJ.resultElement, this.intlService.localizeText("INFO_GRANDEUR_I-J"));
-
-        // impulsion hydraulique
-        let Imp = sect.Calc("Imp", Y);
-        this._formSectionResult.addSectionFixedResult(Imp.resultElement, this.intlService.localizeText("INFO_GRANDEUR_IMP"));
-
-        // contrainte de cisaillement
-        let Tau0 = sect.Calc("Tau0", Y);
-        this._formSectionResult.addSectionFixedResult(Tau0.resultElement, this.intlService.localizeText("INFO_GRANDEUR_TAU0"));
+        const computePrec: number = this._formBase.getParameterValue("Pr"); // précision de calcul
+        this._sectionResults.result = sectNub.CalcSerie(computePrec,
+            undefined, // valeur initiale, non utilisée dans ce cas
+            undefined // variable à calculer, non utilisée
+        );
     }
 }
diff --git a/src/app/formulaire/definition/form-result-section.ts b/src/app/formulaire/definition/form-result-section.ts
index 674299437..14f07562c 100644
--- a/src/app/formulaire/definition/form-result-section.ts
+++ b/src/app/formulaire/definition/form-result-section.ts
@@ -51,10 +51,6 @@ export class FormResultSection extends FormResult {
         this._sectionResults.reset();
     }
 
-    public addSectionFixedResult(val: ResultElement, label: string, drawLabel: string = undefined) {
-        this._sectionResults.addResult(val, label, drawLabel);
-    }
-
     public addSectionFixedParameters(displaySymbol: boolean) {
         for (let p of this._formBase.getDisplayedParamListFromState(ParamRadioConfig.FIX))
             if (p.symbol !== "Pr")
diff --git a/src/app/results/section-results.ts b/src/app/results/section-results.ts
index 680b5b40c..8e3d3b88d 100644
--- a/src/app/results/section-results.ts
+++ b/src/app/results/section-results.ts
@@ -4,7 +4,7 @@ import { CalculatorResults } from "./calculator-results";
 import { NgParameter } from "../formulaire/ngparam";
 
 export class SectionResults extends CalculatorResults {
-    private _results: Object[];
+    private _result: Result;
 
     private _section: acSection;
 
@@ -15,19 +15,15 @@ export class SectionResults extends CalculatorResults {
 
     public reset() {
         this._section = undefined;
-        this._results = [];
+        this._result = undefined;
     }
 
-    public addResult(v: ResultElement, l: string, drawLabel: string) {
-        this._results.push({
-            "label": l,
-            "value": v,
-            "drawLabel": drawLabel
-        });
+    public get result(): Result {
+        return this._result;
     }
 
-    public get results() {
-        return this._results;
+    public set result(r: Result) {
+        this._result = r;
     }
 
     public get section() {
@@ -39,6 +35,6 @@ export class SectionResults extends CalculatorResults {
     }
 
     public get hasResults(): boolean {
-        return this._section != undefined && this._results.length > 0;
+        return this._section != undefined && this._result != undefined;
     }
 }
-- 
GitLab


From a0a9039133e3b47af6cfd30af062a7f207cadad4 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Wed, 4 Apr 2018 17:54:16 +0200
Subject: [PATCH 10/53] =?UTF-8?q?=20#77=20mise=20en=20forme=20des=20r?=
 =?UTF-8?q?=C3=A9sultats=20compl=C3=A9mentaires=20affich=C3=A9s=20vertical?=
 =?UTF-8?q?ement=20-=20VerticalResultElementComponent=20:=20modif=20pour?=
 =?UTF-8?q?=20ne=20pas=20afficher=20le=20vCalc=20du=20ResultElement=20s'il?=
 =?UTF-8?q?=20n'est=20pas=20d=C3=A9fini=20et=20qu'il=20n'y=20a=20pas=20de?=
 =?UTF-8?q?=20message=20de=20log=20-=20VerticalResultElementComponent=20:?=
 =?UTF-8?q?=20alternance=20de=20couleurs=20pour=20les=20<tr>=20g=C3=A9n?=
 =?UTF-8?q?=C3=A9r=C3=A9s?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../result-element-base.component.ts          | 10 ++++--
 .../vertical-result-element.component.html    | 14 ++++-----
 .../vertical-result-element.component.ts      | 31 ++++++++++++++-----
 3 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/src/app/components/result-element/result-element-base.component.ts b/src/app/components/result-element/result-element-base.component.ts
index 6c0cca3ea..caf5db9c1 100644
--- a/src/app/components/result-element/result-element-base.component.ts
+++ b/src/app/components/result-element/result-element-base.component.ts
@@ -35,6 +35,11 @@ export class ResultElementBaseComponent implements OnChanges {
      */
     protected _hasError: boolean;
 
+    /**
+     * true si le result element a une valeur
+     */
+    protected _hasValue: boolean;
+
     /**
      * code HTML du tooltip
      */
@@ -62,8 +67,9 @@ export class ResultElementBaseComponent implements OnChanges {
 
         const nDigits = this.appSetupService.displayDigits;
         const r: ResultElement = this._resultElement;
-        this._hasError = r == undefined || r.vCalc == undefined;
-        this._value = this._hasError ? " " : this._value = r.vCalc.toFixed(nDigits);
+        this._hasValue = r != undefined && r.vCalc != undefined;
+        this._hasError = r == undefined || (r.vCalc == undefined && r.extraResults.length > 0);
+        this._value = this._hasValue ? this._value = r.vCalc.toFixed(nDigits) : " ";
 
         // texte du tooltip
 
diff --git a/src/app/components/result-element/vertical-result-element.component.html b/src/app/components/result-element/vertical-result-element.component.html
index db082ad1c..ec10e0b13 100644
--- a/src/app/components/result-element/vertical-result-element.component.html
+++ b/src/app/components/result-element/vertical-result-element.component.html
@@ -3,29 +3,29 @@
     <div [innerHtml]="htmlTooltip"></div>
 </ng-template>
 
-<td class="bold_right">
+<td *ngIf="hasValue" class="bold_right">
     {{resultLabel}}
 </td>
 
-<td [mdbTooltip]="popTemplate" [isDisabled]="tooltipDisabled" class="bold_center">
+<td *ngIf="hasValue||hasError" [mdbTooltip]="popTemplate" [isDisabled]="tooltipDisabled" class="bold_center">
     <!-- icône en cas d'erreur -->
     <i *ngIf="hasError" class="fa fa-exclamation-triangle" style="color:red" aria-hidden="true"></i>
 
     <!-- valeur  -->
-    <span *ngIf="!hasError">
+    <span *ngIf="hasValue">
         {{resultValue}}
     </span>
 </td>
 
 <!-- template de création de tr supplémentaires pour les extraResult -->
-<ng-template #extraResultTr let-r="extraRes">
+<ng-template #extraResultTr let-r="extraRes" let-c="classes">
     <!-- résultats complémentaires -->
     <tr>
-        <td class="bold_right">
+        <td class={{c.label_class}}>
             {{r.label}}
         </td>
-        <td class="bold_center">
+        <td class={{c.value_class}}>
             {{r.value}}
         </td>
     </tr>
-</ng-template>
\ No newline at end of file
+</ng-template>
diff --git a/src/app/components/result-element/vertical-result-element.component.ts b/src/app/components/result-element/vertical-result-element.component.ts
index b648044f9..4aecd4942 100644
--- a/src/app/components/result-element/vertical-result-element.component.ts
+++ b/src/app/components/result-element/vertical-result-element.component.ts
@@ -11,11 +11,17 @@ import { ResultElementBaseComponent } from "./result-element-base.component";
     selector: "tr[vertical-result-element]",
     templateUrl: "./vertical-result-element.component.html",
     styles: [
-        `.bold_right {
-            text-align: right; font-weight: bold
+        `.label1 {
+            text-align: right; background-color: #f0f0f0
         }`,
-        `.bold_center {
-            text-align: center; font-weight: bold
+        `.value1 {
+            text-align: center; background-color: #f0f0f0
+        }`,
+        `.label2 {
+            text-align: right; background-color: #ffffff
+        }`,
+        `.value2 {
+            text-align: center; background-color: #ffffff
         }`
     ]
 })
@@ -45,9 +51,20 @@ export class VerticalResultElementComponent extends ResultElementBaseComponent {
         super.ngOnChanges();
 
         this.vcRef.clear();
-        for (const k in this._resultElement.extraResults) {
-            const er = this._resultElement.extraResults[k];
-            this.vcRef.createEmbeddedView(this.trTemplate, { extraRes: { "label": k, "value": er } });
+        if (this._resultElement) {
+            const nDigits = this.appSetupService.displayDigits;
+
+            let i = 0;
+            for (const k in this._resultElement.extraResults) {
+                const er: number = this._resultElement.extraResults[k];
+                const lblClass = (i % 2) == 0 ? "label1" : "label2";
+                const valueClass = (i % 2) == 0 ? "value1" : "value2";
+                this.vcRef.createEmbeddedView(this.trTemplate, {
+                    extraRes: { "label": k, "value": er.toFixed(nDigits) },
+                    classes: { "label_class": lblClass, "value_class": valueClass }
+                });
+                i++;
+            }
         }
     }
 }
-- 
GitLab


From 72e692d7ddd2707961a4dcad4c0342f6cc2fe9de Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 5 Apr 2018 12:03:57 +0200
Subject: [PATCH 11/53] =?UTF-8?q?=20#77=20d=C3=A9but=20d'adaptation=20des?=
 =?UTF-8?q?=20courbes=20de=20remous=20et=20du=20r=C3=A9gime=20uniforme=20?=
 =?UTF-8?q?=C3=A0=20la=20factory=20de=20Nub=20(n=C3=A9cessaire=20pour=20co?=
 =?UTF-8?q?mpiler=20le=20projet)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../definition/form-compute-courbe-remous.ts   | 18 ++++++++++--------
 .../definition/form-compute-regime-uniforme.ts | 10 +++++-----
 2 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/src/app/formulaire/definition/form-compute-courbe-remous.ts b/src/app/formulaire/definition/form-compute-courbe-remous.ts
index 6c48fe4ce..eb0f82842 100644
--- a/src/app/formulaire/definition/form-compute-courbe-remous.ts
+++ b/src/app/formulaire/definition/form-compute-courbe-remous.ts
@@ -1,4 +1,4 @@
-import { acSection, ParamsEquation, ComputeNode, Result, MethodeResolution, CourbeRemousParams, CourbeRemous, ResultElement, ParamValues } from "jalhyd";
+import { SectionParametree, acSection, ParamsEquation, ComputeNode, Result, MethodeResolution, CourbeRemousParams, CourbeRemous, ResultElement, ParamValues } from "jalhyd";
 
 import { SelectField } from "../select-field";
 import { RemousResults } from "../../results/remous-results";
@@ -12,12 +12,12 @@ export class FormComputeCourbeRemous extends FormCompute {
         super(formBase, formResult);
     }
 
-    protected getNubAndParameters(): [ComputeNode, ParamsEquation] {
-        return this._formSection.getSectionNubAndParameters(false);
-    }
+    // protected getNubAndParameters(): [ComputeNode, ParamsEquation] {
+    //     return this._formSection.getSectionNubAndParameters(false);
+    // }
 
     protected getCurrentNub() {
-        return undefined;
+        return this._formBase.getNub(this._formSection.sectionNodeType);
     }
 
     private get remousResults(): RemousResults {
@@ -26,10 +26,12 @@ export class FormComputeCourbeRemous extends FormCompute {
     }
 
     protected compute() {
-        var np: [ComputeNode, ParamsEquation] = this.getNubAndParameters();
+        // var np: [ComputeNode, ParamsEquation] = this.getNubAndParameters();
+        // let sect: acSection = np[0] as acSection;
+        // let prmSect: ParamsEquation = np[1];
 
-        let sect: acSection = np[0] as acSection;
-        let prmSect: ParamsEquation = np[1];
+        const sectNub: SectionParametree = this.getCurrentNub() as SectionParametree;
+        const sect: acSection = sectNub.section;
 
         let Yamont: number = this._formBase.getParameterValue("Yamont"); // tirant amont
         let Yaval: number = this._formBase.getParameterValue("Yaval"); // tirant aval
diff --git a/src/app/formulaire/definition/form-compute-regime-uniforme.ts b/src/app/formulaire/definition/form-compute-regime-uniforme.ts
index 8313bf199..b01615cdf 100644
--- a/src/app/formulaire/definition/form-compute-regime-uniforme.ts
+++ b/src/app/formulaire/definition/form-compute-regime-uniforme.ts
@@ -10,12 +10,12 @@ export class FormComputeRegimeUniforme extends FormComputeFixedVar {
         super(formBase, formResult);
     }
 
-    protected getNubAndParameters(): [ComputeNode, ParamsEquation] {
-        const snp: [acSection, ParamsEquation] = this._formSection.getSectionNubAndParameters();
-        return [new RegimeUniforme(snp[0]), snp[1]];
-    }
+    // protected getNubAndParameters(): [ComputeNode, ParamsEquation] {
+    //     const snp: [acSection, ParamsEquation] = this._formSection.getSectionNubAndParameters();
+    //     return [new RegimeUniforme(snp[0]), snp[1]];
+    // }
 
     protected getCurrentNub() {
-        return undefined;
+        return this._formBase.getNub(this._formSection.sectionNodeType);
     }
 }
\ No newline at end of file
-- 
GitLab


From 6e8c4340df60379eb57dd1084f1fa37a98398f34 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 5 Apr 2018 13:45:17 +0200
Subject: [PATCH 12/53]  #77 ajout du fichier jalhyd_branch qui indique la
 branche jalHyd compatible avec cette branche

---
 jalhyd_branch | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 jalhyd_branch

diff --git a/jalhyd_branch b/jalhyd_branch
new file mode 100644
index 000000000..c804db385
--- /dev/null
+++ b/jalhyd_branch
@@ -0,0 +1 @@
+46-gestion-de-la-session-dans-la-lib
-- 
GitLab


From 553b6dd334fe7782c91e00c74a76fbd142bbf7a3 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 5 Apr 2018 14:09:39 +0200
Subject: [PATCH 13/53] =?UTF-8?q?=20#77=20adaptation=20du=20r=C3=A9gime=20?=
 =?UTF-8?q?uniforme=20=C3=A0=20la=20factory=20de=20Nub?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../regime-uniforme.config.json               | 43 ++++++++-----------
 .../concrete/form-regime-uniforme.ts          |  6 ++-
 2 files changed, 22 insertions(+), 27 deletions(-)

diff --git a/src/app/calculators/regime-uniforme/regime-uniforme.config.json b/src/app/calculators/regime-uniforme/regime-uniforme.config.json
index 29ba446e2..5ac0d5738 100644
--- a/src/app/calculators/regime-uniforme/regime-uniforme.config.json
+++ b/src/app/calculators/regime-uniforme/regime-uniforme.config.json
@@ -26,7 +26,6 @@
     {
         "id": "fs_section_trapez",
         "type": "fieldset",
-        "nodeType": "SectionTrapeze",
         "option": "cal",
         "dep_exist": [
             {
@@ -38,21 +37,20 @@
             {
                 "type": "input",
                 "id": "LargeurFond",
-                "unit": "m",
-                "value": 2.5
+                "nodeType": "SectionTrapeze",
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "Fruit",
-                "unit": "m/m",
-                "value": 0.56
+                "nodeType": "SectionTrapeze",
+                "unit": "m/m"
             }
         ]
     },
     {
         "id": "fs_section_rect",
         "type": "fieldset",
-        "nodeType": "SectionRectangle",
         "option": "cal",
         "dep_exist": [
             {
@@ -64,15 +62,14 @@
             {
                 "type": "input",
                 "id": "LargeurBerge",
-                "unit": "m",
-                "value": 2.5
+                "nodeType": "SectionRectangle",
+                "unit": "m"
             }
         ]
     },
     {
         "id": "fs_section_circ",
         "type": "fieldset",
-        "nodeType": "SectionCercle",
         "option": "cal",
         "dep_exist": [
             {
@@ -84,15 +81,14 @@
             {
                 "type": "input",
                 "id": "D",
-                "unit": "m",
-                "value": 2
+                "nodeType": "SectionCercle",
+                "unit": "m"
             }
         ]
     },
     {
         "id": "fs_section_puiss",
         "type": "fieldset",
-        "nodeType": "SectionPuissance",
         "option": "cal",
         "dep_exist": [
             {
@@ -104,14 +100,14 @@
             {
                 "type": "input",
                 "id": "k",
-                "unit": "",
-                "value": 0.5
+                "nodeType": "SectionPuissance",
+                "unit": ""
             },
             {
                 "type": "input",
                 "id": "LargeurBerge",
-                "unit": "m",
-                "value": 2
+                "nodeType": "SectionPuissance",
+                "unit": "m"
             }
         ]
     },
@@ -123,20 +119,17 @@
             {
                 "type": "input",
                 "id": "Ks",
-                "unit": "m1/3s-1",
-                "value": 40
+                "unit": "m1/3s-1"
             },
             {
                 "type": "input",
                 "id": "If",
-                "unit": "m/m",
-                "value": 0.001
+                "unit": "m/m"
             },
             {
                 "type": "input",
                 "id": "YB",
-                "unit": "m",
-                "value": 1
+                "unit": "m"
             }
         ]
     },
@@ -148,14 +141,12 @@
             {
                 "type": "input",
                 "id": "Q",
-                "unit": "m³/s",
-                "value": 1.2
+                "unit": "m³/s"
             },
             {
                 "type": "input",
                 "id": "Y",
-                "unit": "m",
-                "value": 0.8
+                "unit": "m"
             }
         ]
     },
diff --git a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
index 389715403..41395d592 100644
--- a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
+++ b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
@@ -1,5 +1,5 @@
 import { FormDefFixedVar } from "../form-def-fixedvar";
-import { CalculatorType } from "jalhyd";
+import { CalculatorType, ComputeNodeType } from "jalhyd";
 import { ParamService } from "../../../services/param/param.service";
 import { ApplicationSetupService } from "../../../services/app-setup/app-setup.service";
 import { FormResultFixedVar } from "../form-result-fixedvar";
@@ -30,6 +30,10 @@ export class FormulaireRegimeUniforme extends FormulaireDefinition {
     }
 
     protected createNubs() {
+        this._nubs.set(ComputeNodeType.SectionCercle, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionCercle));
+        this._nubs.set(ComputeNodeType.SectionPuissance, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionPuissance));
+        this._nubs.set(ComputeNodeType.SectionRectangle, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionRectangle));
+        this._nubs.set(ComputeNodeType.SectionTrapeze, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionTrapeze));
     }
 
     protected initParse() {
-- 
GitLab


From 6f00232d13e26a2aa7acc5615d84bce32c7501e5 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 5 Apr 2018 15:37:20 +0200
Subject: [PATCH 14/53] =?UTF-8?q?=20#77=20adaptation=20des=20courbes=20de?=
 =?UTF-8?q?=20remous=20=C3=A0=20la=20factory=20de=20Nub?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/calculators/remous/remous.config.json | 52 +++++++------------
 .../remous-results.component.ts               |  4 +-
 .../definition/concrete/form-courbe-remous.ts |  6 ++-
 .../definition/form-compute-courbe-remous.ts  | 37 ++++---------
 src/app/results/remous-results.ts             | 34 +++++++-----
 5 files changed, 56 insertions(+), 77 deletions(-)

diff --git a/src/app/calculators/remous/remous.config.json b/src/app/calculators/remous/remous.config.json
index 61afbc02d..2110d94c0 100644
--- a/src/app/calculators/remous/remous.config.json
+++ b/src/app/calculators/remous/remous.config.json
@@ -26,7 +26,6 @@
     {
         "id": "fs_section_trapez",
         "type": "fieldset",
-        "nodeType": "SectionTrapeze",
         "option": "fix",
         "dep_exist": [
             {
@@ -38,21 +37,20 @@
             {
                 "type": "input",
                 "id": "LargeurFond",
-                "unit": "m",
-                "value": 2.5
+                "nodeType": "SectionTrapeze",
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "Fruit",
-                "unit": "m/m",
-                "value": 0.56
+                "nodeType": "SectionTrapeze",
+                "unit": "m/m"
             }
         ]
     },
     {
         "id": "fs_section_rect",
         "type": "fieldset",
-        "nodeType": "SectionRectangle",
         "option": "fix",
         "dep_exist": [
             {
@@ -64,15 +62,14 @@
             {
                 "type": "input",
                 "id": "LargeurBerge",
-                "unit": "m",
-                "value": 2.5
+                "nodeType": "SectionRectangle",
+                "unit": "m"
             }
         ]
     },
     {
         "id": "fs_section_circ",
         "type": "fieldset",
-        "nodeType": "SectionCercle",
         "option": "fix",
         "dep_exist": [
             {
@@ -84,15 +81,14 @@
             {
                 "type": "input",
                 "id": "D",
-                "unit": "m",
-                "value": 2
+                "nodeType": "SectionCercle",
+                "unit": "m"
             }
         ]
     },
     {
         "id": "fs_section_puiss",
         "type": "fieldset",
-        "nodeType": "SectionPuissance",
         "option": "fix",
         "dep_exist": [
             {
@@ -104,14 +100,14 @@
             {
                 "type": "input",
                 "id": "k",
-                "unit": "",
-                "value": 0.5
+                "nodeType": "SectionPuissance",
+                "unit": ""
             },
             {
                 "type": "input",
                 "id": "LargeurBerge",
-                "unit": "m",
-                "value": 2
+                "nodeType": "SectionPuissance",
+                "unit": "m"
             }
         ]
     },
@@ -123,26 +119,22 @@
             {
                 "type": "input",
                 "id": "Ks",
-                "unit": "m1/3s-1",
-                "value": 40
+                "unit": "m1/3s-1"
             },
             {
                 "type": "input",
                 "id": "Long",
-                "unit": "m",
-                "value": 100
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "If",
-                "unit": "m/m",
-                "value": 0.001
+                "unit": "m/m"
             },
             {
                 "type": "input",
                 "id": "YB",
-                "unit": "m",
-                "value": 1
+                "unit": "m"
             }
         ]
     },
@@ -154,20 +146,17 @@
             {
                 "type": "input",
                 "id": "Q",
-                "unit": "m³/s",
-                "value": 2
+                "unit": "m³/s"
             },
             {
                 "type": "input",
                 "id": "Yaval",
-                "unit": "m",
-                "value": 0.4
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "Yamont",
-                "unit": "m",
-                "value": 0.15
+                "unit": "m"
             }
         ]
     },
@@ -179,8 +168,7 @@
             {
                 "type": "input",
                 "id": "Dx",
-                "unit": "m",
-                "value": 5
+                "unit": "m"
             },
             {
                 "type": "input",
diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index c553ecc73..9b8bccc04 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -244,8 +244,8 @@ export class RemousResultsComponent {
         gr1.drawLine(0, 0, 3, "#753F00", this.uitextFond, "#753F00");
 
         // ligne de berge
-        if (this._remousResults.hautBerge != undefined && this._remousResults.hautBerge.ok)
-            gr1.drawLine(this._remousResults.hautBerge.vCalc, this._remousResults.hautBerge.vCalc, 4, "#C58F50", this.uitextBerge);
+        if (this._remousResults.hautBerge)
+            gr1.drawLine(this._remousResults.hautBerge, this._remousResults.hautBerge, 4, "#C58F50", this.uitextBerge);
 
         // hauteur normale
         if (this._remousResults.hautNormale != undefined && this._remousResults.hautNormale.ok)
diff --git a/src/app/formulaire/definition/concrete/form-courbe-remous.ts b/src/app/formulaire/definition/concrete/form-courbe-remous.ts
index 2ee614614..af674161b 100644
--- a/src/app/formulaire/definition/concrete/form-courbe-remous.ts
+++ b/src/app/formulaire/definition/concrete/form-courbe-remous.ts
@@ -1,4 +1,4 @@
-import { CalculatorType } from "jalhyd";
+import { CalculatorType, ComputeNodeType } from "jalhyd";
 
 import { ParamService } from "../../../services/param/param.service";
 import { ApplicationSetupService } from "../../../services/app-setup/app-setup.service";
@@ -23,6 +23,10 @@ export class FormulaireCourbeRemous extends FormulaireDefinition {
     }
 
     protected createNubs() {
+        this._nubs.set(ComputeNodeType.SectionCercle, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionCercle));
+        this._nubs.set(ComputeNodeType.SectionPuissance, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionPuissance));
+        this._nubs.set(ComputeNodeType.SectionRectangle, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionRectangle));
+        this._nubs.set(ComputeNodeType.SectionTrapeze, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionTrapeze));
     }
 
     protected initParse() {
diff --git a/src/app/formulaire/definition/form-compute-courbe-remous.ts b/src/app/formulaire/definition/form-compute-courbe-remous.ts
index eb0f82842..fcabe29f5 100644
--- a/src/app/formulaire/definition/form-compute-courbe-remous.ts
+++ b/src/app/formulaire/definition/form-compute-courbe-remous.ts
@@ -26,23 +26,14 @@ export class FormComputeCourbeRemous extends FormCompute {
     }
 
     protected compute() {
-        // var np: [ComputeNode, ParamsEquation] = this.getNubAndParameters();
-        // let sect: acSection = np[0] as acSection;
-        // let prmSect: ParamsEquation = np[1];
-
-        const sectNub: SectionParametree = this.getCurrentNub() as SectionParametree;
-        const sect: acSection = sectNub.section;
-
-        let Yamont: number = this._formBase.getParameterValue("Yamont"); // tirant amont
-        let Yaval: number = this._formBase.getParameterValue("Yaval"); // tirant aval
-        let Dx: number = this._formBase.getParameterValue("Dx"); // pas de discrétisation
-        let Long: number = this._formBase.getParameterValue("Long"); // longueur du bief
-        let If: number = this._formBase.getParameterValue("If"); // pente du fond
-        let YB: number = this._formBase.getParameterValue("YB"); // hauteur de berge
+        const cr: CourbeRemous = this.getCurrentNub() as CourbeRemous;
+        const prmCR: CourbeRemousParams = cr.parameters as CourbeRemousParams;
+        const sect: acSection = prmCR.Sn;
+
         let Yn: Result = sect.Calc("Yn"); // hauteur normale
         let Yc: Result = sect.Calc("Yc"); // hauteur critique
 
-        this.remousResults.penteFond = If;
+        this.remousResults.parameters = prmCR;
 
         // méthode de résolution
 
@@ -56,21 +47,18 @@ export class FormComputeCourbeRemous extends FormCompute {
         else if (smeth == "select_resolution_euler")
             methRes = MethodeResolution.EulerExplicite;
         else
-            throw "GenericCalculatorComponent.doComputeRemous() : type de méthode de résolution '" + smeth + "' inconnu";
+            throw "FormComputeCourbeRemous.compute() : type de méthode de résolution '" + smeth + "' inconnu";
 
-        // paramètre supplémentaire à calculer
+        // variable supplémentaire à calculer
 
         const extraSymbol: string = this._formBase.getSelectedValue("select_target");
 
         // calcul
 
-        let prmCR: CourbeRemousParams = new CourbeRemousParams(sect, Yamont, Yaval, Long, Dx, methRes);
-        let cr = new CourbeRemous(prmCR);
-        let res: Result = cr.calculRemous(extraSymbol == "none" ? undefined : extraSymbol);
+        this.remousResults.result = cr.calculRemous(extraSymbol == "none" ? undefined : extraSymbol);
 
-        // affichage du graphe
+        // données du graphe
 
-        this.remousResults.hauteurBerge = new ResultElement(YB);
         this.remousResults.hauteurNormale = Yn.resultElement;
         this.remousResults.hauteurCritique = Yc.resultElement;
         if (extraSymbol != "none") {
@@ -79,12 +67,5 @@ export class FormComputeCourbeRemous extends FormCompute {
         }
         else
             this.remousResults.extraGraph = false;
-
-        // résultats numériques
-
-        this.remousResults.result = res;
-        const xValues = new ParamValues();
-        xValues.setValues(0, Long, Dx);
-        this.remousResults.xValues = xValues;
     }
 }
diff --git a/src/app/results/remous-results.ts b/src/app/results/remous-results.ts
index 1ef254c4c..c450fe10b 100644
--- a/src/app/results/remous-results.ts
+++ b/src/app/results/remous-results.ts
@@ -1,4 +1,4 @@
-import { cLog, Result, ResultElement, ParamValues } from "jalhyd";
+import { cLog, Result, ResultElement, ParamValues, CourbeRemousParams } from "jalhyd";
 
 import { CalculatorResults } from "./calculator-results";
 
@@ -10,7 +10,7 @@ export class RemousResults extends CalculatorResults {
     /**
      * hauteur de berge
      */
-    private _hautBerge: ResultElement;
+    private _hautBerge: number;
 
     /**
      * pente du fond
@@ -75,6 +75,24 @@ export class RemousResults extends CalculatorResults {
         this._extraGraph = false;
     }
 
+    public set parameters(p: CourbeRemousParams) {
+        // pente du fond
+        this._penteFond = p.map.If.v;
+
+        // hauteur de berge
+        this._hautBerge = p.map.YB.v;
+
+        // longueur du bief
+        const Long = p.map.Long.v;
+
+        // pas d'espace
+        const Dx = p.map.Dx.v;
+
+        // série de valeurs de X
+        this._xValues = new ParamValues();
+        this._xValues.setValues(0, Long, Dx);
+    }
+
     public get log() {
         return this._log;
     }
@@ -83,10 +101,6 @@ export class RemousResults extends CalculatorResults {
         return this._xValues;
     }
 
-    public set xValues(p: ParamValues) {
-        this._xValues = p;
-    }
-
     public get result(): Result {
         return this._result;
     }
@@ -122,18 +136,10 @@ export class RemousResults extends CalculatorResults {
         return this._hautBerge;
     }
 
-    public set hauteurBerge(v: ResultElement) {
-        this._hautBerge = v;
-    }
-
     public get penteFond() {
         return this._penteFond;
     }
 
-    public set penteFond(v: number) {
-        this._penteFond = v;
-    }
-
     public get hautNormale() {
         return this._hautNormale;
     }
-- 
GitLab


From f206657f926c3a4e2d04762d1f32e9e631dbaae3 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 5 Apr 2018 15:52:58 +0200
Subject: [PATCH 15/53] =?UTF-8?q?=20#77=20adaptation=20de=20la=20passe=20?=
 =?UTF-8?q?=C3=A0=20bassins=20(dimensions)=20=C3=A0=20la=20factory=20de=20?=
 =?UTF-8?q?Nub?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../definition/concrete/form-passe-bassin-dim.ts   |  3 ++-
 .../definition/form-compute-pab-bassin-dim.ts      | 14 ++------------
 2 files changed, 4 insertions(+), 13 deletions(-)

diff --git a/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts b/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
index 7869967dc..1f88cf6fb 100644
--- a/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
+++ b/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
@@ -1,4 +1,4 @@
-import { CalculatorType } from "jalhyd";
+import { CalculatorType, ComputeNodeType } from "jalhyd";
 
 import { CalculatorResults } from "../../../results/calculator-results";
 import { FormulaireDefinition } from "../form-definition";
@@ -27,6 +27,7 @@ export class FormulairePasseBassinDimensions extends FormulaireDefinition {
     }
 
     protected createNubs() {
+        this._nubs.set(ComputeNodeType.None, this.paramService.createNub(this.calculatorType));
     }
 
     protected initParse() {
diff --git a/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts b/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts
index 30c1d82d4..312748d43 100644
--- a/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts
+++ b/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts
@@ -1,4 +1,4 @@
-import { ComputeNode, ParamsEquation, PabDimensionParams, PabDimension } from "jalhyd";
+import { ComputeNode, ParamsEquation, PabDimensionParams, PabDimension, ComputeNodeType } from "jalhyd";
 
 import { FormComputeFixedVar } from "./form-compute-fixedvar";
 import { FormulaireDefinition } from "./form-definition";
@@ -9,17 +9,7 @@ export class FormComputePasseBassinDimensions extends FormComputeFixedVar {
         super(formBase, formResult);
     }
 
-    public getNubAndParameters(): [ComputeNode, ParamsEquation] {
-        let L: number = this._formBase.getParameterValue("L"); // longueur L
-        let W: number = this._formBase.getParameterValue("W"); // largeur W
-        let Y: number = this._formBase.getParameterValue("Y"); // tirant d'eau Y
-        let V: number = this._formBase.getParameterValue("V"); // volume V
-        let prms = new PabDimensionParams(L, W, Y, V);
-        let nub = new PabDimension(prms); // pour initialiser la calculabilité des paramètres
-        return [nub, prms];
-    }
-
     protected getCurrentNub() {
-        return undefined;
+        return this._formBase.getNub(ComputeNodeType.None);
     }
 }
\ No newline at end of file
-- 
GitLab


From 97b783e777246cb3742ca41986e2b27ef5575e77 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 5 Apr 2018 15:55:37 +0200
Subject: [PATCH 16/53] =?UTF-8?q?=20#77=20adaptation=20de=20la=20passe=20?=
 =?UTF-8?q?=C3=A0=20bassins=20(puissance=20dissip=C3=A9e)=20=C3=A0=20la=20?=
 =?UTF-8?q?factory=20de=20Nub?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../concrete/form-passe-bassin-puissance.ts        |  4 +++-
 .../form-compute-pab-bassin-puissance.ts           | 14 ++------------
 2 files changed, 5 insertions(+), 13 deletions(-)

diff --git a/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts b/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
index 2dd9ae040..b01541152 100644
--- a/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
+++ b/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
@@ -1,8 +1,9 @@
+import { CalculatorType, ComputeNodeType } from "jalhyd";
+
 import { FormDefFixedVar } from "../form-def-fixedvar";
 import { FormResultFixedVar } from "../form-result-fixedvar";
 import { ApplicationSetupService } from "../../../services/app-setup/app-setup.service";
 import { ParamService } from "../../../services/param/param.service";
-import { CalculatorType } from "jalhyd";
 import { FormulaireDefinition } from "../form-definition";
 import { FormComputePasseBassinPuissance } from "../form-compute-pab-bassin-puissance";
 import { CalculatorResults } from "../../../results/calculator-results";
@@ -26,6 +27,7 @@ export class FormulairePasseBassinPuissance extends FormulaireDefinition {
     }
 
     protected createNubs() {
+        this._nubs.set(ComputeNodeType.None, this.paramService.createNub(this.calculatorType));
     }
 
     protected initParse() {
diff --git a/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts b/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts
index c8bd05ea4..e7d689de3 100644
--- a/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts
+++ b/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts
@@ -1,4 +1,4 @@
-import { ComputeNode, ParamsEquation, PabPuissanceParams, PabPuissance } from "jalhyd";
+import { ComputeNode, ParamsEquation, PabPuissanceParams, PabPuissance, ComputeNodeType } from "jalhyd";
 
 import { FormComputeFixedVar } from "./form-compute-fixedvar";
 import { FormulaireDefinition } from "./form-definition";
@@ -9,17 +9,7 @@ export class FormComputePasseBassinPuissance extends FormComputeFixedVar {
         super(formBase, formResult);
     }
 
-    public getNubAndParameters(): [ComputeNode, ParamsEquation] {
-        let DH: number = this._formBase.getParameterValue("DH");  // Chute entre bassins
-        let Q: number = this._formBase.getParameterValue("Q"); // Débit 
-        let V: number = this._formBase.getParameterValue("V"); // volume V
-        let Pv: number = this._formBase.getParameterValue("Pv"); // puissance dissipée
-        let prms = new PabPuissanceParams(DH, Q, V, Pv);
-        let nub = new PabPuissance(prms); // pour initialiser la calculabilité des paramètres
-        return [nub, prms];
-    }
-
     protected getCurrentNub() {
-        return undefined;
+        return this._formBase.getNub(ComputeNodeType.None);
     }
 }
\ No newline at end of file
-- 
GitLab


From 24434498b4ae4f0d5840b8a43bcbd582ed50fcf2 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Mon, 9 Apr 2018 09:58:13 +0200
Subject: [PATCH 17/53]  #77 regroupement des instances de services dans un
 singleton (ServiceFactory)

---
 src/app/app.component.ts                      | 13 ++++-
 .../definition/concrete/form-cond-distri.ts   |  6 +-
 .../definition/concrete/form-courbe-remous.ts |  8 +--
 .../concrete/form-lechapt-calmon.ts           |  6 +-
 .../concrete/form-parallel-structures.ts      |  9 +--
 .../concrete/form-passe-bassin-dim.ts         |  6 +-
 .../concrete/form-passe-bassin-puissance.ts   |  6 +-
 .../concrete/form-regime-uniforme.ts          |  8 +--
 .../concrete/form-section-parametree.ts       | 14 ++---
 .../form-compute-section-parametree.ts        | 12 ++--
 .../formulaire/definition/form-def-section.ts |  3 +-
 .../formulaire/definition/form-definition.ts  | 14 ++---
 src/app/formulaire/fieldset.ts                | 11 ++--
 src/app/formulaire/ngparam.ts                 |  3 +-
 .../services/formulaire/formulaire.service.ts | 55 ++++++++++---------
 src/app/services/param/param.service.ts       | 15 +++--
 src/app/services/service-factory.ts           | 24 ++++++++
 17 files changed, 118 insertions(+), 95 deletions(-)
 create mode 100644 src/app/services/service-factory.ts

diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index f78f761a4..4df3529cb 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -9,6 +9,10 @@ import { ErrorService } from './services/error/error.service';
 // import { AlertDialog } from './components/alert-dialog/alert-dialog.component';
 import { FormulaireService } from './services/formulaire/formulaire.service';
 import { FormulaireDefinition } from './formulaire/definition/form-definition';
+import { ServiceFactory } from './services/service-factory';
+import { ParamService } from './services/param/param.service';
+import { ApplicationSetupService } from './services/app-setup/app-setup.service';
+import { HttpService } from './services/http/http.service';
 
 
 @Component({
@@ -29,11 +33,18 @@ export class AppComponent implements OnInit, OnDestroy, Observer {
 
   // constructor(private intlService: InternationalisationService, private appRef: ApplicationRef, private dialog: MdDialog, private errorService: ErrorService) { }
   constructor(private intlService: InternationalisationService,
+    private paramService: ParamService,
+    private appSetupService: ApplicationSetupService,
     private appRef: ApplicationRef,
     private errorService: ErrorService,
     private router: Router,
-    private formulaireService: FormulaireService
+    private formulaireService: FormulaireService,
+    private httpService: HttpService
   ) {
+    ServiceFactory.instance.applicationSetupService = appSetupService;
+    ServiceFactory.instance.paramService = paramService;
+    ServiceFactory.instance.internationalisationService = intlService;
+    ServiceFactory.instance.httpService = httpService;
   }
 
   // process.on('unhandledRejection', (reason, p) => {
diff --git a/src/app/formulaire/definition/concrete/form-cond-distri.ts b/src/app/formulaire/definition/concrete/form-cond-distri.ts
index a150653e0..5964fce09 100644
--- a/src/app/formulaire/definition/concrete/form-cond-distri.ts
+++ b/src/app/formulaire/definition/concrete/form-cond-distri.ts
@@ -1,7 +1,5 @@
 import { FormDefFixedVar } from "../form-def-fixedvar";
 import { CalculatorType, ComputeNodeType } from "jalhyd";
-import { ParamService } from "../../../services/param/param.service";
-import { ApplicationSetupService } from "../../../services/app-setup/app-setup.service";
 import { FormResultFixedVar } from "../form-result-fixedvar";
 import { FormComputeConduiteDistributrice } from "../form-compute-cond-distri";
 import { FormulaireDefinition } from "../form-definition";
@@ -17,8 +15,8 @@ export class FormulaireConduiteDistributrice extends FormulaireDefinition {
 
     private _formResult: FormResultFixedVar;
 
-    constructor(paramService: ParamService, appSetupService: ApplicationSetupService) {
-        super(CalculatorType.ConduiteDistributrice, paramService, appSetupService);
+    constructor() {
+        super(CalculatorType.ConduiteDistributrice);
         this._formFixedVar = new FormDefFixedVar(this);
         this._formParamCalc = new FormDefParamToCalculate(this);
         this._formResult = new FormResultFixedVar(this, false);
diff --git a/src/app/formulaire/definition/concrete/form-courbe-remous.ts b/src/app/formulaire/definition/concrete/form-courbe-remous.ts
index af674161b..7abfe545a 100644
--- a/src/app/formulaire/definition/concrete/form-courbe-remous.ts
+++ b/src/app/formulaire/definition/concrete/form-courbe-remous.ts
@@ -1,7 +1,5 @@
 import { CalculatorType, ComputeNodeType } from "jalhyd";
 
-import { ParamService } from "../../../services/param/param.service";
-import { ApplicationSetupService } from "../../../services/app-setup/app-setup.service";
 import { FormResultRemous } from "../form-result-remous";
 import { FormDefSection } from "../form-def-section";
 import { FormComputeCourbeRemous } from "../form-compute-courbe-remous";
@@ -15,9 +13,9 @@ export class FormulaireCourbeRemous extends FormulaireDefinition {
 
     private _formResult: FormResultRemous;
 
-    constructor(paramService: ParamService, appSetupService: ApplicationSetupService) {
-        super(CalculatorType.CourbeRemous, paramService, appSetupService)
-        this._formSection = new FormDefSection(this, appSetupService);
+    constructor() {
+        super(CalculatorType.CourbeRemous)
+        this._formSection = new FormDefSection(this);
         this._formResult = new FormResultRemous(this);
         this._formCompute = new FormComputeCourbeRemous(this, this._formSection, this._formResult);
     }
diff --git a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
index ec897fb98..5159fc3bc 100644
--- a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
+++ b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
@@ -1,8 +1,6 @@
 import { CalculatorType, ComputeNodeType } from "jalhyd";
 
 import { FormResultFixedVar } from "../form-result-fixedvar";
-import { ParamService } from "../../../services/param/param.service";
-import { ApplicationSetupService } from "../../../services/app-setup/app-setup.service";
 import { FormDefFixedVar } from "../form-def-fixedvar";
 import { FormComputeLechaptCalmon } from "../form-compute-lechapt-calmon";
 import { FormulaireDefinition } from "../form-definition";
@@ -20,8 +18,8 @@ export class FormulaireLechaptCalmon extends FormulaireDefinition implements Obs
 
     private _formResult: FormResultFixedVar;
 
-    constructor(paramService: ParamService, appSetupService: ApplicationSetupService) {
-        super(CalculatorType.LechaptCalmon, paramService, appSetupService)
+    constructor() {
+        super(CalculatorType.LechaptCalmon)
         this._formFixedVar = new FormDefFixedVar(this);
         this._formParamCalc = new FormDefParamToCalculate(this);
         this._formResult = new FormResultFixedVar(this, false);
diff --git a/src/app/formulaire/definition/concrete/form-parallel-structures.ts b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
index 963b7d918..32ec98830 100644
--- a/src/app/formulaire/definition/concrete/form-parallel-structures.ts
+++ b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
@@ -1,8 +1,9 @@
+import { CalculatorType, CreateStructure, StructureType, LoiDebit, ComputeNodeType, Structure, ParallelStructure } from "jalhyd";
+
 import { FormulaireDefinition } from "../form-definition";
 import { CalculatorResults } from "../../../results/calculator-results";
-import { CalculatorType, CreateStructure, StructureType, LoiDebit } from "jalhyd";
+import { ServiceFactory } from "../../../services/service-factory";
 import { ParamService } from "../../../services/param/param.service";
-import { ApplicationSetupService } from "../../../services/app-setup/app-setup.service";
 import { FormDefParamToCalculate } from "../form-def-paramcalc";
 import { FormDefFixedVar } from "../form-def-fixedvar";
 import { FormDefParallelStructures } from "../form-def-parallel-structures";
@@ -24,8 +25,8 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
 
     private _formResult: FormResultFixedVar;
 
-    constructor(paramService: ParamService, appSetupService: ApplicationSetupService) {
-        super(CalculatorType.ParallelStructure, paramService, appSetupService)
+    constructor() {
+        super(CalculatorType.ParallelStructure)
         this._formFixedVar = new FormDefFixedVar(this);
         this._formParamCalc = new FormDefParamToCalculate(this);
         this._formResult = new FormResultFixedVar(this, false);
diff --git a/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts b/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
index 1f88cf6fb..3ab083098 100644
--- a/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
+++ b/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
@@ -6,8 +6,6 @@ import { FormDefFixedVar } from "../form-def-fixedvar";
 import { FormDefParamToCalculate } from "../form-def-paramcalc";
 import { FormComputePasseBassinDimensions } from "../form-compute-pab-bassin-dim";
 import { FormResultFixedVar } from "../form-result-fixedvar";
-import { ParamService } from "../../../services/param/param.service";
-import { ApplicationSetupService } from "../../../services/app-setup/app-setup.service";
 
 export class FormulairePasseBassinDimensions extends FormulaireDefinition {
     private _formFixedVar: FormDefFixedVar;
@@ -18,8 +16,8 @@ export class FormulairePasseBassinDimensions extends FormulaireDefinition {
 
     private _formResult: FormResultFixedVar;
 
-    constructor(paramService: ParamService, appSetupService: ApplicationSetupService) {
-        super(CalculatorType.PabDimensions, paramService, appSetupService);
+    constructor() {
+        super(CalculatorType.PabDimensions);
         this._formFixedVar = new FormDefFixedVar(this);
         this._formParamCalc = new FormDefParamToCalculate(this);
         this._formResult = new FormResultFixedVar(this, false);
diff --git a/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts b/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
index b01541152..e01964dba 100644
--- a/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
+++ b/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
@@ -2,8 +2,6 @@ import { CalculatorType, ComputeNodeType } from "jalhyd";
 
 import { FormDefFixedVar } from "../form-def-fixedvar";
 import { FormResultFixedVar } from "../form-result-fixedvar";
-import { ApplicationSetupService } from "../../../services/app-setup/app-setup.service";
-import { ParamService } from "../../../services/param/param.service";
 import { FormulaireDefinition } from "../form-definition";
 import { FormComputePasseBassinPuissance } from "../form-compute-pab-bassin-puissance";
 import { CalculatorResults } from "../../../results/calculator-results";
@@ -18,8 +16,8 @@ export class FormulairePasseBassinPuissance extends FormulaireDefinition {
 
     private _formResult: FormResultFixedVar;
 
-    constructor(paramService: ParamService, appSetupService: ApplicationSetupService) {
-        super(CalculatorType.PabPuissance, paramService, appSetupService);
+    constructor() {
+        super(CalculatorType.PabPuissance);
         this._formFixedVar = new FormDefFixedVar(this);
         this._formParamCalc = new FormDefParamToCalculate(this);
         this._formResult = new FormResultFixedVar(this, false);
diff --git a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
index 41395d592..958dbd6fb 100644
--- a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
+++ b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
@@ -1,7 +1,5 @@
 import { FormDefFixedVar } from "../form-def-fixedvar";
 import { CalculatorType, ComputeNodeType } from "jalhyd";
-import { ParamService } from "../../../services/param/param.service";
-import { ApplicationSetupService } from "../../../services/app-setup/app-setup.service";
 import { FormResultFixedVar } from "../form-result-fixedvar";
 import { FormulaireDefinition } from "../form-definition";
 import { FormComputeRegimeUniforme } from "../form-compute-regime-uniforme";
@@ -20,11 +18,11 @@ export class FormulaireRegimeUniforme extends FormulaireDefinition {
 
     private _formResult: FormResultFixedVar;
 
-    constructor(paramService: ParamService, appSetupService: ApplicationSetupService) {
-        super(CalculatorType.RegimeUniforme, paramService, appSetupService)
+    constructor() {
+        super(CalculatorType.RegimeUniforme)
         this._formFixedVar = new FormDefFixedVar(this);
         this._formParamCalc = new FormDefParamToCalculate(this);
-        this._formSection = new FormDefSection(this, appSetupService);
+        this._formSection = new FormDefSection(this);
         this._formResult = new FormResultFixedVar(this, true);
         this._formCompute = new FormComputeRegimeUniforme(this, this._formSection, this._formResult);
     }
diff --git a/src/app/formulaire/definition/concrete/form-section-parametree.ts b/src/app/formulaire/definition/concrete/form-section-parametree.ts
index 6f5e84835..6737d69bd 100644
--- a/src/app/formulaire/definition/concrete/form-section-parametree.ts
+++ b/src/app/formulaire/definition/concrete/form-section-parametree.ts
@@ -1,8 +1,6 @@
 import { CalculatorType, acSection, ParamsEquation, ComputeNodeType } from "jalhyd";
 
 import { FormResultSection } from "../form-result-section";
-import { ParamService } from "../../../services/param/param.service";
-import { ApplicationSetupService } from "../../../services/app-setup/app-setup.service";
 import { FormDefSection } from "../form-def-section";
 import { NgParameter } from "../../ngparam";
 import { InputField } from "../../input-field";
@@ -21,16 +19,12 @@ export class FormulaireSectionParametree extends FormulaireDefinition {
 
     private _formSectionResult: FormResultSection;
 
-    constructor(
-        paramService: ParamService,
-        appSetupService: ApplicationSetupService,
-        intlService: InternationalisationService
-    ) {
-        super(CalculatorType.SectionParametree, paramService, appSetupService);
+    constructor() {
+        super(CalculatorType.SectionParametree);
         this._formFixedVar = new FormDefFixedVar(this);
-        this._formSection = new FormDefSection(this, appSetupService);
+        this._formSection = new FormDefSection(this);
         this._formSectionResult = new FormResultSection(this, this._formSection);
-        this._formCompute = new FormComputeSectionParametree(this, this._formSection, this._formSectionResult, intlService, paramService);
+        this._formCompute = new FormComputeSectionParametree(this, this._formSection, this._formSectionResult);
     }
 
     protected createNubs() {
diff --git a/src/app/formulaire/definition/form-compute-section-parametree.ts b/src/app/formulaire/definition/form-compute-section-parametree.ts
index 864d8b6e4..3b695217c 100644
--- a/src/app/formulaire/definition/form-compute-section-parametree.ts
+++ b/src/app/formulaire/definition/form-compute-section-parametree.ts
@@ -7,19 +7,19 @@ import { Form } from "@angular/forms";
 import { FormDefSection } from "./form-def-section";
 import { FormResultSection } from "./form-result-section";
 import { InputField } from "../input-field";
-import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
 import { FixedResults } from "../../results/fixed-results";
 import { VarResults } from "../../results/var-results";
 import { SectionResults } from "../../results/section-results";
 import { FormulaireDefinition } from "./form-definition";
+import { ServiceFactory } from "../../services/service-factory";
 import { ParamService } from "../../services/param/param.service";
 
 export class FormComputeSectionParametree extends FormCompute {
-    constructor(formBase: FormulaireDefinition, private _formSection: FormDefSection, formResult: FormResult,
-        private intlService: InternationalisationService,
-        private paramService: ParamService
-    ) {
+    private _paramService: ParamService;
+
+    constructor(formBase: FormulaireDefinition, private _formSection: FormDefSection, formResult: FormResult) {
         super(formBase, formResult);
+        this._paramService = ServiceFactory.instance.paramService;
     }
 
     private get _formSectionResult(): FormResultSection {
@@ -63,7 +63,7 @@ export class FormComputeSectionParametree extends FormCompute {
 
         this._varResults.variatedParameter = varParam;
 
-        const computedParam: NgParameter = this.paramService.createParameter(computedParamInfo.symbol);
+        const computedParam: NgParameter = this._paramService.createParameter(computedParamInfo.symbol);
         this._varResults.calculatedParameter = computedParam;
 
         let compSymbol: string = computedParamInfo["symbol"];
diff --git a/src/app/formulaire/definition/form-def-section.ts b/src/app/formulaire/definition/form-def-section.ts
index d99c7ae5e..5cdf380a1 100644
--- a/src/app/formulaire/definition/form-def-section.ts
+++ b/src/app/formulaire/definition/form-def-section.ts
@@ -7,7 +7,6 @@ import { SelectField } from "../select-field";
 import { Field } from "../field";
 import { IObservable, Observer } from "../../services/observer";
 import { NgParameter, ParamRadioConfig } from "../ngparam";
-import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
 import { FormulaireDefinition } from "./form-definition";
 
 export class FormDefSection implements Observer {
@@ -24,7 +23,7 @@ export class FormDefSection implements Observer {
 
     private _formBase: FormulaireDefinition;
 
-    constructor(base: FormulaireDefinition, private appSetupService: ApplicationSetupService) {
+    constructor(base: FormulaireDefinition) {
         this._formBase = base;
     }
 
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 92f52fcec..6eec33bc9 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -4,7 +4,7 @@ import { NgParameter, ParamRadioConfig } from "../ngparam";
 import { Field } from "../field";
 import { StringMap } from "../../stringmap";
 import { FormulaireNode } from "../formulaire-node";
-import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
+import { ServiceFactory } from "../../services/service-factory";
 import { ParamService } from "../../services/param/param.service";
 import { FieldSet } from "../fieldset";
 import { FieldsetContainer } from "../fieldset-container";
@@ -33,13 +33,14 @@ export abstract class FormulaireDefinition extends FormulaireNode {
      */
     protected _nubs: Map<ComputeNodeType, Nub>;
 
+    protected _paramService: ParamService;
+
     constructor(calcType: CalculatorType,
-        protected paramService: ParamService,
-        private appSetupService: ApplicationSetupService
     ) {
         super();
         this._calcType = calcType;
         this._nubs = new Map();
+        this._paramService = ServiceFactory.instance.paramService;
     }
 
     public get calculatorType(): CalculatorType {
@@ -104,12 +105,7 @@ export abstract class FormulaireDefinition extends FormulaireNode {
         let calc_type: CalculatorType = ct == undefined ? this._calcType : CalculatorType[ct];
 
         const res: FieldSet = new FieldSet(calc_type, json["type"] === "fieldset_template");
-        res.parseConfig(json,
-            {
-                "paramService": this.paramService,
-                "appSetupService": this.appSetupService,
-                "parentForm": this
-            });
+        res.parseConfig(json, { "parentForm": this });
         return res;
     }
 
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 4094c69d2..384e9f1e2 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -7,8 +7,8 @@ import { Field } from "./field";
 import { CheckField } from "./check-field";
 import { SelectField } from "./select-field";
 import { NgParameter, ParamRadioConfig } from "./ngparam";
+import { ServiceFactory } from "../services/service-factory";
 import { ParamService } from "../services/param/param.service";
-import { ApplicationSetupService } from "../services/app-setup/app-setup.service";
 import { FormulaireDefinition } from "./definition/form-definition";
 
 export class FieldSet extends FormulaireElement {
@@ -86,8 +86,9 @@ export class FieldSet extends FormulaireElement {
         return res;
     }
 
-    private parse_input(json: {}, parentForm: FormulaireDefinition, default_radio_config: string, paramService: ParamService, appSetupService: ApplicationSetupService): NgParameter {
+    private parse_input(json: {}, parentForm: FormulaireDefinition, default_radio_config: string): NgParameter {
         const input_id: string = json["id"];
+        const paramService: ParamService = ServiceFactory.instance.paramService;
 
         switch (input_id) {
             case "Pr":
@@ -104,14 +105,12 @@ export class FieldSet extends FormulaireElement {
                 res = new NgParameter(nubParam, this.isTemplate);
         }
 
-        res.parseConfig(json, { "appSetupService": appSetupService, "radioConfig": default_radio_config });
+        res.parseConfig(json, { "radioConfig": default_radio_config });
 
         return res;
     }
 
     public parseConfig(json: {}, data?: {}) {
-        const paramService: ParamService = data["paramService"];
-        const appSetupService: ApplicationSetupService = data["appSetupService"];
         const parentForm: FormulaireDefinition = data["parentForm"];
 
         this._confId = json["id"];
@@ -125,7 +124,7 @@ export class FieldSet extends FormulaireElement {
 
             if (field["type"] === "input") {
                 const default_radio_config = json["option"];
-                const param = this.parse_input(field, parentForm, default_radio_config, paramService, appSetupService);
+                const param = this.parse_input(field, parentForm, default_radio_config);
                 this.addField(param);
             } else if (field["type"] === "select") {
                 const param = this.parse_select(field);
diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts
index 51b387486..56a13c093 100644
--- a/src/app/formulaire/ngparam.ts
+++ b/src/app/formulaire/ngparam.ts
@@ -5,6 +5,7 @@ import { Dependency } from "./dependency/dependency";
 import { DependencyConditionType } from "./dependency/dependency-condition";
 import { ValueDependencyCondition } from "./dependency/value-dependency-condition";
 import { FormulaireDefinition } from "./definition/form-definition";
+import { ServiceFactory } from "../services/service-factory";
 import { ApplicationSetupService } from "../services/app-setup/app-setup.service";
 import { StringMap } from "../stringmap";
 
@@ -355,7 +356,7 @@ export class NgParameter extends InputField {
     }
 
     public parseConfig(json: {}, data?: {}) {
-        const appSetupService: ApplicationSetupService = data["appSetupService"];
+        const appSetupService: ApplicationSetupService = ServiceFactory.instance.applicationSetupService;
         const radioConfig: string = data["radioConfig"];
 
         this._confId = json["id"];
diff --git a/src/app/services/formulaire/formulaire.service.ts b/src/app/services/formulaire/formulaire.service.ts
index 0816946bb..2aac9462e 100644
--- a/src/app/services/formulaire/formulaire.service.ts
+++ b/src/app/services/formulaire/formulaire.service.ts
@@ -6,10 +6,9 @@ import { decode } from "he";
 
 import { CalculatorType, EnumEx } from "jalhyd";
 
-import { ParamService } from "../param/param.service";
+import { ServiceFactory } from "../service-factory";
 import { HttpService } from "../../services/http/http.service";
 import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
-import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
 import { FormulaireDefinition } from "../../formulaire/definition/form-definition";
 import { FormulaireElement } from "../../formulaire/formulaire-element";
 import { InputField } from "../../formulaire/input-field";
@@ -32,22 +31,26 @@ export class FormulaireService extends Observable {
 
     private _currentFormId = -1;
 
-    constructor(private paramService: ParamService,
-        private httpService: HttpService,
-        private intlService: InternationalisationService,
-        private appSetupService: ApplicationSetupService
-    ) {
+    constructor() {
         super();
         this._formulaires = [];
     }
 
+    private get _intlService(): InternationalisationService {
+        return ServiceFactory.instance.internationalisationService;
+    }
+
+    private get _httpService(): HttpService {
+        return ServiceFactory.instance.httpService;
+    }
+
     public get formulaires(): FormulaireDefinition[] {
         return this._formulaires;
     }
 
     private loadLocalisation(calc: CalculatorType): Promise<any> {
-        let f: string = this.getConfigPathPrefix(calc) + this.intlService.currentLanguage.tag + ".json"
-        let resp: rxObservable<Response> = this.httpService.httpGetRequestResponse(undefined, undefined, undefined, f);
+        let f: string = this.getConfigPathPrefix(calc) + this._intlService.currentLanguage.tag + ".json"
+        let resp: rxObservable<Response> = this._httpService.httpGetRequestResponse(undefined, undefined, undefined, f);
 
         let prom = resp.map(res => res.text()).toPromise();
         return prom.then((res) => {
@@ -94,28 +97,28 @@ export class FormulaireService extends Observable {
     public getLocalisedTitleFromCalculatorType(type: CalculatorType) {
         switch (type) {
             case CalculatorType.ConduiteDistributrice:
-                return this.intlService.localizeText("INFO_CONDDISTRI_TITRE");
+                return this._intlService.localizeText("INFO_CONDDISTRI_TITRE");
 
             case CalculatorType.LechaptCalmon:
-                return this.intlService.localizeText("INFO_LECHAPT_TITRE");
+                return this._intlService.localizeText("INFO_LECHAPT_TITRE");
 
             case CalculatorType.RegimeUniforme:
-                return this.intlService.localizeText("INFO_REGUNI_TITRE");
+                return this._intlService.localizeText("INFO_REGUNI_TITRE");
 
             case CalculatorType.SectionParametree:
-                return this.intlService.localizeText("INFO_SECTPARAM_TITRE");
+                return this._intlService.localizeText("INFO_SECTPARAM_TITRE");
 
             case CalculatorType.CourbeRemous:
-                return this.intlService.localizeText("INFO_REMOUS_TITRE")
+                return this._intlService.localizeText("INFO_REMOUS_TITRE")
 
             case CalculatorType.PabDimensions:
-                return this.intlService.localizeText("INFO_PABDIM_TITRE")
+                return this._intlService.localizeText("INFO_PABDIM_TITRE")
 
             case CalculatorType.PabPuissance:
-                return this.intlService.localizeText("INFO_PABPUISS_TITRE")
+                return this._intlService.localizeText("INFO_PABPUISS_TITRE")
 
             case CalculatorType.ParallelStructure:
-                return this.intlService.localizeText("INFO_OUVRAGEPARAL_TITRE")
+                return this._intlService.localizeText("INFO_OUVRAGEPARAL_TITRE")
 
             default:
                 return "Invalid calculator type " + type;
@@ -128,42 +131,42 @@ export class FormulaireService extends Observable {
         }
 
         let f: string = this.getConfigPathPrefix(ct) + "config.json"
-        return this.httpService.httpGetRequest(undefined, undefined, undefined, f, processData);
+        return this._httpService.httpGetRequest(undefined, undefined, undefined, f, processData);
     }
 
     public createFormulaire(ct: CalculatorType): Promise<FormulaireDefinition> {
         let f: FormulaireDefinition;
         switch (ct) {
             case CalculatorType.ConduiteDistributrice:
-                f = new FormulaireConduiteDistributrice(this.paramService, this.appSetupService);
+                f = new FormulaireConduiteDistributrice();
                 break;
 
             case CalculatorType.LechaptCalmon:
-                f = new FormulaireLechaptCalmon(this.paramService, this.appSetupService);
+                f = new FormulaireLechaptCalmon();
                 break;
 
             case CalculatorType.SectionParametree:
-                f = new FormulaireSectionParametree(this.paramService, this.appSetupService, this.intlService);
+                f = new FormulaireSectionParametree();
                 break;
 
             case CalculatorType.RegimeUniforme:
-                f = new FormulaireRegimeUniforme(this.paramService, this.appSetupService);
+                f = new FormulaireRegimeUniforme();
                 break;
 
             case CalculatorType.CourbeRemous:
-                f = new FormulaireCourbeRemous(this.paramService, this.appSetupService);
+                f = new FormulaireCourbeRemous();
                 break;
 
             case CalculatorType.PabDimensions:
-                f = new FormulairePasseBassinDimensions(this.paramService, this.appSetupService);
+                f = new FormulairePasseBassinDimensions();
                 break;
 
             case CalculatorType.PabPuissance:
-                f = new FormulairePasseBassinPuissance(this.paramService, this.appSetupService);
+                f = new FormulairePasseBassinPuissance();
                 break;
 
             case CalculatorType.ParallelStructure:
-                f = new FormulaireParallelStructure(this.paramService, this.appSetupService);
+                f = new FormulaireParallelStructure();
                 break;
 
             default:
diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts
index 902774585..e53d3bd0d 100644
--- a/src/app/services/param/param.service.ts
+++ b/src/app/services/param/param.service.ts
@@ -2,17 +2,24 @@ import { ParamDomain, ComputeNodeType, ParamDefinition, ParamDomainValue, ParamC
 
 import { NgParameter } from "../../formulaire/ngparam";
 import { FormulaireDefinition } from "../../formulaire/definition/form-definition";
-import { InternationalisationService } from "../internationalisation/internationalisation.service";
 import { Injectable } from "@angular/core";
+import { ServiceFactory } from "../service-factory";
+import { InternationalisationService } from "../internationalisation/internationalisation.service";
 import { ApplicationSetupService } from "../app-setup/app-setup.service";
 
 @Injectable()
 export class ParamService {
-    constructor(private intlService: InternationalisationService, private appSetupService: ApplicationSetupService) { }
+    private get _intlService(): InternationalisationService {
+        return ServiceFactory.instance.internationalisationService;
+    }
+
+    private get _appSetupService(): ApplicationSetupService {
+        return ServiceFactory.instance.applicationSetupService;
+    }
 
     private createAccuracyParameter(): ParamDefinition {
         const d = new ParamDomain(ParamDomainValue.INTERVAL, 1e-10, 100);
-        const p = new ParamDefinition('Pr', d, this.appSetupService.computePrecision);
+        const p = new ParamDefinition('Pr', d, this._appSetupService.computePrecision);
         p.calculability = ParamCalculability.FREE;
         return p;
     }
@@ -98,7 +105,7 @@ export class ParamService {
             }
         }
 
-        p.updateLocalisation(this.intlService.currentMap);
+        p.updateLocalisation(this._intlService.currentMap);
         return p;
     }
 
diff --git a/src/app/services/service-factory.ts b/src/app/services/service-factory.ts
new file mode 100644
index 000000000..65b08fa1e
--- /dev/null
+++ b/src/app/services/service-factory.ts
@@ -0,0 +1,24 @@
+import { ApplicationSetupService } from "./app-setup/app-setup.service";
+import { ParamService } from "./param/param.service";
+import { InternationalisationService } from "./internationalisation/internationalisation.service";
+import { HttpService } from "./http/http.service";
+
+export class ServiceFactory {
+    private static _instance: ServiceFactory; // instance pour le pattern singleton
+
+    private constructor() { }
+
+    public applicationSetupService: ApplicationSetupService;
+
+    public paramService: ParamService;
+
+    public internationalisationService: InternationalisationService;
+
+    public httpService: HttpService;
+
+    public static get instance() {
+        if (ServiceFactory._instance == undefined)
+            ServiceFactory._instance = new ServiceFactory();
+        return ServiceFactory._instance;
+    }
+}
-- 
GitLab


From f4bc677eb57775dc8007a1f9d94657fa348ecf7e Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Tue, 10 Apr 2018 14:03:27 +0200
Subject: [PATCH 18/53] =?UTF-8?q?=20#77=20correction=20d'un=20bug=20d'affi?=
 =?UTF-8?q?chage=20des=20r=C3=A9sultats?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../result-element/result-element-base.component.ts           | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/app/components/result-element/result-element-base.component.ts b/src/app/components/result-element/result-element-base.component.ts
index caf5db9c1..16e9a84cd 100644
--- a/src/app/components/result-element/result-element-base.component.ts
+++ b/src/app/components/result-element/result-element-base.component.ts
@@ -86,6 +86,10 @@ export class ResultElementBaseComponent implements OnChanges {
         this._emptyTooltip = this._htmlTooltip.length == 0;
     }
 
+    private get hasValue() {
+        return this._hasValue;
+    }
+
     private get resultValue(): string {
         return this._value;
     }
-- 
GitLab


From c6713daab0dd650cd88b10abf02f373b68048cf8 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Tue, 10 Apr 2018 14:16:08 +0200
Subject: [PATCH 19/53] =?UTF-8?q?=20#77=20suppression=20de=20FormCompute.i?=
 =?UTF-8?q?nitParametersValueMode()=20=20-=20transformation=20de=20NgParam?=
 =?UTF-8?q?eter.radioState=20en=20un=20getter=20reflettant=20l'=C3=A9tat?=
 =?UTF-8?q?=20de=20la=20propri=C3=A9t=C3=A9=20NgParam.valueMode?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../definition/form-compute-fixedvar.ts        |  2 --
 src/app/formulaire/definition/form-compute.ts  | 12 ------------
 .../definition/form-def-paramcalc.ts           |  6 ++++--
 src/app/formulaire/ngparam.ts                  | 18 +++++++++++++++---
 4 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/src/app/formulaire/definition/form-compute-fixedvar.ts b/src/app/formulaire/definition/form-compute-fixedvar.ts
index d862d7ef0..d5ae4c50b 100644
--- a/src/app/formulaire/definition/form-compute-fixedvar.ts
+++ b/src/app/formulaire/definition/form-compute-fixedvar.ts
@@ -51,8 +51,6 @@ export abstract class FormComputeFixedVar extends FormCompute {
         this.formResult.addFixedParameters();
 
         let varParam: NgParameter = this.getVariatedParameter();
-        this.initParametersValueMode(nub, computedParam, varParam, varParam && varParam.valueMode);
-
 
         if (varParam == undefined) {
             // pas de paramètre à varier
diff --git a/src/app/formulaire/definition/form-compute.ts b/src/app/formulaire/definition/form-compute.ts
index 79abc4ba5..f364ee0b1 100644
--- a/src/app/formulaire/definition/form-compute.ts
+++ b/src/app/formulaire/definition/form-compute.ts
@@ -16,18 +16,6 @@ export abstract class FormCompute {
         return this._formResult;
     }
 
-    /**
-     * 
-     * @param nub initialise le mode de génération de valeurs des paramètres d'un Nub
-     * @param computedParam paramètre à calculer
-     * @param variatedParam paramètre à varier
-     * @param variatedMode mode de génération du paramètre à varier
-     */
-    protected initParametersValueMode(nub: Nub, computedParam: NgParameter, variatedParam?: NgParameter, variatedMode?: ParamValueMode) {
-        nub.initParametersValueMode(computedParam.paramDefinition, variatedParam && variatedParam.paramDefinition, variatedMode);
-    }
-
-
     /**
      * lance le calcul d'un paramètre en déterminant une valeur initiale
      */
diff --git a/src/app/formulaire/definition/form-def-paramcalc.ts b/src/app/formulaire/definition/form-def-paramcalc.ts
index 1ff777b1d..c999d7a02 100644
--- a/src/app/formulaire/definition/form-def-paramcalc.ts
+++ b/src/app/formulaire/definition/form-def-paramcalc.ts
@@ -1,3 +1,5 @@
+import { ParamValueMode } from "jalhyd";
+
 import { ParamRadioConfig, NgParameter } from "../ngparam";
 import { FormulaireDefinition } from "./form-definition";
 import { FormDefFixedVar } from "./form-def-fixedvar";
@@ -26,7 +28,7 @@ export class FormDefParamToCalculate extends FormDefFixedVar {
         if (this._defaultCalculatedParam != undefined) {
             let p = this._formBase.getParamFromSymbol(this._defaultCalculatedParam);
             p.isDefault = true;
-            p.radioState = ParamRadioConfig.CAL;
+            p.valueMode = ParamValueMode.CALCUL;
         }
     }
 
@@ -35,7 +37,7 @@ export class FormDefParamToCalculate extends FormDefFixedVar {
      */
     private setDefault() {
         let defaultParamCal = this._formBase.getParamFromSymbol(this._defaultCalculatedParam);
-        defaultParamCal.radioState = ParamRadioConfig.CAL;
+        defaultParamCal.valueMode = ParamValueMode.CALCUL;
     }
 
     protected processRadioStateChange(sourceParam: NgParameter, oldState: ParamRadioConfig, newState: ParamRadioConfig) {
diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts
index 56a13c093..5fcebe23c 100644
--- a/src/app/formulaire/ngparam.ts
+++ b/src/app/formulaire/ngparam.ts
@@ -40,7 +40,6 @@ class Context {
 export class NgParameter extends InputField {
     public unit: string;
     public radioConfig: ParamRadioConfig;
-    public radioState: ParamRadioConfig;
 
     /**
      * true si ce paramètre est celui par défaut dans un formulaire (cf. fichier de conf des calculettes, objet "options", champ "idCal")
@@ -89,6 +88,20 @@ export class NgParameter extends InputField {
         return this._paramDef;
     }
 
+    public get radioState() {
+        switch (this._paramDef.paramValues.valueMode) {
+            case ParamValueMode.SINGLE:
+                return ParamRadioConfig.FIX;
+
+            case ParamValueMode.LISTE:
+            case ParamValueMode.MINMAX:
+                return ParamRadioConfig.VAR;
+
+            case ParamValueMode.CALCUL:
+                return ParamRadioConfig.CAL;
+        }
+    }
+
     /**
      * notification envoyée après la modification de la valeur du paramètre
      */
@@ -368,7 +381,7 @@ export class NgParameter extends InputField {
         if (val != undefined)
             this.setValue(this, +val);
         this.radioConfig = NgParameter.getRadioConfig(radioConfig);
-        this.radioState = ParamRadioConfig.FIX;
+        this.valueMode = ParamValueMode.SINGLE;
         this.isDefault = false; // malgré le fait qu'il soit initialisé dans la déclaration de la classe NgParam à false, quand on relit sa valeur, il vaut undefined (merci Microsoft)
     }
 
@@ -407,7 +420,6 @@ export class NgParameter extends InputField {
         super.copyMembers(n);
         n.unit = this.unit;
         n.radioConfig = this.radioConfig;
-        n.radioState = this.radioState;
         n.isDefault = this.isDefault;
         this._paramValues.copyMembers(n._paramValues);
     }
-- 
GitLab


From 01a0fb6870137e3b5396ead56c8a9c7a53c1c5d5 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Tue, 10 Apr 2018 15:49:31 +0200
Subject: [PATCH 20/53] =?UTF-8?q?=20#77=20correction=20d'un=20bug=20sur=20?=
 =?UTF-8?q?les=20radios=20"fix=C3=A9/=C3=A0=20varier/=C3=A0=20calculer"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../param-field-line.component.ts             |  3 +-
 .../definition/form-def-fixedvar.ts           | 48 ++++++++++++-------
 .../definition/form-def-paramcalc.ts          | 13 ++---
 3 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/src/app/components/param-field-line/param-field-line.component.ts b/src/app/components/param-field-line/param-field-line.component.ts
index ebee96d49..8d0575590 100644
--- a/src/app/components/param-field-line/param-field-line.component.ts
+++ b/src/app/components/param-field-line/param-field-line.component.ts
@@ -171,6 +171,7 @@ export class ParamFieldLineComponent implements OnChanges {
     private onRadio = new EventEmitter<any>();
 
     private onRadioClick(option: string) {
+        const oldValue = this._param.valueMode;
         switch (option) {
             case "fix":
                 this._param.valueMode = ParamValueMode.SINGLE;
@@ -187,7 +188,7 @@ export class ParamFieldLineComponent implements OnChanges {
 
         this.onRadio.emit({
             "param": this._param,
-            "option": option
+            "oldValueMode": oldValue
         });
 
         // MAJ validité
diff --git a/src/app/formulaire/definition/form-def-fixedvar.ts b/src/app/formulaire/definition/form-def-fixedvar.ts
index 75e0c71aa..b3711d5f6 100644
--- a/src/app/formulaire/definition/form-def-fixedvar.ts
+++ b/src/app/formulaire/definition/form-def-fixedvar.ts
@@ -1,3 +1,5 @@
+import { ParamValueMode } from "jalhyd";
+
 import { ParamRadioConfig, NgParameter } from "../ngparam";
 import { FormulaireDefinition } from "./form-definition";
 import { FormulaireElement } from "../formulaire-element";
@@ -21,27 +23,29 @@ export class FormDefFixedVar {
         for (const p of this._formBase.allFormElements) {
             if (p instanceof NgParameter)
                 if (p != me && p.radioState != except && p.radioConfig != ParamRadioConfig.FIX)
-                    p.radioState = ParamRadioConfig.FIX;
+                    p.valueMode = ParamValueMode.SINGLE;
         }
     }
 
-    protected processRadioStateChange(sourceParam: NgParameter, oldState: ParamRadioConfig, newState: ParamRadioConfig) {
+    protected processRadioStateChange(sourceParam: NgParameter, oldState: ParamValueMode) {
         switch (oldState) {
-            case ParamRadioConfig.FIX:
-                switch (newState) {
-                    case ParamRadioConfig.VAR:
+            case ParamValueMode.SINGLE:
+                switch (sourceParam.valueMode) { // nouvel état
+                    case ParamValueMode.MINMAX:
+                    case ParamValueMode.LISTE:
                         this.resetOtherRadio(sourceParam, ParamRadioConfig.CAL);
                         break;
 
-                    case ParamRadioConfig.CAL:
+                    case ParamValueMode.CALCUL:
                         this.resetOtherRadio(sourceParam, ParamRadioConfig.VAR);
                         break;
                 }
                 break;
 
-            case ParamRadioConfig.VAR:
-                switch (newState) {
-                    case ParamRadioConfig.CAL:
+            case ParamValueMode.LISTE:
+            case ParamValueMode.MINMAX:
+                switch (sourceParam.valueMode) { // nouvel état
+                    case ParamValueMode.CALCUL:
                         this.resetOtherRadio(sourceParam, ParamRadioConfig.VAR);
                         break;
                 }
@@ -55,13 +59,23 @@ export class FormDefFixedVar {
      * @param uid id numérique unique du paramètre source
      * @param option nouvel état "fix", "var" ou "cal" du paramètre source
      */
-    protected resetRadiosAndResults(sourceParam: NgParameter, option: string) {
-        const oldState: ParamRadioConfig = sourceParam.radioState;
-        const newState: ParamRadioConfig = ParamRadioConfig[option.toUpperCase()];
+    protected resetRadiosAndResults(sourceParam: NgParameter, oldState: ParamValueMode) {
+        this.processRadioStateChange(sourceParam, oldState);
+
+        switch (sourceParam.valueMode) { // nouvel état
+            case ParamValueMode.SINGLE:
+                sourceParam.valueMode = ParamValueMode.SINGLE;
+                break;
 
-        this.processRadioStateChange(sourceParam, oldState, newState);
+            case ParamValueMode.MINMAX:
+            case ParamValueMode.LISTE:
+                sourceParam.valueMode = ParamValueMode.MINMAX;  // min-max par défaut
+                break;
 
-        sourceParam.radioState = newState;
+            case ParamValueMode.CALCUL:
+                sourceParam.valueMode = ParamValueMode.CALCUL;
+                break;
+        }
 
         // on vérifie qu'il y a au moins un paramètre "à calculer" et sinon, on prend le 1er qui est à "fixé"
         if (this._formBase.getDisplayedParamFromState(ParamRadioConfig.CAL) == undefined) {
@@ -78,7 +92,7 @@ export class FormDefFixedVar {
             }
 
             if (newCal != undefined)
-                newCal.radioState = ParamRadioConfig.CAL;
+                newCal.valueMode = ParamValueMode.CALCUL;
         }
 
         this._formBase.reset();
@@ -89,8 +103,8 @@ export class FormDefFixedVar {
      */
     public onRadioClick(info: any) {
         const param: NgParameter = info.param; // paramètre source de l'événement radio
-        const option: string = info.option; // nouvel état (radio)
+        const old: ParamValueMode = info.oldValueMode; // ancien état (radio)
 
-        this.resetRadiosAndResults(param, option);
+        this.resetRadiosAndResults(param, old);
     }
 }
diff --git a/src/app/formulaire/definition/form-def-paramcalc.ts b/src/app/formulaire/definition/form-def-paramcalc.ts
index c999d7a02..e5c3ecdb8 100644
--- a/src/app/formulaire/definition/form-def-paramcalc.ts
+++ b/src/app/formulaire/definition/form-def-paramcalc.ts
@@ -40,17 +40,18 @@ export class FormDefParamToCalculate extends FormDefFixedVar {
         defaultParamCal.valueMode = ParamValueMode.CALCUL;
     }
 
-    protected processRadioStateChange(sourceParam: NgParameter, oldState: ParamRadioConfig, newState: ParamRadioConfig) {
-        super.processRadioStateChange(sourceParam, oldState, newState);
+    protected processRadioStateChange(sourceParam: NgParameter, oldState: ParamValueMode) {
+        super.processRadioStateChange(sourceParam, oldState);
 
         switch (oldState) {
-            case ParamRadioConfig.CAL:
-                switch (newState) {
-                    case ParamRadioConfig.FIX:
+            case ParamValueMode.CALCUL:
+                switch (sourceParam.valueMode) {  // nouvel état
+                    case ParamValueMode.SINGLE:
                         this.setDefault();
                         break;
 
-                    case ParamRadioConfig.VAR:
+                    case ParamValueMode.MINMAX:
+                    case ParamValueMode.LISTE:
                         super.resetOtherRadio(sourceParam, ParamRadioConfig.CAL);
                         this.setDefault();
                         break;
-- 
GitLab


From d5a5514d5089839aad1a1ae923e09b6590e8349a Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 12 Apr 2018 15:41:26 +0200
Subject: [PATCH 21/53] =?UTF-8?q?m=C3=A9nage=20imports?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/components/field-set/field-set.component.ts          | 5 +----
 .../components/generic-calculator/calculator.component.ts    | 1 -
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/src/app/components/field-set/field-set.component.ts b/src/app/components/field-set/field-set.component.ts
index a192bd1d7..8ab6e803c 100644
--- a/src/app/components/field-set/field-set.component.ts
+++ b/src/app/components/field-set/field-set.component.ts
@@ -1,11 +1,8 @@
 import { Component, Input, Output, EventEmitter, ViewChildren, QueryList, DoCheck } from "@angular/core";
 
-import { ParamDefinition } from "jalhyd";
-
-import { NgParameter, ParamRadioConfig } from "../../formulaire/ngparam";
+import { ParamRadioConfig } from "../../formulaire/ngparam";
 import { FieldSet } from "../../formulaire/fieldset";
 import { ParamFieldLineComponent } from "../param-field-line/param-field-line.component";
-import { SelectEntry } from "../../formulaire/select-entry";
 import { Field } from "../../formulaire/field";
 import { InputField } from "../../formulaire/input-field";
 import { SelectField } from "../../formulaire/select-field";
diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index 36988a83d..17d2f6198 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -11,7 +11,6 @@ import { Subscription } from "rxjs/Subscription";
 import { FieldSetComponent } from "../field-set/field-set.component";
 import { BaseComponent } from "../base/base.component";
 import { CalculatorNameComponent } from "./calc-name.component";
-import { SelectEntry } from "../../formulaire/select-entry";
 import { FormulaireElement } from "../../formulaire/formulaire-element";
 import { FieldsetContainer } from "../../formulaire/fieldset-container";
 import { FieldsetContainerComponent } from "../fieldset-container/fieldset-container.component";
-- 
GitLab


From dabdf5d1759c704bbfdf7b79c75caf8ffcf38cd8 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 12 Apr 2018 16:01:22 +0200
Subject: [PATCH 22/53]  #77 suppression des valeurs dans les fichiers de
 config des calculettes quand elles sont fournies par la lib

---
 .../pab-dimensions/pab-dimensions.config.json    | 12 ++++--------
 .../pab-puissance/pab-puissance.config.json      | 12 ++++--------
 .../parallel-structures.config.json              | 16 +++-------------
 3 files changed, 11 insertions(+), 29 deletions(-)

diff --git a/src/app/calculators/pab-dimensions/pab-dimensions.config.json b/src/app/calculators/pab-dimensions/pab-dimensions.config.json
index 8ef2539ad..55dd4639c 100644
--- a/src/app/calculators/pab-dimensions/pab-dimensions.config.json
+++ b/src/app/calculators/pab-dimensions/pab-dimensions.config.json
@@ -7,26 +7,22 @@
             {
                 "type": "input",
                 "id": "L",
-                "unit": "m",
-                "value": 2
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "W",
-                "unit": "m",
-                "value": 1
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "Y",
-                "unit": "m",
-                "value": 0.5
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "V",
-                "unit": "m³",
-                "value": 1
+                "unit": "m³"
             }
         ]
     },
diff --git a/src/app/calculators/pab-puissance/pab-puissance.config.json b/src/app/calculators/pab-puissance/pab-puissance.config.json
index 0a9d8cc4b..59b06d658 100644
--- a/src/app/calculators/pab-puissance/pab-puissance.config.json
+++ b/src/app/calculators/pab-puissance/pab-puissance.config.json
@@ -7,26 +7,22 @@
             {
                 "type": "input",
                 "id": "DH",
-                "unit": "m",
-                "value": 0.3
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "Q",
-                "unit": "m³/s",
-                "value": 0.1
+                "unit": "m³/s"
             },
             {
                 "type": "input",
                 "id": "V",
-                "unit": "m³",
-                "value": 0.5
+                "unit": "m³"
             },
             {
                 "type": "input",
                 "id": "Pv",
-                "unit": "W",
-                "value": 588.6
+                "unit": "W"
             }
         ]
     },
diff --git a/src/app/calculators/parallel-structures/parallel-structures.config.json b/src/app/calculators/parallel-structures/parallel-structures.config.json
index ff29ad62e..438622553 100644
--- a/src/app/calculators/parallel-structures/parallel-structures.config.json
+++ b/src/app/calculators/parallel-structures/parallel-structures.config.json
@@ -9,20 +9,17 @@
                 "type": "input",
                 "id": "Q",
                 "symbol": "Q",
-                "unit": "m³/s",
-                "value": 0.5
+                "unit": "m³/s"
             },
             {
                 "type": "input",
                 "id": "Z1",
-                "unit": "m",
-                "value": 2
+                "unit": "m"
             },
             {
                 "type": "input",
                 "id": "Z2",
-                "unit": "m",
-                "value": 1
+                "unit": "m"
             }
         ]
     },
@@ -103,7 +100,6 @@
                 "type": "input",
                 "id": "ZDV",
                 "unit": "m",
-                "value": 0.2,
                 "nodeType": "StructureRectangle",
                 "dep_exist": [
                     {
@@ -120,7 +116,6 @@
                 "type": "input",
                 "id": "L",
                 "unit": "m",
-                "value": 2,
                 "nodeType": "StructureRectangle",
                 "dep_exist": [
                     {
@@ -137,7 +132,6 @@
                 "type": "input",
                 "id": "W",
                 "unit": "m",
-                "value": 0.5,
                 "dep_exist": [
                     {
                         "refid": "select_ouvrage",
@@ -149,7 +143,6 @@
                 "type": "input",
                 "id": "Cd",
                 "unit": "",
-                "value": 0.4,
                 "nodeType": "StructureRectangle",
                 "dep_exist": [
                     {
@@ -194,7 +187,6 @@
                 "type": "input",
                 "id": "alpha",
                 "unit": "",
-                "value": 0.4,
                 "nodeType": "StructureKIVI",
                 "dep_exist": [
                     {
@@ -207,7 +199,6 @@
                 "type": "input",
                 "id": "beta",
                 "unit": "",
-                "value": 0.4,
                 "nodeType": "StructureKIVI",
                 "dep_exist": [
                     {
@@ -220,7 +211,6 @@
                 "type": "input",
                 "id": "ZRAM",
                 "unit": "",
-                "value": 0.4,
                 "nodeType": "StructureKIVI",
                 "dep_exist": [
                     {
-- 
GitLab


From 16b7c6335552a48a95b0b94f4e7dd4d24089ea09 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 12 Apr 2018 16:23:15 +0200
Subject: [PATCH 23/53] =?UTF-8?q?=20#77=20fichier=20de=20config=20des=20ca?=
 =?UTF-8?q?lculettes=20:=20ajout=20d'un=20champ=20"enum"=20ou=20"value"=20?=
 =?UTF-8?q?aux=20entr=C3=A9es=20des=20selects=20-=20classe=20SelectEntry?=
 =?UTF-8?q?=20:=20le=20r=C3=B4le=20tenu=20avant=20par=20le=20membre=20=5Fv?=
 =?UTF-8?q?alue=20est=20tenu=20par=20=5Fid?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../parallel-structures.config.json           | 36 +++++++----
 .../section-param/section-param.config.json   | 63 ++++++++++++-------
 .../formulaire/definition/form-def-section.ts | 18 +-----
 .../formulaire/definition/form-definition.ts  |  5 +-
 src/app/formulaire/select-entry.ts            | 27 ++++++--
 src/app/formulaire/select-field.ts            | 36 ++++++++++-
 6 files changed, 124 insertions(+), 61 deletions(-)

diff --git a/src/app/calculators/parallel-structures/parallel-structures.config.json b/src/app/calculators/parallel-structures/parallel-structures.config.json
index 438622553..754c7ad59 100644
--- a/src/app/calculators/parallel-structures/parallel-structures.config.json
+++ b/src/app/calculators/parallel-structures/parallel-structures.config.json
@@ -35,10 +35,12 @@
                 "type": "select",
                 "select": [
                     {
-                        "id": "select_ouvrage_vanne_rect"
+                        "id": "select_ouvrage_vanne_rect",
+                        "enum": "StructureType.VanneRectangulaire"
                     },
                     {
-                        "id": "select_ouvrage_seuil_rect"
+                        "id": "select_ouvrage_seuil_rect",
+                        "enum": "StructureType.SeuilRectangulaire"
                     }
                 ]
             },
@@ -47,19 +49,24 @@
                 "type": "select",
                 "select": [
                     {
-                        "id": "select_loidebit1_cem88d"
+                        "id": "select_loidebit1_cem88d",
+                        "enum": "LoiDebit.Cem88d"
                     },
                     {
-                        "id": "select_loidebit1_cem88v"
+                        "id": "select_loidebit1_cem88v",
+                        "enum": "LoiDebit.Cem88v"
                     },
                     {
-                        "id": "select_loidebit1_seuildenoye"
+                        "id": "select_loidebit1_seuildenoye",
+                        "enum": "LoiDebit.WeirFree"
                     },
                     {
-                        "id": "select_loidebit1_cunge80"
+                        "id": "select_loidebit1_cunge80",
+                        "enum": "LoiDebit.Cunge80"
                     },
                     {
-                        "id": "select_loidebit1_kivi"
+                        "id": "select_loidebit1_kivi",
+                        "enum": "LoiDebit.KIVI"
                     }
                 ],
                 "dep_exist": [
@@ -74,19 +81,24 @@
                 "type": "select",
                 "select": [
                     {
-                        "id": "select_loidebit2_cem88v"
+                        "id": "select_loidebit2_cem88v",
+                        "enum": "LoiDebit.Cem88v"
                     },
                     {
-                        "id": "select_loidebit2_cem88d"
+                        "id": "select_loidebit2_cem88d",
+                        "enum": "LoiDebit.Cem88d"
                     },
                     {
-                        "id": "select_loidebit2_vannedenoye"
+                        "id": "select_loidebit2_vannedenoye",
+                        "enum": "LoiDebit.OrificeFree"
                     },
                     {
-                        "id": "select_loidebit2_vannenoye"
+                        "id": "select_loidebit2_vannenoye",
+                        "enum": "LoiDebit.OrificeSubmerged"
                     },
                     {
-                        "id": "select_loidebit2_cunge80"
+                        "id": "select_loidebit2_cunge80",
+                        "enum": "LoiDebit.Cunge80"
                     }
                 ],
                 "dep_exist": [
diff --git a/src/app/calculators/section-param/section-param.config.json b/src/app/calculators/section-param/section-param.config.json
index 4f896ad7b..9740f86d1 100644
--- a/src/app/calculators/section-param/section-param.config.json
+++ b/src/app/calculators/section-param/section-param.config.json
@@ -8,16 +8,20 @@
                 "type": "select",
                 "select": [
                     {
-                        "id": "select_section_trapez"
+                        "id": "select_section_trapez",
+                        "enum": "ComputeNodeType.SectionTrapeze"
                     },
                     {
-                        "id": "select_section_rect"
+                        "id": "select_section_rect",
+                        "enum": "ComputeNodeType.SectionRectangle"
                     },
                     {
-                        "id": "select_section_circ"
+                        "id": "select_section_circ",
+                        "enum": "ComputeNodeType.SectionCercle"
                     },
                     {
-                        "id": "select_section_puiss"
+                        "id": "select_section_puiss",
+                        "enum": "ComputeNodeType.SectionPuissance"
                     }
                 ]
             }
@@ -212,55 +216,72 @@
                 "type": "select",
                 "select": [
                     {
-                        "id": "select_target_Hs"
+                        "id": "select_target_Hs",
+                        "value": "Hs"
                     },
                     {
-                        "id": "select_target_Hsc"
+                        "id": "select_target_Hsc",
+                        "value": "Hsc"
                     },
                     {
-                        "id": "select_target_B"
+                        "id": "select_target_B",
+                        "value": "B"
                     },
                     {
-                        "id": "select_target_P"
+                        "id": "select_target_P",
+                        "value": "P"
                     },
                     {
-                        "id": "select_target_S"
+                        "id": "select_target_S",
+                        "value": "S"
                     },
                     {
-                        "id": "select_target_R"
+                        "id": "select_target_R",
+                        "value": "R"
                     },
                     {
-                        "id": "select_target_V"
+                        "id": "select_target_V",
+                        "value": "V"
                     },
                     {
-                        "id": "select_target_Fr"
+                        "id": "select_target_Fr",
+                        "value": "Fr"
                     },
                     {
-                        "id": "select_target_Yc"
+                        "id": "select_target_Yc",
+                        "value": "Yc"
                     },
                     {
-                        "id": "select_target_Yn"
+                        "id": "select_target_Yn",
+                        "value": "Yn"
                     },
                     {
-                        "id": "select_target_Yf"
+                        "id": "select_target_Yf",
+                        "value": "Yf"
                     },
                     {
-                        "id": "select_target_Yt"
+                        "id": "select_target_Yt",
+                        "value": "Yt"
                     },
                     {
-                        "id": "select_target_Yco"
+                        "id": "select_target_Yco",
+                        "value": "Yco"
                     },
                     {
-                        "id": "select_target_J"
+                        "id": "select_target_J",
+                        "value": "J"
                     },
                     {
-                        "id": "select_target_I-J"
+                        "id": "select_target_I-J",
+                        "value": "I-J"
                     },
                     {
-                        "id": "select_target_Imp"
+                        "id": "select_target_Imp",
+                        "value": "Imp"
                     },
                     {
-                        "id": "select_target_Tau0"
+                        "id": "select_target_Tau0",
+                        "value": "Tau0"
                     }
                 ]
             }
diff --git a/src/app/formulaire/definition/form-def-section.ts b/src/app/formulaire/definition/form-def-section.ts
index 5cdf380a1..bfc65ea32 100644
--- a/src/app/formulaire/definition/form-def-section.ts
+++ b/src/app/formulaire/definition/form-def-section.ts
@@ -54,23 +54,7 @@ export class FormDefSection implements Observer {
     }
 
     private getNodeTypeFromSelectField(): ComputeNodeType {
-        const sect = this._formBase.getSelectedValue(this._sectionSelectFieldId);
-        switch (sect) {
-            case "trapez":
-                return ComputeNodeType.SectionTrapeze;
-
-            case "rect":
-                return ComputeNodeType.SectionRectangle;
-
-            case "circ":
-                return ComputeNodeType.SectionCercle;
-
-            case "puiss":
-                return ComputeNodeType.SectionPuissance;
-
-            default:
-                throw new Error(`getComputeNodeTypeFromSection() : section ${sect} non pris en charge`);
-        }
+        return this._formBase.getSelectedValue(this._sectionSelectFieldId);
     }
 
     public initParse() {
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 6eec33bc9..081f79134 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -265,10 +265,9 @@ export abstract class FormulaireDefinition extends FormulaireNode {
      * @param selectFieldId id du SelectField
      * @returns valeur courante du select sans le préfixe
      */
-    public getSelectedValue(selectFieldId: string): string {
+    public getSelectedValue(selectFieldId: string): any {
         let select: SelectField = <SelectField>this.getFieldById(selectFieldId);
-        let value: string = select.getValue().value;
-        return FormulaireElement.removePrefix(value, selectFieldId + "_");
+        return select.getValue().value;
     }
 
     /**
diff --git a/src/app/formulaire/select-entry.ts b/src/app/formulaire/select-entry.ts
index 07c1eae7e..8da49428e 100644
--- a/src/app/formulaire/select-entry.ts
+++ b/src/app/formulaire/select-entry.ts
@@ -1,13 +1,30 @@
 export class SelectEntry {
-    private _value: string;
+    /**
+     * id dans le fichier de config
+     */
+    private _id: string;
+
+    /**
+     * valeur associée à l'entrée
+     */
+    private _value: any;
+
+    /**
+     * texte affiché pour cette entrée
+     */
     public label: string;
 
-    constructor(v: string, l: string) {
-        this._value = v;
-        this.label = l;
+    constructor(id: string, val: any, lbl?: string) {
+        this._id = id;
+        this._value = val;
+        this.label = lbl;
+    }
+
+    get id(): string {
+        return this._id;
     }
 
-    get value(): string {
+    get value(): any {
         return this._value;
     }
 }
diff --git a/src/app/formulaire/select-field.ts b/src/app/formulaire/select-field.ts
index 65bfbfc94..200963db6 100644
--- a/src/app/formulaire/select-field.ts
+++ b/src/app/formulaire/select-field.ts
@@ -1,3 +1,5 @@
+import { StructureType, LoiDebit, ComputeNodeType } from "jalhyd";
+
 import { Field } from "./field";
 import { SelectEntry } from "./select-entry";
 import { Dependency } from "./dependency/dependency";
@@ -26,6 +28,13 @@ export class SelectField extends Field {
             this._selectedEntry = e;
     }
 
+    public getSelectedEntryFromValue(val: any): SelectEntry {
+        for (const se of this._entries)
+            if (se.value === val)
+                return se;
+        return undefined;
+    }
+
     public getValue() {
         return this._selectedEntry;
     }
@@ -54,7 +63,7 @@ export class SelectField extends Field {
         switch (d.masterCondition.type) {
             case DependencyConditionType.HasValue:
                 let mc: ValueDependencyCondition = <ValueDependencyCondition>d.masterCondition;
-                return this._selectedEntry.value === mc.value;
+                return this._selectedEntry.id === mc.value;
 
             default:
                 throw "SelectField.verifyDependency() : type de condition '" + DependencyConditionType[d.masterCondition.type] + "' non pris en charge";
@@ -65,7 +74,7 @@ export class SelectField extends Field {
         super.updateLocalisation(loc);
 
         for (let e of this._entries) {
-            e.label = loc[e.value];
+            e.label = loc[e.id];
         }
     }
 
@@ -89,7 +98,28 @@ export class SelectField extends Field {
         this._confId = field["id"];
         const values = field["select"];
         for (const v of values) {
-            const e: SelectEntry = new SelectEntry(v["id"], undefined);
+            let val;
+            if (v.enum) {
+                const tmp = v.enum.split(".");
+                switch (tmp[0]) {
+                    case "ComputeNodeType":
+                        val = ComputeNodeType[tmp[1]];
+                        break;
+
+                    case "StructureType":
+                        val = StructureType[tmp[1]];
+                        break;
+
+                    case "LoiDebit":
+                        val = LoiDebit[tmp[1]];
+                        break;
+                }
+            }
+            else if (v.value)
+                val = v.value;
+
+            const id = v["id"];
+            const e: SelectEntry = new SelectEntry(id, val);
             this.addEntry(e);
         }
     }
-- 
GitLab


From c684b17f89a0c391d4d3ff0a8669277c6d33bb58 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 12 Apr 2018 16:27:16 +0200
Subject: [PATCH 24/53] =?UTF-8?q?=20#77=20action=20"reset"=20de=20notifica?=
 =?UTF-8?q?tion=20de=20r=C3=A9initialisation=20du=20formulaire=20renomm?=
 =?UTF-8?q?=C3=A9e=20en=20"resetForm"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/components/generic-calculator/calculator.component.ts | 2 +-
 src/app/formulaire/definition/form-definition.ts              | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index 17d2f6198..ad9a2a845 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -255,7 +255,7 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
         }
         else if (sender instanceof FormulaireDefinition) {
             switch (data["action"]) {
-                case "reset": // réinitialisation du formulaire
+                case "resetForm": // réinitialisation du formulaire
                     var f = sender as FormulaireDefinition;
                     this.updateFormulaireResults(f.uid);
                     //     this.updateUI();
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 081f79134..b8125824f 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -244,7 +244,7 @@ export abstract class FormulaireDefinition extends FormulaireNode {
 
     private notifyReset() {
         this.notifyObservers({
-            "action": "reset"
+            "action": "resetForm"
         }, this);
     }
 
-- 
GitLab


From 6ca3086fd3d953d128cdccdf54a01c2a518a9b39 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 12 Apr 2018 16:30:32 +0200
Subject: [PATCH 25/53] =?UTF-8?q?=20#77=20HorizontalResultElementComponent?=
 =?UTF-8?q?=20:=20correction=20d'un=20crash=20quand=20rien=20n'est=20?=
 =?UTF-8?q?=C3=A0=20afficher?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../result-element/horizontal-result-element.component.ts       | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/app/components/result-element/horizontal-result-element.component.ts b/src/app/components/result-element/horizontal-result-element.component.ts
index c32b2b083..b0b1e2ff5 100644
--- a/src/app/components/result-element/horizontal-result-element.component.ts
+++ b/src/app/components/result-element/horizontal-result-element.component.ts
@@ -40,7 +40,7 @@ export class HorizontalResultElementComponent extends ResultElementBaseComponent
         super.ngOnChanges();
 
         this.vcRef.clear();
-        if (this._headers)
+        if (this._headers && this._resultElement)
             for (const h of this._headers) {
                 let v = this._resultElement.extraResults[h];
                 if (typeof (v) === "number")
-- 
GitLab


From eddaf897a1d1712e7e030daeed26c13324d12ffc Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 12 Apr 2018 16:32:06 +0200
Subject: [PATCH 26/53] =?UTF-8?q?=20#77=20FormulaireElement=20:=20(l=C3=A9?=
 =?UTF-8?q?g=C3=A8re)=20optimisation?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/formulaire/formulaire-element.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/app/formulaire/formulaire-element.ts b/src/app/formulaire/formulaire-element.ts
index 34891354d..49b73808d 100644
--- a/src/app/formulaire/formulaire-element.ts
+++ b/src/app/formulaire/formulaire-element.ts
@@ -126,7 +126,7 @@ export abstract class FormulaireElement extends FormulaireNode {
 
         for (let d of this._dependencies) {
             let master: FormulaireElement = d.masterElement;
-            if (d instanceof ExistenceDependency) {
+            if (d instanceof ExistenceDependency && !this._isDisplayed) {
                 let slave: FormulaireElement = this;
                 slave.isDisplayed = slave._isDisplayed || (master.isDisplayed && master.verifiesDependency(d)); // le problème c'est que master.isDisplayed n'est pas forcément correct à ce moment précis...
             }
-- 
GitLab


From 85ac03ea9190188f6388018fffed49a101331242 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 12 Apr 2018 16:45:46 +0200
Subject: [PATCH 27/53] =?UTF-8?q?=20#77=20suppression=20de=20la=20m=C3=A9t?=
 =?UTF-8?q?hode=20createNubs,=20la=20gestion=20de=20la=20session=20=C3=A9t?=
 =?UTF-8?q?ant=20dans=20la=20lib?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../formulaire/definition/concrete/form-cond-distri.ts   | 4 ----
 .../formulaire/definition/concrete/form-courbe-remous.ts | 9 +--------
 .../definition/concrete/form-lechapt-calmon.ts           | 4 ----
 .../definition/concrete/form-passe-bassin-dim.ts         | 4 ----
 .../definition/concrete/form-passe-bassin-puissance.ts   | 4 ----
 .../definition/concrete/form-regime-uniforme.ts          | 7 -------
 .../definition/concrete/form-section-parametree.ts       | 7 -------
 src/app/formulaire/definition/form-definition.ts         | 7 -------
 8 files changed, 1 insertion(+), 45 deletions(-)

diff --git a/src/app/formulaire/definition/concrete/form-cond-distri.ts b/src/app/formulaire/definition/concrete/form-cond-distri.ts
index 5964fce09..4a3438fdf 100644
--- a/src/app/formulaire/definition/concrete/form-cond-distri.ts
+++ b/src/app/formulaire/definition/concrete/form-cond-distri.ts
@@ -23,10 +23,6 @@ export class FormulaireConduiteDistributrice extends FormulaireDefinition {
         this._formCompute = new FormComputeConduiteDistributrice(this, this._formResult);
     }
 
-    protected createNubs() {
-        this._nubs.set(ComputeNodeType.None, this.paramService.createNub(this.calculatorType));
-    }
-
     protected initParse() {
         this._formParamCalc.initParse();
     }
diff --git a/src/app/formulaire/definition/concrete/form-courbe-remous.ts b/src/app/formulaire/definition/concrete/form-courbe-remous.ts
index 7abfe545a..c532c0685 100644
--- a/src/app/formulaire/definition/concrete/form-courbe-remous.ts
+++ b/src/app/formulaire/definition/concrete/form-courbe-remous.ts
@@ -20,13 +20,6 @@ export class FormulaireCourbeRemous extends FormulaireDefinition {
         this._formCompute = new FormComputeCourbeRemous(this, this._formSection, this._formResult);
     }
 
-    protected createNubs() {
-        this._nubs.set(ComputeNodeType.SectionCercle, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionCercle));
-        this._nubs.set(ComputeNodeType.SectionPuissance, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionPuissance));
-        this._nubs.set(ComputeNodeType.SectionRectangle, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionRectangle));
-        this._nubs.set(ComputeNodeType.SectionTrapeze, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionTrapeze));
-    }
-
     protected initParse() {
         this._formSection.initParse();
     }
@@ -54,4 +47,4 @@ export class FormulaireCourbeRemous extends FormulaireDefinition {
     public get results(): CalculatorResults[] {
         return this._formResult.results;
     }
-}
\ No newline at end of file
+}
diff --git a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
index 5159fc3bc..692684181 100644
--- a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
+++ b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
@@ -26,10 +26,6 @@ export class FormulaireLechaptCalmon extends FormulaireDefinition implements Obs
         this._formCompute = new FormComputeLechaptCalmon(this, this._formResult);
     }
 
-    protected createNubs() {
-        this._nubs.set(ComputeNodeType.None, this.paramService.createNub(this.calculatorType));
-    }
-
     protected initParse() {
         this._formParamCalc.initParse();
     }
diff --git a/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts b/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
index 3ab083098..2cadf2ae5 100644
--- a/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
+++ b/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
@@ -24,10 +24,6 @@ export class FormulairePasseBassinDimensions extends FormulaireDefinition {
         this._formCompute = new FormComputePasseBassinDimensions(this, this._formResult);
     }
 
-    protected createNubs() {
-        this._nubs.set(ComputeNodeType.None, this.paramService.createNub(this.calculatorType));
-    }
-
     protected initParse() {
         this._formParamCalc.initParse();
     }
diff --git a/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts b/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
index e01964dba..18bae07d6 100644
--- a/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
+++ b/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
@@ -24,10 +24,6 @@ export class FormulairePasseBassinPuissance extends FormulaireDefinition {
         this._formCompute = new FormComputePasseBassinPuissance(this, this._formResult);
     }
 
-    protected createNubs() {
-        this._nubs.set(ComputeNodeType.None, this.paramService.createNub(this.calculatorType));
-    }
-
     protected initParse() {
         this._formParamCalc.initParse();
     }
diff --git a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
index 958dbd6fb..b433d5856 100644
--- a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
+++ b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
@@ -27,13 +27,6 @@ export class FormulaireRegimeUniforme extends FormulaireDefinition {
         this._formCompute = new FormComputeRegimeUniforme(this, this._formSection, this._formResult);
     }
 
-    protected createNubs() {
-        this._nubs.set(ComputeNodeType.SectionCercle, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionCercle));
-        this._nubs.set(ComputeNodeType.SectionPuissance, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionPuissance));
-        this._nubs.set(ComputeNodeType.SectionRectangle, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionRectangle));
-        this._nubs.set(ComputeNodeType.SectionTrapeze, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionTrapeze));
-    }
-
     protected initParse() {
         this._formSection.initParse();
         this._formParamCalc.initParse();
diff --git a/src/app/formulaire/definition/concrete/form-section-parametree.ts b/src/app/formulaire/definition/concrete/form-section-parametree.ts
index 6737d69bd..1801c14f2 100644
--- a/src/app/formulaire/definition/concrete/form-section-parametree.ts
+++ b/src/app/formulaire/definition/concrete/form-section-parametree.ts
@@ -27,13 +27,6 @@ export class FormulaireSectionParametree extends FormulaireDefinition {
         this._formCompute = new FormComputeSectionParametree(this, this._formSection, this._formSectionResult);
     }
 
-    protected createNubs() {
-        this._nubs.set(ComputeNodeType.SectionCercle, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionCercle));
-        this._nubs.set(ComputeNodeType.SectionPuissance, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionPuissance));
-        this._nubs.set(ComputeNodeType.SectionRectangle, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionRectangle));
-        this._nubs.set(ComputeNodeType.SectionTrapeze, this.paramService.createNub(this.calculatorType, ComputeNodeType.SectionTrapeze));
-    }
-
     protected initParse() {
         this._formSection.initParse();
     }
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index b8125824f..0b0b14ae1 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -83,12 +83,6 @@ export abstract class FormulaireDefinition extends FormulaireNode {
         return undefined;
     }
 
-    /**
-     * crée le(s) Nub(s) associés au formulaire
-     * (dépend essentiellement du type de calculette)
-     */
-    protected abstract createNubs();
-
     protected abstract initParse();
     protected abstract parseOptions(json: {});
     protected abstract completeParse();
@@ -141,7 +135,6 @@ export abstract class FormulaireDefinition extends FormulaireNode {
     }
 
     public parseConfig(json: {}) {
-        this.createNubs();
         this.initParse();
 
         const templates: { [key: string]: FieldSet } = {};
-- 
GitLab


From 4b9ccea31b85eace1350af9df1c15ef32ace825b Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 12 Apr 2018 17:01:24 +0200
Subject: [PATCH 28/53] =?UTF-8?q?=20#77=20suite=20=C3=A0=20la=20cr=C3=A9at?=
 =?UTF-8?q?ion=20de=20la=20classe=20SessionNub=20dans=20la=20lib,=20FormCo?=
 =?UTF-8?q?mpute.getCurrentNub()=20transform=C3=A9e=20en=20getCurrentSessi?=
 =?UTF-8?q?onNub()?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../definition/form-compute-cond-distri.ts    |  9 ++--
 .../definition/form-compute-courbe-remous.ts  | 15 +++---
 .../definition/form-compute-fixedvar.ts       |  2 +-
 .../definition/form-compute-lechapt-calmon.ts |  9 ++--
 .../definition/form-compute-pab-bassin-dim.ts |  9 ++--
 .../form-compute-pab-bassin-puissance.ts      |  9 ++--
 .../form-compute-parallel-structures.ts       | 52 ++-----------------
 .../form-compute-regime-uniforme.ts           | 16 +++---
 .../form-compute-section-parametree.ts        | 13 +++--
 src/app/formulaire/definition/form-compute.ts |  4 +-
 10 files changed, 54 insertions(+), 84 deletions(-)

diff --git a/src/app/formulaire/definition/form-compute-cond-distri.ts b/src/app/formulaire/definition/form-compute-cond-distri.ts
index 44481cab8..26ca00a13 100644
--- a/src/app/formulaire/definition/form-compute-cond-distri.ts
+++ b/src/app/formulaire/definition/form-compute-cond-distri.ts
@@ -1,4 +1,4 @@
-import { ComputeNode, ParamsEquation, ConduiteDistribParams, ConduiteDistrib, ComputeNodeType } from "jalhyd";
+import { ComputeNode, ParamsEquation, ConduiteDistribParams, ConduiteDistrib, ComputeNodeType, CalculatorType } from "jalhyd";
 
 import { FormComputeFixedVar } from "./form-compute-fixedvar";
 import { FormulaireDefinition } from "./form-definition";
@@ -9,7 +9,10 @@ export class FormComputeConduiteDistributrice extends FormComputeFixedVar {
         super(formBase, formResult);
     }
 
-    protected getCurrentNub() {
-        return this._formBase.getNub(ComputeNodeType.None);
+    protected getCurrentSessionNub() {
+        return this._formBase.getSessionNub({
+            "calcType": CalculatorType.ConduiteDistributrice,
+            "nodeType": ComputeNodeType.None
+        });
     }
 }
diff --git a/src/app/formulaire/definition/form-compute-courbe-remous.ts b/src/app/formulaire/definition/form-compute-courbe-remous.ts
index fcabe29f5..929cd0446 100644
--- a/src/app/formulaire/definition/form-compute-courbe-remous.ts
+++ b/src/app/formulaire/definition/form-compute-courbe-remous.ts
@@ -1,4 +1,4 @@
-import { SectionParametree, acSection, ParamsEquation, ComputeNode, Result, MethodeResolution, CourbeRemousParams, CourbeRemous, ResultElement, ParamValues } from "jalhyd";
+import { SectionParametree, acSection, ParamsEquation, ComputeNode, Result, MethodeResolution, CourbeRemousParams, CourbeRemous, ResultElement, ParamValues, CalculatorType } from "jalhyd";
 
 import { SelectField } from "../select-field";
 import { RemousResults } from "../../results/remous-results";
@@ -12,12 +12,11 @@ export class FormComputeCourbeRemous extends FormCompute {
         super(formBase, formResult);
     }
 
-    // protected getNubAndParameters(): [ComputeNode, ParamsEquation] {
-    //     return this._formSection.getSectionNubAndParameters(false);
-    // }
-
-    protected getCurrentNub() {
-        return this._formBase.getNub(this._formSection.sectionNodeType);
+    protected getCurrentSessionNub() {
+        return this._formBase.getSessionNub({
+            "calcType": CalculatorType.SectionParametree,
+            "nodeType": this._formSection.sectionNodeType
+        });
     }
 
     private get remousResults(): RemousResults {
@@ -26,7 +25,7 @@ export class FormComputeCourbeRemous extends FormCompute {
     }
 
     protected compute() {
-        const cr: CourbeRemous = this.getCurrentNub() as CourbeRemous;
+        const cr: CourbeRemous = this.getCurrentSessionNub().nub as CourbeRemous;
         const prmCR: CourbeRemousParams = cr.parameters as CourbeRemousParams;
         const sect: acSection = prmCR.Sn;
 
diff --git a/src/app/formulaire/definition/form-compute-fixedvar.ts b/src/app/formulaire/definition/form-compute-fixedvar.ts
index d5ae4c50b..14506bd85 100644
--- a/src/app/formulaire/definition/form-compute-fixedvar.ts
+++ b/src/app/formulaire/definition/form-compute-fixedvar.ts
@@ -41,7 +41,7 @@ export abstract class FormComputeFixedVar extends FormCompute {
     }
 
     protected compute() {
-        const nub: Nub = this.getCurrentNub();
+        const nub: Nub = this.getCurrentSessionNub().nub;
 
         if (this._formBase.hasParameter("Pr"))
             var computePrec: number = this._formBase.getParameterValue("Pr"); // précision de calcul
diff --git a/src/app/formulaire/definition/form-compute-lechapt-calmon.ts b/src/app/formulaire/definition/form-compute-lechapt-calmon.ts
index 7af295988..766c4f593 100644
--- a/src/app/formulaire/definition/form-compute-lechapt-calmon.ts
+++ b/src/app/formulaire/definition/form-compute-lechapt-calmon.ts
@@ -1,4 +1,4 @@
-import { ComputeNode, ComputeNodeType, ParamsEquation, LechaptCalmonParams, LechaptCalmon } from "jalhyd";
+import { ComputeNode, ComputeNodeType, ParamsEquation, LechaptCalmonParams, LechaptCalmon, CalculatorType } from "jalhyd";
 
 import { FormComputeFixedVar } from "./form-compute-fixedvar";
 import { FormulaireDefinition } from "./form-definition";
@@ -9,7 +9,10 @@ export class FormComputeLechaptCalmon extends FormComputeFixedVar {
         super(formBase, formResult);
     }
 
-    protected getCurrentNub() {
-        return this._formBase.getNub(ComputeNodeType.None);
+    protected getCurrentSessionNub() {
+        return this._formBase.getSessionNub({
+            "calcType": CalculatorType.LechaptCalmon,
+            "nodeType": ComputeNodeType.None
+        });
     }
 }
diff --git a/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts b/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts
index 312748d43..cd984bfad 100644
--- a/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts
+++ b/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts
@@ -1,4 +1,4 @@
-import { ComputeNode, ParamsEquation, PabDimensionParams, PabDimension, ComputeNodeType } from "jalhyd";
+import { ComputeNode, ParamsEquation, PabDimensionParams, PabDimension, ComputeNodeType, CalculatorType } from "jalhyd";
 
 import { FormComputeFixedVar } from "./form-compute-fixedvar";
 import { FormulaireDefinition } from "./form-definition";
@@ -9,7 +9,10 @@ export class FormComputePasseBassinDimensions extends FormComputeFixedVar {
         super(formBase, formResult);
     }
 
-    protected getCurrentNub() {
-        return this._formBase.getNub(ComputeNodeType.None);
+    protected getCurrentSessionNub() {
+        return this._formBase.getSessionNub({
+            "calcType": CalculatorType.PabDimensions,
+            "nodeType": ComputeNodeType.None
+        });
     }
 }
\ No newline at end of file
diff --git a/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts b/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts
index e7d689de3..b5b961618 100644
--- a/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts
+++ b/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts
@@ -1,4 +1,4 @@
-import { ComputeNode, ParamsEquation, PabPuissanceParams, PabPuissance, ComputeNodeType } from "jalhyd";
+import { ComputeNode, ParamsEquation, PabPuissanceParams, PabPuissance, ComputeNodeType, CalculatorType } from "jalhyd";
 
 import { FormComputeFixedVar } from "./form-compute-fixedvar";
 import { FormulaireDefinition } from "./form-definition";
@@ -9,7 +9,10 @@ export class FormComputePasseBassinPuissance extends FormComputeFixedVar {
         super(formBase, formResult);
     }
 
-    protected getCurrentNub() {
-        return this._formBase.getNub(ComputeNodeType.None);
+    protected getCurrentSessionNub() {
+        return this._formBase.getSessionNub({
+            "calcType": CalculatorType.PabPuissance,
+            "nodeType": ComputeNodeType.None
+        });
     }
 }
\ No newline at end of file
diff --git a/src/app/formulaire/definition/form-compute-parallel-structures.ts b/src/app/formulaire/definition/form-compute-parallel-structures.ts
index 3509249bd..ce8ff3a10 100644
--- a/src/app/formulaire/definition/form-compute-parallel-structures.ts
+++ b/src/app/formulaire/definition/form-compute-parallel-structures.ts
@@ -63,52 +63,10 @@ export class FormComputeParallelStructures extends FormComputeFixedVar {
         }
     }
 
-    public getNubAndParameters(): [ComputeNode, ParamsEquation] {
-        // paramètres communs
-
-        const Q: number = this._formBase.getParameterValue("Q"); // Débit 
-        const Z1: number = this._formBase.getParameterValue("Z1"); // Cote de l'eau amont (m)
-        const Z2: number = this._formBase.getParameterValue("Z2"); // Cote de l'eau aval (m)
-        const prms = new ParallelStructureParams(Q, Z1, Z2);
-
-        const nub: ParallelStructure = new ParallelStructure(prms);
-
-        // ouvrages
-
-        for (const fs of this._formBase.allFieldsets)
-            if (fs.calculatorType == CalculatorType.Structure) {
-                const ts: StructureType = this._formParallelStruct.getStructureType(fs);
-                const ld: LoiDebit = this._formParallelStruct.getLoiDebit(fs);
-
-                // cote de radier
-                const ZDV = fs.getNodeParameterValue("ZDV");
-
-                // ouverture de vanne
-                try {
-                    var W = fs.getNodeParameterValue("W");
-                } catch (e) {
-                }
-
-                // création de l'ouvrage
-                const ouvr = CreateStructure(ts, ld);
-
-                // affectation des valeurs (en prenant garde de ne pas écraser les valeurs par défaut dans le cas d'un paramètre à calculer)
-                if (Z1 != undefined)
-                    ouvr.prms.Z1.v = Z1;
-                if (Z2 != undefined)
-                    ouvr.prms.Z2.v = Z2;
-                if (ZDV != undefined)
-                    ouvr.prms.ZDV.v = ZDV;
-                if (W != undefined)
-                    ouvr.prms.W.v = W;
-
-                nub.addStructure(ouvr);
-            }
-
-        return [nub, prms];
-    }
-
-    protected getCurrentNub() {
-        return undefined;
+    protected getCurrentSessionNub() {
+        return this._formBase.getSessionNub({
+            "calcType": CalculatorType.ParallelStructure,
+            "nodeType": ComputeNodeType.None
+        });
     }
 }
diff --git a/src/app/formulaire/definition/form-compute-regime-uniforme.ts b/src/app/formulaire/definition/form-compute-regime-uniforme.ts
index b01615cdf..cf2bdcf1b 100644
--- a/src/app/formulaire/definition/form-compute-regime-uniforme.ts
+++ b/src/app/formulaire/definition/form-compute-regime-uniforme.ts
@@ -1,4 +1,4 @@
-import { ComputeNode, ParamsEquation, RegimeUniforme, acSection } from "jalhyd";
+import { ComputeNode, ParamsEquation, RegimeUniforme, acSection, CalculatorType } from "jalhyd";
 
 import { FormComputeFixedVar } from "./form-compute-fixedvar";
 import { FormulaireDefinition } from "./form-definition";
@@ -10,12 +10,10 @@ export class FormComputeRegimeUniforme extends FormComputeFixedVar {
         super(formBase, formResult);
     }
 
-    // protected getNubAndParameters(): [ComputeNode, ParamsEquation] {
-    //     const snp: [acSection, ParamsEquation] = this._formSection.getSectionNubAndParameters();
-    //     return [new RegimeUniforme(snp[0]), snp[1]];
-    // }
-
-    protected getCurrentNub() {
-        return this._formBase.getNub(this._formSection.sectionNodeType);
+    protected getCurrentSessionNub() {
+        return this._formBase.getSessionNub({
+            "calcType": CalculatorType.RegimeUniforme,
+            "nodeType": this._formSection.sectionNodeType
+        });
     }
-}
\ No newline at end of file
+}
diff --git a/src/app/formulaire/definition/form-compute-section-parametree.ts b/src/app/formulaire/definition/form-compute-section-parametree.ts
index 3b695217c..c4fe1f453 100644
--- a/src/app/formulaire/definition/form-compute-section-parametree.ts
+++ b/src/app/formulaire/definition/form-compute-section-parametree.ts
@@ -1,4 +1,4 @@
-import { SectionParametree, acSection, ParamsEquation, ComputeNode, Result, ParamValueMode, Nub, ParamsSection } from "jalhyd";
+import { SectionParametree, acSection, ParamsEquation, ComputeNode, Result, ParamValueMode, Nub, ParamsSection, CalculatorType, SessionNub } from "jalhyd";
 
 import { FormCompute } from "./form-compute";
 import { NgParameter } from "../ngparam";
@@ -38,8 +38,11 @@ export class FormComputeSectionParametree extends FormCompute {
         return this._formSectionResult.sectionResults;
     }
 
-    protected getCurrentNub(): Nub {
-        return this._formBase.getNub(this._formSection.sectionNodeType);
+    protected getCurrentSessionNub(): SessionNub {
+        return this._formBase.getSessionNub({
+            "calcType": CalculatorType.SectionParametree,
+            "nodeType": this._formSection.sectionNodeType
+        });
     }
 
     /**
@@ -55,7 +58,7 @@ export class FormComputeSectionParametree extends FormCompute {
         // paramètre à calculer en fonction du paramètre à varier
         let computedParamInfo = this._formSection.getSectionComputedParam();
 
-        const sectNub: SectionParametree = this.getCurrentNub() as SectionParametree;
+        const sectNub: SectionParametree = this.getCurrentSessionNub().nub as SectionParametree;
         const sect: acSection = sectNub.section;
         const prms = sectNub.parameters;
 
@@ -96,7 +99,7 @@ export class FormComputeSectionParametree extends FormCompute {
             return;
         }
 
-        const sectNub: SectionParametree = this.getCurrentNub() as SectionParametree;
+        const sectNub: SectionParametree = this.getCurrentSessionNub().nub as SectionParametree;
 
         const sect: acSection = sectNub.section;
         this._sectionResults.section = sect;
diff --git a/src/app/formulaire/definition/form-compute.ts b/src/app/formulaire/definition/form-compute.ts
index f364ee0b1..1fff53c84 100644
--- a/src/app/formulaire/definition/form-compute.ts
+++ b/src/app/formulaire/definition/form-compute.ts
@@ -1,4 +1,4 @@
-import { ParamValueMode, Nub, Result, ParamDomainValue, ParamDomain } from "jalhyd";
+import { ParamValueMode, Nub, Result, ParamDomainValue, ParamDomain, SessionNub } from "jalhyd";
 
 import { FormResult } from "./form-result";
 import { FormulaireDefinition } from "./form-definition";
@@ -8,7 +8,7 @@ export abstract class FormCompute {
     constructor(protected _formBase: FormulaireDefinition, protected _formResult: FormResult) {
     }
 
-    protected abstract getCurrentNub(): Nub;
+    protected abstract getCurrentSessionNub(): SessionNub;
 
     protected abstract compute();
 
-- 
GitLab


From b78a6b8b0c45d5bcf370daecc7d0d7a98536565d Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Mon, 16 Apr 2018 16:58:14 +0200
Subject: [PATCH 29/53] =?UTF-8?q?=20#77=20modif=20de=20la=20signature=20de?=
 =?UTF-8?q?=20FormCompute.runNubCalc(),=20modif=20pour=20prendre=20en=20co?=
 =?UTF-8?q?mpte=20la=20valeur=20du=20param=C3=A8tre=20=C3=A0=20calculer=20?=
 =?UTF-8?q?pour=20la=20valeur=20initiale?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../definition/form-compute-fixedvar.ts       | 12 ++------
 .../form-compute-section-parametree.ts        | 18 +-----------
 src/app/formulaire/definition/form-compute.ts | 28 +++++++++++++++----
 3 files changed, 25 insertions(+), 33 deletions(-)

diff --git a/src/app/formulaire/definition/form-compute-fixedvar.ts b/src/app/formulaire/definition/form-compute-fixedvar.ts
index 14506bd85..f3d477bc2 100644
--- a/src/app/formulaire/definition/form-compute-fixedvar.ts
+++ b/src/app/formulaire/definition/form-compute-fixedvar.ts
@@ -22,14 +22,6 @@ export abstract class FormComputeFixedVar extends FormCompute {
         return this._formBase.getDisplayedParamFromState(ParamRadioConfig.CAL);
     }
 
-    /**
-     * retourne un identifiant du paramètre dans le formulaire
-     * surchargé dans le cas des ouvrages //
-     */
-    protected getParameterRefid(p: NgParameter) {
-        return p.symbol;
-    }
-
     /**
      * fixe la valeur d'un paramètre de ComputeNode
      * @param node ComputeNode contenant le paramètre
@@ -55,7 +47,7 @@ export abstract class FormComputeFixedVar extends FormCompute {
         if (varParam == undefined) {
             // pas de paramètre à varier
 
-            const res: Result = this.runNubCalc(nub, computedParam.domain, computePrec);
+            const res: Result = this.runNubCalc(nub, computedParam, computePrec);
             this.formResult.fixedResults.result = res;
             this.formResult.fixedResults.calculatedParameter = computedParam;
         }
@@ -76,7 +68,7 @@ export abstract class FormComputeFixedVar extends FormCompute {
                     break;
             }
 
-            const res: Result = this.runNubCalc(nub, computedParam.domain, computePrec);
+            const res: Result = this.runNubCalc(nub, computedParam, computePrec);
 
             this.formResult.varResults.variatedParameter = varParam;
             this.formResult.varResults.calculatedParameter = computedParam;
diff --git a/src/app/formulaire/definition/form-compute-section-parametree.ts b/src/app/formulaire/definition/form-compute-section-parametree.ts
index c4fe1f453..482da27e8 100644
--- a/src/app/formulaire/definition/form-compute-section-parametree.ts
+++ b/src/app/formulaire/definition/form-compute-section-parametree.ts
@@ -71,23 +71,7 @@ export class FormComputeSectionParametree extends FormCompute {
 
         let compSymbol: string = computedParamInfo["symbol"];
 
-        let yField: InputField = <InputField>this._formBase.getFormulaireNodeById("Y");
-        let Y: number = yField.getValue();
-
-        switch (varParam.valueMode) {
-            case ParamValueMode.LISTE:
-                varParam.paramDefinition.paramValues.setValues(varParam.paramDefinition.paramValues.valueList);
-                break;
-
-            case ParamValueMode.MINMAX:
-                const min = varParam.paramDefinition.paramValues.min;
-                const max = varParam.paramDefinition.paramValues.max;
-                const step = varParam.paramDefinition.paramValues.step;
-                varParam.paramDefinition.paramValues.setValues(min, max, step);
-                break;
-        }
-
-        this._varResults.result = this.runNubCalc(sectNub, computedParam.domain, computePrec, computedParam.symbol);
+        this._varResults.result = this.runNubCalc(sectNub, computedParam, computePrec);
         this._varResults.graphTitle = computedParamInfo.symbol + " = f( " + varParam.symbol + " )";
         this._varResults.update(false);
     }
diff --git a/src/app/formulaire/definition/form-compute.ts b/src/app/formulaire/definition/form-compute.ts
index 1fff53c84..22806ea9c 100644
--- a/src/app/formulaire/definition/form-compute.ts
+++ b/src/app/formulaire/definition/form-compute.ts
@@ -16,28 +16,44 @@ export abstract class FormCompute {
         return this._formResult;
     }
 
+    /**
+     * retourne un identifiant du paramètre dans le formulaire
+     * surchargé dans le cas des ouvrages //
+     */
+    protected getParameterRefid(p: NgParameter) {
+        return p.symbol;
+    }
+
     /**
      * lance le calcul d'un paramètre en déterminant une valeur initiale
      */
-    protected runNubCalc(nub: Nub, computedParamDomain: ParamDomain, prec: number, computedParam?: string): Result {
+    protected runNubCalc(nub: Nub, computedParam: NgParameter, prec: number): Result {
         let init: number;
-        switch (computedParamDomain.domain) {
+        switch (computedParam.domain.domain) {
             case ParamDomainValue.ANY:
+                init = computedParam.getValue();
+                break;
+
             case ParamDomainValue.POS_NULL:
-                init = 0;
+                init = Math.max(computedParam.getValue(), 0);
                 break;
 
             case ParamDomainValue.INTERVAL:
-                init = computedParamDomain.minValue;
+                init = (computedParam.domain.minValue + computedParam.domain.maxValue) / 2;
                 break;
 
             case ParamDomainValue.NOT_NULL:
+                init = computedParam.getValue();
+                if (init === 0)
+                    init = 1e-8;
+                break;
+
             case ParamDomainValue.POS:
-                init = 1e-8;
+                init = Math.max(computedParam.getValue(), 1e-8);
                 break;
         }
 
-        return nub.CalcSerie(prec, init, computedParam);
+        return nub.CalcSerie(prec, init, this.getParameterRefid(computedParam));
     }
 
     public doCompute() {
-- 
GitLab


From de2b9f91cdb305dcad1eb6ba5f87dd2d707768f6 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Tue, 17 Apr 2018 09:51:03 +0200
Subject: [PATCH 30/53] =?UTF-8?q?=20#77=201=C3=A8re=20adaptation=20des=20o?=
 =?UTF-8?q?uvrages=20parall=C3=A8les=20=C3=A0=20la=20factory=20de=20Nub=20?=
 =?UTF-8?q?-=20fichier=20de=20config=20de=20la=20calculette=20:=20ajout=20?=
 =?UTF-8?q?des=20champs=20defaultNodeType,=20defaultStructType=20et=20defa?=
 =?UTF-8?q?ultLoiDebit=20=C3=A0=20l'objet=20fieldset=5Ftemplate=20correspo?=
 =?UTF-8?q?ndant=20=C3=A0=20la=20valeur=20initiale=20des=20select=20-=20fi?=
 =?UTF-8?q?chier=20de=20config=20de=20la=20calculette=20:=20ajout=20d'une?=
 =?UTF-8?q?=20d=C3=A9pendance=20d'existence=20de=20ZDV=20et=20L=20=C3=A0?=
 =?UTF-8?q?=20la=20loi=20de=20d=C3=A9bit=20KIVI=20-=20param=C3=A8tres=20:?=
 =?UTF-8?q?=20suppression=20de=20la=20notion=20de=20contexte=20pour=20g?=
 =?UTF-8?q?=C3=A9rer=20les=20valeurs=20par=20d=C3=A9faut,=20les=20nubs=20?=
 =?UTF-8?q?=C3=A9tant=20renseign=C3=A9s=20et=20stock=C3=A9s=20dans=20la=20?=
 =?UTF-8?q?lib=20-=20FormulaireElement.parseDependencies()=20:=20argument?=
 =?UTF-8?q?=20parentForm(type=20FormulaireDefinition)=20remplac=C3=A9=20pa?=
 =?UTF-8?q?r=20un=20node=20parent=20dans=20lequel=20rechercher=20l'=C3=A9l?=
 =?UTF-8?q?=C3=A9ment=20master=20(dont=20l'existence=20d=C3=A9pend)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../parallel-structures.config.json           |  13 +-
 .../fieldset-container.component.ts           |   6 +-
 .../concrete/form-parallel-structures.ts      |  73 ++---
 .../definition/form-def-fixedvar.ts           |  15 -
 .../form-def-parallel-structures.ts           |   6 -
 .../formulaire/definition/form-definition.ts  |  80 ++---
 src/app/formulaire/field.ts                   |  12 +-
 src/app/formulaire/fieldset-container.ts      |  94 ++----
 src/app/formulaire/fieldset-template.ts       |  48 +++
 src/app/formulaire/fieldset.ts                | 295 +++++++++++++++---
 src/app/formulaire/formulaire-element.ts      |  20 +-
 src/app/formulaire/formulaire-node.ts         |  11 +-
 src/app/formulaire/ngparam.ts                 |  99 ------
 src/app/services/param/param.service.ts       |  34 +-
 14 files changed, 455 insertions(+), 351 deletions(-)
 create mode 100644 src/app/formulaire/fieldset-template.ts

diff --git a/src/app/calculators/parallel-structures/parallel-structures.config.json b/src/app/calculators/parallel-structures/parallel-structures.config.json
index 754c7ad59..20c22185c 100644
--- a/src/app/calculators/parallel-structures/parallel-structures.config.json
+++ b/src/app/calculators/parallel-structures/parallel-structures.config.json
@@ -27,7 +27,9 @@
         "id": "fs_ouvrage",
         "type": "fieldset_template",
         "calcType": "Structure",
-        "nodeType": "None",
+        "defaultNodeType": "StructureRectangle",
+        "defaultStructType": "VanneRectangulaire",
+        "defaultLoiDebit": "Cem88v",
         "option": "cal",
         "fields": [
             {
@@ -121,6 +123,10 @@
                     {
                         "refid": "select_ouvrage",
                         "refvalue": "select_ouvrage_seuil_rect"
+                    },
+                    {
+                        "refid": "select_loidebit1",
+                        "refvalue": "select_loidebit1_kivi"
                     }
                 ]
             },
@@ -137,12 +143,17 @@
                     {
                         "refid": "select_ouvrage",
                         "refvalue": "select_ouvrage_seuil_rect"
+                    },
+                    {
+                        "refid": "select_loidebit1",
+                        "refvalue": "select_loidebit1_kivi"
                     }
                 ]
             },
             {
                 "type": "input",
                 "id": "W",
+                "nodeType": "StructureRectangle",
                 "unit": "m",
                 "dep_exist": [
                     {
diff --git a/src/app/components/fieldset-container/fieldset-container.component.ts b/src/app/components/fieldset-container/fieldset-container.component.ts
index e091ef408..5f79ed52e 100644
--- a/src/app/components/fieldset-container/fieldset-container.component.ts
+++ b/src/app/components/fieldset-container/fieldset-container.component.ts
@@ -1,8 +1,6 @@
 import { Component, Input, Output, EventEmitter, QueryList, ViewChildren, DoCheck } from "@angular/core";
 
 import { FieldsetContainer } from "../../formulaire/fieldset-container";
-import { SelectEntry } from "../../formulaire/select-entry";
-import { FieldSet } from "../../formulaire/fieldset";
 import { FieldSetComponent } from "../field-set/field-set.component";
 
 @Component({
@@ -35,7 +33,7 @@ export class FieldsetContainerComponent implements DoCheck {
     }
 
     private addStructure() {
-        this._container.addFromTemplate(this._container.templates[0].id);
+        this._container.addFromTemplate(0);
     }
 
     /*
@@ -114,4 +112,4 @@ export class FieldsetContainerComponent implements DoCheck {
     private onInputChange(event: boolean) {
         this.inputChange.emit();
     }
-}
\ No newline at end of file
+}
diff --git a/src/app/formulaire/definition/concrete/form-parallel-structures.ts b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
index 32ec98830..7882cce11 100644
--- a/src/app/formulaire/definition/concrete/form-parallel-structures.ts
+++ b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
@@ -1,4 +1,4 @@
-import { CalculatorType, CreateStructure, StructureType, LoiDebit, ComputeNodeType, Structure, ParallelStructure } from "jalhyd";
+import { CalculatorType, ComputeNodeType, Structure, ParallelStructure, SessionNub } from "jalhyd";
 
 import { FormulaireDefinition } from "../form-definition";
 import { CalculatorResults } from "../../../results/calculator-results";
@@ -13,6 +13,7 @@ import { FieldsetContainer } from "../../fieldset-container";
 import { FieldSet } from "../../fieldset";
 import { SelectField } from "../../select-field";
 import { NgParameter } from "../../ngparam";
+import { FieldsetTemplate } from "../../fieldset-template";
 
 export class FormulaireParallelStructure extends FormulaireDefinition {
     private _formFixedVar: FormDefFixedVar;
@@ -34,7 +35,27 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
         this._formCompute = new FormComputeParallelStructures(this, this._formParallelStruct, this._formResult);
     }
 
-    protected createNubs() {
+    private createStructNub(templ: FieldsetTemplate): SessionNub {
+        const paramService: ParamService = ServiceFactory.instance.paramService;
+
+        // valeurs par défaut de CalculatorType, ComputeNodeType, StructureType, LoiDebit
+        // !!! attention !!! pour l'instant, il doit y avoir cohérence entre ces valeurs et celles du fichier de conf
+        // cad valeur par défaut du 1er select (type d'ouvrage), du 2ème (loi de débit).
+        // A terme, il faudrait analyser le fichier de conf (dépendances d'existence) pour déterminer automatiquement ces valeurs
+        const params = FieldSet.makeDefaultProps(templ.calcTypeFromConfig, templ.defaultNodeTypeFromConfig);
+        return paramService.createSessionNub(params);
+    }
+
+    public addStructureNub(st: Structure) {
+        this.parallelStructureNub.addStructure(st);
+    }
+
+    private get parallelStructureNub(): ParallelStructure {
+        const params = {
+            "calcType": CalculatorType.ParallelStructure,
+            "nodeType": ComputeNodeType.None
+        };
+        return this.getSessionNub(params).nub as ParallelStructure;
     }
 
     protected initParse() {
@@ -60,41 +81,6 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
      * @return une chaîne représentant le "contexte" courant (ici, combinaison type d'ouvrage-loi de débit)
      * @param fs FieldSet contenant les listes déroulantes type d'ouvrage et loi de débit
      */
-    private getContext(fs: FieldSet): string {
-        // type d'ouvrage courant
-        const fsStructType = this._formParallelStruct.getStructureType(fs);
-
-        // loi de débit courante
-        const loiDebit = this._formParallelStruct.getLoiDebit(fs);
-
-        return `${StructureType[fsStructType]}-${LoiDebit[loiDebit]}`
-    }
-
-    /**
-     * réinitialisation du formulaire.
-     * en plus de du comportement par défaut, on remet les valeurs des champs en fonction du contexte
-     * (type de structure, loi de débit)
-     */
-    public reset() {
-        super.reset();
-
-        for (const e of this.allFormElements) {
-            if (e instanceof FieldSet) {
-                const fs = e as FieldSet;
-                if (!fs.isTemplate && fs.calculatorType === CalculatorType.Structure) {
-                    const fsStructType: StructureType = this._formParallelStruct.getStructureType(fs);
-                    const loiDebit: LoiDebit = this._formParallelStruct.getLoiDebit(fs);
-                    const st = CreateStructure(fsStructType, loiDebit);
-
-                    for (const p of fs.allFormElements)
-                        if (p instanceof NgParameter && p.isDisplayed) {
-                            const defaultParam = st.prms.map[p.symbol];
-                            p.resetValue(this, this.getContext(fs), defaultParam.v);
-                        }
-                }
-            }
-        }
-    }
 
     public resetResults() {
         this._formResult.resetResults();
@@ -154,18 +140,5 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
             // la valeur d'un des select (type d'ouvrage, loi de débit) a changé
             this.reset();
         }
-        // else if (sender instanceof NgParameter) {
-        else {
-            switch (data.action) {
-                case "ngparamBeforeValue":  // la valeur d'un NgParameter est sur le point d'être modifiée
-                    const param: NgParameter = data.param;
-
-                    // FieldSet parent    
-                    const parentFieldset = param.getDirectParent(this) as FieldSet;
-
-                    // contexte dans lequel la valeur du paramètre est fixée manuellement
-                    param.currentContextId = this.getContext(parentFieldset);
-            }
-        }
     }
 }
diff --git a/src/app/formulaire/definition/form-def-fixedvar.ts b/src/app/formulaire/definition/form-def-fixedvar.ts
index b3711d5f6..86ca4d19f 100644
--- a/src/app/formulaire/definition/form-def-fixedvar.ts
+++ b/src/app/formulaire/definition/form-def-fixedvar.ts
@@ -62,21 +62,6 @@ export class FormDefFixedVar {
     protected resetRadiosAndResults(sourceParam: NgParameter, oldState: ParamValueMode) {
         this.processRadioStateChange(sourceParam, oldState);
 
-        switch (sourceParam.valueMode) { // nouvel état
-            case ParamValueMode.SINGLE:
-                sourceParam.valueMode = ParamValueMode.SINGLE;
-                break;
-
-            case ParamValueMode.MINMAX:
-            case ParamValueMode.LISTE:
-                sourceParam.valueMode = ParamValueMode.MINMAX;  // min-max par défaut
-                break;
-
-            case ParamValueMode.CALCUL:
-                sourceParam.valueMode = ParamValueMode.CALCUL;
-                break;
-        }
-
         // on vérifie qu'il y a au moins un paramètre "à calculer" et sinon, on prend le 1er qui est à "fixé"
         if (this._formBase.getDisplayedParamFromState(ParamRadioConfig.CAL) == undefined) {
             let newCal: NgParameter = undefined;
diff --git a/src/app/formulaire/definition/form-def-parallel-structures.ts b/src/app/formulaire/definition/form-def-parallel-structures.ts
index a9965b2a2..e26992be7 100644
--- a/src/app/formulaire/definition/form-def-parallel-structures.ts
+++ b/src/app/formulaire/definition/form-def-parallel-structures.ts
@@ -33,9 +33,6 @@ export class FormDefParallelStructures {
      * @return type d'ouvrage courant du FieldSet donné
      */
     public getStructureType(fs: FieldSet): StructureType {
-        if (fs.calculatorType !== CalculatorType.Structure)
-            throw new Error(`FormDefParallelStructures.getStructureType() : le FieldSet n'est pas du type Structure`);
-
         let structType: string = fs.getSelectedValue("select_ouvrage");
         if (structType == undefined)
             throw new Error(`FormDefParallelStructures.getStructureType() : aucun ouvrage trouvé dans le FieldSet`);
@@ -50,9 +47,6 @@ export class FormDefParallelStructures {
      * @return loi de débit courante du FieldSet donné
      */
     public getLoiDebit(fs: FieldSet): LoiDebit {
-        if (fs.calculatorType !== CalculatorType.Structure)
-            throw new Error(`FormDefParallelStructures.getLoiDebit() : le FieldSet n'est pas du type Structure`);
-
         let loiDebit: string = fs.getSelectedValue("select_loidebit1");
         if (loiDebit == undefined)
             loiDebit = fs.getSelectedValue("select_loidebit2");
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 0b0b14ae1..3dc10da8a 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -1,4 +1,5 @@
-import { CalculatorType, ComputeNodeType, Nub, ParamDefinition } from "jalhyd";
+import { CalculatorType, ComputeNodeType, Nub, ParamDefinition, SessionNub, Props } from "jalhyd";
+
 import { FormulaireElement } from "../formulaire-element";
 import { NgParameter, ParamRadioConfig } from "../ngparam";
 import { Field } from "../field";
@@ -13,6 +14,7 @@ import { DeepFieldsetIterator } from "../form-iterator/deep-fieldset-iterator";
 import { DeepFormulaireElementIterator } from "../form-iterator/deep-element-iterator";
 import { TopFormulaireElementIterator } from "../form-iterator/top-element-iterator";
 import { CalculatorResults } from "../../results/calculator-results";
+import { FieldsetTemplate } from "../fieldset-template";
 
 /**
  * classe de base pour tous les formulaires
@@ -28,18 +30,12 @@ export abstract class FormulaireDefinition extends FormulaireNode {
      */
     private _calculatorName: string;
 
-    /**
-     * map des Nub appartenant à ce formulaire
-     */
-    protected _nubs: Map<ComputeNodeType, Nub>;
-
     protected _paramService: ParamService;
 
     constructor(calcType: CalculatorType,
     ) {
         super();
         this._calcType = calcType;
-        this._nubs = new Map();
         this._paramService = ServiceFactory.instance.paramService;
     }
 
@@ -55,32 +51,41 @@ export abstract class FormulaireDefinition extends FormulaireNode {
         this._calculatorName = name;
     }
 
+    private findNub(params: Props | {}) {
+        return this._paramService.findSessionNub(params);
+    }
+
+    public createSessionNub(params: Props | {}): SessionNub {
+        return this._paramService.createSessionNub(params);
+    }
+
     /**
-     * @return le Nub associé à un type de noeud donné
-     * @param nodeType type de noeud
+     * @return le Nub associé à un type de noeud donné, le crée si nécessaire
+     * @param params paramètres de contexte de création du nub
      */
-    public getNub(nodeType: ComputeNodeType): Nub {
-        return this._nubs.get(nodeType);
+    public getSessionNub(params: Props | {}): SessionNub {
+        let res = this.findNub(params);
+        if (!res)
+            res = this.createSessionNub(params);
+        return res;
+    }
+
+    public replaceSessionNub(sn: SessionNub, params: Props) {
+        return this._paramService.replaceSessionNub(sn, params);
     }
 
     /**
      * @return le paramètre d'un type de noeud
      * @param symbol symbole du paramètre
-     * @param nodeType type de noeud
+     * @param params paramètres de contexte de création du nub
      */
-    public getNubParamFromSymbol(nodeType: ComputeNodeType, symbol: string): ParamDefinition {
-        let nub = this._nubs.get(nodeType);
-
-        if (nub == undefined) // on prend le 1er
-            for (const e of this._nubs.entries()) {
-                nub = e[1]; // valeur
-                break;
-            }
+    public getNubParamFromSymbol(symbol: string, params: Props | {}): ParamDefinition {
+        let sessionNub: SessionNub = this.getSessionNub(params);
 
-        if (nub)
-            return nub.getParameter(symbol);
+        if (sessionNub)
+            return sessionNub.nub.getParameter(symbol);
 
-        return undefined;
+        throw new Error(`FormulaireDefinition.getNubParamFromSymbol() : pas de Nub trouvé pour ${params}`)
     }
 
     protected abstract initParse();
@@ -94,16 +99,13 @@ export abstract class FormulaireDefinition extends FormulaireNode {
         return undefined;
     }
 
-    private parse_fieldset(json: {}): FieldSet {
-        const ct: string = json["calcType"];
-        let calc_type: CalculatorType = ct == undefined ? this._calcType : CalculatorType[ct];
-
-        const res: FieldSet = new FieldSet(calc_type, json["type"] === "fieldset_template");
-        res.parseConfig(json, { "parentForm": this });
-        return res;
+    private parse_fieldset(json: {}) {
+        const fs: FieldSet = new FieldSet();
+        this.kids.push(fs);
+        fs.parseConfig(json, { "parentForm": this });
     }
 
-    private parse_template_container(json: {}, templates: { [key: string]: FieldSet }) {
+    private parse_template_container(json: {}, templates: any[]) {
         const fsc: FieldsetContainer = new FieldsetContainer(this);
         fsc.parseConfig(json, templates);
         this.formElements.push(fsc);
@@ -128,7 +130,7 @@ export abstract class FormulaireDefinition extends FormulaireNode {
                 case "fieldset_template":
                     for (const k of this.kids)
                         if (k instanceof FieldsetContainer)
-                            k.parseDependencies(conf);
+                            k.parseDependencies(conf, this);
                     break;
             }
         }
@@ -137,21 +139,19 @@ export abstract class FormulaireDefinition extends FormulaireNode {
     public parseConfig(json: {}) {
         this.initParse();
 
-        const templates: { [key: string]: FieldSet } = {};
+        const templates: any[] = [];
 
         for (let conf_index in json) {
             const conf = json[conf_index];
             const type: string = conf["type"];
 
             switch (type) {
-                // field set
                 case "fieldset":
+                    this.parse_fieldset(conf);
+                    break;
+
                 case "fieldset_template":
-                    const fs: FieldSet = this.parse_fieldset(conf);
-                    if (fs.isTemplate)
-                        templates[fs.id] = fs;
-                    else
-                        this.kids.push(fs);
+                    templates.push(conf);
                     break;
 
                 // options globales
@@ -278,7 +278,7 @@ export abstract class FormulaireDefinition extends FormulaireNode {
     }
 
     public applyDependencies() {
-        for (const fe of this.allFormElements)
+        for (const fe of this.topFormElements)
             fe.applyDependencies(this);
     }
 
diff --git a/src/app/formulaire/field.ts b/src/app/formulaire/field.ts
index 34411775b..488f6aabf 100644
--- a/src/app/formulaire/field.ts
+++ b/src/app/formulaire/field.ts
@@ -1,5 +1,5 @@
+import { FormulaireNode } from "./formulaire-node";
 import { FormulaireElement } from "./formulaire-element";
-import { FormulaireDefinition } from "./definition/form-definition";
 import { ValueDependency } from "./dependency/value-dependency";
 
 export abstract class Field extends FormulaireElement {
@@ -12,10 +12,10 @@ export abstract class Field extends FormulaireElement {
     public abstract getValue(): any;
     public abstract setValue(sender: any, val: any): void;
 
-    private parse_value_dependencies(json: {}, parentForm: FormulaireDefinition) {
+    private parse_value_dependencies(json: {}, parentNode: FormulaireNode) {
         for (let di in json) {
             let d = json[di];
-            let masterField: FormulaireElement = parentForm.getFormulaireNodeById(d["refid"]) as FormulaireElement;
+            let masterField: FormulaireElement = parentNode.getFormulaireNodeById(d["refid"]) as FormulaireElement;
             if (masterField != undefined) {
                 let masterValue = d["refvalue"];
                 let dep = new ValueDependency(masterField, masterValue);
@@ -27,11 +27,11 @@ export abstract class Field extends FormulaireElement {
         }
     }
 
-    public parseDependencies(json: {}, parentForm: FormulaireDefinition) {
-        super.parseDependencies(json, parentForm);
+    public parseDependencies(json: {}, parentNode: FormulaireNode) {
+        super.parseDependencies(json, parentNode);
 
         const dep = json["dep_value"];
         if (dep != undefined)
-            this.parse_value_dependencies(dep, parentForm);
+            this.parse_value_dependencies(dep, parentNode);
     }
 }
diff --git a/src/app/formulaire/fieldset-container.ts b/src/app/formulaire/fieldset-container.ts
index 5999f7c65..8f263fab4 100644
--- a/src/app/formulaire/fieldset-container.ts
+++ b/src/app/formulaire/fieldset-container.ts
@@ -1,73 +1,51 @@
+import { Structure } from "jalhyd";
+
 import { FormulaireElement } from "./formulaire-element";
 import { FieldSet } from "./fieldset";
+import { FieldsetTemplate } from "./fieldset-template";
 import { Dependency } from "./dependency/dependency";
 import { StringMap } from "../stringmap";
 import { FormulaireDefinition } from "./definition/form-definition";
-import { FormulaireNode } from "./formulaire-node";
+import { FormulaireParallelStructure } from "./definition/concrete/form-parallel-structures";
 
 export class FieldsetContainer extends FormulaireElement {
-    private _templates: FieldSet[];
+    private _templates: FieldsetTemplate[];
 
     private _localisation: StringMap;
 
     public title: string
 
-    constructor(private parentForm: FormulaireDefinition) {
+    constructor(private _parentForm: FormulaireDefinition) {
         super();
         this._templates = [];
     }
 
-    /**
-     * cherche un FormulaireNode par son id de conf
-     */
-    public getFormulaireNodeById(id: string): FormulaireNode {
-        const res = super.getFormulaireNodeById(id);
-        if (res !== undefined)
-            return res;
-
-        for (const t of this._templates) {
-            const res = t.getFormulaireNodeById(id);
-            if (res !== undefined)
-                return res;
-        }
-
-        return undefined;
+    public get parentForm() {
+        return this._parentForm;
     }
 
-    private checkTemplate(fs: FieldSet) {
-        if (!fs.isTemplate)
-            throw new Error(`le Fieldset ${fs.id} n'est pas un template`);
+    private addTemplate(fst: FieldsetTemplate) {
+        this._templates.push(new FieldsetTemplate(fst));
     }
 
-    public addTemplate(fs: FieldSet) {
-        if (this.hasTemplate(fs))
-            console.log(`Warning : le Fieldset template ${fs.id} a déjà été ajouté`);
-        else
-            this._templates.push(fs);
+    public getTemplate(index: number): FieldsetTemplate {
+        return this._templates[index];
     }
 
-    private hasTemplate(fs: FieldSet): boolean {
-        this.checkTemplate(fs);
-
-        for (const f of this._templates)
-            if (f.id === fs.id)
-                return true;
-        return false;
+    public addFieldset(fs: FieldSet) {
+        this.fieldsets.push(fs);
     }
 
-    private getTemplate(id: string) {
-        for (const f of this._templates)
-            if (f.id === id)
-                return f;
-        return undefined;
-    }
+    public addFromTemplate(index: number) {
+        const templ: FieldsetTemplate = this._templates[index];
 
-    public addFromTemplate(templId: string) {
-        const templ: FieldSet = this.getTemplate(templId);
-        const inst = templ.instanciateTemplate();
-        this.fieldsets.push(inst);
-        inst.applyDependencies(this.parentForm);
-        this.updateLocalisation()
+        const inst: FieldSet = templ.instantiateTemplate(this);
+        if (inst.sessionNub.nub instanceof Structure) {
+            const psf = this.parentForm as FormulaireParallelStructure;
+            psf.addStructureNub(inst.sessionNub.nub as Structure);
+        }
+
+        this.updateLocalisation();
 
         // notification de création d'un FieldSet
         this.notifyObservers({
@@ -80,24 +58,15 @@ export class FieldsetContainer extends FormulaireElement {
         return this.kids as FieldSet[];
     }
 
-    public get templates(): FieldSet[] {
-        return this._templates;
-    }
-
     public parseConfig(json: {}, data?: {}) {
         this._confId = json["id"];
+        const templates = data as any[];
 
-        const templs: string[] = json["templates"];
-        for (const t of templs)
-            // this.addTemplate(this.getFieldsetTemplate(t));
-            this.addTemplate(data[t]);
-    }
-
-    public parseDependencies(json: {}) {
-        super.parseDependencies(json, this.parentForm);
-
-        for (const t of this._templates)
-            t.parseDependencies(json, this.parentForm);
+        const templateNames: string[] = json["templates"];
+        for (const t of templateNames)
+            for (const d of templates)
+                if (d.id == t)
+                    this.addTemplate(d);
     }
 
     protected verifyDependency(d: Dependency): boolean {
@@ -111,9 +80,6 @@ export class FieldsetContainer extends FormulaireElement {
             this._localisation = loc;
 
         super.updateLocalisation(loc);
-
-        for (let t of this._templates)
-            t.updateLocalisation(loc);
     }
 
     /**
@@ -129,6 +95,6 @@ export class FieldsetContainer extends FormulaireElement {
      * crée une nouvelle instance
      */
     protected clone(): FieldsetContainer {
-        return new FieldsetContainer(this.parentForm);
+        return new FieldsetContainer(this._parentForm);
     }
 }
diff --git a/src/app/formulaire/fieldset-template.ts b/src/app/formulaire/fieldset-template.ts
new file mode 100644
index 000000000..a8db81d57
--- /dev/null
+++ b/src/app/formulaire/fieldset-template.ts
@@ -0,0 +1,48 @@
+import { FieldSet } from "./fieldset";
+import { CalculatorType, ComputeNodeType } from "jalhyd";
+import { FormulaireDefinition } from "./definition/form-definition";
+import { FieldsetContainer } from "./fieldset-container";
+
+export class FieldsetTemplate {
+    private _jsonConfig: {};
+
+    constructor(config: {}) {
+        this._jsonConfig = config;
+    }
+
+    public get config() {
+        return this._jsonConfig;
+    }
+
+    public get calcTypeFromConfig(): CalculatorType {
+        for (const k in this._jsonConfig) {
+            if (k === "calcType") {
+                const ct: string = this._jsonConfig[k];
+                var calcType: CalculatorType = CalculatorType[ct];
+                break;
+            }
+        }
+
+        return calcType;
+    }
+
+    public get defaultNodeTypeFromConfig(): ComputeNodeType {
+        for (const k in this._jsonConfig) {
+            if (k === "defaultNodeType") {
+                const nt: string = this._jsonConfig[k];
+                var nodeType: ComputeNodeType = ComputeNodeType[nt];
+                break;
+            }
+        }
+
+        return nodeType;
+    }
+
+    public instantiateTemplate(cont: FieldsetContainer): FieldSet {
+        const res = new FieldSet();
+        res.parent_fsc = cont;
+        cont.addFieldset(res);
+        res.parseConfig(this._jsonConfig, { "parentForm": cont.parentForm, "createNub": true });
+        return res;
+    }
+}
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 384e9f1e2..e93200e4d 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -1,4 +1,4 @@
-import { CalculatorType, ComputeNodeType, ParamDefinition } from "jalhyd";
+import { CalculatorType, ComputeNodeType, ParamDefinition, LoiDebit, StructureType, Props, loiAdmissibles, SessionNub } from "jalhyd";
 
 import { FormulaireElement } from "./formulaire-element";
 import { Dependency } from "./dependency/dependency";
@@ -10,37 +10,61 @@ import { NgParameter, ParamRadioConfig } from "./ngparam";
 import { ServiceFactory } from "../services/service-factory";
 import { ParamService } from "../services/param/param.service";
 import { FormulaireDefinition } from "./definition/form-definition";
+import { Observer } from "../services/observer";
+import { StringMap } from "../stringmap";
+import { FieldsetContainer } from "./fieldset-container";
 
-export class FieldSet extends FormulaireElement {
-    private _calcType: CalculatorType;
+export class FieldSet extends FormulaireElement implements Observer {
+    /**
+     * formulaire parent
+     */
+    private _parentForm: FormulaireDefinition;
 
-    constructor(calcType: CalculatorType, isTmpl: boolean = false) {
-        super(isTmpl);
-        this._calcType = calcType;
-    }
+    /**
+     * SessionNub associé
+     */
+    private _sessionNub: SessionNub;
+
+    /**
+     * dictionnaire de traduction
+     */
+    private _localisation: StringMap;
+
+    /**
+     * fichier de configuration
+     */
+    private _jsonConfig: {};
+
+    /**
+     * propriétés déterminant l'état actuel du FieldSet (type de section, loi de débit, ...)
+     */
+    private _props: Props;
+
+    public parent_fsc: FieldsetContainer; // A VIRER
 
-    public get calculatorType(): CalculatorType {
-        return this._calcType;
+    constructor() {
+        super(false);
+        this._props = new Props();
     }
 
     public get fields(): Field[] {
         return this.kids as Field[];
     }
 
+    public get sessionNub(): SessionNub {
+        return this._sessionNub;
+    }
+
     /**
      * crée une nouvelle instance
      */
     protected clone(): FieldSet {
-        return new FieldSet(this._calcType);
-    }
-
-    public instanciateTemplate(): FieldSet {
-        const res = this.getDeepClone() as FieldSet;
-        this.copyDependencies(res, res);
-        return res;
+        return new FieldSet();
     }
 
     public addField(f: Field) {
+        if (f == undefined)
+            throw new Error("FieldSet.addField() : argument incorrect (undefined)");
         this.fields.push(f);
     }
 
@@ -83,13 +107,88 @@ export class FieldSet extends FormulaireElement {
     private parse_select(json: {}): SelectField {
         let res: SelectField = new SelectField(this.isTemplate);
         res.parseConfig(json);
+        res.addObserver(this);
         return res;
     }
 
-    private parse_input(json: {}, parentForm: FormulaireDefinition, default_radio_config: string): NgParameter {
+    public getPropValue(key: string): any {
+        return this._props.getPropValue(key);
+    }
+
+    public setPropValue(key: string, val: any): boolean {
+        const changed = this._props.getPropValue(key) !== val;
+        if (changed) {
+            this._props.setPropValue(key, val);
+
+            // si prop=type d'ouvrage, on prend une loi de débit compatible avec (spécifique aux ouvrages //) comme valeur par défaut
+            if (key === "structureType") {
+                {
+                    const sst: string = StructureType[val];
+                    const ld: LoiDebit = loiAdmissibles[sst][0];
+                    this.setPropValue("loiDebit", ld);
+                }
+            }
+        }
+        return changed;
+    }
+
+    /**
+     * valeurs par défaut pour StructureType, LoiDebit en fonction d'un ComputeNodeType
+     */
+    private static defaultProps(nodeType: ComputeNodeType): [StructureType, LoiDebit] {
+        let structType: StructureType;
+        let loiDebit: LoiDebit
+        switch (nodeType) {
+            case ComputeNodeType.StructureRectangle:
+                structType = StructureType.VanneRectangulaire;
+                loiDebit = LoiDebit.Cem88v;
+                break;
+
+            case ComputeNodeType.StructureKIVI:
+                structType = StructureType.SeuilRectangulaire;
+                loiDebit = LoiDebit.KIVI;
+                break;
+        }
+        return [structType, loiDebit];
+    }
+
+    /**
+     * crée un objet Props servant de filtre pour sélectionner un Nub
+     * @param calcType
+     * @param nodeType 
+     */
+    public static makeDefaultProps(calcType: CalculatorType, nodeType: ComputeNodeType): Props {
+        const res: Props = new Props();
+
+        res.setPropValue("calcType", calcType);
+        res.setPropValue("nodeType", nodeType);
+
+        const p: [StructureType, LoiDebit] = FieldSet.defaultProps(nodeType);
+        res.setPropValue("structureType", p[0]);
+        res.setPropValue("loiDebit", p[1]);
+
+        return res;
+    }
+
+    private getNubParamFromSymbol(symbol: string): ParamDefinition {
+        if (this._sessionNub)
+            return this._sessionNub.nub.getParameter(symbol);
+
+        return this._parentForm.getNubParamFromSymbol(symbol, this._props);
+    }
+
+    /**
+     * crée un input
+     * @param json definition de l'input, extrait du fichier de conf de la calculette
+     * @param node_type_filter filtre sur le type de noeud (input créé si undefined ou égal)
+     * @param default_radio_config config du radio fixé/à varier/à calculer
+     */
+    private parse_input(json: {}, default_radio_config: string): NgParameter {
         const input_id: string = json["id"];
         const paramService: ParamService = ServiceFactory.instance.paramService;
 
+        const calcType: CalculatorType = this.getPropValue("calcType");
+
         switch (input_id) {
             case "Pr":
                 var res: NgParameter = paramService.createParameter(input_id, this.isTemplate);
@@ -97,35 +196,29 @@ export class FieldSet extends FormulaireElement {
 
             default:
                 const nt: string = json["nodeType"];
-                let node_type: ComputeNodeType = nt == undefined ? ComputeNodeType.None : ComputeNodeType[nt];
+                let nodeType: ComputeNodeType = nt == undefined ? this.getPropValue("nodeType") : ComputeNodeType[nt];
 
-                const nubParam: ParamDefinition = parentForm.getNubParamFromSymbol(node_type, input_id);
-                if (nubParam == undefined)
-                    throw new Error(`pas de paramètre '${input_id}' trouvé pour CalculatorType.${CalculatorType[parentForm.calculatorType]}/ComputeNodeType.${ComputeNodeType[node_type]}`);
-                res = new NgParameter(nubParam, this.isTemplate);
+                const nubParam: ParamDefinition = this.getNubParamFromSymbol(input_id);
+                if (nubParam)
+                    res = new NgParameter(nubParam, this.isTemplate);
         }
 
-        res.parseConfig(json, { "radioConfig": default_radio_config });
+        if (res)
+            res.parseConfig(json, { "radioConfig": default_radio_config });
 
         return res;
     }
 
-    public parseConfig(json: {}, data?: {}) {
-        const parentForm: FormulaireDefinition = data["parentForm"];
-
-        this._confId = json["id"];
-
-        const nt: string = json["nodeType"];
-        let node_type: ComputeNodeType = nt == undefined ? ComputeNodeType.None : ComputeNodeType[nt];
-
-        const fields = json["fields"];
+    private parseFields() {
+        const fields = this._jsonConfig["fields"];
         for (const field_index in fields) {
             const field = fields[field_index];
 
             if (field["type"] === "input") {
-                const default_radio_config = json["option"];
-                const param = this.parse_input(field, parentForm, default_radio_config);
-                this.addField(param);
+                const default_radio_config = this._jsonConfig["option"];
+                const param = this.parse_input(field, default_radio_config);
+                if (param) // potentiellement undefined car certaines définitions de FieldSet comportent des paramètres qui ne sont pas tous affichés en même temps (cf. ouvrages //)
+                    this.addField(param);
             } else if (field["type"] === "select") {
                 const param = this.parse_select(field);
                 this.addField(param);
@@ -136,8 +229,114 @@ export class FieldSet extends FormulaireElement {
         }
     }
 
-    public parseDependencies(json: {}, parentForm: FormulaireDefinition) {
-        super.parseDependencies(json, parentForm);
+    private clearFields() {
+        for (const n of this.kids)
+            n.removeObserver(this);
+
+        this.clearKids();
+    }
+
+    /**
+     * met à jour le SessionNubnub associé
+     * @param createOrUpdate true pour forcer la création d'un SessionNub
+     */
+    private updateNub(createOrUpdate: boolean) {
+        if (this._sessionNub)
+            this._sessionNub = this._parentForm.replaceSessionNub(this._sessionNub, this._props);
+        else {
+            if (createOrUpdate)
+                this._sessionNub = this._parentForm.createSessionNub(this._props);
+            else
+                this._sessionNub = this._parentForm.getSessionNub(this._props);
+        }
+    }
+
+    public updateLocalisation(loc?: StringMap) {
+        if (loc == undefined)
+            loc = this._localisation;
+        else
+            this._localisation = loc;
+
+        if (loc)
+            super.updateLocalisation(loc);
+    }
+
+    /**
+     * @param createOrUpdate true pour forcer la création d'un SessionNub
+     */
+    private updateFields(createOrUpdate: boolean = false) {
+        this.clearFields();
+        this.updateNub(createOrUpdate);
+        this.parseFields();
+        this.parseDependencies(this._jsonConfig);
+        this.updateLocalisation();
+
+        // MAJ des selects avec les valeurs actuelles des propriétés
+        // spécifique à chaque calculette, à revoir
+
+        if (this._confId === "fs_ouvrage") {
+            const sf1: SelectField = this.getFormulaireNodeById("select_ouvrage") as SelectField;
+            const st: StructureType = this.getPropValue("structureType");
+            const se1 = sf1.getSelectedEntryFromValue(st);
+            sf1.setValue(se1);
+
+            switch (st) {
+                case StructureType.SeuilRectangulaire:
+                    const sf2: SelectField = this.getFormulaireNodeById("select_loidebit1") as SelectField;
+                    const se2 = sf2.getSelectedEntryFromValue(this.getPropValue("loiDebit"));
+                    sf2.setValue(se2);
+                    break;
+
+                case StructureType.VanneRectangulaire:
+                    const sf3: SelectField = this.getFormulaireNodeById("select_loidebit2") as SelectField;
+                    const se3 = sf3.getSelectedEntryFromValue(this.getPropValue("loiDebit"));
+                    sf3.setValue(se3);
+                    break;
+            }
+        }
+
+        // fin MAJ selects
+
+        this.applyDependencies(this._parentForm);
+    }
+
+    public parseConfig(json: {}, data?: {}) {
+        this._jsonConfig = json;
+        this._parentForm = data["parentForm"];
+        const cn = data["createNub"]; // flag pour forcer la création d'un SessionNub (true pour création/false pour MAJ, false par défaut )
+        const createOrUpdate = cn ? cn : false;
+
+        this._confId = json["id"];
+
+        const ct: string = json["calcType"];
+        const calc_type: CalculatorType = ct == undefined ? this._parentForm.calculatorType : CalculatorType[ct];
+        this.setPropValue("calcType", calc_type);
+
+        const nt: string = json["nodeType"];
+        const node_type: ComputeNodeType = nt == undefined ? ComputeNodeType.None : ComputeNodeType[nt];
+
+        const dnt: string = json["defaultNodeType"];
+        const default_node_type: ComputeNodeType = dnt == undefined ? ComputeNodeType.None : ComputeNodeType[dnt];
+
+        if (nt !== undefined && dnt !== undefined)
+            throw new Error("les champs 'nodeType' et 'defaultNodeType' ne doivent pas être définis en même temps")
+
+        const ntype = dnt !== undefined ? default_node_type : node_type;
+
+        this.setPropValue("nodeType", ntype);
+
+        const st: string = json["defaultStructType"];
+        if (st)
+            this.setPropValue("structureType", StructureType[st])
+        const ld: string = json["defaultLoiDebit"];
+        if (ld)
+            this.setPropValue("loiDebit", LoiDebit[ld])
+
+        this.updateFields(createOrUpdate);
+    }
+
+    public parseDependencies(json: {}) {
+        super.parseDependencies(json, this);
 
         for (const k1 in json) {
             if (k1 === "fields") {
@@ -150,7 +349,7 @@ export class FieldSet extends FormulaireElement {
                         case "check":
                             for (const k of this.kids)
                                 if (k.id == field["id"]) {
-                                    k.parseDependencies(field, parentForm);
+                                    k.parseDependencies(field, this);
                                     break;
                                 }
                             break;
@@ -197,4 +396,24 @@ export class FieldSet extends FormulaireElement {
             }
         return undefined;
     }
+
+    // interface Observer
+
+    update(sender: any, data: any) {
+        if (data.action && data.action === "select") {
+            let update = false;
+            if (data.value.id.indexOf("select_ouvrage") != -1)
+                update = update || this.setPropValue("structureType", data.value.value);
+            else if (data.value.id.indexOf("select_loidebit1") != -1)
+                update = update || this.setPropValue("loiDebit", data.value.value);
+            else if (data.value.id.indexOf("select_loidebit2") != -1)
+                update = update || this.setPropValue("loiDebit", data.value.value);
+
+            if (update) {
+                console.log("--select");
+                this.updateFields();
+                this._parentForm.reset();
+            }
+        }
+    }
 }
diff --git a/src/app/formulaire/formulaire-element.ts b/src/app/formulaire/formulaire-element.ts
index 49b73808d..ca1c6e10a 100644
--- a/src/app/formulaire/formulaire-element.ts
+++ b/src/app/formulaire/formulaire-element.ts
@@ -51,10 +51,15 @@ export abstract class FormulaireElement extends FormulaireNode {
         return Number(s) != NaN;
     }
 
-    private parse_existence_dependencies(json: {}, parentForm: FormulaireDefinition) {
+    /**
+     * analyse les dépendances d'existence
+     * @param json configuration de la dépendance
+     * @param parentNode node parent dans lequel rechercher l'élément master (dont l'existence dépend)
+     */
+    private parse_existence_dependencies(json: {}, parentNode: FormulaireNode) {
         for (let di in json) {
             let d = json[di];
-            let masterField: FormulaireElement = parentForm.getFormulaireNodeById(d["refid"]) as FormulaireElement;
+            let masterField: FormulaireElement = parentNode.getFormulaireNodeById(d["refid"]) as FormulaireElement;
             if (masterField != undefined) {
                 let rv = d["refvalue"];
                 if (rv != undefined)
@@ -82,14 +87,19 @@ export abstract class FormulaireElement extends FormulaireNode {
                 this._dependencies.push(dep);
             }
             else
-                throw new Error(`la dépendance d'existence de '${this.id}' fait référence à un élément inconnu '${d["refid"]}'`);
+                console.log(`WARNING : la dépendance d'existence de '${this.id}' fait référence à un élément inconnu '${d["refid"]}'`);
         }
     }
 
-    public parseDependencies(json: {}, parentForm: FormulaireDefinition) {
+    /**
+     * analyse les dépendances (existence/valeur)
+     * @param json configuration de la dépendance
+     * @param parentNode node parent dans lequel rechercher l'élément master (dont l'existence dépend)
+     */
+    public parseDependencies(json: {}, parentNode: FormulaireNode) {
         const dep = json["dep_exist"];
         if (dep != undefined)
-            this.parse_existence_dependencies(dep, parentForm);
+            this.parse_existence_dependencies(dep, parentNode);
     }
 
     protected abstract verifyDependency(d: Dependency): boolean;
diff --git a/src/app/formulaire/formulaire-node.ts b/src/app/formulaire/formulaire-node.ts
index 285e8917d..8f33e3f9a 100644
--- a/src/app/formulaire/formulaire-node.ts
+++ b/src/app/formulaire/formulaire-node.ts
@@ -53,6 +53,10 @@ export abstract class FormulaireNode implements IObservable {
         return this._kids;
     }
 
+    public clearKids() {
+        this._kids = [];
+    }
+
     public get isTemplate(): boolean {
         return this._isTemplate;
     }
@@ -183,7 +187,12 @@ export abstract class FormulaireNode implements IObservable {
 
     public abstract parseConfig(json: {}, data?: {});
 
-    public abstract parseDependencies(json: {}, parentForm: FormulaireDefinition);
+    /**
+     * analyse les dépendances (existence/valeur)
+     * @param json configuration de la dépendance
+     * @param parentNode nod parent dans lequel rechercher l'élément master (dont l'existence dépend)
+     */
+    public abstract parseDependencies(json: {}, parentNode: FormulaireNode);
 
     // interface IObservable
 
diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts
index 5fcebe23c..530221a2f 100644
--- a/src/app/formulaire/ngparam.ts
+++ b/src/app/formulaire/ngparam.ts
@@ -26,14 +26,6 @@ export enum ParamRadioConfig {
     CAL
 };
 
-/**
- * infos sur le contexte, les valeurs par défaut et saisie manuellement
- */
-class Context {
-    public default: number;
-    public current: number;
-}
-
 /**
  * classe englobante de ParamDefinition (champs supplémentaires pour l'affichage, radio boutons, ...)
  */
@@ -46,18 +38,6 @@ export class NgParameter extends InputField {
      */
     public isDefault: boolean = false; // archi bug du langage ! si on relit cette propriété sans l'avoir modifiée entre-temps, elle vaut undefined !
 
-    /**
-     * dictionnaire indiquant la valeur du paramètre dans différents contextes
-     * clé : contexte représenté par une chaîne
-     * valeur : instance de Context
-     */
-    private _contexts: { [key: string]: Context } = {};
-
-    /**
-     * id du contexte courant
-     */
-    public currentContextId: string;
-
     constructor(private _paramDef: ParamDefinition, isTmpl = false) {
         super(isTmpl);
     }
@@ -115,74 +95,6 @@ export class NgParameter extends InputField {
         );
     }
 
-    /**
-     * @return true si la valeur du paramètre a été modifiée manuellement dans un contexte donné
-     * @param contextId id du contexte
-     */
-    private isOverriden(contextId: string) {
-        const cnt = this._contexts[contextId];
-        if (cnt == undefined)
-            return false;
-        return cnt.current != undefined;
-    }
-
-    /**
-     * fixe la valeur du paramètre dans un contexte donné
-     * @param contextId id du contexte (par ex dans les ouvrages //, valeur de StructureType+LoiDebit)
-     * @param defaultValue valeur par défaut si la valeur du paramètre n'a pas été modifiée par setValue() depuis la création de l'objet
-     */
-    public resetValue(sender: any, contextId: string, defaultValue: number) {
-        if (this.valueMode == ParamValueMode.SINGLE) {
-            if (!this.isOverriden(contextId)) {
-                this._paramDef.v = defaultValue;
-                this.setContextValue(contextId, defaultValue, false);
-            }
-            else
-                this._paramDef.v = this.getContextValue(contextId);
-            this.notifyValueModified(sender);
-        }
-    }
-
-    /**
-     * @return la valeur du paramètre dans un contexte donné
-     * @param contextId id du contexte
-     */
-    private getContextValue(contextId: string): number {
-        if (contextId == undefined)
-            return this._paramDef.v;
-
-        const cnt = this._contexts[contextId];
-        if (cnt == undefined)
-            return this._paramDef.v;
-
-        if (cnt.current != undefined)
-            return cnt.current;
-
-        return cnt.default;
-    }
-
-    /**
-     * fixe la valeur du paramètre dans un contexte donné
-     * @param contextId id du contexte
-     * @param val valeur du paramètre
-     * @param currentOrDefault true si on fixe la valeur modifiée à la main, false si valeur par défaut
-     */
-    private setContextValue(contextId: string, val: number, currentOrDefault: boolean) {
-        if (contextId != undefined) {
-            var cnt = this._contexts[contextId];
-
-            if (cnt == undefined)
-                cnt = new Context();
-
-            if (currentOrDefault)
-                cnt.current = val;
-            else
-                cnt.default = val;
-
-            this._contexts[contextId] = cnt;
-        }
-    }
-
     /**
      * fixe la valeur du paramètre.
      * une notification préalable est envoyée pour laisser l'occasion aux objets liés de préciser le contexte
@@ -191,17 +103,7 @@ export class NgParameter extends InputField {
      * @param val 
      */
     public setValue(sender: any, val: number) {
-        // on laisse l'occasion de préciser le contexte
-        this.notifyObservers(
-            {
-                "action": "ngparamBeforeValue",
-                "param": this,
-                "value": val
-            }, sender
-        )
-
         this._paramDef.v = val;
-        this.setContextValue(this.currentContextId, val, true);
         this.notifyValueModified(sender);
     }
 
@@ -381,7 +283,6 @@ export class NgParameter extends InputField {
         if (val != undefined)
             this.setValue(this, +val);
         this.radioConfig = NgParameter.getRadioConfig(radioConfig);
-        this.valueMode = ParamValueMode.SINGLE;
         this.isDefault = false; // malgré le fait qu'il soit initialisé dans la déclaration de la classe NgParam à false, quand on relit sa valeur, il vaut undefined (merci Microsoft)
     }
 
diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts
index e53d3bd0d..0163b4ada 100644
--- a/src/app/services/param/param.service.ts
+++ b/src/app/services/param/param.service.ts
@@ -1,4 +1,4 @@
-import { ParamDomain, ComputeNodeType, ParamDefinition, ParamDomainValue, ParamCalculability, CalculatorType, NubFactory } from "jalhyd";
+import { ParamDomain, ParamDefinition, ParamDomainValue, ParamCalculability, NubFactory, SessionNub, Props } from "jalhyd";
 
 import { NgParameter } from "../../formulaire/ngparam";
 import { FormulaireDefinition } from "../../formulaire/definition/form-definition";
@@ -24,25 +24,6 @@ export class ParamService {
         return p;
     }
 
-    /**
-     * crée un paramètre de ComputeNode
-     * @param calcType type de calculette
-     * @param nodeType type de noeud
-     * @param symbol symbole du paramètre
-     * @param isTmpl true si le paramètre créé est un template
-     */
-    // public createNodeParameter(calcType: CalculatorType, nodeType: ComputeNodeType, symbol: string, isTmpl = false): NgParameter {
-    //     if (symbol === "Pr")
-    //         var prmDef: ParamDefinition = this.createAccuracyParameter();
-    //     else
-    //         prmDef = ComputeNodeParameters.getInstance().getComputeNodeParameter(calcType, nodeType, symbol);
-
-    //     if (prmDef == undefined)
-    //         throw new Error(`ParamService.createParameter() : pas de paramètre '${symbol}' pour la calculette ${CalculatorType[calcType]}/type de noeud ${ComputeNodeType[nodeType]}`);
-
-    //     return new NgParameter(prmDef.clone(), isTmpl);
-    // }
-
     /**
      * 
      * @param calcType crée un NgParameter n'appartenant pas à un ComputeNode
@@ -52,6 +33,7 @@ export class ParamService {
         if (symbol === "Pr") {
             var prmDef: ParamDefinition = this.createAccuracyParameter();
             var p = new NgParameter(prmDef.clone(), isTmpl);
+            p.confId = "Pr";
         }
         else {
             const dom = new ParamDomain(ParamDomainValue.POS_NULL);
@@ -109,7 +91,15 @@ export class ParamService {
         return p;
     }
 
-    public createNub(calcType: CalculatorType, nodeType: ComputeNodeType = ComputeNodeType.None) {
-        return NubFactory.getInstance().createNub(calcType, nodeType);
+    public createSessionNub(params: Props | {}): SessionNub {
+        return NubFactory.getInstance().createSessionNub(params);
+    }
+
+    public findSessionNub(params: Props | {}): SessionNub {
+        return NubFactory.getInstance().findSessionNub(params);
+    }
+
+    public replaceSessionNub(sn: SessionNub, params: Props): SessionNub {
+        return NubFactory.getInstance().replaceSessionNub(sn, params);
     }
 }
-- 
GitLab


From c93e508e903ba0df70559e774138d501ae1e085f Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Tue, 17 Apr 2018 10:39:23 +0200
Subject: [PATCH 31/53]  #77 correction d'un bug d'affichage du journal de
 calcul - ajout de la traduction pour le code ERROR_DICHO_CONVERGE

---
 .../fixedvar-results.component.ts             | 22 ++++++++++++++-----
 src/app/results/param-calc-results.ts         |  6 +++++
 src/locale/error_messages.en.json             |  3 ++-
 src/locale/error_messages.fr.json             |  1 +
 4 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/src/app/components/fixedvar-results/fixedvar-results.component.ts b/src/app/components/fixedvar-results/fixedvar-results.component.ts
index 68e5c7f4b..790850906 100644
--- a/src/app/components/fixedvar-results/fixedvar-results.component.ts
+++ b/src/app/components/fixedvar-results/fixedvar-results.component.ts
@@ -95,9 +95,9 @@ export class FixedVarResultsComponent implements DoCheck {
 
         this._doUpdate = false;
         if (this._fixedResults != undefined)
-            this._doUpdate = this._fixedResults.hasResults;
+            this._doUpdate = this._fixedResults.hasResults || this._fixedResults.hasLog;
         if (this._varResults != undefined)
-            this._doUpdate = this._doUpdate || this._varResults.hasResults;
+            this._doUpdate = this._doUpdate || this._varResults.hasResults || this._varResults.hasLog;
     }
 
     public ngDoCheck() {
@@ -105,12 +105,22 @@ export class FixedVarResultsComponent implements DoCheck {
             this._doUpdate = !this.updateResults();
     }
 
+    private mergeLog(result: Result, log: cLog) {
+        if (result && result.hasLog) {
+            if (result.hasGlobalLog)
+                log.addLog(result.globalLog);
+            else
+                log.addLog(result.log);
+        }
+    }
+
     private get mergedGlobalLogs(): cLog {
         const res = new cLog();
-        if (this._fixedResults && this._fixedResults.log)
-            res.addLog(this._fixedResults.log);
-        if (this._varResults && this._varResults.log)
-            res.addLog(this._varResults.log);
+        if (this._fixedResults)
+            this.mergeLog(this._fixedResults.result, res);
+
+        if (this._varResults)
+            this.mergeLog(this._varResults.result, res);
         return res;
     }
 
diff --git a/src/app/results/param-calc-results.ts b/src/app/results/param-calc-results.ts
index 2e9802f80..4a24add19 100644
--- a/src/app/results/param-calc-results.ts
+++ b/src/app/results/param-calc-results.ts
@@ -44,6 +44,12 @@ export abstract class CalculatedParamResults extends CalculatorResults {
         return this._result.ok;
     }
 
+    public get hasLog(): boolean {
+        if (this._result == undefined)
+            return false;
+        return this._result.hasLog;
+    }
+
     public get log(): cLog {
         return this._result && this._result.log;  // return x == undefined ? undefined : x.y
     }
diff --git a/src/locale/error_messages.en.json b/src/locale/error_messages.en.json
index 2711bac57..86f94a508 100644
--- a/src/locale/error_messages.en.json
+++ b/src/locale/error_messages.en.json
@@ -5,6 +5,7 @@
     "ERROR_DICHO_NULL_STEP": "Dichotomy (initial interval search): invalid null step",
     "ERROR_DICHO_INVALID_STEP_GROWTH": "Dichotomy (initial interval search): invalid null step growth",
     "ERROR_DICHO_FUNCTION_VARIATION": "unable to determinate function direction of variation",
+    "ERROR_DICHO_CONVERGE": "Dichotomy could not converge",
     "ERROR_NEWTON_DERIVEE_NULLE": "Null function derivative in Newton computation",
     "ERROR_PARAMDOMAIN_INTERVAL_BOUNDS": "invalid %minValue%/%maxValue% min/max boundaries for 'interval' parameter definition domain",
     "ERROR_PARAMDEF_CALC_UNDEFINED": "calculability of '%symbol%' parameter is undefined",
@@ -81,4 +82,4 @@
     "INFO_PABDIM_TITRE": "Pool pass: dimensions",
     "INFO_PABPUISS_TITRE": "Pool pass: dissipated power",
     "INFO_OUVRAGEPARAL_TITRE": "Parallel structures"
-}
+}
\ No newline at end of file
diff --git a/src/locale/error_messages.fr.json b/src/locale/error_messages.fr.json
index d08817f01..f336ee9cf 100644
--- a/src/locale/error_messages.fr.json
+++ b/src/locale/error_messages.fr.json
@@ -5,6 +5,7 @@
     "ERROR_DICHO_NULL_STEP": "Dichotomie&nbsp;: le pas pour la recherche de l'intervalle de départ ne devrait pas être nul",
     "ERROR_DICHO_INVALID_STEP_GROWTH": "Dichotomie&nbsp;: l'augmentation du pas pour la recherche de l'intervalle de départ est incorrecte (=0)",
     "ERROR_DICHO_FUNCTION_VARIATION": "Dichotomie&nbsp;: impossible de determiner le sens de  variation de la fonction",
+    "ERROR_DICHO_CONVERGE": "La dichotomie n'a pas pu converger",
     "ERROR_NEWTON_DERIVEE_NULLE": "Dérivée nulle dans un calcul par la méthode de Newton",
     "ERROR_PARAMDOMAIN_INTERVAL_BOUNDS": "Les bornes (%minValue%/%maxValue%) de l'intervalle sont incorrectes",
     "ERROR_PARAMDEF_CALC_UNDEFINED": "La calculabilité du paramètre %symbol% n'est pas définie",
-- 
GitLab


From febc963ec1ff58d3e2b08c81ab6ac1bc3eddc142 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Tue, 17 Apr 2018 14:03:13 +0200
Subject: [PATCH 32/53] =?UTF-8?q?=20#77=20ajout=20d'un=20m=C3=A9canisme=20?=
 =?UTF-8?q?pour=20relire=20les=20valeurs=20des=20param=C3=A8tres=20dans=20?=
 =?UTF-8?q?l'interface=20avant=20de=20lancer=20un=20calcul=20(cas=20d'un?=
 =?UTF-8?q?=20param=C3=A8tre=20"=C3=A0=20calculer"=20dont=20la=20valeur=20?=
 =?UTF-8?q?a=20=C3=A9t=C3=A9=20modifi=C3=A9e=20par=20un=20calcul=20pr?=
 =?UTF-8?q?=C3=A9c=C3=A9dent=20dont=20on=20va=20utiliser=20la=20valeur=20s?=
 =?UTF-8?q?aisie=20comme=20valeur=20initialie=20d'un=20CalcSerie)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/components/field-set/field-set.component.ts      | 7 +++++++
 .../fieldset-container/fieldset-container.component.ts   | 7 +++++++
 .../generic-calculator/calculator.component.ts           | 9 +++++++++
 .../components/generic-input/generic-input.component.ts  | 9 ++++++++-
 .../param-field-line/param-field-line.component.ts       | 7 +++++++
 5 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/src/app/components/field-set/field-set.component.ts b/src/app/components/field-set/field-set.component.ts
index 8ab6e803c..b2cee2eb2 100644
--- a/src/app/components/field-set/field-set.component.ts
+++ b/src/app/components/field-set/field-set.component.ts
@@ -187,4 +187,11 @@ export class FieldSetComponent implements DoCheck {
     private onInputChange(event: boolean) {
         this.inputChange.emit();
     }
+
+    /**
+     * relit les valeurs dans l'interface et met à jour les NgParameter
+     */
+    public updateParametersFromUI() {
+        this._paramComponents.forEach(fsc => fsc.updateParameterFromUI());
+    }
 }
diff --git a/src/app/components/fieldset-container/fieldset-container.component.ts b/src/app/components/fieldset-container/fieldset-container.component.ts
index 5f79ed52e..8c58ebd5b 100644
--- a/src/app/components/fieldset-container/fieldset-container.component.ts
+++ b/src/app/components/fieldset-container/fieldset-container.component.ts
@@ -112,4 +112,11 @@ export class FieldsetContainerComponent implements DoCheck {
     private onInputChange(event: boolean) {
         this.inputChange.emit();
     }
+
+    /**
+     * relit les valeurs dans l'interface et met à jour les NgParameter
+     */
+    public updateParametersFromUI() {
+        this._fieldsetComponents.forEach(fsc => fsc.updateParametersFromUI());
+    }
 }
diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index ad9a2a845..fb70bb420 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -201,7 +201,16 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
     //     this.changeDetectorRef.markForCheck();
     // }
 
+    /**
+     * relit les valeurs dans l'interface et met à jour les NgParameter
+     */
+    private updateParametersFromUI() {
+        this._fieldsetComponents.forEach(fsc => fsc.updateParametersFromUI());
+        this._fieldsetContainerComponents.forEach(fscc => fscc.updateParametersFromUI());
+    }
+
     private doCompute() {
+        this.updateParametersFromUI();
         this._formulaire.doCompute();
         this._computeClicked = true;
     }
diff --git a/src/app/components/generic-input/generic-input.component.ts b/src/app/components/generic-input/generic-input.component.ts
index ed55114a0..29bfb23cf 100644
--- a/src/app/components/generic-input/generic-input.component.ts
+++ b/src/app/components/generic-input/generic-input.component.ts
@@ -199,8 +199,15 @@ export abstract class GenericInputComponent extends BaseComponent {
      */
     private set uiValue(ui: any) {
         this._uiValue = ui;
+        this.updateModelFromUI();
+    }
+
+    /**
+     * met à jour le modèle d'après la saisie
+     */
+    public updateModelFromUI() {
         if (this.validateUI())
-            this.setAndValidateModel(this, this.uiToModel(ui));
+            this.setAndValidateModel(this, this.uiToModel(this._uiValue));
     }
 
     private updateAll() {
diff --git a/src/app/components/param-field-line/param-field-line.component.ts b/src/app/components/param-field-line/param-field-line.component.ts
index 8d0575590..d66120394 100644
--- a/src/app/components/param-field-line/param-field-line.component.ts
+++ b/src/app/components/param-field-line/param-field-line.component.ts
@@ -294,4 +294,11 @@ export class ParamFieldLineComponent implements OnChanges {
     private get formHasResults(): boolean {
         return this.formulaireService.currentFormHasResults;
     }
+
+    /**
+     * relit la valeur dans l'interface et met à jour le NgParameter
+     */
+    public updateParameterFromUI() {
+        this._ngParamInputComponent.updateModelFromUI();
+    }
 }
-- 
GitLab


From 92eb6d6053076bdff97bf0f161afc6aa11a09a7b Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Tue, 17 Apr 2018 14:55:04 +0200
Subject: [PATCH 33/53]  #77 suppression du flag _isTemplate de FormulaireNode

---
 .../calculator.component.ts                   |  2 +-
 src/app/formulaire/check-field.ts             |  4 +-
 src/app/formulaire/field.ts                   |  4 --
 src/app/formulaire/fieldset.ts                | 10 ++--
 src/app/formulaire/formulaire-element.ts      | 46 +------------------
 src/app/formulaire/formulaire-node.ts         | 26 +----------
 src/app/formulaire/input-field.ts             |  4 --
 src/app/formulaire/ngparam.ts                 |  4 +-
 src/app/formulaire/select-field.ts            |  4 +-
 src/app/services/param/param.service.ts       |  4 +-
 10 files changed, 17 insertions(+), 91 deletions(-)

diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index fb70bb420..340afd5ae 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -102,7 +102,7 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
      * détermine si un FormulaireElement est du type FieldSet
      */
     private isFieldset(fe): boolean {
-        return fe instanceof FieldSet && !fe.isTemplate;
+        return fe instanceof FieldSet;
     }
 
     /**
diff --git a/src/app/formulaire/check-field.ts b/src/app/formulaire/check-field.ts
index b33f214ef..f36bf2c60 100644
--- a/src/app/formulaire/check-field.ts
+++ b/src/app/formulaire/check-field.ts
@@ -6,8 +6,8 @@ import { FormulaireDefinition } from "./definition/form-definition";
 export class CheckField extends Field {
     private _value: boolean;
 
-    constructor(isTmpl: boolean = false) {
-        super(isTmpl);
+    constructor() {
+        super();
         this._value = false;
     }
 
diff --git a/src/app/formulaire/field.ts b/src/app/formulaire/field.ts
index 488f6aabf..36bf7c496 100644
--- a/src/app/formulaire/field.ts
+++ b/src/app/formulaire/field.ts
@@ -3,10 +3,6 @@ import { FormulaireElement } from "./formulaire-element";
 import { ValueDependency } from "./dependency/value-dependency";
 
 export abstract class Field extends FormulaireElement {
-    constructor(isTmpl: boolean = false) {
-        super(isTmpl);
-    }
-
     public abstract get isValid();
 
     public abstract getValue(): any;
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index e93200e4d..4784248cf 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -43,7 +43,7 @@ export class FieldSet extends FormulaireElement implements Observer {
     public parent_fsc: FieldsetContainer; // A VIRER
 
     constructor() {
-        super(false);
+        super();
         this._props = new Props();
     }
 
@@ -99,13 +99,13 @@ export class FieldSet extends FormulaireElement implements Observer {
     }
 
     private parse_check(json: {}): CheckField {
-        let res: CheckField = new CheckField(this.isTemplate);
+        let res: CheckField = new CheckField();
         res.parseConfig(json)
         return res;
     }
 
     private parse_select(json: {}): SelectField {
-        let res: SelectField = new SelectField(this.isTemplate);
+        let res: SelectField = new SelectField();
         res.parseConfig(json);
         res.addObserver(this);
         return res;
@@ -191,7 +191,7 @@ export class FieldSet extends FormulaireElement implements Observer {
 
         switch (input_id) {
             case "Pr":
-                var res: NgParameter = paramService.createParameter(input_id, this.isTemplate);
+                var res: NgParameter = paramService.createParameter(input_id);
                 break;
 
             default:
@@ -200,7 +200,7 @@ export class FieldSet extends FormulaireElement implements Observer {
 
                 const nubParam: ParamDefinition = this.getNubParamFromSymbol(input_id);
                 if (nubParam)
-                    res = new NgParameter(nubParam, this.isTemplate);
+                    res = new NgParameter(nubParam);
         }
 
         if (res)
diff --git a/src/app/formulaire/formulaire-element.ts b/src/app/formulaire/formulaire-element.ts
index ca1c6e10a..2f2a0c9b6 100644
--- a/src/app/formulaire/formulaire-element.ts
+++ b/src/app/formulaire/formulaire-element.ts
@@ -24,8 +24,8 @@ export abstract class FormulaireElement extends FormulaireNode {
 
     protected _dependencies: Dependency[] = [];
 
-    constructor(isTmpl: boolean = false) {
-        super(isTmpl);
+    constructor() {
+        super();
         this._isDisplayed = true;
     }
 
@@ -168,48 +168,6 @@ export abstract class FormulaireElement extends FormulaireNode {
             console.log(d.toString());
     }
 
-    /**
-     * copie les dépendances de l'élément "this" vers un autre
-     * @param dest élément vers lequel copier les dépendances
-     * @param root élément racine instancié si on copie des dépendances de template
-     */
-    public copyDependencies(dest: FormulaireElement, root: FormulaireElement) {
-        if (dest.isTemplate || dest._dependencies.length != 0 || root.isTemplate || this.id !== dest.id)
-            throw new Error("copyDependencies() : erreur de cohérence (1)");
-
-        // copie des dépendances
-        // à priori, elles ne sont qu'avec des FormulaireElement en dehors du FieldsetContainer
-        // ou avec des FormulaireElement du même FieldSet
-        // cad pas avec des FormulaireElement dans des FieldSet dans le même FieldsetContainer
-
-        for (const d of this._dependencies) {
-            // si l'élément esclave est un template
-            if (this.isTemplate) {
-                // élément maître original
-                const ome: FormulaireElement = d.masterElement;
-                if (!ome.isTemplate)
-                    throw new Error("copyDependencies() : erreur de cohérence (2)"); // la dépendance doit être entre éléments templates
-
-                // on recherche l'instanciation de l'élément maître original dans l'élement racine
-                let nme = root.getFormulaireNodeById(ome.id) as FormulaireElement;
-                if (nme === undefined)
-                    throw new Error("copyDependencies() : correspondance non trouvée");
-
-                // copie de la dépendance
-
-                const nd = d.clone(nme);
-                dest._dependencies.push(nd);
-            }
-            else
-                // pas de template impliqué, on réutilise la dépendance    
-                dest._dependencies.push(d);
-        }
-
-        for (const k of this.kids) {
-            const destKid = dest.getFormulaireNodeById(k.id) as FormulaireElement;
-            (k as FormulaireElement).copyDependencies(destKid, root);
-        }
-    }
 
     public updateLocalisation(loc: StringMap, key?: string) {
         if (!key)
diff --git a/src/app/formulaire/formulaire-node.ts b/src/app/formulaire/formulaire-node.ts
index 8f33e3f9a..1349d0dcb 100644
--- a/src/app/formulaire/formulaire-node.ts
+++ b/src/app/formulaire/formulaire-node.ts
@@ -23,25 +23,14 @@ export abstract class FormulaireNode implements IObservable {
      */
     private _kids: FormulaireNode[];
 
-    /**
-     * true si fait partie d'un template
-     */
-    private _isTemplate: boolean;
-
-    /**
-    * élément d'origine si this est issu d'un template
-    */
-    private _fromTemplate: FormulaireNode;
-
     /**
      * implémentation par délégation de IObservable
      */
     private _observable: Observable;
 
-    constructor(isTmpl: boolean = false) {
+    constructor() {
         this._kids = [];
         this._uid = JalhydObject.nextUID;
-        this._isTemplate = isTmpl;
         this._observable = new Observable()
     }
 
@@ -57,24 +46,11 @@ export abstract class FormulaireNode implements IObservable {
         this._kids = [];
     }
 
-    public get isTemplate(): boolean {
-        return this._isTemplate;
-    }
-
-    public get fromTemplate(): FormulaireNode {
-        return this._fromTemplate;
-    }
-
     public get uid() {
         return this._uid;
     }
 
     protected copyTo(n: FormulaireNode) {
-        if (this._isTemplate) {
-            n._isTemplate = false;
-            n._fromTemplate = this;
-        }
-
         n._confId = this._confId;
         for (const k of this._kids) {
             const nk = k.clone();
diff --git a/src/app/formulaire/input-field.ts b/src/app/formulaire/input-field.ts
index fa0110d52..3aa574a33 100644
--- a/src/app/formulaire/input-field.ts
+++ b/src/app/formulaire/input-field.ts
@@ -5,10 +5,6 @@ import { FormulaireDefinition } from "./definition/form-definition";
 export abstract class InputField extends Field {
     private _value: any;
 
-    constructor(isTmpl = false) {
-        super(isTmpl);
-    }
-
     public getValue() {
         return this._value;
     }
diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts
index 530221a2f..2903c82b1 100644
--- a/src/app/formulaire/ngparam.ts
+++ b/src/app/formulaire/ngparam.ts
@@ -38,8 +38,8 @@ export class NgParameter extends InputField {
      */
     public isDefault: boolean = false; // archi bug du langage ! si on relit cette propriété sans l'avoir modifiée entre-temps, elle vaut undefined !
 
-    constructor(private _paramDef: ParamDefinition, isTmpl = false) {
-        super(isTmpl);
+    constructor(private _paramDef: ParamDefinition) {
+        super();
     }
 
     get symbol(): string {
diff --git a/src/app/formulaire/select-field.ts b/src/app/formulaire/select-field.ts
index 200963db6..f3b4bb946 100644
--- a/src/app/formulaire/select-field.ts
+++ b/src/app/formulaire/select-field.ts
@@ -13,8 +13,8 @@ export class SelectField extends Field {
 
     private _selectedEntry: SelectEntry;
 
-    constructor(isTmpl = false) {
-        super(isTmpl);
+    constructor() {
+        super();
         this._entries = [];
     }
 
diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts
index 0163b4ada..82290e177 100644
--- a/src/app/services/param/param.service.ts
+++ b/src/app/services/param/param.service.ts
@@ -29,10 +29,10 @@ export class ParamService {
      * @param calcType crée un NgParameter n'appartenant pas à un ComputeNode
      * @param symbol symbole du paramètre à créer
      */
-    public createParameter(symbol: string, isTmpl = false): NgParameter {
+    public createParameter(symbol: string): NgParameter {
         if (symbol === "Pr") {
             var prmDef: ParamDefinition = this.createAccuracyParameter();
-            var p = new NgParameter(prmDef.clone(), isTmpl);
+            var p = new NgParameter(prmDef.clone());
             p.confId = "Pr";
         }
         else {
-- 
GitLab


From 0807f2d329d712163316d1c568e0a155cca050d8 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Tue, 17 Apr 2018 15:17:14 +0200
Subject: [PATCH 34/53] =?UTF-8?q?=20#77=20suppression=20du=20m=C3=A9canism?=
 =?UTF-8?q?e=20de=20clonage=20d'un=20FormulaireNode?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/formulaire/check-field.ts             | 15 ----------
 .../formulaire/definition/form-definition.ts  | 14 ----------
 src/app/formulaire/fieldset-container.ts      | 16 -----------
 src/app/formulaire/fieldset.ts                |  7 -----
 src/app/formulaire/formulaire-element.ts      |  9 ------
 src/app/formulaire/formulaire-node.ts         | 28 -------------------
 src/app/formulaire/ngparam.ts                 | 18 ------------
 src/app/formulaire/select-field.ts            | 16 -----------
 8 files changed, 123 deletions(-)

diff --git a/src/app/formulaire/check-field.ts b/src/app/formulaire/check-field.ts
index f36bf2c60..a34d05a5c 100644
--- a/src/app/formulaire/check-field.ts
+++ b/src/app/formulaire/check-field.ts
@@ -27,21 +27,6 @@ export class CheckField extends Field {
         return true;
     }
 
-    /**
-     * copie des membres
-     */
-    protected copyMembers(n: CheckField) {
-        super.copyMembers(n);
-        n._value = this._value;
-    }
-
-    /**
-     * crée une nouvelle instance
-     */
-    protected clone(): CheckField {
-        return new CheckField();
-    }
-
     public parseConfig(json: {}, data?: {}) {
         this._confId = json["id"];
         this.setValue(json["value"] == "true");
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 3dc10da8a..8a7ec372d 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -333,20 +333,6 @@ export abstract class FormulaireDefinition extends FormulaireNode {
         return new TopFormulaireElementIterator(this);
     }
 
-    /**
-     * copie des membres
-     */
-    protected copyMembers(n: FormulaireNode) {
-        throw new Error("FormulaireDefinition.copyMembers() non implémenté");
-    }
-
-    /**
-     * crée une nouvelle instance
-     */
-    protected clone(): FormulaireNode {
-        throw new Error("FormulaireDefinition.clone() non implémenté");
-    }
-
     // interface Observer
 
     // update(sender: IObservable, data: any) {
diff --git a/src/app/formulaire/fieldset-container.ts b/src/app/formulaire/fieldset-container.ts
index 8f263fab4..439c97c36 100644
--- a/src/app/formulaire/fieldset-container.ts
+++ b/src/app/formulaire/fieldset-container.ts
@@ -81,20 +81,4 @@ export class FieldsetContainer extends FormulaireElement {
 
         super.updateLocalisation(loc);
     }
-
-    /**
-     * copie des membres
-     */
-    protected copyMembers(n: FieldsetContainer) {
-        super.copyMembers(n);
-        n._localisation = this._localisation;
-        n.title = this.title;
-    }
-
-    /**
-     * crée une nouvelle instance
-     */
-    protected clone(): FieldsetContainer {
-        return new FieldsetContainer(this._parentForm);
-    }
 }
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 4784248cf..6097eb7fd 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -55,13 +55,6 @@ export class FieldSet extends FormulaireElement implements Observer {
         return this._sessionNub;
     }
 
-    /**
-     * crée une nouvelle instance
-     */
-    protected clone(): FieldSet {
-        return new FieldSet();
-    }
-
     public addField(f: Field) {
         if (f == undefined)
             throw new Error("FieldSet.addField() : argument incorrect (undefined)");
diff --git a/src/app/formulaire/formulaire-element.ts b/src/app/formulaire/formulaire-element.ts
index 2f2a0c9b6..8f081c741 100644
--- a/src/app/formulaire/formulaire-element.ts
+++ b/src/app/formulaire/formulaire-element.ts
@@ -180,15 +180,6 @@ export abstract class FormulaireElement extends FormulaireNode {
             f.updateLocalisation(loc);
     }
 
-    /**
-     * copie des membres
-     */
-    protected copyMembers(n: FormulaireElement) {
-        super.copyTo(n);
-        n._isDisplayed = this._isDisplayed;
-        n._label = this._label;
-    }
-
     public toString() {
         return "id:" + this.id + (this._isDisplayed ? " displayed" : " NOT displayed") + " label:" + this.label;
     }
diff --git a/src/app/formulaire/formulaire-node.ts b/src/app/formulaire/formulaire-node.ts
index 1349d0dcb..7f76ed4f7 100644
--- a/src/app/formulaire/formulaire-node.ts
+++ b/src/app/formulaire/formulaire-node.ts
@@ -50,24 +50,6 @@ export abstract class FormulaireNode implements IObservable {
         return this._uid;
     }
 
-    protected copyTo(n: FormulaireNode) {
-        n._confId = this._confId;
-        for (const k of this._kids) {
-            const nk = k.clone();
-            k.copyMembers(nk);
-            n._kids.push(nk);
-        }
-    }
-
-    /**
-     * obtient une copie en profondeur
-     */
-    public getDeepClone(): FormulaireNode {
-        const res = this.clone();
-        this.copyMembers(res);
-        return res;
-    }
-
     /**
      * cherche un FormulaireNode par son id de conf
      */
@@ -151,16 +133,6 @@ export abstract class FormulaireNode implements IObservable {
         return p.kidIndex(this);
     }
 
-    /**
-     * crée une nouvelle instance (appel simple du constructeur)
-     */
-    protected abstract clone(): FormulaireNode;
-
-    /**
-     * copie des membres
-     */
-    protected abstract copyMembers(n: FormulaireNode);
-
     public abstract parseConfig(json: {}, data?: {});
 
     /**
diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts
index 2903c82b1..580d8b6a9 100644
--- a/src/app/formulaire/ngparam.ts
+++ b/src/app/formulaire/ngparam.ts
@@ -313,22 +313,4 @@ export class NgParameter extends InputField {
             super.updateLocalisation(loc, key);
         }
     }
-
-    /**
-     * copie des membres
-     */
-    protected copyMembers(n: NgParameter) {
-        super.copyMembers(n);
-        n.unit = this.unit;
-        n.radioConfig = this.radioConfig;
-        n.isDefault = this.isDefault;
-        this._paramValues.copyMembers(n._paramValues);
-    }
-
-    /**
-     * crée une nouvelle instance
-     */
-    protected clone(): NgParameter {
-        return new NgParameter(this._paramDef.clone());
-    }
 }
diff --git a/src/app/formulaire/select-field.ts b/src/app/formulaire/select-field.ts
index f3b4bb946..be8bc9581 100644
--- a/src/app/formulaire/select-field.ts
+++ b/src/app/formulaire/select-field.ts
@@ -78,22 +78,6 @@ export class SelectField extends Field {
         }
     }
 
-    /**
-     * copie des membres
-     */
-    protected copyMembers(n: SelectField) {
-        super.copyMembers(n);
-        for (const e of this._entries)
-            n.addEntry(e);
-    }
-
-    /**
-     * crée une nouvelle instance
-     */
-    protected clone(): SelectField {
-        return new SelectField();
-    }
-
     public parseConfig(field: {}, data?: {}) {
         this._confId = field["id"];
         const values = field["select"];
-- 
GitLab


From d63e8e7110abb73bfd73659645fe0849a0dbfa7b Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Tue, 17 Apr 2018 15:22:29 +0200
Subject: [PATCH 35/53] =?UTF-8?q?=20#77=20suppression=20du=20m=C3=A9canism?=
 =?UTF-8?q?e=20de=20clonage=20des=20conditions=20de=20d=C3=A9pendance?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/formulaire/dependency/dependency-condition.ts         | 4 ----
 src/app/formulaire/dependency/dependency.ts                   | 2 --
 .../formulaire/dependency/existence-dependency-condition.ts   | 4 ----
 src/app/formulaire/dependency/existence-dependency.ts         | 4 ----
 src/app/formulaire/dependency/value-dependency-condition.ts   | 4 ----
 src/app/formulaire/dependency/value-dependency.ts             | 4 ----
 6 files changed, 22 deletions(-)

diff --git a/src/app/formulaire/dependency/dependency-condition.ts b/src/app/formulaire/dependency/dependency-condition.ts
index 28480a1ad..876e46426 100644
--- a/src/app/formulaire/dependency/dependency-condition.ts
+++ b/src/app/formulaire/dependency/dependency-condition.ts
@@ -13,8 +13,4 @@ export class DependencyCondition {
     public toString(): string {
         return "cond=" + DependencyConditionType[this._type];
     }
-
-    public clone(): DependencyCondition {
-        throw new Error("la méthode DependencyCondition.clone() doit être redéfinie !")
-    }
 }
diff --git a/src/app/formulaire/dependency/dependency.ts b/src/app/formulaire/dependency/dependency.ts
index aa2a1bc09..c3db2e55d 100644
--- a/src/app/formulaire/dependency/dependency.ts
+++ b/src/app/formulaire/dependency/dependency.ts
@@ -27,6 +27,4 @@ export abstract class Dependency {
     public toString(): string {
         return "master=" + this._master.toString() + "\n  " + this._masterCondition.toString();
     }
-
-    public abstract clone(master: FormulaireElement): Dependency;
 }
diff --git a/src/app/formulaire/dependency/existence-dependency-condition.ts b/src/app/formulaire/dependency/existence-dependency-condition.ts
index 9a60f25b3..0ec4ce094 100644
--- a/src/app/formulaire/dependency/existence-dependency-condition.ts
+++ b/src/app/formulaire/dependency/existence-dependency-condition.ts
@@ -5,8 +5,4 @@ export class ExistenceDependencyCondition extends DependencyCondition {
     constructor() {
         super(DependencyConditionType.IsDisplayed);
     }
-
-    public clone(): ExistenceDependencyCondition {
-        return new ExistenceDependencyCondition();
-    }
 }
diff --git a/src/app/formulaire/dependency/existence-dependency.ts b/src/app/formulaire/dependency/existence-dependency.ts
index 20f0e4f57..0f8aecec3 100644
--- a/src/app/formulaire/dependency/existence-dependency.ts
+++ b/src/app/formulaire/dependency/existence-dependency.ts
@@ -14,8 +14,4 @@ export class ExistenceDependency extends Dependency {
     public toString() {
         return "existdep\n  " + super.toString();
     }
-
-    public clone(master: FormulaireElement): Dependency {
-        return new ExistenceDependency(master, this.masterCondition.clone());
-    }
 }
diff --git a/src/app/formulaire/dependency/value-dependency-condition.ts b/src/app/formulaire/dependency/value-dependency-condition.ts
index 8ba997c9d..b0e309568 100644
--- a/src/app/formulaire/dependency/value-dependency-condition.ts
+++ b/src/app/formulaire/dependency/value-dependency-condition.ts
@@ -13,8 +13,4 @@ export class ValueDependencyCondition extends DependencyCondition {
     public toString(): string {
         return super.toString() + " " + this._value;
     }
-
-    public clone(): ValueDependencyCondition {
-        return new ValueDependencyCondition(this._value);
-    }
 }
diff --git a/src/app/formulaire/dependency/value-dependency.ts b/src/app/formulaire/dependency/value-dependency.ts
index c973ecd6c..7b95b83d6 100644
--- a/src/app/formulaire/dependency/value-dependency.ts
+++ b/src/app/formulaire/dependency/value-dependency.ts
@@ -15,8 +15,4 @@ export class ValueDependency extends Dependency {
     public toString() {
         return "valdep\n  " + super.toString() + "\n  slave val " + this.slaveValue;
     }
-
-    public clone(master: FormulaireElement): Dependency {
-        return new ValueDependency(master, this.masterCondition.clone());
-    }
 }
-- 
GitLab


From 3d0a5d4232033acb35da4ed69540b281e7ada325 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Wed, 18 Apr 2018 13:15:04 +0200
Subject: [PATCH 36/53] =?UTF-8?q?=20#77=20classe=20FormulaireNode=20:=20aj?=
 =?UTF-8?q?out=20d'un=20membre=20=5FparentNode=20pour=20r=C3=A9f=C3=A9renc?=
 =?UTF-8?q?er=20le=20parent=20direct?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/formulaire/check-field.ts             |  5 ++-
 .../form-compute-parallel-structures.ts       |  4 +-
 .../form-compute-section-parametree.ts        |  2 +-
 .../formulaire/definition/form-definition.ts  | 11 +++--
 src/app/formulaire/field.ts                   | 10 ++---
 src/app/formulaire/fieldset-container.ts      | 12 ++---
 src/app/formulaire/fieldset-template.ts       |  5 +--
 src/app/formulaire/fieldset.ts                | 19 ++++----
 src/app/formulaire/formulaire-element.ts      | 11 +++--
 src/app/formulaire/formulaire-node.ts         | 44 ++++++-------------
 src/app/formulaire/ngparam.ts                 |  5 ++-
 src/app/formulaire/select-field.ts            |  5 ++-
 src/app/services/param/param.service.ts       |  7 +--
 13 files changed, 59 insertions(+), 81 deletions(-)

diff --git a/src/app/formulaire/check-field.ts b/src/app/formulaire/check-field.ts
index a34d05a5c..cce27669e 100644
--- a/src/app/formulaire/check-field.ts
+++ b/src/app/formulaire/check-field.ts
@@ -2,12 +2,13 @@ import { Field } from "./field";
 import { Dependency } from "./dependency/dependency";
 import { DependencyConditionType } from "./dependency/dependency-condition";
 import { FormulaireDefinition } from "./definition/form-definition";
+import { FormulaireNode } from "./formulaire-node";
 
 export class CheckField extends Field {
     private _value: boolean;
 
-    constructor() {
-        super();
+    constructor(parent: FormulaireNode) {
+        super(parent);
         this._value = false;
     }
 
diff --git a/src/app/formulaire/definition/form-compute-parallel-structures.ts b/src/app/formulaire/definition/form-compute-parallel-structures.ts
index ce8ff3a10..32f402446 100644
--- a/src/app/formulaire/definition/form-compute-parallel-structures.ts
+++ b/src/app/formulaire/definition/form-compute-parallel-structures.ts
@@ -28,10 +28,10 @@ export class FormComputeParallelStructures extends FormComputeFixedVar {
      * ainsi que l'indice du FieldSet parent dans le FieldsetContainer
      */
     private structureParents(p: NgParameter): [FieldsetContainer, FieldSet, number] {
-        const parent1: FormulaireNode = p.getDirectParent(this._formBase);
+        const parent1: FormulaireNode = p.parent;
         if (parent1 !== undefined)
             if (parent1 instanceof FieldSet) {
-                const parent2 = parent1.getDirectParent(this._formBase);
+                const parent2 = parent1.parent;
                 if (parent2 instanceof FieldsetContainer) {
                     const fsIndex = parent1.indexAsKid(this._formBase);
                     return [parent2, parent1, fsIndex];
diff --git a/src/app/formulaire/definition/form-compute-section-parametree.ts b/src/app/formulaire/definition/form-compute-section-parametree.ts
index 482da27e8..c21c8330f 100644
--- a/src/app/formulaire/definition/form-compute-section-parametree.ts
+++ b/src/app/formulaire/definition/form-compute-section-parametree.ts
@@ -66,7 +66,7 @@ export class FormComputeSectionParametree extends FormCompute {
 
         this._varResults.variatedParameter = varParam;
 
-        const computedParam: NgParameter = this._paramService.createParameter(computedParamInfo.symbol);
+        const computedParam: NgParameter = this._paramService.createParameter(computedParamInfo.symbol, this._formBase);
         this._varResults.calculatedParameter = computedParam;
 
         let compSymbol: string = computedParamInfo["symbol"];
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 8a7ec372d..3fdd02802 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -32,9 +32,8 @@ export abstract class FormulaireDefinition extends FormulaireNode {
 
     protected _paramService: ParamService;
 
-    constructor(calcType: CalculatorType,
-    ) {
-        super();
+    constructor(calcType: CalculatorType) {
+        super(undefined);
         this._calcType = calcType;
         this._paramService = ServiceFactory.instance.paramService;
     }
@@ -100,7 +99,7 @@ export abstract class FormulaireDefinition extends FormulaireNode {
     }
 
     private parse_fieldset(json: {}) {
-        const fs: FieldSet = new FieldSet();
+        const fs: FieldSet = new FieldSet(this);
         this.kids.push(fs);
         fs.parseConfig(json, { "parentForm": this });
     }
@@ -122,7 +121,7 @@ export abstract class FormulaireDefinition extends FormulaireNode {
                 case "template_container":
                     for (const k of this.kids)
                         if (k.id == conf["id"]) {
-                            k.parseDependencies(conf, this);
+                            k.parseDependencies(conf);
                             break;
                         }
                     break;
@@ -130,7 +129,7 @@ export abstract class FormulaireDefinition extends FormulaireNode {
                 case "fieldset_template":
                     for (const k of this.kids)
                         if (k instanceof FieldsetContainer)
-                            k.parseDependencies(conf, this);
+                            k.parseDependencies(conf);
                     break;
             }
         }
diff --git a/src/app/formulaire/field.ts b/src/app/formulaire/field.ts
index 36bf7c496..44524d3f3 100644
--- a/src/app/formulaire/field.ts
+++ b/src/app/formulaire/field.ts
@@ -8,10 +8,10 @@ export abstract class Field extends FormulaireElement {
     public abstract getValue(): any;
     public abstract setValue(sender: any, val: any): void;
 
-    private parse_value_dependencies(json: {}, parentNode: FormulaireNode) {
+    private parse_value_dependencies(json: {}) {
         for (let di in json) {
             let d = json[di];
-            let masterField: FormulaireElement = parentNode.getFormulaireNodeById(d["refid"]) as FormulaireElement;
+            let masterField: FormulaireElement = this.parent.getFormulaireNodeById(d["refid"]) as FormulaireElement;
             if (masterField != undefined) {
                 let masterValue = d["refvalue"];
                 let dep = new ValueDependency(masterField, masterValue);
@@ -23,11 +23,11 @@ export abstract class Field extends FormulaireElement {
         }
     }
 
-    public parseDependencies(json: {}, parentNode: FormulaireNode) {
-        super.parseDependencies(json, parentNode);
+    public parseDependencies(json: {}) {
+        super.parseDependencies(json);
 
         const dep = json["dep_value"];
         if (dep != undefined)
-            this.parse_value_dependencies(dep, parentNode);
+            this.parse_value_dependencies(dep);
     }
 }
diff --git a/src/app/formulaire/fieldset-container.ts b/src/app/formulaire/fieldset-container.ts
index 439c97c36..aa73266ee 100644
--- a/src/app/formulaire/fieldset-container.ts
+++ b/src/app/formulaire/fieldset-container.ts
@@ -5,7 +5,7 @@ import { FieldSet } from "./fieldset";
 import { FieldsetTemplate } from "./fieldset-template";
 import { Dependency } from "./dependency/dependency";
 import { StringMap } from "../stringmap";
-import { FormulaireDefinition } from "./definition/form-definition";
+import { FormulaireNode } from "./formulaire-node";
 import { FormulaireParallelStructure } from "./definition/concrete/form-parallel-structures";
 
 export class FieldsetContainer extends FormulaireElement {
@@ -15,15 +15,11 @@ export class FieldsetContainer extends FormulaireElement {
 
     public title: string
 
-    constructor(private _parentForm: FormulaireDefinition) {
-        super();
+    constructor(parent: FormulaireNode) {
+        super(parent);
         this._templates = [];
     }
 
-    public get parentForm() {
-        return this._parentForm;
-    }
-
     private addTemplate(fst: FieldsetTemplate) {
         this._templates.push(new FieldsetTemplate(fst));
     }
@@ -41,7 +37,7 @@ export class FieldsetContainer extends FormulaireElement {
 
         const inst: FieldSet = templ.instantiateTemplate(this);
         if (inst.sessionNub.nub instanceof Structure) {
-            const psf = this.parentForm as FormulaireParallelStructure;
+            const psf = this.parent as FormulaireParallelStructure;
             psf.addStructureNub(inst.sessionNub.nub as Structure);
         }
 
diff --git a/src/app/formulaire/fieldset-template.ts b/src/app/formulaire/fieldset-template.ts
index a8db81d57..bc3102616 100644
--- a/src/app/formulaire/fieldset-template.ts
+++ b/src/app/formulaire/fieldset-template.ts
@@ -39,10 +39,9 @@ export class FieldsetTemplate {
     }
 
     public instantiateTemplate(cont: FieldsetContainer): FieldSet {
-        const res = new FieldSet();
-        res.parent_fsc = cont;
+        const res = new FieldSet(cont);
         cont.addFieldset(res);
-        res.parseConfig(this._jsonConfig, { "parentForm": cont.parentForm, "createNub": true });
+        res.parseConfig(this._jsonConfig, { "parentForm": cont.parent, "createNub": true });
         return res;
     }
 }
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 6097eb7fd..1ebb4e431 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -13,6 +13,7 @@ import { FormulaireDefinition } from "./definition/form-definition";
 import { Observer } from "../services/observer";
 import { StringMap } from "../stringmap";
 import { FieldsetContainer } from "./fieldset-container";
+import { FormulaireNode } from "./formulaire-node";
 
 export class FieldSet extends FormulaireElement implements Observer {
     /**
@@ -40,10 +41,8 @@ export class FieldSet extends FormulaireElement implements Observer {
      */
     private _props: Props;
 
-    public parent_fsc: FieldsetContainer; // A VIRER
-
-    constructor() {
-        super();
+    constructor(parent: FormulaireNode) {
+        super(parent);
         this._props = new Props();
     }
 
@@ -92,13 +91,13 @@ export class FieldSet extends FormulaireElement implements Observer {
     }
 
     private parse_check(json: {}): CheckField {
-        let res: CheckField = new CheckField();
+        let res: CheckField = new CheckField(this);
         res.parseConfig(json)
         return res;
     }
 
     private parse_select(json: {}): SelectField {
-        let res: SelectField = new SelectField();
+        let res: SelectField = new SelectField(this);
         res.parseConfig(json);
         res.addObserver(this);
         return res;
@@ -184,7 +183,7 @@ export class FieldSet extends FormulaireElement implements Observer {
 
         switch (input_id) {
             case "Pr":
-                var res: NgParameter = paramService.createParameter(input_id);
+                var res: NgParameter = paramService.createParameter(input_id, this);
                 break;
 
             default:
@@ -193,7 +192,7 @@ export class FieldSet extends FormulaireElement implements Observer {
 
                 const nubParam: ParamDefinition = this.getNubParamFromSymbol(input_id);
                 if (nubParam)
-                    res = new NgParameter(nubParam);
+                    res = new NgParameter(nubParam, this);
         }
 
         if (res)
@@ -329,7 +328,7 @@ export class FieldSet extends FormulaireElement implements Observer {
     }
 
     public parseDependencies(json: {}) {
-        super.parseDependencies(json, this);
+        super.parseDependencies(json);
 
         for (const k1 in json) {
             if (k1 === "fields") {
@@ -342,7 +341,7 @@ export class FieldSet extends FormulaireElement implements Observer {
                         case "check":
                             for (const k of this.kids)
                                 if (k.id == field["id"]) {
-                                    k.parseDependencies(field, this);
+                                    k.parseDependencies(field);
                                     break;
                                 }
                             break;
diff --git a/src/app/formulaire/formulaire-element.ts b/src/app/formulaire/formulaire-element.ts
index 8f081c741..4f227999f 100644
--- a/src/app/formulaire/formulaire-element.ts
+++ b/src/app/formulaire/formulaire-element.ts
@@ -24,8 +24,8 @@ export abstract class FormulaireElement extends FormulaireNode {
 
     protected _dependencies: Dependency[] = [];
 
-    constructor() {
-        super();
+    constructor(parent: FormulaireNode) {
+        super(parent);
         this._isDisplayed = true;
     }
 
@@ -54,9 +54,8 @@ export abstract class FormulaireElement extends FormulaireNode {
     /**
      * analyse les dépendances d'existence
      * @param json configuration de la dépendance
-     * @param parentNode node parent dans lequel rechercher l'élément master (dont l'existence dépend)
      */
-    private parse_existence_dependencies(json: {}, parentNode: FormulaireNode) {
+    private parse_existence_dependencies(json: {}) {
         for (let di in json) {
             let d = json[di];
             let masterField: FormulaireElement = parentNode.getFormulaireNodeById(d["refid"]) as FormulaireElement;
@@ -96,10 +95,10 @@ export abstract class FormulaireElement extends FormulaireNode {
      * @param json configuration de la dépendance
      * @param parentNode node parent dans lequel rechercher l'élément master (dont l'existence dépend)
      */
-    public parseDependencies(json: {}, parentNode: FormulaireNode) {
+    public parseDependencies(json: {}) {
         const dep = json["dep_exist"];
         if (dep != undefined)
-            this.parse_existence_dependencies(dep, parentNode);
+            this.parse_existence_dependencies(dep);
     }
 
     protected abstract verifyDependency(d: Dependency): boolean;
diff --git a/src/app/formulaire/formulaire-node.ts b/src/app/formulaire/formulaire-node.ts
index 7f76ed4f7..7957b5e04 100644
--- a/src/app/formulaire/formulaire-node.ts
+++ b/src/app/formulaire/formulaire-node.ts
@@ -1,7 +1,5 @@
 import { JalhydObject } from "jalhyd"
 
-import { FormulaireDefinition } from "./definition/form-definition";
-import { DeepFormulaireNodeIterator } from "./form-iterator/deep-node-iterator";
 import { IObservable, Observer, Observable } from "../services/observer";
 
 /**
@@ -18,6 +16,11 @@ export abstract class FormulaireNode implements IObservable {
     */
     private _uid: number;
 
+    /**
+     * parent direct
+     */
+    private _parentNode: FormulaireNode;
+
     /**
      * enfants (utilisé entre autres pour FormulaireDefinition, FieldSet et FieldsetContainer)
      */
@@ -28,7 +31,8 @@ export abstract class FormulaireNode implements IObservable {
      */
     private _observable: Observable;
 
-    constructor() {
+    constructor(parent: FormulaireNode) {
+        this._parentNode = parent;
         this._kids = [];
         this._uid = JalhydObject.nextUID;
         this._observable = new Observable()
@@ -38,6 +42,10 @@ export abstract class FormulaireNode implements IObservable {
         return this._confId;
     }
 
+    public get parent() {
+        return this._parentNode;
+    }
+
     public get kids(): FormulaireNode[] {
         return this._kids;
     }
@@ -82,28 +90,6 @@ export abstract class FormulaireNode implements IObservable {
         return undefined;
     }
 
-    private hasDirectKid(n: FormulaireNode): boolean {
-        for (const k of this._kids)
-            if (k._uid == n._uid)
-                return true;
-        return false;
-    }
-
-    /**
-     * retourne le parent direct de this
-     * @param root FormulaireNode racine dont on part pour rechercher le parent
-     */
-    public getDirectParent(root: FormulaireNode): FormulaireNode {
-        if (root.hasDirectKid(this))
-            return root;
-
-        const it = new DeepFormulaireNodeIterator(root);
-        for (const n of it)
-            if (n.hasDirectKid(this))
-                return n;
-        return undefined;
-    }
-
     /**
      * retourne l'indice d'un FormulaireNode enfant dans la liste des enfants
      * @param kid FormulaireNode enfant dont on cherche l'indice
@@ -126,11 +112,7 @@ export abstract class FormulaireNode implements IObservable {
      * @param root FormulaireNode racine dont on part pour rechercher le parent
      */
     public indexAsKid(root: FormulaireNode): number {
-        // parent de this
-        const p = this.getDirectParent(root);
-
-        // indice
-        return p.kidIndex(this);
+        return this._parentNode.kidIndex(this);
     }
 
     public abstract parseConfig(json: {}, data?: {});
@@ -140,7 +122,7 @@ export abstract class FormulaireNode implements IObservable {
      * @param json configuration de la dépendance
      * @param parentNode nod parent dans lequel rechercher l'élément master (dont l'existence dépend)
      */
-    public abstract parseDependencies(json: {}, parentNode: FormulaireNode);
+    public abstract parseDependencies(json: {});
 
     // interface IObservable
 
diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts
index 580d8b6a9..4c464642c 100644
--- a/src/app/formulaire/ngparam.ts
+++ b/src/app/formulaire/ngparam.ts
@@ -8,6 +8,7 @@ import { FormulaireDefinition } from "./definition/form-definition";
 import { ServiceFactory } from "../services/service-factory";
 import { ApplicationSetupService } from "../services/app-setup/app-setup.service";
 import { StringMap } from "../stringmap";
+import { FormulaireNode } from "./formulaire-node";
 
 export enum ParamRadioConfig {
     /**
@@ -38,8 +39,8 @@ export class NgParameter extends InputField {
      */
     public isDefault: boolean = false; // archi bug du langage ! si on relit cette propriété sans l'avoir modifiée entre-temps, elle vaut undefined !
 
-    constructor(private _paramDef: ParamDefinition) {
-        super();
+    constructor(private _paramDef: ParamDefinition, parent: FormulaireNode) {
+        super(parent);
     }
 
     get symbol(): string {
diff --git a/src/app/formulaire/select-field.ts b/src/app/formulaire/select-field.ts
index be8bc9581..e30c00373 100644
--- a/src/app/formulaire/select-field.ts
+++ b/src/app/formulaire/select-field.ts
@@ -7,14 +7,15 @@ import { DependencyConditionType } from "./dependency/dependency-condition";
 import { ValueDependencyCondition } from "./dependency/value-dependency-condition";
 import { StringMap } from "../stringmap";
 import { IObservable, Observable, Observer } from "../services/observer";
+import { FormulaireNode } from "./formulaire-node";
 
 export class SelectField extends Field {
     private _entries: SelectEntry[];
 
     private _selectedEntry: SelectEntry;
 
-    constructor() {
-        super();
+    constructor(parent: FormulaireNode) {
+        super(parent);
         this._entries = [];
     }
 
diff --git a/src/app/services/param/param.service.ts b/src/app/services/param/param.service.ts
index 82290e177..6bcc6f831 100644
--- a/src/app/services/param/param.service.ts
+++ b/src/app/services/param/param.service.ts
@@ -6,6 +6,7 @@ import { Injectable } from "@angular/core";
 import { ServiceFactory } from "../service-factory";
 import { InternationalisationService } from "../internationalisation/internationalisation.service";
 import { ApplicationSetupService } from "../app-setup/app-setup.service";
+import { FormulaireNode } from "../../formulaire/formulaire-node";
 
 @Injectable()
 export class ParamService {
@@ -29,15 +30,15 @@ export class ParamService {
      * @param calcType crée un NgParameter n'appartenant pas à un ComputeNode
      * @param symbol symbole du paramètre à créer
      */
-    public createParameter(symbol: string): NgParameter {
+    public createParameter(symbol: string, parent: FormulaireNode): NgParameter {
         if (symbol === "Pr") {
             var prmDef: ParamDefinition = this.createAccuracyParameter();
-            var p = new NgParameter(prmDef.clone());
+            var p = new NgParameter(prmDef.clone(), parent);
             p.confId = "Pr";
         }
         else {
             const dom = new ParamDomain(ParamDomainValue.POS_NULL);
-            p = new NgParameter(new ParamDefinition(symbol, dom));
+            p = new NgParameter(new ParamDefinition(symbol, dom), parent);
             p.confId = symbol;
 
             switch (symbol) {
-- 
GitLab


From 5950449c1866dd16c67d537b13ee891b13341632 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Wed, 18 Apr 2018 13:17:13 +0200
Subject: [PATCH 37/53] =?UTF-8?q?=20#77=20FormCompute.runNubCalc()=20:=20a?=
 =?UTF-8?q?m=C3=A9lioration=20du=20choix=20de=20la=20valeur=20initiale=20(?=
 =?UTF-8?q?cas=20o=C3=B9=20le=20param=C3=A8tre=20=C3=A0=20calculer=20a=20u?=
 =?UTF-8?q?ne=20valeur=20ind=C3=A9finie)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/formulaire/definition/form-compute.ts | 20 ++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/app/formulaire/definition/form-compute.ts b/src/app/formulaire/definition/form-compute.ts
index 22806ea9c..8b7902787 100644
--- a/src/app/formulaire/definition/form-compute.ts
+++ b/src/app/formulaire/definition/form-compute.ts
@@ -31,11 +31,17 @@ export abstract class FormCompute {
         let init: number;
         switch (computedParam.domain.domain) {
             case ParamDomainValue.ANY:
-                init = computedParam.getValue();
+                if (computedParam && computedParam.isDefined)
+                    init = computedParam.getValue();
+                if (init === undefined)
+                    init = 0;
                 break;
 
             case ParamDomainValue.POS_NULL:
-                init = Math.max(computedParam.getValue(), 0);
+                if (computedParam && computedParam.isDefined)
+                    init = Math.max(computedParam.getValue(), 0);
+                if (init === undefined)
+                    init = 0;
                 break;
 
             case ParamDomainValue.INTERVAL:
@@ -43,13 +49,17 @@ export abstract class FormCompute {
                 break;
 
             case ParamDomainValue.NOT_NULL:
-                init = computedParam.getValue();
-                if (init === 0)
+                if (computedParam && computedParam.isDefined)
+                    init = computedParam.getValue();
+                if (init === undefined || init === 0)
                     init = 1e-8;
                 break;
 
             case ParamDomainValue.POS:
-                init = Math.max(computedParam.getValue(), 1e-8);
+                if (computedParam && computedParam.isDefined)
+                    init = Math.max(computedParam.getValue(), 1e-8);
+                if (init === undefined)
+                    init = 1e-8;
                 break;
         }
 
-- 
GitLab


From 50f4b892be183a5ea389de5a69ee83d053ced26d Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Wed, 18 Apr 2018 14:20:30 +0200
Subject: [PATCH 38/53] =?UTF-8?q?=20#77=20correction=20d'un=20bug=20de=20c?=
 =?UTF-8?q?alcul=20de=20validit=C3=A9=20(doit=20d=C3=A9pendre=20uniquement?=
 =?UTF-8?q?=20des=20=C3=A9l=C3=A9ments=20affich=C3=A9s)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/formulaire/definition/form-definition.ts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 3fdd02802..9450cf2cc 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -301,7 +301,8 @@ export abstract class FormulaireDefinition extends FormulaireNode {
     public get isValid(): boolean {
         let res: boolean = true;
         for (let fs of this.allFieldsets)
-            res = res && fs.isValid;
+            if (fs.isDisplayed)
+                res = res && fs.isValid;
         return res;
     }
 
-- 
GitLab


From 57042c78129ac9c5f03bc8895a3708cb2938d805 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 19 Apr 2018 10:36:33 +0200
Subject: [PATCH 39/53]  #77 suppression du getter FieldSet.fields

---
 .../field-set/field-set.component.ts          |  2 +-
 src/app/formulaire/fieldset.ts                | 25 +++++++++----------
 2 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/src/app/components/field-set/field-set.component.ts b/src/app/components/field-set/field-set.component.ts
index b2cee2eb2..f822498e8 100644
--- a/src/app/components/field-set/field-set.component.ts
+++ b/src/app/components/field-set/field-set.component.ts
@@ -54,7 +54,7 @@ export class FieldSetComponent implements DoCheck {
     private _isValid: boolean = false;
 
     private get fields() {
-        return this._fieldSet.fields;
+        return this._fieldSet.kids;
     }
 
     private hasRadioFix(): boolean {
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 1ebb4e431..4a4eb4ddb 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -46,22 +46,18 @@ export class FieldSet extends FormulaireElement implements Observer {
         this._props = new Props();
     }
 
-    public get fields(): Field[] {
-        return this.kids as Field[];
-    }
-
     public get sessionNub(): SessionNub {
         return this._sessionNub;
     }
 
-    public addField(f: Field) {
+    private addField(f: Field) {
         if (f == undefined)
             throw new Error("FieldSet.addField() : argument incorrect (undefined)");
-        this.fields.push(f);
+        this.kids.push(f);
     }
 
     public get hasInputs(): boolean {
-        for (let f of this.fields)
+        for (const f of this.kids)
             if (f instanceof NgParameter)
                 return true;
         return false;
@@ -69,7 +65,7 @@ export class FieldSet extends FormulaireElement implements Observer {
 
     public getInput(i: number): NgParameter {
         let n = 0;
-        for (let f of this.fields) {
+        for (let f of this.kids) {
             if (f instanceof NgParameter) {
                 if (n == i)
                     return f;
@@ -85,8 +81,11 @@ export class FieldSet extends FormulaireElement implements Observer {
 
     public get isValid(): boolean {
         let res: boolean = true;
-        for (let f of this.fields)
-            res = res && f.isValid;
+        for (const f of this.kids) {
+            if (f instanceof Field)
+                if (f.isDisplayed)
+                    res = res && f.isValid;
+        }
         return res;
     }
 
@@ -352,7 +351,7 @@ export class FieldSet extends FormulaireElement implements Observer {
     }
 
     public getNodeParameter(symbol: string): NgParameter {
-        for (let p of this.fields)
+        for (const p of this.kids)
             if (p instanceof NgParameter)
                 if (p.isDisplayed && p.symbol === symbol)
                     return p;
@@ -381,9 +380,9 @@ export class FieldSet extends FormulaireElement implements Observer {
      * @returns valeur courante du select sans le préfixe
      */
     public getSelectedValue(selectFieldId: string): string {
-        for (let p of this.fields)
+        for (const p of this.kids)
             if (p instanceof SelectField && p.isDisplayed && p.id === selectFieldId) {
-                let value: string = p.getValue().value;
+                const value: string = p.getValue().value;
                 return FormulaireElement.removePrefix(value, selectFieldId + "_");
             }
         return undefined;
-- 
GitLab


From 02482c8a102f639c57c2ec53c54942d38cfb6a9c Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 19 Apr 2018 11:15:22 +0200
Subject: [PATCH 40/53] =?UTF-8?q?=20#77=20sections=20param=C3=A9tr=C3=A9es?=
 =?UTF-8?q?=20:=20le=20changement=20de=20type=20de=20section=20est=20d?=
 =?UTF-8?q?=C3=A9tect=C3=A9=20par=20abonnement=20au=20propri=C3=A9t=C3=A9s?=
 =?UTF-8?q?=20du=20fieldset=20contenant=20le=20select,=20plus=20au=20selec?=
 =?UTF-8?q?t=20lui=20m=C3=AAme?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../section-param/section-param.config.json   |  2 +-
 .../formulaire/definition/form-def-section.ts | 44 ++++++++++++-------
 src/app/formulaire/fieldset.ts                |  9 ++++
 3 files changed, 38 insertions(+), 17 deletions(-)

diff --git a/src/app/calculators/section-param/section-param.config.json b/src/app/calculators/section-param/section-param.config.json
index 9740f86d1..eaf075531 100644
--- a/src/app/calculators/section-param/section-param.config.json
+++ b/src/app/calculators/section-param/section-param.config.json
@@ -289,6 +289,6 @@
     },
     {
         "type": "options",
-        "sectionSelectId": "select_section"
+        "sectionSourceId": "fs_section"
     }
 ]
\ No newline at end of file
diff --git a/src/app/formulaire/definition/form-def-section.ts b/src/app/formulaire/definition/form-def-section.ts
index bfc65ea32..ac9050d13 100644
--- a/src/app/formulaire/definition/form-def-section.ts
+++ b/src/app/formulaire/definition/form-def-section.ts
@@ -8,12 +8,13 @@ import { Field } from "../field";
 import { IObservable, Observer } from "../../services/observer";
 import { NgParameter, ParamRadioConfig } from "../ngparam";
 import { FormulaireDefinition } from "./form-definition";
+import { FieldSet } from "../fieldset";
 
 export class FormDefSection implements Observer {
     /**
-     * id du SelectField configurant le type de section
+     * id de l'élément configurant le type de section
      */
-    private _sectionSelectFieldId: string;
+    private _sectionSourceId: string;
 
     /**
      * Type de noeud de calcul actuel de la section (si la calculette est basée sur une section et qu'un menu permet 
@@ -27,8 +28,8 @@ export class FormDefSection implements Observer {
         this._formBase = base;
     }
 
-    private get hasSectionNodeTypeSelect(): boolean {
-        return this._sectionSelectFieldId != undefined;
+    private get hasSectionNodeTypeSource(): boolean {
+        return this._sectionSourceId != undefined;
     }
 
     public get sectionNodeType(): ComputeNodeType {
@@ -36,7 +37,7 @@ export class FormDefSection implements Observer {
     }
 
     private updateSectionNodeType() {
-        const nt = this.getNodeTypeFromSelectField();
+        const nt = this.getNodeTypeFromSourceElement();
         if (this._sectionNodeType !== nt) {
             this._sectionNodeType = nt;
             this._formBase.reset();
@@ -53,26 +54,37 @@ export class FormDefSection implements Observer {
         return { symbol, label };
     }
 
-    private getNodeTypeFromSelectField(): ComputeNodeType {
-        return this._formBase.getSelectedValue(this._sectionSelectFieldId);
+    /**
+     * @return l'élément déterminant le type de section
+     */
+    private getSectionSourceElement(): FieldSet {
+        const fs = this._formBase.getFormulaireNodeById(this._sectionSourceId);
+        if (fs === undefined || !(fs instanceof FieldSet))
+            throw new Error(`le champ ${this._sectionSourceId} n'est pas du type FieldSet`);
+        return fs;
+    }
+
+    /**
+     * @return le type de section déterminé par l'élément source
+     */
+    private getNodeTypeFromSourceElement(): ComputeNodeType {
+        const fs: FieldSet = this.getSectionSourceElement();
+        return fs.getPropValue("nodeType");
     }
 
     public initParse() {
     }
 
     public parseOptions(json: {}) {
-        // id du SelectField configurant le type de section
-        this._sectionSelectFieldId = this._formBase.getOption(json, "sectionSelectId");
+        // id de l'élément configurant le type de section
+        this._sectionSourceId = this._formBase.getOption(json, "sectionSourceId");
     }
 
     public completeParse() {
         // si le formulaire a un menu pour le type de section, on s'abonne à la valeur du champ correspondant
-        if (this.hasSectionNodeTypeSelect) {
-            const f: Field = this._formBase.getFieldById(this._sectionSelectFieldId);
-            if (f == undefined || !(f instanceof SelectField))
-                throw new Error(`le champ ${this._sectionSelectFieldId} n'est pas du type SelectField`);
-            const sectTypeField: SelectField = f as SelectField;
-            sectTypeField.addObserver(this);
+        if (this.hasSectionNodeTypeSource) {
+            const se = this.getSectionSourceElement();
+            se.addObserver(this);
             this.updateSectionNodeType()
         }
     }
@@ -80,7 +92,7 @@ export class FormDefSection implements Observer {
     // interface Observer 
 
     update(sender: any, data: any): void {
-        if (sender instanceof SelectField) {
+        if (data.action == "propertyChange") {
             this.updateSectionNodeType();
         }
     }
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 4a4eb4ddb..3b098f78a 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -106,10 +106,19 @@ export class FieldSet extends FormulaireElement implements Observer {
         return this._props.getPropValue(key);
     }
 
+    private notifyPropChange(prop: string, val: any) {
+        this.notifyObservers({
+            "action": "propertyChange",
+            "name": prop,
+            "value": val
+        }, this)
+    }
+
     public setPropValue(key: string, val: any): boolean {
         const changed = this._props.getPropValue(key) !== val;
         if (changed) {
             this._props.setPropValue(key, val);
+            this.notifyPropChange(key, val);
 
             // si prop=type d'ouvrage, on prend une loi de débit compatible avec (spécifique aux ouvrages //) comme valeur par défaut
             if (key === "structureType") {
-- 
GitLab


From 902267586cb98862c27fb57ce68a206558900e3e Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 19 Apr 2018 15:02:38 +0200
Subject: [PATCH 41/53] =?UTF-8?q?=20#77=20correction=20NgParameter.isValid?=
 =?UTF-8?q?()=20pour=20simplement=20renvoyer=20false=20quand=20l'=C3=A9tat?=
 =?UTF-8?q?=20n'est=20pas=20encore=20d=C3=A9fini?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/formulaire/ngparam.ts | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts
index 4c464642c..c60586b3b 100644
--- a/src/app/formulaire/ngparam.ts
+++ b/src/app/formulaire/ngparam.ts
@@ -253,9 +253,12 @@ export class NgParameter extends InputField {
 
             case ParamRadioConfig.CAL:
                 return true;
+
+            case undefined:
+                return false;
         }
 
-        throw "NgParameter.isValid() : valeur de ParamRadioConfig non prise en compte";
+        throw new Error(`"NgParameter.isValid() : valeur de ParamRadioConfig '${this.radioState}' (radioState) non prise en compte`);
     }
 
     private static getRadioConfig(s: string) {
-- 
GitLab


From 1fc6147215573e68e6d0db8a47848fa8f8bb5620 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 19 Apr 2018 15:10:26 +0200
Subject: [PATCH 42/53]  #77 FormComputeFixedVar.compute() : suppression de
 code inutile

---
 .../formulaire/definition/form-compute-fixedvar.ts | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/src/app/formulaire/definition/form-compute-fixedvar.ts b/src/app/formulaire/definition/form-compute-fixedvar.ts
index f3d477bc2..9214f357d 100644
--- a/src/app/formulaire/definition/form-compute-fixedvar.ts
+++ b/src/app/formulaire/definition/form-compute-fixedvar.ts
@@ -54,20 +54,6 @@ export abstract class FormComputeFixedVar extends FormCompute {
         else {
             // il y a un paramètre à varier
 
-            const nubVarParam = nub.getParameter(varParam.symbol);
-            switch (varParam.valueMode) {
-                case ParamValueMode.LISTE:
-                    nubVarParam.paramValues.setValues(varParam.paramDefinition.paramValues.valueList);
-                    break;
-
-                case ParamValueMode.MINMAX:
-                    const min = varParam.paramDefinition.paramValues.min;
-                    const max = varParam.paramDefinition.paramValues.max;
-                    const step = varParam.paramDefinition.paramValues.step;
-                    nubVarParam.paramValues.setValues(min, max, step);
-                    break;
-            }
-
             const res: Result = this.runNubCalc(nub, computedParam, computePrec);
 
             this.formResult.varResults.variatedParameter = varParam;
-- 
GitLab


From 02af2612f4e6c80906b45b31654ee9ceed8d401d Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 19 Apr 2018 15:14:09 +0200
Subject: [PATCH 43/53]  #77 FieldSet.setPropValue() : utilisation de la classe
 de la lib StructureProperties

---
 src/app/formulaire/fieldset.ts | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 3b098f78a..3a78e8802 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -1,4 +1,4 @@
-import { CalculatorType, ComputeNodeType, ParamDefinition, LoiDebit, StructureType, Props, loiAdmissibles, SessionNub } from "jalhyd";
+import { CalculatorType, ComputeNodeType, ParamDefinition, LoiDebit, StructureType, Props, SessionNub, StructureProperties } from "jalhyd";
 
 import { FormulaireElement } from "./formulaire-element";
 import { Dependency } from "./dependency/dependency";
@@ -122,12 +122,13 @@ export class FieldSet extends FormulaireElement implements Observer {
 
             // si prop=type d'ouvrage, on prend une loi de débit compatible avec (spécifique aux ouvrages //) comme valeur par défaut
             if (key === "structureType") {
-                {
-                    const sst: string = StructureType[val];
-                    const ld: LoiDebit = loiAdmissibles[sst][0];
-                    this.setPropValue("loiDebit", ld);
-                }
+                if (!StructureProperties.isCompatibleValues(val, this.getPropValue("loiDebit")))
+                    this.setPropValue("loiDebit", StructureProperties.findCompatibleLoiDebit(val));
             }
+            // si prop=loi débit, on prend un type d'ouvrage compatible
+            else if (key === "loiDebit")
+                if (!StructureProperties.isCompatibleValues(this.getPropValue("structureType"), val))
+                    this.setPropValue("structureType", StructureProperties.findCompatibleStructure(val));
         }
         return changed;
     }
-- 
GitLab


From b8191304f33121ac687cdf7a7c1f88eadfa67bd8 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 19 Apr 2018 15:19:43 +0200
Subject: [PATCH 44/53] =?UTF-8?q?=20#77=20modifs=20suite=20=C3=A0=20la=20s?=
 =?UTF-8?q?uppression=20de=20l'enum=20ComputeNodeType.StructureKIVI?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../parallel-structures/parallel-structures.config.json     | 6 +++---
 src/app/formulaire/fieldset.ts                              | 5 -----
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/src/app/calculators/parallel-structures/parallel-structures.config.json b/src/app/calculators/parallel-structures/parallel-structures.config.json
index 20c22185c..6b9030e2b 100644
--- a/src/app/calculators/parallel-structures/parallel-structures.config.json
+++ b/src/app/calculators/parallel-structures/parallel-structures.config.json
@@ -210,7 +210,7 @@
                 "type": "input",
                 "id": "alpha",
                 "unit": "",
-                "nodeType": "StructureKIVI",
+                "nodeType": "StructureRectangle",
                 "dep_exist": [
                     {
                         "refid": "select_loidebit1",
@@ -222,7 +222,7 @@
                 "type": "input",
                 "id": "beta",
                 "unit": "",
-                "nodeType": "StructureKIVI",
+                "nodeType": "StructureRectangle",
                 "dep_exist": [
                     {
                         "refid": "select_loidebit1",
@@ -234,7 +234,7 @@
                 "type": "input",
                 "id": "ZRAM",
                 "unit": "",
-                "nodeType": "StructureKIVI",
+                "nodeType": "StructureRectangle",
                 "dep_exist": [
                     {
                         "refid": "select_loidebit1",
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 3a78e8802..9e7f18af5 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -144,11 +144,6 @@ export class FieldSet extends FormulaireElement implements Observer {
                 structType = StructureType.VanneRectangulaire;
                 loiDebit = LoiDebit.Cem88v;
                 break;
-
-            case ComputeNodeType.StructureKIVI:
-                structType = StructureType.SeuilRectangulaire;
-                loiDebit = LoiDebit.KIVI;
-                break;
         }
         return [structType, loiDebit];
     }
-- 
GitLab


From 741755ae07e52d5d7eec31ca16941499b27ad537 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 19 Apr 2018 15:22:00 +0200
Subject: [PATCH 45/53] =?UTF-8?q?=20#77=20r=C3=A9organisation=20de=20la=20?=
 =?UTF-8?q?calculette=20sections=20param=C3=A9tr=C3=A9es=20pour=20coller?=
 =?UTF-8?q?=20au=20mod=C3=A8le=20des=20ouvrages=20parall=C3=A8les,=20cad?=
 =?UTF-8?q?=20qu'il=20n'y=20a=20plus=20un=20fieldset=20avec=20un=20select?=
 =?UTF-8?q?=20seul=20(d=C3=A9plac=C3=A9=20dans=20le=20fieldset=20des=20par?=
 =?UTF-8?q?am=C3=A8tres=20sp=C3=A9cifiques=20de=20la=20section)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../section-param/section-param.config.json   | 114 ++++++++----------
 src/app/formulaire/fieldset.ts                |  28 +++--
 2 files changed, 73 insertions(+), 69 deletions(-)

diff --git a/src/app/calculators/section-param/section-param.config.json b/src/app/calculators/section-param/section-param.config.json
index eaf075531..9ed84e745 100644
--- a/src/app/calculators/section-param/section-param.config.json
+++ b/src/app/calculators/section-param/section-param.config.json
@@ -2,6 +2,8 @@
     {
         "id": "fs_section",
         "type": "fieldset",
+        "defaultNodeType": "SectionTrapeze",
+        "option": "var",
         "fields": [
             {
                 "id": "select_section",
@@ -24,100 +26,85 @@
                         "enum": "ComputeNodeType.SectionPuissance"
                     }
                 ]
-            }
-        ]
-    },
-    {
-        "id": "fs_section_trapez",
-        "type": "fieldset",
-        "option": "var",
-        "dep_exist": [
-            {
-                "refid": "select_section",
-                "refvalue": "select_section_trapez"
-            }
-        ],
-        "fields": [
+            },
             {
                 "type": "input",
                 "id": "LargeurFond",
+                "unit": "m",
                 "nodeType": "SectionTrapeze",
-                "unit": "m"
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_trapez"
+                    }
+                ]
             },
             {
                 "type": "input",
                 "id": "Fruit",
                 "nodeType": "SectionTrapeze",
-                "unit": "m/m"
-            }
-        ]
-    },
-    {
-        "id": "fs_section_rect",
-        "type": "fieldset",
-        "option": "var",
-        "dep_exist": [
-            {
-                "refid": "select_section",
-                "refvalue": "select_section_rect"
-            }
-        ],
-        "fields": [
+                "unit": "m/m",
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_trapez"
+                    }
+                ]
+            },
             {
                 "type": "input",
                 "id": "LargeurBerge",
+                "unit": "m",
                 "nodeType": "SectionRectangle",
-                "unit": "m"
-            }
-        ]
-    },
-    {
-        "id": "fs_section_circ",
-        "type": "fieldset",
-        "option": "var",
-        "dep_exist": [
-            {
-                "refid": "select_section",
-                "refvalue": "select_section_circ"
-            }
-        ],
-        "fields": [
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_rect"
+                    }
+                ]
+            },
             {
                 "type": "input",
                 "id": "D",
+                "unit": "m",
                 "nodeType": "SectionCercle",
-                "unit": "m"
-            }
-        ]
-    },
-    {
-        "id": "fs_section_puissance",
-        "type": "fieldset",
-        "option": "var",
-        "dep_exist": [
-            {
-                "refid": "select_section",
-                "refvalue": "select_section_puiss"
-            }
-        ],
-        "fields": [
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_circ"
+                    }
+                ]
+            },
             {
                 "type": "input",
                 "id": "k",
+                "unit": "",
                 "nodeType": "SectionPuissance",
-                "unit": ""
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_puiss"
+                    }
+                ]
             },
             {
                 "type": "input",
                 "id": "LargeurBerge",
+                "unit": "m",
                 "nodeType": "SectionPuissance",
-                "unit": "m"
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_puiss"
+                    }
+                ]
             }
         ]
     },
     {
         "id": "fs_bief",
         "type": "fieldset",
+        "defaultNodeType": "SectionTrapeze",
         "option": "var",
         "fields": [
             {
@@ -140,6 +127,7 @@
     {
         "id": "fs_hydraulique",
         "type": "fieldset",
+        "defaultNodeType": "SectionTrapeze",
         "option": "var",
         "fields": [
             {
@@ -157,6 +145,7 @@
     {
         "id": "fs_param_calc",
         "type": "fieldset",
+        "defaultNodeType": "SectionTrapeze",
         "option": "fix",
         "fields": [
             {
@@ -168,6 +157,7 @@
     {
         "id": "fs_computed_var",
         "type": "fieldset",
+        "defaultNodeType": "SectionTrapeze",
         "dep_exist": [
             {
                 "refid": "LargeurFond",
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 9e7f18af5..5edca538b 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -194,9 +194,15 @@ export class FieldSet extends FormulaireElement implements Observer {
                 const nt: string = json["nodeType"];
                 let nodeType: ComputeNodeType = nt == undefined ? this.getPropValue("nodeType") : ComputeNodeType[nt];
 
-                const nubParam: ParamDefinition = this.getNubParamFromSymbol(input_id);
-                if (nubParam)
-                    res = new NgParameter(nubParam, this);
+                if (nodeType === this.getPropValue("nodeType")) { // si le nodeType du paramètre est le même que celui du fieldset
+                    try {
+                        var nubParam: ParamDefinition = this.getNubParamFromSymbol(input_id);
+                    }
+                    catch (e) {
+                    }
+                    if (nubParam)
+                        res = new NgParameter(nubParam, this);
+                }
         }
 
         if (res)
@@ -290,6 +296,13 @@ export class FieldSet extends FormulaireElement implements Observer {
                     break;
             }
         }
+        else if (this._confId === "fs_section") {
+            const sf: SelectField = this.getFormulaireNodeById("select_section") as SelectField;
+            const nt: ComputeNodeType = this.getPropValue("nodeType");
+            const se = sf.getSelectedEntryFromValue(nt);
+            sf.setValue(se);
+        }
+
 
         // fin MAJ selects
 
@@ -398,15 +411,16 @@ export class FieldSet extends FormulaireElement implements Observer {
     update(sender: any, data: any) {
         if (data.action && data.action === "select") {
             let update = false;
-            if (data.value.id.indexOf("select_ouvrage") != -1)
+            if (data.value.id.indexOf("select_section_") != -1)  // sections paramétrées
+                update = update || this.setPropValue("nodeType", data.value.value);
+            if (data.value.id.indexOf("select_ouvrage") != -1) // ouvrages parallèles
                 update = update || this.setPropValue("structureType", data.value.value);
-            else if (data.value.id.indexOf("select_loidebit1") != -1)
+            else if (data.value.id.indexOf("select_loidebit1") != -1) // ouvrages parallèles
                 update = update || this.setPropValue("loiDebit", data.value.value);
-            else if (data.value.id.indexOf("select_loidebit2") != -1)
+            else if (data.value.id.indexOf("select_loidebit2") != -1) // ouvrages parallèles
                 update = update || this.setPropValue("loiDebit", data.value.value);
 
             if (update) {
-                console.log("--select");
                 this.updateFields();
                 this._parentForm.reset();
             }
-- 
GitLab


From 844ec86e8cefb3f52426a6159f4a3d108ea3bb2b Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Thu, 19 Apr 2018 16:43:26 +0200
Subject: [PATCH 46/53] =?UTF-8?q?=20#77=20r=C3=A9organisation=20des=20d?=
 =?UTF-8?q?=C3=A9pendances=20pour=20g=C3=A9rer=20le=20fait=20que=20certain?=
 =?UTF-8?q?s=20=C3=A9l=C3=A9ments=20ma=C3=AEtres=20(dont=20d=C3=A9pend=20l?=
 =?UTF-8?q?a=20v=C3=A9rification=20des=20conditions)=20peuvent=20ne=20pas?=
 =?UTF-8?q?=20exister=20au=20moment=20de=20l'analyse=20du=20fichier=20de?=
 =?UTF-8?q?=20config=20de=20la=20calculette=20-=20classe=20Dependency=20:?=
 =?UTF-8?q?=20stockage=20de=20l'id=20de=20l'=C3=A9l=C3=A9ment=20ma=C3=AEtr?=
 =?UTF-8?q?e=20plut=C3=B4t=20que=20l'=C3=A9l=C3=A9ment=20lui=20m=C3=AAme,?=
 =?UTF-8?q?=20stockage=20de=20l'=C3=A9l=C3=A9ment=20esclave=20-=20classe?=
 =?UTF-8?q?=20FormulaireElement=20:=20ajout=20de=20applyDependency()=20pou?=
 =?UTF-8?q?r=20appliquer=20une=20d=C3=A9pendance=20dont=20la=20condition?=
 =?UTF-8?q?=20a=20=C3=A9t=C3=A9=20v=C3=A9rifi=C3=A9e,=20suppression=20de?=
 =?UTF-8?q?=20verifyDependency()?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/formulaire/check-field.ts             |  4 -
 src/app/formulaire/dependency/dependency.ts   | 32 +++++--
 .../formulaire/dependency/value-dependency.ts |  4 +-
 src/app/formulaire/field.ts                   | 30 ++++--
 src/app/formulaire/fieldset-container.ts      |  4 -
 src/app/formulaire/fieldset.ts                |  4 -
 src/app/formulaire/formulaire-element.ts      | 92 ++++++-------------
 src/app/formulaire/ngparam.ts                 |  7 +-
 src/app/formulaire/select-field.ts            |  7 +-
 src/app/util.ts                               |  4 +
 10 files changed, 90 insertions(+), 98 deletions(-)

diff --git a/src/app/formulaire/check-field.ts b/src/app/formulaire/check-field.ts
index cce27669e..95f1afcdb 100644
--- a/src/app/formulaire/check-field.ts
+++ b/src/app/formulaire/check-field.ts
@@ -20,10 +20,6 @@ export class CheckField extends Field {
         this._value = val;
     }
 
-    protected verifyDependency(d: Dependency): boolean {
-        throw "CheckField.verifyDependency() : type de condition '" + DependencyConditionType[d.masterCondition.type] + "' non pris en charge";
-    }
-
     public get isValid(): boolean {
         return true;
     }
diff --git a/src/app/formulaire/dependency/dependency.ts b/src/app/formulaire/dependency/dependency.ts
index c3db2e55d..8df53daef 100644
--- a/src/app/formulaire/dependency/dependency.ts
+++ b/src/app/formulaire/dependency/dependency.ts
@@ -7,24 +7,44 @@ import { DependencyCondition } from "./dependency-condition";
  * cad que son affichage, sa valeur, ... sont modifiés
  */
 export abstract class Dependency {
-    private _master: FormulaireElement;
+    private _slave: FormulaireElement;
+
+    private _masterId: string;
 
     private _masterCondition: DependencyCondition;
 
-    constructor(m: FormulaireElement, mc: DependencyCondition) {
-        this._master = m;
+    constructor(s: FormulaireElement, mid: string, mc: DependencyCondition) {
+        this._slave = s;
+        this._masterId = mid;
         this._masterCondition = mc;
     }
 
-    public get masterElement(): FormulaireElement {
-        return this._master;
+    private getMasterElement(id: string): FormulaireElement {
+        let parentNode = this._slave.parent;
+        while (parentNode != undefined) {
+            var res: FormulaireElement = parentNode.getFormulaireNodeById(id) as FormulaireElement;
+            if (res != undefined)
+                return res;
+            parentNode = parentNode.parent;
+        }
+        return undefined;
+    }
+
+    protected get masterElement(): FormulaireElement {
+        return this.getMasterElement(this._masterId);
     }
 
     public get masterCondition(): DependencyCondition {
         return this._masterCondition;
     }
 
+    public apply() {
+        const master: FormulaireElement = this.masterElement;
+        if (master && master.verifiesDependency(this))
+            this._slave.applyDependency(this);
+    }
+
     public toString(): string {
-        return "master=" + this._master.toString() + "\n  " + this._masterCondition.toString();
+        return "slave=" + this._slave.toString() + "\n  mid=" + this._masterId + "\n  " + this._masterCondition.toString();
     }
 }
diff --git a/src/app/formulaire/dependency/value-dependency.ts b/src/app/formulaire/dependency/value-dependency.ts
index 7b95b83d6..4f06d7d33 100644
--- a/src/app/formulaire/dependency/value-dependency.ts
+++ b/src/app/formulaire/dependency/value-dependency.ts
@@ -8,8 +8,8 @@ import { ValueDependencyCondition } from "./value-dependency-condition";
 export class ValueDependency extends Dependency {
     public slaveValue: any;
 
-    constructor(m: FormulaireElement, masterValue: any) {
-        super(m, new ValueDependencyCondition(masterValue));
+    constructor(slave: FormulaireElement, masterId: string, masterValue: any) {
+        super(slave, masterId, new ValueDependencyCondition(masterValue));
     }
 
     public toString() {
diff --git a/src/app/formulaire/field.ts b/src/app/formulaire/field.ts
index 44524d3f3..99b2599df 100644
--- a/src/app/formulaire/field.ts
+++ b/src/app/formulaire/field.ts
@@ -1,6 +1,7 @@
-import { FormulaireNode } from "./formulaire-node";
 import { FormulaireElement } from "./formulaire-element";
 import { ValueDependency } from "./dependency/value-dependency";
+import { Dependency } from "./dependency/dependency";
+import { isNumber } from "util";
 
 export abstract class Field extends FormulaireElement {
     public abstract get isValid();
@@ -11,15 +12,10 @@ export abstract class Field extends FormulaireElement {
     private parse_value_dependencies(json: {}) {
         for (let di in json) {
             let d = json[di];
-            let masterField: FormulaireElement = this.parent.getFormulaireNodeById(d["refid"]) as FormulaireElement;
-            if (masterField != undefined) {
-                let masterValue = d["refvalue"];
-                let dep = new ValueDependency(masterField, masterValue);
-                dep.slaveValue = d["value"];
-                this._dependencies.push(dep);
-            }
-            else
-                throw new Error(`la dépendance de valeur de '${this.id}' fait référence à un élément inconnu '${d["refid"]}'`);
+            let masterValue = d["refvalue"];
+            let dep = new ValueDependency(this, d["refid"], masterValue);
+            dep.slaveValue = d["value"];
+            this._dependencies.push(dep);
         }
     }
 
@@ -30,4 +26,18 @@ export abstract class Field extends FormulaireElement {
         if (dep != undefined)
             this.parse_value_dependencies(dep);
     }
+
+    /**
+     * applique une dépendance dont la condition a été vérifiée
+     */
+    public applyDependency(d: Dependency) {
+        if (d instanceof ValueDependency) {
+            if (isNumber(d.slaveValue))
+                this.setValue(this, +d.slaveValue);
+            else
+                this.setValue(this, d.slaveValue);
+        }
+        else
+            super.applyDependency(d);
+    }
 }
diff --git a/src/app/formulaire/fieldset-container.ts b/src/app/formulaire/fieldset-container.ts
index aa73266ee..4287dcb02 100644
--- a/src/app/formulaire/fieldset-container.ts
+++ b/src/app/formulaire/fieldset-container.ts
@@ -65,10 +65,6 @@ export class FieldsetContainer extends FormulaireElement {
                     this.addTemplate(d);
     }
 
-    protected verifyDependency(d: Dependency): boolean {
-        return true;
-    }
-
     public updateLocalisation(loc?: StringMap) {
         if (loc == undefined)
             loc = this._localisation;
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 5edca538b..60885ad86 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -75,10 +75,6 @@ export class FieldSet extends FormulaireElement implements Observer {
         return undefined;
     }
 
-    protected verifyDependency(d: Dependency): boolean {
-        throw "FieldSet.verifyDependency() : type de condition '" + DependencyConditionType[d.masterCondition.type] + "' non pris en charge";
-    }
-
     public get isValid(): boolean {
         let res: boolean = true;
         for (const f of this.kids) {
diff --git a/src/app/formulaire/formulaire-element.ts b/src/app/formulaire/formulaire-element.ts
index 4f227999f..00bdce133 100644
--- a/src/app/formulaire/formulaire-element.ts
+++ b/src/app/formulaire/formulaire-element.ts
@@ -47,10 +47,6 @@ export abstract class FormulaireElement extends FormulaireNode {
         return super.kids as FormulaireElement[];
     }
 
-    private isNumber(s: string): boolean {
-        return Number(s) != NaN;
-    }
-
     /**
      * analyse les dépendances d'existence
      * @param json configuration de la dépendance
@@ -58,35 +54,30 @@ export abstract class FormulaireElement extends FormulaireNode {
     private parse_existence_dependencies(json: {}) {
         for (let di in json) {
             let d = json[di];
-            let masterField: FormulaireElement = parentNode.getFormulaireNodeById(d["refid"]) as FormulaireElement;
-            if (masterField != undefined) {
-                let rv = d["refvalue"];
-                if (rv != undefined)
-                    var mc: DependencyCondition = new ValueDependencyCondition(rv);
-                else {
-                    let cond = d["cond"];
-                    if (cond != undefined) {
-                        switch (cond) {
-                            case "isvar":
-                                var mc = new DependencyCondition(DependencyConditionType.IsVariable);
-                                break;
-
-                            case "isdisp":
-                                var mc = new DependencyCondition(DependencyConditionType.IsDisplayed);
-                                break;
-
-                            default:
-                                throw "Formulaire.parse_existence_dependencies() : type de condition '" + cond + "' non pris en charge";
-                        }
+            let rv = d["refvalue"];
+            if (rv != undefined)
+                var mc: DependencyCondition = new ValueDependencyCondition(rv);
+            else {
+                let cond = d["cond"];
+                if (cond != undefined) {
+                    switch (cond) {
+                        case "isvar":
+                            var mc = new DependencyCondition(DependencyConditionType.IsVariable);
+                            break;
+
+                        case "isdisp":
+                            var mc = new DependencyCondition(DependencyConditionType.IsDisplayed);
+                            break;
+
+                        default:
+                            throw "Formulaire.parse_existence_dependencies() : type de condition '" + cond + "' non pris en charge";
                     }
-                    else
-                        throw "Formulaire.parse_existence_dependencies() : infos de dépendance manquantes/non prises en charge";
                 }
-                let dep = new ExistenceDependency(masterField, mc);
-                this._dependencies.push(dep);
+                else
+                    throw "Formulaire.parse_existence_dependencies() : infos de dépendance manquantes/non prises en charge";
             }
-            else
-                console.log(`WARNING : la dépendance d'existence de '${this.id}' fait référence à un élément inconnu '${d["refid"]}'`);
+            let dep = new ExistenceDependency(this, d["refid"], mc);
+            this._dependencies.push(dep);
         }
     }
 
@@ -101,23 +92,17 @@ export abstract class FormulaireElement extends FormulaireNode {
             this.parse_existence_dependencies(dep);
     }
 
-    protected abstract verifyDependency(d: Dependency): boolean;
-
     public verifiesDependency(d: Dependency): boolean {
         if (d.masterCondition.type == DependencyConditionType.IsDisplayed)
             return this._isDisplayed;
-
-        return this.verifyDependency(d);
     }
 
-    private getDependencyFromMasterValue(v: any): Dependency {
-        for (let d of this._dependencies)
-            if (d.masterCondition.type == DependencyConditionType.HasValue) {
-                let mv = (<ValueDependencyCondition>d.masterCondition).value;
-                if (mv === v)
-                    return d;
-            }
-        return undefined;
+    /**
+     * applique une dépendance dont la condition a été vérifiée
+     */
+    public applyDependency(d: Dependency) {
+        if (d instanceof ExistenceDependency)
+            this.isDisplayed = true;
     }
 
     private prepareExistenceDependencies() {
@@ -134,28 +119,7 @@ export abstract class FormulaireElement extends FormulaireNode {
         this.prepareExistenceDependencies();
 
         for (let d of this._dependencies) {
-            let master: FormulaireElement = d.masterElement;
-            if (d instanceof ExistenceDependency && !this._isDisplayed) {
-                let slave: FormulaireElement = this;
-                slave.isDisplayed = slave._isDisplayed || (master.isDisplayed && master.verifiesDependency(d)); // le problème c'est que master.isDisplayed n'est pas forcément correct à ce moment précis...
-            }
-            else if (d instanceof ValueDependency) {
-                let vd = <ValueDependency>d;
-                /*
-                let master: HTMLElement = this.getHtmlElementFromId(d.masterElement.id);
-                if (this.getHtmlElementValue(master) == vd.masterValue) {
-                    let slave: HTMLElement = this.getHtmlElementFromId(d.slaveElement.id);
-                    this.setHtmlElementValue(slave, vd.slaveValue);
-                }
-                */
-                if (master.verifiesDependency(d)) {
-                    let slave = parentForm.getFieldById(this.id);
-                    if (this.isNumber(vd.slaveValue))
-                        slave.setValue(this, +vd.slaveValue);
-                    else
-                        slave.setValue(this, vd.slaveValue);
-                }
-            }
+            d.apply();
         }
 
         for (const k of this.getKids())
diff --git a/src/app/formulaire/ngparam.ts b/src/app/formulaire/ngparam.ts
index c60586b3b..671730429 100644
--- a/src/app/formulaire/ngparam.ts
+++ b/src/app/formulaire/ngparam.ts
@@ -290,7 +290,10 @@ export class NgParameter extends InputField {
         this.isDefault = false; // malgré le fait qu'il soit initialisé dans la déclaration de la classe NgParam à false, quand on relit sa valeur, il vaut undefined (merci Microsoft)
     }
 
-    protected verifyDependency(d: Dependency): boolean {
+    public verifiesDependency(d: Dependency): boolean {
+        if (super.verifiesDependency(d))
+            return true;
+
         switch (d.masterCondition.type) {
             case DependencyConditionType.HasValue:
                 {
@@ -302,7 +305,7 @@ export class NgParameter extends InputField {
                 return this.radioState == ParamRadioConfig.VAR;
 
             default:
-                throw "NgParameter.verifyDependency() : type de condition '" + DependencyConditionType[d.masterCondition.type] + "' non pris en charge";
+                throw "NgParameter.verifiesDependency() : type de condition '" + DependencyConditionType[d.masterCondition.type] + "' non pris en charge";
         }
     }
 
diff --git a/src/app/formulaire/select-field.ts b/src/app/formulaire/select-field.ts
index e30c00373..cf136910a 100644
--- a/src/app/formulaire/select-field.ts
+++ b/src/app/formulaire/select-field.ts
@@ -60,14 +60,17 @@ export class SelectField extends Field {
         return this._selectedEntry.label;
     }
 
-    protected verifyDependency(d: Dependency): boolean {
+    public verifiesDependency(d: Dependency): boolean {
+        if (super.verifiesDependency(d))
+            return true;
+
         switch (d.masterCondition.type) {
             case DependencyConditionType.HasValue:
                 let mc: ValueDependencyCondition = <ValueDependencyCondition>d.masterCondition;
                 return this._selectedEntry.id === mc.value;
 
             default:
-                throw "SelectField.verifyDependency() : type de condition '" + DependencyConditionType[d.masterCondition.type] + "' non pris en charge";
+                throw "SelectField.verifiesDependency() : type de condition '" + DependencyConditionType[d.masterCondition.type] + "' non pris en charge";
         }
     }
 
diff --git a/src/app/util.ts b/src/app/util.ts
index d312650ee..cab3a40aa 100644
--- a/src/app/util.ts
+++ b/src/app/util.ts
@@ -5,3 +5,7 @@ export function logObject(obj: {}, m?: string) {
     else
         console.log(m + " " + JSON.stringify(obj));
 }
+
+export function isNumber(s: string): boolean {
+    return Number(s) != NaN;
+}
-- 
GitLab


From a8335b6601a3144857d55da3f2e3c1e73df896ee Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Fri, 20 Apr 2018 10:06:08 +0200
Subject: [PATCH 47/53] =?UTF-8?q?=20#77=20sections=20param=C3=A9tr=C3=A9es?=
 =?UTF-8?q?=20:=20r=C3=A9initialisation=20du=20formulaire=20quand=20on=20c?=
 =?UTF-8?q?hange=20la=20variable=20=C3=A0=20calculer?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../section-param/section-param.config.json      |  3 ++-
 .../formulaire/definition/form-def-section.ts    | 16 ++++++++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/src/app/calculators/section-param/section-param.config.json b/src/app/calculators/section-param/section-param.config.json
index 9ed84e745..77a0ca17e 100644
--- a/src/app/calculators/section-param/section-param.config.json
+++ b/src/app/calculators/section-param/section-param.config.json
@@ -279,6 +279,7 @@
     },
     {
         "type": "options",
-        "sectionSourceId": "fs_section"
+        "sectionSourceId": "fs_section",
+        "targetSelectId": "select_target"
     }
 ]
\ No newline at end of file
diff --git a/src/app/formulaire/definition/form-def-section.ts b/src/app/formulaire/definition/form-def-section.ts
index ac9050d13..b5a845f0e 100644
--- a/src/app/formulaire/definition/form-def-section.ts
+++ b/src/app/formulaire/definition/form-def-section.ts
@@ -16,6 +16,11 @@ export class FormDefSection implements Observer {
      */
     private _sectionSourceId: string;
 
+    /**
+     * id du select configurant la variable à calculer
+     */
+    private _targetSelectId: string;
+
     /**
      * Type de noeud de calcul actuel de la section (si la calculette est basée sur une section et qu'un menu permet 
      * de sélectionner le type de section)
@@ -78,6 +83,9 @@ export class FormDefSection implements Observer {
     public parseOptions(json: {}) {
         // id de l'élément configurant le type de section
         this._sectionSourceId = this._formBase.getOption(json, "sectionSourceId");
+
+        // id du select configurant la variable à calculer
+        this._targetSelectId = this._formBase.getOption(json, "targetSelectId");
     }
 
     public completeParse() {
@@ -87,6 +95,10 @@ export class FormDefSection implements Observer {
             se.addObserver(this);
             this.updateSectionNodeType()
         }
+        if (this._targetSelectId) {
+            const sel = this._formBase.getFormulaireNodeById(this._targetSelectId);
+            sel.addObserver(this);
+        }
     }
 
     // interface Observer 
@@ -95,5 +107,9 @@ export class FormDefSection implements Observer {
         if (data.action == "propertyChange") {
             this.updateSectionNodeType();
         }
+
+        // RAZ formulaire quand on change la variable à calculer
+        if (sender instanceof SelectField)
+            this._formBase.reset();
     }
 }
-- 
GitLab


From b823e1a4a7ff5a728ec236f36be3c264ea52b5a6 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Fri, 20 Apr 2018 11:25:54 +0200
Subject: [PATCH 48/53] =?UTF-8?q?=20#77=20classes=20relatives=20au=20patte?=
 =?UTF-8?q?rn=20observateur/observ=C3=A9=20d=C3=A9plac=C3=A9es=20dans=20la?=
 =?UTF-8?q?=20lib?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/app.component.ts                      |  3 +-
 .../app-setup/app-setup.component.ts          |  3 +-
 .../base-param-input.component.ts             |  3 +-
 .../calculator.component.ts                   |  3 +-
 .../ngparam-input/ngparam-input.component.ts  |  3 +-
 .../results-graph/graph-type.component.ts     |  3 +-
 .../results-graph/results-graph.component.ts  |  3 +-
 .../concrete/form-lechapt-calmon.ts           |  3 +-
 .../formulaire/definition/form-def-section.ts |  4 +-
 src/app/formulaire/fieldset.ts                |  3 +-
 src/app/formulaire/formulaire-node.ts         |  4 +-
 src/app/formulaire/select-field.ts            |  1 -
 src/app/services/error/error.service.ts       |  3 +-
 .../services/formulaire/formulaire.service.ts |  3 +-
 .../internationalisation.service.ts           |  3 +-
 src/app/services/observer.ts                  | 53 -------------------
 16 files changed, 20 insertions(+), 78 deletions(-)
 delete mode 100644 src/app/services/observer.ts

diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 4df3529cb..938ba9907 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -2,9 +2,10 @@ import { Component, ApplicationRef, OnInit, OnDestroy } from '@angular/core';
 //import { MdDialog } from '@angular/material';
 import { Router } from '@angular/router';
 
+import { Observer } from "jalhyd";
+
 import { environment } from '../environments/environment';
 import { InternationalisationService, Language, LanguageCode } from './services/internationalisation/internationalisation.service';
-import { Observer } from './services/observer';
 import { ErrorService } from './services/error/error.service';
 // import { AlertDialog } from './components/alert-dialog/alert-dialog.component';
 import { FormulaireService } from './services/formulaire/formulaire.service';
diff --git a/src/app/components/app-setup/app-setup.component.ts b/src/app/components/app-setup/app-setup.component.ts
index 0c267b4ec..b8a07cf7c 100644
--- a/src/app/components/app-setup/app-setup.component.ts
+++ b/src/app/components/app-setup/app-setup.component.ts
@@ -1,11 +1,10 @@
 import { Component, ViewChild } from "@angular/core";
 
-import { BaseParam, ParamDomainValue } from "jalhyd";
+import { BaseParam, ParamDomainValue, Observer } from "jalhyd";
 
 import { ApplicationSetupService } from '../../services/app-setup/app-setup.service';
 import { InternationalisationService, Language, LanguageCode } from '../../services/internationalisation/internationalisation.service';
 import { NgBaseParam, BaseParamInputComponent } from "../base-param-input/base-param-input.component";
-import { Observer } from "../../services/observer";
 import { BaseComponent } from "../base/base.component";
 
 @Component({
diff --git a/src/app/components/base-param-input/base-param-input.component.ts b/src/app/components/base-param-input/base-param-input.component.ts
index f37d01bbb..bb60d971a 100644
--- a/src/app/components/base-param-input/base-param-input.component.ts
+++ b/src/app/components/base-param-input/base-param-input.component.ts
@@ -3,10 +3,9 @@
 import { Component, Input, forwardRef, OnInit, DoCheck, ChangeDetectorRef } from "@angular/core";
 import { ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl } from "@angular/forms";
 
-import { BaseParam, NumericalString, Message, ParamDomain, ParamDomainValue } from "jalhyd";
+import { BaseParam, NumericalString, Message, ParamDomain, ParamDomainValue, Observable } from "jalhyd";
 
 import { InternationalisationService, LanguageCode } from "../../services/internationalisation/internationalisation.service";
-import { Observable } from "../../services/observer";
 import { GenericInputComponent } from "../generic-input/generic-input.component";
 
 export class NgBaseParam extends Observable {
diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index 340afd5ae..60d4ea1b4 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -1,12 +1,13 @@
 import { Component, OnInit, DoCheck, OnDestroy, ViewChild, ViewChildren, QueryList } from "@angular/core";
 import { ActivatedRoute } from '@angular/router';
 
+import { Observer } from "jalhyd";
+
 import { FormulaireService } from "../../services/formulaire/formulaire.service";
 import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
 import { FieldSet } from "../../formulaire/fieldset";
 import { FormulaireDefinition } from "../../formulaire/definition/form-definition";
 import { CalculatorResultsComponent } from "../../components/calculator-results/calculator-results.component";
-import { Observer } from "../../services/observer";
 import { Subscription } from "rxjs/Subscription";
 import { FieldSetComponent } from "../field-set/field-set.component";
 import { BaseComponent } from "../base/base.component";
diff --git a/src/app/components/ngparam-input/ngparam-input.component.ts b/src/app/components/ngparam-input/ngparam-input.component.ts
index 10e33c675..abce24cdf 100644
--- a/src/app/components/ngparam-input/ngparam-input.component.ts
+++ b/src/app/components/ngparam-input/ngparam-input.component.ts
@@ -3,12 +3,11 @@
 import { Component, Input, forwardRef, OnInit, DoCheck, ChangeDetectorRef } from "@angular/core";
 import { ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl } from "@angular/forms";
 
-import { NumericalString, Message } from "jalhyd";
+import { NumericalString, Message, Observer } from "jalhyd";
 
 import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
 import { NgParameter } from "../../formulaire/ngparam";
 import { GenericInputComponent } from "../generic-input/generic-input.component";
-import { Observer } from "../../services/observer";
 
 @Component({
     selector: "ngparam-input",
diff --git a/src/app/components/results-graph/graph-type.component.ts b/src/app/components/results-graph/graph-type.component.ts
index e3b3c0333..1dcece55e 100644
--- a/src/app/components/results-graph/graph-type.component.ts
+++ b/src/app/components/results-graph/graph-type.component.ts
@@ -1,8 +1,9 @@
 import { Component } from '@angular/core';
 
+import { Observable, IObservable, Observer } from "jalhyd";
+
 import { GenericSelectComponent } from '../generic-select/generic-select.component';
 import { GraphType } from "../../results/var-results";
-import { Observable, IObservable, Observer } from '../../services/observer';
 
 @Component({
     selector: "graph-type",
diff --git a/src/app/components/results-graph/results-graph.component.ts b/src/app/components/results-graph/results-graph.component.ts
index 1d47ecfbc..9744b769f 100644
--- a/src/app/components/results-graph/results-graph.component.ts
+++ b/src/app/components/results-graph/results-graph.component.ts
@@ -1,8 +1,9 @@
 import { Component, ViewChild, AfterContentInit } from '@angular/core';
 
+import { Observer } from "jalhyd";
+
 import { VarResults, GraphType } from "../../results/var-results";
 import { GraphTypeSelectComponent } from './graph-type.component';
-import { Observer } from '../../services/observer';
 
 @Component({
     selector: 'results-graph',
diff --git a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
index 692684181..3e2af2552 100644
--- a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
+++ b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
@@ -1,4 +1,4 @@
-import { CalculatorType, ComputeNodeType } from "jalhyd";
+import { CalculatorType, ComputeNodeType, Observer } from "jalhyd";
 
 import { FormResultFixedVar } from "../form-result-fixedvar";
 import { FormDefFixedVar } from "../form-def-fixedvar";
@@ -6,7 +6,6 @@ import { FormComputeLechaptCalmon } from "../form-compute-lechapt-calmon";
 import { FormulaireDefinition } from "../form-definition";
 import { CalculatorResults } from "../../../results/calculator-results";
 import { FormDefParamToCalculate } from "../form-def-paramcalc";
-import { Observer } from "../../../services/observer";
 import { SelectField } from "../../select-field";
 
 export class FormulaireLechaptCalmon extends FormulaireDefinition implements Observer {
diff --git a/src/app/formulaire/definition/form-def-section.ts b/src/app/formulaire/definition/form-def-section.ts
index b5a845f0e..519e1f482 100644
--- a/src/app/formulaire/definition/form-def-section.ts
+++ b/src/app/formulaire/definition/form-def-section.ts
@@ -1,11 +1,11 @@
 import {
     ComputeNodeType, ParamsSectionTrapez, cSnTrapez, ParamsSectionRectang, cSnRectang,
-    ParamsSectionCirc, cSnCirc, ParamsSectionPuiss, cSnPuiss, acSection, ParamsEquation
+    ParamsSectionCirc, cSnCirc, ParamsSectionPuiss, cSnPuiss, acSection, ParamsEquation,
+    Observer
 } from "jalhyd";
 
 import { SelectField } from "../select-field";
 import { Field } from "../field";
-import { IObservable, Observer } from "../../services/observer";
 import { NgParameter, ParamRadioConfig } from "../ngparam";
 import { FormulaireDefinition } from "./form-definition";
 import { FieldSet } from "../fieldset";
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 60885ad86..76a23bd47 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -1,4 +1,4 @@
-import { CalculatorType, ComputeNodeType, ParamDefinition, LoiDebit, StructureType, Props, SessionNub, StructureProperties } from "jalhyd";
+import { CalculatorType, ComputeNodeType, ParamDefinition, LoiDebit, StructureType, Props, SessionNub, StructureProperties, Observer } from "jalhyd";
 
 import { FormulaireElement } from "./formulaire-element";
 import { Dependency } from "./dependency/dependency";
@@ -10,7 +10,6 @@ import { NgParameter, ParamRadioConfig } from "./ngparam";
 import { ServiceFactory } from "../services/service-factory";
 import { ParamService } from "../services/param/param.service";
 import { FormulaireDefinition } from "./definition/form-definition";
-import { Observer } from "../services/observer";
 import { StringMap } from "../stringmap";
 import { FieldsetContainer } from "./fieldset-container";
 import { FormulaireNode } from "./formulaire-node";
diff --git a/src/app/formulaire/formulaire-node.ts b/src/app/formulaire/formulaire-node.ts
index 7957b5e04..b323f214b 100644
--- a/src/app/formulaire/formulaire-node.ts
+++ b/src/app/formulaire/formulaire-node.ts
@@ -1,6 +1,4 @@
-import { JalhydObject } from "jalhyd"
-
-import { IObservable, Observer, Observable } from "../services/observer";
+import { JalhydObject, IObservable, Observer, Observable } from "jalhyd"
 
 /**
  * représentation sous forme d'arbre du formulaire et de ses éléments
diff --git a/src/app/formulaire/select-field.ts b/src/app/formulaire/select-field.ts
index cf136910a..f6e4bfb7d 100644
--- a/src/app/formulaire/select-field.ts
+++ b/src/app/formulaire/select-field.ts
@@ -6,7 +6,6 @@ import { Dependency } from "./dependency/dependency";
 import { DependencyConditionType } from "./dependency/dependency-condition";
 import { ValueDependencyCondition } from "./dependency/value-dependency-condition";
 import { StringMap } from "../stringmap";
-import { IObservable, Observable, Observer } from "../services/observer";
 import { FormulaireNode } from "./formulaire-node";
 
 export class SelectField extends Field {
diff --git a/src/app/services/error/error.service.ts b/src/app/services/error/error.service.ts
index 2625cc74f..128ce234f 100644
--- a/src/app/services/error/error.service.ts
+++ b/src/app/services/error/error.service.ts
@@ -1,5 +1,6 @@
 import { Injectable } from '@angular/core';
-import { Observable } from '../observer';
+
+import { Observable } from "jalhyd";
 
 @Injectable()
 export class ErrorService extends Observable {
diff --git a/src/app/services/formulaire/formulaire.service.ts b/src/app/services/formulaire/formulaire.service.ts
index 2aac9462e..3283971c4 100644
--- a/src/app/services/formulaire/formulaire.service.ts
+++ b/src/app/services/formulaire/formulaire.service.ts
@@ -4,7 +4,7 @@ import { Observable as rxObservable } from "rxjs/Observable";
 import "rxjs/add/operator/toPromise";
 import { decode } from "he";
 
-import { CalculatorType, EnumEx } from "jalhyd";
+import { CalculatorType, EnumEx, Observable } from "jalhyd";
 
 import { ServiceFactory } from "../service-factory";
 import { HttpService } from "../../services/http/http.service";
@@ -15,7 +15,6 @@ import { InputField } from "../../formulaire/input-field";
 import { SelectField } from "../../formulaire/select-field";
 import { CheckField } from "../../formulaire/check-field";
 import { StringMap } from "../../stringmap";
-import { Observable } from "../observer";
 import { FormulaireConduiteDistributrice } from "../../formulaire/definition/concrete/form-cond-distri";
 import { FormulaireLechaptCalmon } from "../../formulaire/definition/concrete/form-lechapt-calmon";
 import { FormulaireSectionParametree } from "../../formulaire/definition/concrete/form-section-parametree";
diff --git a/src/app/services/internationalisation/internationalisation.service.ts b/src/app/services/internationalisation/internationalisation.service.ts
index 28edb2f14..4b91abba1 100644
--- a/src/app/services/internationalisation/internationalisation.service.ts
+++ b/src/app/services/internationalisation/internationalisation.service.ts
@@ -1,10 +1,9 @@
 import { Injectable } from '@angular/core';
 import { Response } from '@angular/http';
 
-import { Message, MessageCode } from "jalhyd";
+import { Message, MessageCode, Observable } from "jalhyd";
 
 import { HttpService } from "../http/http.service";
-import { Observable } from "../observer";
 import { StringMap } from "../../stringmap";
 
 /*
diff --git a/src/app/services/observer.ts b/src/app/services/observer.ts
deleted file mode 100644
index b7ecdb17c..000000000
--- a/src/app/services/observer.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-export interface Observer {
-    update(sender: any, data: any): void;
-}
-
-export interface IObservable {
-    /**
-     * ajoute un observateur à la liste
-     */
-    addObserver(o: Observer);
-
-    /**
-     * supprime un observateur de la liste
-     */
-    removeObserver(o: Observer);
-
-    /**
-     * notifie un événement aux observateurs
-     */
-    notifyObservers(data: any, sender?: any);
-}
-
-export class Observable implements IObservable {
-    private _observers: Observer[];
-
-    constructor() {
-        this._observers = [];
-    }
-
-    /**
-     * ajoute un observateur à la liste
-     */
-    public addObserver(o: Observer) {
-        if (this._observers.indexOf(o) == -1)
-            this._observers.push(o);
-    }
-
-    /**
-     * supprime un observateur de la liste
-     */
-    public removeObserver(o: Observer) {
-        this._observers = this._observers.filter(a => a !== o);
-    }
-
-    /**
-     * notifie un événement aux observateurs
-     */
-    public notifyObservers(data: any, sender?: any) {
-        if (sender == undefined)
-            sender = this;
-        for (let o of this._observers)
-            o.update(sender, data);
-    }
-}
-- 
GitLab


From 308dad3e2ceb30501d8ad4b8ff7ade6d850bbc97 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Tue, 24 Apr 2018 15:54:24 +0200
Subject: [PATCH 49/53] =?UTF-8?q?=20#77=20fichier=20de=20config=20r=C3=A9g?=
 =?UTF-8?q?ime=20uniforme/courbes=20de=20remous=20:=20r=C3=A9organisaton?=
 =?UTF-8?q?=20pour=20regrouper=20les=20fieldset=20des=20param=C3=A8tres=20?=
 =?UTF-8?q?sp=C3=A9cifiques=20des=20sections=20et=20le=20fieldset=20compor?=
 =?UTF-8?q?tant=20le=20select=20"type=20de=20section"=20dans=20un=20seul?=
 =?UTF-8?q?=20fieldset=20-=20g=C3=A9n=C3=A9ralisation=20du=20principe=20d'?=
 =?UTF-8?q?abonner=20(en=20tant=20qu'observateur)=20le=20formulaire=20aux?=
 =?UTF-8?q?=20propri=C3=A9t=C3=A9s=20des=20fieldset=20contenant=20un=20sel?=
 =?UTF-8?q?ect=20pour=20r=C3=A9agir=20au=20changement=20(r=C3=A9initialisa?=
 =?UTF-8?q?tion=20du=20formulaire,=20effacement=20des=20r=C3=A9sultats,=20?=
 =?UTF-8?q?...)=20-=20les=20cr=C3=A9ation/suppression/remplacement=20des?=
 =?UTF-8?q?=20SessionNub=20ne=20se=20fait=20plus=20qu'au=20niveau=20du=20f?=
 =?UTF-8?q?ormulaire,=20plus=20par=20les=20fieldset=20dans=20le=20cas=20de?=
 =?UTF-8?q?s=20ouvrages=20parall=C3=A8les=20-=20suppression=20de=20certain?=
 =?UTF-8?q?es=20classes=20FormComputeXX=20devenues=20inutiles=20-=20m?=
 =?UTF-8?q?=C3=A9thode=20FormCompute.getCurrentSessionNub()=20supprim?=
 =?UTF-8?q?=C3=A9e?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../parallel-structures.config.json           |   1 +
 .../regime-uniforme.config.json               | 127 ++++++------
 src/app/calculators/remous/remous.config.json | 183 ++++++++++--------
 .../section-param/section-param.config.json   |   3 +-
 .../definition/concrete/form-cond-distri.ts   |  12 +-
 .../definition/concrete/form-courbe-remous.ts |  49 ++++-
 .../concrete/form-lechapt-calmon.ts           |  12 +-
 .../concrete/form-parallel-structures.ts      |  52 ++++-
 .../concrete/form-passe-bassin-dim.ts         |  12 +-
 .../concrete/form-passe-bassin-puissance.ts   |  12 +-
 .../concrete/form-regime-uniforme.ts          |  40 +++-
 .../concrete/form-section-parametree.ts       |  33 +++-
 .../definition/form-compute-cond-distri.ts    |  18 --
 .../definition/form-compute-courbe-remous.ts  |  24 +--
 .../definition/form-compute-fixedvar.ts       |   4 +-
 .../definition/form-compute-lechapt-calmon.ts |  18 --
 .../definition/form-compute-pab-bassin-dim.ts |  18 --
 .../form-compute-pab-bassin-puissance.ts      |  18 --
 .../form-compute-parallel-structures.ts       |   7 -
 .../form-compute-regime-uniforme.ts           |  19 --
 .../form-compute-section-parametree.ts        |  11 +-
 src/app/formulaire/definition/form-compute.ts |   2 -
 .../definition/form-def-fixedvar.ts           |   2 -
 .../definition/form-def-paramcalc.ts          |  22 ++-
 .../formulaire/definition/form-def-section.ts |  83 ++------
 .../formulaire/definition/form-definition.ts  | 105 ++++++++--
 src/app/formulaire/fieldset-container.ts      |   4 -
 src/app/formulaire/fieldset-template.ts       |   7 +-
 src/app/formulaire/fieldset.ts                |  85 +++-----
 src/app/formulaire/select-field.ts            |   9 +-
 src/app/results/remous-results.ts             |   2 +
 31 files changed, 497 insertions(+), 497 deletions(-)
 delete mode 100644 src/app/formulaire/definition/form-compute-cond-distri.ts
 delete mode 100644 src/app/formulaire/definition/form-compute-lechapt-calmon.ts
 delete mode 100644 src/app/formulaire/definition/form-compute-pab-bassin-dim.ts
 delete mode 100644 src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts
 delete mode 100644 src/app/formulaire/definition/form-compute-regime-uniforme.ts

diff --git a/src/app/calculators/parallel-structures/parallel-structures.config.json b/src/app/calculators/parallel-structures/parallel-structures.config.json
index 6b9030e2b..496e6114f 100644
--- a/src/app/calculators/parallel-structures/parallel-structures.config.json
+++ b/src/app/calculators/parallel-structures/parallel-structures.config.json
@@ -265,6 +265,7 @@
     },
     {
         "type": "options",
+        "ouvrageSelectId": "select_ouvrage",
         "idCal": "Q"
     }
 ]
\ No newline at end of file
diff --git a/src/app/calculators/regime-uniforme/regime-uniforme.config.json b/src/app/calculators/regime-uniforme/regime-uniforme.config.json
index 5ac0d5738..5710ce3e1 100644
--- a/src/app/calculators/regime-uniforme/regime-uniforme.config.json
+++ b/src/app/calculators/regime-uniforme/regime-uniforme.config.json
@@ -2,118 +2,109 @@
     {
         "id": "fs_section",
         "type": "fieldset",
+        "defaultNodeType": "SectionTrapeze",
+        "option": "cal",
         "fields": [
             {
                 "id": "select_section",
                 "type": "select",
                 "select": [
                     {
-                        "id": "select_section_trapez"
+                        "id": "select_section_trapez",
+                        "enum": "ComputeNodeType.SectionTrapeze"
                     },
                     {
-                        "id": "select_section_rect"
+                        "id": "select_section_rect",
+                        "enum": "ComputeNodeType.SectionRectangle"
                     },
                     {
-                        "id": "select_section_circ"
+                        "id": "select_section_circ",
+                        "enum": "ComputeNodeType.SectionCercle"
                     },
                     {
-                        "id": "select_section_puiss"
+                        "id": "select_section_puiss",
+                        "enum": "ComputeNodeType.SectionPuissance"
                     }
                 ]
-            }
-        ]
-    },
-    {
-        "id": "fs_section_trapez",
-        "type": "fieldset",
-        "option": "cal",
-        "dep_exist": [
-            {
-                "refid": "select_section",
-                "refvalue": "select_section_trapez"
-            }
-        ],
-        "fields": [
+            },
             {
                 "type": "input",
                 "id": "LargeurFond",
                 "nodeType": "SectionTrapeze",
-                "unit": "m"
+                "unit": "m",
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_trapez"
+                    }
+                ]
             },
             {
                 "type": "input",
                 "id": "Fruit",
                 "nodeType": "SectionTrapeze",
-                "unit": "m/m"
-            }
-        ]
-    },
-    {
-        "id": "fs_section_rect",
-        "type": "fieldset",
-        "option": "cal",
-        "dep_exist": [
-            {
-                "refid": "select_section",
-                "refvalue": "select_section_rect"
-            }
-        ],
-        "fields": [
+                "unit": "m/m",
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_trapez"
+                    }
+                ]
+            },
             {
                 "type": "input",
                 "id": "LargeurBerge",
                 "nodeType": "SectionRectangle",
-                "unit": "m"
-            }
-        ]
-    },
-    {
-        "id": "fs_section_circ",
-        "type": "fieldset",
-        "option": "cal",
-        "dep_exist": [
-            {
-                "refid": "select_section",
-                "refvalue": "select_section_circ"
-            }
-        ],
-        "fields": [
+                "unit": "m",
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_rect"
+                    }
+                ]
+            },
             {
                 "type": "input",
                 "id": "D",
                 "nodeType": "SectionCercle",
-                "unit": "m"
-            }
-        ]
-    },
-    {
-        "id": "fs_section_puiss",
-        "type": "fieldset",
-        "option": "cal",
-        "dep_exist": [
-            {
-                "refid": "select_section",
-                "refvalue": "select_section_puiss"
-            }
-        ],
-        "fields": [
+                "unit": "m",
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_circ"
+                    }
+                ]
+            },
             {
                 "type": "input",
                 "id": "k",
                 "nodeType": "SectionPuissance",
-                "unit": ""
+                "unit": "",
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_puiss"
+                    }
+                ]
             },
             {
                 "type": "input",
                 "id": "LargeurBerge",
                 "nodeType": "SectionPuissance",
-                "unit": "m"
+                "unit": "m",
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_puiss"
+                    }
+                ]
             }
         ]
     },
     {
         "id": "fs_bief",
         "type": "fieldset",
+        "defaultNodeType": "SectionTrapeze",
         "option": "cal",
         "fields": [
             {
@@ -136,6 +127,7 @@
     {
         "id": "fs_hydraulique",
         "type": "fieldset",
+        "defaultNodeType": "SectionTrapeze",
         "option": "cal",
         "fields": [
             {
@@ -153,6 +145,7 @@
     {
         "id": "fs_param_calc",
         "type": "fieldset",
+        "defaultNodeType": "SectionTrapeze",
         "option": "fix",
         "fields": [
             {
@@ -164,6 +157,6 @@
     {
         "type": "options",
         "idCal": "Q",
-        "sectionSelectId": "select_section"
+        "sectionSourceId": "fs_section"
     }
 ]
\ No newline at end of file
diff --git a/src/app/calculators/remous/remous.config.json b/src/app/calculators/remous/remous.config.json
index 2110d94c0..f530722a3 100644
--- a/src/app/calculators/remous/remous.config.json
+++ b/src/app/calculators/remous/remous.config.json
@@ -2,118 +2,109 @@
     {
         "id": "fs_section",
         "type": "fieldset",
+        "defaultNodeType": "SectionTrapeze",
+        "option": "fix",
         "fields": [
             {
                 "id": "select_section",
                 "type": "select",
                 "select": [
                     {
-                        "id": "select_section_trapez"
+                        "id": "select_section_trapez",
+                        "enum": "ComputeNodeType.SectionTrapeze"
                     },
                     {
-                        "id": "select_section_rect"
+                        "id": "select_section_rect",
+                        "enum": "ComputeNodeType.SectionRectangle"
                     },
                     {
-                        "id": "select_section_circ"
+                        "id": "select_section_circ",
+                        "enum": "ComputeNodeType.SectionCercle"
                     },
                     {
-                        "id": "select_section_puiss"
+                        "id": "select_section_puiss",
+                        "enum": "ComputeNodeType.SectionPuissance"
                     }
                 ]
-            }
-        ]
-    },
-    {
-        "id": "fs_section_trapez",
-        "type": "fieldset",
-        "option": "fix",
-        "dep_exist": [
-            {
-                "refid": "select_section",
-                "refvalue": "select_section_trapez"
-            }
-        ],
-        "fields": [
+            },
             {
                 "type": "input",
                 "id": "LargeurFond",
                 "nodeType": "SectionTrapeze",
-                "unit": "m"
+                "unit": "m",
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_trapez"
+                    }
+                ]
             },
             {
                 "type": "input",
                 "id": "Fruit",
                 "nodeType": "SectionTrapeze",
-                "unit": "m/m"
-            }
-        ]
-    },
-    {
-        "id": "fs_section_rect",
-        "type": "fieldset",
-        "option": "fix",
-        "dep_exist": [
-            {
-                "refid": "select_section",
-                "refvalue": "select_section_rect"
-            }
-        ],
-        "fields": [
+                "unit": "m/m",
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_trapez"
+                    }
+                ]
+            },
             {
                 "type": "input",
                 "id": "LargeurBerge",
                 "nodeType": "SectionRectangle",
-                "unit": "m"
-            }
-        ]
-    },
-    {
-        "id": "fs_section_circ",
-        "type": "fieldset",
-        "option": "fix",
-        "dep_exist": [
-            {
-                "refid": "select_section",
-                "refvalue": "select_section_circ"
-            }
-        ],
-        "fields": [
+                "unit": "m",
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_rect"
+                    }
+                ]
+            },
             {
                 "type": "input",
                 "id": "D",
                 "nodeType": "SectionCercle",
-                "unit": "m"
-            }
-        ]
-    },
-    {
-        "id": "fs_section_puiss",
-        "type": "fieldset",
-        "option": "fix",
-        "dep_exist": [
-            {
-                "refid": "select_section",
-                "refvalue": "select_section_puiss"
-            }
-        ],
-        "fields": [
+                "unit": "m",
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_circ"
+                    }
+                ]
+            },
             {
                 "type": "input",
                 "id": "k",
                 "nodeType": "SectionPuissance",
-                "unit": ""
+                "unit": "",
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_puiss"
+                    }
+                ]
             },
             {
                 "type": "input",
                 "id": "LargeurBerge",
                 "nodeType": "SectionPuissance",
-                "unit": "m"
+                "unit": "m",
+                "dep_exist": [
+                    {
+                        "refid": "select_section",
+                        "refvalue": "select_section_puiss"
+                    }
+                ]
             }
         ]
     },
     {
         "id": "fs_bief",
         "type": "fieldset",
+        "defaultNodeType": "SectionTrapeze",
         "option": "fix",
         "fields": [
             {
@@ -141,6 +132,7 @@
     {
         "id": "fs_condlim",
         "type": "fieldset",
+        "defaultNodeType": "SectionTrapeze",
         "option": "fix",
         "fields": [
             {
@@ -163,6 +155,7 @@
     {
         "id": "fs_param_calc",
         "type": "fieldset",
+        "defaultNodeType": "SectionTrapeze",
         "option": "fix",
         "fields": [
             {
@@ -179,13 +172,16 @@
                 "type": "select",
                 "select": [
                     {
-                        "id": "select_resolution_trap"
+                        "id": "select_resolution_trap",
+                        "enum": "MethodeResolution.Trapezes"
                     },
                     {
-                        "id": "select_resolution_rk4"
+                        "id": "select_resolution_rk4",
+                        "enum": "MethodeResolution.RungeKutta4"
                     },
                     {
-                        "id": "select_resolution_euler"
+                        "id": "select_resolution_euler",
+                        "enum": "MethodeResolution.EulerExplicite"
                     }
                 ]
             }
@@ -203,49 +199,64 @@
                         "id": "select_target_none"
                     },
                     {
-                        "id": "select_target_Hs"
+                        "id": "select_target_Hs",
+                        "value": "Hs"
                     },
                     {
-                        "id": "select_target_Hsc"
+                        "id": "select_target_Hsc",
+                        "value": "Hsc"
                     },
                     {
-                        "id": "select_target_B"
+                        "id": "select_target_B",
+                        "value": "B"
                     },
                     {
-                        "id": "select_target_P"
+                        "id": "select_target_P",
+                        "value": "P"
                     },
                     {
-                        "id": "select_target_S"
+                        "id": "select_target_S",
+                        "value": "S"
                     },
                     {
-                        "id": "select_target_R"
+                        "id": "select_target_R",
+                        "value": "R"
                     },
                     {
-                        "id": "select_target_V"
+                        "id": "select_target_V",
+                        "value": "V"
                     },
                     {
-                        "id": "select_target_Fr"
+                        "id": "select_target_Fr",
+                        "value": "Fr"
                     },
                     {
-                        "id": "select_target_Yf"
+                        "id": "select_target_Yf",
+                        "value": "Yf"
                     },
                     {
-                        "id": "select_target_Yt"
+                        "id": "select_target_Yt",
+                        "value": "Yt"
                     },
                     {
-                        "id": "select_target_Yco"
+                        "id": "select_target_Yco",
+                        "value": "Yco"
                     },
                     {
-                        "id": "select_target_J"
+                        "id": "select_target_J",
+                        "value": "J"
                     },
                     {
-                        "id": "select_target_I-J"
+                        "id": "select_target_I-J",
+                        "value": "I-J"
                     },
                     {
-                        "id": "select_target_Imp"
+                        "id": "select_target_Imp",
+                        "value": "Imp"
                     },
                     {
-                        "id": "select_target_Tau0"
+                        "id": "select_target_Tau0",
+                        "value": "Tau0"
                     }
                 ]
             }
@@ -253,6 +264,8 @@
     },
     {
         "type": "options",
-        "sectionSelectId": "select_section"
+        "sectionSourceId": "select_section",
+        "targetSelectId": "select_target",
+        "methodSelectId": "select_resolution"
     }
 ]
\ No newline at end of file
diff --git a/src/app/calculators/section-param/section-param.config.json b/src/app/calculators/section-param/section-param.config.json
index 77a0ca17e..88aac4d94 100644
--- a/src/app/calculators/section-param/section-param.config.json
+++ b/src/app/calculators/section-param/section-param.config.json
@@ -157,7 +157,6 @@
     {
         "id": "fs_computed_var",
         "type": "fieldset",
-        "defaultNodeType": "SectionTrapeze",
         "dep_exist": [
             {
                 "refid": "LargeurFond",
@@ -279,7 +278,7 @@
     },
     {
         "type": "options",
-        "sectionSourceId": "fs_section",
+        "sectionSourceId": "select_section",
         "targetSelectId": "select_target"
     }
 ]
\ No newline at end of file
diff --git a/src/app/formulaire/definition/concrete/form-cond-distri.ts b/src/app/formulaire/definition/concrete/form-cond-distri.ts
index 4a3438fdf..b79c5d50c 100644
--- a/src/app/formulaire/definition/concrete/form-cond-distri.ts
+++ b/src/app/formulaire/definition/concrete/form-cond-distri.ts
@@ -1,17 +1,17 @@
 import { FormDefFixedVar } from "../form-def-fixedvar";
 import { CalculatorType, ComputeNodeType } from "jalhyd";
 import { FormResultFixedVar } from "../form-result-fixedvar";
-import { FormComputeConduiteDistributrice } from "../form-compute-cond-distri";
 import { FormulaireDefinition } from "../form-definition";
 import { CalculatorResults } from "../../../results/calculator-results";
 import { FormDefParamToCalculate } from "../form-def-paramcalc";
+import { FormComputeFixedVar } from "../form-compute-fixedvar";
 
 export class FormulaireConduiteDistributrice extends FormulaireDefinition {
     private _formFixedVar: FormDefFixedVar;
 
     private _formParamCalc: FormDefParamToCalculate;
 
-    private _formCompute: FormComputeConduiteDistributrice;
+    private _formCompute: FormComputeFixedVar;
 
     private _formResult: FormResultFixedVar;
 
@@ -20,24 +20,22 @@ export class FormulaireConduiteDistributrice extends FormulaireDefinition {
         this._formFixedVar = new FormDefFixedVar(this);
         this._formParamCalc = new FormDefParamToCalculate(this);
         this._formResult = new FormResultFixedVar(this, false);
-        this._formCompute = new FormComputeConduiteDistributrice(this, this._formResult);
+        this._formCompute = new FormComputeFixedVar(this, this._formResult);
     }
 
     protected initParse() {
         this._formParamCalc.initParse();
     }
 
-    protected parseOptions(json: {}) {
+    protected completeParse(json: {}) {
         this._formParamCalc.parseOptions(json);
     }
 
-    protected completeParse() {
-    }
-
     /**
      * gestion du clic sur les radios "paramètre fixé, à varier, à calculer"
      */
     public onRadioClick(info: string) {
+        super.onRadioClick(info);
         this._formParamCalc.onRadioClick(info);
     }
 
diff --git a/src/app/formulaire/definition/concrete/form-courbe-remous.ts b/src/app/formulaire/definition/concrete/form-courbe-remous.ts
index c532c0685..0f60d8a59 100644
--- a/src/app/formulaire/definition/concrete/form-courbe-remous.ts
+++ b/src/app/formulaire/definition/concrete/form-courbe-remous.ts
@@ -1,10 +1,12 @@
-import { CalculatorType, ComputeNodeType } from "jalhyd";
+import { CalculatorType, ComputeNodeType, IObservable } from "jalhyd";
 
 import { FormResultRemous } from "../form-result-remous";
 import { FormDefSection } from "../form-def-section";
 import { FormComputeCourbeRemous } from "../form-compute-courbe-remous";
 import { FormulaireDefinition } from "../form-definition";
 import { CalculatorResults } from "../../../results/calculator-results";
+import { FieldSet } from "../../fieldset";
+import { SelectField } from "../../select-field";
 
 export class FormulaireCourbeRemous extends FormulaireDefinition {
     private _formSection: FormDefSection;
@@ -13,6 +15,11 @@ export class FormulaireCourbeRemous extends FormulaireDefinition {
 
     private _formResult: FormResultRemous;
 
+    /**
+     * id du select configurant la méthode de résolution
+     */
+    private _resolveMethSelectId: string;
+
     constructor() {
         super(CalculatorType.CourbeRemous)
         this._formSection = new FormDefSection(this);
@@ -20,16 +27,24 @@ export class FormulaireCourbeRemous extends FormulaireDefinition {
         this._formCompute = new FormComputeCourbeRemous(this, this._formSection, this._formResult);
     }
 
-    protected initParse() {
-        this._formSection.initParse();
-    }
-
     protected parseOptions(json: {}) {
         this._formSection.parseOptions(json);
+
+        // id du select configurant la méthode de résolution
+        this._resolveMethSelectId = this.getOption(json, "methodSelectId");
     }
 
-    protected completeParse() {
-        this._formSection.completeParse();
+    public afterParseFieldset(fs: FieldSet) {
+        this._formSection.afterParseFieldset(fs);
+
+        // si le FieldSet contient le select de méthode de résolution
+        if (this._resolveMethSelectId) {
+            const sel = fs.getFormulaireNodeById(this._resolveMethSelectId);
+            if (sel) {
+                // on abonne le formulaire aux propriétés du FieldSet
+                fs.properties.addObserver(this);
+            }
+        }
     }
 
     public resetResults() {
@@ -47,4 +62,24 @@ export class FormulaireCourbeRemous extends FormulaireDefinition {
     public get results(): CalculatorResults[] {
         return this._formResult.results;
     }
+
+    // interface Observer
+
+    update(sender: IObservable, data: any) {
+        if (sender instanceof FieldSet && data.action == "propertyChange") {
+            switch (sender.id) {
+                case "fs_section":
+                    this.replaceCurrentSessionNub(sender.properties);
+                    for (const fs of this.allFieldsets)
+                        fs.setSessionNub(this._currentSessionNub);
+                    this.reset();
+                    break;
+
+                case "fs_param_calc":
+                case "fs_target_data":
+                    this.reset();
+                    break;
+            }
+        }
+    }
 }
diff --git a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
index 3e2af2552..baf385278 100644
--- a/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
+++ b/src/app/formulaire/definition/concrete/form-lechapt-calmon.ts
@@ -2,18 +2,18 @@ import { CalculatorType, ComputeNodeType, Observer } from "jalhyd";
 
 import { FormResultFixedVar } from "../form-result-fixedvar";
 import { FormDefFixedVar } from "../form-def-fixedvar";
-import { FormComputeLechaptCalmon } from "../form-compute-lechapt-calmon";
 import { FormulaireDefinition } from "../form-definition";
 import { CalculatorResults } from "../../../results/calculator-results";
 import { FormDefParamToCalculate } from "../form-def-paramcalc";
 import { SelectField } from "../../select-field";
+import { FormComputeFixedVar } from "../form-compute-fixedvar";
 
 export class FormulaireLechaptCalmon extends FormulaireDefinition implements Observer {
     private _formFixedVar: FormDefFixedVar;
 
     private _formParamCalc: FormDefParamToCalculate;
 
-    private _formCompute: FormComputeLechaptCalmon;
+    private _formCompute: FormComputeFixedVar;
 
     private _formResult: FormResultFixedVar;
 
@@ -22,18 +22,15 @@ export class FormulaireLechaptCalmon extends FormulaireDefinition implements Obs
         this._formFixedVar = new FormDefFixedVar(this);
         this._formParamCalc = new FormDefParamToCalculate(this);
         this._formResult = new FormResultFixedVar(this, false);
-        this._formCompute = new FormComputeLechaptCalmon(this, this._formResult);
+        this._formCompute = new FormComputeFixedVar(this, this._formResult);
     }
 
     protected initParse() {
         this._formParamCalc.initParse();
     }
 
-    protected parseOptions(json: {}) {
+    protected completeParse(json: {}) {
         this._formParamCalc.parseOptions(json);
-    }
-
-    protected completeParse() {
         // abonnement au changement de valeur du select de matériau
         this.getFormulaireNodeById("select_material").addObserver(this);
     }
@@ -42,6 +39,7 @@ export class FormulaireLechaptCalmon extends FormulaireDefinition implements Obs
      * gestion du clic sur les radios "paramètre fixé, à varier, à calculer"    
      */
     public onRadioClick(info: string) {
+        super.onRadioClick(info);
         this._formParamCalc.onRadioClick(info);
     }
 
diff --git a/src/app/formulaire/definition/concrete/form-parallel-structures.ts b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
index 7882cce11..11e85caf9 100644
--- a/src/app/formulaire/definition/concrete/form-parallel-structures.ts
+++ b/src/app/formulaire/definition/concrete/form-parallel-structures.ts
@@ -14,6 +14,7 @@ import { FieldSet } from "../../fieldset";
 import { SelectField } from "../../select-field";
 import { NgParameter } from "../../ngparam";
 import { FieldsetTemplate } from "../../fieldset-template";
+import { FormulaireNode } from "../../formulaire-node";
 
 export class FormulaireParallelStructure extends FormulaireDefinition {
     private _formFixedVar: FormDefFixedVar;
@@ -26,6 +27,11 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
 
     private _formResult: FormResultFixedVar;
 
+    /**
+     * id du select configurant le type d'ouvrage
+     */
+    private __ouvrageSelectId: string;
+
     constructor() {
         super(CalculatorType.ParallelStructure)
         this._formFixedVar = new FormDefFixedVar(this);
@@ -46,7 +52,7 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
         return paramService.createSessionNub(params);
     }
 
-    public addStructureNub(st: Structure) {
+    private addStructureNub(st: Structure) {
         this.parallelStructureNub.addStructure(st);
     }
 
@@ -58,15 +64,42 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
         return this.getSessionNub(params).nub as ParallelStructure;
     }
 
+    public createFieldset(parent: FormulaireNode, json: {}, data?: {}): FieldSet {
+        if (json["calcType"] === "Structure") {
+            const res: FieldSet = new FieldSet(parent);
+            const sn = this.createStructNub(data["template"]);
+            this.addStructureNub(sn.nub as Structure);
+            res.setSessionNub(sn, false);
+            parent.kids.push(res);
+            return res;
+        }
+        else
+            return super.createFieldset(parent, json);
+    }
+
     protected initParse() {
         this._formParamCalc.initParse();
     }
 
     protected parseOptions(json: {}) {
-        this._formParamCalc.parseOptions(json);
+        // id du select configurant le type d'ouvrage
+        this.__ouvrageSelectId = this.getOption(json, "ouvrageSelectId");
     }
 
-    protected completeParse() {
+
+    public afterParseFieldset(fs: FieldSet) {
+        // si le FieldSet contient le select de type d'ouvrage
+        if (this.__ouvrageSelectId) {
+            const sel = fs.getFormulaireNodeById(this.__ouvrageSelectId);
+            if (sel) {
+                // on abonne le formulaire aux propriétés du FieldSet
+                fs.properties.addObserver(this);
+            }
+        }
+    }
+
+    protected completeParse(json: {}) {
+        this._formParamCalc.parseOptions(json);
         this.subscribeFieldsetContainer();
     }
 
@@ -74,6 +107,7 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
      * gestion du clic sur les radios "paramètre fixé, à varier, à calculer"    
      */
     public onRadioClick(info: string) {
+        super.onRadioClick(info);
         this._formParamCalc.onRadioClick(info);
     }
 
@@ -136,9 +170,15 @@ export class FormulaireParallelStructure extends FormulaireDefinition {
                     this.subscribeStructureInputFields(data["fieldset"]);
                     this.subscribeStructureSelectFields(data["fieldset"]);
             }
-        else if (sender instanceof SelectField) {
-            // la valeur d'un des select (type d'ouvrage, loi de débit) a changé
-            this.reset();
+        else if (sender instanceof FieldSet && data.action == "propertyChange") {
+            switch (sender.id) {
+                case "fs_ouvrage":
+                    // this.replaceCurrentSessionNub(sender.properties);
+                    const newNub = this.replaceSessionNub(sender.sessionNub, sender.properties);
+                    sender.setSessionNub(newNub);
+                    this.reset();
+                    break;
+            }
         }
     }
 }
diff --git a/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts b/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
index 2cadf2ae5..bc8d202d1 100644
--- a/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
+++ b/src/app/formulaire/definition/concrete/form-passe-bassin-dim.ts
@@ -4,15 +4,15 @@ import { CalculatorResults } from "../../../results/calculator-results";
 import { FormulaireDefinition } from "../form-definition";
 import { FormDefFixedVar } from "../form-def-fixedvar";
 import { FormDefParamToCalculate } from "../form-def-paramcalc";
-import { FormComputePasseBassinDimensions } from "../form-compute-pab-bassin-dim";
 import { FormResultFixedVar } from "../form-result-fixedvar";
+import { FormComputeFixedVar } from "../form-compute-fixedvar";
 
 export class FormulairePasseBassinDimensions extends FormulaireDefinition {
     private _formFixedVar: FormDefFixedVar;
 
     private _formParamCalc: FormDefParamToCalculate;
 
-    private _formCompute: FormComputePasseBassinDimensions;
+    private _formCompute: FormComputeFixedVar;
 
     private _formResult: FormResultFixedVar;
 
@@ -21,24 +21,22 @@ export class FormulairePasseBassinDimensions extends FormulaireDefinition {
         this._formFixedVar = new FormDefFixedVar(this);
         this._formParamCalc = new FormDefParamToCalculate(this);
         this._formResult = new FormResultFixedVar(this, false);
-        this._formCompute = new FormComputePasseBassinDimensions(this, this._formResult);
+        this._formCompute = new FormComputeFixedVar(this, this._formResult);
     }
 
     protected initParse() {
         this._formParamCalc.initParse();
     }
 
-    protected parseOptions(json: {}) {
+    protected completeParse(json: {}) {
         this._formParamCalc.parseOptions(json);
     }
 
-    protected completeParse() {
-    }
-
     /**
      * gestion du clic sur les radios "paramètre fixé, à varier, à calculer"    
      */
     public onRadioClick(info: string) {
+        super.onRadioClick(info);
         this._formParamCalc.onRadioClick(info);
     }
 
diff --git a/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts b/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
index 18bae07d6..02ed7376a 100644
--- a/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
+++ b/src/app/formulaire/definition/concrete/form-passe-bassin-puissance.ts
@@ -3,16 +3,16 @@ import { CalculatorType, ComputeNodeType } from "jalhyd";
 import { FormDefFixedVar } from "../form-def-fixedvar";
 import { FormResultFixedVar } from "../form-result-fixedvar";
 import { FormulaireDefinition } from "../form-definition";
-import { FormComputePasseBassinPuissance } from "../form-compute-pab-bassin-puissance";
 import { CalculatorResults } from "../../../results/calculator-results";
 import { FormDefParamToCalculate } from "../form-def-paramcalc";
+import { FormComputeFixedVar } from "../form-compute-fixedvar";
 
 export class FormulairePasseBassinPuissance extends FormulaireDefinition {
     private _formFixedVar: FormDefFixedVar;
 
     private _formParamCalc: FormDefParamToCalculate;
 
-    private _formCompute: FormComputePasseBassinPuissance;
+    private _formCompute: FormComputeFixedVar;
 
     private _formResult: FormResultFixedVar;
 
@@ -21,24 +21,22 @@ export class FormulairePasseBassinPuissance extends FormulaireDefinition {
         this._formFixedVar = new FormDefFixedVar(this);
         this._formParamCalc = new FormDefParamToCalculate(this);
         this._formResult = new FormResultFixedVar(this, false);
-        this._formCompute = new FormComputePasseBassinPuissance(this, this._formResult);
+        this._formCompute = new FormComputeFixedVar(this, this._formResult);
     }
 
     protected initParse() {
         this._formParamCalc.initParse();
     }
 
-    protected parseOptions(json: {}) {
+    protected completeParse(json: {}) {
         this._formParamCalc.parseOptions(json);
     }
 
-    protected completeParse() {
-    }
-
     /**
      * gestion du clic sur les radios "paramètre fixé, à varier, à calculer"    
      */
     public onRadioClick(info: string) {
+        super.onRadioClick(info);
         this._formParamCalc.onRadioClick(info);
     }
 
diff --git a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
index b433d5856..b4f322431 100644
--- a/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
+++ b/src/app/formulaire/definition/concrete/form-regime-uniforme.ts
@@ -1,20 +1,21 @@
 import { FormDefFixedVar } from "../form-def-fixedvar";
-import { CalculatorType, ComputeNodeType } from "jalhyd";
+import { CalculatorType, ComputeNodeType, IObservable, Observer } from "jalhyd";
 import { FormResultFixedVar } from "../form-result-fixedvar";
 import { FormulaireDefinition } from "../form-definition";
-import { FormComputeRegimeUniforme } from "../form-compute-regime-uniforme";
 import { FormDefSection } from "../form-def-section";
 import { CalculatorResults } from "../../../results/calculator-results";
 import { FormDefParamToCalculate } from "../form-def-paramcalc";
+import { FieldSet } from "../../fieldset";
+import { FormComputeFixedVar } from "../form-compute-fixedvar";
 
-export class FormulaireRegimeUniforme extends FormulaireDefinition {
+export class FormulaireRegimeUniforme extends FormulaireDefinition implements Observer {
     private _formFixedVar: FormDefFixedVar;
 
     private _formParamCalc: FormDefParamToCalculate;
 
     private _formSection: FormDefSection;
 
-    private _formCompute: FormComputeRegimeUniforme;
+    private _formCompute: FormComputeFixedVar;
 
     private _formResult: FormResultFixedVar;
 
@@ -24,27 +25,31 @@ export class FormulaireRegimeUniforme extends FormulaireDefinition {
         this._formParamCalc = new FormDefParamToCalculate(this);
         this._formSection = new FormDefSection(this);
         this._formResult = new FormResultFixedVar(this, true);
-        this._formCompute = new FormComputeRegimeUniforme(this, this._formSection, this._formResult);
+        this._formCompute = new FormComputeFixedVar(this, this._formResult);
     }
 
     protected initParse() {
-        this._formSection.initParse();
         this._formParamCalc.initParse();
     }
 
     protected parseOptions(json: {}) {
         this._formSection.parseOptions(json);
-        this._formParamCalc.parseOptions(json);
     }
 
-    protected completeParse() {
-        this._formSection.completeParse();
+    public afterParseFieldset(fs: FieldSet) {
+        this._formSection.afterParseFieldset(fs);
+    }
+
+    protected completeParse(json: {}) {
+        this._formParamCalc.parseOptions(json);
+        super.completeParse(json);
     }
 
     /**
      * gestion du clic sur les radios "paramètre fixé, à varier, à calculer"    
      */
     public onRadioClick(info: string) {
+        super.onRadioClick(info);
         this._formParamCalc.onRadioClick(info);
     }
 
@@ -63,4 +68,21 @@ export class FormulaireRegimeUniforme extends FormulaireDefinition {
     public get results(): CalculatorResults[] {
         return this._formResult.results;
     }
+
+    public reset() {
+        super.reset();
+        this._formParamCalc.parseOptions(this.jsonConfig);
+    }
+
+    // interface Observer
+
+    update(sender: IObservable, data: any) {
+        // changement de propriété du FieldSet contenant le select de choix du type de section
+        if (sender instanceof FieldSet && sender.id === "fs_section" && data.action == "propertyChange") {
+            this.replaceCurrentSessionNub(sender.properties);
+            for (const fs of this.allFieldsets)
+                fs.setSessionNub(this._currentSessionNub);
+            this.reset();
+        }
+    }
 }
diff --git a/src/app/formulaire/definition/concrete/form-section-parametree.ts b/src/app/formulaire/definition/concrete/form-section-parametree.ts
index 1801c14f2..63f636138 100644
--- a/src/app/formulaire/definition/concrete/form-section-parametree.ts
+++ b/src/app/formulaire/definition/concrete/form-section-parametree.ts
@@ -1,4 +1,4 @@
-import { CalculatorType, acSection, ParamsEquation, ComputeNodeType } from "jalhyd";
+import { CalculatorType, acSection, ParamsEquation, ComputeNodeType, IObservable } from "jalhyd";
 
 import { FormResultSection } from "../form-result-section";
 import { FormDefSection } from "../form-def-section";
@@ -9,6 +9,8 @@ import { FormulaireDefinition } from "../form-definition";
 import { InternationalisationService } from "../../../services/internationalisation/internationalisation.service";
 import { CalculatorResults } from "../../../results/calculator-results";
 import { FormDefFixedVar } from "../form-def-fixedvar";
+import { FieldSet } from "../../fieldset";
+import { SelectField } from "../../select-field";
 
 export class FormulaireSectionParametree extends FormulaireDefinition {
     private _formFixedVar: FormDefFixedVar;
@@ -27,22 +29,19 @@ export class FormulaireSectionParametree extends FormulaireDefinition {
         this._formCompute = new FormComputeSectionParametree(this, this._formSection, this._formSectionResult);
     }
 
-    protected initParse() {
-        this._formSection.initParse();
-    }
-
     protected parseOptions(json: {}) {
         this._formSection.parseOptions(json);
     }
 
-    protected completeParse() {
-        this._formSection.completeParse();
+    public afterParseFieldset(fs: FieldSet) {
+        this._formSection.afterParseFieldset(fs);
     }
 
     /**
      * gestion du clic sur les radios "paramètre fixé, à varier, à calculer"    
      */
     public onRadioClick(info: string) {
+        super.onRadioClick(info);
         this._formFixedVar.onRadioClick(info);
     }
 
@@ -61,4 +60,24 @@ export class FormulaireSectionParametree extends FormulaireDefinition {
     public get results(): CalculatorResults[] {
         return this._formSectionResult.results;
     }
+
+    // interface Observer
+
+    update(sender: IObservable, data: any) {
+        // changement de propriété du FieldSet contenant le select de choix du type de section
+        if (sender instanceof FieldSet && data.action == "propertyChange") {
+            switch (sender.id) {
+                case "fs_section":
+                    this.replaceCurrentSessionNub(sender.properties);
+                    for (const fs of this.allFieldsets)
+                        fs.setSessionNub(this._currentSessionNub);
+                    this.reset();
+                    break;
+
+                case "fs_computed_var":
+                    this.reset();
+                    break;
+            }
+        }
+    }
 }
diff --git a/src/app/formulaire/definition/form-compute-cond-distri.ts b/src/app/formulaire/definition/form-compute-cond-distri.ts
deleted file mode 100644
index 26ca00a13..000000000
--- a/src/app/formulaire/definition/form-compute-cond-distri.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { ComputeNode, ParamsEquation, ConduiteDistribParams, ConduiteDistrib, ComputeNodeType, CalculatorType } from "jalhyd";
-
-import { FormComputeFixedVar } from "./form-compute-fixedvar";
-import { FormulaireDefinition } from "./form-definition";
-import { FormResultFixedVar } from "./form-result-fixedvar";
-
-export class FormComputeConduiteDistributrice extends FormComputeFixedVar {
-    constructor(formBase: FormulaireDefinition, formResult: FormResultFixedVar) {
-        super(formBase, formResult);
-    }
-
-    protected getCurrentSessionNub() {
-        return this._formBase.getSessionNub({
-            "calcType": CalculatorType.ConduiteDistributrice,
-            "nodeType": ComputeNodeType.None
-        });
-    }
-}
diff --git a/src/app/formulaire/definition/form-compute-courbe-remous.ts b/src/app/formulaire/definition/form-compute-courbe-remous.ts
index 929cd0446..664a17cf4 100644
--- a/src/app/formulaire/definition/form-compute-courbe-remous.ts
+++ b/src/app/formulaire/definition/form-compute-courbe-remous.ts
@@ -12,20 +12,13 @@ export class FormComputeCourbeRemous extends FormCompute {
         super(formBase, formResult);
     }
 
-    protected getCurrentSessionNub() {
-        return this._formBase.getSessionNub({
-            "calcType": CalculatorType.SectionParametree,
-            "nodeType": this._formSection.sectionNodeType
-        });
-    }
-
     private get remousResults(): RemousResults {
         const f = this._formResult as FormResultRemous;
         return f.remousResults;
     }
 
     protected compute() {
-        const cr: CourbeRemous = this.getCurrentSessionNub().nub as CourbeRemous;
+        const cr: CourbeRemous = this._formBase.currentSessionNub.nub as CourbeRemous;
         const prmCR: CourbeRemousParams = cr.parameters as CourbeRemousParams;
         const sect: acSection = prmCR.Sn;
 
@@ -37,16 +30,7 @@ export class FormComputeCourbeRemous extends FormCompute {
         // méthode de résolution
 
         let msf: SelectField = <SelectField>this._formBase.getFormulaireNodeById("select_resolution");
-        let smeth: string = msf.getValue().value;
-        let methRes: MethodeResolution;
-        if (smeth == "select_resolution_trap")
-            methRes = MethodeResolution.Trapezes;
-        else if (smeth == "select_resolution_rk4")
-            methRes = MethodeResolution.RungeKutta4;
-        else if (smeth == "select_resolution_euler")
-            methRes = MethodeResolution.EulerExplicite;
-        else
-            throw "FormComputeCourbeRemous.compute() : type de méthode de résolution '" + smeth + "' inconnu";
+        let methRes: MethodeResolution = msf.getValue().value;
 
         // variable supplémentaire à calculer
 
@@ -54,13 +38,13 @@ export class FormComputeCourbeRemous extends FormCompute {
 
         // calcul
 
-        this.remousResults.result = cr.calculRemous(extraSymbol == "none" ? undefined : extraSymbol);
+        this.remousResults.result = cr.calculRemous(extraSymbol);
 
         // données du graphe
 
         this.remousResults.hauteurNormale = Yn.resultElement;
         this.remousResults.hauteurCritique = Yc.resultElement;
-        if (extraSymbol != "none") {
+        if (extraSymbol) {
             this.remousResults.extraParamLabel = this._formBase.getSelectedLabel("select_target");
             this.remousResults.extraGraph = ["Hs", "Hsc", "Yf", "Yt", "Yco"].indexOf(extraSymbol) == -1;
         }
diff --git a/src/app/formulaire/definition/form-compute-fixedvar.ts b/src/app/formulaire/definition/form-compute-fixedvar.ts
index 9214f357d..1955e9350 100644
--- a/src/app/formulaire/definition/form-compute-fixedvar.ts
+++ b/src/app/formulaire/definition/form-compute-fixedvar.ts
@@ -5,7 +5,7 @@ import { NgParameter, ParamRadioConfig } from "../ngparam";
 import { FormResultFixedVar } from "./form-result-fixedvar";
 import { FormulaireDefinition } from "./form-definition";
 
-export abstract class FormComputeFixedVar extends FormCompute {
+export class FormComputeFixedVar extends FormCompute {
     constructor(formBase: FormulaireDefinition, formResult: FormResultFixedVar) {
         super(formBase, formResult);
     }
@@ -33,7 +33,7 @@ export abstract class FormComputeFixedVar extends FormCompute {
     }
 
     protected compute() {
-        const nub: Nub = this.getCurrentSessionNub().nub;
+        const nub: Nub = this._formBase.currentSessionNub.nub;
 
         if (this._formBase.hasParameter("Pr"))
             var computePrec: number = this._formBase.getParameterValue("Pr"); // précision de calcul
diff --git a/src/app/formulaire/definition/form-compute-lechapt-calmon.ts b/src/app/formulaire/definition/form-compute-lechapt-calmon.ts
deleted file mode 100644
index 766c4f593..000000000
--- a/src/app/formulaire/definition/form-compute-lechapt-calmon.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { ComputeNode, ComputeNodeType, ParamsEquation, LechaptCalmonParams, LechaptCalmon, CalculatorType } from "jalhyd";
-
-import { FormComputeFixedVar } from "./form-compute-fixedvar";
-import { FormulaireDefinition } from "./form-definition";
-import { FormResultFixedVar } from "./form-result-fixedvar";
-
-export class FormComputeLechaptCalmon extends FormComputeFixedVar {
-    constructor(formBase: FormulaireDefinition, formResult: FormResultFixedVar) {
-        super(formBase, formResult);
-    }
-
-    protected getCurrentSessionNub() {
-        return this._formBase.getSessionNub({
-            "calcType": CalculatorType.LechaptCalmon,
-            "nodeType": ComputeNodeType.None
-        });
-    }
-}
diff --git a/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts b/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts
deleted file mode 100644
index cd984bfad..000000000
--- a/src/app/formulaire/definition/form-compute-pab-bassin-dim.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { ComputeNode, ParamsEquation, PabDimensionParams, PabDimension, ComputeNodeType, CalculatorType } from "jalhyd";
-
-import { FormComputeFixedVar } from "./form-compute-fixedvar";
-import { FormulaireDefinition } from "./form-definition";
-import { FormResultFixedVar } from "./form-result-fixedvar";
-
-export class FormComputePasseBassinDimensions extends FormComputeFixedVar {
-    constructor(formBase: FormulaireDefinition, formResult: FormResultFixedVar) {
-        super(formBase, formResult);
-    }
-
-    protected getCurrentSessionNub() {
-        return this._formBase.getSessionNub({
-            "calcType": CalculatorType.PabDimensions,
-            "nodeType": ComputeNodeType.None
-        });
-    }
-}
\ No newline at end of file
diff --git a/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts b/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts
deleted file mode 100644
index b5b961618..000000000
--- a/src/app/formulaire/definition/form-compute-pab-bassin-puissance.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { ComputeNode, ParamsEquation, PabPuissanceParams, PabPuissance, ComputeNodeType, CalculatorType } from "jalhyd";
-
-import { FormComputeFixedVar } from "./form-compute-fixedvar";
-import { FormulaireDefinition } from "./form-definition";
-import { FormResultFixedVar } from "./form-result-fixedvar";
-
-export class FormComputePasseBassinPuissance extends FormComputeFixedVar {
-    constructor(formBase: FormulaireDefinition, formResult: FormResultFixedVar) {
-        super(formBase, formResult);
-    }
-
-    protected getCurrentSessionNub() {
-        return this._formBase.getSessionNub({
-            "calcType": CalculatorType.PabPuissance,
-            "nodeType": ComputeNodeType.None
-        });
-    }
-}
\ No newline at end of file
diff --git a/src/app/formulaire/definition/form-compute-parallel-structures.ts b/src/app/formulaire/definition/form-compute-parallel-structures.ts
index 32f402446..aaba5b3c5 100644
--- a/src/app/formulaire/definition/form-compute-parallel-structures.ts
+++ b/src/app/formulaire/definition/form-compute-parallel-structures.ts
@@ -62,11 +62,4 @@ export class FormComputeParallelStructures extends FormComputeFixedVar {
             prm.v = val;
         }
     }
-
-    protected getCurrentSessionNub() {
-        return this._formBase.getSessionNub({
-            "calcType": CalculatorType.ParallelStructure,
-            "nodeType": ComputeNodeType.None
-        });
-    }
 }
diff --git a/src/app/formulaire/definition/form-compute-regime-uniforme.ts b/src/app/formulaire/definition/form-compute-regime-uniforme.ts
deleted file mode 100644
index cf2bdcf1b..000000000
--- a/src/app/formulaire/definition/form-compute-regime-uniforme.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { ComputeNode, ParamsEquation, RegimeUniforme, acSection, CalculatorType } from "jalhyd";
-
-import { FormComputeFixedVar } from "./form-compute-fixedvar";
-import { FormulaireDefinition } from "./form-definition";
-import { FormResultFixedVar } from "./form-result-fixedvar";
-import { FormDefSection } from "./form-def-section";
-
-export class FormComputeRegimeUniforme extends FormComputeFixedVar {
-    constructor(formBase: FormulaireDefinition, private _formSection: FormDefSection, formResult: FormResultFixedVar) {
-        super(formBase, formResult);
-    }
-
-    protected getCurrentSessionNub() {
-        return this._formBase.getSessionNub({
-            "calcType": CalculatorType.RegimeUniforme,
-            "nodeType": this._formSection.sectionNodeType
-        });
-    }
-}
diff --git a/src/app/formulaire/definition/form-compute-section-parametree.ts b/src/app/formulaire/definition/form-compute-section-parametree.ts
index c21c8330f..4578a4319 100644
--- a/src/app/formulaire/definition/form-compute-section-parametree.ts
+++ b/src/app/formulaire/definition/form-compute-section-parametree.ts
@@ -38,13 +38,6 @@ export class FormComputeSectionParametree extends FormCompute {
         return this._formSectionResult.sectionResults;
     }
 
-    protected getCurrentSessionNub(): SessionNub {
-        return this._formBase.getSessionNub({
-            "calcType": CalculatorType.SectionParametree,
-            "nodeType": this._formSection.sectionNodeType
-        });
-    }
-
     /**
      * calcul de la section paramétrée dans le cas d'un paramètre à varier
      * @param varParam paramètre à varier
@@ -58,7 +51,7 @@ export class FormComputeSectionParametree extends FormCompute {
         // paramètre à calculer en fonction du paramètre à varier
         let computedParamInfo = this._formSection.getSectionComputedParam();
 
-        const sectNub: SectionParametree = this.getCurrentSessionNub().nub as SectionParametree;
+        const sectNub: SectionParametree = this._formBase.currentSessionNub.nub as SectionParametree;
         const sect: acSection = sectNub.section;
         const prms = sectNub.parameters;
 
@@ -83,7 +76,7 @@ export class FormComputeSectionParametree extends FormCompute {
             return;
         }
 
-        const sectNub: SectionParametree = this.getCurrentSessionNub().nub as SectionParametree;
+        const sectNub: SectionParametree = this._formBase.currentSessionNub.nub as SectionParametree;
 
         const sect: acSection = sectNub.section;
         this._sectionResults.section = sect;
diff --git a/src/app/formulaire/definition/form-compute.ts b/src/app/formulaire/definition/form-compute.ts
index 8b7902787..400f511f1 100644
--- a/src/app/formulaire/definition/form-compute.ts
+++ b/src/app/formulaire/definition/form-compute.ts
@@ -8,8 +8,6 @@ export abstract class FormCompute {
     constructor(protected _formBase: FormulaireDefinition, protected _formResult: FormResult) {
     }
 
-    protected abstract getCurrentSessionNub(): SessionNub;
-
     protected abstract compute();
 
     protected get formResult(): FormResult {
diff --git a/src/app/formulaire/definition/form-def-fixedvar.ts b/src/app/formulaire/definition/form-def-fixedvar.ts
index 86ca4d19f..3c00d5657 100644
--- a/src/app/formulaire/definition/form-def-fixedvar.ts
+++ b/src/app/formulaire/definition/form-def-fixedvar.ts
@@ -79,8 +79,6 @@ export class FormDefFixedVar {
             if (newCal != undefined)
                 newCal.valueMode = ParamValueMode.CALCUL;
         }
-
-        this._formBase.reset();
     }
 
     /**
diff --git a/src/app/formulaire/definition/form-def-paramcalc.ts b/src/app/formulaire/definition/form-def-paramcalc.ts
index e5c3ecdb8..67bcd3939 100644
--- a/src/app/formulaire/definition/form-def-paramcalc.ts
+++ b/src/app/formulaire/definition/form-def-paramcalc.ts
@@ -3,6 +3,7 @@ import { ParamValueMode } from "jalhyd";
 import { ParamRadioConfig, NgParameter } from "../ngparam";
 import { FormulaireDefinition } from "./form-definition";
 import { FormDefFixedVar } from "./form-def-fixedvar";
+import { NgParamInputComponent } from "../../components/ngparam-input/ngparam-input.component";
 
 /** 
  * gestion des formulaires avec "paramètre à calculer" (conduite distributrice, Lechapt-Calmon, régime uniforme, passes à bassin)
@@ -22,22 +23,27 @@ export class FormDefParamToCalculate extends FormDefFixedVar {
     }
 
     public parseOptions(json: {}) {
-        // id du paramètre à calculer par défaut
+        for (const k in json) {
+            const o = json[k];
+            if (o.type === "options") {
+                // id du paramètre à calculer par défaut
 
-        this._defaultCalculatedParam = json["idCal"];
-        if (this._defaultCalculatedParam != undefined) {
-            let p = this._formBase.getParamFromSymbol(this._defaultCalculatedParam);
-            p.isDefault = true;
-            p.valueMode = ParamValueMode.CALCUL;
+                this._defaultCalculatedParam = o["idCal"];
+                if (this._defaultCalculatedParam != undefined) {
+                    const p = this.setDefault();
+                    p.isDefault = true;
+                }
+            }
         }
     }
 
     /**
      * met le paramètre par défaut à CAL
      */
-    private setDefault() {
-        let defaultParamCal = this._formBase.getParamFromSymbol(this._defaultCalculatedParam);
+    private setDefault(): NgParameter {
+        const defaultParamCal: NgParameter = this._formBase.getParamFromSymbol(this._defaultCalculatedParam);
         defaultParamCal.valueMode = ParamValueMode.CALCUL;
+        return defaultParamCal;
     }
 
     protected processRadioStateChange(sourceParam: NgParameter, oldState: ParamValueMode) {
diff --git a/src/app/formulaire/definition/form-def-section.ts b/src/app/formulaire/definition/form-def-section.ts
index 519e1f482..218747378 100644
--- a/src/app/formulaire/definition/form-def-section.ts
+++ b/src/app/formulaire/definition/form-def-section.ts
@@ -1,7 +1,6 @@
 import {
     ComputeNodeType, ParamsSectionTrapez, cSnTrapez, ParamsSectionRectang, cSnRectang,
-    ParamsSectionCirc, cSnCirc, ParamsSectionPuiss, cSnPuiss, acSection, ParamsEquation,
-    Observer
+    ParamsSectionCirc, cSnCirc, ParamsSectionPuiss, cSnPuiss, acSection, ParamsEquation
 } from "jalhyd";
 
 import { SelectField } from "../select-field";
@@ -10,7 +9,7 @@ import { NgParameter, ParamRadioConfig } from "../ngparam";
 import { FormulaireDefinition } from "./form-definition";
 import { FieldSet } from "../fieldset";
 
-export class FormDefSection implements Observer {
+export class FormDefSection {
     /**
      * id de l'élément configurant le type de section
      */
@@ -21,12 +20,6 @@ export class FormDefSection implements Observer {
      */
     private _targetSelectId: string;
 
-    /**
-     * Type de noeud de calcul actuel de la section (si la calculette est basée sur une section et qu'un menu permet 
-     * de sélectionner le type de section)
-     */
-    private _sectionNodeType: ComputeNodeType = undefined;
-
     private _formBase: FormulaireDefinition;
 
     constructor(base: FormulaireDefinition) {
@@ -37,18 +30,6 @@ export class FormDefSection implements Observer {
         return this._sectionSourceId != undefined;
     }
 
-    public get sectionNodeType(): ComputeNodeType {
-        return this._sectionNodeType;
-    }
-
-    private updateSectionNodeType() {
-        const nt = this.getNodeTypeFromSourceElement();
-        if (this._sectionNodeType !== nt) {
-            this._sectionNodeType = nt;
-            this._formBase.reset();
-        }
-    }
-
     public getSectionVariatedParameter(): NgParameter {
         return this._formBase.getDisplayedParamFromState(ParamRadioConfig.VAR);
     }
@@ -59,27 +40,6 @@ export class FormDefSection implements Observer {
         return { symbol, label };
     }
 
-    /**
-     * @return l'élément déterminant le type de section
-     */
-    private getSectionSourceElement(): FieldSet {
-        const fs = this._formBase.getFormulaireNodeById(this._sectionSourceId);
-        if (fs === undefined || !(fs instanceof FieldSet))
-            throw new Error(`le champ ${this._sectionSourceId} n'est pas du type FieldSet`);
-        return fs;
-    }
-
-    /**
-     * @return le type de section déterminé par l'élément source
-     */
-    private getNodeTypeFromSourceElement(): ComputeNodeType {
-        const fs: FieldSet = this.getSectionSourceElement();
-        return fs.getPropValue("nodeType");
-    }
-
-    public initParse() {
-    }
-
     public parseOptions(json: {}) {
         // id de l'élément configurant le type de section
         this._sectionSourceId = this._formBase.getOption(json, "sectionSourceId");
@@ -88,28 +48,27 @@ export class FormDefSection implements Observer {
         this._targetSelectId = this._formBase.getOption(json, "targetSelectId");
     }
 
-    public completeParse() {
-        // si le formulaire a un menu pour le type de section, on s'abonne à la valeur du champ correspondant
-        if (this.hasSectionNodeTypeSource) {
-            const se = this.getSectionSourceElement();
-            se.addObserver(this);
-            this.updateSectionNodeType()
-        }
-        if (this._targetSelectId) {
-            const sel = this._formBase.getFormulaireNodeById(this._targetSelectId);
-            sel.addObserver(this);
+    /**
+     * appelé après la création d'un FieldSet
+     * @param fs nouveau FieldSet
+     */
+    public afterParseFieldset(fs: FieldSet) {
+        if (this.hasSectionNodeTypeSource) { // s'il existe un menu de choix de section dans la calculette
+            const sel = fs.getFormulaireNodeById(this._sectionSourceId);
+            if (sel)  // si le FieldSet contient le select de changement de type de section
+            {
+                // on abonne le formulaire aux propriétés du FieldSet pour MAJ du nub, reset du formulaire, ...
+                fs.properties.addObserver(this._formBase);
+            }
         }
-    }
 
-    // interface Observer 
-
-    update(sender: any, data: any): void {
-        if (data.action == "propertyChange") {
-            this.updateSectionNodeType();
+        // si le formulaire contient le select de la variable à calculer
+        if (this._targetSelectId) {
+            const sel = fs.getFormulaireNodeById(this._targetSelectId);
+            if (sel) {
+                // on abonne le formulaire aux propriétés du FieldSet
+                fs.properties.addObserver(this._formBase);
+            }
         }
-
-        // RAZ formulaire quand on change la variable à calculer
-        if (sender instanceof SelectField)
-            this._formBase.reset();
     }
 }
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index 9450cf2cc..f6e05c3a8 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -1,4 +1,4 @@
-import { CalculatorType, ComputeNodeType, Nub, ParamDefinition, SessionNub, Props } from "jalhyd";
+import { CalculatorType, ComputeNodeType, Nub, ParamDefinition, SessionNub, Props, NubFactory, Observer } from "jalhyd";
 
 import { FormulaireElement } from "../formulaire-element";
 import { NgParameter, ParamRadioConfig } from "../ngparam";
@@ -19,7 +19,7 @@ import { FieldsetTemplate } from "../fieldset-template";
 /**
  * classe de base pour tous les formulaires
  */
-export abstract class FormulaireDefinition extends FormulaireNode {
+export abstract class FormulaireDefinition extends FormulaireNode implements Observer {
     /**
      * type de calculette
      */
@@ -30,12 +30,23 @@ export abstract class FormulaireDefinition extends FormulaireNode {
      */
     private _calculatorName: string;
 
+    /**
+     * SessionNub courant
+     */
+    protected _currentSessionNub: SessionNub;
+
+    /**
+     * fichier de configuration
+     */
+    private _jsonConfig: {};
+
     protected _paramService: ParamService;
 
     constructor(calcType: CalculatorType) {
         super(undefined);
         this._calcType = calcType;
         this._paramService = ServiceFactory.instance.paramService;
+        this.initSessionNub();
     }
 
     public get calculatorType(): CalculatorType {
@@ -50,11 +61,23 @@ export abstract class FormulaireDefinition extends FormulaireNode {
         this._calculatorName = name;
     }
 
-    private findNub(params: Props | {}) {
+    public get jsonConfig(): {} {
+        return this._jsonConfig;
+    }
+
+    protected initSessionNub() {
+        this._currentSessionNub = this.createSessionNub({ "calcType": this._calcType, "nodeType": ComputeNodeType.None });
+    }
+
+    public get currentSessionNub(): SessionNub {
+        return this._currentSessionNub;
+    }
+
+    protected findNub(params: Props | {}) {
         return this._paramService.findSessionNub(params);
     }
 
-    public createSessionNub(params: Props | {}): SessionNub {
+    protected createSessionNub(params: Props | {}): SessionNub {
         return this._paramService.createSessionNub(params);
     }
 
@@ -62,14 +85,18 @@ export abstract class FormulaireDefinition extends FormulaireNode {
      * @return le Nub associé à un type de noeud donné, le crée si nécessaire
      * @param params paramètres de contexte de création du nub
      */
-    public getSessionNub(params: Props | {}): SessionNub {
+    protected getSessionNub(params: Props | {}): SessionNub {
         let res = this.findNub(params);
         if (!res)
             res = this.createSessionNub(params);
         return res;
     }
 
-    public replaceSessionNub(sn: SessionNub, params: Props) {
+    protected replaceCurrentSessionNub(params: Props) {
+        this._currentSessionNub = this._paramService.replaceSessionNub(this._currentSessionNub, params);
+    }
+
+    protected replaceSessionNub(sn: SessionNub, params: Props): SessionNub {
         return this._paramService.replaceSessionNub(sn, params);
     }
 
@@ -78,7 +105,7 @@ export abstract class FormulaireDefinition extends FormulaireNode {
      * @param symbol symbole du paramètre
      * @param params paramètres de contexte de création du nub
      */
-    public getNubParamFromSymbol(symbol: string, params: Props | {}): ParamDefinition {
+    protected getNubParamFromSymbol(symbol: string, params: Props | {}): ParamDefinition {
         let sessionNub: SessionNub = this.getSessionNub(params);
 
         if (sessionNub)
@@ -87,9 +114,14 @@ export abstract class FormulaireDefinition extends FormulaireNode {
         throw new Error(`FormulaireDefinition.getNubParamFromSymbol() : pas de Nub trouvé pour ${params}`)
     }
 
-    protected abstract initParse();
-    protected abstract parseOptions(json: {});
-    protected abstract completeParse();
+    protected initParse() {
+    }
+
+    protected parseOptions(json: {}) {
+    }
+
+    protected completeParse(json: {}) {
+    }
 
     public getOption(json: {}, option: string): string {
         if (json["type"] === "options")
@@ -98,10 +130,20 @@ export abstract class FormulaireDefinition extends FormulaireNode {
         return undefined;
     }
 
+    public afterParseFieldset(fs: FieldSet) {
+    }
+
+    public createFieldset(parent: FormulaireNode, json: {}, data?: {}): FieldSet {
+        const res: FieldSet = new FieldSet(parent);
+        res.setSessionNub(this._currentSessionNub, false);
+        this.kids.push(res);
+        return res;
+    }
+
     private parse_fieldset(json: {}) {
-        const fs: FieldSet = new FieldSet(this);
-        this.kids.push(fs);
+        const fs = this.createFieldset(this, json);
         fs.parseConfig(json, { "parentForm": this });
+        this.afterParseFieldset(fs);
     }
 
     private parse_template_container(json: {}, templates: any[]) {
@@ -136,8 +178,25 @@ export abstract class FormulaireDefinition extends FormulaireNode {
     }
 
     public parseConfig(json: {}) {
+        this._jsonConfig = json;
+
         this.initParse();
 
+        // analyse des options globales
+        // il est utile de le faire avant le reste pour les calculettes utilisant des sections (id des selects type de section/variable à calculer)
+
+        for (let conf_index in json) {
+            const conf = json[conf_index];
+            const type: string = conf["type"];
+
+            if (type === "options") {
+                this.parseOptions(conf);
+                break;
+            }
+        }
+
+        // analyse des éléments du formulaire
+
         const templates: any[] = [];
 
         for (let conf_index in json) {
@@ -155,7 +214,6 @@ export abstract class FormulaireDefinition extends FormulaireNode {
 
                 // options globales
                 case "options":
-                    this.parseOptions(conf);
                     break;
 
                 case "template_container":
@@ -167,7 +225,15 @@ export abstract class FormulaireDefinition extends FormulaireNode {
             }
         }
 
-        this.completeParse();
+        this.completeParse(json);
+
+        // console.log("-----");
+
+        // for (const n of NubFactory.getInstance().sessionNubIterator) {
+        //     console.log(n.nub);
+        //     for (const p of n.nub.parameterIterator)
+        //         console.log(`${p.symbol} uid  ${p.uid} props ${n.properties} mode ${p.valueMode} val ${p.uncheckedValue}`);
+        // }
 
         // logObject(this._fieldSets, "fieldsets");
         // logObject(this._dependencies, "dependences");
@@ -310,6 +376,7 @@ export abstract class FormulaireDefinition extends FormulaireNode {
      * gestion d'un clic sur les radios
      */
     public onRadioClick(info: any) {
+        this.reset();
     }
 
     /**
@@ -333,12 +400,8 @@ export abstract class FormulaireDefinition extends FormulaireNode {
         return new TopFormulaireElementIterator(this);
     }
 
-    // interface Observer
+    //  interface Observer
 
-    // update(sender: IObservable, data: any) {
-    // switch (data["action"]) {
-    //     case "resetForm":  // événement demandant une réinitialisation du formulaire (changement d'un SelectField, ...)
-    //         this.onReset();
-    // }
-    // }
+    public update(sender: any, data: any) {
+    }
 }
diff --git a/src/app/formulaire/fieldset-container.ts b/src/app/formulaire/fieldset-container.ts
index 4287dcb02..67af3f159 100644
--- a/src/app/formulaire/fieldset-container.ts
+++ b/src/app/formulaire/fieldset-container.ts
@@ -36,10 +36,6 @@ export class FieldsetContainer extends FormulaireElement {
         const templ: FieldsetTemplate = this._templates[index];
 
         const inst: FieldSet = templ.instantiateTemplate(this);
-        if (inst.sessionNub.nub instanceof Structure) {
-            const psf = this.parent as FormulaireParallelStructure;
-            psf.addStructureNub(inst.sessionNub.nub as Structure);
-        }
 
         this.updateLocalisation();
 
diff --git a/src/app/formulaire/fieldset-template.ts b/src/app/formulaire/fieldset-template.ts
index bc3102616..c21455761 100644
--- a/src/app/formulaire/fieldset-template.ts
+++ b/src/app/formulaire/fieldset-template.ts
@@ -39,9 +39,10 @@ export class FieldsetTemplate {
     }
 
     public instantiateTemplate(cont: FieldsetContainer): FieldSet {
-        const res = new FieldSet(cont);
-        cont.addFieldset(res);
-        res.parseConfig(this._jsonConfig, { "parentForm": cont.parent, "createNub": true });
+        const parentForm = cont.parent as FormulaireDefinition;
+        const res = parentForm.createFieldset(cont, this._jsonConfig, { "template": this });
+        res.parseConfig(this._jsonConfig, { "parentForm": parentForm });
+        parentForm.afterParseFieldset(res);
         return res;
     }
 }
diff --git a/src/app/formulaire/fieldset.ts b/src/app/formulaire/fieldset.ts
index 76a23bd47..434cf1115 100644
--- a/src/app/formulaire/fieldset.ts
+++ b/src/app/formulaire/fieldset.ts
@@ -49,6 +49,12 @@ export class FieldSet extends FormulaireElement implements Observer {
         return this._sessionNub;
     }
 
+    public setSessionNub(sn: SessionNub, update: boolean = true) {
+        this._sessionNub = sn;
+        if (update)
+            this.updateFields();
+    }
+
     private addField(f: Field) {
         if (f == undefined)
             throw new Error("FieldSet.addField() : argument incorrect (undefined)");
@@ -97,24 +103,16 @@ export class FieldSet extends FormulaireElement implements Observer {
         return res;
     }
 
-    public getPropValue(key: string): any {
-        return this._props.getPropValue(key);
+    public get properties(): Props {
+        return this._props;
     }
 
-    private notifyPropChange(prop: string, val: any) {
-        this.notifyObservers({
-            "action": "propertyChange",
-            "name": prop,
-            "value": val
-        }, this)
+    public getPropValue(key: string): any {
+        return this._props.getPropValue(key);
     }
 
-    public setPropValue(key: string, val: any): boolean {
-        const changed = this._props.getPropValue(key) !== val;
-        if (changed) {
-            this._props.setPropValue(key, val);
-            this.notifyPropChange(key, val);
-
+    public setPropValue(key: string, val: any) {
+        if (this._props.setPropValue(key, val, this)) {
             // si prop=type d'ouvrage, on prend une loi de débit compatible avec (spécifique aux ouvrages //) comme valeur par défaut
             if (key === "structureType") {
                 if (!StructureProperties.isCompatibleValues(val, this.getPropValue("loiDebit")))
@@ -125,7 +123,6 @@ export class FieldSet extends FormulaireElement implements Observer {
                 if (!StructureProperties.isCompatibleValues(this.getPropValue("structureType"), val))
                     this.setPropValue("structureType", StructureProperties.findCompatibleStructure(val));
         }
-        return changed;
     }
 
     /**
@@ -162,10 +159,7 @@ export class FieldSet extends FormulaireElement implements Observer {
     }
 
     private getNubParamFromSymbol(symbol: string): ParamDefinition {
-        if (this._sessionNub)
-            return this._sessionNub.nub.getParameter(symbol);
-
-        return this._parentForm.getNubParamFromSymbol(symbol, this._props);
+        return this._sessionNub.nub.getParameter(symbol);
     }
 
     /**
@@ -233,21 +227,6 @@ export class FieldSet extends FormulaireElement implements Observer {
         this.clearKids();
     }
 
-    /**
-     * met à jour le SessionNubnub associé
-     * @param createOrUpdate true pour forcer la création d'un SessionNub
-     */
-    private updateNub(createOrUpdate: boolean) {
-        if (this._sessionNub)
-            this._sessionNub = this._parentForm.replaceSessionNub(this._sessionNub, this._props);
-        else {
-            if (createOrUpdate)
-                this._sessionNub = this._parentForm.createSessionNub(this._props);
-            else
-                this._sessionNub = this._parentForm.getSessionNub(this._props);
-        }
-    }
-
     public updateLocalisation(loc?: StringMap) {
         if (loc == undefined)
             loc = this._localisation;
@@ -261,9 +240,8 @@ export class FieldSet extends FormulaireElement implements Observer {
     /**
      * @param createOrUpdate true pour forcer la création d'un SessionNub
      */
-    private updateFields(createOrUpdate: boolean = false) {
+    private updateFields() {
         this.clearFields();
-        this.updateNub(createOrUpdate);
         this.parseFields();
         this.parseDependencies(this._jsonConfig);
         this.updateLocalisation();
@@ -307,8 +285,6 @@ export class FieldSet extends FormulaireElement implements Observer {
     public parseConfig(json: {}, data?: {}) {
         this._jsonConfig = json;
         this._parentForm = data["parentForm"];
-        const cn = data["createNub"]; // flag pour forcer la création d'un SessionNub (true pour création/false pour MAJ, false par défaut )
-        const createOrUpdate = cn ? cn : false;
 
         this._confId = json["id"];
 
@@ -336,7 +312,7 @@ export class FieldSet extends FormulaireElement implements Observer {
         if (ld)
             this.setPropValue("loiDebit", LoiDebit[ld])
 
-        this.updateFields(createOrUpdate);
+        this.updateFields();
     }
 
     public parseDependencies(json: {}) {
@@ -404,21 +380,22 @@ export class FieldSet extends FormulaireElement implements Observer {
     // interface Observer
 
     update(sender: any, data: any) {
-        if (data.action && data.action === "select") {
-            let update = false;
-            if (data.value.id.indexOf("select_section_") != -1)  // sections paramétrées
-                update = update || this.setPropValue("nodeType", data.value.value);
-            if (data.value.id.indexOf("select_ouvrage") != -1) // ouvrages parallèles
-                update = update || this.setPropValue("structureType", data.value.value);
-            else if (data.value.id.indexOf("select_loidebit1") != -1) // ouvrages parallèles
-                update = update || this.setPropValue("loiDebit", data.value.value);
-            else if (data.value.id.indexOf("select_loidebit2") != -1) // ouvrages parallèles
-                update = update || this.setPropValue("loiDebit", data.value.value);
-
-            if (update) {
-                this.updateFields();
-                this._parentForm.reset();
+        if (data.action)
+            switch (data.action) {
+                case "select":
+                    if (data.value.id.indexOf("select_section_") != -1)  // sections paramétrées
+                        this.setPropValue("nodeType", data.value.value);
+                    if (data.value.id.indexOf("select_ouvrage") != -1) // ouvrages parallèles
+                        this.setPropValue("structureType", data.value.value);
+                    else if (data.value.id.indexOf("select_loidebit1") != -1) // ouvrages parallèles
+                        this.setPropValue("loiDebit", data.value.value);
+                    else if (data.value.id.indexOf("select_loidebit2") != -1) // ouvrages parallèles
+                        this.setPropValue("loiDebit", data.value.value);
+                    else if (data.value.id.indexOf("select_resolution") != -1) // courbes de remous, méthode de résolution
+                        this.setPropValue("methodeResolution", data.value.value);
+                    else if (data.value.id.indexOf("select_target") != -1) // courbes de remous, variable à calculer
+                        this.setPropValue("varCalc", data.value.value);
+                    break;
             }
-        }
     }
 }
diff --git a/src/app/formulaire/select-field.ts b/src/app/formulaire/select-field.ts
index f6e4bfb7d..d6366564c 100644
--- a/src/app/formulaire/select-field.ts
+++ b/src/app/formulaire/select-field.ts
@@ -1,4 +1,4 @@
-import { StructureType, LoiDebit, ComputeNodeType } from "jalhyd";
+import { StructureType, LoiDebit, ComputeNodeType, MethodeResolution } from "jalhyd";
 
 import { Field } from "./field";
 import { SelectEntry } from "./select-entry";
@@ -100,6 +100,13 @@ export class SelectField extends Field {
                     case "LoiDebit":
                         val = LoiDebit[tmp[1]];
                         break;
+
+                    case "MethodeResolution":
+                        val = MethodeResolution[tmp[1]];
+                        break;
+
+                    default:
+                        throw new Error(`type d'enum ${tmp[0]} non pris en charge`);
                 }
             }
             else if (v.value)
diff --git a/src/app/results/remous-results.ts b/src/app/results/remous-results.ts
index c450fe10b..c41b8f7aa 100644
--- a/src/app/results/remous-results.ts
+++ b/src/app/results/remous-results.ts
@@ -63,6 +63,7 @@ export class RemousResults extends CalculatorResults {
     }
 
     public reset() {
+        this._result = undefined;
         this._log = new cLog();
         this._hautBerge = undefined;
         this._penteFond = undefined;
@@ -73,6 +74,7 @@ export class RemousResults extends CalculatorResults {
         this._hasTor = false;
         this._hasExtra = false;
         this._extraGraph = false;
+        this._extraParamLabel = undefined;
     }
 
     public set parameters(p: CourbeRemousParams) {
-- 
GitLab


From 36a152fcb40401dccbd15a007a8b35359eac4e54 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Tue, 24 Apr 2018 15:55:23 +0200
Subject: [PATCH 50/53] =?UTF-8?q?=20#77=20VerticalResultElementComponent?=
 =?UTF-8?q?=20:=20correction=20d'un=20pb=20d'affichage=20(r=C3=A9sultats?=
 =?UTF-8?q?=20non=20align=C3=A9s=20correctement,=20pas=20en=20gras)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../result-element/vertical-result-element.component.html | 6 +++---
 .../result-element/vertical-result-element.component.ts   | 8 ++++----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/app/components/result-element/vertical-result-element.component.html b/src/app/components/result-element/vertical-result-element.component.html
index ec10e0b13..d71f374c6 100644
--- a/src/app/components/result-element/vertical-result-element.component.html
+++ b/src/app/components/result-element/vertical-result-element.component.html
@@ -3,11 +3,11 @@
     <div [innerHtml]="htmlTooltip"></div>
 </ng-template>
 
-<td *ngIf="hasValue" class="bold_right">
+<td *ngIf="hasValue" class="label2">
     {{resultLabel}}
 </td>
 
-<td *ngIf="hasValue||hasError" [mdbTooltip]="popTemplate" [isDisabled]="tooltipDisabled" class="bold_center">
+<td *ngIf="hasValue||hasError" [mdbTooltip]="popTemplate" [isDisabled]="tooltipDisabled" class="value2">
     <!-- icône en cas d'erreur -->
     <i *ngIf="hasError" class="fa fa-exclamation-triangle" style="color:red" aria-hidden="true"></i>
 
@@ -28,4 +28,4 @@
             {{r.value}}
         </td>
     </tr>
-</ng-template>
+</ng-template>
\ No newline at end of file
diff --git a/src/app/components/result-element/vertical-result-element.component.ts b/src/app/components/result-element/vertical-result-element.component.ts
index 4aecd4942..5028e6788 100644
--- a/src/app/components/result-element/vertical-result-element.component.ts
+++ b/src/app/components/result-element/vertical-result-element.component.ts
@@ -12,16 +12,16 @@ import { ResultElementBaseComponent } from "./result-element-base.component";
     templateUrl: "./vertical-result-element.component.html",
     styles: [
         `.label1 {
-            text-align: right; background-color: #f0f0f0
+            text-align: right; background-color: #f0f0f0; font-weight: bold
         }`,
         `.value1 {
-            text-align: center; background-color: #f0f0f0
+            text-align: center; background-color: #f0f0f0; font-weight: bold
         }`,
         `.label2 {
-            text-align: right; background-color: #ffffff
+            text-align: right; background-color: #ffffff; font-weight: bold
         }`,
         `.value2 {
-            text-align: center; background-color: #ffffff
+            text-align: center; background-color: #ffffff; font-weight: bold
         }`
     ]
 })
-- 
GitLab


From bf604c8eb15757c459fc7ad6c3cffe031f4c504a Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Tue, 24 Apr 2018 16:21:17 +0200
Subject: [PATCH 51/53] =?UTF-8?q?=20#77=20correction=20bug=20d'affichage?=
 =?UTF-8?q?=20(r=C3=A9sultats=20affich=C3=A9s=20sous=20les=20champs=20du?=
 =?UTF-8?q?=20formulaire=20au=20lieu=20de=20=C3=A0=20droite=20en=20=C3=A9c?=
 =?UTF-8?q?ran=20large)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/formulaire/definition/form-result-fixedvar.ts | 2 +-
 src/app/formulaire/definition/form-result-section.ts  | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/app/formulaire/definition/form-result-fixedvar.ts b/src/app/formulaire/definition/form-result-fixedvar.ts
index 316d8d7b9..0dacc750a 100644
--- a/src/app/formulaire/definition/form-result-fixedvar.ts
+++ b/src/app/formulaire/definition/form-result-fixedvar.ts
@@ -51,7 +51,7 @@ export class FormResultFixedVar extends FormResult {
     }
 
     public get hasResults(): boolean {
-        return this._fixedResults.hasResults;
+        return this._fixedResults.hasResults || this._varResults.hasResults;
     }
 
     public get results(): CalculatorResults[] {
diff --git a/src/app/formulaire/definition/form-result-section.ts b/src/app/formulaire/definition/form-result-section.ts
index 14f07562c..d023a8ee2 100644
--- a/src/app/formulaire/definition/form-result-section.ts
+++ b/src/app/formulaire/definition/form-result-section.ts
@@ -59,6 +59,7 @@ export class FormResultSection extends FormResult {
 
     public get hasResults(): boolean {
         return (this._fixedResults != undefined && this._fixedResults.hasResults)
+            || (this._varResults != undefined && this._varResults.hasResults)
             || (this._sectionResults != undefined && this._sectionResults.hasResults);
     }
 
-- 
GitLab


From af144b01d2f744e940193e1536694b51d0e61d67 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Wed, 25 Apr 2018 10:20:01 +0200
Subject: [PATCH 52/53] =?UTF-8?q?=20#77=20correction=20des=20unit=C3=A9s?=
 =?UTF-8?q?=20pour=20la=20charge=20sp=C3=A9cifique,=20critique,=20etc...?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/app/calculators/remous/remous.fr.json |  4 +--
 src/locale/error_messages.en.json         | 32 +++++++++++------------
 src/locale/error_messages.fr.json         | 32 +++++++++++------------
 3 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/src/app/calculators/remous/remous.fr.json b/src/app/calculators/remous/remous.fr.json
index 5ba79bc63..b3086abb4 100644
--- a/src/app/calculators/remous/remous.fr.json
+++ b/src/app/calculators/remous/remous.fr.json
@@ -48,6 +48,6 @@
     "select_target_Yco": "Le tirant d'eau conjugué (m)",
     "select_target_J": "La perte de charge (m)",
     "select_target_I-J": "Variation linéaire de l'énergie spécifique (m/m)",
-    "select_target_Imp": "Impulsion (m/m)",
-    "select_target_Tau0": "La force tractrice (N)"
+    "select_target_Imp": "Impulsion (N)",
+    "select_target_Tau0": "La force tractrice (Pa)"
 }
\ No newline at end of file
diff --git a/src/locale/error_messages.en.json b/src/locale/error_messages.en.json
index 86f94a508..91b814d14 100644
--- a/src/locale/error_messages.en.json
+++ b/src/locale/error_messages.en.json
@@ -43,23 +43,23 @@
     "INFO_LECHAPT_TITRE": "Lechapt-Calmon",
     "INFO_REGUNI_TITRE": "Uniform flow calculation",
     "INFO_SECTPARAM_TITRE": "Parametric section",
-    "INFO_GRANDEUR_HS": "Specific head",
-    "INFO_GRANDEUR_HSC": "Critical head",
-    "INFO_GRANDEUR_B": "Surface width",
-    "INFO_GRANDEUR_P": "Wetted perimeter",
-    "INFO_GRANDEUR_S": "Wetted area",
-    "INFO_GRANDEUR_R": "Hydraulic radius",
-    "INFO_GRANDEUR_V": "Average speed",
+    "INFO_GRANDEUR_HS": "Specific head (m)",
+    "INFO_GRANDEUR_HSC": "Critical head (m)",
+    "INFO_GRANDEUR_B": "Surface width (m)",
+    "INFO_GRANDEUR_P": "Wetted perimeter (m)",
+    "INFO_GRANDEUR_S": "Wetted area (m2)",
+    "INFO_GRANDEUR_R": "Hydraulic radius (m)",
+    "INFO_GRANDEUR_V": "Average speed (m/s)",
     "INFO_GRANDEUR_FR": "Froude number",
-    "INFO_GRANDEUR_YC": "Critical depth",
-    "INFO_GRANDEUR_YN": "Normal depth",
-    "INFO_GRANDEUR_YF": "Subcritical depth",
-    "INFO_GRANDEUR_YT": "Supercritical depth",
-    "INFO_GRANDEUR_YCO": "Conjugate depth",
-    "INFO_GRANDEUR_J": "Head loss",
-    "INFO_GRANDEUR_I-J": "Linear variation of specific head",
-    "INFO_GRANDEUR_IMP": "Impulse",
-    "INFO_GRANDEUR_TAU0": "Tractive force",
+    "INFO_GRANDEUR_YC": "Critical depth (m)",
+    "INFO_GRANDEUR_YN": "Normal depth (m)",
+    "INFO_GRANDEUR_YF": "Subcritical depth (m)",
+    "INFO_GRANDEUR_YT": "Supercritical depth (m)",
+    "INFO_GRANDEUR_YCO": "Conjugate depth (m)",
+    "INFO_GRANDEUR_J": "Head loss (m)",
+    "INFO_GRANDEUR_I-J": "Linear variation of specific head (m/m)",
+    "INFO_GRANDEUR_IMP": "Impulse (N)",
+    "INFO_GRANDEUR_TAU0": "Tractive force (Pa)",
     "INFO_REMOUS_TITRE": "Backwater curves",
     "INFO_REMOUSRESULTS_TITREJOURNAL": "Calculation log",
     "INFO_REMOUSRESULTS_LIGNEFLUVIALE": "Subcritical water profile",
diff --git a/src/locale/error_messages.fr.json b/src/locale/error_messages.fr.json
index f336ee9cf..cafedbd81 100644
--- a/src/locale/error_messages.fr.json
+++ b/src/locale/error_messages.fr.json
@@ -49,23 +49,23 @@
     "INFO_LECHAPT_TITRE": "Lechapt-Calmon",
     "INFO_REGUNI_TITRE": "Régime uniforme",
     "INFO_SECTPARAM_TITRE": "Section paramétrée",
-    "INFO_GRANDEUR_HS": "La charge spécifique",
-    "INFO_GRANDEUR_HSC": "La charge critique",
-    "INFO_GRANDEUR_B": "La largeur au miroir",
-    "INFO_GRANDEUR_P": "Le périmètre mouillé",
-    "INFO_GRANDEUR_S": "La surface mouillée",
-    "INFO_GRANDEUR_R": "Le rayon hydraulique",
-    "INFO_GRANDEUR_V": "La vitesse moyenne",
+    "INFO_GRANDEUR_HS": "La charge spécifique (m)",
+    "INFO_GRANDEUR_HSC": "La charge critique (m)",
+    "INFO_GRANDEUR_B": "La largeur au miroir (m)",
+    "INFO_GRANDEUR_P": "Le périmètre mouillé (m)",
+    "INFO_GRANDEUR_S": "La surface mouillée  (m2)",
+    "INFO_GRANDEUR_R": "Le rayon hydraulique  (m)",
+    "INFO_GRANDEUR_V": "La vitesse moyenne  (m/s)",
     "INFO_GRANDEUR_FR": "Le Froude",
-    "INFO_GRANDEUR_YC": "Le tirant d'eau critique",
-    "INFO_GRANDEUR_YN": "Le tirant d'eau normal",
-    "INFO_GRANDEUR_YF": "Le tirant d'eau fluvial",
-    "INFO_GRANDEUR_YT": "Le tirant d'eau torrentiel",
-    "INFO_GRANDEUR_YCO": "Le tirant d'eau conjugué",
-    "INFO_GRANDEUR_J": "La perte de charge",
-    "INFO_GRANDEUR_I-J": "Variation linéaire de l'énergie spécifique",
-    "INFO_GRANDEUR_IMP": "Impulsion",
-    "INFO_GRANDEUR_TAU0": "La force tractrice",
+    "INFO_GRANDEUR_YC": "Le tirant d'eau critique (m)",
+    "INFO_GRANDEUR_YN": "Le tirant d'eau normal (m)",
+    "INFO_GRANDEUR_YF": "Le tirant d'eau fluvial (m)",
+    "INFO_GRANDEUR_YT": "Le tirant d'eau torrentiel (m)",
+    "INFO_GRANDEUR_YCO": "Le tirant d'eau conjugué (m)",
+    "INFO_GRANDEUR_J": "La perte de charge (m)",
+    "INFO_GRANDEUR_I-J": "Variation linéaire de l'énergie spécifique (m/m)",
+    "INFO_GRANDEUR_IMP": "Impulsion (N)",
+    "INFO_GRANDEUR_TAU0": "La force tractrice (Pa)",
     "INFO_REMOUS_TITRE": "Courbes de remous",
     "INFO_REMOUSRESULTS_TITREJOURNAL": "Journal de calcul",
     "INFO_REMOUSRESULTS_LIGNEFLUVIALE": "Ligne d'eau fluviale",
-- 
GitLab


From bd000a090d5556aa0b35a342d0f2e89a5da9d5c3 Mon Sep 17 00:00:00 2001
From: "francois.grand" <francois.grand@irstea.fr>
Date: Wed, 25 Apr 2018 17:03:01 +0200
Subject: [PATCH 53/53] =?UTF-8?q?=20#77=20courbes=20de=20remous=20:=20rema?=
 =?UTF-8?q?niement=20de=20la=20table=20des=20r=C3=A9sultats=20-=20RemousRe?=
 =?UTF-8?q?sultsComponent=20:=20table=20HTML=20remplac=C3=A9e=20par=20le?=
 =?UTF-8?q?=20composant=20VarResultsComponent=20-=20CalculatedParamResults?=
 =?UTF-8?q?=20:=20ajout=20d'un=20champ=20=5FcalculatedParamHeader=20-=20Ho?=
 =?UTF-8?q?rizontalResultElementComponent=20:=20membre=20=5Fheaders=20reno?=
 =?UTF-8?q?mm=C3=A9=20en=20=5FheaderKeys=20-=20RemousResults=20:=20ajout?=
 =?UTF-8?q?=20d'un=20membre=20de=20type=20VarResults=20utilis=C3=A9=20par?=
 =?UTF-8?q?=20le=20composant=20VarResultsComponent=20des=20r=C3=A9sultats?=
 =?UTF-8?q?=20-=20VarResults=20:=20s=C3=A9paration=20des=20ent=C3=AAtes=20?=
 =?UTF-8?q?en=20cl=C3=A9=20d'ent=C3=AAte=20+=20dictionnaire=20de=20traduct?=
 =?UTF-8?q?ion=20des=20cl=C3=A9s?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../fixed-results.component.ts                |  2 +-
 .../var-results.component.html                |  2 +-
 .../fixedvar-results/var-results.component.ts |  9 +--
 .../remous-results.component.html             | 23 +-----
 .../remous-results.component.ts               | 78 +++++++++----------
 .../horizontal-result-element.component.ts    | 15 ++--
 src/app/results/param-calc-results.ts         | 15 ++++
 src/app/results/remous-results.ts             | 45 +++++++----
 src/app/results/var-results.ts                | 58 ++++++++++----
 9 files changed, 137 insertions(+), 110 deletions(-)

diff --git a/src/app/components/fixedvar-results/fixed-results.component.ts b/src/app/components/fixedvar-results/fixed-results.component.ts
index ac8ef11d3..8427ec4a2 100644
--- a/src/app/components/fixedvar-results/fixed-results.component.ts
+++ b/src/app/components/fixedvar-results/fixed-results.component.ts
@@ -53,7 +53,7 @@ export class FixedResultsComponent {
     }
 
     private get resultLabel(): string {
-        return this._fixedResults && this._fixedResults.calculatedParameter && CalculatorResults.paramLabel(this._fixedResults.calculatedParameter, false);
+        return this._fixedResults && this._fixedResults.calculatedParameter && this._fixedResults.calculatedParameterHeader;
     }
 
     private get uitextParamFixes() {
diff --git a/src/app/components/fixedvar-results/var-results.component.html b/src/app/components/fixedvar-results/var-results.component.html
index c99dd2a03..4c3a42601 100644
--- a/src/app/components/fixedvar-results/var-results.component.html
+++ b/src/app/components/fixedvar-results/var-results.component.html
@@ -12,7 +12,7 @@
                         {{r.param}}
                     </td>
                     <!-- résultat -->
-                    <td horizontal-result-element [result-element]=r.result [headers]=extraResultHeaders>
+                    <td horizontal-result-element [result-element]=r.result [headerKeys]=extraResultKeys>
                     </td>
                 </tr>
             </table>
diff --git a/src/app/components/fixedvar-results/var-results.component.ts b/src/app/components/fixedvar-results/var-results.component.ts
index 5ffd22794..ee35aa404 100644
--- a/src/app/components/fixedvar-results/var-results.component.ts
+++ b/src/app/components/fixedvar-results/var-results.component.ts
@@ -4,7 +4,6 @@ import { InternationalisationService } from "../../services/internationalisation
 import { VarResults } from "../../results/var-results";
 import { ApplicationSetupService } from "../../services/app-setup/app-setup.service";
 import { ResultElement } from "jalhyd";
-import { CalculatorResults } from "../../results/calculator-results";
 
 @Component({
     selector: "var-results",
@@ -46,8 +45,8 @@ export class VarResultsComponent {
                 i++
             }
 
-            this._headers.push(CalculatorResults.paramLabel(this._varResults.variatedParameter, false));
-            this._headers.push(CalculatorResults.paramLabel(this._varResults.calculatedParameter, false));
+            this._headers.push(this._varResults.variableParamHeader);
+            this._headers.push(this._varResults.calculatedParameterHeader);
             this._headers = this._headers.concat(this._varResults.extraResultHeaders);
         }
     }
@@ -56,8 +55,8 @@ export class VarResultsComponent {
         return this._varResults && this._varResults.hasResults;
     }
 
-    private get extraResultHeaders() {
-        return this._varResults && this._varResults.extraResultHeaders;
+    private get extraResultKeys() {
+        return this._varResults && this._varResults.extraResultKeys;
     }
 
     private get headers() {
diff --git a/src/app/components/remous-results/remous-results.component.html b/src/app/components/remous-results/remous-results.component.html
index 9cedfa233..391f0ddaf 100644
--- a/src/app/components/remous-results/remous-results.component.html
+++ b/src/app/components/remous-results/remous-results.component.html
@@ -15,27 +15,6 @@
 
     <div *ngIf="hasData" class="row">
         <!-- résultats numériques -->
-        <table class="table">
-            <thead>
-                <tr>
-                    <th></th>
-                    <th>{{uitextLigneFluviale}}</th>
-                    <th></th>
-                    <th>{{uitextLigneTorrentielle}}</th>
-                    <th></th>
-                </tr>
-                <tr>
-                    <th>{{uitextAbscisse}}</th>
-                    <th>{{uitextTirant}}</th>
-                    <th>{{extraParamLabel}}</th>
-                    <th>{{uitextTirant}}</th>
-                    <th>{{extraParamLabel}}</th>
-                </tr>
-            </thead>
-            <tr *ngFor="let v of values; let i=index" [class]="getResultClass(i)">
-                <td horizontal-result-element [result-element]=v [headers]=_headers>
-                </td>
-            </tr>
-        </table>
+        <var-results></var-results>
     </div>
 </div>
diff --git a/src/app/components/remous-results/remous-results.component.ts b/src/app/components/remous-results/remous-results.component.ts
index 9b8bccc04..5f6f261c0 100644
--- a/src/app/components/remous-results/remous-results.component.ts
+++ b/src/app/components/remous-results/remous-results.component.ts
@@ -1,11 +1,13 @@
 import { Component, ViewChild } from "@angular/core";
 
-import { Result, ArrayReverseIterator, ResultElement } from "jalhyd";
+import { ArrayReverseIterator, ResultElement, ParamValueIterator } from "jalhyd";
 
 import { InternationalisationService } from "../../services/internationalisation/internationalisation.service";
 import { LogComponent } from "../../components/log/log.component";
 import { RemousResults } from "../../results/remous-results";
 import { CalculatorResults } from "../../results/calculator-results";
+import { VarResults } from "../../results/var-results";
+import { VarResultsComponent } from "../fixedvar-results/var-results.component";
 
 @Component({
     selector: "remous-results",
@@ -49,19 +51,20 @@ export class RemousResultsComponent {
     private graph2_options = {};
 
     /**
-     * headers du composant HorizontalResultElementComponent
+     * entêtes de la table de résultats numériques
      */
-    private _headers: string[] = ["flu", "extraFlu", "tor", "extraTor"];
+    private _tableHeaders: string[];
 
     /**
-     * liste de valeurs pour le tableau
+     * true si les résultats doivent être mis à jour
      */
-    private _values: Object[];
+    private _doUpdate: boolean = false;
 
     /**
-     * true si les résultats doivent être mis à jour
+     * composant des résultats variables
      */
-    private _doUpdate: boolean = false;
+    @ViewChild(VarResultsComponent)
+    private varResultsComponent: VarResultsComponent;
 
     /**
      * composant journal
@@ -129,9 +132,11 @@ export class RemousResultsComponent {
         this.graph1_options = {};
         this.graph2_data = {};
         this.graph2_options = {};
+        if (this.varResultsComponent != undefined)
+            this.varResultsComponent.results = undefined;
         if (this.logComponent != undefined)
             this.logComponent.log = undefined;
-        this._values = [];
+        this._tableHeaders = [];
 
         if (this._remousResults != undefined)
             this._doUpdate = this._remousResults.hasResults;
@@ -154,6 +159,10 @@ export class RemousResultsComponent {
         return false;
     }
 
+    private get abscisseIterator(): ParamValueIterator {
+        return this._remousResults.varResults.variatedParameter.paramDefinition.paramValues.getValuesIterator();
+    }
+
     private connectRessaut(lineFlu: LineData, lineTor: LineData) {
         if (lineFlu != undefined && lineTor != undefined) {
             let tX = lineFlu.tx.slice(0); // copie
@@ -167,11 +176,11 @@ export class RemousResultsComponent {
             });
 
             let minXflu; // abscisse de début de la courbe fluviale
-            this._remousResults.xValues.initIterator();
+            let itX = this.abscisseIterator;
             for (let re of this._remousResults.result.resultElements) {
-                if (!this._remousResults.xValues.hasNext)
+                if (!itX.hasNext)
                     throw new Error("RemousResultsComponent.connectRessaut() : erreur interne (itérateur sur x)")
-                const x = this._remousResults.xValues.next;
+                const x = itX.next().value;
                 if (re.getExtraResult("flu") != undefined) {
                     minXflu = x;
                     break;
@@ -189,11 +198,11 @@ export class RemousResultsComponent {
 
             let maxXtor; // abscisse de fin de la courbe torrentielle
             const itRE = new ArrayReverseIterator<ResultElement>(this._remousResults.result.resultElements);
-            this._remousResults.xValues.initIterator();
+            itX = this.abscisseIterator;
             for (let r of itRE) {
-                if (!this._remousResults.xValues.hasNext)
+                if (!itX.hasNext)
                     throw new Error("RemousResultsComponent.connectRessaut() : erreur interne (itérateur sur x)")
-                const x = this._remousResults.xValues.next;
+                const x = itX.next();
                 if (r.getExtraResult("tor") != undefined) {
                     maxXtor = x;
                     break;
@@ -215,6 +224,9 @@ export class RemousResultsComponent {
         // http://www.chartjs.org/docs/latest/charts/line.html
         // le dernier dataset de la liste datasets est dessiné en 1er
 
+        this._remousResults.update();
+        this.varResultsComponent.results = this._remousResults.varResults;
+
         const penteFond: number = this._remousResults.penteFond;
 
         // abscisses
@@ -222,9 +234,9 @@ export class RemousResultsComponent {
         let labs: number[] = [];
         if (this._remousResults.result.ok) {
             var xmax = -1e8;
-            this._remousResults.xValues.initIterator();
-            while (this._remousResults.xValues.hasNext) {
-                const x = this._remousResults.xValues.next;
+            const itX = this.abscisseIterator;
+            while (itX.hasNext) {
+                const x = itX.next().value;
                 labs.push(x);
                 xmax = Math.max(x, xmax);
             }
@@ -268,41 +280,23 @@ export class RemousResultsComponent {
                 lineExtra = gr1.newLine(2);
         }
 
-        this._remousResults.xValues.initIterator();
+        const itX = this.abscisseIterator;
         for (let re of this._remousResults.result.resultElements) {
-            if (!this._remousResults.xValues.hasNext)
+            if (!itX.hasNext)
                 throw new Error("RemousResultsComponent.generateGraph() : erreur interne (itérateur sur x)")
 
-            const x = this._remousResults.xValues.next;
+            const x = itX.next().value;
             const yExtra = re.getExtraResult("tRes");
             if (yExtra != undefined)
                 lineExtra.mapPoint(x, yExtra);
 
             const yFlu = re.getExtraResult("flu");
-            let extraFlu;
-            if (yFlu != undefined) {
+            if (yFlu != undefined)
                 lineFlu.mapPoint(x, yFlu);
-                extraFlu = yExtra;
-            }
 
             const yTor = re.getExtraResult("tor");
-            let extraTor;
-            if (yTor != undefined) {
+            if (yTor != undefined)
                 lineTor.mapPoint(x, yTor);
-                extraTor = yExtra;
-            }
-
-            const re2 = new ResultElement(x);
-            if (yFlu)
-                re2.addExtraResult("flu", yFlu);
-            if (extraFlu)
-                re2.addExtraResult("extraFlu", extraFlu);
-            if (yTor)
-                re2.addExtraResult("tor", yTor);
-            if (extraTor)
-                re2.addExtraResult("extraTor", extraTor);
-
-            this._values.push(re2);
         }
 
         if (this._remousResults.hasExtra) {
@@ -364,8 +358,8 @@ export class RemousResultsComponent {
         }
     }
 
-    private get values() {
-        return this._values;
+    private headers(): string[] {
+        return this._tableHeaders;
     }
 
     private getResultClass(i: number) {
diff --git a/src/app/components/result-element/horizontal-result-element.component.ts b/src/app/components/result-element/horizontal-result-element.component.ts
index b0b1e2ff5..d137a31c0 100644
--- a/src/app/components/result-element/horizontal-result-element.component.ts
+++ b/src/app/components/result-element/horizontal-result-element.component.ts
@@ -15,17 +15,14 @@ export class HorizontalResultElementComponent extends ResultElementBaseComponent
     // template des td pour les extraResult
     @ViewChild("extraResultTd") tdTemplate: TemplateRef<any>;
 
-    /**
-     * entête des extraResult
-     */
-    private _headers: string[];
-
     /**
      * clés des résultats complémentaires à afficher (la cellule est vide s'il n'existe pas dans le ResultElement)
      */
+    private _headerKeys: string[];
+
     @Input()
-    public set headers(h: string[]) {
-        this._headers = h;
+    public set headerKeys(h: string[]) {
+        this._headerKeys = h;
     }
 
     constructor(
@@ -40,8 +37,8 @@ export class HorizontalResultElementComponent extends ResultElementBaseComponent
         super.ngOnChanges();
 
         this.vcRef.clear();
-        if (this._headers && this._resultElement)
-            for (const h of this._headers) {
+        if (this._headerKeys && this._resultElement)
+            for (const h of this._headerKeys) {
                 let v = this._resultElement.extraResults[h];
                 if (typeof (v) === "number")
                     v = v.toFixed(this.appSetupService.displayDigits);
diff --git a/src/app/results/param-calc-results.ts b/src/app/results/param-calc-results.ts
index 4a24add19..dadbf0f38 100644
--- a/src/app/results/param-calc-results.ts
+++ b/src/app/results/param-calc-results.ts
@@ -12,6 +12,11 @@ export abstract class CalculatedParamResults extends CalculatorResults {
      */
     protected _calculatedParam: NgParameter;
 
+    /**
+     * titre de la colonne
+     */
+    private _calculatedParamHeader: string;
+
     /**
      * résultat du calcul sur le paramètre calculé
      */
@@ -19,6 +24,7 @@ export abstract class CalculatedParamResults extends CalculatorResults {
 
     protected reset() {
         this._calculatedParam = undefined;
+        this._calculatedParamHeader = undefined;
         this._result = undefined;
     }
 
@@ -28,6 +34,15 @@ export abstract class CalculatedParamResults extends CalculatorResults {
 
     public set calculatedParameter(p: NgParameter) {
         this._calculatedParam = p;
+        this._calculatedParamHeader = CalculatorResults.paramLabel(this._calculatedParam, true);
+    }
+
+    public get calculatedParameterHeader() {
+        return this._calculatedParamHeader;
+    }
+
+    public set calculatedParameterHeader(s: string) {
+        this._calculatedParamHeader = s;
     }
 
     public get result(): Result {
diff --git a/src/app/results/remous-results.ts b/src/app/results/remous-results.ts
index c41b8f7aa..3f9a2be03 100644
--- a/src/app/results/remous-results.ts
+++ b/src/app/results/remous-results.ts
@@ -1,11 +1,13 @@
-import { cLog, Result, ResultElement, ParamValues, CourbeRemousParams } from "jalhyd";
+import { cLog, Result, ResultElement, ParamValues, CourbeRemousParams, ParamDefinition, ParamDomainValue } from "jalhyd";
 
 import { CalculatorResults } from "./calculator-results";
+import { VarResults } from "./var-results";
+import { NgParameter } from "../formulaire/ngparam";
 
 export class RemousResults extends CalculatorResults {
     private _result: Result;
 
-    private _xValues: ParamValues;
+    private _xValues: ParamDefinition;
 
     /**
      * hauteur de berge
@@ -42,6 +44,11 @@ export class RemousResults extends CalculatorResults {
      */
     private _hasExtra: boolean;
 
+    /**
+     * résultats variables pour l'affichage d'une table de résultats numériques
+     */
+    private _varResults: VarResults;
+
     /**
      * le paramètre supplémentaire est affiché dans un graphe séparé
      */
@@ -74,7 +81,6 @@ export class RemousResults extends CalculatorResults {
         this._hasTor = false;
         this._hasExtra = false;
         this._extraGraph = false;
-        this._extraParamLabel = undefined;
     }
 
     public set parameters(p: CourbeRemousParams) {
@@ -91,16 +97,16 @@ export class RemousResults extends CalculatorResults {
         const Dx = p.map.Dx.v;
 
         // série de valeurs de X
-        this._xValues = new ParamValues();
-        this._xValues.setValues(0, Long, Dx);
+        this._xValues = new ParamDefinition("Abscisse", ParamDomainValue.POS_NULL);
+        this._xValues.paramValues.setValues(0, Long, Dx);
     }
 
     public get log() {
         return this._log;
     }
 
-    public get xValues(): ParamValues {
-        return this._xValues;
+    public get varResults(): VarResults {
+        return this._varResults;
     }
 
     public get result(): Result {
@@ -109,12 +115,14 @@ export class RemousResults extends CalculatorResults {
 
     public set result(r: Result) {
         this._result = r;
+    }
 
+    public update() {
         this._hasFlu = false;
         this._hasTor = false;
         this._hasExtra = false;
 
-        for (const re of r.resultElements) {
+        for (const re of this._result.resultElements) {
             if (!this._hasFlu && re.getExtraResult("flu"))
                 this._hasFlu = true;
             if (!this._hasTor && re.getExtraResult("tor"))
@@ -123,11 +131,22 @@ export class RemousResults extends CalculatorResults {
                 this._hasExtra = true;
         }
 
-        this._log.addLog(r.globalLog);
-    }
-
-    public get extraParamLabel() {
-        return this._extraParamLabel;
+        this._log.addLog(this._result.globalLog);
+
+        this._varResults = new VarResults();
+        this._varResults.variatedParameter = new NgParameter(this._xValues, undefined);
+        this._varResults.calculatedParameter = new NgParameter(new ParamDefinition("Ligne d'eau", ParamDomainValue.POS_NULL), undefined);
+        this._varResults.result = this._result;
+        let keys = [];
+        if (this._hasFlu)
+            keys.push("flu");
+        if (this._hasTor)
+            keys.push("tor");
+        if (this._hasExtra)
+            keys.push("tRes");
+        this._varResults.extraResultKeys = keys;
+        this._varResults.extraResultHeaderMap = { "flu": "Ligne d'eau fluviale", "tor": "Ligne d'eau torrentielle", "tRes": this._extraParamLabel };
+        this._varResults.update(true);
     }
 
     public set extraParamLabel(l: string) {
diff --git a/src/app/results/var-results.ts b/src/app/results/var-results.ts
index 5f6484fb5..ebd48a211 100644
--- a/src/app/results/var-results.ts
+++ b/src/app/results/var-results.ts
@@ -36,9 +36,14 @@ export class VarResults extends CalculatedParamResults {
     private _variableParamHeader: string;
 
     /**
-     * titre de la 2ème colonne des résultats variés
+     * clés des résultats complémentaires
      */
-    private _variableResultHeader: string;
+    private _extraResultKeys: string[];
+
+    /**
+     * mapping clé de résultat complémentaire <-> titre de colonne
+     */
+    private _extraResultHeaderMap: { [key: string]: string };
 
     /**
      * entête des colonnes des résultats supplémentaires
@@ -68,8 +73,9 @@ export class VarResults extends CalculatedParamResults {
     public reset() {
         super.reset();
         this._variableParamHeader = undefined;
-        this._variableResultHeader = undefined;
         this._extraResultHeaders = [];
+        this._extraResultKeys = [];
+        this._extraResultHeaderMap = {};
         this._yValues = [];
         this._graphTitle = undefined;
     }
@@ -80,16 +86,13 @@ export class VarResults extends CalculatedParamResults {
 
     public set variatedParameter(p: NgParameter) {
         this._variatedParam = p;
+        this._variableParamHeader = CalculatorResults.paramLabel(this._variatedParam, true);
     }
 
-    private get variableParamHeader() {
+    public get variableParamHeader() {
         return this._variableParamHeader;
     }
 
-    private get variableResultHeader() {
-        return this._variableResultHeader;
-    }
-
     public get yValues() {
         return this._yValues;
     }
@@ -110,21 +113,42 @@ export class VarResults extends CalculatedParamResults {
         return this._extraResultHeaders;
     }
 
-    public update(displaySymbol: boolean) {
-        // this.reset();
+    public get extraResultKeys() {
+        return this._extraResultKeys;
+    }
 
-        this._variableParamHeader = CalculatorResults.paramLabel(this.variatedParameter, displaySymbol);
-        if (this._calculatedParam)
-            this._variableResultHeader = CalculatorResults.paramLabel(this._calculatedParam, true);
+    public set extraResultKeys(k: string[]) {
+        this._extraResultKeys = k;
+    }
+
+    public set extraResultHeaderMap(m: { [key: string]: string }) {
+        this._extraResultHeaderMap = m;
+    }
+
+    public update(displaySymbol: boolean) {
+        if (this._variableParamHeader === undefined)
+            this._variableParamHeader = CalculatorResults.paramLabel(this.variatedParameter, displaySymbol);
 
         // valeurs du paramètre à calculer
         for (const r of this._result.resultElements)
             this._yValues.push(r.vCalc);
 
+        // clés des résultats supplémentaires
+
+        if (this._extraResultKeys.length === 0)
+            for (const re of this._result.resultElements) // re:ResultElement
+                for (const erk in re.extraResults)
+                    if (!this._extraResultKeys.includes(erk))
+                        this._extraResultKeys.push(erk);
+
         // entêtes des résultats supplémentaires
-        for (const re of this._result.resultElements) // re:ResultElement
-            for (const erk in re.extraResults)
-                if (!this._extraResultHeaders.includes(erk))
-                    this._extraResultHeaders.push(erk);
+
+        for (const k of this._extraResultKeys) {
+            const h = this._extraResultHeaderMap[k];
+            if (h)
+                this._extraResultHeaders.push(h);
+            else
+                this._extraResultHeaders.push(k);
+        }
     }
 }
-- 
GitLab