From 84187b1f7241ef89b4bdb77463dd29ab31402e2d Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 12:32:49 +0200 Subject: [PATCH 01/16] rename and enable --- .../client/source/class/osparc/po/POCenter.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/services/static-webserver/client/source/class/osparc/po/POCenter.js b/services/static-webserver/client/source/class/osparc/po/POCenter.js index 331899482b37..b000864caa50 100644 --- a/services/static-webserver/client/source/class/osparc/po/POCenter.js +++ b/services/static-webserver/client/source/class/osparc/po/POCenter.js @@ -27,9 +27,7 @@ qx.Class.define("osparc.po.POCenter", { this.addWidgetToTabs(miniProfile); this.__addActiveUsersPage(); - if (osparc.utils.Utils.isDevelopmentPlatform()) { - this.__addPendingUsersPage(); - } + this.__addReviewUsersPage(); this.__addPreRegistrationPage(); this.__addInvitationsPage(); this.__addProductPage(); @@ -44,8 +42,8 @@ qx.Class.define("osparc.po.POCenter", { this.addTab(title, iconSrc, users); }, - __addPendingUsersPage: function() { - const title = this.tr("Pending Users"); + __addReviewUsersPage: function() { + const title = this.tr("Review Users"); const iconSrc = "@FontAwesome5Solid/user-plus/22"; const usersPending = new osparc.po.UsersPending(); this.addTab(title, iconSrc, usersPending); From a9389c70d030a89679adc5d77ce7addc1953d22c Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 12:44:47 +0200 Subject: [PATCH 02/16] preRegistrationCreated --- .../client/source/class/osparc/po/UsersPending.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 8d086036bdb5..46c9475a9015 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -253,7 +253,7 @@ qx.Class.define("osparc.po.UsersPending", { row, column: 1, }); - pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.date ? osparc.utils.Utils.formatDateAndTime(new Date(pendingUser.date)) : "-"), { + pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.preRegistrationCreated ? osparc.utils.Utils.formatDateAndTime(new Date(pendingUser.preRegistrationCreated)) : "-"), { row, column: 2, }); From 92ac3dbd6849101dac776095389a8cc8aae113a9 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 12:44:54 +0200 Subject: [PATCH 03/16] avoid changing decision for now --- .../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 46c9475a9015..bf18a50b6488 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -282,15 +282,16 @@ qx.Class.define("osparc.po.UsersPending", { } case "REJECTED": { const approveButton = this.self().createApproveButton(pendingUser.email); + approveButton.setEnabled(false); // avoid changing decision for now buttonsLayout.add(approveButton); break; } case "APPROVED": { - /* const resendEmailButton = this.self().createResendEmailButton(pendingUser.email); + resendEmailButton.setEnabled(false); buttonsLayout.add(resendEmailButton); - */ const rejectButton = this.self().createRejectButton(pendingUser.email); + rejectButton.setEnabled(false); // avoid changing decision for now buttonsLayout.add(rejectButton); break; } From eb4e5ee9f29b841ddc79e59a5a3df5e9c7edf667 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 12:53:53 +0200 Subject: [PATCH 04/16] refactor --- .../source/class/osparc/po/UsersPending.js | 162 ++++++++++-------- 1 file changed, 86 insertions(+), 76 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 bf18a50b6488..a209b7e2de4d 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -56,77 +56,6 @@ qx.Class.define("osparc.po.UsersPending", { return form; }, - createApproveButton: function(email) { - const button = new qx.ui.form.Button(qx.locale.Manager.tr("Approve")); - button.addListener("execute", () => { - const form = this.createInvitationForm(false); - 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, - }, - }; - params.data["invitation"] = {}; - const extraCreditsInUsd = form.getItems()["credits"].getValue(); - if (extraCreditsInUsd > 0) { - params.data["invitation"]["extraCreditsInUsd"] = extraCreditsInUsd; - } - if (form.getItems()["withExpiration"].getValue()) { - params.data["invitation"]["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; - }, - - createRejectButton: function(email) { - const button = new osparc.ui.form.FetchButton(qx.locale.Manager.tr("Reject")); - button.addListener("execute", () => { - button.setFetching(true); - const params = { - data: { - email, - }, - }; - osparc.data.Resources.fetch("poUsers", "rejectUser", params) - .then(() => { - osparc.FlashMessenger.logAs(qx.locale.Manager.tr("User denied"), "INFO"); - }) - .catch(err => osparc.FlashMessenger.logError(err)) - .finally(() => button.setFetching(false)); - }); - return button; - }, - createResendEmailButton: function(email) { const button = new osparc.ui.form.FetchButton(qx.locale.Manager.tr("Resend Email")); button.addListener("execute", () => { @@ -274,14 +203,14 @@ qx.Class.define("osparc.po.UsersPending", { switch (pendingUser.accountRequestStatus) { case "PENDING": { - const approveButton = this.self().createApproveButton(pendingUser.email); + const approveButton = this.__createApproveButton(pendingUser.email); buttonsLayout.add(approveButton); - const rejectButton = this.self().createRejectButton(pendingUser.email); + const rejectButton = this.__createRejectButton(pendingUser.email); buttonsLayout.add(rejectButton); break; } case "REJECTED": { - const approveButton = this.self().createApproveButton(pendingUser.email); + const approveButton = this.__createApproveButton(pendingUser.email); approveButton.setEnabled(false); // avoid changing decision for now buttonsLayout.add(approveButton); break; @@ -290,7 +219,7 @@ qx.Class.define("osparc.po.UsersPending", { const resendEmailButton = this.self().createResendEmailButton(pendingUser.email); resendEmailButton.setEnabled(false); buttonsLayout.add(resendEmailButton); - const rejectButton = this.self().createRejectButton(pendingUser.email); + const rejectButton = this.__createRejectButton(pendingUser.email); rejectButton.setEnabled(false); // avoid changing decision for now buttonsLayout.add(rejectButton); break; @@ -314,6 +243,87 @@ qx.Class.define("osparc.po.UsersPending", { this.__addRows(pendingUsers.concat(reviewedUsers)); }) .catch(err => osparc.FlashMessenger.logError(err)); - } + }, + + __createApproveButton: function(email) { + const button = new qx.ui.form.Button(qx.locale.Manager.tr("Approve")); + button.addListener("execute", () => { + const form = this.createInvitationForm(false); + 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()) { + const approveUser = () => { + approveBtn.setFetching(true); + this.__approveUser(email, form) + .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; + }, + + __createRejectButton: function(email) { + const button = new osparc.ui.form.FetchButton(qx.locale.Manager.tr("Reject")); + button.addListener("execute", () => { + button.setFetching(true); + this.__rejectUser(email) + .then(() => osparc.FlashMessenger.logAs(qx.locale.Manager.tr("User denied"), "INFO")) + .catch(err => osparc.FlashMessenger.logError(err)) + .finally(() => button.setFetching(false)); + }); + return button; + }, + + __approveUser: function(email, form) { + const params = { + data: { + email, + }, + }; + params.data["invitation"] = {}; + const extraCreditsInUsd = form.getItems()["credits"].getValue(); + if (extraCreditsInUsd > 0) { + params.data["invitation"]["extraCreditsInUsd"] = extraCreditsInUsd; + } + if (form.getItems()["withExpiration"].getValue()) { + params.data["invitation"]["trialAccountDays"] = form.getItems()["trialDays"].getValue(); + } + return osparc.data.Resources.fetch("poUsers", "approveUser", params); + }, + + __rejectUser: function(email) { + const params = { + data: { + email, + }, + }; + return osparc.data.Resources.fetch("poUsers", "rejectUser", params); + }, } }); From 8269e4543190f6cc5596be6213ef0c9b2d97316a Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 12:56:23 +0200 Subject: [PATCH 05/16] Confirmation --- .../source/class/osparc/po/UsersPending.js | 36 +++++++++++-------- 1 file changed, 22 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 a209b7e2de4d..37a958070078 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -268,20 +268,28 @@ qx.Class.define("osparc.po.UsersPending", { return; } if (form.validate()) { - const approveUser = () => { - approveBtn.setFetching(true); - this.__approveUser(email, form) - .then(() => { - osparc.FlashMessenger.logAs(qx.locale.Manager.tr("User approved"), "INFO"); - }) - .catch(err => osparc.FlashMessenger.logError(err)) - .finally(() => { - approveBtn.setFetching(false); - win.close(); - }); - }; - - + const msg = this.tr("This user has no access to the project. Do you want to share it?"); + const win = new osparc.ui.window.Confirmation(msg).set({ + caption: this.tr("Share"), + confirmText: this.tr("Share"), + confirmAction: "create" + }); + win.center(); + win.open(); + win.addListener("close", () => { + if (win.getConfirmed()) { + approveBtn.setFetching(true); + this.__approveUser(email, form) + .then(() => { + osparc.FlashMessenger.logAs(qx.locale.Manager.tr("User approved"), "INFO"); + }) + .catch(err => osparc.FlashMessenger.logError(err)) + .finally(() => { + approveBtn.setFetching(false); + win.close(); + }); + } + }); } }); }); From c05c37f98168ccfd7b3ee2cc4963d8d8d1c57dd0 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 13:32:31 +0200 Subject: [PATCH 06/16] RejectButton --- .../source/class/osparc/po/UsersPending.js | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 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 37a958070078..1f4f2598626d 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -297,13 +297,25 @@ qx.Class.define("osparc.po.UsersPending", { }, __createRejectButton: function(email) { - const button = new osparc.ui.form.FetchButton(qx.locale.Manager.tr("Reject")); + const button = new osparc.ui.form.FetchButton("Reject"); button.addListener("execute", () => { - button.setFetching(true); - this.__rejectUser(email) - .then(() => osparc.FlashMessenger.logAs(qx.locale.Manager.tr("User denied"), "INFO")) - .catch(err => osparc.FlashMessenger.logError(err)) - .finally(() => button.setFetching(false)); + const msg = `Are you sure you want to reject ${email}.
The operation cannot be reverted"`; + const win = new osparc.ui.window.Confirmation(msg).set({ + caption: "Reject", + confirmText: "Reject", + confirmAction: "delete", + }); + win.center(); + win.open(); + win.addListener("close", () => { + if (win.getConfirmed()) { + button.setFetching(true); + this.__rejectUser(email) + .then(() => osparc.FlashMessenger.logAs(qx.locale.Manager.tr("User denied"), "INFO")) + .catch(err => osparc.FlashMessenger.logError(err)) + .finally(() => button.setFetching(false)); + } + }); }); return button; }, From 501de9d66ff74f3627fafd04a3e67beedee86e64 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 13:39:50 +0200 Subject: [PATCH 07/16] __confirmApproveUser --- .../source/class/osparc/po/UsersPending.js | 70 ++++++++++++------- 1 file changed, 43 insertions(+), 27 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 1f4f2598626d..422ec067c3ce 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -264,32 +264,10 @@ qx.Class.define("osparc.po.UsersPending", { }); win.open(); approveBtn.addListener("execute", () => { - if (!osparc.data.Permissions.getInstance().canDo("user.invitation.generate", true)) { - return; - } - if (form.validate()) { - const msg = this.tr("This user has no access to the project. Do you want to share it?"); - const win = new osparc.ui.window.Confirmation(msg).set({ - caption: this.tr("Share"), - confirmText: this.tr("Share"), - confirmAction: "create" - }); - win.center(); - win.open(); - win.addListener("close", () => { - if (win.getConfirmed()) { - approveBtn.setFetching(true); - this.__approveUser(email, form) - .then(() => { - osparc.FlashMessenger.logAs(qx.locale.Manager.tr("User approved"), "INFO"); - }) - .catch(err => osparc.FlashMessenger.logError(err)) - .finally(() => { - approveBtn.setFetching(false); - win.close(); - }); - } - }); + if (osparc.data.Permissions.getInstance().canDo("user.invitation.generate", true)) { + if (form.validate()) { + this.__confirmApproveUser(email, form); + } } }); }); @@ -301,7 +279,7 @@ qx.Class.define("osparc.po.UsersPending", { button.addListener("execute", () => { const msg = `Are you sure you want to reject ${email}.
The operation cannot be reverted"`; const win = new osparc.ui.window.Confirmation(msg).set({ - caption: "Reject", + caption: "Reject User", confirmText: "Reject", confirmAction: "delete", }); @@ -320,6 +298,44 @@ qx.Class.define("osparc.po.UsersPending", { return button; }, + __confirmApproveUser: function(email, form) { + const extraCreditsInUsd = form.getItems()["credits"].getValue(); + let trialAccountDays = 0; + if (form.getItems()["withExpiration"].getValue()) { + trialAccountDays = form.getItems()["trialDays"].getValue(); + } + + let msg = `Are you sure you want to approve ${email}`; + if (extraCreditsInUsd) { + msg += ` with ${extraCreditsInUsd}$ credits`; + } + if (trialAccountDays > 0) { + msg += ` and ${trialAccountDays} days of trial`; + } + msg += "?"; + const win = new osparc.ui.window.Confirmation(msg).set({ + caption: "Approve User", + confirmText: "Approve", + confirmAction: "create" + }); + win.center(); + win.open(); + win.addListener("close", () => { + if (win.getConfirmed()) { + approveBtn.setFetching(true); + this.__approveUser(email, form) + .then(() => { + osparc.FlashMessenger.logAs("User approved", "INFO"); + }) + .catch(err => osparc.FlashMessenger.logError(err)) + .finally(() => { + approveBtn.setFetching(false); + win.close(); + }); + } + }); + }, + __approveUser: function(email, form) { const params = { data: { From f0bb119c7986243821051609619eef54ec077b9b Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 13:41:49 +0200 Subject: [PATCH 08/16] minor --- .../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 422ec067c3ce..03599f65cdf4 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -248,7 +248,7 @@ qx.Class.define("osparc.po.UsersPending", { __createApproveButton: function(email) { const button = new qx.ui.form.Button(qx.locale.Manager.tr("Approve")); button.addListener("execute", () => { - const form = this.createInvitationForm(false); + const form = this.self().createInvitationForm(false); const approveBtn = new osparc.ui.form.FetchButton(qx.locale.Manager.tr("Approve")); approveBtn.set({ appearance: "form-button" @@ -307,7 +307,7 @@ qx.Class.define("osparc.po.UsersPending", { let msg = `Are you sure you want to approve ${email}`; if (extraCreditsInUsd) { - msg += ` with ${extraCreditsInUsd}$ credits`; + msg += ` with ${extraCreditsInUsd}$ worth credits`; } if (trialAccountDays > 0) { msg += ` and ${trialAccountDays} days of trial`; From b483b2698fbf5a8f4526bef1106d77197d1d9f99 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 13:44:15 +0200 Subject: [PATCH 09/16] reload --- .../source/class/osparc/po/UsersPending.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 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 03599f65cdf4..594bdf675a3c 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -94,10 +94,7 @@ qx.Class.define("osparc.po.UsersPending", { control = new qx.ui.form.Button(this.tr("Reload")).set({ allowGrowX: false, }); - control.addListener("execute", () => { - this.getChildControl("pending-users-layout").removeAll(); - this.__populatePendingUsersLayout(); - }); + control.addListener("execute", () => this.__reload()); this._add(control); break; case "pending-users-container": @@ -245,6 +242,11 @@ qx.Class.define("osparc.po.UsersPending", { .catch(err => osparc.FlashMessenger.logError(err)); }, + __reload: function() { + this.getChildControl("pending-users-layout").removeAll(); + this.__populatePendingUsersLayout(); + }, + __createApproveButton: function(email) { const button = new qx.ui.form.Button(qx.locale.Manager.tr("Approve")); button.addListener("execute", () => { @@ -289,7 +291,10 @@ qx.Class.define("osparc.po.UsersPending", { if (win.getConfirmed()) { button.setFetching(true); this.__rejectUser(email) - .then(() => osparc.FlashMessenger.logAs(qx.locale.Manager.tr("User denied"), "INFO")) + .then(() => { + osparc.FlashMessenger.logAs(qx.locale.Manager.tr("User denied"), "INFO"); + this.__reload(); + }) .catch(err => osparc.FlashMessenger.logError(err)) .finally(() => button.setFetching(false)); } @@ -326,6 +331,7 @@ qx.Class.define("osparc.po.UsersPending", { this.__approveUser(email, form) .then(() => { osparc.FlashMessenger.logAs("User approved", "INFO"); + this.__reload(); }) .catch(err => osparc.FlashMessenger.logError(err)) .finally(() => { From e02f4ea13f61fd5b8a10a6d0c68574425d7ab184 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 13:57:47 +0200 Subject: [PATCH 10/16] sortByDate --- .../client/source/class/osparc/po/UsersPending.js | 10 ++++++++-- 1 file changed, 8 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 594bdf675a3c..d81df3432a60 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -179,7 +179,7 @@ qx.Class.define("osparc.po.UsersPending", { row, column: 1, }); - pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.preRegistrationCreated ? osparc.utils.Utils.formatDateAndTime(new Date(pendingUser.preRegistrationCreated)) : "-"), { + pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.accountRequestReviewedAt ? osparc.utils.Utils.formatDateAndTime(new Date(pendingUser.accountRequestReviewedAt)) : "-"), { row, column: 2, }); @@ -236,7 +236,13 @@ qx.Class.define("osparc.po.UsersPending", { const reviewedUsers = resps[1]; const pendingUsersLayout = this.getChildControl("pending-users-layout"); pendingUsersLayout.removeAll(); - this.__addHeader(); + const sortByDate = (a, b) => { + const dateA = a.accountRequestReviewedAt ? new Date(a.accountRequestReviewedAt) : new Date(0); + const dateB = b.accountRequestReviewedAt ? new Date(b.accountRequestReviewedAt) : new Date(0); + return dateB - dateA; // sort by most recent first + }; + pendingUsers.sort(sortByDate); + reviewedUsers.sort(sortByDate); this.__addRows(pendingUsers.concat(reviewedUsers)); }) .catch(err => osparc.FlashMessenger.logError(err)); From 055eefb5ce3ddbc72970e486d6a94c3b3330bda7 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 14:11:28 +0200 Subject: [PATCH 11/16] colors --- .../source/class/osparc/po/UsersPending.js | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 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 d81df3432a60..55a89b820be0 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -183,23 +183,32 @@ qx.Class.define("osparc.po.UsersPending", { row, column: 2, }); - pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.accountRequestStatus.toLowerCase()), { + const statusImage = new qx.ui.basic.Image(); + pendingUsersLayout.add(statusImage, { row, column: 3, }); + pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.accountRequestStatus.toLowerCase()), { + row, + column: 4, + }); const infoButton = this.self().createInfoButton(pendingUser); pendingUsersLayout.add(infoButton, { row, - column: 4, + column: 5, }); const buttonsLayout = new qx.ui.container.Composite(new qx.ui.layout.HBox(5)); pendingUsersLayout.add(buttonsLayout, { row, - column: 5, + column: 6, }); switch (pendingUser.accountRequestStatus) { case "PENDING": { + statusImage.set({ + source: "@FontAwesome5Solid/hourglass-end/16", + textColor: "warning-yellow", + }); const approveButton = this.__createApproveButton(pendingUser.email); buttonsLayout.add(approveButton); const rejectButton = this.__createRejectButton(pendingUser.email); @@ -207,12 +216,20 @@ qx.Class.define("osparc.po.UsersPending", { break; } case "REJECTED": { + statusImage.set({ + source: "@FontAwesome5Solid/times/16", + textColor: "danger-red", + }); const approveButton = this.__createApproveButton(pendingUser.email); approveButton.setEnabled(false); // avoid changing decision for now buttonsLayout.add(approveButton); break; } case "APPROVED": { + statusImage.set({ + source: "@FontAwesome5Solid/check/16", + textColor: "product-color", + }); const resendEmailButton = this.self().createResendEmailButton(pendingUser.email); resendEmailButton.setEnabled(false); buttonsLayout.add(resendEmailButton); From 3568bac6c2641dfdf37b3b0c90b66f88ae2561b8 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 14:15:50 +0200 Subject: [PATCH 12/16] icons --- .../client/source/class/osparc/po/UsersPending.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 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 55a89b820be0..ec5212570be4 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -76,7 +76,7 @@ qx.Class.define("osparc.po.UsersPending", { }, createInfoButton: function(infoMetadata) { - const infoButton = new qx.ui.form.Button(null, "@MaterialIcons/info_outline/16"); + const infoButton = new qx.ui.form.Button(null, "@MaterialIcons/info_outline/14"); infoButton.addListener("execute", () => { const container = new qx.ui.container.Scroll(); container.add(new osparc.ui.basic.JsonTreeWidget(infoMetadata, "pendingUserInfo")); @@ -206,7 +206,7 @@ qx.Class.define("osparc.po.UsersPending", { switch (pendingUser.accountRequestStatus) { case "PENDING": { statusImage.set({ - source: "@FontAwesome5Solid/hourglass-end/16", + source: "@FontAwesome5Solid/hourglass-end/14", textColor: "warning-yellow", }); const approveButton = this.__createApproveButton(pendingUser.email); @@ -217,7 +217,7 @@ qx.Class.define("osparc.po.UsersPending", { } case "REJECTED": { statusImage.set({ - source: "@FontAwesome5Solid/times/16", + source: "@FontAwesome5Solid/times/14", textColor: "danger-red", }); const approveButton = this.__createApproveButton(pendingUser.email); @@ -227,7 +227,7 @@ qx.Class.define("osparc.po.UsersPending", { } case "APPROVED": { statusImage.set({ - source: "@FontAwesome5Solid/check/16", + source: "@FontAwesome5Solid/check/14", textColor: "product-color", }); const resendEmailButton = this.self().createResendEmailButton(pendingUser.email); From eb52584bcfac2cc7a6b2dfd35101c39eba08aa66 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 14:23:13 +0200 Subject: [PATCH 13/16] header --- .../client/source/class/osparc/po/UsersPending.js | 5 ++--- 1 file changed, 2 insertions(+), 3 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 ec5212570be4..ad3bef2ec565 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -116,7 +116,7 @@ qx.Class.define("osparc.po.UsersPending", { _buildLayout: function() { this.getChildControl("reload-button"); this.getChildControl("pending-users-container"); - + this.__addHeader(); this.__populatePendingUsersLayout(); }, @@ -251,8 +251,6 @@ qx.Class.define("osparc.po.UsersPending", { .then(resps => { const pendingUsers = resps[0]; const reviewedUsers = resps[1]; - const pendingUsersLayout = this.getChildControl("pending-users-layout"); - pendingUsersLayout.removeAll(); const sortByDate = (a, b) => { const dateA = a.accountRequestReviewedAt ? new Date(a.accountRequestReviewedAt) : new Date(0); const dateB = b.accountRequestReviewedAt ? new Date(b.accountRequestReviewedAt) : new Date(0); @@ -267,6 +265,7 @@ qx.Class.define("osparc.po.UsersPending", { __reload: function() { this.getChildControl("pending-users-layout").removeAll(); + this.__addHeader(); this.__populatePendingUsersLayout(); }, From 9b916c81180e94100d361ae7072039a55cd2ed96 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 14:24:31 +0200 Subject: [PATCH 14/16] minor --- .../source/class/osparc/po/UsersPending.js | 21 ------------------- 1 file changed, 21 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 ad3bef2ec565..f4cbfa40b76e 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -143,27 +143,6 @@ qx.Class.define("osparc.po.UsersPending", { row: 0, column: 2, }); - - 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("Info")).set({ - font: "text-14" - }), { - row: 0, - column: 4, - }); - - pendingUsersLayout.add(new qx.ui.basic.Label(this.tr("Action")).set({ - font: "text-14" - }), { - row: 0, - column: 5, - }); }, __addRows: function(pendingUsers) { From a71ba5f93f3a015529f266a16f7ef62770066d11 Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 14:26:30 +0200 Subject: [PATCH 15/16] aesthetics --- .../client/source/class/osparc/po/UsersPending.js | 3 +++ 1 file changed, 3 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 f4cbfa40b76e..26a057b4c0ff 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -147,9 +147,12 @@ qx.Class.define("osparc.po.UsersPending", { __addRows: function(pendingUsers) { const pendingUsersLayout = this.getChildControl("pending-users-layout"); + const grid = pendingUsersLayout.getLayout(); let row = 1; pendingUsers.forEach(pendingUser => { + grid.setRowAlign(row, "left", "middle"); + pendingUsersLayout.add(new qx.ui.basic.Label(pendingUser.firstName + " " + pendingUser.lastName), { row, column: 0, From bbcbd93a83e52b25945cd6a4cdb6db68eefbc6ed Mon Sep 17 00:00:00 2001 From: odeimaiz Date: Fri, 4 Jul 2025 14:33:48 +0200 Subject: [PATCH 16/16] last --- .../source/class/osparc/po/UsersPending.js | 76 +++++++++---------- 1 file changed, 36 insertions(+), 40 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 26a057b4c0ff..55a9d7d40ef3 100644 --- a/services/static-webserver/client/source/class/osparc/po/UsersPending.js +++ b/services/static-webserver/client/source/class/osparc/po/UsersPending.js @@ -272,7 +272,42 @@ qx.Class.define("osparc.po.UsersPending", { approveBtn.addListener("execute", () => { if (osparc.data.Permissions.getInstance().canDo("user.invitation.generate", true)) { if (form.validate()) { - this.__confirmApproveUser(email, form); + const extraCreditsInUsd = form.getItems()["credits"].getValue(); + let trialAccountDays = 0; + if (form.getItems()["withExpiration"].getValue()) { + trialAccountDays = form.getItems()["trialDays"].getValue(); + } + + let msg = `Are you sure you want to approve ${email}`; + if (extraCreditsInUsd) { + msg += ` with ${extraCreditsInUsd}$ worth credits`; + } + if (trialAccountDays > 0) { + msg += ` and ${trialAccountDays} days of trial`; + } + msg += "?"; + const confWin = new osparc.ui.window.Confirmation(msg).set({ + caption: "Approve User", + confirmText: "Approve", + confirmAction: "create" + }); + confWin.center(); + confWin.open(); + confWin.addListener("close", () => { + if (confWin.getConfirmed()) { + approveBtn.setFetching(true); + this.__approveUser(email, form) + .then(() => { + osparc.FlashMessenger.logAs("User approved", "INFO"); + this.__reload(); + }) + .catch(err => osparc.FlashMessenger.logError(err)) + .finally(() => { + approveBtn.setFetching(false); + win.close(); + }); + } + }); } } }); @@ -307,45 +342,6 @@ qx.Class.define("osparc.po.UsersPending", { return button; }, - __confirmApproveUser: function(email, form) { - const extraCreditsInUsd = form.getItems()["credits"].getValue(); - let trialAccountDays = 0; - if (form.getItems()["withExpiration"].getValue()) { - trialAccountDays = form.getItems()["trialDays"].getValue(); - } - - let msg = `Are you sure you want to approve ${email}`; - if (extraCreditsInUsd) { - msg += ` with ${extraCreditsInUsd}$ worth credits`; - } - if (trialAccountDays > 0) { - msg += ` and ${trialAccountDays} days of trial`; - } - msg += "?"; - const win = new osparc.ui.window.Confirmation(msg).set({ - caption: "Approve User", - confirmText: "Approve", - confirmAction: "create" - }); - win.center(); - win.open(); - win.addListener("close", () => { - if (win.getConfirmed()) { - approveBtn.setFetching(true); - this.__approveUser(email, form) - .then(() => { - osparc.FlashMessenger.logAs("User approved", "INFO"); - this.__reload(); - }) - .catch(err => osparc.FlashMessenger.logError(err)) - .finally(() => { - approveBtn.setFetching(false); - win.close(); - }); - } - }); - }, - __approveUser: function(email, form) { const params = { data: {