diff --git a/services/static-webserver/client/source/class/osparc/auth/core/Utils.js b/services/static-webserver/client/source/class/osparc/auth/core/Utils.js index 2b0825e0b08..d73e80e48e6 100644 --- a/services/static-webserver/client/source/class/osparc/auth/core/Utils.js +++ b/services/static-webserver/client/source/class/osparc/auth/core/Utils.js @@ -46,7 +46,7 @@ qx.Class.define("osparc.auth.core.Utils", { const regEx = /^\+[1-9]\d{4,14}$/; const isValid = regEx.test(phoneNumber); item.set({ - invalidMessage: isValid ? "" : qx.locale.Manager.tr("Invalid phone number. Please, [+][country code][phone number plus area code]"), + invalidMessage: isValid ? "" : qx.locale.Manager.tr("Invalid phone number. Please, [+][country code][phone number]"), valid: isValid }); return isValid; diff --git a/services/static-webserver/client/source/class/osparc/component/metadata/ServicesInStudy.js b/services/static-webserver/client/source/class/osparc/component/metadata/ServicesInStudy.js index 6586de3466a..7fd6081ed09 100644 --- a/services/static-webserver/client/source/class/osparc/component/metadata/ServicesInStudy.js +++ b/services/static-webserver/client/source/class/osparc/component/metadata/ServicesInStudy.js @@ -144,7 +144,7 @@ qx.Class.define("osparc.component.metadata.ServicesInStudy", { const infoButton = new qx.ui.form.Button(null, "@MaterialIcons/info_outline/14"); infoButton.addListener("execute", () => { const metadata = osparc.utils.Services.getMetaData(node["key"], node["version"]); - const serviceDetails = new osparc.servicecard.Large(metadata, { + const serviceDetails = new osparc.info.ServiceLarge(metadata, { nodeId, label: node["label"] }); diff --git a/services/static-webserver/client/source/class/osparc/component/node/BaseNodeView.js b/services/static-webserver/client/source/class/osparc/component/node/BaseNodeView.js index 9269158a7c9..e6a17cc628c 100644 --- a/services/static-webserver/client/source/class/osparc/component/node/BaseNodeView.js +++ b/services/static-webserver/client/source/class/osparc/component/node/BaseNodeView.js @@ -225,7 +225,7 @@ qx.Class.define("osparc.component.node.BaseNodeView", { __openServiceDetails: function() { const node = this.getNode(); - const serviceDetails = new osparc.servicecard.Large(node.getMetaData(), { + const serviceDetails = new osparc.info.ServiceLarge(node.getMetaData(), { nodeId: node.getNodeId(), label: node.getLabel(), study: node.getStudy() diff --git a/services/static-webserver/client/source/class/osparc/component/widget/NodesTree.js b/services/static-webserver/client/source/class/osparc/component/widget/NodesTree.js index aad8666a24e..8793b062440 100644 --- a/services/static-webserver/client/source/class/osparc/component/widget/NodesTree.js +++ b/services/static-webserver/client/source/class/osparc/component/widget/NodesTree.js @@ -237,14 +237,14 @@ qx.Class.define("osparc.component.widget.NodesTree", { if (nodeId) { const study = this.getStudy(); if (nodeId === study.getUuid()) { - const studyDetails = new osparc.studycard.Large(study); + const studyDetails = new osparc.info.StudyLarge(study); const title = this.tr("Study Information"); const width = 500; const height = 500; osparc.ui.window.Window.popUpInWindow(studyDetails, title, width, height); } else { const node = study.getWorkbench().getNode(nodeId); - const serviceDetails = new osparc.servicecard.Large(node.getMetaData(), { + const serviceDetails = new osparc.info.ServiceLarge(node.getMetaData(), { nodeId, label: node.getLabel(), study diff --git a/services/static-webserver/client/source/class/osparc/component/widget/StudyTitleOnlyTree.js b/services/static-webserver/client/source/class/osparc/component/widget/StudyTitleOnlyTree.js index 99210de678b..b500400f865 100644 --- a/services/static-webserver/client/source/class/osparc/component/widget/StudyTitleOnlyTree.js +++ b/services/static-webserver/client/source/class/osparc/component/widget/StudyTitleOnlyTree.js @@ -57,7 +57,7 @@ qx.Class.define("osparc.component.widget.StudyTitleOnlyTree", { }, __openStudyInfo: function() { - const studyDetails = new osparc.studycard.Large(this.getStudy()); + const studyDetails = new osparc.info.StudyLarge(this.getStudy()); const title = this.tr("Study Information"); const width = 500; const height = 500; diff --git a/services/static-webserver/client/source/class/osparc/component/widget/logger/LoggerView.js b/services/static-webserver/client/source/class/osparc/component/widget/logger/LoggerView.js index 6027b03ebbb..1e77c359136 100644 --- a/services/static-webserver/client/source/class/osparc/component/widget/logger/LoggerView.js +++ b/services/static-webserver/client/source/class/osparc/component/widget/logger/LoggerView.js @@ -193,7 +193,7 @@ qx.Class.define("osparc.component.widget.logger.LoggerView", { toolTipText: this.tr("Download logs"), appearance: "toolbar-button" }); - osparc.utils.Utils.setIdToWidget(control, "downloadLogsToClipboardButton"); + osparc.utils.Utils.setIdToWidget(control, "downloadLogsButton"); toolbar.add(control); break; } @@ -226,7 +226,7 @@ qx.Class.define("osparc.component.widget.logger.LoggerView", { toolbar.add(copyToClipboardButton); const downloadButton = this.getChildControl("download-logs-button"); - downloadButton.addListener("execute", () => this.__downloadLogs(), this); + downloadButton.addListener("execute", () => this.downloadLogs(), this); toolbar.add(downloadButton); return toolbar; @@ -297,7 +297,7 @@ qx.Class.define("osparc.component.widget.logger.LoggerView", { osparc.utils.Utils.copyTextToClipboard(this.__getLogsString()); }, - __downloadLogs: function() { + downloadLogs: function() { const logs = this.__getLogsString(); osparc.utils.Utils.downloadContent("data:text/plain;charset=utf-8," + logs, "logs.log"); }, diff --git a/services/static-webserver/client/source/class/osparc/component/workbench/ServiceCatalog.js b/services/static-webserver/client/source/class/osparc/component/workbench/ServiceCatalog.js index 9902f9412da..62952c659b5 100644 --- a/services/static-webserver/client/source/class/osparc/component/workbench/ServiceCatalog.js +++ b/services/static-webserver/client/source/class/osparc/component/workbench/ServiceCatalog.js @@ -304,7 +304,7 @@ qx.Class.define("osparc.component.workbench.ServiceCatalog", { }, __showServiceDetails: function() { - const serviceDetails = new osparc.servicecard.Large(this.__getSelectedService()); + const serviceDetails = new osparc.info.ServiceLarge(this.__getSelectedService()); const title = this.tr("Service information"); const width = 600; const height = 700; diff --git a/services/static-webserver/client/source/class/osparc/component/workbench/WorkbenchUI.js b/services/static-webserver/client/source/class/osparc/component/workbench/WorkbenchUI.js index 2e84c6f6a42..3a968a6e47e 100644 --- a/services/static-webserver/client/source/class/osparc/component/workbench/WorkbenchUI.js +++ b/services/static-webserver/client/source/class/osparc/component/workbench/WorkbenchUI.js @@ -1520,7 +1520,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(), { + const serviceDetails = new osparc.info.ServiceLarge(node.getMetaData(), { nodeId, label: node.getLabel(), study: this.getStudy() diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceMoreOptions.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceMoreOptions.js index f43e68c0113..523bca097f6 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceMoreOptions.js +++ b/services/static-webserver/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.info.ServiceLarge(resourceData, null, false) : new osparc.info.StudyLarge(resourceData, false); infoCard.addListener("openAccessRights", () => this.openAccessRights()); infoCard.addListener("openClassifiers", () => this.openClassfiers()); infoCard.addListener("openQuality", () => this.openQuality()); diff --git a/services/static-webserver/client/source/class/osparc/desktop/MainPage.js b/services/static-webserver/client/source/class/osparc/desktop/MainPage.js index abda0692de0..4e7f1908752 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/MainPage.js +++ b/services/static-webserver/client/source/class/osparc/desktop/MainPage.js @@ -74,6 +74,7 @@ qx.Class.define("osparc.desktop.MainPage", { __createNavigationBar: function() { const navBar = new osparc.navigation.NavigationBar(); navBar.addListener("backToDashboardPressed", () => this.__backToDashboardPressed(), this); + navBar.addListener("downloadStudyLogs", () => this.__downloadStudyLogs(), this); return navBar; }, @@ -124,6 +125,12 @@ qx.Class.define("osparc.desktop.MainPage", { dashboardBtn.setFetching(false); }, + __downloadStudyLogs: function() { + if (this.__studyEditor) { + this.__studyEditor.getStudyLogger().downloadLogs(); + } + }, + __createMainStack: function() { const mainStack = new qx.ui.container.Stack().set({ alignX: "center" diff --git a/services/static-webserver/client/source/class/osparc/desktop/SlideshowToolbar.js b/services/static-webserver/client/source/class/osparc/desktop/SlideshowToolbar.js index 257f23ec4e6..654fe5fd51f 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/SlideshowToolbar.js +++ b/services/static-webserver/client/source/class/osparc/desktop/SlideshowToolbar.js @@ -203,7 +203,7 @@ qx.Class.define("osparc.desktop.SlideshowToolbar", { }, __openStudyDetails: function() { - const studyDetails = new osparc.studycard.Large(this.getStudy()); + const studyDetails = new osparc.info.StudyLarge(this.getStudy()); const title = this.tr("Study Information"); const width = 500; const height = 500; diff --git a/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js b/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js index 4148630b091..db1c318bfaa 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js +++ b/services/static-webserver/client/source/class/osparc/desktop/StudyEditor.js @@ -328,7 +328,7 @@ qx.Class.define("osparc.desktop.StudyEditor", { this.__requestStartPipeline(this.getStudy().getUuid(), partialPipeline); }) .catch(() => { - this.__getStudyLogger().error(null, "Run failed"); + this.getStudyLogger().error(null, "Run failed"); this.getStudy().setPipelineRunning(false); }); }, @@ -338,14 +338,14 @@ qx.Class.define("osparc.desktop.StudyEditor", { const req = new osparc.io.request.ApiRequest(url, "POST"); req.addListener("success", this.__onPipelinesubmitted, this); req.addListener("error", () => { - this.__getStudyLogger().error(null, "Error submitting pipeline"); + this.getStudyLogger().error(null, "Error submitting pipeline"); this.getStudy().setPipelineRunning(false); }, this); req.addListener("fail", e => { if (e.getTarget().getStatus() == "403") { - this.__getStudyLogger().error(null, "Pipeline is already running"); + this.getStudyLogger().error(null, "Pipeline is already running"); } else if (e.getTarget().getStatus() == "422") { - this.__getStudyLogger().info(null, "The pipeline is up-to-date"); + this.getStudyLogger().info(null, "The pipeline is up-to-date"); const msg = this.tr("The pipeline is up-to-date. Do you want to re-run it?"); const win = new osparc.ui.window.Confirmation(msg).set({ confirmText: this.tr("Run"), @@ -359,7 +359,7 @@ qx.Class.define("osparc.desktop.StudyEditor", { } }, this); } else { - this.__getStudyLogger().error(null, "Failed submitting pipeline"); + this.getStudyLogger().error(null, "Failed submitting pipeline"); } this.getStudy().setPipelineRunning(false); }, this); @@ -375,9 +375,9 @@ qx.Class.define("osparc.desktop.StudyEditor", { req.setRequestData(requestData); req.send(); if (partialPipeline.length) { - this.__getStudyLogger().info(null, "Starting partial pipeline"); + this.getStudyLogger().info(null, "Starting partial pipeline"); } else { - this.__getStudyLogger().info(null, "Starting pipeline"); + this.getStudyLogger().info(null, "Starting pipeline"); } return true; @@ -387,15 +387,15 @@ qx.Class.define("osparc.desktop.StudyEditor", { const resp = e.getTarget().getResponse(); const pipelineId = resp.data["pipeline_id"]; const iterationRefIds = resp.data["ref_ids"]; - this.__getStudyLogger().debug(null, "Pipeline ID " + pipelineId); + this.getStudyLogger().debug(null, "Pipeline ID " + pipelineId); const notGood = [null, undefined, -1]; if (notGood.includes(pipelineId)) { - this.__getStudyLogger().error(null, "Submission failed"); + this.getStudyLogger().error(null, "Submission failed"); } else { if (iterationRefIds) { this.__reloadSnapshotsAndIterations(); } - this.__getStudyLogger().info(null, "Pipeline started"); + this.getStudyLogger().info(null, "Pipeline started"); /* If no projectStateUpdated comes in 60 seconds, client must check state of pipeline and update button accordingly. */ const timer = setTimeout(() => { @@ -422,12 +422,12 @@ qx.Class.define("osparc.desktop.StudyEditor", { __requestStopPipeline: function(studyId) { const url = "/computations/" + encodeURIComponent(studyId) + ":stop"; const req = new osparc.io.request.ApiRequest(url, "POST"); - req.addListener("success", () => this.__getStudyLogger().debug(null, "Pipeline aborting"), this); - req.addListener("error", () => this.__getStudyLogger().error(null, "Error stopping pipeline"), this); - req.addListener("fail", () => this.__getStudyLogger().error(null, "Failed stopping pipeline"), this); + req.addListener("success", () => this.getStudyLogger().debug(null, "Pipeline aborting"), this); + req.addListener("error", () => this.getStudyLogger().error(null, "Error stopping pipeline"), this); + req.addListener("fail", () => this.getStudyLogger().error(null, "Failed stopping pipeline"), this); req.send(); - this.__getStudyLogger().info(null, "Stopping pipeline"); + this.getStudyLogger().info(null, "Stopping pipeline"); return true; }, // ------------------ START/STOP PIPELINE ------------------ @@ -436,13 +436,13 @@ qx.Class.define("osparc.desktop.StudyEditor", { this.updateStudyDocument(false) .then(() => { if (node) { - this.__getStudyLogger().debug(node.getNodeId(), "Retrieving inputs"); + this.getStudyLogger().debug(node.getNodeId(), "Retrieving inputs"); node.retrieveInputs(portKey); } else { - this.__getStudyLogger().debug(null, "Retrieving inputs"); + this.getStudyLogger().debug(null, "Retrieving inputs"); } }); - this.__getStudyLogger().debug(null, "Updating pipeline"); + this.getStudyLogger().debug(null, "Updating pipeline"); }, // overridden @@ -455,7 +455,7 @@ qx.Class.define("osparc.desktop.StudyEditor", { this.__slideshowView.nodeSelected(nodeId); }, - __getStudyLogger: function() { + getStudyLogger: function() { return this.__workbenchView.getLogger(); }, @@ -615,7 +615,7 @@ qx.Class.define("osparc.desktop.StudyEditor", { console.error(error); osparc.component.message.FlashMessenger.getInstance().logAs(this.tr("Error saving the study"), "ERROR"); } - this.__getStudyLogger().error(null, "Error updating pipeline"); + this.getStudyLogger().error(null, "Error updating pipeline"); // Need to throw the error to be able to handle it later throw error; }) diff --git a/services/static-webserver/client/source/class/osparc/desktop/WorkbenchView.js b/services/static-webserver/client/source/class/osparc/desktop/WorkbenchView.js index 6432b0af539..d3c222e15d4 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/WorkbenchView.js +++ b/services/static-webserver/client/source/class/osparc/desktop/WorkbenchView.js @@ -832,7 +832,7 @@ qx.Class.define("osparc.desktop.WorkbenchView", { this.__studyOptionsPage.getChildControl("button").show(); this.getChildControl("side-panel-right-tabs").setSelection([this.__studyOptionsPage]); - this.__studyOptionsPage.add(new osparc.studycard.Medium(study), { + this.__studyOptionsPage.add(new osparc.info.StudyMedium(study), { flex: 1 }); diff --git a/services/static-webserver/client/source/class/osparc/info/MergedLarge.js b/services/static-webserver/client/source/class/osparc/info/MergedLarge.js new file mode 100644 index 00000000000..0959709ed9a --- /dev/null +++ b/services/static-webserver/client/source/class/osparc/info/MergedLarge.js @@ -0,0 +1,427 @@ +/* ************************************************************************ + + osparc - the simcore frontend + + https://osparc.io + + Copyright: + 2022 IT'IS Foundation, https://itis.swiss + + License: + MIT: https://opensource.org/licenses/MIT + + Authors: + * Odei Maiz (odeimaiz) + +************************************************************************ */ + + +qx.Class.define("osparc.info.MergedLarge", { + extend: qx.ui.core.Widget, + + /** + * @param study {osparc.data.model.Study} Study + */ + construct: function(study) { + this.base(arguments); + + this.set({ + minHeight: 350, + padding: this.self().PADDING + }); + this._setLayout(new qx.ui.layout.VBox(8)); + + this.setStudy(study); + const nodes = study.getWorkbench().getNodes(); + const nodeIds = Object.keys(nodes); + if (nodeIds.length) { + this.setService(nodes[nodeIds[0]]); + } + + this.addListenerOnce("appear", () => this.__rebuildLayout(), this); + this.addListener("resize", () => this.__rebuildLayout(), this); + }, + + events: { + "updateStudy": "qx.event.type.Data" + }, + + properties: { + study: { + check: "osparc.data.model.Study", + init: null, + nullable: false + }, + + service: { + check: "osparc.data.model.Node", + init: null, + nullable: false + } + }, + + statics: { + PADDING: 5, + EXTRA_INFO_WIDTH: 250, + THUMBNAIL_MIN_WIDTH: 150, + THUMBNAIL_MAX_WIDTH: 230 + }, + + members: { + __rebuildLayout: function() { + this._removeAll(); + + const title = this.__createTitle(); + const titleLayout = this.__createViewWithEdit(title, this.__openTitleEditor); + this._add(titleLayout); + + const extraInfo = this.__extraInfo(); + const extraInfoLayout = this.__createExtraInfo(extraInfo); + this._add(extraInfoLayout); + + const bounds = this.getBounds(); + const offset = 30; + const widgetWidth = bounds ? bounds.width - offset : 500 - offset; + let thumbnailWidth = widgetWidth - 2*this.self().PADDING; + const maxThumbnailHeight = extraInfo.length*20; + const hBox = new qx.ui.container.Composite(new qx.ui.layout.HBox(3).set({ + alignX: "center" + })); + hBox.add(extraInfoLayout); + thumbnailWidth -= this.self().EXTRA_INFO_WIDTH; + thumbnailWidth = Math.min(thumbnailWidth - 20, this.self().THUMBNAIL_MAX_WIDTH); + const thumbnail = this.__createThumbnail(thumbnailWidth, maxThumbnailHeight); + const thumbnailLayout = this.__createViewWithEdit(thumbnail, this.__openThumbnailEditor); + thumbnailLayout.getLayout().set({ + alignX: "center" + }); + hBox.add(thumbnailLayout, { + flex: 1 + }); + this._add(hBox); + + const tags = this.__createTags(); + if (this.__isOwner()) { + const editInTitle = this.__createViewWithEdit(tags.getChildren()[0], this.__openTagsEditor); + tags.addAt(editInTitle, 0); + if (this.__isOwner()) { + osparc.utils.Utils.setIdToWidget(editInTitle.getChildren()[1], "editStudyEditTagsBtn"); + } + } + this._add(tags); + + const description = this.__createDescription(); + if (this.__isOwner()) { + const editInTitle = this.__createViewWithEdit(description.getChildren()[0], this.__openDescriptionEditor); + 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 + }); + more.setCollapsed(true); + more.getChildControl("title").setFont("title-12"); + this._add(more, { + flex: 1 + }); + const copy2Clip = osparc.utils.Utils.getCopyButton(); + copy2Clip.addListener("execute", () => osparc.utils.Utils.copyTextToClipboard(osparc.utils.Utils.prettifyJson(this.getService().serialize())), this); + more.getChildControl("header").add(copy2Clip); + }, + + __isOwner: function() { + return osparc.data.model.Study.isOwner(this.getStudy()); + }, + + __createViewWithEdit: function(view, cb) { + const layout = new qx.ui.container.Composite(new qx.ui.layout.HBox(5).set({ + alignY: "middle" + })); + layout.add(view); + if (this.__isOwner()) { + const editBtn = osparc.utils.Utils.getEditButton(); + editBtn.addListener("execute", () => cb.call(this), this); + layout.add(editBtn); + } + + return layout; + }, + + __extraInfo: function() { + const extraInfo = [{ + label: this.tr("Author"), + view: this.__createOwner(), + action: null + }, { + label: this.tr("Creation Date"), + view: this.__createCreationDate(), + action: null + }, { + label: this.tr("Last Modified"), + view: this.__createLastChangeDate(), + action: null + }, { + label: this.tr("Access Rights"), + view: this.__createAccessRights(), + action: null + }]; + + if (this.getStudy().getQuality() && osparc.component.metadata.Quality.isEnabled(this.getStudy().getQuality())) { + extraInfo.push({ + label: this.tr("Quality"), + view: this.__createQuality(), + action: null + }); + } + + extraInfo.push({ + label: this.tr("Classifiers"), + view: this.__createClassifiers(), + action: null + }); + + if (osparc.data.Permissions.getInstance().isTester()) { + extraInfo.splice(0, 0, { + label: this.tr("Study ID"), + view: this.__createStudyId(), + action: { + button: osparc.utils.Utils.getCopyButton(), + callback: this.__copyUuidToClipboard, + ctx: this + } + }); + + extraInfo.splice(1, 0, { + label: this.tr("Service ID"), + view: this.__createNodeId(), + action: { + button: osparc.utils.Utils.getCopyButton(), + callback: this.__copyNodeIdToClipboard, + ctx: this + } + }); + + extraInfo.splice(2, 0, { + label: this.tr("Key"), + view: this.__createKey(), + action: { + button: osparc.utils.Utils.getCopyButton(), + callback: this.__copyKeyToClipboard, + ctx: this + } + }); + + extraInfo.splice(3, 0, { + label: this.tr("Version"), + view: this.__createVersion(), + action: null + }); + } + return extraInfo; + }, + + __createExtraInfo: function(extraInfo) { + const moreInfo = osparc.info.StudyUtils.createExtraInfo(extraInfo).set({ + width: this.self().EXTRA_INFO_WIDTH + }); + + return moreInfo; + }, + + __createTitle: function() { + const title = osparc.info.StudyUtils.createTitle(this.getStudy()).set({ + font: "title-16" + }); + return title; + }, + + __createStudyId: function() { + return osparc.info.StudyUtils.createUuid(this.getStudy()).set({ + maxWidth: 200 + }); + }, + + __createNodeId: function() { + return osparc.info.ServiceUtils.createNodeId(this.getService().getNodeId()).set({ + maxWidth: 200 + }); + }, + + __createKey: function() { + return osparc.info.ServiceUtils.createKey(this.getService().getKey()); + }, + + __createVersion: function() { + return osparc.info.ServiceUtils.createVersion(this.getService().getVersion()); + }, + + __createOwner: function() { + return osparc.info.StudyUtils.createOwner(this.getStudy()); + }, + + __createCreationDate: function() { + return osparc.info.StudyUtils.createCreationDate(this.getStudy()); + }, + + __createLastChangeDate: function() { + return osparc.info.StudyUtils.createLastChangeDate(this.getStudy()); + }, + + __createAccessRights: function() { + return osparc.info.StudyUtils.createAccessRights(this.getStudy()); + }, + + __createClassifiers: function() { + return osparc.info.StudyUtils.createClassifiers(this.getStudy()); + }, + + __createQuality: function() { + return osparc.info.StudyUtils.createQuality(this.getStudy()); + }, + + __createThumbnail: function(maxWidth, maxHeight = 160) { + return osparc.info.StudyUtils.createThumbnail(this.getStudy(), maxWidth, maxHeight); + }, + + __createTags: function() { + return osparc.info.StudyUtils.createTags(this.getStudy()); + }, + + __createDescription: function() { + const maxHeight = 400; + return osparc.info.StudyUtils.createDescription(this.getStudy(), maxHeight); + }, + + __createResources: function() { + const resourcesLayout = osparc.info.ServiceUtils.createResourcesInfo(); + resourcesLayout.exclude(); + let promise = null; + if (this.getService().getNodeId()) { + const params = { + url: { + studyId: this.getStudy().getUuid(), + nodeId: this.getService().getNodeId() + } + }; + promise = osparc.data.Resources.fetch("nodesInStudyResources", "getResources", params); + } else { + const params = { + url: osparc.data.Resources.getServiceUrl( + this.getService().getKey(), + this.getService().getVersion() + ) + }; + promise = osparc.data.Resources.fetch("serviceResources", "getResources", params); + } + promise + .then(serviceResources => { + resourcesLayout.show(); + osparc.info.ServiceUtils.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().serialize(), "serviceDescriptionSettings")); + return container; + }, + + __openTitleEditor: function() { + const title = this.tr("Edit Title"); + const titleEditor = new osparc.component.widget.Renamer(this.getStudy().getName(), null, title); + titleEditor.addListener("labelChanged", e => { + titleEditor.close(); + const newLabel = e.getData()["newLabel"]; + this.__updateStudy({ + "name": newLabel + }); + }, this); + titleEditor.center(); + titleEditor.open(); + }, + + __copyUuidToClipboard: function() { + osparc.utils.Utils.copyTextToClipboard(this.getStudy().getUuid()); + }, + + __copyNodeIdToClipboard: function() { + osparc.utils.Utils.copyTextToClipboard(this.getService().getNodeId()); + }, + + __copyKeyToClipboard: function() { + osparc.utils.Utils.copyTextToClipboard(this.getService().getKey()); + }, + + __openTagsEditor: function() { + const tagManager = new osparc.component.form.tag.TagManager(this.getStudy().serialize(), null, "study", this.getStudy().getUuid()).set({ + liveUpdate: false + }); + tagManager.addListener("updateTags", e => { + tagManager.close(); + const updatedData = e.getData(); + this.getStudy().setTags(updatedData["tags"]); + this.fireDataEvent("updateStudy", updatedData); + }, this); + }, + + __openThumbnailEditor: function() { + const title = this.tr("Edit Thumbnail"); + const oldThumbnail = this.getStudy().getThumbnail(); + let suggestions = new Set([]); + const wb = this.getStudy().getWorkbench(); + const nodes = wb.getWorkbenchInitData() ? wb.getWorkbenchInitData() : wb.getNodes(); + Object.values(nodes).forEach(node => { + const srvMetadata = osparc.utils.Services.getMetaData(node["key"], node["version"]); + if (srvMetadata && srvMetadata["thumbnail"] && !osparc.data.model.Node.isFrontend(node)) { + suggestions.add(srvMetadata["thumbnail"]); + } + }); + suggestions = Array.from(suggestions); + const thumbnailEditor = new osparc.component.editor.ThumbnailEditor(oldThumbnail, suggestions); + const win = osparc.ui.window.Window.popUpInWindow(thumbnailEditor, title, suggestions.length > 2 ? 500 : 350, suggestions.length ? 280 : 110); + thumbnailEditor.addListener("updateThumbnail", e => { + win.close(); + const validUrl = e.getData(); + this.__updateStudy({ + "thumbnail": validUrl + }); + }, this); + thumbnailEditor.addListener("cancel", () => win.close()); + }, + + __openDescriptionEditor: function() { + const title = this.tr("Edit Description"); + const textEditor = new osparc.component.editor.TextEditor(this.getStudy().getDescription()); + const win = osparc.ui.window.Window.popUpInWindow(textEditor, title, 400, 300); + textEditor.addListener("textChanged", e => { + win.close(); + const newDescription = e.getData(); + this.__updateStudy({ + "description": newDescription + }); + }, this); + textEditor.addListener("cancel", () => { + win.close(); + }, this); + }, + + __updateStudy: function(params) { + this.getStudy().updateStudy(params) + .then(studyData => { + this.fireDataEvent("updateStudy", studyData); + qx.event.message.Bus.getInstance().dispatchByName("updateStudy", studyData); + }) + .catch(err => { + console.error(err); + osparc.component.message.FlashMessenger.getInstance().logAs(this.tr("There was an error while updating the information."), "ERROR"); + }); + } + } +}); diff --git a/services/static-webserver/client/source/class/osparc/servicecard/Large.js b/services/static-webserver/client/source/class/osparc/info/ServiceLarge.js similarity index 91% rename from services/static-webserver/client/source/class/osparc/servicecard/Large.js rename to services/static-webserver/client/source/class/osparc/info/ServiceLarge.js index 318ff2bd40a..0a8e7e738b2 100644 --- a/services/static-webserver/client/source/class/osparc/servicecard/Large.js +++ b/services/static-webserver/client/source/class/osparc/info/ServiceLarge.js @@ -16,7 +16,7 @@ ************************************************************************ */ -qx.Class.define("osparc.servicecard.Large", { +qx.Class.define("osparc.info.ServiceLarge", { extend: qx.ui.core.Widget, /** @@ -152,7 +152,7 @@ qx.Class.define("osparc.servicecard.Large", { this._add(resources); const rawMetadata = this.__createRawMetadata(); - const more = new osparc.desktop.PanelView(this.tr("raw metadata"), rawMetadata).set({ + const more = new osparc.desktop.PanelView(this.tr("Raw metadata"), rawMetadata).set({ caretSize: 14 }); more.setCollapsed(true); @@ -199,7 +199,7 @@ qx.Class.define("osparc.servicecard.Large", { } else { text = serviceName; } - const title = osparc.servicecard.Utils.createTitle(text).set({ + const title = osparc.info.ServiceUtils.createTitle(text).set({ font: "title-16" }); return title; @@ -253,19 +253,9 @@ qx.Class.define("osparc.servicecard.Large", { } if (osparc.data.Permissions.getInstance().isTester()) { - extraInfo.unshift({ - label: this.tr("Key"), - view: this.__createKey(), - action: { - button: osparc.utils.Utils.getCopyButton(), - callback: this.__copyKeyToClipboard, - ctx: this - } - }); - if (this.getNodeId()) { - extraInfo.unshift({ - label: this.tr("UUID"), + extraInfo.splice(0, 0, { + label: this.tr("Service ID"), view: this.__createNodeId(), action: { button: osparc.utils.Utils.getCopyButton(), @@ -274,13 +264,23 @@ qx.Class.define("osparc.servicecard.Large", { } }); } + + extraInfo.splice(1, 0, { + label: this.tr("Key"), + view: this.__createKey(), + action: { + button: osparc.utils.Utils.getCopyButton(), + callback: this.__copyKeyToClipboard, + ctx: this + } + }); } return extraInfo; }, __createExtraInfo: function(extraInfo) { - const moreInfo = osparc.servicecard.Utils.createExtraInfo(extraInfo).set({ + const moreInfo = osparc.info.ServiceUtils.createExtraInfo(extraInfo).set({ width: this.self().EXTRA_INFO_WIDTH }); @@ -288,48 +288,48 @@ qx.Class.define("osparc.servicecard.Large", { }, __createNodeId: function() { - return osparc.servicecard.Utils.createNodeId(this.getNodeId()); + return osparc.info.ServiceUtils.createNodeId(this.getNodeId()); }, __createKey: function() { - return osparc.servicecard.Utils.createKey(this.getService()); + return osparc.info.ServiceUtils.createKey(this.getService()["key"]); }, __createVersion: function() { - return osparc.servicecard.Utils.createVersion(this.getService()); + return osparc.info.ServiceUtils.createVersion(this.getService()["version"]); }, __createContact: function() { - return osparc.servicecard.Utils.createContact(this.getService()); + return osparc.info.ServiceUtils.createContact(this.getService()); }, __createAuthors: function() { - return osparc.servicecard.Utils.createAuthors(this.getService()); + return osparc.info.ServiceUtils.createAuthors(this.getService()); }, __createAccessRights: function() { - return osparc.servicecard.Utils.createAccessRights(this.getService()); + return osparc.info.ServiceUtils.createAccessRights(this.getService()); }, __createClassifiers: function() { - return osparc.servicecard.Utils.createClassifiers(this.getService()); + return osparc.info.ServiceUtils.createClassifiers(this.getService()); }, __createQuality: function() { - return osparc.servicecard.Utils.createQuality(this.getService()); + return osparc.info.ServiceUtils.createQuality(this.getService()); }, __createThumbnail: function(maxWidth, maxHeight = 160) { - return osparc.servicecard.Utils.createThumbnail(this.getService(), maxWidth, maxHeight); + return osparc.info.ServiceUtils.createThumbnail(this.getService(), maxWidth, maxHeight); }, __createDescription: function() { const maxHeight = 400; - return osparc.servicecard.Utils.createDescription(this.getService(), maxHeight); + return osparc.info.ServiceUtils.createDescription(this.getService(), maxHeight); }, __createResources: function() { - const resourcesLayout = osparc.servicecard.Utils.createResourcesInfo(); + const resourcesLayout = osparc.info.ServiceUtils.createResourcesInfo(); resourcesLayout.exclude(); let promise = null; if (this.getNodeId()) { @@ -352,7 +352,7 @@ qx.Class.define("osparc.servicecard.Large", { promise .then(serviceResources => { resourcesLayout.show(); - osparc.servicecard.Utils.resourcesToResourcesInfo(resourcesLayout, serviceResources); + osparc.info.ServiceUtils.resourcesToResourcesInfo(resourcesLayout, serviceResources); }) .catch(err => console.error(err)); return resourcesLayout; @@ -387,7 +387,7 @@ qx.Class.define("osparc.servicecard.Large", { }, __openAccessRights: function() { - const permissionsView = osparc.servicecard.Utils.openAccessRights(this.getService()); + const permissionsView = osparc.info.ServiceUtils.openAccessRights(this.getService()); permissionsView.addListener("updateService", e => { const updatedServiceData = e.getData(); this.setService(updatedServiceData); @@ -414,7 +414,7 @@ qx.Class.define("osparc.servicecard.Large", { }, __openQuality: function() { - const qualityEditor = osparc.servicecard.Utils.openQuality(this.getService()); + const qualityEditor = osparc.info.ServiceUtils.openQuality(this.getService()); qualityEditor.addListener("updateQuality", e => { const updatedServiceData = e.getData(); this.setService(updatedServiceData); diff --git a/services/static-webserver/client/source/class/osparc/servicecard/Utils.js b/services/static-webserver/client/source/class/osparc/info/ServiceUtils.js similarity index 96% rename from services/static-webserver/client/source/class/osparc/servicecard/Utils.js rename to services/static-webserver/client/source/class/osparc/info/ServiceUtils.js index c113fe5a065..b1fe55159b3 100644 --- a/services/static-webserver/client/source/class/osparc/servicecard/Utils.js +++ b/services/static-webserver/client/source/class/osparc/info/ServiceUtils.js @@ -16,7 +16,7 @@ ************************************************************************ */ -qx.Class.define("osparc.servicecard.Utils", { +qx.Class.define("osparc.info.ServiceUtils", { type: "static", statics: { @@ -46,25 +46,25 @@ qx.Class.define("osparc.servicecard.Utils", { }, /** - * @param serviceData {Object} Serialized Service Object + * @param serviceKey {String} Service key */ - createKey: function(serviceData) { + createKey: function(serviceKey) { const key = new qx.ui.basic.Label().set({ maxWidth: 220 }); key.set({ - value: serviceData["key"], - toolTipText: serviceData["key"] + value: serviceKey, + toolTipText: serviceKey }); return key; }, /** - * @param serviceData {Object} Serialized Service Object + * @param serviceVersion {String} Service version */ - createVersion: function(serviceData) { + createVersion: function(serviceVersion) { const key = new qx.ui.basic.Label().set({ - value: serviceData["version"], + value: serviceVersion, maxWidth: 150 }); return key; diff --git a/services/static-webserver/client/source/class/osparc/studycard/Large.js b/services/static-webserver/client/source/class/osparc/info/StudyLarge.js similarity index 91% rename from services/static-webserver/client/source/class/osparc/studycard/Large.js rename to services/static-webserver/client/source/class/osparc/info/StudyLarge.js index 97c818cc241..68e0910f66e 100644 --- a/services/static-webserver/client/source/class/osparc/studycard/Large.js +++ b/services/static-webserver/client/source/class/osparc/info/StudyLarge.js @@ -16,7 +16,7 @@ ************************************************************************ */ -qx.Class.define("osparc.studycard.Large", { +qx.Class.define("osparc.info.StudyLarge", { extend: qx.ui.core.Widget, /** @@ -205,9 +205,9 @@ qx.Class.define("osparc.studycard.Large", { }); if (osparc.data.Permissions.getInstance().isTester()) { - extraInfo.unshift({ - label: this.tr("UUID"), - view: this.__createUuid(), + extraInfo.splice(0, 0, { + label: this.tr("Study ID"), + view: this.__createStudyId(), action: { button: osparc.utils.Utils.getCopyButton(), callback: this.__copyUuidToClipboard, @@ -219,7 +219,7 @@ qx.Class.define("osparc.studycard.Large", { }, __createExtraInfo: function(extraInfo) { - const moreInfo = osparc.studycard.Utils.createExtraInfo(extraInfo).set({ + const moreInfo = osparc.info.StudyUtils.createExtraInfo(extraInfo).set({ width: this.self().EXTRA_INFO_WIDTH }); @@ -227,51 +227,51 @@ qx.Class.define("osparc.studycard.Large", { }, __createTitle: function() { - const title = osparc.studycard.Utils.createTitle(this.getStudy()).set({ + const title = osparc.info.StudyUtils.createTitle(this.getStudy()).set({ font: "title-16" }); return title; }, - __createUuid: function() { - return osparc.studycard.Utils.createUuid(this.getStudy()); + __createStudyId: function() { + return osparc.info.StudyUtils.createUuid(this.getStudy()); }, __createOwner: function() { - return osparc.studycard.Utils.createOwner(this.getStudy()); + return osparc.info.StudyUtils.createOwner(this.getStudy()); }, __createCreationDate: function() { - return osparc.studycard.Utils.createCreationDate(this.getStudy()); + return osparc.info.StudyUtils.createCreationDate(this.getStudy()); }, __createLastChangeDate: function() { - return osparc.studycard.Utils.createLastChangeDate(this.getStudy()); + return osparc.info.StudyUtils.createLastChangeDate(this.getStudy()); }, __createAccessRights: function() { - return osparc.studycard.Utils.createAccessRights(this.getStudy()); + return osparc.info.StudyUtils.createAccessRights(this.getStudy()); }, __createClassifiers: function() { - return osparc.studycard.Utils.createClassifiers(this.getStudy()); + return osparc.info.StudyUtils.createClassifiers(this.getStudy()); }, __createQuality: function() { - return osparc.studycard.Utils.createQuality(this.getStudy()); + return osparc.info.StudyUtils.createQuality(this.getStudy()); }, __createThumbnail: function(maxWidth, maxHeight = 160) { - return osparc.studycard.Utils.createThumbnail(this.getStudy(), maxWidth, maxHeight); + return osparc.info.StudyUtils.createThumbnail(this.getStudy(), maxWidth, maxHeight); }, __createTags: function() { - return osparc.studycard.Utils.createTags(this.getStudy()); + return osparc.info.StudyUtils.createTags(this.getStudy()); }, __createDescription: function() { const maxHeight = 400; - return osparc.studycard.Utils.createDescription(this.getStudy(), maxHeight); + return osparc.info.StudyUtils.createDescription(this.getStudy(), maxHeight); }, __openTitleEditor: function() { @@ -293,7 +293,7 @@ qx.Class.define("osparc.studycard.Large", { }, __openAccessRights: function() { - const permissionsView = osparc.studycard.Utils.openAccessRights(this.getStudy().serialize()); + const permissionsView = osparc.info.StudyUtils.openAccessRights(this.getStudy().serialize()); permissionsView.addListener("updateStudy", e => { const updatedData = e.getData(); this.getStudy().setAccessRights(updatedData["accessRights"]); @@ -320,7 +320,7 @@ qx.Class.define("osparc.studycard.Large", { }, __openQuality: function() { - const qualityEditor = osparc.studycard.Utils.openQuality(this.getStudy().serialize()); + const qualityEditor = osparc.info.StudyUtils.openQuality(this.getStudy().serialize()); qualityEditor.addListener("updateQuality", e => { const updatedData = e.getData(); this.getStudy().setQuality(updatedData["quality"]); diff --git a/services/static-webserver/client/source/class/osparc/studycard/Medium.js b/services/static-webserver/client/source/class/osparc/info/StudyMedium.js similarity index 89% rename from services/static-webserver/client/source/class/osparc/studycard/Medium.js rename to services/static-webserver/client/source/class/osparc/info/StudyMedium.js index fc623e84b49..951b05293cd 100644 --- a/services/static-webserver/client/source/class/osparc/studycard/Medium.js +++ b/services/static-webserver/client/source/class/osparc/info/StudyMedium.js @@ -16,7 +16,7 @@ ************************************************************************ */ -qx.Class.define("osparc.studycard.Medium", { +qx.Class.define("osparc.info.StudyMedium", { extend: qx.ui.core.Widget, /** @@ -197,7 +197,7 @@ qx.Class.define("osparc.studycard.Medium", { }, __createExtraInfo: function(extraInfo) { - const moreInfo = osparc.studycard.Utils.createExtraInfo(extraInfo).set({ + const moreInfo = osparc.info.StudyUtils.createExtraInfo(extraInfo).set({ width: this.self().EXTRA_INFO_WIDTH }); @@ -205,32 +205,32 @@ qx.Class.define("osparc.studycard.Medium", { }, __createTitle: function() { - return osparc.studycard.Utils.createTitle(this.getStudy()); + return osparc.info.StudyUtils.createTitle(this.getStudy()); }, __createOwner: function() { - return osparc.studycard.Utils.createOwner(this.getStudy()); + return osparc.info.StudyUtils.createOwner(this.getStudy()); }, __createCreationDate: function() { - return osparc.studycard.Utils.createCreationDate(this.getStudy()); + return osparc.info.StudyUtils.createCreationDate(this.getStudy()); }, __createLastChangeDate: function() { - return osparc.studycard.Utils.createLastChangeDate(this.getStudy()); + return osparc.info.StudyUtils.createLastChangeDate(this.getStudy()); }, __createAccessRights: function() { - return osparc.studycard.Utils.createAccessRights(this.getStudy()); + return osparc.info.StudyUtils.createAccessRights(this.getStudy()); }, __createQuality: function() { - return osparc.studycard.Utils.createQuality(this.getStudy()); + return osparc.info.StudyUtils.createQuality(this.getStudy()); }, __createThumbnail: function(maxWidth, maxHeight = 150) { if (this.getStudy().getThumbnail()) { - return osparc.studycard.Utils.createThumbnail(this.getStudy(), maxWidth, maxHeight); + return osparc.info.StudyUtils.createThumbnail(this.getStudy(), maxWidth, maxHeight); } return null; }, @@ -238,13 +238,13 @@ qx.Class.define("osparc.studycard.Medium", { __createDescription: function() { if (this.getStudy().getDescription()) { const maxHeight = 300; - return osparc.studycard.Utils.createDescription(this.getStudy(), maxHeight); + return osparc.info.StudyUtils.createDescription(this.getStudy(), maxHeight); } return null; }, __openAccessRights: function() { - const permissionsView = osparc.studycard.Utils.openAccessRights(this.getStudy().serialize()); + const permissionsView = osparc.info.StudyUtils.openAccessRights(this.getStudy().serialize()); permissionsView.addListener("updateAccessRights", e => { const updatedData = e.getData(); this.getStudy().setAccessRights(updatedData["accessRights"]); @@ -252,7 +252,7 @@ qx.Class.define("osparc.studycard.Medium", { }, __openQuality: function() { - const qualityEditor = osparc.studycard.Utils.openQuality(this.getStudy().serialize()); + const qualityEditor = osparc.info.StudyUtils.openQuality(this.getStudy().serialize()); qualityEditor.addListener("updateQuality", e => { const updatedData = e.getData(); this.getStudy().setQuality(updatedData["quality"]); @@ -260,7 +260,7 @@ qx.Class.define("osparc.studycard.Medium", { }, __openStudyDetails: function() { - const studyDetails = new osparc.studycard.Large(this.getStudy()); + const studyDetails = new osparc.info.StudyLarge(this.getStudy()); const title = this.tr("Study Information"); const width = 500; const height = 500; diff --git a/services/static-webserver/client/source/class/osparc/studycard/Utils.js b/services/static-webserver/client/source/class/osparc/info/StudyUtils.js similarity index 99% rename from services/static-webserver/client/source/class/osparc/studycard/Utils.js rename to services/static-webserver/client/source/class/osparc/info/StudyUtils.js index af8bddb3cff..2771afcb08f 100644 --- a/services/static-webserver/client/source/class/osparc/studycard/Utils.js +++ b/services/static-webserver/client/source/class/osparc/info/StudyUtils.js @@ -16,7 +16,7 @@ ************************************************************************ */ -qx.Class.define("osparc.studycard.Utils", { +qx.Class.define("osparc.info.StudyUtils", { type: "static", statics: { diff --git a/services/static-webserver/client/source/class/osparc/navigation/NavigationBar.js b/services/static-webserver/client/source/class/osparc/navigation/NavigationBar.js index 4a524f99a5f..a9a821925f9 100644 --- a/services/static-webserver/client/source/class/osparc/navigation/NavigationBar.js +++ b/services/static-webserver/client/source/class/osparc/navigation/NavigationBar.js @@ -61,7 +61,8 @@ qx.Class.define("osparc.navigation.NavigationBar", { }, events: { - "backToDashboardPressed": "qx.event.type.Event" + "backToDashboardPressed": "qx.event.type.Event", + "downloadStudyLogs": "qx.event.type.Event" }, properties: { @@ -171,7 +172,7 @@ qx.Class.define("osparc.navigation.NavigationBar", { this.getChildControl("left-items").add(control); break; case "dashboard-button": - control = new osparc.ui.form.FetchButton(this.tr("Dashboard"), "@FontAwesome5Solid/arrow-left/16").set({ + control = new osparc.ui.form.FetchButton(this.tr("Dashboard"), "@FontAwesome5Solid/home/16").set({ ...this.self().BUTTON_OPTIONS, font: "title-14" }); @@ -182,7 +183,52 @@ qx.Class.define("osparc.navigation.NavigationBar", { case "dashboard-label": control = new qx.ui.basic.Label(this.tr("Dashboard")).set({ paddingLeft: 20, // to align it with the button - font: "text-16" + font: "text-14" + }); + this.getChildControl("left-items").add(control); + break; + case "study-menu-info": + control = new qx.ui.menu.Button().set({ + label: this.tr("Information..."), + icon: "@MaterialIcons/info_outline/14", + ...this.self().BUTTON_OPTIONS + }); + control.addListener("execute", () => { + const infoMerged = new osparc.info.MergedLarge(this.getStudy()); + const title = this.tr("Information"); + const width = 600; + const height = 700; + osparc.ui.window.Window.popUpInWindow(infoMerged, title, width, height); + }); + break; + case "study-menu-download-logs": + control = new qx.ui.menu.Button().set({ + label: this.tr("Download logs"), + icon: "@FontAwesome5Solid/download/14", + ...this.self().BUTTON_OPTIONS + }); + control.addListener("execute", () => this.fireEvent("downloadStudyLogs")); + break; + case "study-menu-button": { + const optionsMenu = new qx.ui.menu.Menu(); + optionsMenu.add(this.getChildControl("study-menu-info")); + optionsMenu.add(this.getChildControl("study-menu-download-logs")); + control = new qx.ui.form.MenuButton().set({ + ...this.self().BUTTON_OPTIONS, + menu: optionsMenu, + icon: "@FontAwesome5Solid/ellipsis-v/16" + }); + this.getChildControl("left-items").add(control); + break; + } + case "edit-title-label": + control = new osparc.ui.form.EditLabel().set({ + labelFont: "text-16", + inputFont: "text-16" + }); + control.addListener("editValue", e => { + const newLabel = e.getData(); + this.getStudy().setName(newLabel); }); this.getChildControl("left-items").add(control); break; @@ -252,6 +298,10 @@ qx.Class.define("osparc.navigation.NavigationBar", { case "dashboard": this.getChildControl("dashboard-label").show(); this.getChildControl("dashboard-button").exclude(); + if (osparc.utils.Utils.isProduct("s4llite")) { + this.getChildControl("study-menu-button").exclude(); + this.getChildControl("edit-title-label").exclude(); + } this.getChildControl("read-only-icon").exclude(); if (this.__tabButtons) { this.__tabButtons.show(); @@ -262,6 +312,11 @@ qx.Class.define("osparc.navigation.NavigationBar", { case "app": this.getChildControl("dashboard-label").exclude(); this.getChildControl("dashboard-button").show(); + if (osparc.utils.Utils.isProduct("s4llite")) { + this.getChildControl("study-menu-button").show(); + this.getStudy().bind("name", this.getChildControl("edit-title-label"), "value"); + this.getChildControl("edit-title-label").show(); + } if (this.__tabButtons) { this.__tabButtons.exclude(); } diff --git a/services/static-webserver/client/source/class/osparc/ui/form/EditLabel.js b/services/static-webserver/client/source/class/osparc/ui/form/EditLabel.js index 6ee9b0d636a..2809e35166b 100644 --- a/services/static-webserver/client/source/class/osparc/ui/form/EditLabel.js +++ b/services/static-webserver/client/source/class/osparc/ui/form/EditLabel.js @@ -24,6 +24,7 @@ qx.Class.define("osparc.ui.form.EditLabel", { this._setLayout(new qx.ui.layout.HBox().set({ alignY: "middle" })); + this.setCursor("text"); this.__loadingIcon = new qx.ui.basic.Image("@FontAwesome5Solid/circle-notch/12"); this.__loadingIcon.getContentElement().addClass("rotate"); this.__renderLayout();