From 87162d41736ca6054519506a9484b415e13a9516 Mon Sep 17 00:00:00 2001
From: "mathias.chouet" <mathias.chouet@irstea.fr>
Date: Mon, 25 Mar 2019 09:42:45 +0100
Subject: [PATCH] Fix nghyd#134 check linked parameters targets after loading a
 complex session

---
 src/nub.ts                          | 29 ++++++++++++++++++++++++-----
 src/session.ts                      | 21 +++++++++++++++++++++
 src/structure/parallel_structure.ts | 18 ++++++++++++++++++
 3 files changed, 63 insertions(+), 5 deletions(-)

diff --git a/src/nub.ts b/src/nub.ts
index d0f07ef8..b090c1be 100644
--- a/src/nub.ts
+++ b/src/nub.ts
@@ -450,11 +450,7 @@ export abstract class Nub extends ComputeNode {
                         const destNub = Session.getInstance().findNubByUid(p.targetNub);
                         if (destNub) {
                             param.defineReference(destNub, p.targetParam);
-                        } else {
-                            // @TODO et si la cible du lien n'existe pas ??
-                            // cf FormulaireService.updateParamsLinks()
-                            console.log("LA CIBLE DU LIEN N'EXISTE PAS !!");
-                        }
+                        } // si la cible du lien n'existe pas, Session.fixLinks() est censé s'en occuper
                         break;
 
                     default:
@@ -464,6 +460,29 @@ export abstract class Nub extends ComputeNode {
         }
     }
 
+    /**
+     * Once session is loaded, run a second pass on all linked parameters to
+     * reset their target if needed
+     */
+    public fixLinks(obj: any) {
+        if (obj.parameters && Array.isArray(obj.parameters)) {
+            for (const p of obj.parameters) {
+                const mode: ParamValueMode = (ParamValueMode as any)[p.mode]; // get enum index for string value
+                if (mode === ParamValueMode.LINK) {
+                    const param = this.getParameter(p.symbol);
+                    // formulaire dont le Nub est la cible du lien
+                    const destNub = Session.getInstance().findNubByUid(p.targetNub);
+                    if (destNub) {
+                        param.defineReference(destNub, p.targetParam);
+                    } else {
+                        // quit
+                        console.error("fixLinks : cannot find target Nub");
+                    }
+                }
+            }
+        }
+    }
+
     // overloaded by ParallelStructure
     public hasStructureUid(uid: string): boolean {
         return false;
diff --git a/src/session.ts b/src/session.ts
index 65d4c67b..4a93e4cc 100644
--- a/src/session.ts
+++ b/src/session.ts
@@ -150,6 +150,10 @@ export class Session {
                 }
             });
         }
+
+        // second pass for links
+        this.fixLinks(serialised, uids);
+
         return newNubs;
     }
 
@@ -423,6 +427,23 @@ export class Session {
         return nubPointer;
     }
 
+    /**
+     * Asks all loaded Nubs to relink any parameter that has a wrong target
+     */
+    private fixLinks(serialised: string, uids?: string[]) {
+        const data = JSON.parse(serialised);
+        if (data.session && Array.isArray(data.session)) {
+            // for each Nub representation, create the corresponding Nub in the session
+            data.session.forEach((e: any) => {
+                if (! uids || uids.length === 0 || uids.includes(e.uid)) {
+                    const nub = this.findNubByUid(e.uid);
+                    // find linked parameters
+                    nub.fixLinks(e);
+                }
+            });
+        }
+    }
+
     /**
      * Crée un Nub de type Section
      * @param nt ComputeNodeType
diff --git a/src/structure/parallel_structure.ts b/src/structure/parallel_structure.ts
index 02250171..984fce3b 100644
--- a/src/structure/parallel_structure.ts
+++ b/src/structure/parallel_structure.ts
@@ -340,6 +340,24 @@ export class ParallelStructure extends Nub {
         }
     }
 
+    /**
+     * Once session is loaded, run a second pass on all linked parameters to
+     * reset their target if needed
+     */
+    public fixLinks(obj: any) {
+        // iterate over parameters
+        super.fixLinks(obj);
+
+        // iterate over structures if any
+        if (obj.structures && Array.isArray(obj.structures)) {
+            for (const s of obj.structures) {
+                // get the Nub
+                const subNub = Session.getInstance().findNubByUid(s.uid);
+                subNub.fixLinks(s);
+            }
+        }
+    }
+
     /**
      * paramétrage de la calculabilité des paramètres
      */
-- 
GitLab