diff --git a/frontend-js/package-lock.json b/frontend-js/package-lock.json index 29898ad842e00b3eb7c8dd24e29d521cd5cf3cef..5db0016f8df18b58e138862b0a2d99c344a5f5fd 100644 --- a/frontend-js/package-lock.json +++ b/frontend-js/package-lock.json @@ -11,9 +11,9 @@ "dev": true }, "@types/react": { - "version": "15.6.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-15.6.14.tgz", - "integrity": "sha512-k6YJBmHfzkCtk3iT6aN2hclkPYL2fxlSc3dW//G2kENlmMJ/V+pKhqsHdJJeVluIi1bA296cCLLGATLm7WXToQ==", + "version": "15.6.15", + "resolved": "https://registry.npmjs.org/@types/react/-/react-15.6.15.tgz", + "integrity": "sha512-LOHbyeKRNYLEotniN3DlRGrpXorXupvFSbKrNzc9dZ87uL+IJDbGYVerxKaG1jbnhuc7RhEWxlNmUVtYm3mtNg==", "dev": true }, "@types/react-dom": { @@ -22,7 +22,7 @@ "integrity": "sha512-XGLjgNtPnBuO1cITYWZAk4KbH0UEDqMg2kuG3xx0UgnrcSd6ijO57Fp9rimmrDKcBnx3b2vFQuEYRXu2GihRYQ==", "dev": true, "requires": { - "@types/react": "15.6.14" + "@types/react": "15.6.15" } }, "JSONStream": { @@ -45,30 +45,38 @@ "litemol": "github:dsehnal/LiteMol#a5419c696faa84530dd93acd55b747cf8136902b" }, "dependencies": { + "ProtVista": { + "version": "git://github.com/davidhoksza/protvista.git#4e4bb737ba1e183291505bd25f8bae2e651ce21e", + "dev": true, + "requires": { + "d3": "3.5.17", + "file-saver": "1.3.3", + "jquery": "2.2.4", + "jszip": "3.1.4", + "underscore": "1.8.3" + }, + "dependencies": { + "jquery": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz", + "integrity": "sha1-LInWiJterFIqfuoywUUhVZxsvwI=", + "dev": true + } + } + }, "jquery": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz", "integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==", "dev": true - } - } - }, - "ProtVista": { - "version": "git://github.com/davidhoksza/protvista.git#4e4bb737ba1e183291505bd25f8bae2e651ce21e", - "dev": true, - "requires": { - "d3": "3.5.17", - "file-saver": "1.3.3", - "jquery": "2.2.4", - "jszip": "3.1.4", - "underscore": "1.8.3" - }, - "dependencies": { - "jquery": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.4.tgz", - "integrity": "sha1-LInWiJterFIqfuoywUUhVZxsvwI=", - "dev": true + }, + "litemol": { + "version": "github:dsehnal/LiteMol#a5419c696faa84530dd93acd55b747cf8136902b", + "dev": true, + "requires": { + "@types/react": "15.6.15", + "@types/react-dom": "15.5.7" + } } } }, @@ -2050,14 +2058,6 @@ "immediate": "3.0.6" } }, - "litemol": { - "version": "github:dsehnal/LiteMol#a5419c696faa84530dd93acd55b747cf8136902b", - "dev": true, - "requires": { - "@types/react": "15.6.14", - "@types/react-dom": "15.5.7" - } - }, "lodash": { "version": "4.17.4", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", @@ -2389,6 +2389,11 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, + "multi-checkbox-list": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/multi-checkbox-list/-/multi-checkbox-list-0.2.0.tgz", + "integrity": "sha512-b1HVb8XqCNtC2OAu2AVgs/eaNnMS9Zudv61Nsi3OR9527P5c5IfwGbCzgLyBHiT0pHeL7Kpk6V+6bQYM8sYaTg==" + }, "nave": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/nave/-/nave-0.5.3.tgz", diff --git a/frontend-js/package.json b/frontend-js/package.json index feff0ba36e760ab9d2c38435db2947ea5a37d133..a6345728a80f84bacd029cabca6a84b59c234f9a 100644 --- a/frontend-js/package.json +++ b/frontend-js/package.json @@ -4,7 +4,7 @@ "description": "frontentd for minerva google maps interface", "main": "minerva.js", "scripts": { - "build:css": "cleancss --skip-rebase -o dist/minerva.css node_modules/dual-listbox/dist/*.css src/main/css/*.css", + "build:css": "cleancss --skip-rebase -o dist/minerva.css node_modules/dual-listbox/dist/*.css node_modules/multi-checkbox-list/dist/*.css src/main/css/*.css", "build:js": "browserify --debug --standalone minerva src/main/js/minerva.js | exorcist dist/minerva.js.map > dist/minerva.js ", "//": "rm -rf dist & rmdir /q /s dist & mkdir dist & browserify --debug --standalone minerva src/main/js/minerva.js | exorcist dist/minerva.js.map > dist/minerva.js & uglifyjs --compress --mangle --in-source-map dist/minerva.js.map --source-map-include-sources --source-map dist/minerva.min.js.map -o dist/minerva.min.js dist/minerva.js", "build-deploy": "npm run build && npm run deploy", @@ -17,6 +17,7 @@ }, "author": "Piotr Gawron", "devDependencies": { + "MolStar": "git://github.com/davidhoksza/MolStar.git", "assert": "1.4.1", "bluebird": "^3.4.6", "bootstrap": "^3.3.7", @@ -36,7 +37,6 @@ "log4js-memory-appender": "1.0.5", "mkdirp": "^0.5.1", "mocha": "^3.5.3", - "MolStar": "git://github.com/davidhoksza/MolStar.git", "uglifyjs": "^2.4.10" }, "dependencies": { @@ -49,6 +49,7 @@ "jstree": "^3.3.4", "jszip": "^3.1.4", "log4js": "0.6.38", + "multi-checkbox-list": "^0.2.0", "pileup": "^0.6.8", "request": "^2.82.0", "spectrum-colorpicker": "^1.8.0", diff --git a/frontend-js/src/main/js/Configuration.js b/frontend-js/src/main/js/Configuration.js index 2e543b48870c327e8c24acd8b4ae5d9a6165a77d..4755bee12f43b880d69f54d33f45bfd23d8ccff9 100644 --- a/frontend-js/src/main/js/Configuration.js +++ b/frontend-js/src/main/js/Configuration.js @@ -370,4 +370,54 @@ Configuration.prototype.update = function (original) { } }; +Configuration.prototype.getElementTypeTree = function () { + var elementTypes = this.getElementTypes(); + var reactionTypes = this.getReactionTypes(); + + var treeNodes = { + "lcsb.mapviewer.model.map.BioEntity": { + text: "BioEntity", + children: [] + } + }; + + var i, type; + for (i = 0; i < elementTypes.length; i++) { + type = elementTypes[i]; + var name = type.className; + if (name.indexOf(".") > 0) { + name = name.substr(name.lastIndexOf(".") + 1); + } + treeNodes[type.className] = { + text: name, + data: type, + children: [] + }; + } + + for (i = 0; i < reactionTypes.length; i++) { + type = reactionTypes[i]; + treeNodes[type.className] = { + text: type.name, + data: type, + children: [] + }; + } + + for (var treeNodeName in treeNodes) { + if (treeNodes.hasOwnProperty(treeNodeName)) { + var treeNode = treeNodes[treeNodeName]; + if (treeNode.data !== undefined) { + var parentNode = treeNodes[treeNode.data.parentClass]; + if (parentNode.data===undefined || parentNode.data.name !== "Compartment") { + parentNode.children.push(treeNode); + } + } + } + } + + return treeNodes["lcsb.mapviewer.model.map.BioEntity"]; +}; + + module.exports = Configuration; diff --git a/frontend-js/src/main/js/ServerConnector.js b/frontend-js/src/main/js/ServerConnector.js index 48c374d88e905eb1a63193a0336715b074115ba2..c08e3bddbecf4019f15b05e46b0213cbc69824bc 100644 --- a/frontend-js/src/main/js/ServerConnector.js +++ b/frontend-js/src/main/js/ServerConnector.js @@ -1105,7 +1105,7 @@ ServerConnector.updateUserPreferences = function (params) { var obj = JSON.parse(content); var user = new User(obj); if (self._usersByLogin[user.getLogin()] !== undefined) { - self._usersByLogin[user.getLogin()].update(user); + self._usersByLogin[user.getLogin()].getPreferences().update(user.getPreferences()); } else { self._usersByLogin[user.getLogin()] = user; } diff --git a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js index 22d5dc4f982a105bb6dbf9aea5a5efc14de836a7..d6bc264d41e533742610f5ee739ad409383c17a5 100644 --- a/frontend-js/src/main/js/gui/admin/AddProjectDialog.js +++ b/frontend-js/src/main/js/gui/admin/AddProjectDialog.js @@ -129,7 +129,8 @@ AddProjectDialog.prototype.showAnnotatorsDialog = function () { if (self._annotatorsDialog === undefined) { self._annotatorsDialog = new ChooseAnnotatorsDialog({ element: Functions.createElement({type: "div"}), - customMap: null + customMap: null, + configuration: self.getConfiguration() }); promise = self._annotatorsDialog.init(); } else { diff --git a/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js b/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js index 1eeddfc1711839108c2f4611c62fbd98d883c1d7..2282b96c74a7b84883b7b53e89072cb71d27bc33 100644 --- a/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js +++ b/frontend-js/src/main/js/gui/admin/ChooseAnnotatorsDialog.js @@ -3,11 +3,11 @@ /* exported logger */ var AbstractGuiElement = require('../AbstractGuiElement'); -var DualListbox = require('dual-listbox').DualListbox; var GuiConnector = require("../../GuiConnector"); +var MultiCheckboxList = require("multi-checkbox-list"); var UserPreferences = require("../../map/data/UserPreferences"); -var InvalidArgumentError = require ('../../InvalidArgumentError'); +var InvalidArgumentError = require('../../InvalidArgumentError'); var Functions = require('../../Functions'); var logger = require('../../logger'); @@ -27,40 +27,30 @@ ChooseAnnotatorsDialog.prototype.createGui = function () { var self = this; var content = Functions.createElement({ type: "div", - style: "display:table" + style: "display:table;height:100%;width:100%" }); content.appendChild(Functions.createElement({ type: "div", - style: "display:table-cell", - content: "<div name='elementTree'/>", + style: "display:table-cell;height:100%;", + content: "<div name='elementTree' style='height:100%;overflow-y:scroll;'/>", xss: false })); var annotatorsDiv = Functions.createElement({ type: "div", - style: "display:table-cell", + style: "display:table-cell;width:100%", + content: "<div style='height:100%;width:100%;overflow-y:auto;'><div name='annotatorListBox'></div><div class='minerva-annotators-params'></div></div>", xss: false }); - - annotatorsDiv.appendChild(Functions.createElement({ - type: "div", - name: "annotatorListBox" - })); - - annotatorsDiv.appendChild(Functions.createElement({ - type: "div", - className: "minerva-annotators-params" - })); - - content.appendChild(annotatorsDiv); + content.appendChild(annotatorsDiv); self.getElement().appendChild(content); }; -function onChangeParameterValue(element, user){ +function onChangeParameterValue(element, user) { var name = $(element).siblings(".minerva-annotator-param-name")[0].childNodes[0].nodeValue; var annotatorClassName = $(element).parent().parent().attr('name'); - + var data = new UserPreferences(); var annotatorsParams = {}; @@ -69,47 +59,173 @@ function onChangeParameterValue(element, user){ else annotatorsParams[annotatorClassName][name] = element.value; data.setAnnotatorsParameters(annotatorsParams); - return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert); + return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert); } +ChooseAnnotatorsDialog.prototype.saveAnnotatorsInfo = function (elementTypes, selectedAnnotators) { + selectedAnnotators = selectedAnnotators.slice(); + return ServerConnector.getLoggedUser().then(function (user) { + + var data = new UserPreferences(); + + var elementAnnotators = {}; + for (var i = 0; i < elementTypes.length; i++) { + elementAnnotators[elementTypes[i].className] = selectedAnnotators; + + var userAnnotators = user.getPreferences().getElementAnnotators(elementTypes[i].className); + userAnnotators.length = 0; + userAnnotators.push.apply(userAnnotators, selectedAnnotators); + } + data.setElementAnnotators(elementAnnotators); + return ServerConnector.updateUserPreferences({ + user: user, + preferences: data + }); + }).catch(GuiConnector.alert); +}; + +ChooseAnnotatorsDialog.prototype.getAllChildrenTypesIfNeeded = function (elementType, includeChildren) { + var result = [elementType]; + if (includeChildren) { + var queue = [elementType]; + var elementTypes = this.getConfiguration().getElementTypes(); + while (queue.length > 0) { + var type = queue.shift(); + for (var i = 0; i < elementTypes.length; i++) { + if (type.className === elementTypes[i].parentClass) { + queue.push(elementTypes[i]); + result.push(elementTypes[i]); + } + } + } + } + return result; +}; + + ChooseAnnotatorsDialog.prototype.setElementType = function (elementType) { var self = this; - var configuration; + var configuration = self.getConfiguration(); - return ServerConnector.getConfiguration().then(function (result) { - configuration = result; - return ServerConnector.getLoggedUser(); - }).then(function (user) { + return ServerConnector.getLoggedUser().then(function (user) { var element = $("[name='annotatorListBox']", self.getElement())[0]; var annotatorsParams = $(".minerva-annotators-params", self.getElement())[0]; Functions.removeChildren(element); - + var selectElement = Functions.createElement({ - type: "select", - className: "minerva-multi-select" + type: "div", + style: "width:50%; height:200px;float:left; OVERFLOW-Y:scroll" }); - var annotators = configuration.getElementAnnotators(elementType); + element.appendChild(selectElement); + var includeChildrenCheckbox = Functions.createElement({type: "input", inputType: "checkbox"}); + element.appendChild(includeChildrenCheckbox); + element.appendChild(Functions.createElement({type: "span", content: "Apply to all in subtree"})); + element.appendChild(Functions.createElement({type: "br"})); + var copyFromButton = Functions.createElement({ + type: "button", content: "Copy from", onclick: function () { + var typeClassName = copyFromSelect.value; + var annotators; + for (var i = 0; i < configuration.getElementTypes().length; i++) { + var type = configuration.getElementTypes()[i]; + if (typeClassName === type.className) { + annotators = user.getPreferences().getElementAnnotators(typeClassName); + } + } + if (annotators === undefined) { + return GuiConnector.alert("Invalid element type: " + copyFromSelect.value); + } else { + var includeChildren = includeChildrenCheckbox.checked; + return self.saveAnnotatorsInfo(self.getAllChildrenTypesIfNeeded(elementType, includeChildren), annotators).then(function () { + return self.setElementType(elementType); + }); + } + } + }); + element.appendChild(copyFromButton); + var copyFromSelect = Functions.createElement({type: "select", style: "margin:5px"}); + element.appendChild(copyFromSelect); + var options = [], i; + for (i = 0; i < configuration.getElementTypes().length; i++) { + var type = configuration.getElementTypes()[i]; + var name = type.className; + if (name.indexOf(".") > 0) { + name = name.substr(name.lastIndexOf(".") + 1); + } + options.push(Functions.createElement({ + type: "option", + value: type.className, + content: name + })); + } + options.sort(function (a, b) { + return a.text === b.text ? 0 : a.text < b.text ? -1 : 1 + }); + for (i = 0; i < options.length; i++) { + copyFromSelect.appendChild(options[i]); + } + + var annotators = configuration.getElementAnnotators(elementType); var selectedAnnotators = user.getPreferences().getElementAnnotators(elementType.className); - for (var i = 0; i < annotators.length; i++) { + var selectedValues = []; + + var entries = []; + + for (i = 0; i < annotators.length; i++) { var annotator = annotators[i]; - var selected = false; + var entry = {name: annotator.getName(), value: annotator.getClassName(), selected: false}; for (var j = 0; j < selectedAnnotators.length; j++) { if (annotator.getName() === selectedAnnotators[j]) { - selected = true; - } + entry.selected = true; + } } - var option = new Option(); - option.value = annotator.getClassName(); - option.attributes.selected = selected; - option.innerHTML = "<div>" + annotator.getName() + "</div>"; - selectElement.appendChild(option); + entries.push(entry); + } + var checkboxList = new MultiCheckboxList(selectElement, { + entries: entries, + listTitle: "Available annotators", + selectedTitle: "Selected annotators", + selectedList: true + }); + var changeSelection = function (elementId, selected) { + + var annotators = configuration.getElementAnnotators(); + var annotator; + for (var i = 0; i < annotators.length; i++) { + if (elementId === annotators[i].getClassName()) { + annotator = annotators[i]; + } + } + if (selected) { + selectedAnnotators.push(annotator.getName()); + } else { + var index = selectedAnnotators.indexOf(annotator.getName()); + if (index > -1) { + selectedAnnotators.splice(index, 1); + } + } + createAnnotatorsParams(); + var includeChildren = includeChildrenCheckbox.checked; + return self.saveAnnotatorsInfo(self.getAllChildrenTypesIfNeeded(elementType, includeChildren), selectedAnnotators); + }; + includeChildrenCheckbox.onchange = function () { + var includeChildren = includeChildrenCheckbox.checked; + return self.saveAnnotatorsInfo(self.getAllChildrenTypesIfNeeded(elementType, includeChildren), selectedAnnotators); }; - function createAnnotatorsParams(){ + checkboxList.addListener("select", function (element) { + return changeSelection(element.value, true); + }); + checkboxList.addListener("deselect", function (element) { + return changeSelection(element.value, false); + }); + + + function createAnnotatorsParams() { + var existingAnnotatorsParameters = user.getPreferences().getAnnotatorsParameters(); Functions.removeChildren(annotatorsParams); @@ -117,35 +233,34 @@ ChooseAnnotatorsDialog.prototype.setElementType = function (elementType) { var annotator = annotators[i]; for (var j = 0; j < selectedAnnotators.length; j++) { if (annotator.getName() === selectedAnnotators[j]) { - var paramsDefs = annotator.getParametersDefinitions(); if (paramsDefs.length > 0) { - + annotatorsParams.appendChild(Functions.createElement({ - type: "div", + type: "div", className: "minerva-annotators-params-header", content: '<div>Available parameters</div>' - })) - + })); + var annotatorParams = Functions.createElement({ - type: "div", + type: "div", className: "minerva-annotator-params", name: annotator.getClassName() }); - + annotatorParams.appendChild(Functions.createElement({ - type: "div", + type: "div", className: "minerva-annotator-params-header", content: annotator.getName() })); - + for (var k = 0; k < paramsDefs.length; k++) { - var param = paramsDefs[k]; + var param = paramsDefs[k]; var paramElement = Functions.createElement({ - type: "div", + type: "div", className: "minerva-annotator-param" }); - + var paramName = Functions.createElement({ type: "div", className: "minerva-annotator-param-name", @@ -153,10 +268,10 @@ ChooseAnnotatorsDialog.prototype.setElementType = function (elementType) { }); var tooltipContainer = Functions.createElement({ - type: "span" + type: "span" }); tooltipContainer.appendChild(Functions.createElement({ - type: "span", + type: "span", className: "glyphicon glyphicon-question-sign tooltip-icon" })); tooltipContainer.appendChild(Functions.createElement({ @@ -164,104 +279,60 @@ ChooseAnnotatorsDialog.prototype.setElementType = function (elementType) { className: "annotator-tooltip", content: param.description })); - - paramName.appendChild(tooltipContainer) - paramElement.appendChild(paramName); - + + paramName.appendChild(tooltipContainer); + paramElement.appendChild(paramName); + var paramValue; - + var existingParamValue; if (existingAnnotatorsParameters[annotator.getClassName()]) { existingParamValue = existingAnnotatorsParameters[annotator.getClassName()][param.name] } - + if (param.type.indexOf("String") >= 0) { paramValue = Functions.createElement({ type: "textarea", - onchange: function(){return onChangeParameterValue(this, user);} + onchange: function () { + return onChangeParameterValue(this, user); + } }); if (existingParamValue) paramValue.value = existingParamValue; } else if (param.type.indexOf("Integer") >= 0) { paramValue = Functions.createElement({ type: "input", inputType: "number", - onchange: function(){return onChangeParameterValue(this, user);} + onchange: function () { + return onChangeParameterValue(this, user); + } }); if (existingParamValue) paramValue.value = existingParamValue; } else if (param.type.indexOf("Boolean") >= 0) { paramValue = Functions.createElement({ type: "input", inputType: "checkbox", - onchange: function(){return onChangeParameterValue(this, user);} + onchange: function () { + return onChangeParameterValue(this, user); + } }); paramValue.checked = (existingParamValue && existingParamValue === 'true'); } else { throw new InvalidAlgorithmError("Unknown annotator parameter type"); - } - + } + paramElement.appendChild(paramValue); - annotatorParams.appendChild(paramElement); + annotatorParams.appendChild(paramElement); } - + annotatorsParams.appendChild(annotatorParams); } - } - } - }; - - } - createAnnotatorsParams(); - - element.appendChild(selectElement); - new DualListbox(selectElement, { - addEvent: function (value) { - var annotators = configuration.getElementAnnotators(); - var annotator; - for (var i = 0; i < annotators.length; i++) { - if (value === annotators[i].getClassName()) { - annotator = annotators[i]; } } - selectedAnnotators.push(annotator.getName()); + } + } - createAnnotatorsParams(); - - var data = new UserPreferences(); - - var elementAnnotators = {}; - elementAnnotators[elementType.className] = selectedAnnotators; - data.setElementAnnotators(elementAnnotators); - return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert); - }, - removeEvent: function (value) { - var annotators = configuration.getElementAnnotators(); - var annotator; - for (var i = 0; i < annotators.length; i++) { - if (value === annotators[i].getClassName()) { - annotator = annotators[i]; - } - } - var index = selectedAnnotators.indexOf(annotator.getName()); - if (index > -1) { - selectedAnnotators.splice(index, 1); - } + createAnnotatorsParams(); - createAnnotatorsParams(); - - var data = new UserPreferences(); - - var elementAnnotators = {}; - elementAnnotators[elementType.className] = selectedAnnotators; - data.setElementAnnotators(elementAnnotators); - return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert); - }, - availableTitle: 'Available', - selectedTitle: 'Used', - addButtonText: '>', - removeButtonText: '<', - addAllButtonText: '>>', - removeAllButtonText: '<<' - }); }); }; @@ -270,7 +341,7 @@ ChooseAnnotatorsDialog.prototype.init = function () { var self = this; return ServerConnector.getConfiguration().then(function (configuration) { - var treeData = self.createElementTree(configuration); + var treeData = configuration.getElementTypeTree(); var element = $('[name="elementTree"]', self.getElement()); element.jstree({ @@ -287,54 +358,6 @@ ChooseAnnotatorsDialog.prototype.init = function () { }); }; -ChooseAnnotatorsDialog.prototype.createElementTree = function (configuration) { - - var elementTypes = configuration.getElementTypes(); - var reactionTypes = configuration.getReactionTypes(); - - var treeNodes = { - "lcsb.mapviewer.model.map.BioEntity": { - text: "BioEntity", - children: [] - } - }; - - var i; - for (i = 0; i < elementTypes.length; i++) { - var type = elementTypes[i]; - var name = type.className; - if (name.indexOf(".") > 0) { - name = name.substr(name.lastIndexOf(".") + 1); - } - treeNodes[type.className] = { - text: name, - data: type, - children: [] - }; - } - - for (i = 0; i < reactionTypes.length; i++) { - var type = reactionTypes[i]; - treeNodes[type.className] = { - text: type.name, - data: type, - children: [] - }; - } - - for (var treeNodeName in treeNodes) { - if (treeNodes.hasOwnProperty(treeNodeName)) { - var treeNode = treeNodes[treeNodeName]; - if (treeNode.data !== undefined) { - var parentNode = treeNodes[treeNode.data.parentClass]; - parentNode.children.push(treeNode); - } - } - } - - return treeNodes["lcsb.mapviewer.model.map.BioEntity"]; -}; - ChooseAnnotatorsDialog.prototype.destroy = function () { $(this.getElement()).dialog("destroy"); }; @@ -351,8 +374,8 @@ ChooseAnnotatorsDialog.prototype.open = function () { }); } - $(div).dialog("open"); + $(div).css("overflow", "hidden"); }; module.exports = ChooseAnnotatorsDialog; diff --git a/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js b/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js index 5dba50c8917f3a5bcab685c50653529ae7a1a32b..1241d1c4e0eab5527b165a179657f645e62f8106 100644 --- a/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js +++ b/frontend-js/src/main/js/gui/admin/ChooseValidatorsDialog.js @@ -6,6 +6,7 @@ var AbstractGuiElement = require('../AbstractGuiElement'); var DualListbox = require('dual-listbox').DualListbox; var GuiConnector = require("../../GuiConnector"); var UserPreferences = require("../../map/data/UserPreferences"); +var MultiCheckboxList = require("multi-checkbox-list"); var Functions = require('../../Functions'); var logger = require('../../logger'); @@ -25,19 +26,19 @@ ChooseValidatorsDialog.prototype.createGui = function () { var self = this; var content = Functions.createElement({ type: "div", - style: "display:table" + style: "display:table;height:100%;width:100%" }); content.appendChild(Functions.createElement({ type: "div", - style: "display:table-cell", - content: "<div name='elementTree'/>", + style: "display:table-cell;height:100%;", + content: "<div name='elementTree' style='height:100%;overflow-y:scroll;'/>", xss: false })); content.appendChild(Functions.createElement({ type: "div", - style: "display:table-cell", - content: "<div name='annotatorListBox'/>", + style: "display:table-cell;height:100%;width:100%;", + content: "<div name='annotatorListBox' style='height:100%;width:100%;overflow-y:auto;'><span> </span></div>", xss: false })); @@ -79,66 +80,61 @@ ChooseValidatorsDialog.prototype.createValidAnnotationsDualListBox = function (u var validAnnotations = user.getPreferences().getElementValidAnnotations(elementType.className); + var entries = []; + + for (var i = 0; i < miriamTypes.length; i++) { var miriamType = miriamTypes[i]; + var entry = {name: miriamType.getCommonName(), value: miriamType.getName(), selected: false}; + var selected = false; for (var j = 0; j < validAnnotations.length; j++) { if (miriamType.getName() === validAnnotations[j]) { - selected = true; + entry.selected = true; } } - var option = new Option(); - option.value = miriamType.getName(); - option.attributes.selected = selected; - option.innerHTML = "<div>" + miriamType.getCommonName() + "</div>"; - validAnnotationSelect.appendChild(option); + entries.push(entry); } - new DualListbox(validAnnotationSelect, { - addEvent: function (value) { - var miriamTypes = configuration.getMiriamTypes(); - var miriamType; - for (var i = 0; i < miriamTypes.length; i++) { - if (value === miriamTypes[i].getName()) { - miriamType = miriamTypes[i]; - } - } - validAnnotations.push(miriamType.getName()); - - var data = new UserPreferences(); + var checkboxList = new MultiCheckboxList(validAnnotationSelect, { + entries: entries, + listTitle: "Available", + selectedTitle: "Selected", + selectedList: true + }); - var elementAnnotators = {}; - elementAnnotators[elementType.className] = validAnnotations; - data.setElementValidAnnotations(elementAnnotators); - return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert); - }, - removeEvent: function (value) { - var miriamTypes = configuration.getMiriamTypes(); - var miriamType; - for (var i = 0; i < miriamTypes.length; i++) { - if (value === miriamTypes[i].getName()) { - miriamType = miriamTypes[i]; - } + var changeSelection = function (elementId, selected) { + var miriamTypes = configuration.getMiriamTypes(); + var miriamType; + for (var i = 0; i < miriamTypes.length; i++) { + if (elementId === miriamTypes[i].getName()) { + miriamType = miriamTypes[i]; } + } + if (selected) { + validAnnotations.push(miriamType.getName()); + } else { var index = validAnnotations.indexOf(miriamType.getName()); if (index > -1) { validAnnotations.splice(index, 1); } + } - var data = new UserPreferences(); + var data = new UserPreferences(); - var elementAnnotators = {}; - elementAnnotators[elementType.className] = validAnnotations; - data.setElementValidAnnotations(elementAnnotators); - return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert); - }, - availableTitle: 'Available', - selectedTitle: 'Used', - addButtonText: '>', - removeButtonText: '<', - addAllButtonText: '>>', - removeAllButtonText: '<<' + var elementAnnotators = {}; + elementAnnotators[elementType.className] = validAnnotations; + data.setElementValidAnnotations(elementAnnotators); + return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert); + }; + + checkboxList.addListener("select", function (element) { + return changeSelection(element.value, true); }); + checkboxList.addListener("deselect", function (element) { + return changeSelection(element.value, false); + }); + }; ChooseValidatorsDialog.prototype.createVerifyAnnotationsDualListBox = function (user, configuration, elementType, verifyAnnotationSelect) { @@ -162,6 +158,8 @@ ChooseValidatorsDialog.prototype.createVerifyAnnotationsDualListBox = function ( } }); checkbox.checked = requiredAnnotationsData.requiredAtLeastOnce; + verifyCheckboxDiv.appendChild(Functions.createElement({type: "br"})); + verifyCheckboxDiv.appendChild(Functions.createElement({type: "br"})); verifyCheckboxDiv.appendChild(checkbox); verifyCheckboxDiv.appendChild(Functions.createElement({ type: "span", @@ -171,80 +169,69 @@ ChooseValidatorsDialog.prototype.createVerifyAnnotationsDualListBox = function ( var miriamTypes = configuration.getMiriamTypes(); + var entries = []; for (var i = 0; i < miriamTypes.length; i++) { var miriamType = miriamTypes[i]; - var selected = false; + var entry = {name: miriamType.getCommonName(), value: miriamType.getName(), selected: false}; for (var j = 0; j < requiredAnnotationsData.list.length; j++) { if (miriamType.getName() === requiredAnnotationsData.list[j]) { - selected = true; + entry.selected = true; } } - var option = new Option(); - option.value = miriamType.getName(); - option.attributes.selected = selected; - option.innerHTML = "<div>" + miriamType.getCommonName() + "</div>"; - verifyAnnotationSelect.appendChild(option); + entries.push(entry); } - new DualListbox(verifyAnnotationSelect, { - addEvent: function (value) { - var miriamTypes = configuration.getMiriamTypes(); - var miriamType; - for (var i = 0; i < miriamTypes.length; i++) { - if (value === miriamTypes[i].getName()) { - miriamType = miriamTypes[i]; - } - } - requiredAnnotationsData.list.push(miriamType.getName()); + var checkboxList = new MultiCheckboxList(verifyAnnotationSelect, { + entries: entries, + listTitle: "Available", + selectedTitle: "Selected", + selectedList: true + }); - var data = new UserPreferences(); + var changeSelection = function (elementId, selected) { - var elementRequiredAnnotations = {}; - elementRequiredAnnotations[elementType.className] = { - "require-at-least-one": requiredAnnotationsData.requiredAtLeastOnce, - "annotation-list": requiredAnnotationsData.list - }; - data.setElementRequiredAnnotations(elementRequiredAnnotations); - return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert); - }, - removeEvent: function (value) { - var miriamTypes = configuration.getMiriamTypes(); - var miriamType; - for (var i = 0; i < miriamTypes.length; i++) { - if (value === miriamTypes[i].getName()) { - miriamType = miriamTypes[i]; - } + var miriamTypes = configuration.getMiriamTypes(); + var miriamType; + for (var i = 0; i < miriamTypes.length; i++) { + if (elementId === miriamTypes[i].getName()) { + miriamType = miriamTypes[i]; } + } + if (selected) { + requiredAnnotationsData.list.push(miriamType.getName()); + } else { var index = requiredAnnotationsData.list.indexOf(miriamType.getName()); if (index > -1) { requiredAnnotationsData.list.splice(index, 1); } + } - var data = new UserPreferences(); + var data = new UserPreferences(); - var elementRequiredAnnotations = {}; - elementRequiredAnnotations[elementType.className] = { - "require-at-least-one": requiredAnnotationsData.requiredAtLeastOnce, - "annotation-list": requiredAnnotationsData.list - }; - data.setElementRequiredAnnotations(elementRequiredAnnotations); - return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert); - }, - availableTitle: 'Available', - selectedTitle: 'Used', - addButtonText: '>', - removeButtonText: '<', - addAllButtonText: '>>', - removeAllButtonText: '<<' + var elementRequiredAnnotations = {}; + elementRequiredAnnotations[elementType.className] = { + "require-at-least-one": requiredAnnotationsData.requiredAtLeastOnce, + "annotation-list": requiredAnnotationsData.list + }; + data.setElementRequiredAnnotations(elementRequiredAnnotations); + return ServerConnector.updateUserPreferences({user: user, preferences: data}).then(null, GuiConnector.alert); + }; + + checkboxList.addListener("select", function (element) { + return changeSelection(element.value, true); + }); + checkboxList.addListener("deselect", function (element) { + return changeSelection(element.value, false); }); + }; ChooseValidatorsDialog.prototype.init = function () { var self = this; return ServerConnector.getConfiguration().then(function (configuration) { - var treeData = self.createElementTree(configuration); + var treeData = configuration.getElementTypeTree(); var element = $('[name="elementTree"]', self.getElement()); element.jstree({ @@ -261,54 +248,6 @@ ChooseValidatorsDialog.prototype.init = function () { }); }; -ChooseValidatorsDialog.prototype.createElementTree = function (configuration) { - - var elementTypes = configuration.getElementTypes(); - var reactionTypes = configuration.getReactionTypes(); - - var treeNodes = { - "lcsb.mapviewer.model.map.BioEntity": { - text: "BioEntity", - children: [] - } - }; - - var i, type; - for (i = 0; i < elementTypes.length; i++) { - type = elementTypes[i]; - var name = type.className; - if (name.indexOf(".") > 0) { - name = name.substr(name.lastIndexOf(".") + 1); - } - treeNodes[type.className] = { - text: name, - data: type, - children: [] - }; - } - - for (i = 0; i < reactionTypes.length; i++) { - type = reactionTypes[i]; - treeNodes[type.className] = { - text: type.name, - data: type, - children: [] - }; - } - - for (var treeNodeName in treeNodes) { - if (treeNodes.hasOwnProperty(treeNodeName)) { - var treeNode = treeNodes[treeNodeName]; - if (treeNode.data !== undefined) { - var parentNode = treeNodes[treeNode.data.parentClass]; - parentNode.children.push(treeNode); - } - } - } - - return treeNodes["lcsb.mapviewer.model.map.BioEntity"]; -}; - ChooseValidatorsDialog.prototype.destroy = function () { $(this.getElement()).dialog("destroy"); }; diff --git a/frontend-js/src/main/js/map/data/UserPreferences.js b/frontend-js/src/main/js/map/data/UserPreferences.js index 750c29555351c6e3217462e1f2f4ed5feb93902b..36ff821d76c9f6f184047d51a2875af2ce813b6a 100644 --- a/frontend-js/src/main/js/map/data/UserPreferences.js +++ b/frontend-js/src/main/js/map/data/UserPreferences.js @@ -81,7 +81,8 @@ UserPreferences.prototype.setElementAnnotators = function (elementAnnotators) { UserPreferences.prototype.getElementAnnotators = function (className) { var result = this._elementAnnotators[className]; if (result === undefined) { - result = []; + this._elementAnnotators[className] = []; + result = this._elementAnnotators[className]; } return result; }; diff --git a/frontend-js/src/test/js/Configuration-test.js b/frontend-js/src/test/js/Configuration-test.js index 6a8adcbc5611e90a3b5253e970e9884ef38b3bb4..e8aadbf1284d8bee39e41b3fcac7bf81b1fa4185 100644 --- a/frontend-js/src/test/js/Configuration-test.js +++ b/frontend-js/src/test/js/Configuration-test.js @@ -107,4 +107,18 @@ describe('Configuration', function () { }); }); }); + + it('getElementTypeTree', function () { + + return ServerConnector.getConfiguration().then(function (configuration) { + var treeData = configuration.getElementTypeTree(); + + assert.ok(treeData); + assert.ok(treeData.text); + assert.ok(treeData.children); + assert.equal(2, treeData.children.length); + }) + }); + + }); diff --git a/frontend-js/src/test/js/gui/admin/ChooseAnnotatorsDialog-test.js b/frontend-js/src/test/js/gui/admin/ChooseAnnotatorsDialog-test.js index e7e321353be67a636b60147947759b85ba43662b..ee6700ba892626c817a31ae7d9f0aa772b8fd67e 100644 --- a/frontend-js/src/test/js/gui/admin/ChooseAnnotatorsDialog-test.js +++ b/frontend-js/src/test/js/gui/admin/ChooseAnnotatorsDialog-test.js @@ -10,38 +10,50 @@ var chai = require('chai'); var assert = chai.assert; describe('ChooseAnnotatorsDialog', function () { - it('init', function () { - var dialog = new ChooseAnnotatorsDialog({ + function createDialog() { + return new ChooseAnnotatorsDialog({ element: testDiv, - customMap: null + customMap: null, + configuration: helper.getConfiguration() }); + } + + it('init', function () { + var dialog = createDialog(); assert.equal(0, logger.getWarnings().length); return dialog.init(); }); - it('createElementTree', function () { - var dialog = new ChooseAnnotatorsDialog({ - element: testDiv, - customMap: null - }); + it('setElementType', function () { + var dialog = createDialog(); return ServerConnector.getConfiguration().then(function (configuration) { - var treeData = dialog.createElementTree(configuration); - - assert.ok(treeData); - assert.ok(treeData.text); - assert.ok(treeData.children); - assert.equal(2, treeData.children.length); + return dialog.setElementType(configuration.getReactionTypes()[0]); }) }); - it('setElementType', function () { - var dialog = new ChooseAnnotatorsDialog({ - element: testDiv, - customMap: null + it('saveAnnotatorsInfo', function () { + var dialog = createDialog(); + var user; + return ServerConnector.getLoggedUser().then(function (result) { + user = result; + return ServerConnector.getConfiguration(); + }).then(function (configuration) { + var elementTypes = configuration.getElementTypes(); + return dialog.saveAnnotatorsInfo(elementTypes, []); }); - return ServerConnector.getConfiguration().then(function (configuration) { - return dialog.setElementType(configuration.getReactionTypes()[0]); - }) }); + it('getAllChildrenTypesIfNeeded', function () { + var dialog = createDialog(); + var configuration = helper.getConfiguration(); + var elementTypes = configuration.getElementTypes(); + var elementType; + for (var i = 0; i < elementTypes.length; i++) { + if (elementTypes[i].className === "lcsb.mapviewer.model.map.species.Protein") { + elementType = elementTypes[i]; + } + } + assert.equal(1, dialog.getAllChildrenTypesIfNeeded(elementType, false).length); + assert.ok(dialog.getAllChildrenTypesIfNeeded(elementType, true).length >= 5); + }); }); diff --git a/frontend-js/src/test/js/gui/admin/ChooseValidatorsDialog-test.js b/frontend-js/src/test/js/gui/admin/ChooseValidatorsDialog-test.js index ef96a952b42b83c668ae49e1f15afef37967b8d9..b92f7df9a55b821cb149554cf615923f9c926e58 100644 --- a/frontend-js/src/test/js/gui/admin/ChooseValidatorsDialog-test.js +++ b/frontend-js/src/test/js/gui/admin/ChooseValidatorsDialog-test.js @@ -19,21 +19,6 @@ describe('ChooseValidatorsDialog', function () { return dialog.init(); }); - it('createElementTree', function () { - var dialog = new ChooseValidatorsDialog({ - element: testDiv, - customMap: null - }); - return ServerConnector.getConfiguration().then(function (configuration) { - var treeData = dialog.createElementTree(configuration); - - assert.ok(treeData); - assert.ok(treeData.text); - assert.ok(treeData.children); - assert.equal(2, treeData.children.length); - }) - }); - it('setElementType', function () { var dialog = new ChooseValidatorsDialog({ element: testDiv, diff --git a/frontend-js/testFiles/apiCalls/users/anonymous.updatePreferences/PATCH_token=MOCK_TOKEN_ID& b/frontend-js/testFiles/apiCalls/users/anonymous.updatePreferences/PATCH_token=MOCK_TOKEN_ID& new file mode 100644 index 0000000000000000000000000000000000000000..c194425b27770302c4302d9cb07dcb579ff46a44 --- /dev/null +++ b/frontend-js/testFiles/apiCalls/users/anonymous.updatePreferences/PATCH_token=MOCK_TOKEN_ID& @@ -0,0 +1 @@ +{"preferences":{"annotators-parameters":{},"element-annotators":{"lcsb.mapviewer.model.map.BioEntity":[],"lcsb.mapviewer.model.map.compartment.BottomSquareCompartment":["Gene Ontology"],"lcsb.mapviewer.model.map.compartment.Compartment":["Gene Ontology"],"lcsb.mapviewer.model.map.compartment.LeftSquareCompartment":["Gene Ontology"],"lcsb.mapviewer.model.map.compartment.OvalCompartment":["Gene Ontology"],"lcsb.mapviewer.model.map.compartment.PathwayCompartment":["Gene Ontology"],"lcsb.mapviewer.model.map.compartment.RightSquareCompartment":["Gene Ontology"],"lcsb.mapviewer.model.map.compartment.SquareCompartment":["Gene Ontology"],"lcsb.mapviewer.model.map.compartment.TopSquareCompartment":["Gene Ontology"],"lcsb.mapviewer.model.map.reaction.Reaction":[],"lcsb.mapviewer.model.map.reaction.type.BooleanLogicGateReaction":[],"lcsb.mapviewer.model.map.reaction.type.DissociationReaction":[],"lcsb.mapviewer.model.map.reaction.type.HeterodimerAssociationReaction":[],"lcsb.mapviewer.model.map.reaction.type.KnownTransitionOmittedReaction":[],"lcsb.mapviewer.model.map.reaction.type.NegativeInfluenceReaction":[],"lcsb.mapviewer.model.map.reaction.type.PositiveInfluenceReaction":[],"lcsb.mapviewer.model.map.reaction.type.ReducedModulationReaction":[],"lcsb.mapviewer.model.map.reaction.type.ReducedPhysicalStimulationReaction":[],"lcsb.mapviewer.model.map.reaction.type.ReducedTriggerReaction":[],"lcsb.mapviewer.model.map.reaction.type.StateTransitionReaction":[],"lcsb.mapviewer.model.map.reaction.type.TranscriptionReaction":[],"lcsb.mapviewer.model.map.reaction.type.TranslationReaction":[],"lcsb.mapviewer.model.map.reaction.type.TransportReaction":[],"lcsb.mapviewer.model.map.reaction.type.TruncationReaction":[],"lcsb.mapviewer.model.map.reaction.type.UnknownNegativeInfluenceReaction":[],"lcsb.mapviewer.model.map.reaction.type.UnknownPositiveInfluenceReaction":[],"lcsb.mapviewer.model.map.reaction.type.UnknownReducedModulationReaction":[],"lcsb.mapviewer.model.map.reaction.type.UnknownReducedPhysicalStimulationReaction":[],"lcsb.mapviewer.model.map.reaction.type.UnknownReducedTriggerReaction":[],"lcsb.mapviewer.model.map.reaction.type.UnknownTransitionReaction":[],"lcsb.mapviewer.model.map.species.AntisenseRna":[],"lcsb.mapviewer.model.map.species.Chemical":["Chebi"],"lcsb.mapviewer.model.map.species.Complex":["Gene Ontology"],"lcsb.mapviewer.model.map.species.Degraded":[],"lcsb.mapviewer.model.map.species.Drug":[],"lcsb.mapviewer.model.map.species.Element":[],"lcsb.mapviewer.model.map.species.Gene":["HGNC"],"lcsb.mapviewer.model.map.species.GenericProtein":["Biocompendium","HGNC"],"lcsb.mapviewer.model.map.species.Ion":["Chebi"],"lcsb.mapviewer.model.map.species.IonChannelProtein":["Biocompendium","HGNC"],"lcsb.mapviewer.model.map.species.Phenotype":["Gene Ontology"],"lcsb.mapviewer.model.map.species.Protein":["Biocompendium","HGNC"],"lcsb.mapviewer.model.map.species.ReceptorProtein":["Biocompendium","HGNC"],"lcsb.mapviewer.model.map.species.Rna":["HGNC"],"lcsb.mapviewer.model.map.species.SimpleMolecule":["Chebi"],"lcsb.mapviewer.model.map.species.Species":[],"lcsb.mapviewer.model.map.species.TruncatedProtein":["Biocompendium","HGNC"],"lcsb.mapviewer.model.map.species.Unknown":[]},"element-required-annotations":{"lcsb.mapviewer.model.map.BioEntity":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.compartment.BottomSquareCompartment":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.compartment.Compartment":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.compartment.LeftSquareCompartment":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.compartment.OvalCompartment":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.compartment.PathwayCompartment":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.compartment.RightSquareCompartment":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.compartment.SquareCompartment":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.compartment.TopSquareCompartment":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.Reaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.BooleanLogicGateReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.DissociationReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.HeterodimerAssociationReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.KnownTransitionOmittedReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.NegativeInfluenceReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.PositiveInfluenceReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.ReducedModulationReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.ReducedPhysicalStimulationReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.ReducedTriggerReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.StateTransitionReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.TranscriptionReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.TranslationReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.TransportReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.TruncationReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.UnknownNegativeInfluenceReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.UnknownPositiveInfluenceReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.UnknownReducedModulationReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.UnknownReducedPhysicalStimulationReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.UnknownReducedTriggerReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.reaction.type.UnknownTransitionReaction":{"annotation-list":["PUBMED"],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.AntisenseRna":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.Chemical":{"annotation-list":["CHEBI","PUBCHEM","PUBCHEM_SUBSTANCE"],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.Complex":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.Degraded":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.Drug":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.Element":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.Gene":{"annotation-list":["HGNC","HGNC_SYMBOL"],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.GenericProtein":{"annotation-list":["HGNC","HGNC_SYMBOL"],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.Ion":{"annotation-list":["CHEBI","PUBCHEM","PUBCHEM_SUBSTANCE"],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.IonChannelProtein":{"annotation-list":["HGNC","HGNC_SYMBOL"],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.Phenotype":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.Protein":{"annotation-list":["HGNC","HGNC_SYMBOL"],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.ReceptorProtein":{"annotation-list":["HGNC","HGNC_SYMBOL"],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.Rna":{"annotation-list":["HGNC","HGNC_SYMBOL"],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.SimpleMolecule":{"annotation-list":["CHEBI","PUBCHEM","PUBCHEM_SUBSTANCE"],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.Species":{"annotation-list":[],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.TruncatedProtein":{"annotation-list":["HGNC","HGNC_SYMBOL","CHEMBL_COMPOUND"],"require-at-least-one":true},"lcsb.mapviewer.model.map.species.Unknown":{"annotation-list":[],"require-at-least-one":true}},"element-valid-annotations":{"lcsb.mapviewer.model.map.BioEntity":["PUBMED"],"lcsb.mapviewer.model.map.compartment.BottomSquareCompartment":["GO","MESH_2012","PUBMED"],"lcsb.mapviewer.model.map.compartment.Compartment":["GO","MESH_2012","PUBMED"],"lcsb.mapviewer.model.map.compartment.LeftSquareCompartment":["GO","MESH_2012","PUBMED"],"lcsb.mapviewer.model.map.compartment.OvalCompartment":["GO","MESH_2012","PUBMED"],"lcsb.mapviewer.model.map.compartment.PathwayCompartment":["GO","MESH_2012","PUBMED"],"lcsb.mapviewer.model.map.compartment.RightSquareCompartment":["GO","MESH_2012","PUBMED"],"lcsb.mapviewer.model.map.compartment.SquareCompartment":["GO","MESH_2012","PUBMED"],"lcsb.mapviewer.model.map.compartment.TopSquareCompartment":["GO","MESH_2012","PUBMED"],"lcsb.mapviewer.model.map.reaction.Reaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.BooleanLogicGateReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.DissociationReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.HeterodimerAssociationReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.KnownTransitionOmittedReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.NegativeInfluenceReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.PositiveInfluenceReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.ReducedModulationReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.ReducedPhysicalStimulationReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.ReducedTriggerReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.StateTransitionReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.TranscriptionReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.TranslationReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.TransportReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.TruncationReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.UnknownNegativeInfluenceReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.UnknownPositiveInfluenceReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.UnknownReducedModulationReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.UnknownReducedPhysicalStimulationReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.UnknownReducedTriggerReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.reaction.type.UnknownTransitionReaction":["KEGG_PATHWAY","KEGG_REACTION","PUBMED","REACTOME"],"lcsb.mapviewer.model.map.species.AntisenseRna":["PUBMED"],"lcsb.mapviewer.model.map.species.Chemical":["CHEBI","HMDB","KEGG_COMPOUND","PUBCHEM","PUBCHEM_SUBSTANCE","PUBMED"],"lcsb.mapviewer.model.map.species.Complex":["CHEMBL_TARGET","EC","GO","INTERPRO","MESH_2012","PUBMED"],"lcsb.mapviewer.model.map.species.Degraded":["PUBMED"],"lcsb.mapviewer.model.map.species.Drug":["CHEBI","CHEMBL_COMPOUND","DRUGBANK","HMDB","PUBMED"],"lcsb.mapviewer.model.map.species.Element":["PUBMED"],"lcsb.mapviewer.model.map.species.Gene":["ENSEMBL","ENTREZ","HGNC","HGNC_SYMBOL","KEGG_GENES","MGD","PANTHER","PUBMED","REFSEQ","UNIPROT"],"lcsb.mapviewer.model.map.species.GenericProtein":["CHEMBL_TARGET","EC","ENSEMBL","ENTREZ","HGNC","HGNC_SYMBOL","INTERPRO","KEGG_GENES","MGD","PANTHER","PUBMED","REFSEQ","UNIPROT","UNIPROT_ISOFORM"],"lcsb.mapviewer.model.map.species.Ion":["CHEBI","HMDB","KEGG_COMPOUND","PUBCHEM","PUBCHEM_SUBSTANCE","PUBMED"],"lcsb.mapviewer.model.map.species.IonChannelProtein":["CHEMBL_TARGET","EC","ENSEMBL","ENTREZ","HGNC","HGNC_SYMBOL","INTERPRO","KEGG_GENES","MGD","PANTHER","PUBMED","REFSEQ","UNIPROT","UNIPROT_ISOFORM"],"lcsb.mapviewer.model.map.species.Phenotype":["GO","MESH_2012","OMIM","PUBMED"],"lcsb.mapviewer.model.map.species.Protein":["CHEMBL_TARGET","EC","ENSEMBL","ENTREZ","HGNC","HGNC_SYMBOL","INTERPRO","KEGG_GENES","MGD","PANTHER","PUBMED","REFSEQ","UNIPROT","UNIPROT_ISOFORM","CHEMBL_COMPOUND"],"lcsb.mapviewer.model.map.species.ReceptorProtein":["CHEMBL_TARGET","EC","ENSEMBL","ENTREZ","HGNC","HGNC_SYMBOL","INTERPRO","KEGG_GENES","MGD","PANTHER","PUBMED","REFSEQ","UNIPROT","UNIPROT_ISOFORM"],"lcsb.mapviewer.model.map.species.Rna":["ENSEMBL","ENTREZ","HGNC","HGNC_SYMBOL","KEGG_GENES","MGD","PANTHER","PUBMED","REFSEQ","UNIPROT"],"lcsb.mapviewer.model.map.species.SimpleMolecule":["CHEBI","HMDB","KEGG_COMPOUND","PUBCHEM","PUBCHEM_SUBSTANCE","PUBMED"],"lcsb.mapviewer.model.map.species.Species":["PUBMED"],"lcsb.mapviewer.model.map.species.TruncatedProtein":["CHEMBL_TARGET","EC","ENSEMBL","ENTREZ","HGNC","HGNC_SYMBOL","INTERPRO","KEGG_GENES","MGD","PANTHER","PUBMED","REFSEQ","UNIPROT","UNIPROT_ISOFORM","CHEMBL_COMPOUND"],"lcsb.mapviewer.model.map.species.Unknown":["PUBMED"]},"gui-preferences":{"admin-projects-datatable-length":"10"},"project-upload":{"annotate-model":false,"auto-resize":true,"cache-data":false,"sbgn":false,"semantic-zooming":false,"validate-miriam":true}}} \ No newline at end of file