Commit b63e98d1 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

publication list can be exported to CSV

parent 5b67811f
......@@ -1167,6 +1167,14 @@
"cssom": "0.3.2"
}
},
"csv-stringify": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-4.3.1.tgz",
"integrity": "sha512-VRjPYIUzex5kfbsOY7LaJcNE2qMWGQQAanb3/Vv85WbOgA+dAfDNfwntRvv335icJgGYrnTX403WxJxRVpLDFA==",
"requires": {
"lodash.get": "4.4.2"
}
},
"cycle": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
......@@ -3210,6 +3218,11 @@
"lodash._isiterateecall": "3.0.9"
}
},
"lodash.get": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
"integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
},
"lodash.isarguments": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
......
......@@ -39,6 +39,7 @@
"uglifyjs": "^2.4.10"
},
"dependencies": {
"csv-stringify": "^4.0.0",
"datatables.net-rowreorder": "^1.2.5",
"dual-listbox": "1.0.7",
"file-saver": "^1.3.8",
......
......@@ -1604,7 +1604,7 @@ ServerConnector.getMaxSearchDistance = function () {
*
* @param {number} overlayId
* @param {string} projectId
* @returns {PromiseLike<DataOverlay>}
* @returns {PromiseLike<DataOverlay>|Promise<DataOverlay>}
*/
ServerConnector.getOverlayById = function (overlayId, projectId) {
var self = this;
......
......@@ -11,8 +11,11 @@ var IdentifiedElement = require('../../map/data/IdentifiedElement');
var Reaction = require('../../map/data/Reaction');
var Functions = require('../../Functions');
// noinspection JSUnusedLocalSymbols
var logger = require('../../logger');
var stringify = require('csv-stringify');
/**
*
* @param {Object} params
......@@ -40,14 +43,14 @@ 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>" +
"<th>Submaps</th>" +
"</tr>"
content: "<tr>" + "<th>Pubmed ID</th>" +
"<th>Title</th>" +
"<th>Authors</th>" +
"<th>Journal</th>" +
"<th>Year</th>" +
"<th>Elements on map</th>" +
"<th>Submaps</th>" +
"</tr>"
});
var body = Functions.createElement({
type: "tbody"
......@@ -74,7 +77,7 @@ PublicationListDialog.prototype.createPublicationListDialogGui = function () {
*/
PublicationListDialog.prototype._dataTableAjaxCall = function (data, callback) {
var self = this;
return ServerConnector.getPublications({
return self.getServerConnector().getPublications({
start: data.start,
length: data.length,
sortColumn: self.getColumnsDefinition()[data.order[0].column].name,
......@@ -89,7 +92,6 @@ PublicationListDialog.prototype._dataTableAjaxCall = function (data, callback) {
var row = [];
var submaps = {};
submaps[self.getMap().getId()] = true;
row[0] = "<a href='" + publication.link + "'>" + publication.id + "</a>";
row[1] = publication.title;
row[2] = publication.authors.join();
......@@ -174,6 +176,35 @@ PublicationListDialog.prototype.show = function () {
ajax: function (data, callback, settings) {
resolve(self._dataTableAjaxCall(data, callback, settings));
},
dom: 'Bfrtip',
buttons: [
{
text: 'CSV',
action: function (e, data) {
GuiConnector.showProcessing();
return self.getServerConnector().getPublications({
start: 0,
length: data.page.info().recordsDisplay,
sortColumn: self.getColumnsDefinition()[data.order()[0][0]].name,
sortOrder: data.order()[0][1],
search: data.search()
}).then(function (publicationList) {
return self.publicationListAsCsvString(publicationList);
}).then(function (result) {
var blob = new Blob([result], {
type: "text/plain;charset=utf-8"
});
var FileSaver = require("file-saver");
return FileSaver.saveAs(blob, "publications.csv");
}).catch(function(error){
GuiConnector.alert(error);
}).finally(function(){
GuiConnector.hideProcessing();
});
}
}
],
columns: self.getColumnsDefinition()
});
});
......@@ -223,4 +254,69 @@ PublicationListDialog.prototype.destroy = function () {
}
};
/**
*
* @returns {Promise}
*/
PublicationListDialog.prototype.publicationListToArray = function (publicationList) {
var self = this;
var result = [];
var elementsToFetch = [];
publicationList.data.map(function (entry) {
var publication = entry.publication.article;
var elements = entry.elements;
for (var j = 0; j < elements.length; j++) {
elementsToFetch.push(new IdentifiedElement(elements[j]));
}
});
return self.getProject().getBioEntitiesByIdentifiedElements(elementsToFetch).then(function(){
return Promise.all(publicationList.data.map(function (entry) {
var publication = entry.publication.article;
var elements = entry.elements;
var row = [];
row[0] = publication.id;
row[1] = publication.title;
row[2] = publication.authors.join();
row[3] = publication.journal;
row[4] = publication.year;
row[5] = "";
row[6] = "";
var submaps = [];
for (var j = 0; j < elements.length; j++) {
var modelId = elements[j].modelId;
if (submaps[modelId] === undefined) {
row[6] += self.getMap().getSubmapById(modelId).getModel().getName() + ", ";
submaps[elements[j].modelId] = true;
}
}
return Promise.all(elements.map(function (element) {
var model = self.getMap().getSubmapById(element.modelId).getModel();
return model.getByIdentifiedElement(new IdentifiedElement(element)).then(function (reaction) {
row[5] += reaction.getElementId() + ",";
});
})).then(function () {
result.push(row);
});
}));
}).then(function () {
return result;
});
};
PublicationListDialog.prototype.publicationListAsCsvString = function (publicationList) {
var self = this;
return self.publicationListToArray(publicationList).then(function(data){
return new Promise(function(resolve){
stringify(data,function(err, output){
resolve(output);
});
});
});
};
module.exports = PublicationListDialog;
......@@ -315,7 +315,7 @@ Project.prototype.getDisease = function () {
/**
*
* @param {AnnotationOptions} disease
* @param {AnnotationOptions|null} disease
*/
Project.prototype.setDisease = function (disease) {
if (disease !== undefined && disease !== null) {
......@@ -335,7 +335,7 @@ Project.prototype.getOrganism = function () {
/**
*
* @param {AnnotationOptions} organism
* @param {AnnotationOptions|null} organism
*/
Project.prototype.setOrganism = function (organism) {
if (organism !== undefined && organism !== null) {
......@@ -553,5 +553,34 @@ Project.prototype.getElementsPointingToSubmap = function (modelId) {
});
};
/**
*
* @param {IdentifiedElement[]} elements
* @param {boolean} complete
* @returns {Promise}
*/
Project.prototype.getBioEntitiesByIdentifiedElements = function (elements, complete) {
var self = this;
var elementsByModelId = [];
var i;
for (i = 0; i < elements.length; i++) {
var element = elements[i];
var modelId = element.getModelId();
if (elementsByModelId[modelId] === undefined) {
elementsByModelId[modelId] = [];
}
elementsByModelId[modelId].push(element);
}
var models = self.getModels();
var promises = [];
for (i = 0; i < models.length; i++) {
if (elementsByModelId[models[i].getId()] !== undefined) {
promises.push(models[i].getByIdentifiedElements(elementsByModelId[models[i].getId()], complete));
}
}
return Promise.all(promises);
};
module.exports = Project;
......@@ -197,6 +197,14 @@ Reaction.prototype.getReactionId = function () {
return this._reactionId;
};
/**
*
* @returns {string}
*/
Reaction.prototype.getElementId = function () {
return this.getReactionId();
};
/**
*
* @param {string} reactionId
......
......@@ -4,6 +4,7 @@ require('../../mocha-config.js');
var PublicationListDialog = require('../../../../main/js/gui/leftPanel/PublicationListDialog');
var ServerConnector = require('../../ServerConnector-mock');
var Functions = require('../../../../main/js/Functions');
var chai = require('chai');
var assert = chai.assert;
......@@ -54,4 +55,42 @@ describe('PublicationListDialog', function () {
});
});
it('publicationListAsCsvString', function () {
var dialog;
return ServerConnector.getProject().then(function (project) {
dialog = createPublicationListDialog(helper.createCustomMap(project));
// noinspection JSAccessibilityCheck
return ServerConnector.getPublications({
start: 0,
length: 10
});
}).then(function (publicationList) {
return dialog.publicationListAsCsvString(publicationList);
}).then(function (result) {
assert.ok(Functions.isString(result));
assert.ok(result.indexOf("re21") >= 0);
}).finally(function () {
dialog.destroy();
});
});
it('publicationListToArray', function () {
var dialog;
return ServerConnector.getProject().then(function (project) {
dialog = createPublicationListDialog(helper.createCustomMap(project));
// noinspection JSAccessibilityCheck
return ServerConnector.getPublications({
start: 0,
length: 10
});
}).then(function (publicationList) {
return dialog.publicationListToArray(publicationList);
}).then(function (result) {
assert.equal(10, result.length);
}).finally(function () {
dialog.destroy();
});
});
});
......@@ -17,11 +17,13 @@
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="https://cdn.datatables.net/1.10.13/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/rowreorder/1.2.3/js/dataTables.rowReorder.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.5.2/js/dataTables.buttons.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css"/>
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"/>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/rowreorder/1.2.3/css/rowReorder.dataTables.min.css"/>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.5.2/css/buttons.dataTables.min.css"/>
<link rel="shortcut icon" href="./resources/images/favicon.png" type="image/png" />
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment