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 bd718b59ddf2..a8b5967cfeea 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js @@ -121,14 +121,20 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", { const walletsEnabled = osparc.desktop.credits.Utils.areWalletsEnabled(); if (walletsEnabled) { - osparc.store.Study.getInstance().getWallet(studyId) - .then(wallet => { + Promise.all([ + osparc.store.Study.getInstance().getWallet(studyId), + osparc.store.Study.getInstance().getOne(studyId), + ]).then(([wallet, latestStudyData]) => { + const currentUserGroupIds = osparc.study.Utils.state.getCurrentGroupIds(latestStudyData["state"]); if ( isStudyCreation || wallet === null || - osparc.desktop.credits.Utils.getWallet(wallet["walletId"]) === null + (osparc.desktop.credits.Utils.getWallet(wallet["walletId"]) === null && currentUserGroupIds.length === 0) ) { - // pop up study options if the study was just created or if it has no wallet assigned or user has no access to it + // pop up StudyOptions if: + // - the study was just created + // - it has no wallet assigned + // - I do not have access to it and the project is not being used const resourceSelector = new osparc.study.StudyOptions(studyId); if (isStudyCreation) { resourceSelector.getChildControl("open-button").setLabel(qx.locale.Manager.tr("New")); @@ -157,7 +163,28 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", { } }); } else { - openStudy(); + const found = osparc.store.Store.getInstance().getWallets().find(w => w.getWalletId() === wallet["walletId"]); + if (found) { + // I have access to the wallet + if (osparc.store.Store.getInstance().getContextWallet() !== found) { + // switch to that wallet and inform the user that the context wallet has changed + const text = qx.locale.Manager.tr("Switched to Credit Account") + " '" + found.getName() + "'"; + osparc.FlashMessenger.logAs(text); + } + osparc.store.Store.getInstance().setActiveWallet(found); + openStudy(); + } else { + // I do not have access to the wallet or it's being used + // cancel and explain the user why + const isRTCEnabled = osparc.utils.DisabledPlugins.isRTCEnabled(); + const msg = isRTCEnabled ? + qx.locale.Manager.tr("You can't join the project because you don't have access to the Credit Account associated with it. Please contact the project owner.") : + qx.locale.Manager.tr("You can't join the project because it's already open by another user."); + osparc.FlashMessenger.logAs(msg, "ERROR"); + if (cancelCB) { + cancelCB(); + } + } } }); } else { @@ -196,7 +223,22 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", { osparc.utils.Utils.addBorderRightRadius(rButton); } return rButton; - } + }, + + getOpenText: function(resourceData) { + const studyAlias = osparc.product.Utils.getStudyAlias({firstUpperCase: true}); + let openText = qx.locale.Manager.tr("New") + " " + studyAlias; + if (resourceData["resourceType"] === "study") { + // if it's in use call it join + const isRTCEnabled = osparc.utils.DisabledPlugins.isRTCEnabled(); + if (osparc.study.Utils.state.getCurrentGroupIds(resourceData["state"]).length && isRTCEnabled) { + openText = qx.locale.Manager.tr("Join"); + } else { + openText = qx.locale.Manager.tr("Open"); + } + } + return openText; + }, }, members: { @@ -899,8 +941,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", { }, _getOpenMenuButton: function(resourceData) { - const studyAlias = osparc.product.Utils.getStudyAlias({firstUpperCase: true}); - const openText = (resourceData["resourceType"] === "study") ? this.tr("Open") : this.tr("New") + " " + studyAlias; + const openText = osparc.dashboard.ResourceBrowserBase.getOpenText(resourceData); const openButton = new qx.ui.menu.Button(openText); openButton["openResourceButton"] = true; openButton.addListener("execute", () => { 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 f4f1e8fc2e07..bd95c4276b4e 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js @@ -157,7 +157,14 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { maxHeight: 40 }); return toolbar; - } + }, + + disableIfInUse: function(resourceData, widget) { + if (resourceData["resourceType"] === "study") { + // disable if it's being used + widget.setEnabled(!osparc.study.Utils.state.getCurrentGroupIds(resourceData["state"]).length); + } + }, }, properties: { @@ -225,8 +232,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { toolbar.add(serviceVersionSelector); } - const studyAlias = osparc.product.Utils.getStudyAlias({firstUpperCase: true}); - const openText = (this.__resourceData["resourceType"] === "study") ? this.tr("Open") : this.tr("New") + " " + studyAlias; + const openText = osparc.dashboard.ResourceBrowserBase.getOpenText(this.__resourceData); const openButton = new osparc.ui.form.FetchButton(openText).set({ enabled: true }); @@ -536,6 +542,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { const lazyLoadContent = () => { const billingSettings = new osparc.study.BillingSettings(resourceData); + this.self().disableIfInUse(resourceData, billingSettings); billingSettings.addListener("debtPayed", () => { page.payDebtButton.set({ visibility: osparc.study.Utils.isInDebt(resourceData) ? "visible" : "excluded" @@ -785,6 +792,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { const lazyLoadContent = () => { const servicesUpdate = new osparc.metadata.ServicesInStudyUpdate(resourceData); + this.self().disableIfInUse(resourceData, servicesUpdate); servicesUpdate.addListener("updateService", e => { const updatedData = e.getData(); this.__fireUpdateEvent(resourceData, updatedData); @@ -818,6 +826,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { const lazyLoadContent = () => { const servicesBootOpts = new osparc.metadata.ServicesInStudyBootOpts(resourceData); + this.self().disableIfInUse(resourceData, servicesBootOpts); servicesBootOpts.addListener("updateService", e => { const updatedData = e.getData(); this.__fireUpdateEvent(resourceData, updatedData); diff --git a/services/static-webserver/client/source/class/osparc/desktop/wallets/WalletListItem.js b/services/static-webserver/client/source/class/osparc/desktop/wallets/WalletListItem.js index 5fdf8fe6c2bf..fc6750140763 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/wallets/WalletListItem.js +++ b/services/static-webserver/client/source/class/osparc/desktop/wallets/WalletListItem.js @@ -153,7 +153,7 @@ qx.Class.define("osparc.desktop.wallets.WalletListItem", { rowSpan: 2 }); break; - case "favourite-button": + case "preferred-button": control = new qx.ui.form.Button().set({ iconPosition: "right", width: 110, // make Primary and Secondary buttons same width @@ -326,8 +326,11 @@ qx.Class.define("osparc.desktop.wallets.WalletListItem", { }, __applyPreferredWallet: function(isPreferredWallet) { - const favouriteButton = this.getChildControl("favourite-button"); - favouriteButton.setBackgroundColor("transparent"); + const favouriteButton = this.getChildControl("preferred-button"); + favouriteButton.set({ + backgroundColor: "transparent", + width: 60, + }); const favouriteButtonIcon = favouriteButton.getChildControl("icon"); if (isPreferredWallet) { favouriteButton.set({ diff --git a/services/static-webserver/client/source/class/osparc/desktop/wallets/WalletsList.js b/services/static-webserver/client/source/class/osparc/desktop/wallets/WalletsList.js index 5ed1afa1372f..57c069388d79 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/wallets/WalletsList.js +++ b/services/static-webserver/client/source/class/osparc/desktop/wallets/WalletsList.js @@ -229,8 +229,8 @@ qx.Class.define("osparc.desktop.wallets.WalletsList", { flex: 1 }); if (showCurrently) { - const selectColumn = new qx.ui.basic.Label(this.tr("Currently in use")).set({ - marginRight: 18 + const selectColumn = new qx.ui.basic.Label(this.tr("Preferred")).set({ + marginRight: 8 // align it with the "preferred-button" }); header.add(selectColumn) } diff --git a/services/static-webserver/client/source/class/osparc/study/Utils.js b/services/static-webserver/client/source/class/osparc/study/Utils.js index 800becc4380f..e61810cf0d40 100644 --- a/services/static-webserver/client/source/class/osparc/study/Utils.js +++ b/services/static-webserver/client/source/class/osparc/study/Utils.js @@ -375,37 +375,34 @@ qx.Class.define("osparc.study.Utils", { }, state: { + __getShareState: function(state) { + if (state && "shareState" in state) { + return state["shareState"]; + } + return null; + }, + getProjectStatus: function(state) { - if ( - state && - "shareState" in state && - "status" in state["shareState"] - ) { - return state["shareState"]["status"]; + const shareState = this.__getShareState(state); + if (shareState && "status" in shareState) { + return shareState["status"]; } return null; }, isProjectLocked: function(state) { - if ( - state && - "shareState" in state && - "locked" in state["shareState"] - ) { - return state["shareState"]["locked"]; + const shareState = this.__getShareState(state); + if (shareState && "locked" in shareState) { + return shareState["locked"]; } return false; }, getCurrentGroupIds: function(state) { - if ( - state && - "shareState" in state && - "currentUserGroupids" in state["shareState"] - ) { - return state["shareState"]["currentUserGroupids"]; + const shareState = this.__getShareState(state); + if (shareState && "currentUserGroupids" in shareState) { + return shareState["currentUserGroupids"]; } - return []; }, @@ -449,7 +446,7 @@ qx.Class.define("osparc.study.Utils", { return "UNKNOWN_SERVICES"; } } - if (studyData["state"] && studyData["state"]["shareState"] && studyData["state"]["shareState"]["locked"]) { + if (this.state.isProjectLocked(studyData["state"])) { return "IN_USE"; } if (this.isInDebt(studyData)) {