diff --git a/services/static-webserver/client/source/class/osparc/conversation/Conversation.js b/services/static-webserver/client/source/class/osparc/conversation/Conversation.js index 9bb2cab5b763..8ed290b1e09c 100644 --- a/services/static-webserver/client/source/class/osparc/conversation/Conversation.js +++ b/services/static-webserver/client/source/class/osparc/conversation/Conversation.js @@ -90,9 +90,7 @@ qx.Class.define("osparc.conversation.Conversation", { const newLabel = e.getData()["newLabel"]; if (this.getConversationId()) { osparc.study.Conversations.renameConversation(this.__studyData["uuid"], this.getConversationId(), newLabel) - .then(() => { - this.getChildControl("button").setLabel(newLabel); - }); + .then(() => this.renameConversation(newLabel)); } else { // create new conversation first osparc.study.Conversations.addConversation(this.__studyData["uuid"], newLabel) @@ -111,11 +109,11 @@ qx.Class.define("osparc.conversation.Conversation", { column: 3 }); - const trashButton = new qx.ui.form.Button(null, "@FontAwesome5Solid/times/12").set({ + const closeButton = new qx.ui.form.Button(null, "@FontAwesome5Solid/times/12").set({ ...buttonsAesthetics, paddingLeft: 4, // adds spacing between buttons }); - trashButton.addListener("execute", () => { + closeButton.addListener("execute", () => { const deleteConversation = () => { osparc.study.Conversations.deleteConversation(this.__studyData["uuid"], this.getConversationId()) .then(() => this.fireEvent("conversationDeleted")); @@ -138,15 +136,19 @@ qx.Class.define("osparc.conversation.Conversation", { } }); // eslint-disable-next-line no-underscore-dangle - tabButton._add(trashButton, { + tabButton._add(closeButton, { row: 0, column: 4 }); - this.bind("conversationId", trashButton, "visibility", { + this.bind("conversationId", closeButton, "visibility", { converter: value => value ? "visible" : "excluded" }); }, + renameConversation: function(newName) { + this.getChildControl("button").setLabel(newName); + }, + __buildLayout: function() { this.__messagesTitle = new qx.ui.basic.Label(); this._add(this.__messagesTitle); diff --git a/services/static-webserver/client/source/class/osparc/conversation/MessageUI.js b/services/static-webserver/client/source/class/osparc/conversation/MessageUI.js index fdddc051d6b3..399dfad55d72 100644 --- a/services/static-webserver/client/source/class/osparc/conversation/MessageUI.js +++ b/services/static-webserver/client/source/class/osparc/conversation/MessageUI.js @@ -101,10 +101,7 @@ qx.Class.define("osparc.conversation.MessageUI", { break; case "message-content": control = new osparc.ui.markdown.Markdown().set({ - decorator: "rounded", noMargin: true, - paddingLeft: 8, - paddingRight: 8, allowGrowX: true, }); control.getContentElement().setStyles({ diff --git a/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js b/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js index 9cefd0c9affa..6f335b73b3dc 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js @@ -1024,13 +1024,16 @@ qx.Class.define("osparc.dashboard.CardBase", { __openResourceDetails: function(openWindowCB) { const resourceData = this.getResourceData(); - const resourceDetails = new osparc.dashboard.ResourceDetails(resourceData); + const { + resourceDetails, + window, + } = osparc.dashboard.ResourceDetails.popUpInWindow(resourceData); + resourceDetails.addListenerOnce("pagesAdded", () => { if (openWindowCB in resourceDetails) { resourceDetails[openWindowCB](); } - }) - const win = osparc.dashboard.ResourceDetails.popUpInWindow(resourceDetails); + }); [ "updateStudy", "updateTemplate", @@ -1041,11 +1044,11 @@ qx.Class.define("osparc.dashboard.CardBase", { resourceDetails.addListener(ev, e => this.fireDataEvent(ev, e.getData())); }); resourceDetails.addListener("publishTemplate", e => { - win.close(); + window.close(); this.fireDataEvent("publishTemplate", e.getData()); }); resourceDetails.addListener("openStudy", e => { - const openCB = () => win.close(); + const openCB = () => window.close(); const studyId = e.getData()["uuid"]; const isStudyCreation = false; this._startStudyById(studyId, openCB, null, isStudyCreation); diff --git a/services/static-webserver/client/source/class/osparc/dashboard/NewPlusMenu.js b/services/static-webserver/client/source/class/osparc/dashboard/NewPlusMenu.js index 9de7d11a1739..d645af47b556 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/NewPlusMenu.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/NewPlusMenu.js @@ -360,10 +360,13 @@ qx.Class.define("osparc.dashboard.NewPlusMenu", { // so that is not consumed by the menu button itself e.stopPropagation(); latestMetadata["resourceType"] = "service"; - const resourceDetails = new osparc.dashboard.ResourceDetails(latestMetadata); - const win = osparc.dashboard.ResourceDetails.popUpInWindow(resourceDetails); + const { + resourceDetails, + window, + } = osparc.dashboard.ResourceDetails.popUpInWindow(latestMetadata); + resourceDetails.addListener("openService", ev => { - win.close(); + window.close(); const openServiceData = ev.getData(); this.fireDataEvent("newStudyFromServiceClicked", { serviceMetadata: openServiceData, diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js index b9666fec810a..eb58ca7fed86 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js @@ -939,19 +939,22 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", { }, _openResourceDetails: function(resourceData) { - const resourceDetails = new osparc.dashboard.ResourceDetails(resourceData); - const win = osparc.dashboard.ResourceDetails.popUpInWindow(resourceDetails); + const { + resourceDetails, + window, + } = osparc.dashboard.ResourceDetails.popUpInWindow(resourceData); + resourceDetails.addListener("updateStudy", e => this._updateStudyData(e.getData())); resourceDetails.addListener("updateTemplate", e => this._updateTemplateData(e.getData())); resourceDetails.addListener("updateTutorial", e => this._updateTutorialData(e.getData())); resourceDetails.addListener("updateService", e => this._updateServiceData(e.getData())); resourceDetails.addListener("updateHypertool", e => this._updateHypertoolData(e.getData())); resourceDetails.addListener("publishTemplate", e => { - win.close(); + window.close(); this.fireDataEvent("publishTemplate", e.getData()); }); resourceDetails.addListener("openStudy", e => { - const openCB = () => win.close(); + const openCB = () => window.close(); const studyId = e.getData()["uuid"]; const isStudyCreation = false; this._startStudyById(studyId, openCB, null, isStudyCreation); @@ -962,13 +965,13 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", { "openHypertool", ].forEach(eventName => { resourceDetails.addListener(eventName, e => { - win.close(); + window.close(); const templateData = e.getData(); this._createStudyFromTemplate(templateData); }); }); resourceDetails.addListener("openService", e => { - win.close(); + window.close(); const openServiceData = e.getData(); this._createStudyFromService(openServiceData["key"], openServiceData["version"]); }); diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js index bd5f17852275..c164ab94d793 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js @@ -21,6 +21,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { construct: function(resourceData) { this.base(arguments); + this.__widgets = []; this.__resourceData = resourceData; let latestPromise = null; @@ -107,21 +108,22 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { WIDTH: 830, HEIGHT: 700, - popUpInWindow: function(resourceDetails) { - // eslint-disable-next-line no-underscore-dangle - const title = resourceDetails.__resourceData.name; - const win = osparc.ui.window.Window.popUpInWindow(resourceDetails, title, this.WIDTH, this.HEIGHT).set({ + popUpInWindow: function(resourceData) { + const resourceDetails = new osparc.dashboard.ResourceDetails(resourceData); + const title = resourceData.name; + const window = osparc.ui.window.Window.popUpInWindow(resourceDetails, title, this.WIDTH, this.HEIGHT).set({ layout: new qx.ui.layout.Grow(), + ...osparc.ui.window.TabbedWindow.DEFAULT_PROPS, }); - win.set(osparc.ui.window.TabbedWindow.DEFAULT_PROPS); - win.set({ - width: this.WIDTH, - height: this.HEIGHT, + resourceDetails.addListener("closeWindow", () => window.close()); + window.addListener("close", () => { + // trigger children's destroy functions + resourceDetails.destroy(); }); - resourceDetails.addListener("closeWindow", () => { - win.close(); - }); - return win; + return { + resourceDetails, + window, + }; }, createToolbar: function() { @@ -147,6 +149,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { members: { __resourceData: null, __resourceModel: null, + __widgets: null, __infoPage: null, __servicesUpdatePage: null, __conversationsPage: null, @@ -379,42 +382,29 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { if (this.__resourceData["resourceType"] === "function") { // for now, we only want the preview page - const page = this.__getPreviewPage(); - if (page) { - tabsView.add(page); - } + this.__addPreviewPage(); this.fireEvent("pagesAdded"); return; } - // add Open service button - [ - this.__getInfoPage, - this.__getBillingPage, - this.__getServicesUpdatePage, - this.__getServicesBootOptionsPage, - this.__getConversationsPage, - this.__getPermissionsPage, - this.__getPublishPage, - this.__getCreateTemplatePage, - this.__getCreateFunctionsPage, - this.__getTagsPage, - this.__getQualityPage, - this.__getClassifiersPage, - this.__getPreviewPage - ].forEach(pageCallee => { - if (pageCallee) { - const page = pageCallee.call(this); - if (page) { - tabsView.add(page); - } - } - }); + this.__addInfoPage(); + this.__addBillingPage(); + this.__addServicesUpdatePage(); + this.__addServicesBootOptionsPage(); + this.__addConversationsPage(); + this.__addPermissionsPage(); + this.__addPublishPage(); + this.__addCreateTemplatePage(); + this.__addCreateFunctionsPage(); + this.__addTagsPage(); + this.__addQualityPage(); + this.__addClassifiersPage(); + this.__addPreviewPage(); if (osparc.product.Utils.showComputationalActivity()) { - this.__getActivityOverviewPopUp(); + this.__addActivityOverviewPopUp(); } - this.__getProjectFilesPopUp(); + this.__addProjectFilesPopUp(); if (selectedTabId) { const pageFound = tabsView.getChildren().find(page => page.tabId === selectedTabId); @@ -446,7 +436,12 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { } }, - __getInfoPage: function() { + __addPage: function(page) { + const tabsView = this.getChildControl("tabs-view"); + tabsView.add(page); + }, + + __addInfoPage: function() { const id = "Information"; const title = this.tr("Overview"); const iconSrc = "@FontAwesome5Solid/info/22"; @@ -475,15 +470,16 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { infoCard.addListener("openClassifiers", () => this.openClassifiers()); infoCard.addListener("openQuality", () => this.openQuality()); page.addToContent(infoCard); + this.__widgets.push(infoCard); } page.addListenerOnce("appear", lazyLoadContent, this); - return page; + this.__addPage(page); }, - __getBillingPage: function() { + __addBillingPage: function() { if (!osparc.desktop.credits.Utils.areWalletsEnabled()) { - return null; + return; } const resourceData = this.__resourceData; @@ -513,10 +509,11 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { }, this); const billingScroll = new qx.ui.container.Scroll(billingSettings); page.addToContent(billingScroll); + this.__widgets.push(billingSettings); } page.addListenerOnce("appear", lazyLoadContent, this); - return page; + this.__addPage(page); } else if (osparc.utils.Resources.isService(resourceData)) { const id = "Tiers"; const title = this.tr("Tiers"); @@ -528,15 +525,15 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { const pricingUnitsList = new osparc.service.PricingUnitsList(resourceData); const pricingUnitsListScroll = new qx.ui.container.Scroll(pricingUnitsList); page.addToContent(pricingUnitsListScroll); + this.__widgets.push(pricingUnitsList); } page.addListenerOnce("appear", lazyLoadContent, this); - return page; + this.__addPage(page); } - return null; }, - __getPreviewPage: function() { + __addPreviewPage: function() { const resourceData = this.__resourceData; if ( osparc.utils.Resources.isService(resourceData) || @@ -544,7 +541,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { ["app", "guided", "standalone"].includes(osparc.study.Utils.getUiMode(resourceData)) ) { // there is no pipelining or don't show it - return null; + return; } const id = "Pipeline"; @@ -561,16 +558,17 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { const resourceModel = this.__resourceModel; const preview = new osparc.study.StudyPreview(resourceModel); page.addToContent(preview); + this.__widgets.push(preview); } page.addListenerOnce("appear", lazyLoadContent, this); - return page; + this.__addPage(page); }, - __getConversationsPage: function() { + __addConversationsPage: function() { const resourceData = this.__resourceData; if (osparc.utils.Resources.isService(resourceData)) { - return null; + return; } const id = "Conversations"; @@ -582,13 +580,14 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { const lazyLoadContent = () => { const conversations = new osparc.study.Conversations(resourceData); page.addToContent(conversations); + this.__widgets.push(conversations); } page.addListenerOnce("appear", lazyLoadContent, this); - return page; + this.__addPage(page); }, - __getPermissionsPage: function() { + __addPermissionsPage: function() { const id = "Permissions"; const title = this.tr("Sharing"); const iconSrc = "@FontAwesome5Solid/share-alt/22"; @@ -619,19 +618,20 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { }, this); } page.addToContent(collaboratorsView); + this.__widgets.push(collaboratorsView); } page.addListenerOnce("appear", lazyLoadContent, this); - return page; + this.__addPage(page); }, - __getClassifiersPage: function() { + __addClassifiersPage: function() { if (!osparc.product.Utils.showClassifiers()) { - return null; + return; } const id = "Classifiers"; if (!osparc.data.Permissions.getInstance().canDo("study.classifier")) { - return null; + return; } const title = this.tr("Classifiers"); const iconSrc = "@FontAwesome5Solid/search/22"; @@ -654,15 +654,16 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { classifiers = new osparc.metadata.ClassifiersViewer(resourceData); } page.addToContent(classifiers); + this.__widgets.push(classifiers); } page.addListenerOnce("appear", lazyLoadContent, this); - return page; + this.__addPage(page); }, - __getQualityPage: function() { + __addQualityPage: function() { if (!osparc.product.Utils.showQuality()) { - return null; + return; } const resourceData = this.__resourceData; @@ -683,21 +684,21 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { this.__fireUpdateEvent(updatedData); }); page.addToContent(qualityEditor); + this.__widgets.push(qualityEditor); } page.addListenerOnce("appear", lazyLoadContent, this); - return page; + this.__addPage(page); } - return null; }, - __getTagsPage: function() { + __addTagsPage: function() { const resourceData = this.__resourceData; if (osparc.utils.Resources.isService(resourceData)) { - return null; + return; } if (!osparc.data.model.Study.canIWrite(resourceData["accessRights"])) { - return null; + return; } const id = "Tags"; @@ -714,16 +715,17 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { this.__fireUpdateEvent(resourceData, updatedData); }, this); page.addToContent(tagManager); + this.__widgets.push(tagManager); } page.addListenerOnce("appear", lazyLoadContent, this); - return page; + this.__addPage(page); }, - __getServicesUpdatePage: function() { + __addServicesUpdatePage: function() { const resourceData = this.__resourceData; if (osparc.utils.Resources.isService(resourceData)) { - return null; + return; } const id = "ServicesUpdate"; @@ -743,19 +745,20 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { this.__fireUpdateEvent(resourceData, updatedData); }); page.addToContent(servicesUpdate); + this.__widgets.push(servicesUpdate); } page.addListenerOnce("appear", lazyLoadContent, this); - return page; + this.__addPage(page); }, - __getServicesBootOptionsPage: function() { + __addServicesBootOptionsPage: function() { const resourceData = this.__resourceData; if ( osparc.utils.Resources.isService(resourceData) || !osparc.data.Permissions.getInstance().canDo("study.node.bootOptions.read") ) { - return null; + return; } const id = "ServicesBootOptions"; @@ -775,6 +778,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { this.__fireUpdateEvent(resourceData, updatedData); }); page.addToContent(servicesBootOpts); + this.__widgets.push(servicesBootOpts); if ( osparc.utils.Resources.isStudy(resourceData) || @@ -796,15 +800,15 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { } page.addListenerOnce("appear", lazyLoadContent, this); - return page; + this.__addPage(page); }, - __getPublishPage: function() { + __addPublishPage: function() { if ( !osparc.utils.Resources.isStudy(this.__resourceData) || !osparc.product.Utils.showPublicProjects() ) { - return null; + return; } const canIWrite = osparc.data.model.Study.canIWrite(this.__resourceData["accessRights"]); @@ -830,20 +834,20 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { toolbar.add(publishTemplateButton); page.addToHeader(toolbar); page.addToContent(saveAsTemplate); + this.__widgets.push(saveAsTemplate); } page.addListenerOnce("appear", lazyLoadContent, this); - return page; + this.__addPage(page); } - return null; }, - __getCreateTemplatePage: function() { + __addCreateTemplatePage: function() { if ( !osparc.utils.Resources.isStudy(this.__resourceData) || !osparc.product.Utils.showTemplates() ) { - return null; + return; } const canIWrite = osparc.data.model.Study.canIWrite(this.__resourceData["accessRights"]); @@ -869,25 +873,25 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { toolbar.add(createTemplateButton); page.addToHeader(toolbar); page.addToContent(saveAsTemplate); + this.__widgets.push(saveAsTemplate); } page.addListenerOnce("appear", lazyLoadContent, this); - return page; + this.__addPage(page); } - return null; }, - __getCreateFunctionsPage: function() { + __addCreateFunctionsPage: function() { if (!osparc.data.Permissions.getInstance().checkFunctionPermissions("writeFunctions")) { - return null; + return; } if (!osparc.utils.Resources.isStudy(this.__resourceData)) { - return null; + return; } if (!osparc.study.Utils.canCreateFunction(this.__resourceData["workbench"])) { - return null; + return; } const id = "CreateFunction"; @@ -901,10 +905,12 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { toolbar.add(createFunctionButton); page.addToHeader(toolbar); page.addToContent(createFunction); - return page; + this.__widgets.push(createFunction); + + this.__addPage(page); }, - __getProjectFilesPopUp: function() { + __addProjectFilesPopUp: function() { const resourceData = this.__resourceData; if (!osparc.utils.Resources.isService(resourceData)) { const title = osparc.product.Utils.resourceTypeToAlias(resourceData["resourceType"], {firstUpperCase: true}) + this.tr(" Files"); @@ -928,7 +934,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { } }, - __getActivityOverviewPopUp: function() { + __addActivityOverviewPopUp: function() { const resourceData = this.__resourceData; if (osparc.utils.Resources.isStudy(resourceData)) { const title = this.tr("Activity Overview..."); @@ -946,5 +952,11 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { this.addWidgetToTabs(dataAccess); } }, + + // overridden + destroy: function() { + this.__widgets.forEach(w => w.destroy()); + this.base(arguments); + }, } }); diff --git a/services/static-webserver/client/source/class/osparc/desktop/organizations/ServicesList.js b/services/static-webserver/client/source/class/osparc/desktop/organizations/ServicesList.js index 2265026c55a5..58b1bc96195f 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/organizations/ServicesList.js +++ b/services/static-webserver/client/source/class/osparc/desktop/organizations/ServicesList.js @@ -92,10 +92,12 @@ qx.Class.define("osparc.desktop.organizations.ServicesList", { .then(serviceData => { if (serviceData) { serviceData["resourceType"] = "service"; - const resourceDetails = new osparc.dashboard.ResourceDetails(serviceData).set({ + const { + resourceDetails, + } = osparc.dashboard.ResourceDetails.popUpInWindow(serviceData); + resourceDetails.set({ showOpenButton: false }); - osparc.dashboard.ResourceDetails.popUpInWindow(resourceDetails); } }); }); diff --git a/services/static-webserver/client/source/class/osparc/desktop/organizations/TutorialsList.js b/services/static-webserver/client/source/class/osparc/desktop/organizations/TutorialsList.js index 6636b4bd918e..c735aefe30a1 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/organizations/TutorialsList.js +++ b/services/static-webserver/client/source/class/osparc/desktop/organizations/TutorialsList.js @@ -90,10 +90,12 @@ qx.Class.define("osparc.desktop.organizations.TutorialsList", { .then(templateData => { if (templateData) { templateData["resourceType"] = "tutorial"; - const resourceDetails = new osparc.dashboard.ResourceDetails(templateData).set({ + const { + resourceDetails, + } = osparc.dashboard.ResourceDetails.popUpInWindow(templateData); + resourceDetails.set({ showOpenButton: false }); - osparc.dashboard.ResourceDetails.popUpInWindow(resourceDetails); } }); }); diff --git a/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js b/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js index 7cd46cbae751..6e5233ffa8b2 100644 --- a/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js +++ b/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js @@ -332,11 +332,14 @@ qx.Class.define("osparc.notification.NotificationUI", { if (studyData) { const studyDataCopy = osparc.data.model.Study.deepCloneStudyObject(studyData); studyDataCopy["resourceType"] = notification.getCategory() === "TEMPLATE_SHARED" ? "template" : "study"; - const resourceDetails = new osparc.dashboard.ResourceDetails(studyDataCopy); - const win = osparc.dashboard.ResourceDetails.popUpInWindow(resourceDetails); + const { + resourceDetails, + window, + } = osparc.dashboard.ResourceDetails.popUpInWindow(studyDataCopy); + resourceDetails.addListener("openStudy", () => { if (notification.getCategory() === "STUDY_SHARED") { - const openCB = () => win.close(); + const openCB = () => window.close(); osparc.dashboard.ResourceBrowserBase.startStudyById(studyId, openCB); } }); diff --git a/services/static-webserver/client/source/class/osparc/share/ShareePermissions.js b/services/static-webserver/client/source/class/osparc/share/ShareePermissions.js index 2a2a2bf9909a..cd516e76833f 100644 --- a/services/static-webserver/client/source/class/osparc/share/ShareePermissions.js +++ b/services/static-webserver/client/source/class/osparc/share/ShareePermissions.js @@ -90,12 +90,11 @@ qx.Class.define("osparc.share.ShareePermissions", { hBox.add(infoButton); hBox.add(label); osparc.store.Services.getService(inaccessibleService.key, inaccessibleService.version) - .then(metadata => { - label.setValue(metadata["name"] + " : " + metadata["version"]) + .then(serviceMetadata => { + label.setValue(serviceMetadata["name"] + " : " + serviceMetadata["version"]) infoButton.addListener("execute", () => { - metadata["resourceType"] = "service"; - const resourceDetails = new osparc.dashboard.ResourceDetails(metadata); - osparc.dashboard.ResourceDetails.popUpInWindow(resourceDetails); + serviceMetadata["resourceType"] = "service"; + osparc.dashboard.ResourceDetails.popUpInWindow(serviceMetadata); }, this); }) diff --git a/services/static-webserver/client/source/class/osparc/study/Conversations.js b/services/static-webserver/client/source/class/osparc/study/Conversations.js index 7d8a5800796d..0839624779e0 100644 --- a/services/static-webserver/client/source/class/osparc/study/Conversations.js +++ b/services/static-webserver/client/source/class/osparc/study/Conversations.js @@ -20,7 +20,7 @@ qx.Class.define("osparc.study.Conversations", { extend: qx.ui.core.Widget, /** - * @param studyData {String} Study Data + * @param studyData {Object} Study Data */ construct: function(studyData) { this.base(arguments); @@ -29,11 +29,22 @@ qx.Class.define("osparc.study.Conversations", { this.__conversations = []; - this.fetchConversations(studyData); + this.set({ + studyData, + }); this.__listenToConversationWS(); }, + properties: { + studyData: { + check: "Object", + init: null, + nullable: false, + apply: "__applyStudyData", + }, + }, + statics: { popUpInWindow: function(studyData) { const conversations = new osparc.study.Conversations(studyData); @@ -41,6 +52,9 @@ qx.Class.define("osparc.study.Conversations", { const viewWidth = 600; const viewHeight = 700; const win = osparc.ui.window.Window.popUpInWindow(conversations, title, viewWidth, viewHeight); + win.addListener("close", () => { + conversations.destroy(); + }, this); return win; }, @@ -143,6 +157,7 @@ qx.Class.define("osparc.study.Conversations", { members: { __conversations: null, + __newConversationButton: null, __wsHandlers: null, _createChildControlImpl: function(id) { @@ -167,6 +182,31 @@ qx.Class.define("osparc.study.Conversations", { this.__wsHandlers = []; const socket = osparc.wrapper.WebSocket.getInstance(); + + [ + "conversation:created", + "conversation:updated", + "conversation:deleted", + ].forEach(eventName => { + const eventHandler = conversation => { + if (conversation) { + switch (eventName) { + case "conversation:created": + this.__addConversationPage(conversation); + break; + case "conversation:updated": + this.__updateConversationName(conversation); + break; + case "conversation:deleted": + this.__removeConversationPage(conversation); + break; + } + } + }; + socket.on(eventName, eventHandler, this); + this.__wsHandlers.push({ eventName, handler: eventHandler }); + }); + [ "conversation:message:created", "conversation:message:updated", @@ -200,7 +240,7 @@ qx.Class.define("osparc.study.Conversations", { return this.__conversations.find(conversation => conversation.getConversationId() === conversationId); }, - fetchConversations: function(studyData) { + __applyStudyData: function(studyData) { const loadMoreButton = this.getChildControl("loading-button"); loadMoreButton.setFetching(true); @@ -212,67 +252,126 @@ qx.Class.define("osparc.study.Conversations", { } }; osparc.data.Resources.fetch("conversations", "getConversationsPage", params) - .then(conversations => this.__addConversations(conversations, studyData)) + .then(conversations => { + if (conversations.length) { + conversations.forEach(conversation => this.__addConversationPage(conversation)); + } else { + this.__addTempConversationPage(); + } + }) .finally(() => { loadMoreButton.setFetching(false); loadMoreButton.exclude(); }); }, - __addConversations: function(conversations, studyData) { - const conversationPages = []; - const conversationsLayout = this.getChildControl("conversations-layout"); + __createConversationPage: function(conversationData) { + const studyData = this.getStudyData(); + let conversationPage = null; + if (conversationData) { + const conversationId = conversationData["conversationId"]; + conversationPage = new osparc.conversation.Conversation(studyData, conversationId); + conversationPage.setLabel(conversationData["name"]); + conversationPage.addListener("conversationDeleted", () => this.__removeConversationPage(conversationData, true)); + } else { + // create a temporary conversation + conversationPage = new osparc.conversation.Conversation(studyData); + conversationPage.setLabel(this.tr("new")); + } + return conversationPage; + }, - const newConversationButton = new qx.ui.form.Button().set({ - icon: "@FontAwesome5Solid/plus/12", - toolTipText: this.tr("Add new conversation"), - allowGrowX: false, - backgroundColor: "transparent", - }); + __addTempConversationPage: function() { + const temporaryConversationPage = this.__createConversationPage(); + this.__addToPages(temporaryConversationPage); + }, - const reloadConversations = () => { - conversationPages.forEach(conversationPage => conversationPage.fireDataEvent("close", conversationPage)); - conversationsLayout.getChildControl("bar").remove(newConversationButton); - this.fetchConversations(studyData); - }; + __addConversationPage: function(conversationData) { + // ignore it if it was already there + const conversationId = conversationData["conversationId"]; + const conversation = this.__getConversation(conversationId); + if (conversation) { + return null; + } - this.__conversations = []; - if (conversations.length === 0) { - const noConversationTab = new osparc.conversation.Conversation(studyData); - conversationPages.push(noConversationTab); - noConversationTab.setLabel(this.tr("new")); - noConversationTab.addListener("conversationDeleted", () => reloadConversations()); - conversationsLayout.add(noConversationTab); - } else { - conversations.forEach(conversationData => { - const conversationId = conversationData["conversationId"]; - const conversation = new osparc.conversation.Conversation(studyData, conversationId); - this.__conversations.push(conversation); - conversationPages.push(conversation); - conversation.setLabel(conversationData["name"]); - conversation.addListener("conversationDeleted", () => reloadConversations()); - conversationsLayout.add(conversation); + const conversationPage = this.__createConversationPage(conversationData); + this.__addToPages(conversationPage); + + this.__conversations.push(conversationPage); + + return conversationPage; + }, + + __addToPages: function(conversationPage) { + const conversationsLayout = this.getChildControl("conversations-layout"); + conversationsLayout.add(conversationPage); + + if (this.__newConversationButton === null) { + // initialize the new button only once + const newConversationButton = this.__newConversationButton = new qx.ui.form.Button().set({ + icon: "@FontAwesome5Solid/plus/12", + toolTipText: this.tr("Add new conversation"), + allowGrowX: false, + backgroundColor: "transparent", }); + newConversationButton.addListener("execute", () => { + const studyData = this.getStudyData(); + osparc.study.Conversations.addConversation(studyData["uuid"], "new " + (this.__conversations.length + 1)) + .then(conversationDt => { + this.__addConversationPage(conversationDt); + const newConversationPage = this.__getConversation(conversationDt["conversationId"]); + if (newConversationPage) { + conversationsLayout.setSelection([newConversationPage]); + } + }); + }); + conversationsLayout.getChildControl("bar").add(newConversationButton); } + // remove and add to move to last position + conversationsLayout.getChildControl("bar").remove(this.__newConversationButton); + conversationsLayout.getChildControl("bar").add(this.__newConversationButton); + }, - newConversationButton.addListener("execute", () => { - osparc.study.Conversations.addConversation(studyData["uuid"], "new " + (conversations.length + 1)) - .then(() => { - reloadConversations(); - }); - }); + __removeConversationPage: function(conversationData, changeSelection = false) { + const conversationId = conversationData["conversationId"]; + const conversation = this.__getConversation(conversationId); + if (conversation) { + const conversationsLayout = this.getChildControl("conversations-layout"); + conversationsLayout.remove(conversation); + this.__conversations = this.__conversations.filter(c => c !== conversation); + const conversationPages = conversationsLayout.getSelectables(); + if (conversationPages.length) { + if (changeSelection) { + // change selection to the first conversation + conversationsLayout.setSelection([conversationPages[0]]); + } + } else { + // no conversations left, add a temporary one + this.__addTempConversationPage(); + } + } + }, - conversationsLayout.getChildControl("bar").add(newConversationButton); + // it can only be renamed, not updated + __updateConversationName: function(conversationData) { + const conversationId = conversationData["conversationId"]; + const conversation = this.__getConversation(conversationId); + if (conversation) { + conversation.renameConversation(conversationData["name"]); + } }, - }, - destruct: function() { - const socket = osparc.wrapper.WebSocket.getInstance(); - if (this.__wsHandlers) { - this.__wsHandlers.forEach(({ eventName }) => { - socket.removeSlot(eventName); - }); - this.__wsHandlers = null; - } + // overridden + destroy: function() { + const socket = osparc.wrapper.WebSocket.getInstance(); + if (this.__wsHandlers) { + this.__wsHandlers.forEach(({ eventName }) => { + socket.removeSlot(eventName); + }); + this.__wsHandlers = null; + } + + this.base(arguments); + }, }, }); diff --git a/services/static-webserver/client/source/class/osparc/ui/window/Window.js b/services/static-webserver/client/source/class/osparc/ui/window/Window.js index c8f8c304d308..8f8cf31aa719 100644 --- a/services/static-webserver/client/source/class/osparc/ui/window/Window.js +++ b/services/static-webserver/client/source/class/osparc/ui/window/Window.js @@ -73,8 +73,8 @@ qx.Class.define("osparc.ui.window.Window", { showMinimize: false, showMaximize: false, resizable: true, - width: width, - minHeight: minHeight, + width, + minHeight, maxHeight: Math.max(minHeight, document.documentElement.clientHeight), modal: true, clickAwayClose: true diff --git a/services/static-webserver/client/source/class/osparc/widget/PersistentIframe.js b/services/static-webserver/client/source/class/osparc/widget/PersistentIframe.js index b4293f56ca1a..81f4d9bb7ec7 100644 --- a/services/static-webserver/client/source/class/osparc/widget/PersistentIframe.js +++ b/services/static-webserver/client/source/class/osparc/widget/PersistentIframe.js @@ -338,11 +338,14 @@ qx.Class.define("osparc.widget.PersistentIframe", { "uuid": templateId, "resourceType": "function", }; - const resourceDetails = new osparc.dashboard.ResourceDetails(functionData).set({ + const { + resourceDetails, + window, + } = osparc.dashboard.ResourceDetails.popUpInWindow(functionData); + resourceDetails.set({ showOpenButton: false, }); - const win = osparc.dashboard.ResourceDetails.popUpInWindow(resourceDetails); - win.setCaption("Function Details"); + window.setCaption("Function Details"); } break; }