Commit 6dba4a2a authored by Piotr Gawron's avatar Piotr Gawron
Browse files

comments functionality works via API

parent 84e943c9
......@@ -690,6 +690,21 @@ ServerConnector.readFile = function(url) {
});
};
ServerConnector.sendPostRequest = function(url, params) {
return new Promise(function(resolve, reject) {
request.post({url:url, form:params}, function(error, response, body) {
if (error) {
reject(error);
} else if (response.statusCode !== 200) {
reject(response);
} else {
resolve(body);
}
});
});
};
ServerConnector.getToken = function() {
var self = this;
return new Promise(function(resolve) {
......@@ -738,8 +753,11 @@ ServerConnector.getApiUrl = function(paramObj) {
var type = paramObj.type;
var method = paramObj.method;
var params = this.createGetParams(paramObj.params);
var result = this.getApiBaseUrl() + "/"+type+"/"+method+"?"+params;
var result = this.getApiBaseUrl() + "/"+type+"/"+method;
if (params!=="") {
result+="?"+params;
}
return result;
};
......@@ -754,6 +772,12 @@ ServerConnector.getProjectUrl = function(projectId, token) {
});
};
ServerConnector.addCommentUrl = function() {
return this.getApiUrl({type:"comment",
method: "addComment",
});
};
ServerConnector.getOverlaysUrl = function(projectId, token) {
return this.getApiUrl({type:"overlay",
method: "getOverlayList",
......@@ -807,9 +831,12 @@ ServerConnector.getOverlayElementsUrl = function(overlayId, projectId, token) {
ServerConnector.idsToString = function (ids) {
var result = "";
if (ids!==undefined) {
ids.sort(function(a, b){return a-b});
for (var i = 0; i < ids.length; i++) {
if (result !== "") {
result = result + "," + ids[i];
if (ids[i-1]!=ids[i]) {
result = result + "," + ids[i];
} // we ignore duplicates
} else {
result = ids[i];
}
......@@ -818,6 +845,10 @@ ServerConnector.idsToString = function (ids) {
return result;
};
ServerConnector.pointToString = function (point) {
return point.x+","+point.y;
};
ServerConnector.columnsToString = function (columns) {
if (columns === undefined) {
return "";
......@@ -865,6 +896,21 @@ ServerConnector.getConfigurationUrl = function(token) {
});
return result;
};
ServerConnector.getClosestElementsByCoordinatesUrl = function(params) {
var coordinates = this.pointToString(params.coordinates);
var projectId = params.projectId;
var modelId = params.modelId;
var token = params.token;
return this.getApiUrl({type:"project",
method:"getClosestElementsByCoordinates",
params: {
projectId: projectId,
coordinates: coordinates,
modelId: modelId,
token: token},
});
};
ServerConnector.getConfigurationParam = function(paramId) {
var self = this;
......@@ -1078,4 +1124,51 @@ ServerConnector.getSessionData = function() {
}
return this._sessionData;
};
ServerConnector.getClosestElementsByCoordinates = function(params) {
var self = this;
var projectId;
return new Promise(function(resolve, reject) {
return self.getProjectId(params.projectId).then(function(result) {
projectId = result;
return self.getToken();
}).then(function(token) {
return self.readFile(self.getClosestElementsByCoordinatesUrl({projectId:projectId, token:token, modelId:params.modelId, coordinates: params.coordinates}));
}).then(function(content) {
var array=JSON.parse(content);
var result = [];
for (var i = 0; i < array.length; i++) {
result.push(new IdentifiedElement(array[i]));
}
resolve(result);
}).catch(function(exception){
reject(exception);
});
});
};
ServerConnector.addComment = function(params) {
var self = this;
var projectId;
return new Promise(function(resolve, reject) {
return self.getProjectId(params.projectId).then(function(result) {
params.projectId = result;
return self.getToken();
}).then(function(token) {
params.token = token;
params.coordinates =self.pointToString(params.coordinates);
return self.sendPostRequest(self.addCommentUrl(),params);
}).then(function(content) {
var response=JSON.parse(content);
if (response.status==="OK") {
resolve();
} else {
reject(response);
}
}).catch(function(exception){
reject(exception);
});
});
};
module.exports = ServerConnector;
"use strict";
var Promise = require("bluebird");
var Alias = require('../map/data/Alias');
var Reaction = require('../map/data/Reaction');
var logger = require('../logger');
var Functions = require('../Functions');
function CommentDialog(element, customMap) {
var self = this;
this.setElement(element);
this.setMap(customMap);
var table = document.createElement('table');
var typeLabel = document.createElement('label');
typeLabel.innerHTML = "Type";
var typeOptions = document.createElement("select");
this.setTypeOptions(typeOptions);
table.appendChild(createRow([ typeLabel, typeOptions ]));
var detailDiv = document.createElement('div');
table.appendChild(createRow([ document.createElement('div'), detailDiv ]));
var pinnedLabel = document.createElement('label');
pinnedLabel.innerHTML = "Pinned";
var pinnedCheckbox = document.createElement('input');
pinnedCheckbox.type = "checkbox";
table.appendChild(createRow([ pinnedLabel, pinnedCheckbox ]));
this.setPinnedCheckbox(pinnedCheckbox);
var nameLabel = document.createElement('label');
nameLabel.innerHTML = "Name:<br/>(Visible to moderators only)";
var nameInput = document.createElement('input');
nameInput.type = "text";
table.appendChild(createRow([ nameLabel, nameInput ]));
this.setNameInput(nameInput);
nameInput.onchange = function(el) {
logger.debug(nameInput.value);
}
var emailLabel = document.createElement('label');
emailLabel.innerHTML = "Email:<br/>(Visible to moderators only)";
var emailInput = document.createElement('input');
emailInput.type = "text";
table.appendChild(createRow([ emailLabel, emailInput ]));
this.setEmailInput(emailInput);
var contentLabel = document.createElement('label');
contentLabel.innerHTML = "Content:";
var contentInput = document.createElement('textarea');
contentInput.cols = "80";
contentInput.rows = "3";
table.appendChild(createRow([ contentLabel, contentInput ]));
this.setContentInput(contentInput);
var sendButton = document.createElement('button');
sendButton.innerHTML = "Send";
sendButton.onclick = function() {
self.addComment().then(function() {
if (self.close !== undefined) {
self.close();
} else {
logger.warn("Cannot close dialog");
}
});
}
table.appendChild(createRow([ sendButton ]));
element.appendChild(table);
typeOptions.onchange = function() {
var option = self.getSelectedType();
var text = "";
if (option instanceof Alias) {
if (option.getFullName() !== undefined) {
text = option.getFullName();
}
} else if (option instanceof Reaction) {
text = "Reactants: ";
var reactants = option.getReactants();
for (var i = 0; i < reactants.length; i++) {
text += reactants[i].getName() + ",";
}
text += "<br/>";
text += "Modifiers: ";
var modifiers = option.getModifiers();
for (var i = 0; i < modifiers.length; i++) {
text += modifiers[i].getName() + ",";
}
text += "<br/>";
text += "Products: ";
var products = option.getProducts();
for (var i = 0; i < products.length; i++) {
text += products[i].getName() + ",";
}
text += "<br/>";
}
detailDiv.innerHTML = text;
};
}
CommentDialog.GENERAL = "<General>";
function createRow(elements) {
var row = document.createElement('tr');
for (var i = 0; i < elements.length; i++) {
var container = document.createElement('td');
container.appendChild(elements[i]);
row.appendChild(container);
}
return row;
};
CommentDialog.prototype.setMap = function(map) {
this._map = map;
}
CommentDialog.prototype.getMap = function() {
return this._map;
}
CommentDialog.prototype.setElement = function(element) {
this._element = element;
}
CommentDialog.prototype.getElement = function() {
return this._element;
}
CommentDialog.prototype.open = function(types) {
var self = this;
self.setTypes([ CommentDialog.GENERAL ]);
var promises = [ CommentDialog.GENERAL ];
for (var i = 0; i < types.length; i++) {
var ie = types[i];
if (ie.getType() === "ALIAS") {
promises.push(self.getMap().getSubmodelById(ie.getModelId()).getModel().getAliasById(ie.getId(), true));
} else if (ie.getType() === "REACTION") {
promises.push(self.getMap().getSubmodelById(ie.getModelId()).getModel().getReactionById(ie.getId(), true));
} else {
throw new Error("Unknown element type: " + ie.getType());
}
}
return Promise.all(promises).then(function(elements) {
self.setTypes(elements);
});
};
CommentDialog.prototype.setTypes = function(types) {
var typeOptions = this.getTypeOptions();
while (typeOptions.firstChild) {
typeOptions.removeChild(typeOptions.firstChild);
}
for (var i = 0; i < types.length; i++) {
var option = document.createElement("option");
option.value = i;
var element = types[i];
var text = element;
if (element instanceof Alias) {
text = element.getType() + ": " + element.getName();
} else if (element instanceof Reaction) {
text = "Reaction: " + element.getReactionId();
}
option.text = text;
typeOptions.appendChild(option);
}
typeOptions.value = 0;
this._types = types;
}
CommentDialog.prototype.getTypes = function() {
return this._types;
};
CommentDialog.prototype.getSelectedType = function() {
return this._types[this.getTypeOptions().value];
};
CommentDialog.prototype.setSelectedType = function(value) {
if (Functions.isInt(value)) {
this.getTypeOptions().value = value;
this.getTypeOptions().onchange();
} else {
throw new Error("Unknown value type: " + value)
}
};
CommentDialog.prototype.getTypeOptions = function() {
return this._typeOptions;
};
CommentDialog.prototype.setTypeOptions = function(typeOptions) {
this._typeOptions = typeOptions;
};
CommentDialog.prototype.setContentInput = function(contentInput) {
this._contentInput = contentInput;
};
CommentDialog.prototype.getContentInput = function() {
return this._contentInput;
};
CommentDialog.prototype.setNameInput = function(nameInput) {
this._nameInput = nameInput;
};
CommentDialog.prototype.getNameInput = function() {
return this._nameInput;
};
CommentDialog.prototype.setEmailInput = function(emailInput) {
this._emailInput = emailInput;
};
CommentDialog.prototype.getEmailInput = function() {
return this._emailInput;
};
CommentDialog.prototype.setPinnedCheckbox = function(pinnedCheckbox) {
this._pinnedCheckbox = pinnedCheckbox;
};
CommentDialog.prototype.getPinnedCheckbox = function() {
return this._pinnedCheckbox;
};
CommentDialog.prototype.getTypes = function(types) {
return this._types;
};
CommentDialog.prototype.getName = function() {
return this.getNameInput().value;
};
CommentDialog.prototype.getEmail = function() {
return this.getEmailInput().value;
};
CommentDialog.prototype.getContent = function() {
return this.getContentInput().value;
};
CommentDialog.prototype.isPinned = function() {
return this.getPinnedCheckbox().checked;
};
CommentDialog.prototype.getSelectedTypeId = function() {
var selected = this.getSelectedType();
if (selected instanceof Alias) {
return selected.getId();
} else if (selected instanceof Reaction) {
return selected.getId();
} else {
return "";
}
};
CommentDialog.prototype.getSelectedTypeClass = function() {
var selected = this.getSelectedType();
if (selected instanceof Alias) {
return "ALIAS";
} else if (selected instanceof Reaction) {
return "REACTION";
} else {
return "POINT";
}
};
CommentDialog.prototype.addComment = function() {
var self = this;
var name = self.getName();
return ServerConnector.addComment({
modelId : self.getMap().getActiveSubmapId(),
coordinates : self.getMap().getActiveSubmapClickCoordinates(),
name : name,
email : self.getEmail(),
content : self.getContent(),
pinned : self.isPinned(),
elementId : self.getSelectedTypeId(),
elementType : self.getSelectedTypeClass()
});
};
module.exports = CommentDialog;
......@@ -317,13 +317,15 @@ AbstractCustomMap.prototype.registerMapClickEvents = function() {
});
// select last clicked map
google.maps.event.addListener(this.getGoogleMap(), 'click', function() {
google.maps.event.addListener(this.getGoogleMap(), 'click', function(mouseEvent) {
customMap.setActiveSubmapId(self.getId());
customMap.setActiveSubmapClickCoordinates(self.fromLatLngToPoint(mouseEvent.latLng));
});
// select last clicked map
google.maps.event.addListener(this.getGoogleMap(), 'rightclick', function() {
google.maps.event.addListener(this.getGoogleMap(), 'rightclick', function(mouseEvent) {
customMap.setActiveSubmapId(self.getId());
customMap.setActiveSubmapClickCoordinates(self.fromLatLngToPoint(mouseEvent.latLng));
});
// prepare for image export
......@@ -356,7 +358,6 @@ AbstractCustomMap.prototype.registerMapClickEvents = function() {
// context menu event
google.maps.event.addListener(this.getGoogleMap(), 'rightclick', function(mouseEvent) {
ServerConnector.requestUpdateCommentList(self.getId(), mouseEvent.latLng);
GuiConnector.showRightClickMenu(GuiConnector.xPos, GuiConnector.yPos);
});
};
......
......@@ -7,6 +7,7 @@ var functions = require('../Functions');
var AbstractCustomMap = require('./AbstractCustomMap');
var AliasMarker = require('./marker/AliasMarker');
var CommentDialog = require('../gui/CommentDialog');
var ControlType = require('./ControlType');
var CustomMapOptions = require('./CustomMapOptions');
var IdentifiedElement = require('./data/IdentifiedElement');
......@@ -83,7 +84,11 @@ function CustomMap(options) {
// list of reference genomes
this._referenceGenome = [];
var commentDialog = new CommentDialog(document.getElementById("feedbackContent"), this);
this.setCommentDialog(commentDialog);
ServerConnector.actualizeSessionData();
}
......@@ -1660,6 +1665,16 @@ CustomMap.prototype.setActiveSubmapId = function(submapId) {
this._activeSubmapId = submapId;
};
CustomMap.prototype.setActiveSubmapClickCoordinates = function(coordinates) {
if (!(coordinates instanceof google.maps.Point)) {
throw new Error("Coordinates must be provided as google.maps.Point object, but found: "+coordinates );
}
this._activeSubmapCoordinates = coordinates;
};
CustomMap.prototype.getActiveSubmapClickCoordinates = function() {
return this._activeSubmapCoordinates;
};
CustomMap.prototype.updateAliasesForLayout = function(layoutId, jsonAliases) {
logger.debug("Updating aliases for layout: " + layoutId);
......@@ -1739,4 +1754,22 @@ CustomMap.prototype.getControl = function(type) {
return this._controls[type];
};
CustomMap.prototype.setCommentDialog = function(commentDialog) {
this._commentDialog = commentDialog;
commentDialog.close = function(){
jsfCommentDialog.hide();
}
};
CustomMap.prototype.getCommentDialog = function() {
return this._commentDialog;
};
CustomMap.prototype.openCommentDialog = function() {
var self = this;
return ServerConnector.getClosestElementsByCoordinates({modelId:this.getActiveSubmapId(), coordinates:this.getActiveSubmapClickCoordinates()}).then(function(elements){
return self.getCommentDialog().open(elements);
});
};
module.exports = CustomMap;
......@@ -110,6 +110,10 @@ Alias.prototype.getName = function() {
return this.name;
};
Alias.prototype.getFullName = function() {
return this.fullName;
};
Alias.prototype.setType = function(type) {
this.type = type;
};
......
......@@ -136,17 +136,18 @@ MapModel.prototype.getAliasById = function(id, complete) {
MapModel.prototype.getCompleteAliasById = function(id) {
var self = this;
return new Promise(function(resolve, reject) {
if (self._aliases[id].isComplete()) {
if (self._aliases[id]!==undefined && self._aliases[id].isComplete()) {
resolve(self._aliases[id]);
} else {
ServerConnector.getAliases([id]).then(function(aliases){
if (self._aliases[id] === undefined) {
self._aliases[id] = aliases[0];
} else {
self._aliases[id] .update(aliases[0]);
}
resolve(self._aliases[id]);
}, reject);
}
ServerConnector.getAliases([id]).then(function(aliases){
if (self._aliases[id] === undefined) {
self._aliases[id] = aliases[0];
} else {
self._aliases[id] .update(aliases[0]);
}
resolve(self._aliases[id]);
}, reject);
});
};
......@@ -157,8 +158,11 @@ MapModel.prototype.getCompleteAliasById = function(id) {
* identifier of the {@link Reaction}
* @returns {@link Reaction} by identifier
*/
MapModel.prototype.getReactionById = function(id) {
MapModel.prototype.getReactionById = function(id, complete) {
var self = this;
if (complete) {
return this.getCompleteReactionById(id);
}
return new Promise(function(resolve, reject) {
if (self._reactions[id] !== undefined) {
resolve(self._reactions[id]);
......@@ -170,6 +174,69 @@ MapModel.prototype.getReactionById = function(id) {
});
};
MapModel.prototype.getCompleteReactionById = function(id) {
var self = this;
return new Promise(function(resolve, reject) {
if (self._reactions[id]!==undefined && self._reactions[id].isComplete()) {
resolve(self._reactions[id]);
} else {
var result;