From 69bb0a630c26b291c094fa1a1769c44a2d7f305c Mon Sep 17 00:00:00 2001
From: Odei Maiz <33152403+odeimaiz@users.noreply.github.com>
Date: Tue, 20 Aug 2024 16:27:40 +0200
Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20[Frontend]=20Fix=20App=20mode:?=
 =?UTF-8?q?=20Wait=20until=20the=20workbench=20is=20deserialized=20to=20st?=
 =?UTF-8?q?art=20(#6214)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../class/osparc/desktop/StudyEditor.js       | 137 ++++++++++--------
 .../source/class/osparc/viewer/NodeViewer.js  |  56 +++----
 2 files changed, 103 insertions(+), 90 deletions(-)

diff --git a/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js b/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js
index 02f7604615d..dc61d5202f8 100644
--- a/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js
+++ b/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js
@@ -169,70 +169,16 @@ qx.Class.define("osparc.desktop.StudyEditor", {
           this.__workbenchView.setStudy(study);
           this.__slideshowView.setStudy(study);
 
-          this.__attachSocketEventHandlers();
-
-          study.initStudy();
-
-          if (osparc.product.Utils.hasIdlingTrackerEnabled()) {
-            this.__startIdlingTracker();
-          }
-
-          // Count dynamic services.
-          // If it is larger than PROJECTS_MAX_NUM_RUNNING_DYNAMIC_NODES, dynamics won't start -> Flash Message
-          const maxNumber = osparc.store.StaticInfo.getInstance().getMaxNumberDyNodes();
-          const dontCheck = study.getDisableServiceAutoStart();
-          if (maxNumber && !dontCheck) {
-            const nodes = study.getWorkbench().getNodes();
-            const nDynamics = Object.values(nodes).filter(node => node.isDynamic()).length;
-            if (nDynamics > maxNumber) {
-              let msg = this.tr("The Study contains more than ") + maxNumber + this.tr(" Interactive services.");
-              msg += "<br>";
-              msg += this.tr("Please start them manually.");
-              osparc.FlashMessenger.getInstance().logAs(msg, "WARNING");
-            }
-          }
-
-          osparc.data.Resources.get("organizations")
-            .then(() => {
-              if (osparc.data.model.Study.canIWrite(study.getAccessRights())) {
-                this.__startAutoSaveTimer();
-              } else {
-                const msg = this.self().READ_ONLY_TEXT;
-                osparc.FlashMessenger.getInstance().logAs(msg, "WARNING");
+          // wait until the workbench is deserialized to move to the next step
+          if (study.getWorkbench().isDeserialized()) {
+            this.__initStudy(study);
+          } else {
+            study.getWorkbench().addListener("changeDeserialized", e => {
+              if (e.getData()) {
+                this.__initStudy(study);
               }
-            });
-
-          const pageContext = study.getUi().getMode();
-          switch (pageContext) {
-            case "guided":
-            case "app":
-              this.__slideshowView.startSlides();
-              break;
-            default:
-              this.__workbenchView.openFirstNode();
-              break;
+            }, this);
           }
-          this.addListener("changePageContext", e => {
-            const pageCxt = e.getData();
-            study.getUi().setMode(pageCxt);
-          });
-          this.setPageContext(pageContext);
-
-          const workbench = study.getWorkbench();
-          workbench.addListener("retrieveInputs", e => {
-            const data = e.getData();
-            const node = data["node"];
-            const portKey = data["portKey"];
-            this.__updatePipelineAndRetrieve(node, portKey);
-          }, this);
-
-          workbench.addListener("openNode", e => {
-            const nodeId = e.getData();
-            this.nodeSelected(nodeId);
-          }, this);
-
-          workbench.addListener("updateStudyDocument", () => this.updateStudyDocument());
-          workbench.addListener("restartAutoSaveTimer", () => this.__restartAutoSaveTimer());
         })
         .catch(err => {
           console.error(err);
@@ -255,6 +201,73 @@ qx.Class.define("osparc.desktop.StudyEditor", {
       this.__updatingStudy = 0;
     },
 
+    __initStudy: function(study) {
+      this.__attachSocketEventHandlers();
+
+      study.initStudy();
+
+      if (osparc.product.Utils.hasIdlingTrackerEnabled()) {
+        this.__startIdlingTracker();
+      }
+
+      // Count dynamic services.
+      // If it is larger than PROJECTS_MAX_NUM_RUNNING_DYNAMIC_NODES, dynamics won't start -> Flash Message
+      const maxNumber = osparc.store.StaticInfo.getInstance().getMaxNumberDyNodes();
+      const dontCheck = study.getDisableServiceAutoStart();
+      if (maxNumber && !dontCheck) {
+        const nodes = study.getWorkbench().getNodes();
+        const nDynamics = Object.values(nodes).filter(node => node.isDynamic()).length;
+        if (nDynamics > maxNumber) {
+          let msg = this.tr("The Study contains more than ") + maxNumber + this.tr(" Interactive services.");
+          msg += "<br>";
+          msg += this.tr("Please start them manually.");
+          osparc.FlashMessenger.getInstance().logAs(msg, "WARNING");
+        }
+      }
+
+      osparc.data.Resources.get("organizations")
+        .then(() => {
+          if (osparc.data.model.Study.canIWrite(study.getAccessRights())) {
+            this.__startAutoSaveTimer();
+          } else {
+            const msg = this.self().READ_ONLY_TEXT;
+            osparc.FlashMessenger.getInstance().logAs(msg, "WARNING");
+          }
+        });
+
+      const pageContext = study.getUi().getMode();
+      switch (pageContext) {
+        case "guided":
+        case "app":
+          this.__slideshowView.startSlides();
+          break;
+        default:
+          this.__workbenchView.openFirstNode();
+          break;
+      }
+      this.addListener("changePageContext", e => {
+        const pageCxt = e.getData();
+        study.getUi().setMode(pageCxt);
+      });
+      this.setPageContext(pageContext);
+
+      const workbench = study.getWorkbench();
+      workbench.addListener("retrieveInputs", e => {
+        const data = e.getData();
+        const node = data["node"];
+        const portKey = data["portKey"];
+        this.__updatePipelineAndRetrieve(node, portKey);
+      }, this);
+
+      workbench.addListener("openNode", e => {
+        const nodeId = e.getData();
+        this.nodeSelected(nodeId);
+      }, this);
+
+      workbench.addListener("updateStudyDocument", () => this.updateStudyDocument());
+      workbench.addListener("restartAutoSaveTimer", () => this.__restartAutoSaveTimer());
+    },
+
     __setStudyDataInBackend: function(studyData) {
       this.__studyDataInBackend = osparc.data.model.Study.deepCloneStudyObject(studyData, true);
 
diff --git a/services/static-webserver/client/source/class/osparc/viewer/NodeViewer.js b/services/static-webserver/client/source/class/osparc/viewer/NodeViewer.js
index face09ef10f..94aeb50ef5f 100644
--- a/services/static-webserver/client/source/class/osparc/viewer/NodeViewer.js
+++ b/services/static-webserver/client/source/class/osparc/viewer/NodeViewer.js
@@ -37,39 +37,14 @@ qx.Class.define("osparc.viewer.NodeViewer", {
         const study = new osparc.data.model.Study(studyData);
         this.setStudy(study);
 
-        const startPolling = () => {
-          const node = study.getWorkbench().getNode(nodeId);
-          this.setNode(node);
-
-          node.addListener("retrieveInputs", e => {
-            const data = e.getData();
-            const portKey = data["portKey"];
-            node.retrieveInputs(portKey);
-          }, this);
-
-          node.initIframeHandler();
-
-          const iframeHandler = node.getIframeHandler();
-          if (iframeHandler) {
-            iframeHandler.startPolling();
-            iframeHandler.addListener("iframeChanged", () => this.__iFrameChanged(), this);
-            iframeHandler.getIFrame().addListener("load", () => this.__iFrameChanged(), this);
-            this.__iFrameChanged();
-
-            this.__attachSocketEventHandlers();
-          } else {
-            console.error(node.getLabel() + " iframe handler not ready");
-          }
-        }
-
         if (study.getWorkbench().isDeserialized()) {
-          startPolling();
+          this.__initStudy(study, nodeId);
         } else {
           study.getWorkbench().addListener("changeDeserialized", e => {
             if (e.getData()) {
-              startPolling();
+              this.__initStudy(study, nodeId);
             }
-          });
+          }, this);
         }
       })
       .catch(err => console.error(err));
@@ -90,6 +65,31 @@ qx.Class.define("osparc.viewer.NodeViewer", {
   },
 
   members: {
+    __initStudy: function(study, nodeId) {
+      const node = study.getWorkbench().getNode(nodeId);
+      this.setNode(node);
+
+      node.addListener("retrieveInputs", e => {
+        const data = e.getData();
+        const portKey = data["portKey"];
+        node.retrieveInputs(portKey);
+      }, this);
+
+      node.initIframeHandler();
+
+      const iframeHandler = node.getIframeHandler();
+      if (iframeHandler) {
+        iframeHandler.startPolling();
+        iframeHandler.addListener("iframeChanged", () => this.__iFrameChanged(), this);
+        iframeHandler.getIFrame().addListener("load", () => this.__iFrameChanged(), this);
+        this.__iFrameChanged();
+
+        this.__attachSocketEventHandlers();
+      } else {
+        console.error(node.getLabel() + " iframe handler not ready");
+      }
+    },
+
     __iFrameChanged: function() {
       this._removeAll();