Commit 061c5517 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

configuration tab in admin panel allows editing config params

parent 6c1d7c4b
......@@ -2864,6 +2864,11 @@
"amdefine": "1.0.1"
}
},
"spectrum-colorpicker": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/spectrum-colorpicker/-/spectrum-colorpicker-1.8.0.tgz",
"integrity": "sha1-uSbPUALAp3hgtfg1HhwJPGUgAQc="
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
......
......@@ -46,6 +46,7 @@
"log4js": "0.6.38",
"mkdirp": "^0.5.1",
"pileup": "^0.6.8",
"request": "^2.82.0"
"request": "^2.82.0",
"spectrum-colorpicker": "^1.8.0"
}
}
......@@ -2,10 +2,12 @@
/* exported logger */
// noinspection JSUnusedLocalSymbols
var logger = require('./logger');
var Annotator = require('./map/data/Annotator');
var ConfigurationType = require('./ConfigurationType');
var ConfigurationOption = require('./ConfigurationOption');
var MiriamType = require('./map/data/MiriamType');
var PrivilegeType = require('./map/data/PrivilegeType');
var ModificationStateType = require('./map/data/ModificationStateType');
......@@ -19,8 +21,7 @@ function Configuration(json) {
for (i = 0; i < json.options.length; i++) {
var conf = json.options[i];
var type = conf.type;
var value = conf.value;
self.setOption(type, value);
self.setOption(type, new ConfigurationOption(conf));
}
var legendFiles = [];
......@@ -62,6 +63,17 @@ Configuration.prototype.getOption = function (type) {
return this._options[type];
};
Configuration.prototype.getOptions = function () {
var self = this;
var result = [];
for (var key in self._options) {
if (self._options.hasOwnProperty(key) && self._options[key] instanceof ConfigurationOption) {
result.push(self._options[key]);
}
}
return result;
};
Configuration.prototype.setOverlayTypes = function (overlayTypes) {
this._overlayTypes = overlayTypes;
};
......
"use strict";
var ObjectWithListeners = require('./ObjectWithListeners');
var logger = require('./logger');
function ConfigurationOption(data) {
// call super constructor
ObjectWithListeners.call(this);
var self = this;
self.setType(data.type);
self.setCommonName(data.commonName);
self.setValue(data.value);
self.setValueType(data.valueType);
}
ConfigurationOption.prototype = Object.create(ObjectWithListeners.prototype);
ConfigurationOption.prototype.constructor = ConfigurationOption;
ConfigurationOption.prototype.setType = function (type) {
this._type = type;
};
ConfigurationOption.prototype.getType = function () {
return this._type;
};
ConfigurationOption.prototype.setValue = function (value) {
this._value = value;
};
ConfigurationOption.prototype.getValue = function () {
return this._value;
};
ConfigurationOption.prototype.setValueType = function (valueType) {
this._valueType = valueType;
};
ConfigurationOption.prototype.getValueType = function () {
return this._valueType;
};
ConfigurationOption.prototype.setCommonName = function (commonName) {
this._commonName = commonName;
};
ConfigurationOption.prototype.getCommonName = function () {
return this._commonName;
};
module.exports = ConfigurationOption;
......@@ -11,7 +11,7 @@ var ConfigurationType = {
REQUEST_ACCOUNT_EMAIL: "REQUEST_ACCOUNT_EMAIL",
SIMPLE_COLOR_VAL: "SIMPLE_COLOR_VAL",
SEARCH_DISTANCE: "SEARCH_DISTANCE",
USER_MANUAL_FILE: "USER_MANUAL_FILE",
USER_MANUAL_FILE: "USER_MANUAL_FILE"
};
module.exports = ConfigurationType;
......@@ -494,29 +494,37 @@ ServerConnector.getIdOrAsterisk = function (id) {
ServerConnector.getReactionsUrl = function (queryParams, filterParams) {
return this.getApiUrl({
url: this.getBioEntitiesUrl(queryParams) + "reactions/",
params: filterParams,
params: filterParams
});
};
ServerConnector.getAliasesUrl = function (queryParams, filterParams) {
return this.getApiUrl({
url: this.getBioEntitiesUrl(queryParams) + "elements/",
params: filterParams,
params: filterParams
});
};
ServerConnector.getConfigurationUrl = function (queryParams, filterParams) {
var result = this.getApiUrl({
return this.getApiUrl({
type: "configuration/",
params: filterParams
});
return result;
};
ServerConnector.getConfigurationOptionUrl = function (queryParams, filterParams) {
var self = this;
return self.getApiUrl({
url: self.getConfigurationUrl() + "options/" + queryParams.type,
params: filterParams
});
};
ServerConnector.getSearchUrl = function (queryParams, filterParams) {
return this.getApiUrl({
url: this.getModelsUrl(queryParams) + "bioEntities:search",
params: filterParams,
params: filterParams
});
};
......@@ -641,9 +649,27 @@ ServerConnector.getConfigurationParam = function (paramId) {
}
var self = this;
return self.getConfiguration().then(function (configuration) {
return configuration.getOption(paramId);
var option = configuration.getOption(paramId);
if (option.getValue !== undefined) {
return option.getValue();
} else {
return option;
}
});
};
ServerConnector.updateConfigurationOption = function (option) {
var self = this;
var queryParams = {
type: option.getType()
};
var filterParams = {
option: {
type: option.getType(),
value: option.getValue()
}
};
return self.sendPatchRequest(self.getConfigurationOptionUrl(queryParams), filterParams);
};
ServerConnector.getModels = function (projectId) {
var queryParams = {};
......
"use strict";
/* exported Promise*/
/* exported logger */
var AbstractAdminPanel = require('./AbstractAdminPanel');
var Functions = require('../../Functions');
var GuiConnector = require('../../GuiConnector');
/* exported logger */
// noinspection JSUnusedLocalSymbols
var logger = require('../../logger');
// noinspection JSUnusedLocalSymbols
var Promise = require("bluebird");
function ConfigurationAdminPanel(params) {
AbstractAdminPanel.call(this, params);
var self = this;
self._createGui();
}
ConfigurationAdminPanel.prototype = Object.create(AbstractAdminPanel.prototype);
ConfigurationAdminPanel.prototype.constructor = ConfigurationAdminPanel;
ConfigurationAdminPanel.prototype.init = function() {
ConfigurationAdminPanel.prototype._createGui = function () {
var self = this;
var configurationDiv = Functions.createElement({
type: "div"
});
self.getElement().appendChild(configurationDiv);
var configurationTable = Functions.createElement({
type: "table",
name: "configurationTable",
className: "display",
style: "width:100%"
});
configurationDiv.appendChild(configurationTable);
// noinspection JSUnusedGlobalSymbols
$(configurationTable).DataTable({
fnRowCallback: function (nRow, aData) {
nRow.setAttribute('id', aData[0]);
},
columns: [{
title: 'Name'
}, {
title: 'Value'
}, {
title: 'Save'
}]
});
$(configurationTable).on("click", "[name='saveOption']", function () {
var button = this;
return self.saveOption($(button).attr("data")).then(null, GuiConnector.alert);
});
$(configurationTable).on("input", ".minerva-color-input", function () {
var input = this;
var value = $(input).val();
var type = $(input).attr("data");
if (value.length !== 6) {
value = "FFFFFF";
}
$("[name='edit-color-" + type + "']", configurationTable).css("background-color", "#" + value);
});
$(configurationTable).on("click", ".minerva-color-button", function () {
var button = this;
var value = $(button).css("background-color");
var type = $(button).attr("data");
logger.debug(type);
var colorPicker = $(button).parent().spectrum({
color: value,
move: function (color) {
var value = color.toHexString().replace("#", '');
$("[name='edit-" + type + "']", configurationTable).val(value);
$("[name='edit-color-" + type + "']", configurationTable).css("background-color", "#" + value);
},
hide: function () {
colorPicker.spectrum("destroy");
}
});
return new Promise.delay(1).then(function () {
colorPicker.show();
colorPicker.spectrum("show");
});
});
};
ConfigurationAdminPanel.prototype.init = function () {
var self = this;
return ServerConnector.getConfiguration().then(function (configuration) {
self.setOptions(configuration.getOptions());
});
};
ConfigurationAdminPanel.prototype.setOptions = function (options) {
var self = this;
var dataTable = $($("[name='configurationTable']", self.getElement())[0]).DataTable();
var data = [];
for (var i = 0; i < options.length; i++) {
var option = options[i];
var rowData = self.optionToTableRow(option);
data.push(rowData);
}
dataTable.clear().rows.add(data).draw();
};
ConfigurationAdminPanel.prototype.optionToTableRow = function (option) {
var value = option.getValue();
var row = [];
var editOption;
if (option.getValueType() === "STRING" ||
option.getValueType() === "INTEGER" ||
option.getValueType() === "DOUBLE" ||
option.getValueType() === "EMAIL" ||
option.getValueType() === "PASSWORD" ||
option.getValueType() === "URL") {
editOption = "<input name='edit-" + option.getType() + "' value='" + value + "'/>";
} else if (option.getValueType() === "COLOR") {
editOption = "<div>" +
"<input class='minerva-color-input' name='edit-" + option.getType() + "' data='" + option.getType() + "' value='" + value + "'/>" +
"<button class='minerva-color-button' name='edit-color-" + option.getType() + "' data='" + option.getType() + "' style='background-color: #" + value + "'>&nbsp</button>" +
"</div>";
} else {
logger.warn("Don't know how to handle: " + option.getValueType());
editOption = "<input name='edit-" + option.getType() + "' value='" + value + "'readonly/>";
}
row[0] = option.getCommonName();
row[1] = editOption;
row[2] = "<button name='saveOption' data='" + option.getType() + "'>SAVE</button>";
return row;
};
ConfigurationAdminPanel.prototype.saveOption = function (type) {
var self = this;
return ServerConnector.getConfiguration().then(function (configuration) {
var option = configuration.getOption(type);
var value = $("[name='edit-" + type + "']", self.getElement()).val();
option.setValue(value);
return ServerConnector.updateConfigurationOption(option);
});
};
ConfigurationAdminPanel.prototype.destroy = function () {
var self = this;
var table = $("[name='configurationTable']", self.getElement())[0];
if ($.fn.DataTable.isDataTable(table)) {
$(table).DataTable().destroy();
}
};
......
"use strict";
/* exported logger */
/* exported Promise*/
var AbstractAdminPanel = require('./AbstractAdminPanel');
var Promise = require("bluebird");
function ServicesAdminPanel(params) {
AbstractAdminPanel.call(this, params);
}
ServicesAdminPanel.prototype = Object.create(AbstractAdminPanel.prototype);
ServicesAdminPanel.prototype.constructor = ServicesAdminPanel;
ServicesAdminPanel.prototype.init = function() {
};
module.exports = ServicesAdminPanel;
......@@ -177,6 +177,7 @@ UsersAdminPanel.prototype.setUsers = function (users) {
dataTable.clear().rows.add(data).draw();
};
UsersAdminPanel.prototype.addUpdateListener = function (user, dataTableRow) {
var self = this;
......
......@@ -6,11 +6,29 @@
require("./mocha-config");
var Configuration = require('../../main/js/Configuration');
var ConfigurationType = require('../../main/js/ConfigurationType');
var logger = require('./logger');
var assert = require('assert');
describe('Configuration', function () {
it('constructor', function () {
var configuration = new Configuration({
options: {},
overlayTypes: {},
imageFormats: {},
modelFormats: {},
elementTypes: {},
reactionTypes: {},
miriamTypes: {},
mapTypes: {},
modificationStateTypes: {},
privilegeTypes: {},
annotators: {}
});
assert.ok(configuration);
assert.equal(0, logger.getWarnings().length);
});
describe('getParentType', function () {
it('for element type', function () {
......@@ -57,4 +75,29 @@ describe('Configuration', function () {
});
});
});
describe('getOption', function () {
it('DEFAULT_MAP', function () {
return ServerConnector.getConfiguration().then(function (configuration) {
var option = configuration.getOption(ConfigurationType.DEFAULT_MAP);
assert.ok(option);
assert.ok(option.getType());
assert.ok(option.getValue());
assert.ok(option.getCommonName());
});
});
it('get for element', function () {
return ServerConnector.getConfiguration().then(function (configuration) {
var found = false;
var types = configuration.getElementTypes();
for (var i = 0; i < types.length; i++) {
var annotators = configuration.getElementAnnotators(types[i]);
if (annotators.length > 0) {
found = true;
}
}
assert.ok(found);
});
});
});
});
"use strict";
require("../../mocha-config");
var ConfigurationAdminPanel = require('../../../../main/js/gui/admin/ConfigurationAdminPanel');
var ConfigurationType = require('../../../../main/js/ConfigurationType');
var logger = require('../../logger');
var assert = require('assert');
describe('ConfigurationAdminPanel', function () {
it('init', function () {
var mapTab;
var project;
return ServerConnector.getProject().then(function (result) {
project = result;
return ServerConnector.getConfiguration();
}).then(function (configuration) {
mapTab = new ConfigurationAdminPanel({
element: testDiv,
project: project,
configuration: configuration
});
return mapTab.init();
}).then(function () {
assert.equal(0, logger.getWarnings().length);
return mapTab.destroy();
});
});
it('saveOption', function () {
var mapTab;
var project;
return ServerConnector.getProject().then(function (result) {
project = result;
return ServerConnector.getConfiguration();
}).then(function (configuration) {
mapTab = new ConfigurationAdminPanel({
element: testDiv,
project: project,
configuration: configuration
});
return mapTab.init();
}).then(function () {
return mapTab.saveOption(ConfigurationType.DEFAULT_MAP);
}).then(function () {
return mapTab.destroy();
});
});
});
......@@ -92,6 +92,8 @@ global.window.$ = $;
require("bootstrap");
require('datatables.net')(window, $);
require('spectrum-colorpicker');
global.tinycolor= window.tinycolor;
require('jstree');
global.google = require('./google-map-mock');
......
{"idObject":6,"type":"DEFAULT_MAP","value":"sample","valueType":"STRING","commonName":"Default Project Id"}
\ No newline at end of file
......@@ -25,7 +25,7 @@ public enum ConfigurationElementType {
EMAIL_PASSWORD("E-mail server password", "email.secret.password", ConfigurationElementEditType.PASSWORD, true), //
/**
* Addres of the imap server.
* Address of the imap server.
*/
EMAIL_IMAP_SERVER("IMAP server", "your.imap.domain.com", ConfigurationElementEditType.STRING, true), //
......@@ -35,7 +35,7 @@ public enum ConfigurationElementType {
EMAIL_SMTP_SERVER("SMTP server", "your.smtp.domain.com", ConfigurationElementEditType.STRING, true), //
/**
* Port used for smtp connection (sending emails).
* Port used for smtp connection (sending e-mails).
*/
EMAIL_SMTP_PORT("SMTP port", "25", ConfigurationElementEditType.INTEGER, true), //
......
package lcsb.mapviewer.api.configuration;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import lcsb.mapviewer.api.BaseController;
import lcsb.mapviewer.common.Configuration;
import lcsb.mapviewer.services.SecurityException;
import lcsb.mapviewer.services.interfaces.IConfigurationService;
import lcsb.mapviewer.services.view.ConfigurationView;
@RestController
public class ConfigurationController extends BaseController {
......@@ -52,6 +61,25 @@ public class ConfigurationController extends BaseController {
return result;
}
@RequestMapping(value = "/configuration/options/", method = { RequestMethod.GET }, produces = {
MediaType.APPLICATION_JSON_VALUE })
public List<ConfigurationView> getOptions(@CookieValue(value = Configuration.AUTH_TOKEN) String token)
throws SecurityException {
return configurationController.getAllValues(token);
}
@RequestMapping(value = "/configuration/options/{option}", method = { RequestMethod.PATCH }, produces = {
MediaType.APPLICATION_JSON_VALUE })
public ConfigurationView getOption( //
@RequestBody String body, //
@CookieValue(value = Configuration.