From d9a723a1c075d75dc0f71c898fe217087e338c4a Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 10:43:03 +0100 Subject: [PATCH 01/27] minor --- .../client/source/class/osparc/store/Services.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/services/static-webserver/client/source/class/osparc/store/Services.js b/services/static-webserver/client/source/class/osparc/store/Services.js index f6851b3aa43..c2abeed32ec 100644 --- a/services/static-webserver/client/source/class/osparc/store/Services.js +++ b/services/static-webserver/client/source/class/osparc/store/Services.js @@ -44,7 +44,11 @@ qx.Class.define("osparc.store.Services", { resolve(servicesObj); }) - .catch(err => console.error("getServices failed", err)); + .catch(err => { + const msg = err.message || qx.locale.Manager.tr("Unable to fetch Services"); + osparc.FlashMessenger.getInstance().logAs(msg, "ERROR"); + console.error(err); + }); }); }, From dbe8b8f20073045fc229fb478a4d37ea448d1d8b Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 10:45:09 +0100 Subject: [PATCH 02/27] refactor isMyFrontendOld --- .../client/source/class/osparc/NewRelease.js | 20 +++++++---- .../source/class/osparc/NewUITracker.js | 33 ++++++++++--------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/NewRelease.js b/services/static-webserver/client/source/class/osparc/NewRelease.js index af6c23f34eb..bac9d1efb25 100644 --- a/services/static-webserver/client/source/class/osparc/NewRelease.js +++ b/services/static-webserver/client/source/class/osparc/NewRelease.js @@ -44,13 +44,19 @@ qx.Class.define("osparc.NewRelease", { /** * Compare the latest version provided by the backend with the one loaded in the browser (might be an old cached one) */ - isMyFrontendOld: async function() { - const lastUICommit = await osparc.store.AppSummary.getLatestUIFromBE(); - const thisUICommit = osparc.utils.LibVersions.getVcsRefUI(); - if (lastUICommit && thisUICommit) { - return lastUICommit !== thisUICommit; - } - return false; + isMyFrontendOld: function() { + return new Promise((resolve, reject) => { + osparc.store.AppSummary.getLatestUIFromBE() + .then(lastUICommit => { + const thisUICommit = osparc.utils.LibVersions.getVcsRefUI(); + if (lastUICommit && thisUICommit) { + resolve(lastUICommit !== thisUICommit) + } else { + reject(); + } + }) + .catch(() => reject()); + }); } }, diff --git a/services/static-webserver/client/source/class/osparc/NewUITracker.js b/services/static-webserver/client/source/class/osparc/NewUITracker.js index 04a19536128..c85fb3f9390 100644 --- a/services/static-webserver/client/source/class/osparc/NewUITracker.js +++ b/services/static-webserver/client/source/class/osparc/NewUITracker.js @@ -27,21 +27,24 @@ qx.Class.define("osparc.NewUITracker", { __checkInterval: null, startTracker: function() { - const checkNewUI = async () => { - const newReleaseAvailable = await osparc.NewRelease.isMyFrontendOld(); - if (newReleaseAvailable) { - let msg = ""; - msg += qx.locale.Manager.tr("A new version of the application is now available."); - msg += "
"; - msg += qx.locale.Manager.tr("Click the Reload button to get the latest features."); - // permanent message - const flashMessage = osparc.FlashMessenger.getInstance().logAs(msg, "INFO", 0).set({ - maxWidth: 500 - }); - const reloadButton = osparc.utils.Utils.reloadNoCacheButton(); - flashMessage.addWidget(reloadButton); - this.stopTracker(); - } + const checkNewUI = () => { + osparc.NewRelease.isMyFrontendOld() + .then(newReleaseAvailable => { + if (newReleaseAvailable) { + let msg = ""; + msg += qx.locale.Manager.tr("A new version of the application is now available."); + msg += "
"; + msg += qx.locale.Manager.tr("Click the Reload button to get the latest features."); + // permanent message + const flashMessage = osparc.FlashMessenger.getInstance().logAs(msg, "INFO", 0).set({ + maxWidth: 500 + }); + const reloadButton = osparc.utils.Utils.reloadNoCacheButton(); + flashMessage.addWidget(reloadButton); + this.stopTracker(); + } + }) + .catch(() => setTimeout(() => checkNewUI(), 5*1000)); }; checkNewUI(); this.__checkInterval = setInterval(checkNewUI, this.self().CHECK_INTERVAL); From da8474345fdc63896587d6103bb1148a901f82cd Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 11:02:05 +0100 Subject: [PATCH 03/27] make sure only exiting props are set --- .../client/source/class/osparc/store/Folders.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/static-webserver/client/source/class/osparc/store/Folders.js b/services/static-webserver/client/source/class/osparc/store/Folders.js index 7deb66618bb..d6e83d8fb23 100644 --- a/services/static-webserver/client/source/class/osparc/store/Folders.js +++ b/services/static-webserver/client/source/class/osparc/store/Folders.js @@ -172,6 +172,7 @@ qx.Class.define("osparc.store.Folders", { __addToCache: function(folderData) { let folder = this.foldersCached.find(f => f.getFolderId() === folderData["folderId"] && f.getWorkspaceId() === folderData["workspaceId"]); if (folder) { + const props = Object.keys(qx.util.PropertyUtil.getProperties(osparc.data.model.Folder)); // put Object.keys(folderData).forEach(key => { if (key === "createdAt") { @@ -180,7 +181,7 @@ qx.Class.define("osparc.store.Folders", { folder.set("lastModified", new Date(folderData["modifiedAt"])); } else if (key === "trashedAt") { folder.set("trashedAt", new Date(folderData["trashedAt"])); - } else { + } else if (props.includes(key)) { folder.set(key, folderData[key]); } }); From 7dc40ffebee264c64465e5499f277791f9041ccd Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 11:36:01 +0100 Subject: [PATCH 04/27] support empty description --- .../client/source/class/osparc/form/tag/TagItem.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js index 7e79bb54bf3..356d3bcb409 100644 --- a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js +++ b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js @@ -309,10 +309,13 @@ qx.Class.define("osparc.form.tag.TagItem", { * Creates an object containing the udpated tag info */ __serializeData: function() { + const name = this.getChildControl("nameinput").getValue(); + const description = this.getChildControl("descriptioninput").getValue(); + const color = this.getChildControl("colorinput").getValue(); return { - name: this.getChildControl("nameinput").getValue().trim(), - description: this.getChildControl("descriptioninput").getValue().trim(), - color: this.getChildControl("colorinput").getValue() + name: name.trim(), + description: description ? description.trim() : "", + color: color }; }, _applyMode: function() { From 383096b93bb36072c107871a034a6a5ce17b989a Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 11:52:28 +0100 Subject: [PATCH 05/27] notifications look like other menus --- .../class/osparc/notification/NotificationUI.js | 12 +++++++++--- .../osparc/notification/NotificationsContainer.js | 7 ++++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js b/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js index da49db7f0a4..67194c84418 100644 --- a/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js +++ b/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js @@ -22,6 +22,7 @@ qx.Class.define("osparc.notification.NotificationUI", { this.base(arguments); this.set({ + margin: 4, maxWidth: this.self().MAX_WIDTH, padding: this.self().PADDING, cursor: "pointer" @@ -216,9 +217,14 @@ qx.Class.define("osparc.notification.NotificationUI", { } }); - notification.bind("read", this, "backgroundColor", { - converter: read => read ? "background-main-3" : "background-main-4" - }); + const highlight = mouseOn => { + this.set({ + backgroundColor: mouseOn ? "strong-main" : "transparent" + }) + }; + this.addListener("mouseover", () => highlight(true)); + this.addListener("mouseout", () => highlight(false)); + highlight(false); }, __notificationTapped: function() { diff --git a/services/static-webserver/client/source/class/osparc/notification/NotificationsContainer.js b/services/static-webserver/client/source/class/osparc/notification/NotificationsContainer.js index 34757474f64..c59a8a94a4c 100644 --- a/services/static-webserver/client/source/class/osparc/notification/NotificationsContainer.js +++ b/services/static-webserver/client/source/class/osparc/notification/NotificationsContainer.js @@ -27,9 +27,14 @@ qx.Class.define("osparc.notification.NotificationsContainer", { zIndex: osparc.utils.Utils.FLOATING_Z_INDEX, maxWidth: osparc.notification.NotificationUI.MAX_WIDTH, maxHeight: 250, - backgroundColor: "background-main-3", + backgroundColor: "background-main", decorator: "rounded", }); + let color = qx.theme.manager.Color.getInstance().resolve("text"); + color = qx.util.ColorUtil.stringToRgb(color); + color.push(0.3); // add transparency + color = qx.util.ColorUtil.rgbToRgbString(color); + osparc.utils.Utils.addBorder(this, 1, color); osparc.utils.Utils.setIdToWidget(this, "notificationsContainer"); const root = qx.core.Init.getApplication().getRoot(); From 1e4ecff9f0010022960c099713b39ded290cfd8b Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 11:53:08 +0100 Subject: [PATCH 06/27] minor --- .../client/source/class/osparc/form/tag/TagItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js index 356d3bcb409..884401c9aea 100644 --- a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js +++ b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js @@ -306,7 +306,7 @@ qx.Class.define("osparc.form.tag.TagItem", { return container; }, /** - * Creates an object containing the udpated tag info + * Creates an object containing the updated tag info */ __serializeData: function() { const name = this.getChildControl("nameinput").getValue(); From a01502b68f60ca31911c5bc9a0cae6ef8718d648 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 12:11:40 +0100 Subject: [PATCH 07/27] Tag Data Model --- .../source/class/osparc/data/model/Tag.js | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 services/static-webserver/client/source/class/osparc/data/model/Tag.js diff --git a/services/static-webserver/client/source/class/osparc/data/model/Tag.js b/services/static-webserver/client/source/class/osparc/data/model/Tag.js new file mode 100644 index 00000000000..5fb7912a8d3 --- /dev/null +++ b/services/static-webserver/client/source/class/osparc/data/model/Tag.js @@ -0,0 +1,85 @@ +/* ************************************************************************ + + osparc - the simcore frontend + + https://osparc.io + + Copyright: + 2024 IT'IS Foundation, https://itis.swiss + + License: + MIT: https://opensource.org/licenses/MIT + + Authors: + * Odei Maiz (odeimaiz) + +************************************************************************ */ + +/** + * Class that stores Tag data. + */ + +qx.Class.define("osparc.data.model.Tag", { + extend: qx.core.Object, + + /** + * @param tagData {Object} Object containing the serialized Tag Data + */ + construct: function(tagData) { + this.base(arguments); + + this.set({ + tagId: tagData.id, + name: tagData.name, + description: tagData.description, + accessRights: tagData.accessRights, + }); + }, + + properties: { + tagId: { + check: "Number", + nullable: true, + init: null, + event: "changeTagId" + }, + + name: { + check: "String", + nullable: false, + init: null, + event: "changeName" + }, + + description: { + check: "String", + nullable: false, + init: null, + event: "changeDescription" + }, + + color: { + check: "Color", + event: "changeColor", + init: "#303030" + }, + + accessRights: { + check: "Object", + nullable: false, + init: null, + event: "changeAccessRights" + }, + }, + + members: { + serialize: function() { + const jsonObject = {}; + const propertyKeys = this.self().getProperties(); + propertyKeys.forEach(key => { + jsonObject[key] = this.get(key); + }); + return jsonObject; + } + } +}); From 95f14de8fd133b513b360ae5b17fa5da0c253e5c Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 12:16:13 +0100 Subject: [PATCH 08/27] renamings --- .../source/class/osparc/form/tag/TagItem.js | 141 ++++++++++-------- 1 file changed, 76 insertions(+), 65 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js index 884401c9aea..822ff3391c7 100644 --- a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js +++ b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js @@ -29,34 +29,40 @@ qx.Class.define("osparc.form.tag.TagItem", { id: { check: "Integer" }, + name: { check: "String", event: "changeName", init: "" }, + description: { check: "String", nullable: true, event: "changeDescription", init: "" }, + color: { check: "Color", event: "changeColor", init: "#303030" }, + accessRights: { check: "Object", nullable: false, + event: "changeAccessRights", apply: "__renderLayout", - event: "changeAccessRights" }, + mode: { check: "String", init: "display", nullable: false, apply: "_applyMode" }, + appearance: { init: "tagitem", refine: true @@ -78,57 +84,7 @@ qx.Class.define("osparc.form.tag.TagItem", { __colorButton: null, __loadingIcon: null, __validationManager: null, - /** - * Renders this tag item from scratch. - */ - __renderLayout: function() { - this._removeAll(); - if (this.getMode() === this.self().modes.EDIT) { - this.__renderEditMode(); - } else if (this.getMode() === this.self().modes.DISPLAY) { - this.__renderDisplayMode(); - } - }, - __renderEditMode: function() { - const nameContainer = new qx.ui.container.Composite(new qx.ui.layout.VBox()).set({ - width: 90 - }); - nameContainer.add(new qx.ui.basic.Label(this.tr("Name")).set({ - buddy: this.getChildControl("nameinput") - })); - nameContainer.add(this.getChildControl("nameinput").set({ - value: this.getName() - })); - this._add(nameContainer); - const descInputContainer = new qx.ui.container.Composite(new qx.ui.layout.VBox()); - descInputContainer.add(new qx.ui.basic.Label(this.tr("Description")).set({ - buddy: this.getChildControl("descriptioninput") - })); - descInputContainer.add(this.getChildControl("descriptioninput").set({ - value: this.getDescription() - })); - this._add(descInputContainer, { - flex: 1 - }); - this._add(this.__colorPicker()); - this._add(this.__tagItemEditButtons()); - }, - __renderDisplayMode: function() { - const tagContainer = new qx.ui.container.Composite(new qx.ui.layout.HBox()).set({ - width: 100 - }); - tagContainer.add(this.getChildControl("tag")); - this._add(tagContainer); - const descriptionContainer = new qx.ui.container.Composite(new qx.ui.layout.HBox()); - descriptionContainer.add(this.getChildControl("description"), { - width: "100%" - }); - this._add(descriptionContainer, { - flex: 1 - }); - this._add(this.__tagItemButtons()); - this.resetBackgroundColor(); - }, + _createChildControlImpl: function(id) { let control; switch (id) { @@ -151,7 +107,7 @@ qx.Class.define("osparc.form.tag.TagItem", { } control = this.__description; break; - case "nameinput": + case "name-input": // Tag name input in edit mode if (this.__nameInput === null) { this.__nameInput = new qx.ui.form.TextField().set({ @@ -162,7 +118,7 @@ qx.Class.define("osparc.form.tag.TagItem", { } control = this.__nameInput; break; - case "descriptioninput": + case "description-input": // Tag description input in edit mode if (this.__descriptionInput === null) { this.__descriptionInput = new qx.ui.form.TextArea().set({ @@ -172,7 +128,7 @@ qx.Class.define("osparc.form.tag.TagItem", { } control = this.__descriptionInput; break; - case "colorinput": + case "color-input": // Color input in edit mode if (this.__colorInput === null) { this.__colorInput = new qx.ui.form.TextField().set({ @@ -180,20 +136,20 @@ qx.Class.define("osparc.form.tag.TagItem", { width: 60, required: true }); - this.__colorInput.bind("value", this.getChildControl("colorbutton"), "backgroundColor"); - this.__colorInput.bind("value", this.getChildControl("colorbutton"), "textColor", { + this.__colorInput.bind("value", this.getChildControl("color-button"), "backgroundColor"); + this.__colorInput.bind("value", this.getChildControl("color-button"), "textColor", { converter: value => osparc.utils.Utils.getContrastedBinaryColor(value) }); this.__validationManager.add(this.__colorInput, osparc.utils.Validators.hexColor); } control = this.__colorInput; break; - case "colorbutton": + case "color-button": // Random color generator button in edit mode if (this.__colorButton === null) { this.__colorButton = new qx.ui.form.Button(null, "@FontAwesome5Solid/sync-alt/12"); this.__colorButton.addListener("execute", () => { - this.getChildControl("colorinput").setValue(osparc.utils.Utils.getRandomColor()); + this.getChildControl("color-input").setValue(osparc.utils.Utils.getRandomColor()); }, this); } control = this.__colorButton; @@ -201,6 +157,61 @@ qx.Class.define("osparc.form.tag.TagItem", { } return control || this.base(arguments, id); }, + + /** + * Renders this tag item from scratch. + */ + __renderLayout: function() { + this._removeAll(); + if (this.getMode() === this.self().modes.EDIT) { + this.__renderEditMode(); + } else if (this.getMode() === this.self().modes.DISPLAY) { + this.__renderDisplayMode(); + } + }, + + __renderEditMode: function() { + const nameContainer = new qx.ui.container.Composite(new qx.ui.layout.VBox()).set({ + width: 90 + }); + nameContainer.add(new qx.ui.basic.Label(this.tr("Name")).set({ + buddy: this.getChildControl("name-input") + })); + nameContainer.add(this.getChildControl("name-input").set({ + value: this.getName() + })); + this._add(nameContainer); + const descInputContainer = new qx.ui.container.Composite(new qx.ui.layout.VBox()); + descInputContainer.add(new qx.ui.basic.Label(this.tr("Description")).set({ + buddy: this.getChildControl("description-input") + })); + descInputContainer.add(this.getChildControl("description-input").set({ + value: this.getDescription() + })); + this._add(descInputContainer, { + flex: 1 + }); + this._add(this.__colorPicker()); + this._add(this.__tagItemEditButtons()); + }, + + __renderDisplayMode: function() { + const tagContainer = new qx.ui.container.Composite(new qx.ui.layout.HBox()).set({ + width: 100 + }); + tagContainer.add(this.getChildControl("tag")); + this._add(tagContainer); + const descriptionContainer = new qx.ui.container.Composite(new qx.ui.layout.HBox()); + descriptionContainer.add(this.getChildControl("description"), { + width: "100%" + }); + this._add(descriptionContainer, { + flex: 1 + }); + this._add(this.__tagItemButtons()); + this.resetBackgroundColor(); + }, + /** * Generates and returns the buttons for deleting and editing an existing label (display mode) */ @@ -295,11 +306,11 @@ qx.Class.define("osparc.form.tag.TagItem", { __colorPicker: function() { const container = new qx.ui.container.Composite(new qx.ui.layout.VBox()); container.add(new qx.ui.basic.Label(this.tr("Color")).set({ - buddy: this.getChildControl("colorinput") + buddy: this.getChildControl("color-input") })); const innerContainer = new qx.ui.container.Composite(new qx.ui.layout.HBox()); - const refreshButton = this.getChildControl("colorbutton"); - const colorInput = this.getChildControl("colorinput"); + const refreshButton = this.getChildControl("color-button"); + const colorInput = this.getChildControl("color-input"); innerContainer.add(refreshButton); innerContainer.add(colorInput); container.add(innerContainer); @@ -309,9 +320,9 @@ qx.Class.define("osparc.form.tag.TagItem", { * Creates an object containing the updated tag info */ __serializeData: function() { - const name = this.getChildControl("nameinput").getValue(); - const description = this.getChildControl("descriptioninput").getValue(); - const color = this.getChildControl("colorinput").getValue(); + const name = this.getChildControl("name-input").getValue(); + const description = this.getChildControl("description-input").getValue(); + const color = this.getChildControl("color-input").getValue(); return { name: name.trim(), description: description ? description.trim() : "", From 0fd8fdacf0de2c324920c16e172f9a09c9e6a828 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 13:18:53 +0100 Subject: [PATCH 09/27] tag property --- .../client/source/class/osparc/data/model/Tag.js | 3 ++- .../osparc/desktop/preferences/pages/TagsPage.js | 7 ++++++- .../source/class/osparc/form/tag/TagItem.js | 16 ++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/data/model/Tag.js b/services/static-webserver/client/source/class/osparc/data/model/Tag.js index 5fb7912a8d3..fc7e00a5fcc 100644 --- a/services/static-webserver/client/source/class/osparc/data/model/Tag.js +++ b/services/static-webserver/client/source/class/osparc/data/model/Tag.js @@ -32,6 +32,7 @@ qx.Class.define("osparc.data.model.Tag", { tagId: tagData.id, name: tagData.name, description: tagData.description, + color: tagData.color, accessRights: tagData.accessRights, }); }, @@ -53,7 +54,7 @@ qx.Class.define("osparc.data.model.Tag", { description: { check: "String", - nullable: false, + nullable: true, init: null, event: "changeDescription" }, diff --git a/services/static-webserver/client/source/class/osparc/desktop/preferences/pages/TagsPage.js b/services/static-webserver/client/source/class/osparc/desktop/preferences/pages/TagsPage.js index 7265c65cebd..06639a8619e 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/preferences/pages/TagsPage.js +++ b/services/static-webserver/client/source/class/osparc/desktop/preferences/pages/TagsPage.js @@ -50,7 +50,12 @@ qx.Class.define("osparc.desktop.preferences.pages.TagsPage", { osparc.utils.Utils.setIdToWidget(this.__addTagButton, "addTagBtn"); osparc.data.Resources.get("tags") .then(tags => { - this.__tagItems = tags.map(tag => new osparc.form.tag.TagItem().set({...tag})); + this.__tagItems = tags.map(tagData => { + const tag = new osparc.data.model.Tag(tagData); + return new osparc.form.tag.TagItem().set({ + tag + }); + }); this.__renderLayout(); this.__attachEventHandlers(); }) diff --git a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js index 822ff3391c7..a20bad6bedc 100644 --- a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js +++ b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js @@ -26,6 +26,14 @@ qx.Class.define("osparc.form.tag.TagItem", { }, properties: { + tag: { + check: "osparc.data.model.Tag", + nullable: false, + init: null, + event: "changeTag", + apply: "__applyTag", + }, + id: { check: "Integer" }, @@ -158,6 +166,14 @@ qx.Class.define("osparc.form.tag.TagItem", { return control || this.base(arguments, id); }, + __applyTag: function(tag) { + tag.bind("tagId", this, "id"); + tag.bind("name", this, "name"); + tag.bind("description", this, "description"); + tag.bind("color", this, "color"); + tag.bind("accessRights", this, "accessRights"); + }, + /** * Renders this tag item from scratch. */ From a30b321e6206588de9b231e30b59078d97253279 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 13:21:40 +0100 Subject: [PATCH 10/27] minor --- .../client/source/class/osparc/form/tag/TagManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/static-webserver/client/source/class/osparc/form/tag/TagManager.js b/services/static-webserver/client/source/class/osparc/form/tag/TagManager.js index ae3ef918adb..2fc7e81b97c 100644 --- a/services/static-webserver/client/source/class/osparc/form/tag/TagManager.js +++ b/services/static-webserver/client/source/class/osparc/form/tag/TagManager.js @@ -88,8 +88,8 @@ qx.Class.define("osparc.form.tag.TagManager", { newItem.addListener("tagSaved", () => this.__repopulateTags(), this); newItem.addListener("cancelNewTag", e => tagsContainer.remove(e.getTarget()), this); newItem.addListener("deleteTag", e => tagsContainer.remove(e.getTarget()), this); - this.__repopulateTags(); tagsContainer.add(newItem); + this.__repopulateTags(); }); this._add(addTagButton); From af1ae38b2a7543e74177de871af6bde8efafadaf Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 13:27:00 +0100 Subject: [PATCH 11/27] Tags store --- .../client/source/class/osparc/store/Tags.js | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 services/static-webserver/client/source/class/osparc/store/Tags.js diff --git a/services/static-webserver/client/source/class/osparc/store/Tags.js b/services/static-webserver/client/source/class/osparc/store/Tags.js new file mode 100644 index 00000000000..caa7da1d82e --- /dev/null +++ b/services/static-webserver/client/source/class/osparc/store/Tags.js @@ -0,0 +1,133 @@ +/* ************************************************************************ + + osparc - the simcore frontend + + https://osparc.io + + Copyright: + 2024 IT'IS Foundation, https://itis.swiss + + License: + MIT: https://opensource.org/licenses/MIT + + Authors: + * Odei Maiz (odeimaiz) + +************************************************************************ */ + +qx.Class.define("osparc.store.Tags", { + extend: qx.core.Object, + type: "singleton", + + construct: function() { + this.base(arguments); + + this.tagsCached = []; + }, + + events: { + "tagAdded": "qx.event.type.Data", + "tagRemoved": "qx.event.type.Data", + }, + + members: { + tagsCached: null, + + fetchTags: function() { + if (osparc.auth.Data.getInstance().isGuest()) { + return new Promise(resolve => { + resolve([]); + }); + } + + return osparc.data.Resources.get("tags") + .then(tagsData => { + const tags = []; + tagsData.forEach(tagData => { + const tag = this.__addToCache(tagData); + tags.push(tag); + }); + return tags; + }); + }, + + postTag: function(name, parentTagId = null, workspaceId = null) { + const newTagData = { + name, + parentTagId, + workspaceId, + }; + const params = { + data: newTagData + }; + return osparc.data.Resources.getInstance().fetch("tags", "post", params) + .then(tagData => { + const tag = this.__addToCache(tagData); + this.fireDataEvent("tagAdded", tag); + return tag; + }); + }, + + deleteTag: function(tagId, workspaceId) { + const params = { + "url": { + tagId + } + }; + return osparc.data.Resources.getInstance().fetch("tags", "delete", params) + .then(() => { + const tag = this.getTag(tagId); + if (tag) { + this.__deleteFromCache(tagId, workspaceId); + this.fireDataEvent("tagRemoved", tag); + } + }) + .catch(console.error); + }, + + putTag: function(tagId, updateData) { + const params = { + url: { + tagId + }, + data: updateData + }; + return osparc.data.Resources.getInstance().fetch("tags", "update", params) + .then(tagData => { + this.__addToCache(tagData); + }) + .catch(console.error); + }, + + getTag: function(tagId = null) { + return this.tagsCached.find(f => f.getTagId() === tagId); + }, + + __addToCache: function(tagData) { + let tag = this.tagsCached.find(f => f.getTagId() === tagData["tagId"] && f.getWorkspaceId() === tagData["workspaceId"]); + if (tag) { + const props = Object.keys(qx.util.PropertyUtil.getProperties(osparc.data.model.Tag)); + // put + Object.keys(tagData).forEach(key => { + if (props.includes(key)) { + tag.set(key, tagData[key]); + } + }); + } else { + // get and post + tag = new osparc.data.model.Tag(tagData); + this.tagsCached.unshift(tag); + } + return tag; + }, + + __deleteFromCache: function(tagId) { + const idx = this.tagsCached.findIndex(f => f.getTagId() === tagId); + if (idx > -1) { + this.tagsCached.splice(idx, 1); + return true; + } + return false; + } + } +}); From d945454500c13ea3a15a5ef6cf04bcd1e6ae11e4 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 13:44:12 +0100 Subject: [PATCH 12/27] fetch tags --- .../client/source/class/osparc/dashboard/Dashboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js b/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js index cc714440242..c73aff584fb 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js @@ -182,7 +182,7 @@ qx.Class.define("osparc.dashboard.Dashboard", { preResourcePromises.push(store.getAllGroupsAndMembers()); preResourcePromises.push(osparc.store.Services.getServicesLatest(false)); if (permissions.canDo("study.tag")) { - preResourcePromises.push(osparc.data.Resources.get("tags")); + preResourcePromises.push(osparc.store.Tags.getInstance().fetchTags()); } Promise.all(preResourcePromises) .then(() => { From 9dafd2417c0780aaa16de8e8e238d85c863f2abe Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 13:44:35 +0100 Subject: [PATCH 13/27] getTags --- .../osparc/desktop/preferences/pages/TagsPage.js | 16 ++++------------ .../client/source/class/osparc/store/Tags.js | 12 ++++++++---- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/desktop/preferences/pages/TagsPage.js b/services/static-webserver/client/source/class/osparc/desktop/preferences/pages/TagsPage.js index 06639a8619e..add2f2f3040 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/preferences/pages/TagsPage.js +++ b/services/static-webserver/client/source/class/osparc/desktop/preferences/pages/TagsPage.js @@ -48,18 +48,10 @@ qx.Class.define("osparc.desktop.preferences.pages.TagsPage", { icon: "@FontAwesome5Solid/plus/14" }); osparc.utils.Utils.setIdToWidget(this.__addTagButton, "addTagBtn"); - osparc.data.Resources.get("tags") - .then(tags => { - this.__tagItems = tags.map(tagData => { - const tag = new osparc.data.model.Tag(tagData); - return new osparc.form.tag.TagItem().set({ - tag - }); - }); - this.__renderLayout(); - this.__attachEventHandlers(); - }) - .catch(err => console.error(err)); + const tags = osparc.store.Tags.getInstance().getTags(); + this.__tagItems = tags.map(tag => new osparc.form.tag.TagItem().set({tag})); + this.__renderLayout(); + this.__attachEventHandlers(); }, __renderLayout: function() { diff --git a/services/static-webserver/client/source/class/osparc/store/Tags.js b/services/static-webserver/client/source/class/osparc/store/Tags.js index caa7da1d82e..89bd738f711 100644 --- a/services/static-webserver/client/source/class/osparc/store/Tags.js +++ b/services/static-webserver/client/source/class/osparc/store/Tags.js @@ -51,6 +51,10 @@ qx.Class.define("osparc.store.Tags", { }); }, + getTags: function() { + return this.tagsCached; + }, + postTag: function(name, parentTagId = null, workspaceId = null) { const newTagData = { name, @@ -68,9 +72,9 @@ qx.Class.define("osparc.store.Tags", { }); }, - deleteTag: function(tagId, workspaceId) { + deleteTag: function(tagId) { const params = { - "url": { + url: { tagId } }; @@ -78,7 +82,7 @@ qx.Class.define("osparc.store.Tags", { .then(() => { const tag = this.getTag(tagId); if (tag) { - this.__deleteFromCache(tagId, workspaceId); + this.__deleteFromCache(tagId); this.fireDataEvent("tagRemoved", tag); } }) @@ -104,7 +108,7 @@ qx.Class.define("osparc.store.Tags", { }, __addToCache: function(tagData) { - let tag = this.tagsCached.find(f => f.getTagId() === tagData["tagId"] && f.getWorkspaceId() === tagData["workspaceId"]); + let tag = this.tagsCached.find(f => f.getTagId() === tagData["tagId"]); if (tag) { const props = Object.keys(qx.util.PropertyUtil.getProperties(osparc.data.model.Tag)); // put From e019c162015fda2eea557faee9a27aeb4328583f Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 13:45:16 +0100 Subject: [PATCH 14/27] deleteTag --- .../client/source/class/osparc/form/tag/TagItem.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js index a20bad6bedc..c5e24d076c1 100644 --- a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js +++ b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js @@ -251,12 +251,7 @@ qx.Class.define("osparc.form.tag.TagItem", { editButton.addListener("execute", () => this.setMode(this.self().modes.EDIT), this); deleteButton.addListener("execute", () => { deleteButton.setFetching(true); - const params = { - url: { - tagId: this.getId() - } - }; - osparc.data.Resources.fetch("tags", "delete", params) + osparc.store.Tags.getInstance().deleteTag(this.getId()) .then(() => this.fireEvent("deleteTag")) .catch(console.error) .finally(() => deleteButton.setFetching(false)); From f8a57216e38a3d4085c31aaca92be36cb2050423 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 13:47:11 +0100 Subject: [PATCH 15/27] put and post Tag --- .../client/source/class/osparc/form/tag/TagItem.js | 4 ++-- .../client/source/class/osparc/store/Tags.js | 7 +------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js index c5e24d076c1..2d5e89deb67 100644 --- a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js +++ b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js @@ -287,9 +287,9 @@ qx.Class.define("osparc.form.tag.TagItem", { params.url = { tagId: this.getId() }; - fetch = osparc.data.Resources.fetch("tags", "put", params); + fetch = osparc.store.Tags.getInstance().putTag(this.getId(), data); } else { - fetch = osparc.data.Resources.fetch("tags", "post", params); + fetch = osparc.store.Tags.getInstance().postTag(data); } fetch .then(tag => this.set(tag)) diff --git a/services/static-webserver/client/source/class/osparc/store/Tags.js b/services/static-webserver/client/source/class/osparc/store/Tags.js index 89bd738f711..3de2ec04526 100644 --- a/services/static-webserver/client/source/class/osparc/store/Tags.js +++ b/services/static-webserver/client/source/class/osparc/store/Tags.js @@ -55,12 +55,7 @@ qx.Class.define("osparc.store.Tags", { return this.tagsCached; }, - postTag: function(name, parentTagId = null, workspaceId = null) { - const newTagData = { - name, - parentTagId, - workspaceId, - }; + postTag: function(newTagData) { const params = { data: newTagData }; From f939f833f1f654e57175f146575da3ced9f11536 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 13:56:24 +0100 Subject: [PATCH 16/27] cleanup --- .../client/source/class/osparc/form/tag/TagItem.js | 6 ------ .../client/source/class/osparc/store/Tags.js | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js index 2d5e89deb67..e67abc8c838 100644 --- a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js +++ b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js @@ -278,15 +278,9 @@ qx.Class.define("osparc.form.tag.TagItem", { saveButton.addListener("execute", () => { if (this.__validationManager.validate()) { const data = this.__serializeData(); - const params = { - data - }; saveButton.setFetching(true); let fetch; if (this.isPropertyInitialized("id")) { - params.url = { - tagId: this.getId() - }; fetch = osparc.store.Tags.getInstance().putTag(this.getId(), data); } else { fetch = osparc.store.Tags.getInstance().postTag(data); diff --git a/services/static-webserver/client/source/class/osparc/store/Tags.js b/services/static-webserver/client/source/class/osparc/store/Tags.js index 3de2ec04526..91f763bfdad 100644 --- a/services/static-webserver/client/source/class/osparc/store/Tags.js +++ b/services/static-webserver/client/source/class/osparc/store/Tags.js @@ -91,7 +91,7 @@ qx.Class.define("osparc.store.Tags", { }, data: updateData }; - return osparc.data.Resources.getInstance().fetch("tags", "update", params) + return osparc.data.Resources.getInstance().fetch("tags", "put", params) .then(tagData => { this.__addToCache(tagData); }) From 7bfb91379ecc734d283c086fc840368d06441bd8 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 14:04:46 +0100 Subject: [PATCH 17/27] put and post Tag --- .../client/source/class/osparc/form/tag/TagItem.js | 2 +- .../static-webserver/client/source/class/osparc/store/Tags.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js index e67abc8c838..77282a5db7f 100644 --- a/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js +++ b/services/static-webserver/client/source/class/osparc/form/tag/TagItem.js @@ -286,7 +286,7 @@ qx.Class.define("osparc.form.tag.TagItem", { fetch = osparc.store.Tags.getInstance().postTag(data); } fetch - .then(tag => this.set(tag)) + .then(tag => this.setTag(tag)) .catch(console.error) .finally(() => { this.fireEvent("tagSaved"); diff --git a/services/static-webserver/client/source/class/osparc/store/Tags.js b/services/static-webserver/client/source/class/osparc/store/Tags.js index 91f763bfdad..c47036686df 100644 --- a/services/static-webserver/client/source/class/osparc/store/Tags.js +++ b/services/static-webserver/client/source/class/osparc/store/Tags.js @@ -93,7 +93,7 @@ qx.Class.define("osparc.store.Tags", { }; return osparc.data.Resources.getInstance().fetch("tags", "put", params) .then(tagData => { - this.__addToCache(tagData); + return this.__addToCache(tagData); }) .catch(console.error); }, From 4141491c078d7a1d326ad45f6019d48c3cd8879c Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 14:20:21 +0100 Subject: [PATCH 18/27] osparc.ui.basic.Tag expects the model --- .../class/osparc/dashboard/GridButtonItem.js | 2 +- .../class/osparc/dashboard/ListButtonItem.js | 2 +- .../osparc/dashboard/ResourceContainerManager.js | 8 ++++---- .../client/source/class/osparc/info/StudyUtils.js | 2 +- .../client/source/class/osparc/ui/basic/Tag.js | 14 +++++++------- 5 files changed, 14 insertions(+), 14 deletions(-) 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 148a6b114bb..828a0c74ba7 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/GridButtonItem.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/GridButtonItem.js @@ -262,7 +262,7 @@ qx.Class.define("osparc.dashboard.GridButtonItem", { tagsContainer.setVisibility(tags.length ? "visible" : "excluded"); tagsContainer.removeAll(); tags.forEach(tag => { - const tagUI = new osparc.ui.basic.Tag(tag.name, tag.color, "searchBarFilter"); + const tagUI = new osparc.ui.basic.Tag(tag, "searchBarFilter"); tagUI.set({ font: "text-12", toolTipText: this.tr("Click to filter by this Tag") 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 e89e03a0943..71f59b970df 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ListButtonItem.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ListButtonItem.js @@ -237,7 +237,7 @@ qx.Class.define("osparc.dashboard.ListButtonItem", { const tagsContainer = this.getChildControl("tags"); tagsContainer.removeAll(); tags.forEach(tag => { - const tagUI = new osparc.ui.basic.Tag(tag.name, tag.color, "searchBarFilter"); + const tagUI = new osparc.ui.basic.Tag(tag, "searchBarFilter"); tagUI.set({ alignY: "middle", font: "text-12", diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js index b28b5d89a04..083a15fecd1 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js @@ -208,7 +208,7 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { }, __createCard: function(resourceData) { - const tags = resourceData.tags ? osparc.store.Store.getInstance().getTags().filter(tag => resourceData.tags.includes(tag.id)) : []; + const tags = resourceData.tags ? osparc.store.Store.getInstance().getTags().filter(tag => resourceData.tags.includes(tag.getTagId())) : []; const card = this.getMode() === "grid" ? new osparc.dashboard.GridButtonItem() : new osparc.dashboard.ListButtonItem(); card.set({ appearance: resourceData.type ? `pb-${resourceData.type}` : `pb-${resourceData.resourceType}`, @@ -434,7 +434,7 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { }, __groupByTags: function(cards, resourceData) { - const tags = resourceData.tags ? osparc.store.Store.getInstance().getTags().filter(tag => resourceData.tags.includes(tag.id)) : []; + const tags = resourceData.tags ? osparc.store.Store.getInstance().getTags().filter(tag => resourceData.tags.includes(tag.getTagId())) : []; if (tags.length === 0) { let noGroupContainer = this.__getGroupContainer("no-group"); const card = this.__createCard(resourceData); @@ -443,9 +443,9 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { cards.push(card); } else { tags.forEach(tag => { - let groupContainer = this.__getGroupContainer(tag.id); + let groupContainer = this.__getGroupContainer(tag.getTagId()); if (groupContainer === null) { - groupContainer = this.__createGroupContainer(tag.id, tag.name, tag.color); + groupContainer = this.__createGroupContainer(tag.getTagId(), tag.getName(), tag.getColor()); groupContainer.setHeaderIcon("@FontAwesome5Solid/tag/24"); this.__groupedContainers.add(groupContainer); this.__groupedContainers.getChildren().sort((a, b) => a.getHeaderLabel().localeCompare(b.getHeaderLabel())); diff --git a/services/static-webserver/client/source/class/osparc/info/StudyUtils.js b/services/static-webserver/client/source/class/osparc/info/StudyUtils.js index 95ea7f20b7f..45800343d6b 100644 --- a/services/static-webserver/client/source/class/osparc/info/StudyUtils.js +++ b/services/static-webserver/client/source/class/osparc/info/StudyUtils.js @@ -216,7 +216,7 @@ qx.Class.define("osparc.info.StudyUtils", { if (tagsContainer.indexOf(noTagsLabel) > -1) { tagsContainer.remove(noTagsLabel); } - tagsContainer.add(new osparc.ui.basic.Tag(selectedTag.name, selectedTag.color)); + tagsContainer.add(new osparc.ui.basic.Tag(selectedTag)); }); }; study.addListener("changeTags", () => addTags(study), this); diff --git a/services/static-webserver/client/source/class/osparc/ui/basic/Tag.js b/services/static-webserver/client/source/class/osparc/ui/basic/Tag.js index 4b23fc0efde..6ffb8c3b8aa 100644 --- a/services/static-webserver/client/source/class/osparc/ui/basic/Tag.js +++ b/services/static-webserver/client/source/class/osparc/ui/basic/Tag.js @@ -13,17 +13,17 @@ qx.Class.define("osparc.ui.basic.Tag", { extend: qx.ui.basic.Label, /** * Constructor for the Tag element. - * @param {String} value Short text to be shown on the tag - * @param {String} color Color for the background, must be in hex3 or hex6 form + * @param {osparc.data.model.Tag} tag Short text to be shown on the tag * @param {String} [filterGroupId] If present, clicking on the tab will dispatch a bus message with the * id ``GroupIdTagsTrigger`` to be subscribed by a filter. */ - construct: function(value, color, filterGroupId) { - this.base(arguments, value); + construct: function(tag, filterGroupId) { + this.base(arguments); + + tag.bind("name", this, "value"); + tag.bind("color", this, "color"); this.setFont("text-11"); - if (color) { - this.setColor(color); - } + if (filterGroupId) { this.setCursor("pointer"); this.addListener("tap", e => { From ac227d5bfe107b891e2b155beeb166aee6d27409 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 14:26:56 +0100 Subject: [PATCH 19/27] use won store and more modeling --- .../osparc/dashboard/ResourceContainerManager.js | 4 ++-- .../class/osparc/dashboard/ResourceFilter.js | 13 ++++++------- .../class/osparc/dashboard/SearchBarFilter.js | 15 ++++++++------- .../source/class/osparc/filter/UserTagsFilter.js | 2 +- .../source/class/osparc/form/tag/TagManager.js | 2 +- .../client/source/class/osparc/info/StudyUtils.js | 2 +- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js index 083a15fecd1..b1a71f6699c 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js @@ -208,7 +208,7 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { }, __createCard: function(resourceData) { - const tags = resourceData.tags ? osparc.store.Store.getInstance().getTags().filter(tag => resourceData.tags.includes(tag.getTagId())) : []; + const tags = resourceData.tags ? osparc.store.Tags.getInstance().getTags().filter(tag => resourceData.tags.includes(tag.getTagId())) : []; const card = this.getMode() === "grid" ? new osparc.dashboard.GridButtonItem() : new osparc.dashboard.ListButtonItem(); card.set({ appearance: resourceData.type ? `pb-${resourceData.type}` : `pb-${resourceData.resourceType}`, @@ -434,7 +434,7 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { }, __groupByTags: function(cards, resourceData) { - const tags = resourceData.tags ? osparc.store.Store.getInstance().getTags().filter(tag => resourceData.tags.includes(tag.getTagId())) : []; + const tags = resourceData.tags ? osparc.store.Tags.getInstance().getTags().filter(tag => resourceData.tags.includes(tag.getTagId())) : []; if (tags.length === 0) { let noGroupContainer = this.__getGroupContainer("no-group"); const card = this.__createCard(resourceData); diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceFilter.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceFilter.js index 142cdab7d3f..0c452e3e33a 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceFilter.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceFilter.js @@ -158,16 +158,15 @@ qx.Class.define("osparc.dashboard.ResourceFilter", { const maxTags = 5; this.__tagButtons = []; layout.removeAll(); - osparc.store.Store.getInstance().getTags().forEach((tag, idx) => { - const button = new qx.ui.form.ToggleButton(tag.name, "@FontAwesome5Solid/tag/18"); + osparc.store.Tags.getInstance().getTags().forEach((tag, idx) => { + const button = new qx.ui.form.ToggleButton(null, "@FontAwesome5Solid/tag/18"); + button.id = tag.getTagId(); + tag.bind("name", button, "label"); + tag.bind("color", button.getChildControl("icon"), "textColor"); osparc.utils.Utils.setIdToWidget(button, this.__resourceType + "-tagFilterItem"); - button.id = tag.id; button.set({ appearance: "filter-toggle-button", - value: selectedTagIds.includes(tag.id) - }); - button.getChildControl("icon").set({ - textColor: tag.color + value: selectedTagIds.includes(tag.getTagId()) }); layout.add(button); diff --git a/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js b/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js index b836a93ef44..a9af83630cb 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js @@ -208,14 +208,14 @@ qx.Class.define("osparc.dashboard.SearchBarFilter", { }, __addTags: function(menuButton) { - const tags = osparc.store.Store.getInstance().getTags(); + const tags = osparc.store.Tags.getInstance().getTags(); menuButton.setVisibility(tags.length ? "visible" : "excluded"); if (tags.length) { const tagsMenu = new qx.ui.menu.Menu(); osparc.utils.Utils.setIdToWidget(tagsMenu, "searchBarFilter-tags-menu"); tags.forEach(tag => { - const tagButton = new qx.ui.menu.Button(tag.name, "@FontAwesome5Solid/tag/12"); - tagButton.getChildControl("icon").setTextColor(tag.color); + const tagButton = new qx.ui.menu.Button(tag.getName(), "@FontAwesome5Solid/tag/12"); + tagButton.getChildControl("icon").setTextColor(tag.getColor()); tagsMenu.add(tagButton); tagButton.addListener("execute", () => this.addTagActiveFilter(tag), this); }); @@ -275,12 +275,13 @@ qx.Class.define("osparc.dashboard.SearchBarFilter", { }, setTagsActiveFilter: function(tagIds) { - const tags = osparc.store.Store.getInstance().getTags(); + const tags = osparc.store.Tags.getInstance().getTags(); tags.forEach(tag => { - if (tagIds.includes(tag.id)) { - this.__addChip("tag", tag.id, tag.name); + const tagId = tag.getTagId(); + if (tagIds.includes(tagId)) { + this.__addChip("tag", tag.id, tag.getName()); } else { - this.__removeChip("tag", tag.id, tag.name); + this.__removeChip("tag", tag.id, tag.getName()); } }); }, diff --git a/services/static-webserver/client/source/class/osparc/filter/UserTagsFilter.js b/services/static-webserver/client/source/class/osparc/filter/UserTagsFilter.js index c0a74265e01..f850e6eacc7 100644 --- a/services/static-webserver/client/source/class/osparc/filter/UserTagsFilter.js +++ b/services/static-webserver/client/source/class/osparc/filter/UserTagsFilter.js @@ -18,7 +18,7 @@ qx.Class.define("osparc.filter.UserTagsFilter", { }, members: { __buildMenu: function() { - osparc.store.Store.getInstance().getTags() + osparc.store.Tags.getInstance().getTags() .forEach(tag => { const menuButton = this._addOption(tag.name); menuButton.setIcon("@FontAwesome5Solid/square/12"); diff --git a/services/static-webserver/client/source/class/osparc/form/tag/TagManager.js b/services/static-webserver/client/source/class/osparc/form/tag/TagManager.js index 2fc7e81b97c..d33fe1d2f00 100644 --- a/services/static-webserver/client/source/class/osparc/form/tag/TagManager.js +++ b/services/static-webserver/client/source/class/osparc/form/tag/TagManager.js @@ -119,7 +119,7 @@ qx.Class.define("osparc.form.tag.TagManager", { __repopulateTags: function() { this.__tagsContainer.removeAll(); - const tags = osparc.store.Store.getInstance().getTags(); + const tags = osparc.store.Tags.getInstance().getTags(); tags.forEach(tag => this.__tagsContainer.add(this.__tagButton(tag))); }, diff --git a/services/static-webserver/client/source/class/osparc/info/StudyUtils.js b/services/static-webserver/client/source/class/osparc/info/StudyUtils.js index 45800343d6b..4221f58eccc 100644 --- a/services/static-webserver/client/source/class/osparc/info/StudyUtils.js +++ b/services/static-webserver/client/source/class/osparc/info/StudyUtils.js @@ -211,7 +211,7 @@ qx.Class.define("osparc.info.StudyUtils", { tagsContainer.removeAll(); const noTagsLabel = new qx.ui.basic.Label(qx.locale.Manager.tr("Add tags")); tagsContainer.add(noTagsLabel); - osparc.store.Store.getInstance().getTags().filter(tag => model.getTags().includes(tag.id)) + osparc.store.Tags.getInstance().getTags().filter(tag => model.getTags().includes(tag.id)) .forEach(selectedTag => { if (tagsContainer.indexOf(noTagsLabel) > -1) { tagsContainer.remove(noTagsLabel); From 64c1b191a4b08b6639d05b1fea54de66e9f0f120 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 14:30:14 +0100 Subject: [PATCH 20/27] minor --- .../client/source/class/osparc/dashboard/SearchBarFilter.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js b/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js index a9af83630cb..5b376a6b404 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/SearchBarFilter.js @@ -271,7 +271,7 @@ qx.Class.define("osparc.dashboard.SearchBarFilter", { }, addTagActiveFilter: function(tag) { - this.__addChip("tag", tag.id, tag.name); + this.__addChip("tag", tag.getTagId(), tag.getName()); }, setTagsActiveFilter: function(tagIds) { @@ -279,9 +279,9 @@ qx.Class.define("osparc.dashboard.SearchBarFilter", { tags.forEach(tag => { const tagId = tag.getTagId(); if (tagIds.includes(tagId)) { - this.__addChip("tag", tag.id, tag.getName()); + this.__addChip("tag", tagId, tag.getName()); } else { - this.__removeChip("tag", tag.id, tag.getName()); + this.__removeChip("tag", tagId, tag.getName()); } }); }, From 9596adc529cd10da6eeeaf1a9469c75bd45a5540 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 14:41:00 +0100 Subject: [PATCH 21/27] minor --- .../client/source/class/osparc/dashboard/CardBase.js | 2 +- 1 file changed, 1 insertion(+), 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 8d59dee3728..06c61abb026 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js @@ -926,7 +926,7 @@ qx.Class.define("osparc.dashboard.CardBase", { }, _filterTags: function(tags) { - const checks = this.getTags().map(tag => tag.id); + const checks = this.getTags().map(tag => tag.getId()); return this.self().filterTags(checks, tags); }, From baa4bf5beada114797d5e84da5c30fa509c3dec2 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 14:42:04 +0100 Subject: [PATCH 22/27] minor fix --- .../client/source/class/osparc/dashboard/CardBase.js | 2 +- 1 file changed, 1 insertion(+), 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 06c61abb026..1b7a8fe6e82 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/CardBase.js @@ -926,7 +926,7 @@ qx.Class.define("osparc.dashboard.CardBase", { }, _filterTags: function(tags) { - const checks = this.getTags().map(tag => tag.getId()); + const checks = this.getTags().map(tag => tag.getTagId()); return this.self().filterTags(checks, tags); }, From 7b555a882374cf3be1551b0aaf23cb827776945a Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 14:56:02 +0100 Subject: [PATCH 23/27] modeling --- .../client/source/class/osparc/form/tag/TagManager.js | 11 ++++++----- .../source/class/osparc/form/tag/TagToggleButton.js | 8 ++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/form/tag/TagManager.js b/services/static-webserver/client/source/class/osparc/form/tag/TagManager.js index d33fe1d2f00..6f704c1f222 100644 --- a/services/static-webserver/client/source/class/osparc/form/tag/TagManager.js +++ b/services/static-webserver/client/source/class/osparc/form/tag/TagManager.js @@ -124,20 +124,21 @@ qx.Class.define("osparc.form.tag.TagManager", { }, __tagButton: function(tag) { - const tagButton = new osparc.form.tag.TagToggleButton(tag, this.__selectedTags.includes(tag.id)); + const tagId = tag.getTagId(); + const tagButton = new osparc.form.tag.TagToggleButton(tag, this.__selectedTags.includes(tagId)); tagButton.addListener("changeValue", evt => { const selected = evt.getData(); if (this.isLiveUpdate()) { tagButton.setFetching(true); if (selected) { - this.__saveAddTag(tag.id, tagButton); + this.__saveAddTag(tagId, tagButton); } else { - this.__saveRemoveTag(tag.id, tagButton); + this.__saveRemoveTag(tagId, tagButton); } } else if (selected) { - this.__selectedTags.push(tag.id); + this.__selectedTags.push(tagId); } else { - this.__selectedTags.remove(tag.id); + this.__selectedTags.remove(tagId); } }, this); tagButton.subscribeToFilterGroup("studyBrowserTagManager"); diff --git a/services/static-webserver/client/source/class/osparc/form/tag/TagToggleButton.js b/services/static-webserver/client/source/class/osparc/form/tag/TagToggleButton.js index 3075d738cf3..35feee0c3bc 100644 --- a/services/static-webserver/client/source/class/osparc/form/tag/TagToggleButton.js +++ b/services/static-webserver/client/source/class/osparc/form/tag/TagToggleButton.js @@ -23,11 +23,11 @@ qx.Class.define("osparc.form.tag.TagToggleButton", { appearance: "tagbutton" }); this.setIcon("@FontAwesome5Solid/square/14"); - this.getChildControl("icon").setTextColor(tag.color); - if (tag.description) { - this.setLabel(tag.name + " : " + tag.description); + this.getChildControl("icon").setTextColor(tag.getColor()); + if (tag.getDescription()) { + this.setLabel(tag.getName() + " : " + tag.getDescription()); } else { - this.setLabel(tag.name); + this.setLabel(tag.getName()); } this.getChildControl("check"); From 7b206d12cebd58bdf63332ccdf33a36021d0c499 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 15:03:57 +0100 Subject: [PATCH 24/27] fixes --- .../client/source/class/osparc/store/Tags.js | 2 +- .../client/source/class/osparc/ui/basic/Tag.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/store/Tags.js b/services/static-webserver/client/source/class/osparc/store/Tags.js index c47036686df..4ffd9f5cd4f 100644 --- a/services/static-webserver/client/source/class/osparc/store/Tags.js +++ b/services/static-webserver/client/source/class/osparc/store/Tags.js @@ -103,7 +103,7 @@ qx.Class.define("osparc.store.Tags", { }, __addToCache: function(tagData) { - let tag = this.tagsCached.find(f => f.getTagId() === tagData["tagId"]); + let tag = this.tagsCached.find(f => f.getTagId() === tagData["id"]); if (tag) { const props = Object.keys(qx.util.PropertyUtil.getProperties(osparc.data.model.Tag)); // put diff --git a/services/static-webserver/client/source/class/osparc/ui/basic/Tag.js b/services/static-webserver/client/source/class/osparc/ui/basic/Tag.js index 6ffb8c3b8aa..64930674e25 100644 --- a/services/static-webserver/client/source/class/osparc/ui/basic/Tag.js +++ b/services/static-webserver/client/source/class/osparc/ui/basic/Tag.js @@ -20,8 +20,10 @@ qx.Class.define("osparc.ui.basic.Tag", { construct: function(tag, filterGroupId) { this.base(arguments); - tag.bind("name", this, "value"); - tag.bind("color", this, "color"); + if (tag) { + tag.bind("name", this, "value"); + tag.bind("color", this, "color"); + } this.setFont("text-11"); if (filterGroupId) { From 7a2a53fb1eaa7e7b240bb20ae16a80483faf6320 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 15:08:06 +0100 Subject: [PATCH 25/27] minor --- .../source/class/osparc/dashboard/ResourceContainerManager.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js b/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js index b1a71f6699c..fa99ba050dd 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/ResourceContainerManager.js @@ -446,6 +446,8 @@ qx.Class.define("osparc.dashboard.ResourceContainerManager", { let groupContainer = this.__getGroupContainer(tag.getTagId()); if (groupContainer === null) { groupContainer = this.__createGroupContainer(tag.getTagId(), tag.getName(), tag.getColor()); + tag.bind("name", groupContainer, "headerLabel"); + tag.bind("color", groupContainer, "headerColor"); groupContainer.setHeaderIcon("@FontAwesome5Solid/tag/24"); this.__groupedContainers.add(groupContainer); this.__groupedContainers.getChildren().sort((a, b) => a.getHeaderLabel().localeCompare(b.getHeaderLabel())); From 1c0ec1cd322fa17c76f12ac43556dd0235d87c6b Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 15:24:44 +0100 Subject: [PATCH 26/27] fetch Tags once --- .../client/source/class/osparc/dashboard/Dashboard.js | 3 --- .../client/source/class/osparc/desktop/MainPage.js | 2 +- .../client/source/class/osparc/desktop/MainPageDesktop.js | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js b/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js index c73aff584fb..4a1420ade43 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/Dashboard.js @@ -181,9 +181,6 @@ qx.Class.define("osparc.dashboard.Dashboard", { const store = osparc.store.Store.getInstance(); preResourcePromises.push(store.getAllGroupsAndMembers()); preResourcePromises.push(osparc.store.Services.getServicesLatest(false)); - if (permissions.canDo("study.tag")) { - preResourcePromises.push(osparc.store.Tags.getInstance().fetchTags()); - } Promise.all(preResourcePromises) .then(() => { [ diff --git a/services/static-webserver/client/source/class/osparc/desktop/MainPage.js b/services/static-webserver/client/source/class/osparc/desktop/MainPage.js index d2b72acfdcc..0ccb9bbe8b9 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/MainPage.js +++ b/services/static-webserver/client/source/class/osparc/desktop/MainPage.js @@ -66,7 +66,7 @@ qx.Class.define("osparc.desktop.MainPage", { preloadPromises.push(store.reloadWallets()); } preloadPromises.push(store.getAllClassifiers(true)); - preloadPromises.push(store.getTags()); + preloadPromises.push(osparc.store.Tags.getInstance().fetchTags()); Promise.all(preloadPromises) .then(() => { const mainStack = this.__createMainStack(); diff --git a/services/static-webserver/client/source/class/osparc/desktop/MainPageDesktop.js b/services/static-webserver/client/source/class/osparc/desktop/MainPageDesktop.js index 93f5f50c74d..40c99616a40 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/MainPageDesktop.js +++ b/services/static-webserver/client/source/class/osparc/desktop/MainPageDesktop.js @@ -61,7 +61,7 @@ qx.Class.define("osparc.desktop.MainPageDesktop", { preloadPromises.push(store.reloadWallets()); } preloadPromises.push(store.getAllClassifiers(true)); - preloadPromises.push(store.getTags()); + preloadPromises.push(osparc.store.Tags.getInstance().fetchTags()); Promise.all(preloadPromises) .then(() => { const desktopCenter = new osparc.desktop.credits.DesktopCenter(); From 7a3f8a8858259d402edc4a44831c357589ebfa18 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Thu, 14 Nov 2024 15:24:50 +0100 Subject: [PATCH 27/27] minor fixes --- .../client/source/class/osparc/filter/UserTagsFilter.js | 4 ++-- .../client/source/class/osparc/info/StudyUtils.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/filter/UserTagsFilter.js b/services/static-webserver/client/source/class/osparc/filter/UserTagsFilter.js index f850e6eacc7..caf5914e5d3 100644 --- a/services/static-webserver/client/source/class/osparc/filter/UserTagsFilter.js +++ b/services/static-webserver/client/source/class/osparc/filter/UserTagsFilter.js @@ -20,9 +20,9 @@ qx.Class.define("osparc.filter.UserTagsFilter", { __buildMenu: function() { osparc.store.Tags.getInstance().getTags() .forEach(tag => { - const menuButton = this._addOption(tag.name); + const menuButton = this._addOption(tag.getName()); menuButton.setIcon("@FontAwesome5Solid/square/12"); - menuButton.getChildControl("icon").setTextColor(tag.color); + menuButton.getChildControl("icon").setTextColor(tag.getColor()); }); }, __attachEventListeners: function(filterId, filterGroupId) { diff --git a/services/static-webserver/client/source/class/osparc/info/StudyUtils.js b/services/static-webserver/client/source/class/osparc/info/StudyUtils.js index 4221f58eccc..f1d2c3449e5 100644 --- a/services/static-webserver/client/source/class/osparc/info/StudyUtils.js +++ b/services/static-webserver/client/source/class/osparc/info/StudyUtils.js @@ -211,7 +211,7 @@ qx.Class.define("osparc.info.StudyUtils", { tagsContainer.removeAll(); const noTagsLabel = new qx.ui.basic.Label(qx.locale.Manager.tr("Add tags")); tagsContainer.add(noTagsLabel); - osparc.store.Tags.getInstance().getTags().filter(tag => model.getTags().includes(tag.id)) + osparc.store.Tags.getInstance().getTags().filter(tag => model.getTags().includes(tag.getTagId())) .forEach(selectedTag => { if (tagsContainer.indexOf(noTagsLabel) > -1) { tagsContainer.remove(noTagsLabel);