From 3829854e15a10f4f2cfa4b84e319c742ad975fae Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 11 Feb 2025 13:23:20 +0100 Subject: [PATCH 1/5] patch icon --- .../source/class/osparc/info/ServiceLarge.js | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/info/ServiceLarge.js b/services/static-webserver/client/source/class/osparc/info/ServiceLarge.js index 217c13e58e9b..fed2d70ec04d 100644 --- a/services/static-webserver/client/source/class/osparc/info/ServiceLarge.js +++ b/services/static-webserver/client/source/class/osparc/info/ServiceLarge.js @@ -143,9 +143,14 @@ qx.Class.define("osparc.info.ServiceLarge", { // Show description only vBox.add(description.getChildren()[1]); } else { - const title = this.__createTitle(); + const hBox = new qx.ui.container.Composite(new qx.ui.layout.HBox(10)); + const icon = this.__createIcon(); + const iconLayout = this.__createViewWithEdit(icon, this.__openIconEditor); + hBox.add(iconLayout); + const title = this.__createName(); const titleLayout = this.__createViewWithEdit(title, this.__openTitleEditor); - vBox.add(titleLayout); + hBox.add(titleLayout); + vBox.add(hBox); const extraInfo = this.__extraInfo(); const extraInfoLayout = this.__createExtraInfo(extraInfo); @@ -218,7 +223,17 @@ qx.Class.define("osparc.info.ServiceLarge", { return null; }, - __createTitle: function() { + __createIcon: function() { + const serviceIcon = this.getService()["icon"]; + const iconSize = osparc.dashboard.GridButtonBase.ICON_SIZE; + const icon = new osparc.ui.basic.Thumbnail(serviceIcon, iconSize, iconSize).set({ + minHeight: iconSize, + minWidth: iconSize, + }); + return icon; + }, + + __createName: function() { const serviceName = this.getService()["name"]; let text = ""; if (this.getInstanceLabel()) { @@ -443,9 +458,19 @@ qx.Class.define("osparc.info.ServiceLarge", { return container; }, + __openIconEditor: function() { + const iconEditor = new osparc.widget.Renamer(this.getService()["icon"], null, this.tr("Edit Icon")); + iconEditor.addListener("labelChanged", e => { + iconEditor.close(); + const newIcon = e.getData()["newLabel"]; + this.__patchService("icon", newIcon); + }, this); + iconEditor.center(); + iconEditor.open(); + }, + __openTitleEditor: function() { - const title = this.tr("Edit Title"); - const titleEditor = new osparc.widget.Renamer(this.getService()["name"], null, title); + const titleEditor = new osparc.widget.Renamer(this.getService()["name"], null, this.tr("Edit Name")); titleEditor.addListener("labelChanged", e => { titleEditor.close(); const newLabel = e.getData()["newLabel"]; From f67fde54e8e74be7666b393c5aa6af535bc4f37f Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 11 Feb 2025 13:29:10 +0100 Subject: [PATCH 2/5] resourceData["icon"] --- .../client/source/class/osparc/dashboard/CardBase.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 5df1eef59a09..dddc5d7f23a5 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js @@ -461,20 +461,24 @@ qx.Class.define("osparc.dashboard.CardBase", { let owner = null; let workbench = null; let defaultHits = null; + let icon = null; switch (resourceData["resourceType"]) { case "study": uuid = resourceData.uuid ? resourceData.uuid : null; owner = resourceData.prjOwner ? resourceData.prjOwner : ""; workbench = resourceData.workbench ? resourceData.workbench : {}; + icon = osparc.study.Utils.guessIcon(resourceData); break; case "template": uuid = resourceData.uuid ? resourceData.uuid : null; owner = resourceData.prjOwner ? resourceData.prjOwner : ""; workbench = resourceData.workbench ? resourceData.workbench : {}; + icon = osparc.study.Utils.guessIcon(resourceData); break; case "service": uuid = resourceData.key ? resourceData.key : null; owner = resourceData.owner ? resourceData.owner : resourceData.contact; + icon = resourceData["icon"] || osparc.dashboard.CardBase.PRODUCT_ICON; defaultHits = 0; break; } @@ -489,7 +493,7 @@ qx.Class.define("osparc.dashboard.CardBase", { lastChangeDate: resourceData.lastChangeDate ? new Date(resourceData.lastChangeDate) : null, trashedAt: resourceData.trashedAt ? new Date(resourceData.trashedAt) : null, trashedBy: resourceData.trashedBy || null, - icon: ["study", "template"].includes(resourceData.resourceType) ? osparc.study.Utils.guessIcon(resourceData) : osparc.dashboard.CardBase.PRODUCT_ICON, + icon, thumbnail: resourceData.thumbnail || this.self().PRODUCT_THUMBNAIL, state: resourceData.state ? resourceData.state : {}, classifiers: resourceData.classifiers && resourceData.classifiers ? resourceData.classifiers : [], From b5b4790d1d5cc48181da5b807b075b27a804de0f Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 11 Feb 2025 14:34:46 +0100 Subject: [PATCH 3/5] __guessIcon --- .../client/source/class/osparc/study/Utils.js | 43 ++++++++----------- 1 file changed, 17 insertions(+), 26 deletions(-) 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 f2fb9ea35948..e7f684ff0d6e 100644 --- a/services/static-webserver/client/source/class/osparc/study/Utils.js +++ b/services/static-webserver/client/source/class/osparc/study/Utils.js @@ -358,42 +358,33 @@ qx.Class.define("osparc.study.Utils", { return ["UNKNOWN_SERVICES", false].includes(blocked); }, + getNonFrontendNodes: function(studyData) { + return Object.values(studyData["workbench"]).filter(node => !osparc.data.model.Node.isFrontend(node)); + }, + guessIcon: function(studyData) { - if (osparc.product.Utils.isProduct("osparc")) { - return this.__guessOsparcIcon(studyData); - } - if (osparc.product.Utils.isS4LProduct() || osparc.product.Utils.isProduct("s4llite")) { - return this.__guessS4LIcon(studyData); - } if (osparc.product.Utils.isProduct("tis") || osparc.product.Utils.isProduct("tiplite")) { return this.__guessTIPIcon(studyData); } - return osparc.dashboard.CardBase.PRODUCT_ICON; - }, - - __guessOsparcIcon: function(studyData) { - // the was to guess the TI type is to check the boot mode of the ti-postpro in the pipeline - const wbServices = Object.values(studyData["workbench"]); - if (wbServices.length > 1) { - return "osparc/icons/diagram.png"; - } - return osparc.dashboard.CardBase.PRODUCT_ICON; + return this.__guessIcon(studyData); }, - __guessS4LIcon: function(studyData) { + __guessIcon: function(studyData) { // the was to guess the TI type is to check the boot mode of the ti-postpro in the pipeline - const wbServices = Object.values(studyData["workbench"]); + const wbServices = this.self().getNonFrontendNodes(studyData); if (wbServices.length === 1) { - if (wbServices[0]["key"].includes("iseg")) { - return "https://raw.githubusercontent.com/ITISFoundation/osparc-iseg/master/iSeg/images/isegicon.png"; - } - if (wbServices[0]["key"].includes("jupyter")) { - return "https://images.seeklogo.com/logo-png/35/1/jupyter-logo-png_seeklogo-354673.png"; - } - if (wbServices[0]["key"].includes("s4l-ui")) { - return "https://raw.githubusercontent.com/ZurichMedTech/s4l-assets/refs/heads/main/app/icons/s4l/Sim4Life.png"; + const wbService = wbServices[0]; + const allServices = osparc.store.Services.servicesCached; + if (wbService.key in allServices && wbService.version in allServices[wbService.key]) { + const serviceMetadata = allServices[wbService.key][wbService.version]; + if (serviceMetadata["icon"]) { + return serviceMetadata["icon"]; + } } } + if (wbServices.length > 1) { + return "osparc/icons/diagram.png"; + } return osparc.dashboard.CardBase.PRODUCT_ICON; }, From d3b516c1f462d4ba4bda0adeba04465fff2fe0e3 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 11 Feb 2025 14:54:14 +0100 Subject: [PATCH 4/5] minor --- .../client/source/class/osparc/info/ServiceLarge.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/services/static-webserver/client/source/class/osparc/info/ServiceLarge.js b/services/static-webserver/client/source/class/osparc/info/ServiceLarge.js index fed2d70ec04d..7a1865cfcc01 100644 --- a/services/static-webserver/client/source/class/osparc/info/ServiceLarge.js +++ b/services/static-webserver/client/source/class/osparc/info/ServiceLarge.js @@ -224,12 +224,16 @@ qx.Class.define("osparc.info.ServiceLarge", { }, __createIcon: function() { - const serviceIcon = this.getService()["icon"]; + const serviceIcon = this.getService()["icon"] || "osparc/no_photography_black_24dp.svg"; const iconSize = osparc.dashboard.GridButtonBase.ICON_SIZE; const icon = new osparc.ui.basic.Thumbnail(serviceIcon, iconSize, iconSize).set({ minHeight: iconSize, minWidth: iconSize, }); + icon.getChildControl("image").set({ + minWidth: iconSize, + minHeight: iconSize, + }); return icon; }, From 2853ac56e62eb386bc681bb1fde4bdc450a866a5 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Tue, 11 Feb 2025 14:57:26 +0100 Subject: [PATCH 5/5] minor --- .../source/resource/osparc/icons/diagram.png | Bin 7941 -> 9967 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/services/static-webserver/client/source/resource/osparc/icons/diagram.png b/services/static-webserver/client/source/resource/osparc/icons/diagram.png index bb43d717baeec50b357cd61766534e78e6e9ba0a..7ed509475bd60d9c2468256d89b0d96f195f55eb 100644 GIT binary patch literal 9967 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 E1J?F#Qvd(}