diff --git a/.travis.yml b/.travis.yml index 4cf8e094946..7adf219d81c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,8 @@ matrix: services: - docker + cache: pip + before_install: - python --version - uname -a diff --git a/api/specs/shared/schemas/node-output-tree-api-v0.0.1.yaml b/api/specs/shared/schemas/node-output-tree-api-v0.0.1.yaml new file mode 100644 index 00000000000..5a58806f831 --- /dev/null +++ b/api/specs/shared/schemas/node-output-tree-api-v0.0.1.yaml @@ -0,0 +1,53 @@ +$schema: http://json-schema.org/draft-07/schema# +$id: https://simcore.io/api/specs/shared/schemas/node-output-tree-api-v0.0.1.yaml + +title: node output tree api +description: nodes using the tree representation for the output + must be able to handle the following requests +type: object +required: + # the validator does not appreciate when required is missing here... and + # sadly does not throw any meaningful error about it... so for now I put this... + - getItemList + - getItem +properties: + getItemList: + description: a list of items making up one level of the tree + type: object + properties: + request: + summary: oa3 json schema description of the request structure. + description: | + If no `rootKey` is specified, the first level of the tree is returned. + The `filter` will return any items matching the filter string as well as any + folder items containing matching items further down the tree. + type: object + properties: + rootKey: + type: string + filter: + type: string + response: + type: array + items: + type: object + properties: + key: + type: string + label: + type: string + folder: + type: boolean + getItem: + description: get details about an item in the list + type: object + properties: + request: + type: object + required: + - key + properties: + key: + type: string + response: + type: object diff --git a/api/specs/webserver/v0/node-v0.0.1.yaml b/api/specs/webserver/v0/node-v0.0.1.yaml index e0b9106e7e4..0c42d1b865d 100644 --- a/api/specs/webserver/v0/node-v0.0.1.yaml +++ b/api/specs/webserver/v0/node-v0.0.1.yaml @@ -69,8 +69,10 @@ paths: schema: type: object # oneOf: - # - $ref: '../../shared/schemas/node-output-list-api-v0.0.1.yaml#/properties/getItemList/request' - # - $ref: '../../shared/schemas/node-output-list-api-v0.0.1.yaml#/properties/getItem/request' + # - $ref: '../../shared/schemas/node-output-list-api-v0.0.1.yaml#/properties/getItemList/properties/request' + # - $ref: '../../shared/schemas/node-output-list-api-v0.0.1.yaml#/properties/getItem/properties/request' + # - $ref: '../../shared/schemas/node-output-tree-api-v0.0.1.yaml#/properties/getItemList/properties/request' + # - $ref: '../../shared/schemas/node-output-tree-api-v0.0.1.yaml#/properties/getItem/properties/request' responses: default: description: node type specific api call according to the node type presented @@ -79,8 +81,10 @@ paths: schema: type: object # oneOf: - # - $ref: '../../shared/schemas/node-output-list-api-v0.0.1.yaml#/properties/getItemList/response' - # - $ref: '../../shared/schemas/node-output-list-api-v0.0.1.yaml#/properties/getItem/response' + # - $ref: '../../shared/schemas/node-output-list-api-v0.0.1.yaml#/properties/getItemList/properties/response' + # - $ref: '../../shared/schemas/node-output-list-api-v0.0.1.yaml#/properties/getItem/properties/response' + # - $ref: '../../shared/schemas/node-output-tree-api-v0.0.1.yaml#/properties/getItemList/properties/response' + # - $ref: '../../shared/schemas/node-output-tree-api-v0.0.1.yaml#/properties/getItem/properties/response' /node/{nodeInstanceUUID}/iframe: get: @@ -122,10 +126,6 @@ components: type: string config: type: object - apiCalls: - type: object - # oneOf: - # - $ref: '../../shared/schemas/node-output-list-api-v0.0.1.yaml#/properties' outputApiCall: type: object properties: diff --git a/services/apihub/tests/requirements.txt b/services/apihub/tests/requirements.txt index da5de527fbc..12b03b4a3c7 100644 --- a/services/apihub/tests/requirements.txt +++ b/services/apihub/tests/requirements.txt @@ -5,6 +5,6 @@ openapi_spec_validator pytest~=3.6 pytest-cov~=2.5 pytest-docker~=0.6 -requests~=2.18 +requests==2.20.1 requests-html~=0.9 openapi_core diff --git a/services/director/requirements/base.txt b/services/director/requirements/base.txt index a8a8d8bad55..863664a2d02 100644 --- a/services/director/requirements/base.txt +++ b/services/director/requirements/base.txt @@ -2,5 +2,5 @@ # Please keep alphabetical order aiohttp==3.3.2 docker==3.5.0 -requests==2.19.1 +requests==2.20.1 tenacity==4.12.0 \ No newline at end of file diff --git a/services/storage/requirements/base.txt b/services/storage/requirements/base.txt index d6dd8cbed97..bf98a5d195d 100644 --- a/services/storage/requirements/base.txt +++ b/services/storage/requirements/base.txt @@ -15,7 +15,7 @@ passlib==1.7.1 # See http://initd.org/psycopg/docs/install.html#binary-install-from-pypi psycopg2-binary==2.7.5 python-socketio==1.9.0 -requests==2.19.0 +requests==2.20.1 sqlalchemy==1.2.9 tenacity==4.12.0 trafaret-config==2.0.1 diff --git a/services/web/client/source/class/qxapp/component/form/Auto.js b/services/web/client/source/class/qxapp/component/form/Auto.js index 675d1288bec..207cc21c6eb 100644 --- a/services/web/client/source/class/qxapp/component/form/Auto.js +++ b/services/web/client/source/class/qxapp/component/form/Auto.js @@ -66,7 +66,14 @@ qx.Class.define("qxapp.component.form.Auto", { /** * @param structure {Array} form structure */ - construct : function(content) { + construct : function(content, nodeModel) { + // nodeModel is necessary for creating links + if (nodeModel) { + this.setNodeModel(nodeModel); + } else { + this.setNodeModel(null); + } + this.base(arguments); this.__ctrlMap = {}; this.__ctrlLinkMap = {}; @@ -86,6 +93,13 @@ qx.Class.define("qxapp.component.form.Auto", { this); }, + properties: { + nodeModel: { + check: "qxapp.data.model.NodeModel", + nullable: true + } + }, + events : { /** * fire when the form changes content and @@ -530,7 +544,17 @@ qx.Class.define("qxapp.component.form.Auto", { nodeUuid: fromNodeId, output: fromPortId }; - this.getControlLink(toPortId).setValue("Linked to " + fromNodeId + ": " + fromPortId); + + const workbenchModel = this.getNodeModel().getWorkbenchModel(); + const fromNode = workbenchModel.getNodeModel(fromNodeId); + const fromNodeLabel = fromNode.getLabel(fromNodeId); + const port = fromNode.getOutput(fromPortId); + const fromPortLabel = port ? port.label : null; + if (fromNodeLabel && fromPortLabel) { + this.getControlLink(toPortId).setValue("Linked to " + fromNodeLabel + ": " + fromPortLabel); + } else { + this.getControlLink(toPortId).setValue("Linked to " + fromNodeId + ": " + fromPortId); + } this.fireDataEvent("linkAdded", toPortId); }, diff --git a/services/web/client/source/class/qxapp/component/form/renderer/PropForm.js b/services/web/client/source/class/qxapp/component/form/renderer/PropForm.js index aa0be3c39c9..8b2435f8118 100644 --- a/services/web/client/source/class/qxapp/component/form/renderer/PropForm.js +++ b/services/web/client/source/class/qxapp/component/form/renderer/PropForm.js @@ -21,9 +21,17 @@ qx.Class.define("qxapp.component.form.renderer.PropForm", { * * @param vizWidget {Widget} visualization widget to embedd */ - construct: function(form, nodeModel) { + construct: function(form, workbenchModel, nodeModel) { + // workbenchModel and nodeModel are necessary for creating links + if (workbenchModel) { + this.setWorkbenchModel(workbenchModel); + } else { + this.setWorkbenchModel(null); + } if (nodeModel) { this.setNodeModel(nodeModel); + } else { + this.setNodeModel(null); } this.base(arguments, form); @@ -40,8 +48,14 @@ qx.Class.define("qxapp.component.form.renderer.PropForm", { }, properties: { + workbenchModel: { + check: "qxapp.data.model.WorkbenchModel", + nullable: true + }, + nodeModel: { - check: "qxapp.data.model.NodeModel" + check: "qxapp.data.model.NodeModel", + nullable: true } }, @@ -145,12 +159,19 @@ qx.Class.define("qxapp.component.form.renderer.PropForm", { } }, - __arePortsCompatible: function(node1, port1, node2, port2) { - return qxapp.data.Store.getInstance().arePortsCompatible(node1, port1, node2, port2); + __arePortsCompatible: function(node1Id, port1Id, node2Id, port2Id) { + if (this.getWorkbenchModel()) { + const node1 = this.getWorkbenchModel().getNodeModel(node1Id); + const port1 = node1.getOutput(port1Id); + const node2 = this.getWorkbenchModel().getNodeModel(node2Id); + const port2 = node2.getInput(port2Id); + return qxapp.data.Store.getInstance().arePortsCompatible(port1, port2); + } + return false; }, __createDropMechanism: function(uiElement, portId) { - if (this.isPropertyInitialized("nodeModel")) { + if (this.getNodeModel()) { uiElement.setDroppable(true); uiElement.nodeId = this.getNodeModel().getNodeId(); uiElement.portId = portId; diff --git a/services/web/client/source/class/qxapp/component/widget/InputsMapper.js b/services/web/client/source/class/qxapp/component/widget/InputsMapper.js index ef638470abc..bbe2f7e8757 100644 --- a/services/web/client/source/class/qxapp/component/widget/InputsMapper.js +++ b/services/web/client/source/class/qxapp/component/widget/InputsMapper.js @@ -22,7 +22,7 @@ qx.Class.define("qxapp.component.widget.InputsMapper", { let that = this; tree.setDelegate({ - createItem: () => new qxapp.component.widget.inputs.NodeOutputListItem(), + createItem: () => new qxapp.component.widget.inputs.NodeOutputTreeItem(), bindItem: (c, item, id) => { c.bindDefaultProperties(item, id); // c.bindProperty("key", "key", null, item, id); @@ -78,7 +78,7 @@ qx.Class.define("qxapp.component.widget.InputsMapper", { const nodeInstanceUUID = null; const itemProps = qxapp.data.Store.getInstance().getItem(nodeInstanceUUID, fromPortKey, newItem.getKey()); if (itemProps) { - let form = new qxapp.component.form.Auto(itemProps); + let form = new qxapp.component.form.Auto(itemProps, this.getNodeModel()); let propsWidget = new qxapp.component.form.renderer.PropForm(form); newItem["propsWidget"] = propsWidget; } diff --git a/services/web/client/source/class/qxapp/component/widget/NodePorts.js b/services/web/client/source/class/qxapp/component/widget/NodePorts.js index 628f28c1b0b..66b28571483 100644 --- a/services/web/client/source/class/qxapp/component/widget/NodePorts.js +++ b/services/web/client/source/class/qxapp/component/widget/NodePorts.js @@ -62,7 +62,7 @@ qx.Class.define("qxapp.component.widget.NodePorts", { return this.getNodeModel().getMetaData(); }, - populateNodeLayout: function() { + populatePortsData: function() { const metaData = this.getNodeModel().getMetaData(); this.__inputPort = {}; this.__outputPort = {}; @@ -92,8 +92,9 @@ qx.Class.define("qxapp.component.widget.NodePorts", { let widget = null; switch (port.type) { case "node-output-list-api-v0.0.1": { - let nodeOutputList = new qxapp.component.widget.inputs.NodeOutputList(this.getNodeModel(), port, portKey); - widget = nodeOutputList.getOutputWidget(); + console.log("widget for ", port.type, " to be implemented"); + // let nodeOutputList = new qxapp.component.widget.inputs.NodeOutputList(this.getNodeModel(), port, portKey); + // widget = nodeOutputList.getOutputWidget(); break; } case "node-output-list-icon-api-v0.0.1": { @@ -101,6 +102,11 @@ qx.Class.define("qxapp.component.widget.NodePorts", { widget = nodeOutputList.getOutputWidget(); break; } + case "node-output-tree-api-v0.0.1": { + let nodeOutputList = new qxapp.component.widget.inputs.NodeOutputTree(this.getNodeModel(), port, portKey); + widget = nodeOutputList.getOutputWidget(); + break; + } } if (widget !== null) { this._add(widget, { diff --git a/services/web/client/source/class/qxapp/component/widget/inputs/NodeOutputLabel.js b/services/web/client/source/class/qxapp/component/widget/inputs/NodeOutputLabel.js index 27c3509a99c..c9966d14eb0 100644 --- a/services/web/client/source/class/qxapp/component/widget/inputs/NodeOutputLabel.js +++ b/services/web/client/source/class/qxapp/component/widget/inputs/NodeOutputLabel.js @@ -1,3 +1,17 @@ +/* ************************************************************************ + Copyright: 2018 ITIS Foundation + License: MIT + Authors: Odei Maiz + Utf8Check: äöü +************************************************************************ */ + +/** + * Creates the widget that shows the outputs of the node in a key: value way. + * If the value is an object, it will show the internal key-value pairs + * [PortLabel]: [PortValue] + * + */ + qx.Class.define("qxapp.component.widget.inputs.NodeOutputLabel", { extend: qx.ui.core.Widget, @@ -6,15 +20,28 @@ qx.Class.define("qxapp.component.widget.inputs.NodeOutputLabel", { this.setNodeModel(nodeModel); - let toolTip = new qx.ui.tooltip.ToolTip(port.description); - let portLabel = this.__portLabel = new qx.ui.basic.Label(port.label).set({ - toolTip: toolTip, - textAlign: "right", - allowGrowX: true, - paddingRight: 20 + this._setLayout(new qx.ui.layout.HBox(5)); + + let portLabel = this._createChildControlImpl("portLabel"); + portLabel.set({ + value: "" + port.label + ": ", + toolTip: new qx.ui.tooltip.ToolTip(port.description) + }); + + let portOutput = this._createChildControlImpl("portOutput"); + let outputValue = "Unknown value"; + if (Object.prototype.hasOwnProperty.call(port, "value")) { + if (typeof port.value === "object") { + outputValue = this.__pretifyObject(port.value); + } else { + outputValue = JSON.stringify(port.value); + } + } + portOutput.set({ + value: outputValue }); - this.__createDragMechanism(portLabel, portKey); + this.__createDragMechanism(this, portKey); }, properties: { @@ -25,7 +52,39 @@ qx.Class.define("qxapp.component.widget.inputs.NodeOutputLabel", { }, members: { - __portLabel: null, + _createChildControlImpl: function(id) { + let control; + switch (id) { + case "portLabel": { + const title14Font = qx.bom.Font.fromConfig(qxapp.theme.Font.fonts["title-14"]); + control = new qx.ui.basic.Label().set({ + font: title14Font, + textAlign: "right", + allowGrowX: true, + padding: 15, + rich: true + }); + this._add(control, { + flex: 1 + }); + break; + } + case "portOutput": { + const title14Font = qx.bom.Font.fromConfig(qxapp.theme.Font.fonts["title-14"]); + control = new qx.ui.basic.Label().set({ + font: title14Font, + textAlign: "right", + allowGrowX: true, + padding: 15, + rich: true + }); + this._add(control); + break; + } + } + + return control || this.base(arguments, id); + }, __createDragMechanism: function(uiPort, portKey) { uiPort.setDraggable(true); @@ -40,8 +99,21 @@ qx.Class.define("qxapp.component.widget.inputs.NodeOutputLabel", { }, this); }, + __pretifyObject: function(object) { + let myText = ""; + const entries = Object.entries(object); + for (let i=0; i new qxapp.component.widget.inputs.NodeOutputListItem(), + createItem: () => new qxapp.component.widget.inputs.NodeOutputTreeItem(), bindItem: (c, item, id) => { c.bindDefaultProperties(item, id); c.bindProperty("key", "model", null, item, id); diff --git a/services/web/client/source/class/qxapp/component/widget/inputs/NodeOutputListItem.js b/services/web/client/source/class/qxapp/component/widget/inputs/NodeOutputTreeItem.js similarity index 87% rename from services/web/client/source/class/qxapp/component/widget/inputs/NodeOutputListItem.js rename to services/web/client/source/class/qxapp/component/widget/inputs/NodeOutputTreeItem.js index f45f395d0ab..74642f1d506 100644 --- a/services/web/client/source/class/qxapp/component/widget/inputs/NodeOutputListItem.js +++ b/services/web/client/source/class/qxapp/component/widget/inputs/NodeOutputTreeItem.js @@ -1,4 +1,4 @@ -qx.Class.define("qxapp.component.widget.inputs.NodeOutputListItem", { +qx.Class.define("qxapp.component.widget.inputs.NodeOutputTreeItem", { extend: qx.ui.tree.VirtualTreeItem, construct: function() { diff --git a/services/web/client/source/class/qxapp/data/Store.js b/services/web/client/source/class/qxapp/data/Store.js index f73642e6ce4..6dd55922832 100644 --- a/services/web/client/source/class/qxapp/data/Store.js +++ b/services/web/client/source/class/qxapp/data/Store.js @@ -46,13 +46,9 @@ qx.Class.define("qxapp.data.Store", { return topLevelPort1.isInput !== topLevelPort2.isInput; }, - arePortsCompatible: function(node1, port1, node2, port2) { - console.log("arePortsCompatible", node1, port1, node2, port2); - return true; - /* - return this.__matchPortType(port1.portType, port2.portType) && - (port1.isInput !== port2.isInput); - */ + arePortsCompatible: function(port1, port2) { + const arePortsCompatible = this.__matchPortType(port1.type, port2.type); + return arePortsCompatible; }, getUserProjectList: function() { @@ -87,515 +83,11 @@ qx.Class.define("qxapp.data.Store", { }, getItemList: function(nodeInstanceUUID, portKey) { - switch (portKey) { - case "defaultNeuromanModels": - return [{ - key: "Yoon-sun-UUID", - label: "Yoon-sun", - thumbnail: "qxapp/yoonsun.png" - }, { - key: "Yoon-sun-Light-UUID", - label: "Yoon-sun Light", - thumbnail: "qxapp/yoonsun-light.png" - }, { - key: "Rat-UUID", - label: "Rat", - thumbnail: "qxapp/rat.png" - }, { - key: "Rat-Light-UUID", - label: "Rat Light", - thumbnail: "qxapp/rat-light.png" - }]; - case "defaultMaterials": - return [{ - key: "Dielectric-UUID", - label: "Dielectric" - }, { - key: "PEC-UUID", - label: "PEC" - }, { - key: "PMC-UUID", - label: "PMC" - }]; - case "defaultBoundaries": - return [{ - key: "Dirichlet-UUID", - label: "Dirichlet" - }, { - key: "Neumann-UUID", - label: "Neumann" - }, { - key: "Flux-UUID", - label: "Flux" - }]; - case "modeler": - return [{ - key: "MODEL1-UUID", - label: "Model 1" - }, { - key: "MODEL2-UUID", - label: "Model 2" - }, { - key: "MODEL3-UUID", - label: "Model 3" - }]; - case "materialDB": - return [{ - key: "Air-UUID", - label: "Air" - }, { - key: "Brain-UUID", - label: "Brain" - }, { - key: "Eye-UUID", - label: "Eye" - }]; - case "defaultStimulationSelectivity": - return [{ - key: "StSeSubgroup-UUID", - label: "Subgroup" - }]; - } - return []; + return qxapp.dev.fake.Data.getItemList(nodeInstanceUUID, portKey); }, getItem: function(nodeInstanceUUID, portKey, itemUuid) { - switch (portKey) { - case "materialDB": { - switch (itemUuid) { - case "Air-UUID": { - return { - "massDensity": { - displayOrder: 0, - label: "Mass Density", - unit: "kg/m3", - type: "number", - defaultValue: 1.16409 - }, - "electricConductivity": { - displayOrder: 1, - label: "Electric Conductivity", - unit: "S/m", - type: "number", - defaultValue: 0 - }, - "electricRelativePermitivity": { - displayOrder: 2, - label: "Electric Relative Permittivity", - unit: "", - type: "number", - defaultValue: 1 - }, - "magneticConductivity": { - displayOrder: 3, - label: "Magnetic Conductivity", - unit: "Ohm/m", - type: "number", - defaultValue: 0 - }, - "magneticRelativePermeability": { - displayOrder: 4, - label: "Magnetic Relative Permeability", - unit: "", - type: "number", - defaultValue: 1 - } - }; - } - case "Brain-UUID": { - return { - "massDensity": { - displayOrder: 0, - label: "Mass Density", - unit: "kg/m3", - type: "number", - defaultValue: 1045.5 - }, - "electricConductivity": { - displayOrder: 1, - label: "Electric Conductivity", - unit: "S/m", - type: "number", - defaultValue: 0.234007 - }, - "electricRelativePermitivity": { - displayOrder: 2, - label: "Electric Relative Permittivity", - unit: "", - type: "number", - defaultValue: 1 - }, - "magneticConductivity": { - displayOrder: 3, - label: "Magnetic Conductivity", - unit: "Ohm/m", - type: "number", - defaultValue: 0 - }, - "magneticRelativePermeability": { - displayOrder: 4, - label: "Magnetic Relative Permeability", - unit: "", - type: "number", - defaultValue: 1 - } - }; - } - case "Eye-UUID": { - return { - "massDensity": { - displayOrder: 0, - label: "Mass Density", - unit: "kg/m3", - type: "number", - defaultValue: 1050.5 - }, - "electricConductivity": { - displayOrder: 1, - label: "Electric Conductivity", - unit: "S/m", - type: "number", - defaultValue: 0.62 - }, - "electricRelativePermitivity": { - displayOrder: 2, - label: "Electric Relative Permittivity", - unit: "", - type: "number", - defaultValue: 1 - }, - "magneticConductivity": { - displayOrder: 3, - label: "Magnetic Conductivity", - unit: "Ohm/m", - type: "number", - defaultValue: 0 - }, - "magneticRelativePermeability": { - displayOrder: 4, - label: "Magnetic Relative Permeability", - unit: "", - type: "number", - defaultValue: 1 - } - }; - } - } - } - // eslint-disable-next-line no-fallthrough - case "defaultMaterials": { - switch (itemUuid) { - case "Dielectric-UUID": { - return { - "massDensity": { - displayOrder: 0, - label: "Mass Density", - unit: "kg/m3", - type: "number", - defaultValue: 1.205 - }, - "electricConductivity": { - displayOrder: 1, - label: "Electric Conductivity", - unit: "S/m", - type: "number", - defaultValue: 0 - }, - "electricRelativePermitivity": { - displayOrder: 2, - label: "Electric Relative Permittivity", - unit: "", - type: "number", - defaultValue: 1 - }, - "magneticRelativePermeability": { - displayOrder: 3, - label: "Magnetic Relative Permeability", - unit: "", - type: "number", - defaultValue: 1 - }, - "magneticConductivity": { - displayOrder: 4, - label: "Magnetic Conductivity", - unit: "Ohm/m", - type: "number", - defaultValue: 0 - } - }; - } - } - } - } - return {}; - }, - - getList: function(nodeImageId) { - switch (nodeImageId) { - // case "services/demodec/dynamic/itis/s4l/Modeler-0.0.0": { - case "data:application/s4l-api/modeler": { - return [ - { - name: "Model 1", - uuid: "MODEL1-UUID", - properties: {} - }, { - name: "Model 2", - uuid: "MODEL2-UUID", - properties: {} - }, { - name: "Model 3", - uuid: "MODEL3-UUID", - properties: {} - }, { - name: "Model 4", - uuid: "MODEL4-UUID", - properties: {} - } - ]; - } - // case "services/demodec/dynamic/itis/s4l/MaterialDB-0.0.0": { - case "data:application/s4l-api/materialDB": { - return [ - { - name: "Air", - uuid: "Air-UUID", - properties: { - "massDensity": { - displayOrder: 0, - label: "Mass Density", - unit: "kg/m3", - type: "number", - defaultValue: 1.16409 - }, - "electricConductivity": { - displayOrder: 1, - label: "Electric Conductivity", - unit: "S/m", - type: "number", - defaultValue: 0 - }, - "electricRelativePermitivity": { - displayOrder: 2, - label: "Electric Relative Permittivity", - unit: "", - type: "number", - defaultValue: 1 - }, - "magneticConductivity": { - displayOrder: 3, - label: "Magnetic Conductivity", - unit: "Ohm/m", - type: "number", - defaultValue: 0 - }, - "magneticRelativePermeability": { - displayOrder: 4, - label: "Magnetic Relative Permeability", - unit: "", - type: "number", - defaultValue: 1 - } - } - }, { - name: "Brain", - uuid: "Brain-UUID", - properties: { - "massDensity": { - displayOrder: 0, - label: "Mass Density", - unit: "kg/m3", - type: "number", - defaultValue: 1045.5 - }, - "electricConductivity": { - displayOrder: 1, - label: "Electric Conductivity", - unit: "S/m", - type: "number", - defaultValue: 0.234007 - }, - "electricRelativePermitivity": { - displayOrder: 2, - label: "Electric Relative Permittivity", - unit: "", - type: "number", - defaultValue: 1 - }, - "magneticConductivity": { - displayOrder: 3, - label: "Magnetic Conductivity", - unit: "Ohm/m", - type: "number", - defaultValue: 0 - }, - "magneticRelativePermeability": { - displayOrder: 4, - label: "Magnetic Relative Permeability", - unit: "", - type: "number", - defaultValue: 1 - } - } - }, { - name: "Eye", - uuid: "Eye-UUID", - properties: { - "massDensity": { - displayOrder: 0, - label: "Mass Density", - unit: "kg/m3", - type: "number", - defaultValue: 1050.5 - }, - "electricConductivity": { - displayOrder: 1, - label: "Electric Conductivity", - unit: "S/m", - type: "number", - defaultValue: 0.62 - }, - "electricRelativePermitivity": { - displayOrder: 2, - label: "Electric Relative Permittivity", - unit: "", - type: "number", - defaultValue: 1 - }, - "magneticConductivity": { - displayOrder: 3, - label: "Magnetic Conductivity", - unit: "Ohm/m", - type: "number", - defaultValue: 0 - }, - "magneticRelativePermeability": { - displayOrder: 4, - label: "Magnetic Relative Permeability", - unit: "", - type: "number", - defaultValue: 1 - } - } - } - ]; - } - case "services/demodec/dynamic/itis/s4l/Simulator/LF/Materials-0.0.0": { - return [ - { - name: "PEC", - uuid: "PEC-UUID", - properties: {} - }, { - name: "PMC", - uuid: "PMC-UUID", - properties: {} - }, { - name: "Dielectric", - uuid: "Dielectric-UUID", - properties: { - "massDensity": { - displayOrder: 0, - label: "Mass Density", - unit: "kg/m3", - type: "number", - defaultValue: 1000 - }, - "electricConductivity": { - displayOrder: 1, - label: "Electric Conductivity", - unit: "S/m", - type: "number", - defaultValue: 0 - }, - "electricRelativePermitivity": { - displayOrder: 2, - label: "Electric Relative Permittivity", - unit: "", - type: "number", - defaultValue: 1 - }, - "magneticConductivity": { - displayOrder: 3, - label: "Magnetic Conductivity", - unit: "Ohm/m", - type: "number", - defaultValue: 0 - }, - "magneticRelativePermeability": { - displayOrder: 4, - label: "Magnetic Relative Permeability", - unit: "", - type: "number", - defaultValue: 1 - } - } - } - ]; - } - case "services/demodec/dynamic/itis/s4l/Simulator/LF/Boundary-0.0.0": { - return [ - { - name: "Dirichlet", - uuid: "Dirichlet-UUID", - properties: { - "constantPotential": { - displayOrder: 0, - label: "Constant Potential", - unit: "V", - type: "number", - defaultValue: 0 - }, - "phase": { - displayOrder: 1, - label: "Phase", - unit: "deg", - type: "number", - defaultValue: 0 - } - } - }, { - name: "Neumann", - uuid: "Neumann-UUID", - properties: { - "normalDerivative": { - displayOrder: 0, - label: "Normal Derivative", - unit: "V/m", - type: "number", - defaultValue: 0 - }, - "phase": { - displayOrder: 1, - label: "Phase", - unit: "deg", - type: "number", - defaultValue: 0 - } - } - }, { - name: "Flux", - uuid: "Flux-UUID", - properties: { - "constantFlux": { - displayOrder: 0, - label: "Constant Flux", - type: "number", - defaultValue: 0 - }, - "phase": { - displayOrder: 1, - label: "Phase", - unit: "deg", - type: "number", - defaultValue: 0 - } - } - } - ]; - } - } - return []; + return qxapp.dev.fake.Data.getItem(nodeInstanceUUID, portKey, itemUuid); }, getBuiltInServices: function() { @@ -653,7 +145,7 @@ qx.Class.define("qxapp.data.Store", { displayOrder: 0, label: "Modeler", description: "Modeler Live link", - type: "node-output-list-api-v0.0.1" + type: "node-output-tree-api-v0.0.1" } } }, @@ -673,7 +165,7 @@ qx.Class.define("qxapp.data.Store", { displayOrder: 0, label: "Subgroups", description: "Subgroups", - type: "node-output-list-api-v0.0.1" + type: "node-output-tree-api-v0.0.1" } }, inputs: { @@ -719,7 +211,7 @@ qx.Class.define("qxapp.data.Store", { displayOrder: 0, label: "Modeler", description: "Modeler Live link", - type: "node-output-list-api-v0.0.1" + type: "node-output-tree-api-v0.0.1" } } }, @@ -740,7 +232,7 @@ qx.Class.define("qxapp.data.Store", { displayOrder: 0, label: "MaterialDB", description: "MaterialDB Live link", - type: "node-output-list-api-v0.0.1" + type: "node-output-tree-api-v0.0.1" } } }, @@ -878,7 +370,7 @@ qx.Class.define("qxapp.data.Store", { displayOrder: 0, label: "Default Material Settings", description: "Default Material Settings", - type: "node-output-list-api-v0.0.1" + type: "node-output-tree-api-v0.0.1" } }, inputs: { @@ -937,7 +429,7 @@ qx.Class.define("qxapp.data.Store", { displayOrder: 0, label: "Default Boundary Settings", description: "Default Boundary Settings", - type: "node-output-list-api-v0.0.1" + type: "node-output-tree-api-v0.0.1" } }, inputs: { diff --git a/services/web/client/source/class/qxapp/data/model/NodeModel.js b/services/web/client/source/class/qxapp/data/model/NodeModel.js index d17e6961584..715bd52bb11 100644 --- a/services/web/client/source/class/qxapp/data/model/NodeModel.js +++ b/services/web/client/source/class/qxapp/data/model/NodeModel.js @@ -3,7 +3,9 @@ qx.Class.define("qxapp.data.model.NodeModel", { extend: qx.core.Object, - construct: function(key, version, uuid) { + construct: function(workbenchModel, key, version, uuid) { + this.setWorkbenchModel(workbenchModel); + this.base(arguments); this.__metaData = {}; @@ -44,6 +46,11 @@ qx.Class.define("qxapp.data.model.NodeModel", { }, properties: { + workbenchModel: { + check: "qxapp.data.model.WorkbenchModel", + nullable: false + }, + key: { check: "String", nullable: false @@ -71,7 +78,9 @@ qx.Class.define("qxapp.data.model.NodeModel", { }, propsWidget: { - check: "qxapp.component.form.renderer.PropForm" + check: "qxapp.component.form.renderer.PropForm", + init: null, + nullable: true }, inputsMapper: { @@ -142,6 +151,18 @@ qx.Class.define("qxapp.data.model.NodeModel", { return this.__inputsDefault; }, + getInput: function(outputId) { + return this.__inputs[outputId]; + }, + + getInputs: function() { + return this.__inputs; + }, + + getOutput: function(outputId) { + return this.__outputs[outputId]; + }, + getOutputs: function() { return this.__outputs; }, @@ -193,13 +214,13 @@ qx.Class.define("qxapp.data.model.NodeModel", { populateNodeData: function(nodeData) { if (nodeData) { + if (nodeData.label) { + this.setLabel(nodeData.label); + } + this.setInputData(nodeData); this.setOutputData(nodeData); - if (nodeData.position) { - this.setPosition(nodeData.position.x, nodeData.position.y); - } - if (nodeData.inputNodes) { this.__inputNodes = nodeData.inputNodes; } @@ -208,10 +229,17 @@ qx.Class.define("qxapp.data.model.NodeModel", { this.setIsOutputNode(nodeData.outputNode); } - if (nodeData.label) { - this.setLabel(nodeData.label); + if (nodeData.position) { + this.setPosition(nodeData.position.x, nodeData.position.y); } } + + if (this.__inputsDefaultWidget) { + this.__inputsDefaultWidget.populatePortsData(); + } + if (this.__outputWidget) { + this.__outputWidget.populatePortsData(); + } }, getInputsDefaultWidget: function() { @@ -220,9 +248,7 @@ qx.Class.define("qxapp.data.model.NodeModel", { __addInputsDefaultWidgets: function() { const isInputModel = false; - let nodePorts = new qxapp.component.widget.NodePorts(this, isInputModel); - nodePorts.populateNodeLayout(); - this.__inputsDefaultWidget = nodePorts; + this.__inputsDefaultWidget = new qxapp.component.widget.NodePorts(this, isInputModel); }, /** @@ -261,7 +287,7 @@ qx.Class.define("qxapp.data.model.NodeModel", { * */ __addSetttings: function(inputs) { - let form = this.__settingsForm = new qxapp.component.form.Auto(inputs); + let form = this.__settingsForm = new qxapp.component.form.Auto(inputs, this); form.addListener("linkAdded", e => { let changedField = e.getData(); this.getPropsWidget().linkAdded(changedField); @@ -271,7 +297,7 @@ qx.Class.define("qxapp.data.model.NodeModel", { this.getPropsWidget().linkRemoved(changedField); }, this); - let propsWidget = new qxapp.component.form.renderer.PropForm(form, this); + let propsWidget = new qxapp.component.form.renderer.PropForm(form, this.getWorkbenchModel(), this); this.setPropsWidget(propsWidget); propsWidget.addListener("RemoveLink", e => { let changedField = e.getData(); @@ -285,9 +311,7 @@ qx.Class.define("qxapp.data.model.NodeModel", { __addOutputWidget: function() { const isInputModel = true; - let nodePorts = new qxapp.component.widget.NodePorts(this, isInputModel); - nodePorts.populateNodeLayout(); - this.__outputWidget = nodePorts; + this.__outputWidget = new qxapp.component.widget.NodePorts(this, isInputModel); }, __addInputsDefault: function(inputsDefault) { @@ -297,6 +321,8 @@ qx.Class.define("qxapp.data.model.NodeModel", { }, __addInputs: function(inputs) { + this.__inputs = inputs; + if (inputs === null) { return; } diff --git a/services/web/client/source/class/qxapp/data/model/WorkbenchModel.js b/services/web/client/source/class/qxapp/data/model/WorkbenchModel.js index 259e40ebe7d..401ecedf50a 100644 --- a/services/web/client/source/class/qxapp/data/model/WorkbenchModel.js +++ b/services/web/client/source/class/qxapp/data/model/WorkbenchModel.js @@ -92,7 +92,7 @@ qx.Class.define("qxapp.data.model.WorkbenchModel", { if (existingNodeModel) { return existingNodeModel; } - let nodeModel = new qxapp.data.model.NodeModel(key, version, uuid); + let nodeModel = new qxapp.data.model.NodeModel(this, key, version, uuid); nodeModel.populateNodeData(nodeData); nodeModel.addListener("ShowInLogger", e => { this.fireDataEvent("ShowInLogger", e.getData()); @@ -216,8 +216,8 @@ qx.Class.define("qxapp.data.model.WorkbenchModel", { // node especific if (!nodeModel.isContainer()) { - node.key = nodeModel.getMetaData().key; - node.version = nodeModel.getMetaData().version; + node.key = nodeModel.getKey(); + node.version = nodeModel.getVersion(); } } return workbench; diff --git a/services/web/client/source/class/qxapp/desktop/PrjBrowser.js b/services/web/client/source/class/qxapp/desktop/PrjBrowser.js index ab578833028..c3418389d8e 100644 --- a/services/web/client/source/class/qxapp/desktop/PrjBrowser.js +++ b/services/web/client/source/class/qxapp/desktop/PrjBrowser.js @@ -209,7 +209,7 @@ qx.Class.define("qxapp.desktop.PrjBrowser", { name: p.name, thumbnail: p.thumbnail, projectUuid: p.projectUuid, - created: Date(p.creationDate), + created: new Date(p.creationDate), owner: p.owner }) ) diff --git a/services/web/client/source/class/qxapp/desktop/PrjEditor.js b/services/web/client/source/class/qxapp/desktop/PrjEditor.js index bae0c37182c..ad994d7ecaf 100644 --- a/services/web/client/source/class/qxapp/desktop/PrjEditor.js +++ b/services/web/client/source/class/qxapp/desktop/PrjEditor.js @@ -146,7 +146,7 @@ qx.Class.define("qxapp.desktop.PrjEditor", { widget = this.__workbenchView; } else { this.__nodeView.setNodeModel(nodeModel); - if (nodeModel.getMetaData().key.includes("file-picker")) { + if (nodeModel.getKey().includes("file-picker")) { widget = new qxapp.component.widget.FilePicker(nodeModel); } else { widget = this.__nodeView; @@ -159,7 +159,7 @@ qx.Class.define("qxapp.desktop.PrjEditor", { } } - // SHow screenshots in the ExtraView + // Show screenshots in the ExtraView if (nodeId === "root") { this.showScreenshotInExtraView("workbench"); } else { @@ -167,7 +167,7 @@ qx.Class.define("qxapp.desktop.PrjEditor", { if (nodeModel.isContainer()) { this.showScreenshotInExtraView("container"); } else { - let nodeKey = nodeModel.getMetaData().key; + let nodeKey = nodeModel.getKey(); if (nodeKey.includes("file-picker")) { this.showScreenshotInExtraView("file-picker"); } else if (nodeKey.includes("modeler")) { diff --git a/services/web/client/source/class/qxapp/dev/fake/Data.js b/services/web/client/source/class/qxapp/dev/fake/Data.js index bfda0692cb6..3a52d3eb2cd 100644 --- a/services/web/client/source/class/qxapp/dev/fake/Data.js +++ b/services/web/client/source/class/qxapp/dev/fake/Data.js @@ -198,6 +198,7 @@ qx.Class.define("qxapp.dev.fake.Data", { "UUID2": { key: "services/computational/itis/sleeper", version: "0.0.0", + label: "Sleeper 1", inputs: { inNumber: 3.5 }, @@ -212,11 +213,12 @@ qx.Class.define("qxapp.dev.fake.Data", { "UUID3": { key: "services/computational/itis/sleeper", version: "0.0.0", + label: "Sleeper 2", inputs: { inNumber: 3.5 }, outputs: { - outNumber: 33 + outNumber: 32 }, position: { x: 10, @@ -246,6 +248,7 @@ qx.Class.define("qxapp.dev.fake.Data", { } }, inputNodes: [ + "UUID2", "UUID3", "UUID1" ], @@ -2042,6 +2045,309 @@ qx.Class.define("qxapp.dev.fake.Data", { } }; return temp2Data; + }, + + getItemList: function(nodeInstanceUUID, portKey) { + switch (portKey) { + case "defaultNeuromanModels": + return [{ + key: "Yoon-sun-UUID", + label: "Yoon-sun", + thumbnail: "qxapp/yoonsun.png" + }, { + key: "Yoon-sun-Light-UUID", + label: "Yoon-sun Light", + thumbnail: "qxapp/yoonsun-light.png" + }, { + key: "Rat-UUID", + label: "Rat", + thumbnail: "qxapp/rat.png" + }, { + key: "Rat-Light-UUID", + label: "Rat Light", + thumbnail: "qxapp/rat-light.png" + }]; + case "defaultMaterials": + return [{ + key: "Dielectric-UUID", + label: "Dielectric" + }, { + key: "PEC-UUID", + label: "PEC" + }, { + key: "PMC-UUID", + label: "PMC" + }]; + case "defaultBoundaries": + return [{ + key: "Dirichlet-UUID", + label: "Dirichlet" + }, { + key: "Neumann-UUID", + label: "Neumann" + }, { + key: "Flux-UUID", + label: "Flux" + }]; + case "modeler": + return [{ + key: "MODEL1-UUID", + label: "Model 1" + }, { + key: "MODEL2-UUID", + label: "Model 2" + }, { + key: "MODEL3-UUID", + label: "Model 3" + }]; + case "materialDB": + return [{ + key: "Air-UUID", + label: "Air" + }, { + key: "Brain-UUID", + label: "Brain" + }, { + key: "Eye-UUID", + label: "Eye" + }]; + case "defaultStimulationSelectivity": + return [{ + key: "StSeSubgroup-UUID", + label: "Subgroup" + }]; + } + return []; + }, + + getItem: function(nodeInstanceUUID, portKey, itemUuid) { + switch (portKey) { + case "materialDB": { + switch (itemUuid) { + case "Air-UUID": { + return { + "massDensity": { + displayOrder: 0, + label: "Mass Density", + unit: "kg/m3", + type: "number", + defaultValue: 1.16409 + }, + "electricConductivity": { + displayOrder: 1, + label: "Electric Conductivity", + unit: "S/m", + type: "number", + defaultValue: 0 + }, + "electricRelativePermitivity": { + displayOrder: 2, + label: "Electric Relative Permittivity", + unit: "", + type: "number", + defaultValue: 1 + }, + "magneticConductivity": { + displayOrder: 3, + label: "Magnetic Conductivity", + unit: "Ohm/m", + type: "number", + defaultValue: 0 + }, + "magneticRelativePermeability": { + displayOrder: 4, + label: "Magnetic Relative Permeability", + unit: "", + type: "number", + defaultValue: 1 + } + }; + } + case "Brain-UUID": { + return { + "massDensity": { + displayOrder: 0, + label: "Mass Density", + unit: "kg/m3", + type: "number", + defaultValue: 1045.5 + }, + "electricConductivity": { + displayOrder: 1, + label: "Electric Conductivity", + unit: "S/m", + type: "number", + defaultValue: 0.234007 + }, + "electricRelativePermitivity": { + displayOrder: 2, + label: "Electric Relative Permittivity", + unit: "", + type: "number", + defaultValue: 1 + }, + "magneticConductivity": { + displayOrder: 3, + label: "Magnetic Conductivity", + unit: "Ohm/m", + type: "number", + defaultValue: 0 + }, + "magneticRelativePermeability": { + displayOrder: 4, + label: "Magnetic Relative Permeability", + unit: "", + type: "number", + defaultValue: 1 + } + }; + } + case "Eye-UUID": { + return { + "massDensity": { + displayOrder: 0, + label: "Mass Density", + unit: "kg/m3", + type: "number", + defaultValue: 1050.5 + }, + "electricConductivity": { + displayOrder: 1, + label: "Electric Conductivity", + unit: "S/m", + type: "number", + defaultValue: 0.62 + }, + "electricRelativePermitivity": { + displayOrder: 2, + label: "Electric Relative Permittivity", + unit: "", + type: "number", + defaultValue: 1 + }, + "magneticConductivity": { + displayOrder: 3, + label: "Magnetic Conductivity", + unit: "Ohm/m", + type: "number", + defaultValue: 0 + }, + "magneticRelativePermeability": { + displayOrder: 4, + label: "Magnetic Relative Permeability", + unit: "", + type: "number", + defaultValue: 1 + } + }; + } + } + break; + } + case "defaultMaterials": { + switch (itemUuid) { + case "Dielectric-UUID": { + return { + "massDensity": { + displayOrder: 0, + label: "Mass Density", + unit: "kg/m3", + type: "number", + defaultValue: 1.205 + }, + "electricConductivity": { + displayOrder: 1, + label: "Electric Conductivity", + unit: "S/m", + type: "number", + defaultValue: 0 + }, + "electricRelativePermitivity": { + displayOrder: 2, + label: "Electric Relative Permittivity", + unit: "", + type: "number", + defaultValue: 1 + }, + "magneticRelativePermeability": { + displayOrder: 3, + label: "Magnetic Relative Permeability", + unit: "", + type: "number", + defaultValue: 1 + }, + "magneticConductivity": { + displayOrder: 4, + label: "Magnetic Conductivity", + unit: "Ohm/m", + type: "number", + defaultValue: 0 + } + }; + } + } + break; + } + case "defaultBoundaries": { + switch (itemUuid) { + case "Dirichlet-UUID": { + return { + "constantPotential": { + displayOrder: 0, + label: "Constant Potential", + unit: "V", + type: "number", + defaultValue: 0 + }, + "phase": { + displayOrder: 1, + label: "Phase", + unit: "deg", + type: "number", + defaultValue: 0 + } + }; + } + case "Neumann-UUID": { + return { + "normalDerivative": { + displayOrder: 0, + label: "Normal Derivative", + unit: "V/m", + type: "number", + defaultValue: 0 + }, + "phase": { + displayOrder: 1, + label: "Phase", + unit: "deg", + type: "number", + defaultValue: 0 + } + }; + } + case "Flux-UUID": { + return { + "constantFlux": { + displayOrder: 0, + label: "Constant Flux", + type: "number", + defaultValue: 0 + }, + "phase": { + displayOrder: 1, + label: "Phase", + unit: "deg", + type: "number", + defaultValue: 0 + } + }; + } + } + break; + } + } + return {}; } } // statics diff --git a/services/web/client/source/class/qxapp/theme/Font.js b/services/web/client/source/class/qxapp/theme/Font.js index 401fa0c8c88..9838eed4419 100644 --- a/services/web/client/source/class/qxapp/theme/Font.js +++ b/services/web/client/source/class/qxapp/theme/Font.js @@ -24,6 +24,12 @@ qx.Theme.define("qxapp.theme.Font", { family: ["Roboto"], color: "text", bold: true + }, + + "title-14": { + size: 14, + family: ["Roboto"], + color: "text" } } }); diff --git a/services/web/server/requirements/base.txt b/services/web/server/requirements/base.txt index e257aca7f80..c2b5cd79edd 100644 --- a/services/web/server/requirements/base.txt +++ b/services/web/server/requirements/base.txt @@ -17,7 +17,7 @@ minio==4.0.0 networkx==2.1 passlib==1.7.1 python-socketio==1.9.0 -requests==2.19.0 +requests==2.20.1 sqlalchemy==1.2.9 tenacity==4.12.0 trafaret-config==2.0.1 diff --git a/services/web/server/src/simcore_service_webserver/cli_config.py b/services/web/server/src/simcore_service_webserver/cli_config.py index 65838d339fc..e844641f740 100644 --- a/services/web/server/src/simcore_service_webserver/cli_config.py +++ b/services/web/server/src/simcore_service_webserver/cli_config.py @@ -6,8 +6,7 @@ import trafaret_config import trafaret_config.commandline as commandline -from .resources_keys import RSC_CONFIG_DIR_KEY -from .resources import resources +from .resources import resources, RSC_CONFIG_DIR_KEY log = logging.getLogger(__name__) diff --git a/services/web/server/src/simcore_service_webserver/resources.py b/services/web/server/src/simcore_service_webserver/resources.py index 6ce1d3be591..2a8b9fe369f 100644 --- a/services/web/server/src/simcore_service_webserver/resources.py +++ b/services/web/server/src/simcore_service_webserver/resources.py @@ -3,8 +3,8 @@ """ from servicelib.resources import ResourcesFacade -# pylint: disable=unused-import -from .resources_keys import RSC_CONFIG_DIR_KEY +# RSC=resource +RSC_CONFIG_DIR_KEY = __name__ + ".config" resources = ResourcesFacade( package_name=__name__, diff --git a/services/web/server/src/simcore_service_webserver/resources_keys.py b/services/web/server/src/simcore_service_webserver/resources_keys.py deleted file mode 100644 index a6ede7535ee..00000000000 --- a/services/web/server/src/simcore_service_webserver/resources_keys.py +++ /dev/null @@ -1,20 +0,0 @@ -""" Namespace to keep keys to identify resources - - -See resources module -""" -from .__version__ import get_version_object - -package_version = get_version_object() - - -API_MAJOR_VERSION = package_version.major -API_URL_VERSION = "v{:.0f}".format(API_MAJOR_VERSION) - -# RSC=resource -RSC_CONFIG_DIR_KEY = "config" -#RSC_OPENAPI_DIR_KEY = "oas3/{}".format(API_URL_VERSION) -#RSC_OPENAPI_ROOTFILE_KEY = "{}/openapi.yaml".format(RSC_OPENAPI_DIR_KEY) -RSC_CONFIG_DIR_KEY = "config" - -# RSC_CONFIG_SCHEMA_KEY = RSC_CONFIG_DIR_KEY + "/config-schema-v1.json"