From 9bfc1b34d6c15ffe0d19a18c5250a2f5ee77d821 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 14:03:48 +0100 Subject: [PATCH 01/17] add resource_id to notifications --- .../client/source/class/osparc/notification/Notifications.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/static-webserver/client/source/class/osparc/notification/Notifications.js b/services/static-webserver/client/source/class/osparc/notification/Notifications.js index 2f7ab34c146..0dc8fcaa70c 100644 --- a/services/static-webserver/client/source/class/osparc/notification/Notifications.js +++ b/services/static-webserver/client/source/class/osparc/notification/Notifications.js @@ -38,6 +38,7 @@ qx.Class.define("osparc.notification.Notifications", { const specNotification = { "category": "NEW_ORGANIZATION", "actionable_path": "organization/"+orgId, + "resource_id": orgId, "title": "New organization", "text": "You're now member of a new Organization" }; @@ -55,6 +56,7 @@ qx.Class.define("osparc.notification.Notifications", { const specNotification = { "category": "STUDY_SHARED", "actionable_path": "study/"+studyId, + "resource_id": studyId, "title": `${study} shared`, "text": `A ${study} was shared with you` }; @@ -72,6 +74,7 @@ qx.Class.define("osparc.notification.Notifications", { const specNotification = { "category": "TEMPLATE_SHARED", "actionable_path": "template/"+templateId, + "resource_id": templateId, "title": `${template} shared`, "text": `A ${template} was shared with you` }; @@ -86,6 +89,7 @@ qx.Class.define("osparc.notification.Notifications", { const specNotification = { "category": "ANNOTATION_NOTE", "actionable_path": "study/"+studyId, + "resource_id": studyId, "title": "Note added", "text": "A Note was added for you" }; @@ -100,6 +104,7 @@ qx.Class.define("osparc.notification.Notifications", { const specNotification = { "category": "WALLET_SHARED", "actionable_path": "wallet/"+walletId, + "resource_id": walletId, "title": "Credits shared", "text": "A Credit Account was shared with you" }; From 293dabe50e590f3759e49b8e183d9ef0eb0f6775 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 14:20:06 +0100 Subject: [PATCH 02/17] user_from_id --- .../client/source/class/osparc/notification/Notifications.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/static-webserver/client/source/class/osparc/notification/Notifications.js b/services/static-webserver/client/source/class/osparc/notification/Notifications.js index 0dc8fcaa70c..2ad082a3715 100644 --- a/services/static-webserver/client/source/class/osparc/notification/Notifications.js +++ b/services/static-webserver/client/source/class/osparc/notification/Notifications.js @@ -29,7 +29,8 @@ qx.Class.define("osparc.notification.Notifications", { return { "user_id": userId.toString(), "date": new Date().toISOString(), - "product": osparc.product.Utils.getProductName() + "product": osparc.product.Utils.getProductName(), + "user_from_id": osparc.auth.Data.getInstance().getUserId(), }; }, From 098165f463498844d1ac020745d4c29a66e5a929 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 14:29:08 +0100 Subject: [PATCH 03/17] update model --- .../src/simcore_service_webserver/users/_notifications.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/web/server/src/simcore_service_webserver/users/_notifications.py b/services/web/server/src/simcore_service_webserver/users/_notifications.py index 256e521f89c..0da6ebc2be3 100644 --- a/services/web/server/src/simcore_service_webserver/users/_notifications.py +++ b/services/web/server/src/simcore_service_webserver/users/_notifications.py @@ -26,8 +26,10 @@ class NotificationCategory(StrAutoEnum): class BaseUserNotification(BaseModel): user_id: UserID + user_from_id: Literal[None] | UserID = None category: NotificationCategory actionable_path: str + resource_id: Literal[""] | str = "" title: str text: str date: datetime From 16be2993fbe8ccc9c91c833ab0de529c195e935c Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 15:11:35 +0100 Subject: [PATCH 04/17] init properties --- .../class/osparc/notification/Notification.js | 16 ++++++++++++++++ .../class/osparc/notification/Notifications.js | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/services/static-webserver/client/source/class/osparc/notification/Notification.js b/services/static-webserver/client/source/class/osparc/notification/Notification.js index 37f102e466f..af219894c0f 100644 --- a/services/static-webserver/client/source/class/osparc/notification/Notification.js +++ b/services/static-webserver/client/source/class/osparc/notification/Notification.js @@ -23,10 +23,12 @@ qx.Class.define("osparc.notification.Notification", { this.set({ id: notificationObj.id, + resourceId: notificationObj.resource_id ? notificationObj.resource_id : null, category: notificationObj.category, actionablePath: notificationObj.actionable_path, title: notificationObj.title, text: notificationObj.text, + userFromId: notificationObj.user_from_id ? notificationObj.user_from_id : null, date: new Date(notificationObj.date), read: ["true", "True", true].includes(notificationObj.read) }); @@ -40,6 +42,13 @@ qx.Class.define("osparc.notification.Notification", { event: "changeId" }, + resourceId: { + check: "String", + init: null, + nullable: true, + event: "changeResourceId" + }, + category: { check: [ "NEW_ORGANIZATION", @@ -74,6 +83,13 @@ qx.Class.define("osparc.notification.Notification", { event: "changeText" }, + userFromId: { + check: "Number", + init: null, + nullable: true, + event: "changeUserFromId" + }, + date: { check: "Date", init: null, diff --git a/services/static-webserver/client/source/class/osparc/notification/Notifications.js b/services/static-webserver/client/source/class/osparc/notification/Notifications.js index 2ad082a3715..6c4ecb00d35 100644 --- a/services/static-webserver/client/source/class/osparc/notification/Notifications.js +++ b/services/static-webserver/client/source/class/osparc/notification/Notifications.js @@ -28,9 +28,9 @@ qx.Class.define("osparc.notification.Notifications", { __newNotificationBase: function(userId) { return { "user_id": userId.toString(), + "user_from_id": osparc.auth.Data.getInstance().getUserId(), "date": new Date().toISOString(), "product": osparc.product.Utils.getProductName(), - "user_from_id": osparc.auth.Data.getInstance().getUserId(), }; }, From 291d9450cd39510344055c03fef04aeea6a0e33a Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 15:48:47 +0100 Subject: [PATCH 05/17] refactoring --- .../class/osparc/dashboard/StudyBrowser.js | 5 ++ .../class/osparc/desktop/MainPageDesktop.js | 48 +++++++++---------- .../source/class/osparc/info/CommentUI.js | 14 +++--- .../class/osparc/navigation/NavigationBar.js | 12 +---- .../client/source/class/osparc/store/Store.js | 16 ++----- 5 files changed, 41 insertions(+), 54 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js index 804986735a7..18ecdc933d3 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js @@ -115,6 +115,11 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { } // "Starting..." page this._hideLoadingPage(); + + osparc.data.Resources.get("notifications") + .then(notifications => { + osparc.notification.Notifications.getInstance().addNotifications(notifications); + }); }) .catch(err => { console.error(err); 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 e39b9c72357..93f5f50c74d 100644 --- a/services/static-webserver/client/source/class/osparc/desktop/MainPageDesktop.js +++ b/services/static-webserver/client/source/class/osparc/desktop/MainPageDesktop.js @@ -26,31 +26,29 @@ qx.Class.define("osparc.desktop.MainPageDesktop", { this._add(osparc.notification.RibbonNotifications.getInstance()); const navBar = new osparc.navigation.NavigationBar(); - navBar.populateLayout() - .then(() => { - // exclude some items from the navigation bar - navBar.getChildControl("dashboard-label").exclude(); - navBar.getChildControl("dashboard-button").exclude(); - navBar.getChildControl("notifications-button").exclude(); - navBar.getChildControl("help").exclude(); - - // exclude all the menu entries except "log-out" from user menu - const userMenuButton = navBar.getChildControl("user-menu"); - const userMenu = userMenuButton.getMenu(); - // eslint-disable-next-line no-underscore-dangle - const userMenuEntries = userMenu._getCreatedChildControls(); - Object.entries(userMenuEntries).forEach(([id, userMenuEntry]) => { - if (!["mini-profile-view", "po-center", "log-out"].includes(id)) { - userMenuEntry.exclude(); - } - }); - // exclude also the separators - userMenu.getChildren().forEach(child => { - if (child.classname === "qx.ui.menu.Separator") { - child.exclude(); - } - }); - }); + navBar.populateLayout(); + // exclude some items from the navigation bar + navBar.getChildControl("dashboard-label").exclude(); + navBar.getChildControl("dashboard-button").exclude(); + navBar.getChildControl("notifications-button").exclude(); + navBar.getChildControl("help").exclude(); + + // exclude all the menu entries except "log-out" from user menu + const userMenuButton = navBar.getChildControl("user-menu"); + const userMenu = userMenuButton.getMenu(); + // eslint-disable-next-line no-underscore-dangle + const userMenuEntries = userMenu._getCreatedChildControls(); + Object.entries(userMenuEntries).forEach(([id, userMenuEntry]) => { + if (!["mini-profile-view", "po-center", "log-out"].includes(id)) { + userMenuEntry.exclude(); + } + }); + // exclude also the separators + userMenu.getChildren().forEach(child => { + if (child.classname === "qx.ui.menu.Separator") { + child.exclude(); + } + }); this._add(navBar); osparc.MaintenanceTracker.getInstance().startTracker(); diff --git a/services/static-webserver/client/source/class/osparc/info/CommentUI.js b/services/static-webserver/client/source/class/osparc/info/CommentUI.js index 47a005cdb12..62871860da6 100644 --- a/services/static-webserver/client/source/class/osparc/info/CommentUI.js +++ b/services/static-webserver/client/source/class/osparc/info/CommentUI.js @@ -117,14 +117,12 @@ qx.Class.define("osparc.info.CommentUI", { const commentContent = this.getChildControl("comment-content"); commentContent.setValue(this.__comment["contents"]); - osparc.store.Store.getInstance().getUser(this.__comment["user_id"]) - .then(user => { - if (user) { - const userSource = osparc.utils.Avatar.getUrl(user["login"], 32); - thumbnail.setSource(userSource); - userName.setValue(user["label"]); - } - }); + const user = osparc.store.Store.getInstance().getUser(this.__comment["user_id"]) + if (user) { + const userSource = osparc.utils.Avatar.getUrl(user["login"], 32); + thumbnail.setSource(userSource); + userName.setValue(user["label"]); + } } } }); diff --git a/services/static-webserver/client/source/class/osparc/navigation/NavigationBar.js b/services/static-webserver/client/source/class/osparc/navigation/NavigationBar.js index d3b00b12978..9397aed32e8 100644 --- a/services/static-webserver/client/source/class/osparc/navigation/NavigationBar.js +++ b/services/static-webserver/client/source/class/osparc/navigation/NavigationBar.js @@ -92,16 +92,8 @@ qx.Class.define("osparc.navigation.NavigationBar", { __tabButtons: null, populateLayout: function() { - return new Promise(resolve => { - osparc.data.Resources.get("notifications") - .then(notifications => { - osparc.notification.Notifications.getInstance().addNotifications(notifications); - this.__buildLayout(); - osparc.WindowSizeTracker.getInstance().addListener("changeCompactVersion", () => this.__navBarResized(), this); - resolve(); - }) - .catch(err => console.error(err)); - }); + this.__buildLayout(); + osparc.WindowSizeTracker.getInstance().addListener("changeCompactVersion", () => this.__navBarResized(), this); }, __buildLayout: function() { diff --git a/services/static-webserver/client/source/class/osparc/store/Store.js b/services/static-webserver/client/source/class/osparc/store/Store.js index 3a180897e28..435d3e2204f 100644 --- a/services/static-webserver/client/source/class/osparc/store/Store.js +++ b/services/static-webserver/client/source/class/osparc/store/Store.js @@ -626,17 +626,11 @@ qx.Class.define("osparc.store.Store", { }, getUser: function(uid) { - return new Promise(resolve => { - if (uid) { - this.getReachableMembers() - .then(visibleMembers => { - resolve(Object.values(visibleMembers).find(member => member.id === uid)); - }) - .catch(() => resolve(null)); - } else { - resolve(null); - } - }); + if (uid) { + const visibleMembers = this.getReachableMembers(); + return Object.values(visibleMembers).find(member => member.id === uid); + } + return null; }, reloadCreditPrice: function() { From 7c5a3aa2d057ea79cfdd6adeefbce6f29dafff19 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 15:48:54 +0100 Subject: [PATCH 06/17] show proper message --- .../osparc/notification/NotificationUI.js | 91 +++++++++++++------ 1 file changed, 63 insertions(+), 28 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 6ed2ee9356a..481124d0e28 100644 --- a/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js +++ b/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js @@ -112,37 +112,72 @@ qx.Class.define("osparc.notification.NotificationUI", { return control || this.base(arguments, id); }, - __applyNotification: function(notification) { - const icon = this.getChildControl("icon"); - notification.bind("category", icon, "source", { - converter: value => { - let source = ""; - switch (value) { - case "NEW_ORGANIZATION": - source = "@FontAwesome5Solid/users/14"; - break; - case "STUDY_SHARED": - source = "@FontAwesome5Solid/file/14"; - break; - case "TEMPLATE_SHARED": - source = "@FontAwesome5Solid/copy/14"; - break; - case "ANNOTATION_NOTE": - source = "@FontAwesome5Solid/file/14"; - break; - case "WALLET_SHARED": - source = "@MaterialIcons/account_balance_wallet/14"; - break; + __applyNotification: async function(notification) { + console.log("notification", notification); + let resourceId = null; + if (notification.getResourceId()) { + resourceId = notification.getResourceId(); + } else if (notification.getActionablePath()) { + // extract it from the actionable path + const actionablePath = notification.getActionablePath(); + resourceId = actionablePath.split("/")[1]; + } + const userFromId = notification.getUserFromId(); + + let source = ""; + let title = ""; + let description = ""; + switch (notification.getCategory()) { + case "NEW_ORGANIZATION": + source = "@FontAwesome5Solid/users/14"; + if (resourceId) { + const group = await osparc.store.Store.getInstance().getGroup(resourceId); + title = group["name"]; } - return source; - } - }); + break; + case "STUDY_SHARED": + source = "@FontAwesome5Solid/file/14"; + if (resourceId) { + const params = { + url: { + "studyId": resourceId + } + }; + const study = await osparc.data.Resources.getOne("studies", params); + const studyAlias = osparc.product.Utils.getStudyAlias({ + firstUpperCase: true + }); + if (study) { + title = `${studyAlias} ${study["name"]}`; + } else { + title = `${studyAlias} shared`; + } + } + if (userFromId) { + const user = osparc.store.Store.getInstance().getUser(userFromId); + if (user) { + description = "was shared by " + user["label"]; + } + } + break; + case "TEMPLATE_SHARED": + source = "@FontAwesome5Solid/copy/14"; + break; + case "ANNOTATION_NOTE": + source = "@FontAwesome5Solid/file/14"; + break; + case "WALLET_SHARED": + source = "@MaterialIcons/account_balance_wallet/14"; + break; + } + const icon = this.getChildControl("icon"); + icon.setSource(source); - const title = this.getChildControl("title"); - notification.bind("title", title, "value"); + const titleLabel = this.getChildControl("title"); + titleLabel.setValue(title ? title : notification.getTitle()); - const text = this.getChildControl("text"); - notification.bind("text", text, "value"); + const descriptionLabel = this.getChildControl("text"); + descriptionLabel.setValue(description ? description : notification.getText()); const date = this.getChildControl("date"); notification.bind("date", date, "value", { From 0a237fa481f43edb695b56de02efe4394a8d4d09 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 15:58:58 +0100 Subject: [PATCH 07/17] getTemplate --- .../client/source/class/osparc/store/Store.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/static-webserver/client/source/class/osparc/store/Store.js b/services/static-webserver/client/source/class/osparc/store/Store.js index 435d3e2204f..0e015ed7811 100644 --- a/services/static-webserver/client/source/class/osparc/store/Store.js +++ b/services/static-webserver/client/source/class/osparc/store/Store.js @@ -427,6 +427,11 @@ qx.Class.define("osparc.store.Store", { } }, + getTemplate: function(templateId) { + const templates = this.getTemplates(); + return templates.find(template => template["uuid"] === templateId); + }, + deleteStudy: function(studyId) { const params = { url: { From ba14a419086d9fac927931cbb763351afecf5efd Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 15:59:11 +0100 Subject: [PATCH 08/17] shared template texts --- .../osparc/notification/NotificationUI.js | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) 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 481124d0e28..b51ab80932d 100644 --- a/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js +++ b/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js @@ -162,6 +162,28 @@ qx.Class.define("osparc.notification.NotificationUI", { break; case "TEMPLATE_SHARED": source = "@FontAwesome5Solid/copy/14"; + if (resourceId) { + const params = { + url: { + "studyId": resourceId + } + }; + const template = osparc.store.Store.getInstance().getTemplate(params); + const templateAlias = osparc.product.Utils.getTemplateAlias({ + firstUpperCase: true + }); + if (template) { + title = `${templateAlias} ${template["name"]}`; + } else { + title = `${templateAlias} shared`; + } + } + if (userFromId) { + const user = osparc.store.Store.getInstance().getUser(userFromId); + if (user) { + description = "was shared by " + user["label"]; + } + } break; case "ANNOTATION_NOTE": source = "@FontAwesome5Solid/file/14"; From ed08d7a8aa42fae592c98f91059d81c339f8a793 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 16:13:32 +0100 Subject: [PATCH 09/17] template title --- .../source/class/osparc/notification/NotificationUI.js | 7 +------ 1 file changed, 1 insertion(+), 6 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 b51ab80932d..8002626a2f7 100644 --- a/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js +++ b/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js @@ -163,12 +163,7 @@ qx.Class.define("osparc.notification.NotificationUI", { case "TEMPLATE_SHARED": source = "@FontAwesome5Solid/copy/14"; if (resourceId) { - const params = { - url: { - "studyId": resourceId - } - }; - const template = osparc.store.Store.getInstance().getTemplate(params); + const template = osparc.store.Store.getInstance().getTemplate(resourceId); const templateAlias = osparc.product.Utils.getTemplateAlias({ firstUpperCase: true }); From 3c823770247b59ec96e3f355906000d220ba7884 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 16:59:09 +0100 Subject: [PATCH 10/17] enrich Note as well --- .../class/osparc/notification/NotificationUI.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) 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 8002626a2f7..a396e6e6289 100644 --- a/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js +++ b/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js @@ -182,6 +182,23 @@ qx.Class.define("osparc.notification.NotificationUI", { break; case "ANNOTATION_NOTE": source = "@FontAwesome5Solid/file/14"; + if (resourceId) { + const params = { + url: { + "studyId": resourceId + } + }; + const study = await osparc.data.Resources.getOne("studies", params); + if (study) { + title = `Note added in ${study["name"]}`; + } + } + if (userFromId) { + const user = osparc.store.Store.getInstance().getUser(userFromId); + if (user) { + description = "It was added by " + user["label"]; + } + } break; case "WALLET_SHARED": source = "@MaterialIcons/account_balance_wallet/14"; From 2119b63345fc88cdd70e8acc84925d915d09b914 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 17:03:08 +0100 Subject: [PATCH 11/17] also orgs --- .../class/osparc/notification/NotificationUI.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 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 a396e6e6289..2d6fcc02c40 100644 --- a/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js +++ b/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js @@ -132,7 +132,7 @@ qx.Class.define("osparc.notification.NotificationUI", { source = "@FontAwesome5Solid/users/14"; if (resourceId) { const group = await osparc.store.Store.getInstance().getGroup(resourceId); - title = group["name"]; + description = "You're now member of '" + group["name"] + "'"; } break; case "STUDY_SHARED": @@ -148,9 +148,7 @@ qx.Class.define("osparc.notification.NotificationUI", { firstUpperCase: true }); if (study) { - title = `${studyAlias} ${study["name"]}`; - } else { - title = `${studyAlias} shared`; + title = `${studyAlias} '${study["name"]}'`; } } if (userFromId) { @@ -168,9 +166,7 @@ qx.Class.define("osparc.notification.NotificationUI", { firstUpperCase: true }); if (template) { - title = `${templateAlias} ${template["name"]}`; - } else { - title = `${templateAlias} shared`; + title = `${templateAlias} '${template["name"]}'`; } } if (userFromId) { @@ -190,13 +186,13 @@ qx.Class.define("osparc.notification.NotificationUI", { }; const study = await osparc.data.Resources.getOne("studies", params); if (study) { - title = `Note added in ${study["name"]}`; + title = `Note added in '${study["name"]}'`; } } if (userFromId) { const user = osparc.store.Store.getInstance().getUser(userFromId); if (user) { - description = "It was added by " + user["label"]; + description = "was added by " + user["label"]; } } break; From cde23dd89581d8091965bdeed4a880245aafe7f2 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 17:18:31 +0100 Subject: [PATCH 12/17] markAsRead --- .../osparc/notification/NotificationUI.js | 15 +-------------- .../osparc/notification/Notifications.js | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 15 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 2d6fcc02c40..d4a5b8ba11b 100644 --- a/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js +++ b/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js @@ -232,20 +232,7 @@ qx.Class.define("osparc.notification.NotificationUI", { this.fireEvent("notificationTapped"); - if (notification.isRead() === false) { - // set as read - const params = { - url: { - notificationId: notification.getId() - }, - data: { - "read": true - } - }; - osparc.data.Resources.fetch("notifications", "patch", params) - .then(() => notification.setRead(true)) - .catch(() => notification.setRead(false)); - } + osparc.notification.Notifications.markAsRead(notification); // open actionable path const actionablePath = notification.getActionablePath(); diff --git a/services/static-webserver/client/source/class/osparc/notification/Notifications.js b/services/static-webserver/client/source/class/osparc/notification/Notifications.js index 6c4ecb00d35..2f4b4922843 100644 --- a/services/static-webserver/client/source/class/osparc/notification/Notifications.js +++ b/services/static-webserver/client/source/class/osparc/notification/Notifications.js @@ -148,7 +148,24 @@ qx.Class.define("osparc.notification.Notifications", { data: this.__newWalletObj(userId, studyId) }; return osparc.data.Resources.fetch("notifications", "post", params); - } + }, + + markAsRead: function(notification) { + if (notification.isRead() === false) { + // set as read + const params = { + url: { + notificationId: notification.getId() + }, + data: { + "read": true + } + }; + osparc.data.Resources.fetch("notifications", "patch", params) + .then(() => notification.setRead(true)) + .catch(() => notification.setRead(false)); + } + }, }, members: { From 42fbb093ef04f4c16a0add2671806aaff5b3e849 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 17:18:38 +0100 Subject: [PATCH 13/17] comment --- .../client/source/class/osparc/dashboard/StudyBrowser.js | 1 + 1 file changed, 1 insertion(+) diff --git a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js index 18ecdc933d3..ab29d814808 100644 --- a/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js +++ b/services/static-webserver/client/source/class/osparc/dashboard/StudyBrowser.js @@ -116,6 +116,7 @@ qx.Class.define("osparc.dashboard.StudyBrowser", { // "Starting..." page this._hideLoadingPage(); + // since all the resources (templates, users, orgs...) were already loaded, notifications can be built osparc.data.Resources.get("notifications") .then(notifications => { osparc.notification.Notifications.getInstance().addNotifications(notifications); From dd393887e31d060b8ad44f3fe98aa3f4bb3675e7 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 17:19:35 +0100 Subject: [PATCH 14/17] refactor --- .../source/class/osparc/notification/NotificationUI.js | 5 +++-- 1 file changed, 3 insertions(+), 2 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 d4a5b8ba11b..b2b002a4f80 100644 --- a/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js +++ b/services/static-webserver/client/source/class/osparc/notification/NotificationUI.js @@ -231,10 +231,11 @@ qx.Class.define("osparc.notification.NotificationUI", { } this.fireEvent("notificationTapped"); - osparc.notification.Notifications.markAsRead(notification); + this.__openActionablePath(notification); + }, - // open actionable path + __openActionablePath: function(notification) { const actionablePath = notification.getActionablePath(); const items = actionablePath.split("/"); const resourceId = items.pop(); From 8ca98028d02ca48e9e4bfe7b82412e56f5b88aa2 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Mon, 4 Nov 2024 17:26:02 +0100 Subject: [PATCH 15/17] refactor --- .../source/class/osparc/notification/Notifications.js | 10 +++++++++- .../class/osparc/notification/NotificationsButton.js | 7 ++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/notification/Notifications.js b/services/static-webserver/client/source/class/osparc/notification/Notifications.js index 2f4b4922843..a34a0e2886c 100644 --- a/services/static-webserver/client/source/class/osparc/notification/Notifications.js +++ b/services/static-webserver/client/source/class/osparc/notification/Notifications.js @@ -188,6 +188,14 @@ qx.Class.define("osparc.notification.Notifications", { getNotifications: function() { return this.__notifications; - } + }, + + markAllAsRead: function() { + this.__notifications.forEach(notification => { + if (notification.isRead() === false) { + osparc.notification.Notifications.markAsRead(notification); + } + }); + }, } }); diff --git a/services/static-webserver/client/source/class/osparc/notification/NotificationsButton.js b/services/static-webserver/client/source/class/osparc/notification/NotificationsButton.js index 0b58a2b4e3f..dd8d4b543d4 100644 --- a/services/static-webserver/client/source/class/osparc/notification/NotificationsButton.js +++ b/services/static-webserver/client/source/class/osparc/notification/NotificationsButton.js @@ -82,7 +82,8 @@ qx.Class.define("osparc.notification.NotificationsButton", { }, __updateButton: function() { - const notifications = osparc.notification.Notifications.getInstance().getNotifications(); + const notificationManager = osparc.notification.Notifications.getInstance(); + const notifications = notificationManager.getNotifications(); notifications.forEach(notification => notification.addListener("changeRead", () => this.__updateButton(), this)); const nUnreadNotifications = notifications.filter(notification => notification.getRead() === false).length; @@ -117,6 +118,10 @@ qx.Class.define("osparc.notification.NotificationsButton", { // Show the container this.__notificationsContainer.show(); + // mark all notifications as read + const notificationManager = osparc.notification.Notifications.getInstance(); + notificationManager.markAllAsRead(); + // Add listener for taps outside the container to hide it document.addEventListener("mousedown", this.__onTapOutside.bind(this), true); }, From cf0eacccf7c6573f32116267e622f03c226b8a77 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Tue, 5 Nov 2024 08:34:21 +0100 Subject: [PATCH 16/17] update openapi --- .../api/v0/openapi.yaml | 32 +++++++++++++++++++ .../users/_notifications.py | 8 +++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml b/services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml index 0df5e076a76..fd624b92f1b 100644 --- a/services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml +++ b/services/web/server/src/simcore_service_webserver/api/v0/openapi.yaml @@ -12471,6 +12471,22 @@ components: read: title: Read type: boolean + resource_id: + title: Resource ID + anyOf: + - enum: + - "" + type: string + - type: string + default: "" + user_from_id: + title: User ID of the one creating it + anyOf: + - enum: + - None + type: integer + - type: integer + default: None UserNotificationCreate: title: UserNotificationCreate required: @@ -12510,6 +12526,22 @@ components: type: string - type: string default: UNDEFINED + resource_id: + title: Resource ID + anyOf: + - enum: + - "" + type: string + - type: string + default: "" + user_from_id: + title: User ID of the one creating it + anyOf: + - enum: + - None + type: integer + - type: integer + default: None UserNotificationPatch: title: UserNotificationPatch required: diff --git a/services/web/server/src/simcore_service_webserver/users/_notifications.py b/services/web/server/src/simcore_service_webserver/users/_notifications.py index 0da6ebc2be3..885371f7f65 100644 --- a/services/web/server/src/simcore_service_webserver/users/_notifications.py +++ b/services/web/server/src/simcore_service_webserver/users/_notifications.py @@ -26,14 +26,14 @@ class NotificationCategory(StrAutoEnum): class BaseUserNotification(BaseModel): user_id: UserID - user_from_id: Literal[None] | UserID = None category: NotificationCategory actionable_path: str - resource_id: Literal[""] | str = "" title: str text: str date: datetime product: Literal["UNDEFINED"] | ProductName = "UNDEFINED" + resource_id: Literal[""] | str = "" + user_from_id: Literal[None] | UserID = None @validator("category", pre=True) @classmethod @@ -108,6 +108,8 @@ class Config: "date": "2023-02-23T16:28:13.122Z", "product": "s4l", "read": False, + "resource_id": "3fb96d89-ff5d-4d27-b5aa-d20d46e20e12", + "user_from_id": "2", }, { "id": "390053c9-3931-40e1-839f-585268f6fd3e", @@ -119,6 +121,8 @@ class Config: "date": "2023-09-29T16:28:13.122Z", "product": "tis", "read": False, + "resource_id": "3fb96d89-ff5d-4d27-b5aa-d20d46e20e13", + "user_from_id": "2", }, ] } From a7a7170c4ed3a232452b31bd9a0c74c1b4f3f132 Mon Sep 17 00:00:00 2001 From: Odei Maiz Date: Tue, 5 Nov 2024 08:37:51 +0100 Subject: [PATCH 17/17] tests --- .../web/server/tests/unit/isolated/test_user_notifications.py | 4 ++++ .../tests/unit/with_dbs/03/test_users__notifications.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/services/web/server/tests/unit/isolated/test_user_notifications.py b/services/web/server/tests/unit/isolated/test_user_notifications.py index d606a84297f..7faf71f0aaf 100644 --- a/services/web/server/tests/unit/isolated/test_user_notifications.py +++ b/services/web/server/tests/unit/isolated/test_user_notifications.py @@ -80,6 +80,8 @@ def test_get_notification_key(user_id: UserID): "text": "You're now member of a new Organization", "date": "2023-02-23T16:23:13.122Z", "product": "s4l", + "resource_id": "other_id", + "user_from_id": "2", } ), id="category_from_string", @@ -95,6 +97,8 @@ def test_get_notification_key(user_id: UserID): "text": "You're now member of a new Organization", "date": "2023-02-23T16:23:13.122Z", "product": "tis", + "resource_id": "other_id", + "user_from_id": "2", } ), id="category_from_lower_case_string", diff --git a/services/web/server/tests/unit/with_dbs/03/test_users__notifications.py b/services/web/server/tests/unit/with_dbs/03/test_users__notifications.py index 77aaccade51..0aef84ee328 100644 --- a/services/web/server/tests/unit/with_dbs/03/test_users__notifications.py +++ b/services/web/server/tests/unit/with_dbs/03/test_users__notifications.py @@ -196,6 +196,8 @@ async def test_list_user_notifications( "date": "2023-02-23T16:23:13.122Z", "product": "osparc", "read": True, + "resource_id": "3fb96d89-ff5d-4d27-b5aa-d20d46e20e12", + "user_from_id": "2", }, id="with_extra_params_that_will_get_overwritten", ), @@ -265,6 +267,8 @@ async def test_create_user_notification_capped_list_length( "text": "You're now member of a new Organization", "date": "2023-02-23T16:23:13.122Z", "product": "osparc", + "resource_id": "3fb96d89-ff5d-4d27-b5aa-d20d46e20e12", + "user_from_id": "2", }, ) for _ in range(notification_count)