From e09473815644282820785c43ccfadc1887a4f128 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 23 May 2025 13:33:08 +0200 Subject: [PATCH 1/6] getReviewedUsers --- .../source/class/osparc/data/Resources.js | 4 ++ .../source/class/osparc/po/UsersPending.js | 60 ++++--------------- 2 files changed, 16 insertions(+), 48 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/data/Resources.js b/services/static-webserver/client/source/class/osparc/data/Resources.js index 916b810e87d0..824cf7de3cee 100644 --- a/services/static-webserver/client/source/class/osparc/data/Resources.js +++ b/services/static-webserver/client/source/class/osparc/data/Resources.js @@ -1065,6 +1065,10 @@ qx.Class.define("osparc.data.Resources", { method: "GET", url: statics.API + "/admin/user-accounts?review_status=PENDING" }, + getReviewedUsers: { + method: "GET", + url: statics.API + "/admin/user-accounts?review_status=REVIEWED" + }, approveUser: { method: "POST", url: statics.API + "/admin/user-accounts:approve" diff --git a/services/static-webserver/client/source/class/osparc/po/UsersPending.js b/services/static-webserver/client/source/class/osparc/po/UsersPending.js index 5b93793f58f2..4c0e99925a0c 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -20,50 +20,6 @@ qx.Class.define("osparc.po.UsersPending", { extend: osparc.po.BaseView, statics: { - getPendingUsers: function() { - return new Promise(resolve => { - resolve({ - data: [{ - name: "John Doe", - email: "john.doe@email.com", - date: "2025-01-01 00:00:00.702394", - status: "PENDING", - info: { - "institution": "ETH Zurich", - "department": "Department of Physics", - "position": "PhD Student", - "country": "Switzerland", - "city": "Zurich", - }, - }, { - name: "Jane Doe", - email: "jane.doe@email.com", - date: "2025-01-01 00:01:00.702394", - status: "REJECTED", - info: { - "institution": "ETH Zurich", - "department": "Department of Physics", - "position": "PhD Student", - "country": "Switzerland", - "city": "Zurich", - }, - }, { - name: "Alice Smith", - email: "alice.smith@email.com", - date: "2025-01-01 00:02:00.702394", - status: "APPROVED", - info: { - "institution": "ETH Zurich", - "department": "Department of Physics", - "position": "PhD Student", - "country": "Switzerland", - "city": "Zurich", - }, - }] - }); - }); - }, - createApproveButton: function(email) { const button = new osparc.ui.form.FetchButton(qx.locale.Manager.tr("Approve")); button.addListener("execute", () => { @@ -250,8 +206,12 @@ qx.Class.define("osparc.po.UsersPending", { break; } case "APPROVED": { + /* const resendEmailButton = this.self().createResendEmailButton(pendingUser.email); buttonsLayout.add(resendEmailButton); + */ + const rejectButton = this.self().createRejectButton(pendingUser.email); + buttonsLayout.add(rejectButton); break; } } @@ -260,13 +220,17 @@ qx.Class.define("osparc.po.UsersPending", { }, __populatePendingUsersLayout: function() { - // osparc.data.Resources.fetch("poUsers", "getPendingUsers", params) - this.self().getPendingUsers() - .then(pendingUsers => { + Promise.all([ + osparc.data.Resources.fetch("poUsers", "getPendingUsers"), + osparc.data.Resources.fetch("poUsers", "getReviewedUsers") + ]) + .then(resps => { + const pendingUsers = resps[0]["data"]; + const reviewedUsers = resps[1]["data"]; const pendingUsersLayout = this.getChildControl("pending-users-layout"); pendingUsersLayout.removeAll(); this.__addHeader(); - this.__addRows(pendingUsers["data"]); + this.__addRows(pendingUsers.concat(reviewedUsers)); }) .catch(err => osparc.FlashMessenger.logError(err)); } From 41fcd8e95ceaaa55adf4fdb24d8ae5f0c7e87b4f Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 23 May 2025 13:34:50 +0200 Subject: [PATCH 2/6] list both --- .../client/source/class/osparc/po/UsersPending.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/po/UsersPending.js b/services/static-webserver/client/source/class/osparc/po/UsersPending.js index 4c0e99925a0c..e71ad429b0d2 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -225,8 +225,8 @@ qx.Class.define("osparc.po.UsersPending", { osparc.data.Resources.fetch("poUsers", "getReviewedUsers") ]) .then(resps => { - const pendingUsers = resps[0]["data"]; - const reviewedUsers = resps[1]["data"]; + const pendingUsers = resps[0]; + const reviewedUsers = resps[1]; const pendingUsersLayout = this.getChildControl("pending-users-layout"); pendingUsersLayout.removeAll(); this.__addHeader(); From d1973156eadb140ab2c165a63ad34c9abbe48f86 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 23 May 2025 13:39:48 +0200 Subject: [PATCH 3/6] connect to backend --- .../source/class/osparc/po/UsersPending.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/po/UsersPending.js b/services/static-webserver/client/source/class/osparc/po/UsersPending.js index e71ad429b0d2..30c1cd049565 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -138,14 +138,14 @@ qx.Class.define("osparc.po.UsersPending", { column: 2, }); - pendingUsersLayout.add(new qx.ui.basic.Label(this.tr("Info")).set({ + pendingUsersLayout.add(new qx.ui.basic.Label(this.tr("Status")).set({ font: "text-14" }), { row: 0, column: 3, }); - pendingUsersLayout.add(new qx.ui.basic.Label(this.tr("Status")).set({ + pendingUsersLayout.add(new qx.ui.basic.Label(this.tr("Info")).set({ font: "text-14" }), { row: 0, @@ -165,7 +165,8 @@ qx.Class.define("osparc.po.UsersPending", { let row = 1; pendingUsers.forEach(pendingUser => { - pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.name), { + console.log("Pending user", pendingUser); + pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.firstName + " " + pendingUser.lastName), { row, column: 0, }); @@ -173,16 +174,16 @@ qx.Class.define("osparc.po.UsersPending", { row, column: 1, }); - pendingUsersLayout.add(new qx.ui.basic.Label(osparc.utils.Utils.formatDateAndTime(new Date(pendingUser.date))), { + pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.date ? osparc.utils.Utils.formatDateAndTime(new Date(pendingUser.date)) : "-"), { row, column: 2, }); - const infoButton = this.self().createInfoButton(pendingUser.info); - pendingUsersLayout.add(infoButton, { + pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.accountRequestStatus.toLowerCase()), { row, column: 3, }); - pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.status.toLowerCase()), { + const infoButton = this.self().createInfoButton(pendingUser); + pendingUsersLayout.add(infoButton, { row, column: 4, }); @@ -192,7 +193,7 @@ qx.Class.define("osparc.po.UsersPending", { column: 5, }); - switch (pendingUser.status) { + switch (pendingUser.accountRequestStatus) { case "PENDING": { const approveButton = this.self().createApproveButton(pendingUser.email); buttonsLayout.add(approveButton); From 4970024d24a561d0eb135757f1dcea0324aac2a4 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 23 May 2025 13:57:24 +0200 Subject: [PATCH 4/6] approve working --- .../source/class/osparc/po/UsersPending.js | 87 ++++++++++++++++--- 1 file changed, 73 insertions(+), 14 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/po/UsersPending.js b/services/static-webserver/client/source/class/osparc/po/UsersPending.js index 30c1cd049565..7ef1d6beab36 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -20,21 +20,81 @@ qx.Class.define("osparc.po.UsersPending", { extend: osparc.po.BaseView, statics: { + createInvitationForm: function() { + const form = new qx.ui.form.Form(); + + const extraCreditsInUsd = new qx.ui.form.Spinner().set({ + minimum: 0, + maximum: 1000, + value: 100 + }); + form.add(extraCreditsInUsd, qx.locale.Manager.tr("Welcome Credits (USD)"), null, "credits"); + + const withExpiration = new qx.ui.form.CheckBox().set({ + value: false + }); + form.add(withExpiration, qx.locale.Manager.tr("With expiration"), null, "withExpiration"); + + const trialDays = new qx.ui.form.Spinner().set({ + minimum: 1, + maximum: 1000, + value: 1 + }); + withExpiration.bind("value", trialDays, "visibility", { + converter: val => val ? "visible" : "excluded" + }); + form.add(trialDays, qx.locale.Manager.tr("Trial Days"), null, "trialDays"); + + return form; + }, + createApproveButton: function(email) { - const button = new osparc.ui.form.FetchButton(qx.locale.Manager.tr("Approve")); + const button = new qx.ui.form.Button(qx.locale.Manager.tr("Approve")); button.addListener("execute", () => { - button.setFetching(true); - const params = { - data: { - email, - }, - }; - osparc.data.Resources.fetch("poUsers", "approveUser", params) - .then(() => { - osparc.FlashMessenger.logAs(qx.locale.Manager.tr("User approved"), "INFO"); - }) - .catch(err => osparc.FlashMessenger.logError(err)) - .finally(() => button.setFetching(false)); + const form = this.createInvitationForm(); + const approveBtn = new osparc.ui.form.FetchButton(qx.locale.Manager.tr("Approve")); + approveBtn.set({ + appearance: "form-button" + }); + form.addButton(approveBtn); + const layout = new qx.ui.container.Composite(new qx.ui.layout.VBox(10)); + const invitationForm = new qx.ui.form.renderer.Single(form); + layout.add(invitationForm); + const win = osparc.ui.window.Window.popUpInWindow(layout, email, 350, 150).set({ + clickAwayClose: false, + resizable: false, + showClose: true + }); + win.open(); + approveBtn.addListener("execute", () => { + if (!osparc.data.Permissions.getInstance().canDo("user.invitation.generate", true)) { + return; + } + if (form.validate()) { + approveBtn.setFetching(true); + const params = { + data: { + email, + }, + }; + const extraCreditsInUsd = form.getItems()["credits"].getValue(); + if (extraCreditsInUsd > 0) { + params.data["extraCreditsInUsd"] = extraCreditsInUsd; + } + if (form.getItems()["withExpiration"].getValue()) { + params.data["trialAccountDays"] = form.getItems()["trialDays"].getValue(); + } + osparc.data.Resources.fetch("poUsers", "approveUser", params) + .then(() => { + osparc.FlashMessenger.logAs(qx.locale.Manager.tr("User approved"), "INFO"); + }) + .catch(err => osparc.FlashMessenger.logError(err)) + .finally(() => { + approveBtn.setFetching(false); + win.close(); + }); + } + }); }); return button; }, @@ -165,7 +225,6 @@ qx.Class.define("osparc.po.UsersPending", { let row = 1; pendingUsers.forEach(pendingUser => { - console.log("Pending user", pendingUser); pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.firstName + " " + pendingUser.lastName), { row, column: 0, From 93a71f82990b6c1df7abf31599033c1b9f87307f Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 23 May 2025 14:04:55 +0200 Subject: [PATCH 5/6] reload button --- .../client/source/class/osparc/po/UsersPending.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/services/static-webserver/client/source/class/osparc/po/UsersPending.js b/services/static-webserver/client/source/class/osparc/po/UsersPending.js index 7ef1d6beab36..3499f4891612 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -152,6 +152,16 @@ qx.Class.define("osparc.po.UsersPending", { _createChildControlImpl: function(id) { let control; switch (id) { + case "reload-button": + control = new qx.ui.form.Button(this.tr("Reload")).set({ + allowGrowX: false, + }); + control.addListener("execute", () => { + this.getChildControl("pending-users-layout").removeAll(); + this.__populatePendingUsersLayout(); + }); + this._add(control); + break; case "pending-users-container": control = new qx.ui.container.Scroll(); this._add(control, { @@ -169,6 +179,7 @@ qx.Class.define("osparc.po.UsersPending", { }, _buildLayout: function() { + this.getChildControl("reload-button"); this.getChildControl("pending-users-container"); this.__populatePendingUsersLayout(); From 2ed1bb9819f4e33ea14a26609375f6c4a14a28cf Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 23 May 2025 14:14:39 +0200 Subject: [PATCH 6/6] minor --- .../client/source/class/osparc/po/UsersPending.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/po/UsersPending.js b/services/static-webserver/client/source/class/osparc/po/UsersPending.js index 3499f4891612..b7d704a4bbc4 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -77,12 +77,13 @@ qx.Class.define("osparc.po.UsersPending", { email, }, }; + params.data["invitation"] = {}; const extraCreditsInUsd = form.getItems()["credits"].getValue(); if (extraCreditsInUsd > 0) { - params.data["extraCreditsInUsd"] = extraCreditsInUsd; + params.data["invitation"]["extraCreditsInUsd"] = extraCreditsInUsd; } if (form.getItems()["withExpiration"].getValue()) { - params.data["trialAccountDays"] = form.getItems()["trialDays"].getValue(); + params.data["invitation"]["trialAccountDays"] = form.getItems()["trialDays"].getValue(); } osparc.data.Resources.fetch("poUsers", "approveUser", params) .then(() => {