diff --git a/services/web/client/source/class/osparc/component/form/Auto.js b/services/web/client/source/class/osparc/component/form/Auto.js index 376d34222e8..77fd3592248 100644 --- a/services/web/client/source/class/osparc/component/form/Auto.js +++ b/services/web/client/source/class/osparc/component/form/Auto.js @@ -529,6 +529,12 @@ qx.Class.define("osparc.component.form.Auto", { if (s.set.filter) { s.set.filter = RegExp(s.filter); } + if ("minimum" in s.set) { + control.setMinimum(s.set["minimum"]); + } + if ("maximum" in s.set) { + control.setMaximum(s.set["maximum"]); + } control.set(s.set); } control.key = key; diff --git a/services/web/client/source/class/osparc/component/node/BaseNodeView.js b/services/web/client/source/class/osparc/component/node/BaseNodeView.js index 58fe90bf0eb..4c186d80d6f 100644 --- a/services/web/client/source/class/osparc/component/node/BaseNodeView.js +++ b/services/web/client/source/class/osparc/component/node/BaseNodeView.js @@ -180,7 +180,7 @@ qx.Class.define("osparc.component.node.BaseNodeView", { }, __openServiceDetails: function() { - const serviceDetails = new osparc.servicecard.Large(this.getNode().getMetaData(), this.getNode().getNodeId()); + const serviceDetails = new osparc.servicecard.Large(this.getNode().getMetaData(), this.getNode().getNodeId(), this.getStudy()); const title = this.tr("Service information"); const width = 600; const height = 700; diff --git a/services/web/client/source/class/osparc/component/widget/NodesTree.js b/services/web/client/source/class/osparc/component/widget/NodesTree.js index d115134cc46..8aa642eee0f 100644 --- a/services/web/client/source/class/osparc/component/widget/NodesTree.js +++ b/services/web/client/source/class/osparc/component/widget/NodesTree.js @@ -244,7 +244,7 @@ qx.Class.define("osparc.component.widget.NodesTree", { osparc.ui.window.Window.popUpInWindow(studyDetails, title, width, height); } else { const node = study.getWorkbench().getNode(nodeId); - const serviceDetails = new osparc.servicecard.Large(node.getMetaData(), nodeId); + const serviceDetails = new osparc.servicecard.Large(node.getMetaData(), nodeId, study); const title = this.tr("Service information"); const width = 600; const height = 700; diff --git a/services/web/client/source/class/osparc/component/workbench/WorkbenchUI.js b/services/web/client/source/class/osparc/component/workbench/WorkbenchUI.js index 0de61e14437..db8485380f9 100644 --- a/services/web/client/source/class/osparc/component/workbench/WorkbenchUI.js +++ b/services/web/client/source/class/osparc/component/workbench/WorkbenchUI.js @@ -1645,7 +1645,7 @@ qx.Class.define("osparc.component.workbench.WorkbenchUI", { __openNodeInfo: function(nodeId) { if (nodeId) { const node = this.getStudy().getWorkbench().getNode(nodeId); - const serviceDetails = new osparc.servicecard.Large(node.getMetaData(), nodeId); + const serviceDetails = new osparc.servicecard.Large(node.getMetaData(), nodeId, this.getStudy()); const title = this.tr("Service information"); const width = 600; const height = 700; diff --git a/services/web/client/source/class/osparc/dashboard/ResourceMoreOptions.js b/services/web/client/source/class/osparc/dashboard/ResourceMoreOptions.js index d0415b71260..e0f421d36a7 100644 --- a/services/web/client/source/class/osparc/dashboard/ResourceMoreOptions.js +++ b/services/web/client/source/class/osparc/dashboard/ResourceMoreOptions.js @@ -200,7 +200,7 @@ qx.Class.define("osparc.dashboard.ResourceMoreOptions", { const title = this.tr("Information"); const icon = "@FontAwesome5Solid/info"; const resourceData = this.__resourceData; - const infoCard = osparc.utils.Resources.isService(resourceData) ? new osparc.servicecard.Large(resourceData, null, false) : new osparc.studycard.Large(resourceData, false); + const infoCard = osparc.utils.Resources.isService(resourceData) ? new osparc.servicecard.Large(resourceData, null, null, false) : new osparc.studycard.Large(resourceData, false); infoCard.addListener("openAccessRights", () => this.openAccessRights()); infoCard.addListener("openClassifiers", () => this.openClassfiers()); infoCard.addListener("openQuality", () => this.openQuality()); diff --git a/services/web/client/source/class/osparc/data/Resources.js b/services/web/client/source/class/osparc/data/Resources.js index 0fe785aaa79..e869c8bda47 100644 --- a/services/web/client/source/class/osparc/data/Resources.js +++ b/services/web/client/source/class/osparc/data/Resources.js @@ -154,6 +154,31 @@ qx.Class.define("osparc.data.Resources", { } } }, + /* + * NODES + */ + "nodesInStudyResources": { + idField: "nodeId", + useCache: false, + endpoints: { + getResources: { + useCache: false, + method: "GET", + url: statics.API + "/projects/{studyId}/nodes/{nodeId}/resources" + } + } + }, + "serviceResources": { + idField: ["key", "version"], + useCache: false, + endpoints: { + getResources: { + useCache: false, + method: "GET", + url: statics.API + "/catalog/services/{key}/{version}/resources" + } + } + }, /* * SNAPSHOTS */ diff --git a/services/web/client/source/class/osparc/servicecard/Large.js b/services/web/client/source/class/osparc/servicecard/Large.js index 5c120e72a4b..c5396e9546a 100644 --- a/services/web/client/source/class/osparc/servicecard/Large.js +++ b/services/web/client/source/class/osparc/servicecard/Large.js @@ -24,7 +24,7 @@ qx.Class.define("osparc.servicecard.Large", { * @param instanceUuid {String} uuid of the service instance * @param openOptions {Boolean} open edit options in new window or fire event */ - construct: function(serviceData, instanceUuid = null, openOptions = true) { + construct: function(serviceData, instanceUuid = null, study = null, openOptions = true) { this.base(arguments); this.set({ @@ -39,6 +39,10 @@ qx.Class.define("osparc.servicecard.Large", { this.setInstanceUuid(instanceUuid); } + if (study) { + this.setStudy(study); + } + if (openOptions !== undefined) { this.setOpenOptions(openOptions); } @@ -72,6 +76,12 @@ qx.Class.define("osparc.servicecard.Large", { nullable: true }, + study: { + check: "osparc.data.model.Study", + init: null, + nullable: true + }, + openOptions: { check: "Boolean", init: true, @@ -127,6 +137,9 @@ qx.Class.define("osparc.servicecard.Large", { description.addAt(editInTitle, 0); this._add(description); + const resources = this.__createResources(); + this._add(resources); + const rawMetadata = this.__createRawMetadata(); const more = new osparc.desktop.PanelView(this.tr("raw metadata"), rawMetadata).set({ caretSize: 14 @@ -282,6 +295,36 @@ qx.Class.define("osparc.servicecard.Large", { return osparc.servicecard.Utils.createDescription(this.getService(), maxHeight); }, + __createResources: function() { + const resourcesLayout = osparc.servicecard.Utils.createResourcesInfo(); + resourcesLayout.exclude(); + let promise = null; + if (this.getInstanceUuid()) { + const params = { + url: { + studyId: this.getStudy().getUuid(), + nodeId: this.getInstanceUuid() + } + }; + promise = osparc.data.Resources.fetch("nodesInStudyResources", "getResources", params); + } else { + const params = { + url: osparc.data.Resources.getServiceUrl( + this.getService()["key"], + this.getService()["version"] + ) + }; + promise = osparc.data.Resources.fetch("serviceResources", "getResources", params); + } + promise + .then(serviceResources => { + resourcesLayout.show(); + osparc.servicecard.Utils.resourcesToResourcesInfo(resourcesLayout, serviceResources); + }) + .catch(err => console.error(err)); + return resourcesLayout; + }, + __createRawMetadata: function() { const container = new qx.ui.container.Scroll(); container.add(new osparc.ui.basic.JsonTreeWidget(this.getService(), "serviceDescriptionSettings")); diff --git a/services/web/client/source/class/osparc/servicecard/Utils.js b/services/web/client/source/class/osparc/servicecard/Utils.js index 5237d051c96..42d3078de6c 100644 --- a/services/web/client/source/class/osparc/servicecard/Utils.js +++ b/services/web/client/source/class/osparc/servicecard/Utils.js @@ -193,6 +193,70 @@ qx.Class.define("osparc.servicecard.Utils", { return descriptionLayout; }, + createResourcesInfo: function() { + const resourcesLayout = new qx.ui.container.Composite(new qx.ui.layout.VBox(5).set({ + alignY: "middle" + })); + + const label = new qx.ui.basic.Label(qx.locale.Manager.tr("Resources")).set({ + font: "title-12" + }); + resourcesLayout.add(label); + + const grid = new qx.ui.layout.Grid(5, 3); + grid.setColumnAlign(0, "right", "middle"); + grid.setColumnAlign(1, "left", "middle"); + const resourcesInfo = new qx.ui.container.Composite(grid).set({ + allowGrowX: false, + alignX: "left", + alignY: "middle" + }); + resourcesLayout.add(resourcesInfo); + + return resourcesLayout; + }, + + resourcesToResourcesInfo: function(resourcesLayout, resourcesInfo) { + const layout = resourcesLayout.getChildren()[1]; + let row = 0; + Object.keys(resourcesInfo).forEach(resourceKey => { + let column = 0; + const resourceInfo = resourcesInfo[resourceKey]; + let label = resourceKey; + if (resourceKey === "RAM") { + label += " (GB)"; + } + layout.add(new qx.ui.basic.Label(label).set({ + font: "title-12" + }), { + row, + column + }); + column++; + Object.keys(resourceInfo).forEach(resourceInfoKey => { + layout.add(new qx.ui.basic.Label(resourceInfoKey).set({ + font: "title-12" + }), { + row, + column + }); + column++; + let value = resourceInfo[resourceInfoKey]; + if (resourceKey === "RAM") { + value = osparc.utils.Utils.bytesToGB(value); + } + layout.add(new qx.ui.basic.Label(String(value)).set({ + font: "text-12" + }), { + row, + column + }); + column++; + }); + row++; + }); + }, + createExtraInfo: function(extraInfos) { const grid = new qx.ui.layout.Grid(5, 3); grid.setColumnAlign(0, "right", "middle"); diff --git a/services/web/client/source/class/osparc/store/Store.js b/services/web/client/source/class/osparc/store/Store.js index 8403c28b742..c9ce4224717 100644 --- a/services/web/client/source/class/osparc/store/Store.js +++ b/services/web/client/source/class/osparc/store/Store.js @@ -62,6 +62,14 @@ qx.Class.define("osparc.store.Store", { check: "Array", init: [] }, + nodesInStudyResources: { + check: "Array", + init: [] + }, + serviceResources: { + check: "Array", + init: [] + }, snapshots: { check: "Array", init: [],