Skip to content
Snippets Groups Projects
AddOverlayDialog.js 10.6 KiB
Newer Older
"use strict";

/* exported logger */
var $ = require('jquery');

var AbstractGuiElement = require('./AbstractGuiElement');
var GuiConnector = require('../GuiConnector');
var GuiUtils = require('./leftPanel/GuiUtils');
var DataOverlay = require('../map/data/DataOverlay');
var NetworkError = require('../NetworkError');
var SecurityError = require('../SecurityError');

var OverlayParser = require('../map/OverlayParser');

var Functions = require('../Functions');
// noinspection JSUnusedLocalSymbols
var logger = require('../logger');
var HttpStatus = require('http-status-codes');

var Promise = require("bluebird");
var TextEncoder = require('text-encoding').TextEncoder;

/**
 *
 * @param {Object} params
 * @param {HTMLElement} params.element
 * @param {CustomMap} params.customMap
 * @param {Configuration} params.configuration
 * @param {Project} params.project
 * @param {ServerConnector} [params.serverConnector]
 *
 * @constructor
 *
 * @extends AbstractGuiElement
 */
function AddOverlayDialog(params) {
  AbstractGuiElement.call(this, params);
  var self = this;
  self.registerListenerType("onAddOverlay");
  self.createGui();
}

AddOverlayDialog.prototype = Object.create(AbstractGuiElement.prototype);
AddOverlayDialog.prototype.constructor = AddOverlayDialog;

/**
 *
 */
AddOverlayDialog.prototype.createGui = function () {
  var self = this;
  var guiUtils = new GuiUtils(self.getConfiguration());
  var content = document.createElement("div");
  content.style.width = "100%";
  content.style.height = "100%";
  content.appendChild(guiUtils.createLabel("Name: "));
  var nameInput = Functions.createElement({
    type: "input",
    inputType: "text",
    name: "overlay-name"
  });
  content.appendChild(nameInput);
  content.appendChild(guiUtils.createNewLine());

  content.appendChild(guiUtils.createLabel("Description: "));
  content.appendChild(guiUtils.createNewLine());
  var descriptionInput = Functions.createElement({
    type: "textarea",
    name: "overlay-description"
  });
  content.appendChild(descriptionInput);
  content.appendChild(guiUtils.createNewLine());

  content.appendChild(guiUtils.createLabel("Type: "));
  content.appendChild(guiUtils.createNewLine());
  var types = self.getConfiguration().getOverlayTypes();
  var typeSelect = Functions.createElement({
    type: "select",
    name: "overlay-type",
    value: types[0]
  });
  for (var i = 0; i < types.length; i++) {
    $(typeSelect).append($('<option>', {
      value: types[i],
      text: types[i]
    }));
  }

  content.appendChild(typeSelect);
  content.appendChild(guiUtils.createNewLine());

  content.appendChild(guiUtils.createLabel("Upload file: "));
  var fileInput = Functions.createElement({
    type: "input",
    inputType: "file",
    name: "overlay-file"
  });
  fileInput.addEventListener("change", function () {
Piotr Gawron's avatar
Piotr Gawron committed
    return self.processFile(fileInput.files[0]).catch(GuiConnector.alert);
  }, false);
  content.appendChild(fileInput);
  content.appendChild(guiUtils.createNewLine());

  content.appendChild(guiUtils.createLabel("Or provide list of elements here (one per line): "));
  content.appendChild(guiUtils.createNewLine());
  var contentInput = Functions.createElement({
    type: "textarea",
    name: "overlay-content"
  });
  content.appendChild(contentInput);
  content.appendChild(guiUtils.createNewLine());

  if (self.getProject().getMapCanvasType() === "GOOGLE_MAPS_API") {
    var consentCheckbox = Functions.createElement({
      type: "input",
      name: "overlay-google-consent",
      inputType: "checkbox"
    });
    content.appendChild(consentCheckbox);
    content.appendChild(guiUtils.createLabel("I am aware that if this map is displayed using Google Maps API, " +
      "it falls under their license <a href='https://cloud.google.com/maps-platform/terms/' target='_blank'>" +
      "https://cloud.google.com/maps-platform/terms/</a>, to which I agree. I warrant that this dataset contains no " +
      "Protected Health Information (as defined in and subject to HIPAA)."));

    content.appendChild(guiUtils.createNewLine());
  }

  self.getElement().appendChild(content);
};

/**
 *
 * @param file
 * @returns {Promise}
 */
AddOverlayDialog.prototype.processFile = function (file) {
  var self = this;
  self.setFileContent(null);
  if (file) {
    return new Promise(function (resolve, reject) {
      var reader = new FileReader();
      reader.readAsArrayBuffer(file);
      reader.onload = function (evt) {
        try {
          var overlayParser = new OverlayParser();
          self.setFileContent(evt.target.result);
          var overlay = overlayParser.parse(evt.target.result);
          var nameInput = $("[name='overlay-name']", self.getElement())[0];
          var descriptionInput = $("[name='overlay-description']", self.getElement())[0];
          if (overlay.getName() !== undefined) {
            nameInput.value = overlay.getName();
          } else {
            var filename = $("[name='overlay-file']", self.getElement())[0].value;
            if (filename.indexOf(".") > 0) {
              filename = filename.substr(0, filename.indexOf("."));
            }
            if (filename.lastIndexOf("\\") >= 0) {
              filename = filename.substr(filename.lastIndexOf("\\") + 1);
            }
            nameInput.value = filename;

          }
          if (overlay.getDescription() !== undefined) {
            descriptionInput.value = overlay.getDescription();
          }
          var typeSelect = $("[name='overlay-type']", self.getElement())[0];
          $(typeSelect).attr("disabled", false);
          if (overlay.getType() !== undefined) {
            if ($("option[value='" + overlay.getType() + "']", typeSelect).length === 0) {
              GuiConnector.warn("Invalid type: " + overlay.getType());
            } else {
              $(typeSelect).attr("disabled", true);
            self.setType(overlay.getType());
          } else {
            self.setType("GENERIC");
          if (overlayParser.containsMixedNewLineCharacters(evt.target.result)) {
            GuiConnector.warn("Selected file contains new line characters from different operating systems " +
              "(MAC/Windows/Linux). This might cause confusion when reading the file in the editor later on.")
          }
          resolve(self.getFileContent());
        } catch (error) {
          reject(error);
        }
      };
      reader.onerror = function () {
        reject(new Error("Problem reading file"));
      };
    });
  } else {
    return Promise.resolve(null);
  }
};

 * @param {?null|string} fileContent
AddOverlayDialog.prototype.setFileContent = function (fileContent) {
  if (typeof fileContent === 'string' || fileContent instanceof String) {
    fileContent = new TextEncoder("UTF8").encode(fileContent);
  }

  this._fileContent = fileContent;
};

/**
 *
 * @returns {string|null}
 */
AddOverlayDialog.prototype.getFileContent = function () {
  var self = this;
  var contentInput = $("[name='overlay-content']", self.getElement())[0];

  if (contentInput.value !== undefined && contentInput.value !== null) {
    contentInput.value = contentInput.value.trim();
    if (contentInput.value !== "") {
      self.setFileContent(contentInput.value);
    }
  }
  if (self._fileContent === undefined) {
    return null;
  } else {
    return self._fileContent;
  }
};

/**
 *
 * @returns {Promise}
 */
AddOverlayDialog.prototype.init = function () {
  return Promise.resolve();
};

/**
 *
 * @returns {Promise}
 */
AddOverlayDialog.prototype.addOverlay = function () {
  var self = this;
  var nameInput = $("[name='overlay-name']", self.getElement())[0];
  var descriptionInput = $("[name='overlay-description']", self.getElement())[0];
  var filename = $("[name='overlay-file']", self.getElement())[0].value;
  var type = $("[name='overlay-type']", self.getElement()).val();
  var consent = $("[name='overlay-google-consent']", self.getElement()).is(":checked");
  var overlay = new DataOverlay({
    name: nameInput.value,
    description: descriptionInput.value,
    filename: filename,
    googleLicenseConsent: consent,
    type: type
  });

  if (filename === undefined || filename === "") {
    filename = "unknown.txt";
  }
  GuiConnector.showProcessing();
  return self.getServerConnector().uploadFile({
    filename: filename,
    content: self.getFileContent()
  }).then(function (file) {
    return self.getServerConnector().addOverlay({
      fileId: file.id,
      overlay: overlay,
      projectId: self.getProject().getProjectId()
    });
  }).then(function (result) {
    overlay = result;
    GuiConnector.hideProcessing();
    return self.callListeners("onAddOverlay", overlay);
  });
};

/**
 *
 * @returns {PromiseLike}
 */
AddOverlayDialog.prototype.destroy = function () {
  $(this.getElement()).dialog("destroy");
  return Promise.resolve();
};

AddOverlayDialog.prototype.open = function () {
  var self = this;
  var div = self.getElement();
  if (!$(div).hasClass("ui-dialog-content")) {
    var buttons = [{
      text: "UPLOAD",
      click: function () {
        var dialog = this;
        var fileContent = self.getFileContent();
        if (fileContent === null) {
          GuiConnector.alert("Neither file was selected nor data was entered");
        } else {
          return self.addOverlay().then(function (result) {
            $(dialog).dialog("close");
            return result;
Piotr Gawron's avatar
Piotr Gawron committed
          }).catch(function (error) {
            GuiConnector.hideProcessing();
            if (error instanceof NetworkError && error.statusCode === HttpStatus.BAD_REQUEST) {
Piotr Gawron's avatar
Piotr Gawron committed
              $("[name='overlay-file']", self.getElement()).val("");
              var errorMessage = JSON.parse(error.content);
              GuiConnector.alert("Problematic input: <br/>" + errorMessage.reason);
Piotr Gawron's avatar
Piotr Gawron committed
              GuiConnector.alert("You cannot add more overlays, Custom Overlay limit is reached.");
            } else {
              GuiConnector.alert(error);
            }
          });
        }
      }
    }, {
      text: "CANCEL",
      click: function () {
        $(this).dialog("close");
      }
    }];

    $(div).dialog({
      dialogClass: 'minerva-add-overlay-dialog',
      title: "Add overlay",
      buttons: buttons,
      modal: true
    });
  }

  $(div).dialog("open");
};

/**
 *
 * @param {string} type
 */
AddOverlayDialog.prototype.setType = function (type) {
  var self = this;
  if (type !== undefined) {
    var typeSelect = $("[name='overlay-type']", self.getElement());
    typeSelect.val(type);
  }
};

/**
 *
 * @return {string}
 */
AddOverlayDialog.prototype.getType = function () {
  var self = this;
  return $("[name='overlay-type']", self.getElement()).val();
};
module.exports = AddOverlayDialog;