From 45248a483ef0b8d169d0651ed188f7bd5ed5e252 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Fri, 2 Nov 2018 10:39:42 +0100
Subject: [PATCH] allow to use functions manipulating column data

---
 frontend-js/src/main/js/Functions.js          |  4 ++
 frontend-js/src/main/js/GuiConnector.js       |  2 +-
 .../main/js/gui/export/AbstractExportPanel.js | 18 +++++--
 .../main/js/gui/export/ElementExportPanel.js  | 51 +++++++++++++------
 .../js/gui/export/ElementExportPanel-test.js  | 20 +++++++-
 5 files changed, 72 insertions(+), 23 deletions(-)

diff --git a/frontend-js/src/main/js/Functions.js b/frontend-js/src/main/js/Functions.js
index 2eefe04ecd..87849f8e7b 100644
--- a/frontend-js/src/main/js/Functions.js
+++ b/frontend-js/src/main/js/Functions.js
@@ -738,6 +738,10 @@ Functions.prototype.computeMD5 = function (s) {
   return i.toLowerCase()
 };
 
+Functions.prototype.isString = function (value) {
+  return (value instanceof String || typeof value === "string");
+};
+
 var singleton = new Functions();
 
 module.exports = singleton;
diff --git a/frontend-js/src/main/js/GuiConnector.js b/frontend-js/src/main/js/GuiConnector.js
index dfaa7c33f6..2f74cd06eb 100644
--- a/frontend-js/src/main/js/GuiConnector.js
+++ b/frontend-js/src/main/js/GuiConnector.js
@@ -186,7 +186,7 @@ GuiConnector.prototype.updateMouseCoordinates = function (x, y) {
 
 /**
  *
- * @param {string} messageText
+ * @param {string} [messageText]
  */
 GuiConnector.prototype.showProcessing = function (messageText) {
   var self = returnThisOrSingleton(this);
diff --git a/frontend-js/src/main/js/gui/export/AbstractExportPanel.js b/frontend-js/src/main/js/gui/export/AbstractExportPanel.js
index ceb70d95de..2b44db9912 100644
--- a/frontend-js/src/main/js/gui/export/AbstractExportPanel.js
+++ b/frontend-js/src/main/js/gui/export/AbstractExportPanel.js
@@ -10,6 +10,14 @@ var Functions = require('../../Functions');
 var DualListbox = require('dual-listbox').DualListbox;
 var Promise = require("bluebird");
 
+/**
+ * @typedef {Object} ExportColumn
+ * @property {string} columnName
+ * @property {string|function(BioEntity):Promise<string>} method
+ * @property {string} name
+ * @property {function(Object):string} formatFunction
+ */
+
 /**
  *
  * @param {Configuration} [params.configuration]
@@ -59,7 +67,7 @@ function compareSimple(val1, val2) {
  *
  * @param annotations
  * @returns {HTMLElement}
- * @private
+ * @protected
  */
 AbstractExportPanel.prototype._createMiriamTypeDiv = function (annotations) {
   var self = this;
@@ -128,7 +136,7 @@ AbstractExportPanel.prototype.createDualListbox = function (selectElement) {
  *
  * @param {BioEntityType[]} elementTypes
  * @returns {HTMLElement}
- * @private
+ * @protected
  */
 AbstractExportPanel.prototype._createSelectTypeDiv = function (elementTypes) {
   var typeDiv = Functions.createElement({
@@ -238,7 +246,7 @@ AbstractExportPanel.prototype._createSelectColumnDiv = function (columnTypes) {
     var row = Functions.createElement({
       type: "li",
       content: "<div class=\"checkbox\"><label> <input type=\"checkbox\" name=\"column_" + columnType.columnName
-      + "\" value=\"" + columnType.columnName + "\" />" + columnType.name + "</label></div>",
+        + "\" value=\"" + columnType.columnName + "\" />" + columnType.name + "</label></div>",
       xss: false
     });
     choicesContainer.appendChild(row);
@@ -270,7 +278,7 @@ AbstractExportPanel.prototype.getSelectedMiriamTypes = function () {
 
 /**
  *
- * @returns {Promise}
+ * @returns {Promise<ExportColumn[]>}
  */
 AbstractExportPanel.prototype.getSelectedColumns = function () {
   var self = this;
@@ -562,7 +570,7 @@ AbstractExportPanel.prototype.getSelectedExcludedCompartments = function () {
 
 /**
  *
- * @param {{name:string}[]} columns
+ * @param {ExportColumn[]} columns
  * @param {MiriamType[]} miriamTypes
  * @returns {Promise<string>}
  */
diff --git a/frontend-js/src/main/js/gui/export/ElementExportPanel.js b/frontend-js/src/main/js/gui/export/ElementExportPanel.js
index 3bd7a1f563..7a9c8489d7 100644
--- a/frontend-js/src/main/js/gui/export/ElementExportPanel.js
+++ b/frontend-js/src/main/js/gui/export/ElementExportPanel.js
@@ -4,6 +4,7 @@
 
 var AbstractExportPanel = require('./AbstractExportPanel');
 var GuiMessageError = require('../GuiMessageError');
+var Functions = require('../../Functions');
 
 var logger = require('../../logger');
 
@@ -117,7 +118,7 @@ ElementExportPanel.prototype.createResponseString = function () {
     for (var i = 0; i < elements.length; i++) {
       rowPromises.push(self.createResponseRow(elements[i], selectedColumns, miriamTypes));
     }
-    return Promise.all(rowPromises).then(function(rows){
+    return Promise.all(rowPromises).then(function (rows) {
       return rows.join("\n");
     });
   });
@@ -125,27 +126,43 @@ ElementExportPanel.prototype.createResponseString = function () {
 
 /**
  *
- * @param {Alias} alias
- * @param {Array} columns
- * @param {MiriamType[]} miriamTypes
+ * @param {BioEntity} alias
+ * @param column
  * @returns {Promise<string>}
+ * @private
  */
-ElementExportPanel.prototype.createResponseRow = function (alias, columns, miriamTypes) {
-  var stringBuilder = [];
-  var i, value;
-  for (i = 0; i < columns.length; i++) {
-    var column = columns[i];
-    value = alias[column.method]();
+ElementExportPanel.prototype._createResponseCell = function (alias, column) {
+  var valuePromise;
+  if (Functions.isString(column.method)) {
+    valuePromise = Promise.resolve(alias[column.method]());
+  } else {
+    valuePromise = Promise.resolve(column.method(alias));
+  }
+  return valuePromise.then(function (value) {
     if (column.formatFunction !== undefined) {
       value = column.formatFunction(value);
     }
-    if (value instanceof String || typeof value === "string") {
+    if (Functions.isString(value)) {
       value = value.replace(/[\n\r]/g, ' ');
     }
-    stringBuilder.push(value);
+    return value;
+  });
+};
+/**
+ *
+ * @param {Alias} alias
+ * @param {Array} columns
+ * @param {MiriamType[]} miriamTypes
+ * @returns {Promise<string>}
+ */
+ElementExportPanel.prototype.createResponseRow = function (alias, columns, miriamTypes) {
+  var valuePromises = [];
+  var i;
+  for (i = 0; i < columns.length; i++) {
+    valuePromises.push(this._createResponseCell(alias, columns[i]));
   }
   for (i = 0; i < miriamTypes.length; i++) {
-    value = "";
+    var value = "";
     var miriamType = miriamTypes[i];
     var references = alias.getReferences();
     for (var j = 0; j < references.length; j++) {
@@ -154,14 +171,16 @@ ElementExportPanel.prototype.createResponseRow = function (alias, columns, miria
         value += reference.getResource() + ",";
       }
     }
-    stringBuilder.push(value);
+    valuePromises.push(value);
   }
-  return Promise.resolve(stringBuilder.join("\t"));
+  return Promise.all(valuePromises).then(function (values) {
+    return values.join("\t");
+  });
 };
 
 /**
  *
- * @returns {*[]}
+ * @returns {ExportColumn[]}
  */
 ElementExportPanel.prototype.getAllColumns = function () {
   return [{
diff --git a/frontend-js/src/test/js/gui/export/ElementExportPanel-test.js b/frontend-js/src/test/js/gui/export/ElementExportPanel-test.js
index d77073641a..03cddb2805 100644
--- a/frontend-js/src/test/js/gui/export/ElementExportPanel-test.js
+++ b/frontend-js/src/test/js/gui/export/ElementExportPanel-test.js
@@ -283,10 +283,28 @@ describe('ElementExportPanel', function () {
       var alias = helper.createAlias();
       var desc = "test\ntest2\n";
       alias.setDescription(desc);
-      return exportObject.createResponseRow(alias, exportObject.getAllColumns(), []).then (function(rowString){
+      return exportObject.createResponseRow(alias, exportObject.getAllColumns(), []).then(function (rowString) {
         assert.ok(rowString.indexOf("test\ntest2\n") === -1);
       });
     });
+    it('column with function manipulating data', function () {
+      var exportObject = new ElementExportPanel({
+        element: testDiv,
+        project: helper.createProject(),
+        configuration: helper.getConfiguration()
+      });
+      var alias = helper.createAlias();
+      return exportObject.createResponseRow(alias, [{
+        "columnName": "id",
+        "method": function (alias) {
+          return "Alias id: " + alias.getId();
+        },
+        "name": "Id"
+      }], []).then(function (rowString) {
+        assert.ok(rowString.indexOf("Alias id") >= 0);
+        assert.ok(rowString.indexOf(alias.getId() + "") >= 0);
+      });
+    });
   });
 
 });
-- 
GitLab