From 62aedd0d17543c04afc0c280989e6f325f47c49a Mon Sep 17 00:00:00 2001
From: David Dorchies <david.dorchies@inrae.fr>
Date: Tue, 20 Feb 2024 11:50:27 +0000
Subject: [PATCH 1/2] fix(pab): input latency for big pab

- cache linkableValues in ngParam and compute its value only on AfterViewInit

Refs #660
---
 .../param-field-line.component.ts             | 15 +++++---
 .../param-link/param-link.component.ts        |  2 +-
 src/app/formulaire/elements/ngparam.ts        |  7 +++-
 src/app/services/formulaire.service.ts        | 37 +++++++++++--------
 4 files changed, 37 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 43cea6de7..76a2e89dc 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
@@ -1,4 +1,4 @@
-import { Component, ViewChild, Input, Output, EventEmitter, OnChanges } from "@angular/core";
+import { Component, ViewChild, Input, Output, EventEmitter, OnChanges, AfterViewInit } from "@angular/core";
 
 import { I18nService } from "../../services/internationalisation.service";
 import { NgParameter, ParamRadioConfig } from "../../formulaire/elements/ngparam";
@@ -19,7 +19,7 @@ import { ParamValuesComponent } from "../param-values/param-values.component";
         "./param-field-line.component.scss"
     ]
 })
-export class ParamFieldLineComponent implements OnChanges {
+export class ParamFieldLineComponent implements OnChanges, AfterViewInit  {
 
     constructor() {
         this.intlService = ServiceFactory.i18nService;
@@ -193,16 +193,17 @@ export class ParamFieldLineComponent implements OnChanges {
     */
     public hasRadioLink(): boolean {
         if (this._formService.formulaires.length > 0 && !this.isParameterLinkTarget()) {
+            this._formService.getLinkableValues(this.param);
             // au moins 2 modules de calcul ouverts
             if (this._formService.formulaires.length > 1) {
-                return this._formService.getLinkableValues(this.param).length > 0;
+                return this.param.linkableValues.length > 0;
             }
 
             // ou un seul module de calcul "ouvrages parallèles" avec au moins 2 ouvrages
             if (this._formService.formulaires[0].currentNub instanceof ParallelStructure) {
                 const ps: ParallelStructure = this._formService.formulaires[0].currentNub;
                 if (ps.structures.length > 1) {
-                    return this._formService.getLinkableValues(this.param).length > 0;
+                    return this.param.linkableValues.length > 0;
                 }
             }
 
@@ -210,7 +211,7 @@ export class ParamFieldLineComponent implements OnChanges {
             if (this._formService.formulaires[0].currentNub instanceof Pab) {
                 const pab: Pab = this._formService.formulaires[0].currentNub;
                 if (pab.children.length > 1) {
-                    return this._formService.getLinkableValues(this.param).length > 0;
+                    return this.param.linkableValues.length > 0;
                 }
             }
 
@@ -359,6 +360,10 @@ export class ParamFieldLineComponent implements OnChanges {
         this._ngParamInputComponent.showError = this.isRadioFixChecked;
     }
 
+    public ngAfterViewInit() {
+        this._formService.getLinkableValues(this.param, true);
+    }
+
     /**
      * relit la valeur dans l'interface et met à jour le NgParameter
      */
diff --git a/src/app/components/param-link/param-link.component.ts b/src/app/components/param-link/param-link.component.ts
index b62fc1cbc..bf8f08cee 100644
--- a/src/app/components/param-link/param-link.component.ts
+++ b/src/app/components/param-link/param-link.component.ts
@@ -262,7 +262,7 @@ export class ParamLinkComponent implements OnChanges, Observer, OnDestroy {
         let noMoreTarget = false;
         // liste des paramètres liables
         if (this.param.valueMode === ParamValueMode.LINK) {
-            this._linkableParams = this.formService.getLinkableValues(this.param);
+            this._linkableParams = this.formService.getLinkableValues(this.param, true);
             noMoreTarget = this._linkableParams.length === 0;
         } else {
             this._linkableParams = [];
diff --git a/src/app/formulaire/elements/ngparam.ts b/src/app/formulaire/elements/ngparam.ts
index a579f0141..9c030ad57 100644
--- a/src/app/formulaire/elements/ngparam.ts
+++ b/src/app/formulaire/elements/ngparam.ts
@@ -29,6 +29,11 @@ export enum ParamRadioConfig {
  */
 export class NgParameter extends InputField implements Observer {
 
+    /** cache of linkable values for this parameter */
+    public linkableValues: LinkedValue[];
+
+    public disabled: boolean;
+
     /** set to true to disable UI validation on this input */
     private _allowEmpty = false;
 
@@ -41,8 +46,6 @@ export class NgParameter extends InputField implements Observer {
      */
     private _radioConfig: ParamRadioConfig;
 
-    public disabled: boolean;
-
     constructor(private _paramDef: ParamDefinition, parent: FormulaireNode) {
         super(parent);
         this._radioConfig = this.radioState;
diff --git a/src/app/services/formulaire.service.ts b/src/app/services/formulaire.service.ts
index 9053c30d5..8d8139535 100644
--- a/src/app/services/formulaire.service.ts
+++ b/src/app/services/formulaire.service.ts
@@ -769,30 +769,35 @@ export class FormulaireService extends Observable {
      * Demande à la Session JalHYd la liste des paramètres/résultats pouvant être liés au
      * paramètre fourni
      */
-    public getLinkableValues(p: NgParameter): LinkedValue[] {
+    public getLinkableValues(p: NgParameter, update = false): LinkedValue[] {
         let linkableValues: LinkedValue[] = [];
         if (p) {
-            linkableValues = Session.getInstance().getLinkableValues(p.paramDefinition);
-            // join form names to ease usage
-            for (let i = 0; i < linkableValues.length; i++) {
-                const lv = linkableValues[i];
-                for (const f of this._formulaires) {
-                    if (f.currentNub) {
-                        if (f.currentNub.uid === lv.nub.uid) {
-                            lv.meta["formTitle"] = f.calculatorName;
-                        } else {
-                            // child structures ?
-                            for (const s of f.currentNub.getChildren()) {
-                                if (s.uid === lv.nub.uid) {
-                                    lv.meta["formTitle"] = f.calculatorName;
+            if (update || p.linkableValues === undefined) {
+                linkableValues = Session.getInstance().getLinkableValues(p.paramDefinition);
+                // join form names to ease usage
+                for (let i = 0; i < linkableValues.length; i++) {
+                    const lv = linkableValues[i];
+                    for (const f of this._formulaires) {
+                        if (f.currentNub) {
+                            if (f.currentNub.uid === lv.nub.uid) {
+                                lv.meta["formTitle"] = f.calculatorName;
+                            } else {
+                                // child structures ?
+                                for (const s of f.currentNub.getChildren()) {
+                                    if (s.uid === lv.nub.uid) {
+                                        lv.meta["formTitle"] = f.calculatorName;
+                                    }
                                 }
                             }
                         }
                     }
                 }
+                linkableValues = this.filterLinkableValues(linkableValues);
+            } else {
+                linkableValues = p.linkableValues;
             }
         }
-        linkableValues = this.filterLinkableValues(linkableValues);
+        p.linkableValues = linkableValues;
         return linkableValues;
     }
 
@@ -866,7 +871,7 @@ export class FormulaireService extends Observable {
     }
 
     /**
-     * Génère un formulaire SectionParametree à partir du module courant 
+     * Génère un formulaire SectionParametree à partir du module courant
      * s'il est du type régime uniforme ou courbe de remous
      */
     public async generateParametricSectionForm(Y?: number): Promise<FormulaireDefinition> {
-- 
GitLab


From 20bf2f8cc92486b3ff37fdc3a1e0d3ef4df85e5c Mon Sep 17 00:00:00 2001
From: David Dorchies <david.dorchies@inrae.fr>
Date: Tue, 20 Feb 2024 14:47:22 +0000
Subject: [PATCH 2/2] feat: restrict linkable values caching to PAB only

Otherwise test "parallel structures with multiple linked parameters" fails.

Refs #660
---
 src/app/services/formulaire.service.ts | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/app/services/formulaire.service.ts b/src/app/services/formulaire.service.ts
index 8d8139535..ad8d6b1b1 100644
--- a/src/app/services/formulaire.service.ts
+++ b/src/app/services/formulaire.service.ts
@@ -768,10 +768,20 @@ export class FormulaireService extends Observable {
     /**
      * Demande à la Session JalHYd la liste des paramètres/résultats pouvant être liés au
      * paramètre fourni
+     * @param p the parameter on which we look for available links
+     * @param update force calculation instead of using cached linkable values
      */
     public getLinkableValues(p: NgParameter, update = false): LinkedValue[] {
         let linkableValues: LinkedValue[] = [];
         if (p) {
+            if (!(this.currentForm.currentNub instanceof Pab)) {
+                /**
+                 * link caching is only for PAB otherwise link buttons of parallel
+                 * structures are not created/deleted when new structure is
+                 * created/deleted.
+                 */
+                update = true;
+            }
             if (update || p.linkableValues === undefined) {
                 linkableValues = Session.getInstance().getLinkableValues(p.paramDefinition);
                 // join form names to ease usage
-- 
GitLab