diff --git a/services/static-webserver/client/source/class/osparc/MaintenanceTracker.js b/services/static-webserver/client/source/class/osparc/MaintenanceTracker.js index 0274270e2ea..d6aa69a3084 100644 --- a/services/static-webserver/client/source/class/osparc/MaintenanceTracker.js +++ b/services/static-webserver/client/source/class/osparc/MaintenanceTracker.js @@ -41,8 +41,8 @@ qx.Class.define("osparc.MaintenanceTracker", { statics: { CHECK_INTERVAL: 15*60*1000, // Check every 15' - CLOSABLE_WARN_IN_ADVANCE: 24*60*60*1000, // Show Ribbon Closable Message 24h in advance - PERMANENT_WARN_IN_ADVANCE: 30*60*1000 // Show Ribbon Permanent Message 30' in advance + CLOSABLE_WARN_IN_ADVANCE: 48*60*60*1000, // Show Closable Ribbon Message 48h in advance + PERMANENT_WARN_IN_ADVANCE: 60*60*1000 // Show Permanent Ribbon Message 60' in advance }, members: { 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 6d5932f0007..9b5e902c281 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js @@ -349,7 +349,7 @@ qx.Class.define("osparc.dashboard.CardBase", { state: { check: "Object", nullable: false, - apply: "_applyState" + apply: "__applyState" }, projectState: { @@ -359,11 +359,11 @@ qx.Class.define("osparc.dashboard.CardBase", { apply: "_applyProjectState" }, - locked: { - check: "Boolean", + blocked: { + check: [true, "UNKNOWN_SERVICES", "IN_USE", false], init: false, nullable: false, - apply: "_applyLocked" + apply: "__applyBlocked" }, menu: { @@ -515,7 +515,6 @@ qx.Class.define("osparc.dashboard.CardBase", { uiModeIcon.set({ source, toolTipText, - alignY: "bottom" }); } }, @@ -552,7 +551,7 @@ qx.Class.define("osparc.dashboard.CardBase", { // Block card const unaccessibleServices = osparc.study.Utils.getInaccessibleServices(workbench) if (unaccessibleServices.length) { - this.__enableCard(false); + this.setBlocked("UNKNOWN_SERVICES"); const image = "@FontAwesome5Solid/ban/"; let toolTipText = this.tr("Service info missing"); unaccessibleServices.forEach(unSrv => { @@ -600,16 +599,17 @@ qx.Class.define("osparc.dashboard.CardBase", { } }, - _applyState: function(state) { + __applyState: function(state) { const locked = ("locked" in state) ? state["locked"]["value"] : false; - const projectState = ("state" in state) ? state["state"]["value"] : undefined; + this.setBlocked(locked ? "IN_USE" : false); if (locked) { this.__showBlockedCardFromStatus(state["locked"]); } + + const projectState = ("state" in state) ? state["state"]["value"] : undefined; if (projectState) { this._applyProjectState(state["state"]); } - this.setLocked(locked); }, _applyProjectState: function(projectStatus) { @@ -722,46 +722,70 @@ qx.Class.define("osparc.dashboard.CardBase", { } }, - _applyLocked: function(locked) { - this.__enableCard(!locked); + __applyBlocked: function(blocked) { + const enabled = !blocked; + if (enabled) { + this.resetToolTipText(); + } + + this._getChildren().forEach(item => { + if (item) { + item.setOpacity(enabled ? 1.0 : 0.7); + } + }); + this.getChildControl("lock-status").set({ appearance: "form-button-outlined/disabled", textColor: "text-disabled", opacity: 1.0, - visibility: locked ? "visible" : "excluded" + visibility: enabled ? "excluded" : "visible" }); + // let the "pointer" cursor for IN_USE or UNKNOWN_SERVICE this.set({ - cursor: locked ? "not-allowed" : "pointer" + cursor: blocked === true ? "not-allowed" : "pointer" }); [ "tick-selected", "tick-unselected", - "menu-button" + // "menu-button" ].forEach(childName => { const child = this.getChildControl(childName); - child.set({ - enabled: !locked - }); + child.setEnabled(enabled); }); + + this.evaluateMenuButtons(); }, - __enableCard: function(enabled) { - if (enabled) { - this.resetToolTipText(); - } + evaluateMenuButtons: function() { + if (this.getMenu()) { + const menuButtons = this.getMenu().getChildren(); + const resourceData = this.getResourceData(); - this._getChildren().forEach(item => { - if (item) { - item.setOpacity(enabled ? 1.0 : 0.7); - } - }); - - if (this.getMenu() && this.getMenu().getChildren()) { - const openButton = this.getMenu().getChildren().find(menuBtn => "openResource" in menuBtn); + const openButton = menuButtons.find(menuBtn => "openResourceButton" in menuBtn); if (openButton) { - openButton.setEnabled(enabled); + openButton.setEnabled(osparc.study.Utils.canBeOpened(resourceData)); + } + const duplicateButton = menuButtons.find(menuBtn => "duplicateButton" in menuBtn); + if (duplicateButton) { + duplicateButton.setEnabled(osparc.study.Utils.canBeDuplicated(resourceData)); + } + const exportCMISButton = menuButtons.find(menuBtn => "exportCMISButton" in menuBtn); + if (exportCMISButton) { + exportCMISButton.setEnabled(osparc.study.Utils.canBeExported(resourceData)); + } + const studyDataButton = menuButtons.find(menuBtn => "studyDataButton" in menuBtn); + if (studyDataButton) { + studyDataButton.setEnabled(osparc.study.Utils.canShowStudyData(resourceData)); + } + const moveToFolderButton = menuButtons.find(menuBtn => "moveToFolderButton" in menuBtn); + if (moveToFolderButton) { + moveToFolderButton.setEnabled(osparc.study.Utils.canMoveToFolder(resourceData)); + } + const deleteButton = menuButtons.find(menuBtn => "deleteButton" in menuBtn); + if (deleteButton) { + deleteButton.setEnabled(osparc.study.Utils.canBeDeleted(resourceData)); } } }, diff --git a/services/static-webserver/client/source/class/osparc/dashboard/GridButtonItem.js b/services/static-webserver/client/source/class/osparc/dashboard/GridButtonItem.js index 2705b7c126c..6e3856a20c4 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/GridButtonItem.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/GridButtonItem.js @@ -187,7 +187,8 @@ qx.Class.define("osparc.dashboard.GridButtonItem", { }, __itemSelected: function() { - if (this.isLocked()) { + // It could be blocked by IN_USE or UNKNOWN_SERVICE + if (this.getBlocked() === true) { this.setValue(false); return; } @@ -279,6 +280,7 @@ qx.Class.define("osparc.dashboard.GridButtonItem", { menu.setPosition("top-left"); osparc.utils.Utils.prettifyMenu(menu); osparc.utils.Utils.setIdToWidget(menu, "studyItemMenuMenu"); + this.evaluateMenuButtons(); } menuButton.setVisibility(menu ? "visible" : "excluded"); } diff --git a/services/static-webserver/client/source/class/osparc/dashboard/GridButtonPlaceholder.js b/services/static-webserver/client/source/class/osparc/dashboard/GridButtonPlaceholder.js index 89a055b1217..89f9c94270a 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/GridButtonPlaceholder.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/GridButtonPlaceholder.js @@ -118,7 +118,7 @@ qx.Class.define("osparc.dashboard.GridButtonPlaceholder", { }); }, - isLocked: function() { + getBlocked: function() { return true; }, diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ListButtonBase.js b/services/static-webserver/client/source/class/osparc/dashboard/ListButtonBase.js index d390efbf9c8..9ca55ac44cd 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ListButtonBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ListButtonBase.js @@ -49,9 +49,9 @@ qx.Class.define("osparc.dashboard.ListButtonBase", { TITLE: 2, PROGRESS: 3, DESCRIPTION: 4, - UPDATES: 5, - UI_MODE: 6, - TAGS: 7, + TAGS: 5, + UPDATES: 6, + UI_MODE: 7, STATUS: 8, PERMISSION: 9, TSR: 10, diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ListButtonItem.js b/services/static-webserver/client/source/class/osparc/dashboard/ListButtonItem.js index 11e5e4457d5..875fbc71dec 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ListButtonItem.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ListButtonItem.js @@ -273,16 +273,20 @@ qx.Class.define("osparc.dashboard.ListButtonItem", { }, __itemSelected: function() { + // It could be blocked by IN_USE or UNKNOWN_SERVICE + if (this.getBlocked() === true) { + this.setValue(false); + return; + } + if (this.isResourceType("study") && this.isMultiSelectionMode()) { const selected = this.getValue(); - if (this.isLocked() && selected) { - this.setValue(false); - } - const tick = this.getChildControl("tick-selected"); + tick.setVisibility(selected ? "visible" : "excluded"); + const untick = this.getChildControl("tick-unselected"); - this.getChildControl("menu-selection-stack").setSelection([selected ? tick : untick]); + untick.setVisibility(selected ? "excluded" : "visible"); } else { this.__showMenuOnly(); } diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ListButtonPlaceholder.js b/services/static-webserver/client/source/class/osparc/dashboard/ListButtonPlaceholder.js index e52b765cc49..7074ded3194 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ListButtonPlaceholder.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ListButtonPlaceholder.js @@ -104,7 +104,7 @@ qx.Class.define("osparc.dashboard.ListButtonPlaceholder", { }); }, - isLocked: function() { + getBlocked: function() { return true; }, 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 d1219cec8e8..95986f1e293 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceBrowserBase.js @@ -462,7 +462,7 @@ qx.Class.define("osparc.dashboard.ResourceBrowserBase", { _getOpenMenuButton: function(resourceData) { const openButton = new qx.ui.menu.Button(this.tr("Open")); - openButton.openResource = true; + openButton["openResourceButton"] = true; openButton.addListener("execute", () => { switch (resourceData["resourceType"]) { case "study": { 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 2d645c68451..9f3e14a0937 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js @@ -82,13 +82,14 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { members: { __resourceData: null, __resourceModel: null, + __infoPage: null, __dataPage: null, + __servicesUpdatePage: null, __permissionsPage: null, __tagsPage: null, __billingSettings: null, __classifiersPage: null, __qualityPage: null, - __servicesUpdatePage: null, __openButton: null, __createToolbar: function() { @@ -127,6 +128,12 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { openButton.addListener("execute", () => this.__openTapped()); + if (this.__resourceData["resourceType"] === "study") { + const studyData = this.__resourceData; + const canBeOpened = osparc.study.Utils.canBeOpened(studyData); + openButton.setEnabled(canBeOpened); + } + toolbar.add(openButton); }, @@ -175,7 +182,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { win.open(); win.addListenerOnce("close", () => { if (win.getConfirmed()) { - this._openPage(this.__servicesUpdatePage); + this.openUpdateServices(); } else { this.__openResource(); } @@ -196,10 +203,18 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { } }, + __openInfo: function() { + this._openPage(this.__infoPage); + }, + openData: function() { this._openPage(this.__dataPage); }, + openUpdateServices: function() { + this._openPage(this.__servicesUpdatePage); + }, + openAccessRights: function() { this._openPage(this.__permissionsPage); }, @@ -220,10 +235,6 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { this._openPage(this.__billingSettings); }, - openUpdateServices: function() { - this._openPage(this.__servicesUpdatePage); - }, - __createServiceVersionSelector: function() { const hBox = new qx.ui.container.Composite(new qx.ui.layout.HBox().set({ alignY: "middle" @@ -314,7 +325,7 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { const id = "Information"; const title = this.tr("Overview"); const iconSrc = "@FontAwesome5Solid/info/22"; - const page = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id); + const page = this.__infoPage = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id); this.__addOpenButton(page); const lazyLoadContent = () => { @@ -364,6 +375,12 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { const page = this.__billingSettings = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id); this.__addOpenButton(page); + if (this.__resourceData["resourceType"] === "study") { + const studyData = this.__resourceData; + const canBeOpened = osparc.study.Utils.canShowBillingOptions(studyData); + page.setEnabled(canBeOpened); + } + const lazyLoadContent = () => { const billingSettings = new osparc.study.BillingSettings(resourceData); const billingScroll = new qx.ui.container.Scroll(billingSettings); @@ -408,6 +425,12 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { const page = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id); this.__addOpenButton(page); + if (this.__resourceData["resourceType"] === "study") { + const studyData = this.__resourceData; + const canBeOpened = osparc.study.Utils.canShowPreview(studyData); + page.setEnabled(canBeOpened); + } + const lazyLoadContent = () => { const resourceModel = this.__resourceModel; const preview = new osparc.study.StudyPreview(resourceModel); @@ -457,6 +480,12 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { const page = this.__dataPage = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id); this.__addOpenButton(page); + if (this.__resourceData["resourceType"] === "study") { + const studyData = this.__resourceData; + const canBeOpened = osparc.study.Utils.canShowStudyData(studyData); + page.setEnabled(canBeOpened); + } + const lazyLoadContent = () => { const studyDataManager = new osparc.widget.NodeDataManager(resourceData["uuid"]); page.addToContent(studyDataManager); @@ -624,6 +653,12 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { const page = this.__servicesUpdatePage = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id); this.__addOpenButton(page); + if (this.__resourceData["resourceType"] === "study") { + const studyData = this.__resourceData; + const canBeOpened = osparc.study.Utils.canShowServiceUpdates(studyData); + page.setEnabled(canBeOpened); + } + const lazyLoadContent = () => { const servicesUpdate = new osparc.metadata.ServicesInStudyUpdate(resourceData); servicesUpdate.addListener("updateService", e => { @@ -653,6 +688,12 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { const page = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id); this.__addOpenButton(page); + if (this.__resourceData["resourceType"] === "study") { + const studyData = this.__resourceData; + const canBeOpened = osparc.study.Utils.canShowServiceBootOptions(studyData); + page.setEnabled(canBeOpened); + } + const lazyLoadContent = () => { const servicesBootOpts = new osparc.metadata.ServicesInStudyBootOpts(resourceData); servicesBootOpts.addListener("updateService", e => { @@ -696,6 +737,12 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { const title = this.tr("Publish ") + osparc.product.Utils.getTemplateAlias({firstUpperCase: true}); const page = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id); + if (this.__resourceData["resourceType"] === "study") { + const studyData = this.__resourceData; + const canBeOpened = osparc.study.Utils.canBeDuplicated(studyData); + page.setEnabled(canBeOpened); + } + const lazyLoadContent = () => { const saveAsTemplate = new osparc.study.SaveAsTemplate(this.__resourceData); saveAsTemplate.addListener("publishTemplate", e => this.fireDataEvent("publishTemplate", e.getData())); diff --git a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js index a5904fda2a6..2e174d99229 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js @@ -420,7 +420,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { cards.forEach(card => { card.setMultiSelectionMode(this.getMultiSelection()); card.addListener("tap", e => { - if (card.isLocked()) { + if (card.getBlocked() === true) { card.setValue(false); } else { this.__itemClicked(card, e.getNativeEvent().shiftKey); @@ -1075,6 +1075,8 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { menu.add(deleteButton); } } + + card.evaluateMenuButtons(); }, __getRenameStudyMenuButton: function(studyData) { @@ -1136,6 +1138,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { __getStudyDataMenuButton: function(card) { const text = osparc.utils.Utils.capitalize(osparc.product.Utils.getStudyAlias()) + this.tr(" files..."); const studyDataButton = new qx.ui.menu.Button(text, "@FontAwesome5Solid/file/12"); + studyDataButton["studyDataButton"] = true; studyDataButton.addListener("tap", () => card.openData(), this); return studyDataButton; }, @@ -1149,8 +1152,9 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { __getMoveToFolderMenuButton: function(studyData) { const text = osparc.utils.Utils.capitalize(this.tr("Move to Folder...")); - const studyBillingSettingsButton = new qx.ui.menu.Button(text, "@FontAwesome5Solid/folder/12"); - studyBillingSettingsButton.addListener("tap", () => { + const moveToFolderButton = new qx.ui.menu.Button(text, "@FontAwesome5Solid/folder/12"); + moveToFolderButton["moveToFolderButton"] = true; + moveToFolderButton.addListener("tap", () => { if (Object.keys(studyData["accessRights"]).length > 1) { osparc.FlashMessenger.getInstance().logAs(this.tr("Shared projects can't be moved yet"), "WARNING"); } else { @@ -1172,17 +1176,19 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { moveStudyToFolder.addListener("cancel", () => win.close()); } }, this); - return studyBillingSettingsButton; + return moveToFolderButton; }, __getDuplicateMenuButton: function(studyData) { const duplicateButton = new qx.ui.menu.Button(this.tr("Duplicate"), "@FontAwesome5Solid/copy/12"); + duplicateButton["duplicateButton"] = true; duplicateButton.addListener("execute", () => this.__duplicateStudy(studyData), this); return duplicateButton; }, __getExportMenuButton: function(studyData) { const exportButton = new qx.ui.menu.Button(this.tr("Export cMIS"), "@FontAwesome5Solid/cloud-download-alt/12"); + exportButton["exportCMISButton"] = true; const isDisabled = osparc.utils.DisabledPlugins.isExportDisabled(); exportButton.setVisibility(isDisabled ? "excluded" : "visible"); exportButton.addListener("execute", () => this.__exportStudy(studyData), this); @@ -1211,6 +1217,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { __getDeleteStudyMenuButton: function(studyData) { const deleteButton = new qx.ui.menu.Button(this.tr("Delete"), "@FontAwesome5Solid/trash/12"); + deleteButton["deleteButton"] = true; deleteButton.set({ appearance: "menu-button" }); diff --git a/services/static-webserver/client/source/class/osparc/dashboard/TemplateBrowser.js b/services/static-webserver/client/source/class/osparc/dashboard/TemplateBrowser.js index 8b7c62000de..d9ba8b01296 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/TemplateBrowser.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/TemplateBrowser.js @@ -124,7 +124,7 @@ qx.Class.define("osparc.dashboard.TemplateBrowser", { }, __itemClicked: function(card) { - if (!card.isLocked()) { + if (!card.getBlocked()) { card.setValue(false); const templateData = this.__getTemplateData(card.getUuid()); this._openResourceDetails(templateData); diff --git a/services/static-webserver/client/source/class/osparc/pricing/ServicesList.js b/services/static-webserver/client/source/class/osparc/pricing/ServicesList.js index efc8651bdfa..f3b5c60949b 100644 --- a/services/static-webserver/client/source/class/osparc/pricing/ServicesList.js +++ b/services/static-webserver/client/source/class/osparc/pricing/ServicesList.js @@ -86,7 +86,8 @@ qx.Class.define("osparc.pricing.ServicesList", { metadataPromises.push(osparc.service.Store.getService(key, version)); }); Promise.all(metadataPromises) - .then(() => { + .catch(err => console.error(err)) + .finally(() => { const sList = []; services.forEach(service => { const key = service["serviceKey"]; @@ -96,11 +97,9 @@ qx.Class.define("osparc.pricing.ServicesList", { sList.push(new osparc.data.model.Service(serviceMetadata)); } }); - const servicesList = this.getChildControl("services-list"); servicesList.setModel(new qx.data.Array(sList)); }) - .catch(err => console.error(err)); }, __openAddServiceToPlan: function() { diff --git a/services/static-webserver/client/source/class/osparc/service/Store.js b/services/static-webserver/client/source/class/osparc/service/Store.js index 9c72e9dd6be..8158eb836bc 100644 --- a/services/static-webserver/client/source/class/osparc/service/Store.js +++ b/services/static-webserver/client/source/class/osparc/service/Store.js @@ -65,7 +65,8 @@ qx.Class.define("osparc.service.Store", { this.__addExtraTypeInfo(service); this.__addToCache(service) resolve(service); - }); + }) + .catch(console.error); }); }, 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 91dd4475551..a1f4fc76f31 100644 --- a/services/static-webserver/client/source/class/osparc/study/Utils.js +++ b/services/static-webserver/client/source/class/osparc/study/Utils.js @@ -231,25 +231,67 @@ qx.Class.define("osparc.study.Utils", { }); }, - mustache: { - mustacheRegEx: function() { - return /{{([^{}]*)}}/g; - }, - - mustache2Var: function(mustached) { - return mustached.replace("{{", "").replace("}}", ""); - }, - - getVariables: function(obj) { - const variables = new Set(); - const secondaryStudyDataStr = JSON.stringify(obj); - const mustaches = secondaryStudyDataStr.match(this.self().mustache.mustacheRegEx()) || []; - mustaches.forEach(mustache => { - const variable = this.self().mustache.mustache2Var(mustache); - variables.add(variable); - }); - return Array.from(variables); + __getBlockedState: function(studyData) { + if (studyData["workbench"]) { + const unaccessibleServices = osparc.study.Utils.getInaccessibleServices(studyData["workbench"]) + if (unaccessibleServices.length) { + return "UNKNOWN_SERVICES"; + } + } + if (studyData["state"] && studyData["state"]["locked"] && studyData["state"]["locked"]["value"]) { + return "IN_USE"; } + return false; + }, + + canBeOpened: function(studyData) { + const blocked = this.__getBlockedState(studyData); + return [false].includes(blocked); + }, + + canShowBillingOptions: function(studyData) { + const blocked = this.__getBlockedState(studyData); + return [false].includes(blocked); + }, + + canShowServiceUpdates: function(studyData) { + const blocked = this.__getBlockedState(studyData); + return [false].includes(blocked); + }, + + canShowServiceBootOptions: function(studyData) { + const blocked = this.__getBlockedState(studyData); + return [false].includes(blocked); + }, + + canShowStudyData: function(studyData) { + const blocked = this.__getBlockedState(studyData); + return [false].includes(blocked); + }, + + canShowPreview: function(studyData) { + const blocked = this.__getBlockedState(studyData); + return [false].includes(blocked); + }, + + canBeDeleted: function(studyData) { + const blocked = this.__getBlockedState(studyData); + return ["UNKNOWN_SERVICES", false].includes(blocked); + }, + + canBeDuplicated: function(studyData) { + const blocked = this.__getBlockedState(studyData); + return [false].includes(blocked); + }, + + canBeExported: function(studyData) { + const blocked = this.__getBlockedState(studyData); + return ["UNKNOWN_SERVICES", false].includes(blocked); + }, + + canMoveToFolder: function(studyData) { + const blocked = this.__getBlockedState(studyData); + return ["UNKNOWN_SERVICES", false].includes(blocked); } } }); diff --git a/services/static-webserver/client/source/class/osparc/theme/Appearance.js b/services/static-webserver/client/source/class/osparc/theme/Appearance.js index ebf773d2934..2954ef996e9 100644 --- a/services/static-webserver/client/source/class/osparc/theme/Appearance.js +++ b/services/static-webserver/client/source/class/osparc/theme/Appearance.js @@ -1121,7 +1121,11 @@ qx.Theme.define("osparc.theme.Appearance", { "tooltip": { style: state => ({ decorator: "tooltip", - padding: [5, 10] + padding: [5, 10], + // showTimeout is themeable so it can be tuned + // it was defaulted to 700 which was too short + showTimeout: 2000, + hideTimeout: 5000, }) },