From fb9fed1a1265940280c0217297d557cc0d6c4e72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Grand?= <francois.grand@inrae.fr>
Date: Tue, 17 Jan 2023 17:32:09 +0100
Subject: [PATCH] refactor: modify code to fit encapsulation of properties Nub
 field (cherry-picked from #585)

refs #592
---
 .../fieldset-container.component.ts           |  4 +-
 .../macrorugo-compound-results.component.ts   |  2 +-
 .../modules-diagram.component.ts              |  4 +-
 .../pab-profile-chart.component.ts            |  6 +-
 .../pab-table/pab-table.component.ts          |  4 +-
 .../definition/form-courbe-remous.ts          |  2 +-
 .../formulaire/definition/form-definition.ts  | 14 ++-
 src/app/formulaire/definition/form-espece.ts  |  2 +-
 .../formulaire/definition/form-fixedvar.ts    |  2 +-
 .../definition/form-macrorugo-compound.ts     |  2 +-
 .../definition/form-parallel-structures.ts    | 18 ++--
 .../formulaire/definition/form-pb-cloison.ts  |  8 +-
 .../formulaire/definition/form-prebarrage.ts  |  2 +-
 src/app/formulaire/definition/form-solveur.ts |  4 +-
 .../definition/form-verificateur.ts           |  2 +-
 src/app/formulaire/elements/fieldset.ts       | 97 ++++++++++---------
 .../select/select-field-device-loi-debit.ts   |  2 +-
 .../elements/select/select-field-nub-prop.ts  |  5 +-
 18 files changed, 93 insertions(+), 87 deletions(-)

diff --git a/src/app/components/fieldset-container/fieldset-container.component.ts b/src/app/components/fieldset-container/fieldset-container.component.ts
index f612f362a..042df7517 100644
--- a/src/app/components/fieldset-container/fieldset-container.component.ts
+++ b/src/app/components/fieldset-container/fieldset-container.component.ts
@@ -89,8 +89,8 @@ export class FieldsetContainerComponent implements DoCheck, AfterViewInit {
             const prms = after.backupParameters();
             // replace in-place to change properties (overkill)
             // @WTF why only those two ?
-            newFs.setNubPropValue("structureType", after.properties.getPropValue("structureType"));
-            newFs.setNubPropValue("loiDebit", after.properties.getPropValue("loiDebit"));
+            newFs.setPropValue("structureType", after.getPropValue("structureType"));
+            newFs.setPropValue("loiDebit", after.getPropValue("loiDebit"));
 
             // au cas où un des paramètres du fieldset source est en mode calcul,
             // on met le paramètre copié en mode fixé (nghyd#567)
diff --git a/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts
index 86eba4301..f388647da 100644
--- a/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts
+++ b/src/app/components/macrorugo-compound-results/macrorugo-compound-results.component.ts
@@ -92,7 +92,7 @@ export class MacrorugoCompoundResultsComponent extends ResultsComponentDirective
             this.mrcResults
             && this.mrcResults.result
             && this.mrcResults.result.sourceNub
-            && this.mrcResults.result.sourceNub.properties.getPropValue("inclinedApron") === MRCInclination.INCLINED
+            && this.mrcResults.result.sourceNub.getPropValue("inclinedApron") === MRCInclination.INCLINED
         );
     }
 
diff --git a/src/app/components/modules-diagram/modules-diagram.component.ts b/src/app/components/modules-diagram/modules-diagram.component.ts
index 6f227edcb..0b607e51e 100644
--- a/src/app/components/modules-diagram/modules-diagram.component.ts
+++ b/src/app/components/modules-diagram/modules-diagram.component.ts
@@ -265,11 +265,11 @@ export class ModulesDiagramComponent implements AfterContentInit, AfterViewCheck
      */
     private describe(n: Nub) {
         let type = CalculatorType[n.calcType];
-        const nt = n.properties.getPropValue("nodeType");
+        const nt = n.getPropValue("nodeType");
         if (nt) {
             type = SectionType[nt];
         } else {
-            const ld = n.properties.getPropValue("loiDebit");
+            const ld = n.getPropValue("loiDebit");
             if (ld !== undefined) {
                 type = LoiDebit[ld];
             }
diff --git a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
index c8eff7ec5..ee664e43a 100644
--- a/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
+++ b/src/app/components/pab-profile-chart/pab-profile-chart.component.ts
@@ -268,7 +268,7 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen
                     ddSeries[sti] = [];
                 }
                 // orifices have no relevant ZDV
-                if (st.properties.getPropValue("loiDebit") !== LoiDebit.OrificeSubmerged) {
+                if (st.getPropValue("loiDebit") !== LoiDebit.OrificeSubmerged) {
                     // 2 points, to draw a segment
                     ddSeries[sti].push({
                         x: xs[i],
@@ -305,7 +305,7 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen
             }
             // orifices have no relevant ZDV; lift gate will be drawn later for each series
             if (! [ LoiDebit.OrificeSubmerged, LoiDebit.VanLevLarinier, LoiDebit.VanLevVillemonte ]
-                .includes(st.properties.getPropValue("loiDebit"))
+                .includes(st.getPropValue("loiDebit"))
             ) {
                 // 2 points, to draw a segment
                 ddSeries[sti].push({
@@ -403,7 +403,7 @@ export class PabProfileChartComponent extends ResultsComponentDirective implemen
                 // draw lift gate if any
                 if (isLastAbscissa) {
                     for (const st of dw.structures) {
-                        if ([ LoiDebit.VanLevLarinier, LoiDebit.VanLevVillemonte ].includes(st.properties.getPropValue("loiDebit"))) {
+                        if ([LoiDebit.VanLevLarinier, LoiDebit.VanLevVillemonte].includes(st.getPropValue("loiDebit"))) {
                             // skip a point to disjoin line
                             dataN.push({
                                 x: x,
diff --git a/src/app/components/pab-table/pab-table.component.ts b/src/app/components/pab-table/pab-table.component.ts
index 8ef4e14c1..ead6072f1 100644
--- a/src/app/components/pab-table/pab-table.component.ts
+++ b/src/app/components/pab-table/pab-table.component.ts
@@ -594,7 +594,7 @@ export class PabTableComponent implements AfterViewInit, AfterViewChecked, OnIni
                     if (i === 0) { // 1st row
                         deviceParamRow.cells.push({
                             model: ouvrage,
-                            modelValue: ouvrage.properties.getPropValue("loiDebit"),
+                            modelValue: ouvrage.getPropValue("loiDebit"),
                             options: loisCloisons,
                             selectable: ouvrage
                         });
@@ -719,7 +719,7 @@ export class PabTableComponent implements AfterViewInit, AfterViewChecked, OnIni
                 if (i === 0) { // 1st row
                     deviceParamRowDW.cells.push({
                         model: ouvrage,
-                        modelValue: ouvrage.properties.getPropValue("loiDebit"),
+                        modelValue: ouvrage.getPropValue("loiDebit"),
                         options: loisAval
                     });
                 }
diff --git a/src/app/formulaire/definition/form-courbe-remous.ts b/src/app/formulaire/definition/form-courbe-remous.ts
index 3762c846c..62c8d3b3b 100644
--- a/src/app/formulaire/definition/form-courbe-remous.ts
+++ b/src/app/formulaire/definition/form-courbe-remous.ts
@@ -31,7 +31,7 @@ export class FormulaireCourbeRemous extends FormulaireSection {
         this._remousResults.parameters = prmCR;
 
         // variable supplémentaire à calculer
-        this._remousResults.extraParamSymbol = this.currentNub.properties.getPropValue("varCalc");
+        this._remousResults.extraParamSymbol = this.currentNub.getPropValue("varCalc");
 
         // calcul
         this._remousResults.result = cr.CalcSerie();
diff --git a/src/app/formulaire/definition/form-definition.ts b/src/app/formulaire/definition/form-definition.ts
index f2141323a..b4a34d345 100644
--- a/src/app/formulaire/definition/form-definition.ts
+++ b/src/app/formulaire/definition/form-definition.ts
@@ -81,14 +81,18 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
         return this._calculateDisabled;
     }
 
+    private getPropValue(key: string): any {
+        if (this._currentNub === undefined)
+            return this.defaultProperties[key];
+        return this._currentNub.getPropValue(key);
+    }
+
     public get calculatorType(): CalculatorType {
-        const props = this._currentNub === undefined ? this.defaultProperties : (this._currentNub.properties as Props).props;
-        return props["calcType"];
+        return this.getPropValue("calcType")
     }
 
     public get nodeType(): SectionType {
-        const props = this._currentNub === undefined ? this.defaultProperties : (this._currentNub.properties as Props).props;
-        return props["nodeType"];
+        return this.getPropValue("nodeType")
     }
 
     public get calculatorName() {
@@ -127,7 +131,7 @@ export abstract class FormulaireDefinition extends FormulaireNode implements Obs
     }
 
     public set currentNub(n: Nub) {
-        const nubCalcType = (n.properties as Props).getPropValue("calcType");
+        const nubCalcType = n.getPropValue("calcType");
         if (this._props["calcType"] !== nubCalcType) {
             throw new Error(
                 `Nub ${n.properties["calcType"]} incompatible avec le formulaire ${this._calculatorName} (${this._props["calcType"]})`
diff --git a/src/app/formulaire/definition/form-espece.ts b/src/app/formulaire/definition/form-espece.ts
index 10ded3b83..f0a36b93e 100644
--- a/src/app/formulaire/definition/form-espece.ts
+++ b/src/app/formulaire/definition/form-espece.ts
@@ -10,7 +10,7 @@ export class FormulaireEspece extends FormulaireFixedVar {
 
     protected completeParse(firstNotif: boolean = true) {
         super.completeParse(firstNotif);
-        this.updateDivingJetCriteriaInputs(this.currentNub.properties.getPropValue("divingJetSupported"));
+        this.updateDivingJetCriteriaInputs(this.currentNub.getPropValue("divingJetSupported"));
     }
 
     /**
diff --git a/src/app/formulaire/definition/form-fixedvar.ts b/src/app/formulaire/definition/form-fixedvar.ts
index 0a329f489..8eb6917e7 100644
--- a/src/app/formulaire/definition/form-fixedvar.ts
+++ b/src/app/formulaire/definition/form-fixedvar.ts
@@ -63,7 +63,7 @@ export class FormulaireFixedVar extends FormulaireDefinition {
 
     public afterParseFieldset(fs: FieldSet) {
         // observe all Select fields @see this.update()
-        fs.properties.addObserver(this);
+        fs.addPropertiesObserver(this);
     }
 
     protected completeParse(firstNotif: boolean = true) {
diff --git a/src/app/formulaire/definition/form-macrorugo-compound.ts b/src/app/formulaire/definition/form-macrorugo-compound.ts
index ec470e645..306332cb5 100644
--- a/src/app/formulaire/definition/form-macrorugo-compound.ts
+++ b/src/app/formulaire/definition/form-macrorugo-compound.ts
@@ -56,7 +56,7 @@ export class FormulaireMacrorugoCompound extends FormulaireRepeatableFieldset {
         super.completeParse(firstNotif);
         this.fieldsetContainer.addObserver(this);
         if (firstNotif) {
-            this.updateApronState(this.currentNub.properties.getPropValue("inclinedApron"));
+            this.updateApronState(this.currentNub.getPropValue("inclinedApron"));
         }
     }
 
diff --git a/src/app/formulaire/definition/form-parallel-structures.ts b/src/app/formulaire/definition/form-parallel-structures.ts
index b47c4808b..a5de99edd 100644
--- a/src/app/formulaire/definition/form-parallel-structures.ts
+++ b/src/app/formulaire/definition/form-parallel-structures.ts
@@ -1,4 +1,4 @@
-import { Structure, Nub, ParallelStructure, StructureProperties, Props, Session, ParamDefinition, Prop_NullParameters } from "jalhyd";
+import { Structure, Nub, ParallelStructure, StructureProperties, Props, Session, ParamDefinition, Prop_NullParameters, IProperties } from "jalhyd";
 
 import { FieldsetContainer } from "../elements/fieldset-container";
 import { FieldSet } from "../elements/fieldset";
@@ -71,7 +71,7 @@ export class FormulaireParallelStructure extends FormulaireRepeatableFieldset {
      * and return it; does not store it in the Session (for Structures, not for Calculator Modules)
      * @param p properties for the new Nub
      */
-    protected createStructure(p: Props): Structure {
+    protected createStructure(p: IProperties): Structure {
         return Session.getInstance().createNub(p, this.currentNub as ParallelStructure) as Structure;
     }
 
@@ -81,9 +81,9 @@ export class FormulaireParallelStructure extends FormulaireRepeatableFieldset {
      * @param sn Structure to replace
      * @param params properties to build the new Nub (calcType, loiDebit...)
      */
-    protected replaceNub(sn: Structure, params: Props): Nub {
+    protected replaceNub(sn: Structure): Nub {
         const parent = (this.currentNub as ParallelStructure);
-        const newStructure = this.createStructure(params);
+        const newStructure = this.createStructure(sn);
         parent.replaceChildInplace(sn, newStructure);
         return newStructure;
     }
@@ -108,7 +108,7 @@ export class FormulaireParallelStructure extends FormulaireRepeatableFieldset {
      * @param name nom de la propriété qui vient de changer
      * @param val nouvelle valeur de la propriété
      */
-    protected adjustProperties(props: Props, name: string, val: any) {
+    protected adjustProperties(props: IProperties, name: string, val: any) {
         if (name === "structureType") {
             if (! StructureProperties.isCompatibleValues(
                 val, props.getPropValue("loiDebit"), this.currentNub as ParallelStructure
@@ -159,12 +159,12 @@ export class FormulaireParallelStructure extends FormulaireRepeatableFieldset {
         } else if (sender instanceof FieldSet && data.action === "propertyChange") {
             switch (sender.id) {
                 case "fs_ouvrage":
-                    const props = sender.properties;
                     // ensure loiDebit is set
-                    props.setPropValue("loiDebit", data.value);
-                    this.adjustProperties(props, data["name"], data["value"]);
+                    //props.setPropValue("loiDebit", data.value); // ?? et si la propriété modifiée n'est pas la loi de débit ?
+
+                    this.adjustProperties(sender, data["name"], data["value"]);
                     // replace Structure Nub
-                    const newNub = this.replaceNub((sender.nub as Structure), props);
+                    const newNub = this.replaceNub(sender.nub as Structure);
                     sender.setNub(newNub);
                     // treat the fieldset as new to re-subscribe to Nub properties change events
                     this.afterParseFieldset(sender);
diff --git a/src/app/formulaire/definition/form-pb-cloison.ts b/src/app/formulaire/definition/form-pb-cloison.ts
index 25910c87d..145c03fe4 100644
--- a/src/app/formulaire/definition/form-pb-cloison.ts
+++ b/src/app/formulaire/definition/form-pb-cloison.ts
@@ -27,12 +27,12 @@ export class FormulairePbCloison extends FormulaireParallelStructure {
         } else if (sender instanceof FieldSet && data.action === "propertyChange") {
             switch (sender.id) {
                 case "fs_ouvrage":
-                    const props = sender.properties;
                     // ensure loiDebit is set
-                    props.setPropValue("loiDebit", data.value);
-                    this.adjustProperties(props, data["name"], data["value"]);
+                    //props.setPropValue("loiDebit", data.value); // ?? et si la propriété modifiée n'est pas la loi de débit ?
+
+                    this.adjustProperties(sender, data["name"], data["value"]);
                     // replace Structure Nub
-                    const newNub = this.replaceNub((sender.nub as Structure), props);
+                    const newNub = this.replaceNub(sender.nub as Structure);
                     sender.setNub(newNub);
                     // treat the fieldset as new to re-subscribe to Nub properties change events
                     this.afterParseFieldset(sender);
diff --git a/src/app/formulaire/definition/form-prebarrage.ts b/src/app/formulaire/definition/form-prebarrage.ts
index 95e5f6549..c9a0d9e0d 100644
--- a/src/app/formulaire/definition/form-prebarrage.ts
+++ b/src/app/formulaire/definition/form-prebarrage.ts
@@ -367,7 +367,7 @@ export class FormulairePrebarrage extends FormulaireFixedVar {
                     } catch (e) {
                         let res;
                         if (p.parentNub.calcType === CalculatorType.Structure) {
-                            res = p.parentNub.getParent().uid;
+                            res = p.parentNub.parent.uid;
                         } else {
                             res = p.parentNub.uid;
                         }
diff --git a/src/app/formulaire/definition/form-solveur.ts b/src/app/formulaire/definition/form-solveur.ts
index f658c98ee..0a3d446ef 100644
--- a/src/app/formulaire/definition/form-solveur.ts
+++ b/src/app/formulaire/definition/form-solveur.ts
@@ -58,7 +58,7 @@ export class FormulaireSolveur extends FormulaireFixedVar {
                     // if searchedParam is set to a value that won't be available anymore
                     // once nubToCalculate is updated, setPropValue throws an error, but
                     // nubToCalculate is updated anyway; here, just inhibit the error
-                    this._currentNub.properties.setPropValue("nubToCalculate", data.value.value);
+                    this._currentNub.setPropValue("nubToCalculate", data.value.value);
                 } catch (e) { }
                 // refresh targetted result selector
                 const trSel = this.getFormulaireNodeById(this._targettedResultSelectId) as SelectField;
@@ -73,7 +73,7 @@ export class FormulaireSolveur extends FormulaireFixedVar {
                 // update Solveur property: searched Parameter
                 try {
                     const p: ParamDefinition = data.value.value;
-                    this._currentNub.properties.setPropValue(
+                    this._currentNub.setPropValue(
                         "searchedParameter",
                         p.nubUid + "/" + p.symbol
                     );
diff --git a/src/app/formulaire/definition/form-verificateur.ts b/src/app/formulaire/definition/form-verificateur.ts
index 893754665..337bc789a 100644
--- a/src/app/formulaire/definition/form-verificateur.ts
+++ b/src/app/formulaire/definition/form-verificateur.ts
@@ -97,7 +97,7 @@ export class FormulaireVerificateur extends FormulaireFixedVar {
             this.reset(); // reset results
             if (sender.id === "select_target_pass" && data.action === "select") {
                 // update Verificateur property: Pass to check
-                this._currentNub.properties.setPropValue("nubToVerify", data.value ? data.value.value : undefined);
+                this._currentNub.setPropValue("nubToVerify", data.value ? data.value.value : undefined);
 
             } else if (sender.id === "select_species_list" && data.action === "select") {
                 // update Verificateur property: Species list (string[])
diff --git a/src/app/formulaire/elements/fieldset.ts b/src/app/formulaire/elements/fieldset.ts
index d0229afe7..2c130b65f 100644
--- a/src/app/formulaire/elements/fieldset.ts
+++ b/src/app/formulaire/elements/fieldset.ts
@@ -1,7 +1,7 @@
 import {
     CalculatorType,
     ParamDefinition,
-    Props,
+    IProperties,
     Observer,
     Nub,
     enumValueFromString
@@ -16,7 +16,7 @@ import { SelectFieldFactory } from "./select/select-field-factory";
 import { FormulaireFixedVar } from "../definition/form-fixedvar";
 import { SelectEntry } from "./select/select-entry";
 
-export class FieldSet extends FormulaireElement implements Observer {
+export class FieldSet extends FormulaireElement implements IProperties {
 
     /** Nub associé */
     private _nub: Nub;
@@ -45,7 +45,7 @@ export class FieldSet extends FormulaireElement implements Observer {
     }
 
     private addField(f: Field) {
-        if (! f) {
+        if (!f) {
             throw new Error("FieldSet.addField() : argument incorrect (undefined)");
         }
         this.kids.push(f);
@@ -114,40 +114,8 @@ export class FieldSet extends FormulaireElement implements Observer {
         return res;
     }
 
-    public get properties(): Props {
-        return this.nub.properties;
-    }
-
-    private get sectionProperties(): Props {
-        const section = this.nub.getChildren()[0];
-        if (section) {
-            return section.properties;
-        } else {
-            return new Props();
-        }
-    }
-
-    /**
-     * get associated nub property value
-     * @param key property name
-     * @param inSection if true, will look for the required property in the Nub's section (children[0])
-     */
-    private getNubPropValue(key: string, inSection: boolean = false): any {
-        if (inSection) {
-            return this.sectionProperties.getPropValue(key);
-        } else {
-            return this.properties.getPropValue(key);
-        }
-    }
-
-    /**
-     * assign associated nub property
-     * @param key nub property name
-     * @param val value to assign with
-     * @returns true if property value has changed
-     */
-    public setNubPropValue(key: string, val: any): boolean {
-        return this.properties.setPropValue(key, val, this);
+    public addPropertiesObserver(o: Observer) {
+        this.nub.addPropertiesObserver(o);
     }
 
     private getNubParamFromSymbol(symbol: string): ParamDefinition {
@@ -250,7 +218,7 @@ export class FieldSet extends FormulaireElement implements Observer {
     private setSelectValueFromProperty(selectId: string, inSection: boolean = false) {
         const selectField: SelectField = this.getFormulaireNodeById(selectId) as SelectField;
         if (selectField) {
-            let propVal: any = this.getNubPropValue(selectField.associatedProperty, inSection);
+            let propVal: any = this.getPropValue(selectField.associatedProperty, inSection);
             if (propVal === undefined) {
                 propVal = ""; // clodo bullet-proof loading
             }
@@ -277,9 +245,9 @@ export class FieldSet extends FormulaireElement implements Observer {
         this._helpLink = json["help"];
 
         const ct: string = json["calcType"];
-        const currentCt = this.properties.getPropValue("calcType");
+        const currentCt = this.getPropValue("calcType");
         const calc_type: CalculatorType = currentCt ? currentCt : (ct ? CalculatorType[ct] : this.parentForm.calculatorType);
-        this.setNubPropValue("calcType", calc_type);
+        this.setPropValue("calcType", calc_type);
 
         // parse fields once, so that SelectField elements are present
         // when setting default properties below
@@ -293,9 +261,9 @@ export class FieldSet extends FormulaireElement implements Observer {
                     const prop = sel.associatedProperty;
                     const defaultValue = sel.configDefaultValue;
                     // Sets Nub default property, unless this property is already set
-                    const currentValue = this.properties.getPropValue(prop);
+                    const currentValue = this.getPropValue(prop);
                     if (defaultValue !== undefined && currentValue === undefined) {
-                        this.setNubPropValue(prop, enumValueFromString(prop, defaultValue));
+                        this.setPropValue(prop, enumValueFromString(prop, defaultValue));
                     }
                 }
             }
@@ -314,7 +282,7 @@ export class FieldSet extends FormulaireElement implements Observer {
 
     public getNodeParameterValue(symbol: string): number {
         const p = this.getNodeParameter(symbol);
-        if (! p) {
+        if (!p) {
             throw new Error(`FieldSet.getNodeParameterValue() : pas de paramètre ${symbol} trouvé`);
         }
 
@@ -336,7 +304,7 @@ export class FieldSet extends FormulaireElement implements Observer {
     public getSelectedValue(selectFieldId: string): string | string[] {
         for (const p of this.kids) {
             if (p instanceof SelectField && p.isDisplayed && p.id === selectFieldId) {
-                if (! p.multiple) {
+                if (!p.multiple) {
                     const value: string = (p.getValue() as SelectEntry).value;
                     return FormulaireElement.removePrefix(value, selectFieldId + "_");
                 } else {
@@ -359,7 +327,7 @@ export class FieldSet extends FormulaireElement implements Observer {
                     if (senderId === "select_section") {
                         // sections paramétrées, courbes de remous, régimes uniformes
                         // "nodeType" is a property of the section child, not of the parent
-                        const oldNodeType = this.nub.getChildren()[0].properties.getPropValue("nodeType");
+                        const oldNodeType = this.nub.getChildren()[0].getPropValue("nodeType");
                         if (oldNodeType !== data.value.value) { // avoid infinite loops
                             // manually notify parent so that it replaces the child Nub @WARNING clodo trick
                             this.parentForm.update(this, {
@@ -380,9 +348,9 @@ export class FieldSet extends FormulaireElement implements Observer {
                                             const prop = sel.associatedProperty;
                                             // for multiple select
                                             if (Array.isArray(data.value)) {
-                                                this.setNubPropValue(prop, data.value.map((v: any) => v.value));
+                                                this.setPropValue(prop, data.value.map((v: any) => v.value));
                                             } else {
-                                                this.setNubPropValue(prop, data.value.value);
+                                                this.setPropValue(prop, data.value.value);
                                             }
                                         }
                                     }
@@ -394,4 +362,39 @@ export class FieldSet extends FormulaireElement implements Observer {
             }
         }
     }
+
+    // interface IProperties
+
+    /**
+     * list of properties keys
+     */
+    public get keys(): string[] {
+        return this._nub.keys;
+    }
+
+    /**
+     * get associated nub property value
+     * @param key property name
+     * @param inSection if true, will look for the required property in the Nub's section (children[0])
+     */
+    public getPropValue(key: string, inSection: boolean = false): any {
+        if (inSection) {
+            const section = this.nub.getChildren()[0];
+            if (section) {
+                return section.getPropValue(key);
+            }
+            return undefined;
+        }
+        return this.nub.getPropValue(key);
+    }
+
+    /**
+     * assign associated nub property
+     * @param key nub property name
+     * @param val value to assign with
+     * @returns true if property value has changed
+     */
+    public setPropValue(key: string, val: any): boolean {
+        return this.nub.setPropValue(key, val, this);
+    }
 }
diff --git a/src/app/formulaire/elements/select/select-field-device-loi-debit.ts b/src/app/formulaire/elements/select/select-field-device-loi-debit.ts
index 07c1f555a..683adebae 100644
--- a/src/app/formulaire/elements/select/select-field-device-loi-debit.ts
+++ b/src/app/formulaire/elements/select/select-field-device-loi-debit.ts
@@ -34,7 +34,7 @@ export class SelectFieldDeviceLoiDebit extends SelectField {
      */
     private get loiDebit(): LoiDebit {
         const child = this.nub.getChildren()[this.parent.indexAsKid()];
-        return child.properties.getPropValue("loiDebit");
+        return child.getPropValue("loiDebit");
     }
 
     protected populate() {
diff --git a/src/app/formulaire/elements/select/select-field-nub-prop.ts b/src/app/formulaire/elements/select/select-field-nub-prop.ts
index 4fa8c4e86..233502db0 100644
--- a/src/app/formulaire/elements/select/select-field-nub-prop.ts
+++ b/src/app/formulaire/elements/select/select-field-nub-prop.ts
@@ -1,6 +1,5 @@
-import { Session } from "jalhyd";
+import { Props } from "jalhyd";
 import { FormulaireNode } from "../formulaire-node";
-import { SelectEntry } from "./select-entry";
 import { SelectField } from "./select-field";
 
 /*
@@ -27,7 +26,7 @@ export class SelectFieldNubProperty extends SelectField {
 
     protected populate() {
         // find enum associated to property
-        const enumClass = Session.enumFromProperty[this._associatedProperty];
+        const enumClass = Props.enumFromProperty[this._associatedProperty];
         if (enumClass !== undefined) {
             // add one select entry per enum entry, in the enum order
             for (let j = 0; j < Object.keys(enumClass).length / 2; j++) {
-- 
GitLab