From ddb5997e7c678b3d9ae650f8549c0266bb6777a7 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Thu, 24 Aug 2017 16:19:21 +0200
Subject: [PATCH] lazy intialization of publication list dialog

---
 .../js/gui/leftPanel/PublicationListDialog.js | 274 +++++++++---------
 frontend-js/src/main/js/map/CustomMap.js      |  45 +--
 2 files changed, 153 insertions(+), 166 deletions(-)

diff --git a/frontend-js/src/main/js/gui/leftPanel/PublicationListDialog.js b/frontend-js/src/main/js/gui/leftPanel/PublicationListDialog.js
index afd0d2494d..0250e411b1 100644
--- a/frontend-js/src/main/js/gui/leftPanel/PublicationListDialog.js
+++ b/frontend-js/src/main/js/gui/leftPanel/PublicationListDialog.js
@@ -13,161 +13,167 @@ var Functions = require('../../Functions');
 var logger = require('../../logger');
 
 function PublicationListDialog(params) {
-    AbstractGuiElement.call(this, params);
-    var self = this;
-    self.createPublicationListDialogGui();
-    $(self.getElement()).dialog({
-        title: "Publication list",
-        autoOpen: false,
-        resizable: false,
-        width: Math.max(window.innerWidth / 2, window.innerWidth - 100),
-        height: Math.max(window.innerHeight / 2, window.innerHeight - 100),
-    });
+  AbstractGuiElement.call(this, params);
+  var self = this;
+  self.createPublicationListDialogGui();
 }
 
 PublicationListDialog.prototype = Object.create(AbstractGuiElement.prototype);
 PublicationListDialog.prototype.constructor = PublicationListDialog;
 
 PublicationListDialog.prototype.createPublicationListDialogGui = function () {
-    var self = this;
-    var head = Functions.createElement({
-        type: "thead",
-        content: "<tr>" + "<th>Pubmed ID</th>" + //
-        "<th>Title</th>" + //
-        "<th>Authors</th>" + //
-        "<th>Journal</th>" + //
-        "<th>Year</th>" + //
-        "<th>Elements on map</th>" + //
-        "</tr>"//
-    });
-    var body = Functions.createElement({
-        type: "tbody",
-    });
-    var tableElement = Functions.createElement({
-        type: "table",
-        className: "minerva-publication-table",
-        style: "width: 100%",
-    });
-
-    tableElement.appendChild(head);
-    tableElement.appendChild(body);
-
-    self.tableElement = tableElement;
-    self.getElement().appendChild(tableElement);
+  var self = this;
+  var head = Functions.createElement({
+    type: "thead",
+    content: "<tr>" + "<th>Pubmed ID</th>" + //
+    "<th>Title</th>" + //
+    "<th>Authors</th>" + //
+    "<th>Journal</th>" + //
+    "<th>Year</th>" + //
+    "<th>Elements on map</th>" + //
+    "</tr>"//
+  });
+  var body = Functions.createElement({
+    type: "tbody",
+  });
+  var tableElement = Functions.createElement({
+    type: "table",
+    className: "minerva-publication-table",
+    style: "width: 100%",
+  });
+
+  tableElement.appendChild(head);
+  tableElement.appendChild(body);
+
+  self.tableElement = tableElement;
+  self.getElement().appendChild(tableElement);
 };
 
 PublicationListDialog.prototype._dataTableAjaxCall = function (data, callback) {
-    var self = this;
-    return ServerConnector.getPublications({
-        start: data.start,
-        length: data.length,
-        sortColumn: self.getColumnsDefinition()[data.order[0].column].name,
-        sortOrder: data.order[0].dir,
-        search: data.search.value,
-    }).then(function (publicationList) {
-        var out = [];
-        var allElements = [];
-        for (var i = 0; i < publicationList.data.length; i++) {
-            var publication = publicationList.data[i].publication.article;
-            var elements = publicationList.data[i].elements;
-
-            var row = [];
-            row[0] = "<a href='" + publication.link + "'>" + publication.id + "</a>";
-            row[1] = publication.title;
-            row[2] = publication.authors.join();
-            row[3] = publication.journal;
-            row[4] = publication.year;
-            row[5] = "<div>";
-            for (var j = 0; j < elements.length; j++) {
-                row[5] += "<a name='" + elements[j].id + "' href='#'>" + elements[j].type + ":" + elements[j].id + "</a>, ";
-                allElements.push(new IdentifiedElement(elements[j]));
-            }
-            row[5] += "</div>";
-            out.push(row);
+  var self = this;
+  return ServerConnector.getPublications({
+    start: data.start,
+    length: data.length,
+    sortColumn: self.getColumnsDefinition()[data.order[0].column].name,
+    sortOrder: data.order[0].dir,
+    search: data.search.value,
+  }).then(function (publicationList) {
+    var out = [];
+    var allElements = [];
+    for (var i = 0; i < publicationList.data.length; i++) {
+      var publication = publicationList.data[i].publication.article;
+      var elements = publicationList.data[i].elements;
+
+      var row = [];
+      row[0] = "<a href='" + publication.link + "'>" + publication.id + "</a>";
+      row[1] = publication.title;
+      row[2] = publication.authors.join();
+      row[3] = publication.journal;
+      row[4] = publication.year;
+      row[5] = "<div>";
+      for (var j = 0; j < elements.length; j++) {
+        row[5] += "<a name='" + elements[j].id + "' href='#'>" + elements[j].type + ":" + elements[j].id + "</a>, ";
+        allElements.push(new IdentifiedElement(elements[j]));
+      }
+      row[5] += "</div>";
+      out.push(row);
+    }
+    callback({
+      draw: data.draw,
+      recordsTotal: publicationList.totalSize,
+      recordsFiltered: publicationList.filteredSize,
+      data: out,
+    });
+    var promises = [];
+    allElements.forEach(function (element) {
+      var model = self.getMap().getSubmapById(element.getModelId()).getModel();
+      promises.push(model.getByIdentifiedElement(element, true).then(function (elementData) {
+        var name = null;
+        if (elementData instanceof Alias) {
+          name = elementData.getName();
+        } else if (elementData instanceof Reaction) {
+          name = elementData.getReactionId();
         }
-        callback({
-            draw: data.draw,
-            recordsTotal: publicationList.totalSize,
-            recordsFiltered: publicationList.filteredSize,
-            data: out,
-        });
-        var promises = [];
-        allElements.forEach(function (element) {
-            var model = self.getMap().getSubmapById(element.getModelId()).getModel();
-            promises.push(model.getByIdentifiedElement(element, true).then(function (elementData) {
-                var name = null;
-                if (elementData instanceof Alias) {
-                    name = elementData.getName();
-                } else if (elementData instanceof Reaction) {
-                    name = elementData.getReactionId();
-                }
-                $("a[name=" + elementData.getId() + "]", $(self.getElement())).html(name);
-                var onclick = function () {
-                    var searchOverlay = self.getMap().getOverlayByName("search");
-                    var query;
-                    if (element.getType() === "ALIAS") {
-                        query = "element:" + element.getId();
-                    } else {
-                        query = "reaction:" + element.getId();
-                    }
-                    self.getMap().openSubmap(elementData.getModelId());
-                    return searchOverlay.searchByQuery(query, true, true).then(function () {
-                        $(self.getElement()).dialog("close");
-                    }).then(null, GuiConnector.alert);
-                };
-                $("a[name=" + elementData.getId() + "]", $(self.getElement())).click(onclick);
-            }));
-        });
-        return Promise.all(promises);
+        $("a[name=" + elementData.getId() + "]", $(self.getElement())).html(name);
+        var onclick = function () {
+          var searchOverlay = self.getMap().getOverlayByName("search");
+          var query;
+          if (element.getType() === "ALIAS") {
+            query = "element:" + element.getId();
+          } else {
+            query = "reaction:" + element.getId();
+          }
+          self.getMap().openSubmap(elementData.getModelId());
+          return searchOverlay.searchByQuery(query, true, true).then(function () {
+            $(self.getElement()).dialog("close");
+          }).then(null, GuiConnector.alert);
+        };
+        $("a[name=" + elementData.getId() + "]", $(self.getElement())).click(onclick);
+      }));
     });
+    return Promise.all(promises);
+  });
 };
 
 PublicationListDialog.prototype.show = function () {
-    var self = this;
-    $(self.getElement()).dialog("open");
-
-    if (!$.fn.DataTable.isDataTable(self.tableElement)) {
-        return new Promise(function (resolve) {
-            $(self.tableElement).dataTable({
-                serverSide: true,
-                ordering: true,
-                searching: true,
-                ajax: function (data, callback, settings) {
-                    resolve(self._dataTableAjaxCall(data, callback, settings));
-                },
-                columns: self.getColumnsDefinition(),
-            });
-        });
-    } else {
-        return Promise.resolve();
-    }
+  var self = this;
+  if (!$(self.getElement()).hasClass("ui-dialog-content")) {
+    $(self.getElement()).dialog({
+      title: "Publication list",
+      autoOpen: false,
+      resizable: false,
+      width: Math.max(window.innerWidth / 2, window.innerWidth - 100),
+      height: Math.max(window.innerHeight / 2, window.innerHeight - 100),
+    });
+  }
+
+  $(self.getElement()).dialog("open");
+
+  if (!$.fn.DataTable.isDataTable(self.tableElement)) {
+    return new Promise(function (resolve) {
+      $(self.tableElement).dataTable({
+        serverSide: true,
+        ordering: true,
+        searching: true,
+        ajax: function (data, callback, settings) {
+          resolve(self._dataTableAjaxCall(data, callback, settings));
+        },
+        columns: self.getColumnsDefinition(),
+      });
+    });
+  } else {
+    return Promise.resolve();
+  }
 
 };
 
 PublicationListDialog.prototype.getColumnsDefinition = function () {
-    return [{
-        name: "pubmedId"
-    }, {
-        name: "title"
-    }, {
-        name: "authors"
-    }, {
-        name: "journal"
-    }, {
-        name: "year"
-    }, {
-        orderable: false,
-        searchable: false,
-        name: "elemnts"
-    }];
+  return [{
+    name: "pubmedId"
+  }, {
+    name: "title"
+  }, {
+    name: "authors"
+  }, {
+    name: "journal"
+  }, {
+    name: "year"
+  }, {
+    orderable: false,
+    searchable: false,
+    name: "elemnts"
+  }];
 };
 
 PublicationListDialog.prototype.destroy = function () {
-    var self = this;
-    $(self.getElement()).dialog("destroy");
-    if ($.fn.DataTable.isDataTable(self.tableElement)) {
-        $(self.tableElement).DataTable().destroy();
-    }
+  var self = this;
+  var div = self.getElement();
+  if ($(div).hasClass("ui-dialog-content")) {
+    $(div).dialog("destroy");
+  }
+  if ($.fn.DataTable.isDataTable(self.tableElement)) {
+    $(self.tableElement).DataTable().destroy();
+  }
 };
 
 module.exports = PublicationListDialog;
diff --git a/frontend-js/src/main/js/map/CustomMap.js b/frontend-js/src/main/js/map/CustomMap.js
index 5af13d335a..e25f8985da 100644
--- a/frontend-js/src/main/js/map/CustomMap.js
+++ b/frontend-js/src/main/js/map/CustomMap.js
@@ -28,7 +28,7 @@ var TouchMap = require('./TouchMap');
 
 /**
  * Default constructor.
- *
+ * 
  * @param options
  *          CustomMapOptions object representing all parameters needed for map
  *          creation
@@ -75,12 +75,12 @@ CustomMap.prototype.constructor = CustomMap;
 /**
  * This code must be run after the object is created. It requires to download
  * some data via promises.
- *
+ * 
  * @return promise with empty result
  */
-CustomMap.prototype.init = function () {
+CustomMap.prototype.init = function() {
   var self = this;
-  return ServerConnector.getLogoImg().then(function (url) {
+  return ServerConnector.getLogoImg().then(function(url) {
     var logo2 = self.getControl(ControlType.LOGO_2_IMG);
     if (!/^(f|ht)tps?:\/\//i.test(url)) {
       url = GuiConnector.getImgPrefix() + url;
@@ -92,7 +92,7 @@ CustomMap.prototype.init = function () {
 /**
  * Create submaps.
  */
-CustomMap.prototype.createSubmaps = function () {
+CustomMap.prototype.createSubmaps = function() {
   this.submaps = [];
   for (var i = 0; i < this.getModel().getSubmodels().length; i++) {
     this.submaps.push(new Submap(this, this.getModel().getSubmodels()[i]));
@@ -102,7 +102,7 @@ CustomMap.prototype.createSubmaps = function () {
 /**
  * Creates logo and put it on the google map.
  */
-CustomMap.prototype.createLogo = function () {
+CustomMap.prototype.createLogo = function() {
   var logoControlDiv2 = document.createElement('DIV');
   var logo2 = document.createElement('IMG');
   logo2.style.cursor = 'pointer';
@@ -111,8 +111,8 @@ CustomMap.prototype.createLogo = function () {
   this.addControl(logo2);
 
   logoControlDiv2.appendChild(logo2);
-  google.maps.event.addDomListener(logo2, 'click', function () {
-    return ServerConnector.getLogoLink().then(function (url) {
+  google.maps.event.addDomListener(logo2, 'click', function() {
+    return ServerConnector.getLogoLink().then(function(url) {
       var win = window.open(url, '_blank');
       win.focus();
     });
@@ -130,7 +130,7 @@ CustomMap.prototype.createLogo = function () {
   this.addControl(logo);
 
   logoControlDiv.appendChild(logo);
-  google.maps.event.addDomListener(logo, 'click', function () {
+  google.maps.event.addDomListener(logo, 'click', function() {
     var win = window.open('http://wwwen.uni.lu/lcsb/', '_blank');
     win.focus();
   });
@@ -291,7 +291,7 @@ CustomMap.prototype.registerDbOverlay = function (dbOverlay) {
 
 /**
  * Refresh comment list.
- *
+ * 
  * @return promise that is resolved when comment list is refreshed
  */
 CustomMap.prototype.refreshComments = function () {
@@ -480,7 +480,7 @@ CustomMap.prototype.createMapChangedCallbacks = function () {
  *
  * @param identifier
  *          identifier of the submap
- * @returns submap (or this map) with given identfier of the model
+ * @returns AbstractCustomMap (submap or this map) with given identfier of the model
  */
 CustomMap.prototype.getSubmapById = function (identifier) {
   identifier = parseInt(identifier);
@@ -696,26 +696,7 @@ CustomMap.prototype.renderOverlayCollection = function (params) {
   return overlayCollection.getIdentifiedElements().then(function (identifiedElements) {
     elements = identifiedElements;
 
-    var elementsByModelId = [];
-    var modelId;
-
-    for (var i = 0; i < elements.length; i++) {
-      var element = elements[i];
-      modelId = element.getModelId();
-      if (elementsByModelId[modelId] === undefined) {
-        elementsByModelId[modelId] = [];
-      }
-      elementsByModelId[modelId].push(element);
-    }
-    var promises = [];
-    for (modelId in elementsByModelId) {
-      if (elementsByModelId.hasOwnProperty(modelId)) {
-        promises.push(self.getModel().getSubmodelById(parseInt(modelId)).getByIdentifiedElements(elementsByModelId[modelId], false));
-      }
-    }
-    return Promise.all(promises);
-  }).then(function () {
-    return Promise.each(elements, function (element) {
+    return Promise.each(elements, function(element) {
       var icon = element.getIcon();
       if (icon !== null && icon !== undefined) {
         return self.createMarkerForDbOverlay(element, overlayCollection).then(function (marker) {
@@ -1239,7 +1220,7 @@ CustomMap.prototype.destroy = function () {
     commentDialog.destroy();
   }
   var submaps = self.getSubmaps();
-  for (var i=0;i<submaps.length;i++) {
+  for (var i = 0; i < submaps.length; i++) {
     submaps[i].destroy();
   }
 };
-- 
GitLab