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

admin panel allows to add set of plugins that should be listed when browsing

parent c97618c4
......@@ -566,12 +566,13 @@ h1 {
font-weight: 400;
}
.minerva-projects-tab, .minerva-users-tab, .minerva-configuration-tab .tab-pane, .minerva-genome-tab {
.minerva-projects-tab, .minerva-users-tab, .minerva-configuration-tab .tab-pane, .minerva-genome-tab, .minerva-plugin-tab {
margin-left: 10px;
margin-top: 10px;
}
.minerva-projects-tab .minerva-menu-row button,
.minerva-plugin-tab .minerva-menu-row button,
.minerva-edit-project-dialog .minerva-menu-row button,
.minerva-users-tab .minerva-menu-row button,
.minerva-genome-tab .minerva-menu-row button {
......
......@@ -8,6 +8,7 @@ var CustomMapOptions = require('./map/CustomMapOptions');
var AbstractGuiElement = require('./gui/AbstractGuiElement');
var ConfigurationAdminPanel = require('./gui/admin/ConfigurationAdminPanel');
var PluginAdminPanel = require('./gui/admin/PluginAdminPanel');
var GenomeAdminPanel = require('./gui/admin/GenomeAdminPanel');
var MapsAdminPanel = require('./gui/admin/MapsAdminPanel');
var UsersAdminPanel = require('./gui/admin/UsersAdminPanel');
......@@ -60,6 +61,9 @@ Admin.prototype._createGui = function () {
}, {
name: "GENOMES",
panelClass: GenomeAdminPanel
}, {
name: "PLUGINS",
panelClass: PluginAdminPanel
}];
for (var i = 0; i < panels.length; i++) {
......
......@@ -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);
......
......@@ -27,6 +27,7 @@ var MapModel = require('./map/data/MapModel');
var Mesh = require('./map/data/Mesh');
var MiRna = require('./map/data/MiRna');
var NetworkError = require('./NetworkError');
var PluginData = require('./map/data/PluginData');
var Project = require('./map/data/Project');
var ProjectStatistics = require('./map/data/ProjectStatistics');
var Reaction = require('./map/data/Reaction');
......@@ -384,23 +385,45 @@ ServerConnector.getProjectsUrl = function (queryParams, filterParams) {
});
};
ServerConnector.getRegisterPluginUrl = function (queryParams, filterParams) {
ServerConnector.getPluginsUrl = function (queryParams, filterParams) {
return this.getApiUrl({
type: "plugins/",
params: filterParams
});
};
/**
*
* @param {Object} queryParams
* @param {string} queryParams.hash
* @param [filterParams]
* @returns {string}
*/
ServerConnector.getPluginUrl = function (queryParams, filterParams) {
return this.getApiUrl({
url: this.getPluginsUrl(queryParams) + queryParams.hash + "/",
params: filterParams
});
};
/**
*
* @param {Object} queryParams
* @param {string} queryParams.hash
* @param {string} queryParams.key
* @param [filterParams]
* @returns {string}
*/
ServerConnector.getPluginGlobalParamUrl = function (queryParams, filterParams) {
return this.getApiUrl({
url: this.getRegisterPluginUrl(queryParams) + queryParams.hash + "/data/global/" + queryParams.key + "/",
url: this.getPluginUrl(queryParams) + "data/global/" + queryParams.key + "/",
params: filterParams
});
};
ServerConnector.getPluginUserParamUrl = function (queryParams, filterParams) {
return this.getApiUrl({
url: this.getRegisterPluginUrl(queryParams) + queryParams.hash + "/data/users/" + queryParams.login + "/" + queryParams.key + "/",
url: this.getPluginsUrl(queryParams) + queryParams.hash + "/data/users/" + queryParams.login + "/" + queryParams.key + "/",
params: filterParams
});
};
......@@ -1175,6 +1198,10 @@ ServerConnector.getProjectStatistics = function (projectId) {
});
};
/**
*
* @returns {Promise<User>}
*/
ServerConnector.getLoggedUser = function () {
var self = this;
if (self._loggedUser !== undefined) {
......@@ -1192,6 +1219,34 @@ ServerConnector.getLoggedUser = function () {
}
};
/**
*
* @returns {Promise<PluginData[]>}
*/
ServerConnector.getPluginsData = function () {
var self = this;
return self.sendGetRequest(self.getPluginsUrl()).then(function (content) {
var data = JSON.parse(content);
var result = [];
for (var i = 0; i < data.length; i++) {
result.push(new PluginData(data[i]));
}
return result;
});
};
/**
*
* @param {Object} params
* @param {string} params.hash
*
* @returns {Promise<PluginData[]>}
*/
ServerConnector.removePlugin = function (params) {
var self = this;
return self.sendDeleteRequest(self.getPluginUrl(params));
};
/**
*
* @param {string} login
......@@ -2492,12 +2547,21 @@ ServerConnector.getSbmlParameter = function (params) {
});
};
ServerConnector.registerPlugin = function (params) {
var self = this;
if (params === undefined) {
params = {};
}
return self.sendPostRequest(self.getRegisterPluginUrl(), params);
/**
*
* @param {PluginData} pluginData
* @returns {Promise}
*/
ServerConnector.registerPlugin = function (pluginData) {
var self = this;
var params = {
hash: pluginData.getHash(),
url: pluginData.getUrls()[0],
name: pluginData.getName(),
version: pluginData.getVersion(),
isPublic: pluginData.isPublic()
};
return self.sendPostRequest(self.getPluginsUrl(), params);
};
ServerConnector.getPluginGlobalParam = function (params) {
......
......@@ -143,12 +143,14 @@ PluginDialog.prototype._createPluginGui = function () {
*/
PluginDialog.prototype.init = function () {
var self = this;
var pluginsData = self.getConfiguration().getPluginsData();
for (var i = 0; i < pluginsData.length; i++) {
var pluginData = pluginsData[i];
self._knownPlugins.push({url: self.getServerConnector().getServerBaseUrl() + pluginData.url});
}
return Promise.resolve();
return self.getServerConnector().getPluginsData().then(function (pluginsData) {
for (var i = 0; i < pluginsData.length; i++) {
var pluginData = pluginsData[i];
if (pluginData.isPublic()) {
self._knownPlugins.push({url: self.getServerConnector().getServerBaseUrl() + pluginData.getUrls()[0]});
}
}
});
};
/**
......
"use strict";
var Promise = require("bluebird");
var AbstractGuiElement = require('../AbstractGuiElement');
var GuiConnector = require('../../GuiConnector');
var Functions = require('../../Functions');
var PluginData = require('../../map/data/PluginData');
// noinspection JSUnusedLocalSymbols
var logger = require('../../logger');
/**
*
* @param {Object} params
* @param {HTMLElement} params.element
* @param {Configuration} params.configuration
* @param {ServerConnector} params.serverConnector
* @constructor
*
* @extends AbstractGuiElement
*/
function AddPluginDialog(params) {
params["customMap"] = null;
AbstractGuiElement.call(this, params);
var self = this;
$(self.getElement()).css({overflow: "hidden"});
self.createGui();
self.registerListenerType("onSave");
}
AddPluginDialog.prototype = Object.create(AbstractGuiElement.prototype);
AddPluginDialog.prototype.constructor = AddPluginDialog;
/**
*
*/
AddPluginDialog.prototype.createGui = function () {
var self = this;
var result = Functions.createElement({
type: "div",
style: "margin-top:10px;"
});
var table = Functions.createElement({
type: "table",
name: "detailsTable",
className: "display",
style: "width:100%"
});
result.appendChild(table);
var menuRow = Functions.createElement({
type: "div",
className: "minerva-menu-row",
style: "display:table-row; margin:10px"
});
result.appendChild(menuRow);
var saveUserButton = Functions.createElement({
type: "button",
name: "savePlugin",
content: '<span class="ui-icon ui-icon-disk"></span>&nbsp;SAVE',
onclick: function () {
return self.onSaveClicked().then(function () {
return self.close();
}).catch(GuiConnector.alert);
},
xss: false
});
$(saveUserButton).attr("disabled", true);
var cancelButton = Functions.createElement({
type: "button",
name: "cancelGenome",
content: '<span class="ui-icon ui-icon-cancel"></span>&nbsp;CANCEL',
onclick: function () {
return self.close();
},
xss: false
});
menuRow.appendChild(saveUserButton);
menuRow.appendChild(cancelButton);
$(self.getElement()).on("click", "[name='validateUrl']", function () {
return self.onValidateClicked().catch(GuiConnector.alert);
});
return self.getElement().appendChild(result);
};
/**
*
* @returns {PluginData}
*/
AddPluginDialog.prototype.getPluginData = function () {
return this._pluginData;
};
/**
*
* @param {PluginData} pluginData
*/
AddPluginDialog.prototype.setPluginData = function (pluginData) {
this._pluginData = pluginData;
};
/**
*
* @returns {Promise}
*/
AddPluginDialog.prototype.onSaveClicked = function () {
var self = this;
var pluginData = self.getPluginData();
if (pluginData === undefined) {
return Promise.reject(new Error("You must validate the url first"));
} else {
return self.getServerConnector().registerPlugin(pluginData).then(function () {
return self.callListeners("onSave");
});
}
};
/**
*
* @returns {Promise|PromiseLike}
*/
AddPluginDialog.prototype.onValidateClicked = function () {
var self = this;
var url = $("[name='pluginUrl']").val();
var error;
return self.getServerConnector().sendRequest({
url: url,
description: "Loading plugin: " + url,
method: "GET"
}).then(function (content) {
var hash = Functions.computeMD5(content);
var pluginRawData = undefined;
// noinspection JSUnusedLocalSymbols
var minervaDefine = function (pluginFunction) {
try {
if (typeof pluginFunction === "function") {
pluginRawData = pluginFunction();
} else {
pluginRawData = pluginFunction;
}
} catch (e) {
error = e;
}
};
content += "//# sourceURL=" + url;
eval(content);
if (error) {
return Promise.reject(error);
}
$("[name='pluginVersion']").val(pluginRawData.getVersion());
$("[name='pluginName']").val(pluginRawData.getName());
self.setPluginData(new PluginData({
hash: hash,
urls: [url],
name: pluginRawData.getName(),
version: pluginRawData.getVersion(),
isPublic: true
}));
var saveUserButton = $('[name="savePlugin"]');
saveUserButton.attr("disabled", false);
});
};
/**
*
* @returns {Promise}
*/
AddPluginDialog.prototype.init = function () {
var self = this;
var detailsTable = $("[name=detailsTable]", self.getElement())[0];
// noinspection JSCheckFunctionSignatures
var dataTable = $(detailsTable).DataTable({
columns: [{
title: "Name"
}, {
title: "Value"
}],
paging: false,
ordering: false,
searching: false,
bInfo: false
});
var data = [];
data.push(['Url', "<div><input type='text' name='pluginUrl'/><button name='validateUrl'><span class='ui-icon ui-icon-circle-check'></span>&nbsp;VALIDATE</button></div>"]);
data.push(['Name', "<input name='pluginName' readonly/>"]);
data.push(['Version', "<input name='pluginVersion' readonly/>"]);
dataTable.clear().rows.add(data).draw();
return Promise.resolve();
};
/**
*
*
* @returns {Promise}
*/
AddPluginDialog.prototype.destroy = function () {
var self = this;
var div = self.getElement();
var detailsTable = $("[name=detailsTable]", div)[0];
if ($.fn.DataTable.isDataTable(detailsTable)) {
$(detailsTable).DataTable().destroy();
}
if ($(div).hasClass("ui-dialog-content")) {
$(div).dialog("destroy");
}
return Promise.resolve();
};
/**
*
*/
AddPluginDialog.prototype.open = function () {
var self = this;
var div = self.getElement();
if (!$(div).hasClass("ui-dialog-content")) {
$(div).dialog({
title: "Add plugin",
width: window.innerWidth / 2,
height: window.innerHeight / 2
});
}
$(div).dialog("open");
};
/**
*
*/
AddPluginDialog.prototype.close = function () {
var self = this;
$(self.getElement()).dialog("close");
};
module.exports = AddPluginDialog;
"use strict";
var AbstractAdminPanel = require('./AbstractAdminPanel');
var AddPluginDialog = require('./AddPluginDialog');
var Functions = require('../../Functions');
var GuiConnector = require('../../GuiConnector');
var PrivilegeType = require('../../map/data/PrivilegeType');
// noinspection JSUnusedLocalSymbols
var logger = require('../../logger');
var Promise = require('bluebird');
/**
*
* @param {Configuration} params.configuration
* @param {HTMLElement} params.element
*
* @constructor
*/
function PluginAdminPanel(params) {
params["panelName"] = "plugins";
AbstractAdminPanel.call(this, params);
var self = this;
$(self.getElement()).addClass("minerva-plugin-tab");
self._createGui();
}
PluginAdminPanel.prototype = Object.create(AbstractAdminPanel.prototype);
PluginAdminPanel.prototype.constructor = PluginAdminPanel;
/**
*
* @private
*/
PluginAdminPanel.prototype._createGui = function () {
var self = this;
var pluginDiv = Functions.createElement({
type: "div"
});
self.getElement().appendChild(pluginDiv);
pluginDiv.appendChild(self._createMenuRow());
var pluginsTable = Functions.createElement({
type: "table",
name: "pluginsTable",
className: "display",
style: "width:100%"
});
pluginDiv.appendChild(pluginsTable);
// noinspection JSUnusedGlobalSymbols
$(pluginsTable).DataTable({
columns: [{
title: 'Name'
}, {
title: 'Version'
}, {
title: 'Url'
}, {
title: 'Remove',
orderable: false
}],
order: [[1, "asc"]]
});
self.bindUserGuiPreference({
jQueryObject: $(pluginsTable),
event: 'length.dt',
preferenceName: 'admin-plugins-datatable-length',
defaultValue: '10',
getter: function () {
return $(pluginsTable).DataTable().page.len() + '';
},
setter: function (value) {
return $(pluginsTable).DataTable().page.len(value).draw();
}
});
$(pluginsTable).on("click", "[name='removePlugin']", function () {
var button = this;
return self.askConfirmRemoval({
title: "INFO",
content: "Do you really want to remove this plugin?",
input: false
}).then(function (param) {
if (param.status) {
return self.getServerConnector().removePlugin({hash: $(button).attr("data")}).then(function () {
return self.onRefreshClicked();
});
}
}).catch(GuiConnector.alert);
});
pluginDiv.appendChild(self._createMenuRow());
};
/**
*
* @returns {HTMLElement}
* @private
*/
PluginAdminPanel.prototype._createMenuRow = function () {
var self = this;
var menuRow = Functions.createElement({
type: "div",
className: "minerva-menu-row",
style: "display:table-row; margin:10px"
});
var addPluginButton = Functions.createElement({
type: "button",
name: "addPlugin",
content: '<span class="ui-icon ui-icon-circle-plus"></span>&nbsp;ADD PLUGIN',
onclick: function () {
return self.onAddClicked().catch(GuiConnector.alert);
},
xss: false
});
var refreshButton = Functions.createElement({
type: "button",
name: "refreshPlugins",
content: '<span class="ui-icon ui-icon-refresh"></span>&nbsp;REFRESH',
onclick: function () {
return self.onRefreshClicked().catch(GuiConnector.alert);
},
xss: false
});
menuRow.appendChild(addPluginButton);
menuRow.appendChild(refreshButton);
return menuRow;
};
/**
*
* @returns {Promise}
*/