From a8a8046f2124f685a8d5914e17a49413b53a4934 Mon Sep 17 00:00:00 2001 From: Odei Maiz <33152403+odeimaiz@users.noreply.github.com> Date: Thu, 6 Feb 2025 12:10:53 +0100 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20[Frontend]=20ViP=20Market:?= =?UTF-8?q?=20adapt=20to=20latest=20model=20(#7164)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On behalf of @odeimaiz --- .../class/osparc/store/LicensedItems.js | 14 ++++++ .../vipMarket/AnatomicalModelDetails.js | 31 +++++++----- .../vipMarket/AnatomicalModelListItem.js | 28 +++++++---- .../source/class/osparc/vipMarket/Market.js | 48 ++++++++----------- .../class/osparc/vipMarket/VipMarket.js | 29 +++++------ 5 files changed, 86 insertions(+), 64 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/store/LicensedItems.js b/services/static-webserver/client/source/class/osparc/store/LicensedItems.js index 3aad7d40754..938f7d45377 100644 --- a/services/static-webserver/client/source/class/osparc/store/LicensedItems.js +++ b/services/static-webserver/client/source/class/osparc/store/LicensedItems.js @@ -25,6 +25,20 @@ qx.Class.define("osparc.store.LicensedItems", { this.__licensedItems = null; }, + statics: { + purchasesToNSeats: function(purchases) { + let nSeats = 0; + purchases.forEach(purchase => { + if ("numberOfSeats" in purchase) { + nSeats += purchase["numberOfSeats"]; + } else if ("getNumberOfSeats" in purchase) { + nSeats += purchase.getNumberOfSeats(); + } + }); + return nSeats; + }, + }, + members: { __licensedItems: null, diff --git a/services/static-webserver/client/source/class/osparc/vipMarket/AnatomicalModelDetails.js b/services/static-webserver/client/source/class/osparc/vipMarket/AnatomicalModelDetails.js index 1710d84bd44..c919e3c876a 100644 --- a/services/static-webserver/client/source/class/osparc/vipMarket/AnatomicalModelDetails.js +++ b/services/static-webserver/client/source/class/osparc/vipMarket/AnatomicalModelDetails.js @@ -53,8 +53,8 @@ qx.Class.define("osparc.vipMarket.AnatomicalModelDetails", { this._removeAll(); const anatomicalModelsData = this.getAnatomicalModelsData(); - if (anatomicalModelsData) { - const modelInfo = this.__createModelInfo(anatomicalModelsData["licensedResourceData"]); + if (anatomicalModelsData && anatomicalModelsData["licensedResourceData"]) { + const modelInfo = this.__createModelInfo(anatomicalModelsData["licensedResourceData"]["source"]); const pricingUnits = this.__createPricingUnits(anatomicalModelsData); const importButton = this.__createImportSection(anatomicalModelsData); this._add(modelInfo); @@ -161,13 +161,22 @@ qx.Class.define("osparc.vipMarket.AnatomicalModelDetails", { row: idx, }); - const doiValue = new qx.ui.basic.Label().set({ - value: anatomicalModelsData["doi"] ? anatomicalModelsData["doi"] : "-", - font: "text-14", - alignX: "left", - marginTop: 16, - }); - featuresLayout.add(doiValue, { + const doiToLink = doi => { + const doiLabel = new osparc.ui.basic.LinkLabel("-").set({ + font: "text-14", + alignX: "left", + marginTop: 16, + }); + if (doi) { + doiLabel.set({ + value: doi, + url: "https://doi.org/" + doi, + font: "link-label-14", + }); + } + return doiLabel; + }; + featuresLayout.add(doiToLink(anatomicalModelsData["doi"]), { column: 1, row: idx, }); @@ -196,7 +205,7 @@ qx.Class.define("osparc.vipMarket.AnatomicalModelDetails", { }); pUnit.addListener("rentPricingUnit", () => { this.fireDataEvent("modelPurchaseRequested", { - modelId: anatomicalModelsData["modelId"], + modelId: anatomicalModelsData["licensedResourceData"]["source"]["id"], licensedItemId: anatomicalModelsData["licensedItemId"], pricingPlanId: anatomicalModelsData["pricingPlanId"], pricingUnitId: pricingUnit.getPricingUnitId(), @@ -236,7 +245,7 @@ qx.Class.define("osparc.vipMarket.AnatomicalModelDetails", { }); importButton.addListener("execute", () => { this.fireDataEvent("modelImportRequested", { - modelId: anatomicalModelsData["modelId"] + modelId: anatomicalModelsData["licensedResourceData"]["source"]["id"] }); }, this); if (anatomicalModelsData["purchases"].length) { diff --git a/services/static-webserver/client/source/class/osparc/vipMarket/AnatomicalModelListItem.js b/services/static-webserver/client/source/class/osparc/vipMarket/AnatomicalModelListItem.js index 415e7cc7517..83568616d0f 100644 --- a/services/static-webserver/client/source/class/osparc/vipMarket/AnatomicalModelListItem.js +++ b/services/static-webserver/client/source/class/osparc/vipMarket/AnatomicalModelListItem.js @@ -24,11 +24,12 @@ qx.Class.define("osparc.vipMarket.AnatomicalModelListItem", { this.base(arguments); const layout = new qx.ui.layout.Grid(5, 5); - layout.setColumnWidth(0, 64); layout.setRowFlex(0, 1); - layout.setColumnFlex(1, 1); + layout.setColumnFlex(1, 1); // flex display name + layout.setColumnWidth(0, 48); layout.setColumnAlign(0, "center", "middle"); layout.setColumnAlign(1, "left", "middle"); + layout.setColumnAlign(2, "center", "middle"); this._setLayout(layout); this.set({ @@ -145,6 +146,16 @@ qx.Class.define("osparc.vipMarket.AnatomicalModelListItem", { column: 1 }); break; + case "n-seats": + control = new qx.ui.basic.Label().set({ + font: "text-14", + alignY: "middle", + }); + this._add(control, { + row: 0, + column: 2 + }); + break; } control.set({ anonymous: true, // pass the tap action over @@ -162,11 +173,12 @@ qx.Class.define("osparc.vipMarket.AnatomicalModelListItem", { }, __applyPurchases: function(purchases) { - if (purchases.length) { - this.set({ - textColor: "default-button-text", - backgroundColor: "strong-main", - }) + const nSeatsLabel = this.getChildControl("n-seats"); + const nSeats = osparc.store.LicensedItems.purchasesToNSeats(purchases); + if (nSeats) { + nSeatsLabel.setValue(`(${nSeats})`); + } else { + nSeatsLabel.resetValue(); } }, @@ -189,7 +201,7 @@ qx.Class.define("osparc.vipMarket.AnatomicalModelListItem", { _shouldApplyFilter: function(data) { if (data.text) { const checks = [ - this.getName(), + this.getDisplayName(), ]; if (checks.filter(check => check && check.toLowerCase().trim().includes(data.text)).length == 0) { return true; diff --git a/services/static-webserver/client/source/class/osparc/vipMarket/Market.js b/services/static-webserver/client/source/class/osparc/vipMarket/Market.js index edad4b3a2d7..6e76681978d 100644 --- a/services/static-webserver/client/source/class/osparc/vipMarket/Market.js +++ b/services/static-webserver/client/source/class/osparc/vipMarket/Market.js @@ -41,40 +41,30 @@ qx.Class.define("osparc.vipMarket.Market", { ]) .then(values => { const licensedItems = values[0]; - const categories = {}; + const categories = []; licensedItems.forEach(licensedItem => { - if (licensedItem["licensedResourceData"] && licensedItem["licensedResourceData"]["category"]) { - const category = licensedItem["licensedResourceData"]["category"]; - if (!(category in categories)) { - categories[category] = []; + if (licensedItem["licensedResourceData"] && licensedItem["licensedResourceData"]["categoryId"]) { + const categoryId = licensedItem["licensedResourceData"]["categoryId"]; + let category = categories.find(cat => cat["categoryId"] === categoryId); + if (!category) { + category = { + categoryId, + label: licensedItem["licensedResourceData"]["categoryDisplay"] || "Category", + icon: licensedItem["licensedResourceData"]["categoryIcon"] || "@FontAwesome5Solid/users/20", + items: [], + }; + categories.push(category); } - categories[category].push(licensedItem); + category["items"].push(licensedItem); } }); - const expectedCategories = [{ - category: "HumanWholeBody", - label: "Humans", - icon: "@FontAwesome5Solid/users/20", - }, { - category: "HumanBodyRegion", - label: "Humans (Region)", - icon: "@FontAwesome5Solid/users/20", - }, { - category: "AnimalWholeBody", - label: "Animals", - icon: "@FontAwesome5Solid/users/20", - }, { - category: "ComputationalPhantom", - label: "Phantoms", - icon: "@FontAwesome5Solid/users/20", - }] - expectedCategories.forEach(expectedCategory => { - this.__buildViPMarketPage(expectedCategory, categories[expectedCategory["category"]]); + categories.forEach(category => { + this.__buildViPMarketPage(category, category["items"]); }); if (openCategory) { - this.openCategory(openCategory); + this.__openCategory(openCategory); } }); }, @@ -96,16 +86,16 @@ qx.Class.define("osparc.vipMarket.Market", { __buildViPMarketPage: function(marketTabInfo, licensedItems = []) { const vipMarketView = new osparc.vipMarket.VipMarket(licensedItems); vipMarketView.set({ - category: marketTabInfo["category"], + category: marketTabInfo["categoryId"], }); this.bind("openBy", vipMarketView, "openBy"); vipMarketView.addListener("importMessageSent", () => this.fireEvent("importMessageSent")); const page = this.addTab(marketTabInfo["label"], marketTabInfo["icon"], vipMarketView); - page.category = marketTabInfo["category"]; + page.category = marketTabInfo["categoryId"]; return page; }, - openCategory: function(category) { + __openCategory: function(category) { const viewFound = this.getChildControl("tabs-view").getChildren().find(view => view.category === category); if (viewFound) { this._openPage(viewFound); diff --git a/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js b/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js index bd9da478ba1..b55b5ffe318 100644 --- a/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js +++ b/services/static-webserver/client/source/class/osparc/vipMarket/VipMarket.js @@ -43,7 +43,7 @@ qx.Class.define("osparc.vipMarket.VipMarket", { }, category: { - check: ["HumanWholeBody", "HumanBodyRegion", "AnimalWholeBody", "ComputationalPhantom"], + check: "String", init: null, nullable: true, }, @@ -182,21 +182,16 @@ qx.Class.define("osparc.vipMarket.VipMarket", { this.__anatomicalModels = []; licensedItems.forEach(licensedItem => { const anatomicalModel = osparc.utils.Utils.deepCloneObject(licensedItem); - anatomicalModel["modelId"] = licensedItem["licensedItemId"]; + anatomicalModel["modelId"] = anatomicalModel["licensedResourceData"]["source"]["id"]; anatomicalModel["thumbnail"] = ""; anatomicalModel["date"] = null; - if (anatomicalModel["licensedResourceData"]) { - if (anatomicalModel["licensedResourceData"]["id"]) { - anatomicalModel["modelId"] = anatomicalModel["licensedResourceData"]["id"]; - } - if (anatomicalModel["licensedResourceData"]["thumbnail"]) { - anatomicalModel["thumbnail"] = anatomicalModel["licensedResourceData"]["thumbnail"]; + if (anatomicalModel["licensedResourceData"] && anatomicalModel["licensedResourceData"]["source"]) { + const anatomicalModelSource = anatomicalModel["licensedResourceData"]["source"]; + if (anatomicalModelSource["thumbnail"]) { + anatomicalModel["thumbnail"] = anatomicalModelSource["thumbnail"]; } - if ( - anatomicalModel["licensedResourceData"]["features"] && - anatomicalModel["licensedResourceData"]["features"]["date"] - ) { - anatomicalModel["date"] = new Date(anatomicalModel["licensedResourceData"]["features"]["date"]); + if (anatomicalModelSource["features"] && anatomicalModelSource["features"]["date"]) { + anatomicalModel["date"] = new Date(anatomicalModelSource["features"]["date"]); } } // attach license data @@ -277,9 +272,11 @@ qx.Class.define("osparc.vipMarket.VipMarket", { const sortModel = sortBy => { models.sort((a, b) => { // first criteria - if (b["purchases"].length !== a["purchases"].length) { - // leased first - return b["purchases"].length - a["purchases"].length; + const nASeats = osparc.store.LicensedItems.purchasesToNSeats(a["purchases"]); + const nBSeats = osparc.store.LicensedItems.purchasesToNSeats(b["purchases"]); + if (nBSeats !== nASeats) { + // nSeats first + return nBSeats - nASeats; } // second criteria if (sortBy) {