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 7db4d4468918..d617ea8ddd63 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceDetails.js @@ -960,14 +960,14 @@ qx.Class.define("osparc.dashboard.ResourceDetails", { return; } - if (!osparc.study.Utils.isPotentialFunction(this.__resourceData["workbench"])) { - return; - } + const isPotentialFunction = osparc.study.CreateFunction.isPotentialFunction(this.__resourceData["workbench"]); const id = "CreateFunction"; const iconSrc = "@MaterialIcons/functions/24"; const title = this.tr("Create Function"); const page = new osparc.dashboard.resources.pages.BasePage(title, iconSrc, id); + page.setEnabled(isPotentialFunction); + osparc.utils.Utils.toolTipTextOnDisabledWidget(page.getChildControl("button"), osparc.study.CreateFunction.CREATE_FUNCTION_TEXT); const createFunction = new osparc.study.CreateFunction(this.__resourceData); const createFunctionButton = createFunction.getCreateFunctionButton(); osparc.utils.Utils.setIdToWidget(createFunctionButton, "create_function_page_btn"); diff --git a/services/static-webserver/client/source/class/osparc/data/Resources.js b/services/static-webserver/client/source/class/osparc/data/Resources.js index b521517c0fa4..60e1415d3f7d 100644 --- a/services/static-webserver/client/source/class/osparc/data/Resources.js +++ b/services/static-webserver/client/source/class/osparc/data/Resources.js @@ -102,7 +102,7 @@ qx.Class.define("osparc.data.Resources", { endpoints: { get: { method: "GET", - url: "/{productName}/app-summary.json", + url: `/{productName}/app-summary.json?no-cache=${new Date().getTime()}`, isJsonFile: true } } diff --git a/services/static-webserver/client/source/class/osparc/form/renderer/PropForm.js b/services/static-webserver/client/source/class/osparc/form/renderer/PropForm.js index fb504f8c25fb..452f9efa4689 100644 --- a/services/static-webserver/client/source/class/osparc/form/renderer/PropForm.js +++ b/services/static-webserver/client/source/class/osparc/form/renderer/PropForm.js @@ -939,11 +939,9 @@ qx.Class.define("osparc.form.renderer.PropForm", { converter: label => label + ": " + fromPortLabel }); - // Hack: Show tooltip if element is disabled const addToolTip = () => { - ctrlLink.getContentElement().removeAttribute("title"); const toolTipText = fromNode.getLabel() + ":\n" + fromPortLabel; - ctrlLink.getContentElement().setAttribute("title", toolTipText); + osparc.utils.Utils.toolTipTextOnDisabledWidget(ctrlLink, toolTipText); }; fromNode.addListener("changeLabel", () => addToolTip()); addToolTip(); diff --git a/services/static-webserver/client/source/class/osparc/study/CreateFunction.js b/services/static-webserver/client/source/class/osparc/study/CreateFunction.js index 0b7c9a348ef3..9b71ea943fd9 100644 --- a/services/static-webserver/client/source/class/osparc/study/CreateFunction.js +++ b/services/static-webserver/client/source/class/osparc/study/CreateFunction.js @@ -32,6 +32,37 @@ qx.Class.define("osparc.study.CreateFunction", { this.__buildLayout(); }, + statics: { + CREATE_FUNCTION_TEXT: qx.locale.Manager.tr(` + In order to Create a Function, the pipeline needs: + - at least one parameter and one probe (numbers) + - at least one computational app + - no dynamic apps + `), + + isPotentialFunction: function(workbench) { + // const filePickers = osparc.study.Utils.extractFilePickers(workbench); + // const parameters = osparc.study.Utils.extractParameters(workbench); + // const probes = osparc.study.Utils.extractProbes(workbench); + // return (filePickers.length + parameters.length) && probes.length; + + const parameters = osparc.study.Utils.extractFunctionableParameters(workbench); + const probes = osparc.study.Utils.extractFunctionableProbes(workbench); + const computationals = osparc.study.Utils.extractComputationalServices(workbench); + const dynamics = osparc.study.Utils.extractDynamicServices(workbench); + + return Boolean( + (parameters.length && probes.length) && + computationals.length > 0 && + dynamics.length === 0 + ); + }, + + checkExposedInputsOutputs: function(exposedInputs, exposedOutputs) { + return Boolean(Object.values(exposedInputs).some(exposedInputValue => exposedInputValue) && Object.values(exposedOutputs).some(exposedOutputValue => exposedOutputValue)); + }, + }, + members: { __studyData: null, __form: null, @@ -238,6 +269,12 @@ qx.Class.define("osparc.study.CreateFunction", { }, __createFunction: function(defaultInputs, exposedInputs, exposedOutputs) { + if (!osparc.study.CreateFunction.checkExposedInputsOutputs(exposedInputs, exposedOutputs)) { + const msg = this.tr("Expose at least one input and one output"); + osparc.FlashMessenger.logAs(msg, "ERROR"); + return; + } + this.__createFunctionBtn.setFetching(true); // first publish it as a hidden template 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 e61810cf0d40..57bff3573829 100644 --- a/services/static-webserver/client/source/class/osparc/study/Utils.js +++ b/services/static-webserver/client/source/class/osparc/study/Utils.js @@ -270,30 +270,6 @@ qx.Class.define("osparc.study.Utils", { return parameters; }, - isPotentialFunction: function(workbench) { - // in order to create a function, the pipeline needs: - // - at least one parameter or one probe - // - for now, only float types are allowed - // - at least one computational service - // - no dynamic services - - // const filePickers = osparc.study.Utils.extractFilePickers(workbench); - // const parameters = osparc.study.Utils.extractParameters(workbench); - // const probes = osparc.study.Utils.extractProbes(workbench); - // return (filePickers.length + parameters.length) && probes.length; - - const parameters = osparc.study.Utils.extractFunctionableParameters(workbench); - const probes = osparc.study.Utils.extractFunctionableProbes(workbench); - const computationals = osparc.study.Utils.extractComputationalServices(workbench); - const dynamics = osparc.study.Utils.extractDynamicServices(workbench); - - return ( - (parameters.length || probes.length) && - computationals.length > 0 && - dynamics.length === 0 - ); - }, - getCantReadServices: function(studyServices = []) { return studyServices.filter(studyService => studyService["myAccessRights"]["execute"] === false); }, diff --git a/services/static-webserver/client/source/class/osparc/utils/Utils.js b/services/static-webserver/client/source/class/osparc/utils/Utils.js index 70a3bd1f87bc..c7bbdaf277c6 100644 --- a/services/static-webserver/client/source/class/osparc/utils/Utils.js +++ b/services/static-webserver/client/source/class/osparc/utils/Utils.js @@ -91,6 +91,14 @@ qx.Class.define("osparc.utils.Utils", { FLOATING_Z_INDEX: 1000001 + 1, + toolTipTextOnDisabledWidget: function(widget, toolTipText) { + if (widget && widget.getContentElement()) { + const el = widget.getContentElement(); + el.removeAttribute("title"); + el.setAttribute("title", toolTipText); + } + }, + errorsToForm: function(form, errors) { const items = form.getItems(); // reset validity